the browser-facing portion of osu!
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'master' into feature/beatmaps-multiple-mappers-revert-rename

bakaneko 100f3206 620c1f78

+2671 -1895
+1
.env.example
··· 44 44 # SESSION_DRIVER=redis 45 45 # SESSION_DOMAIN= 46 46 # SESSION_SECURE_COOKIE=false 47 + # SESSION_PREFIX= 47 48 48 49 # MAIL_DRIVER=log 49 50 # MAIL_HOST=
+1 -1
.github/workflows/lint.yml
··· 49 49 - name: Install js dependencies 50 50 run: yarn --frozen-lockfile 51 51 52 - - run: 'yarn lint --max-warnings 88 > /dev/null' 52 + - run: 'yarn lint --max-warnings 87 > /dev/null' 53 53 54 54 - run: yarn pretty 55 55
+1 -1
SETUP.md
··· 352 352 or if using Docker: 353 353 354 354 ``` 355 - docker compose run --rm php test js 355 + docker compose run --rm testjs 356 356 ``` 357 357 358 358 # Documentation
+77
app/Console/Commands/DailyChallengeUserStatsRecalculate.php
··· 1 + <?php 2 + 3 + // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4 + // See the LICENCE file in the repository root for full licence text. 5 + 6 + declare(strict_types=1); 7 + 8 + namespace App\Console\Commands; 9 + 10 + use App\Models\DailyChallengeUserStats; 11 + use Illuminate\Console\Command; 12 + 13 + class DailyChallengeUserStatsRecalculate extends Command 14 + { 15 + protected $signature = 'daily-challenge:user-stats-recalculate {--all} {id?*}'; 16 + 17 + protected $description = 'Recalculate user daily challenge stats'; 18 + 19 + public function handle(): int 20 + { 21 + $isAll = $this->option('all'); 22 + $userIds = $this->argument('id'); 23 + 24 + if (count($userIds) > 0 && $isAll) { 25 + $this->error("can't specify both user ids and all option"); 26 + 27 + return 1; 28 + } 29 + 30 + if (count($userIds) === 0 && !$isAll) { 31 + $this->error('either user ids or all option is required'); 32 + 33 + return 1; 34 + } 35 + 36 + if ($isAll) { 37 + DailyChallengeUserStats::chunkById(100, function ($statsArray) { 38 + $this->process($statsArray->keyBy('user_id')->all(), true); 39 + }); 40 + } else { 41 + $statsByUserId = DailyChallengeUserStats::find($userIds)->keyBy('user_id'); 42 + $statsArray = []; 43 + foreach ($userIds as $userId) { 44 + $statsArray[$userId] = $statsByUserId[$userId] ?? null; 45 + } 46 + 47 + $this->process($statsArray, false); 48 + } 49 + 50 + return 0; 51 + } 52 + 53 + private function process(array $statsArray, bool $isAll): void 54 + { 55 + $verbose = $this->option('verbose') || !$isAll; 56 + 57 + foreach ($statsArray as $userId => $stats) { 58 + if ($stats === null) { 59 + if ($verbose) { 60 + $this->info("User {$userId}: no stats"); 61 + } 62 + continue; 63 + } 64 + 65 + $origAttributes = $stats->getAttributes(); 66 + $stats->fix(); 67 + 68 + if ($origAttributes === $stats->getAttributes()) { 69 + if ($verbose) { 70 + $this->info("User {$userId}: no change"); 71 + } 72 + } else { 73 + $this->info("User {$userId}: updated"); 74 + } 75 + } 76 + } 77 + }
+1
app/Console/Kernel.php
··· 82 82 83 83 Commands\DailyChallengeCreateNext::class, 84 84 Commands\DailyChallengeUserStatsCalculate::class, 85 + Commands\DailyChallengeUserStatsRecalculate::class, 85 86 ]; 86 87 87 88 /**
+9 -5
app/Http/Controllers/BeatmapsetsController.php
··· 197 197 198 198 priv_check('BeatmapsetDownload', $beatmapset)->ensureCan(); 199 199 200 - $recentlyDownloaded = BeatmapDownload::where('user_id', Auth::user()->user_id) 200 + $user = Auth::user(); 201 + $userId = $user->getKey(); 202 + $recentlyDownloaded = BeatmapDownload::where('user_id', $userId) 201 203 ->where('timestamp', '>', Carbon::now()->subHours()->getTimestamp()) 202 204 ->count(); 203 205 204 - if ($recentlyDownloaded > Auth::user()->beatmapsetDownloadAllowance()) { 206 + if ($recentlyDownloaded > $user->beatmapsetDownloadAllowance()) { 205 207 abort(429, osu_trans('beatmapsets.download.limit_exceeded')); 206 208 } 207 209 208 210 $noVideo = get_bool(Request::input('noVideo', false)); 209 - $mirror = BeatmapMirror::getRandomForRegion(request_country(request())); 211 + $mirror = BeatmapMirror::getRandomForRegion(request_country()) 212 + ?? BeatmapMirror::getDefault() 213 + ?? abort(503, osu_trans('beatmapsets.download.no_mirrors')); 210 214 211 215 BeatmapDownload::create([ 212 - 'user_id' => Auth::user()->user_id, 213 - 'timestamp' => Carbon::now()->getTimestamp(), 216 + 'user_id' => $userId, 217 + 'timestamp' => time(), 214 218 'beatmapset_id' => $beatmapset->beatmapset_id, 215 219 'fulfilled' => 1, 216 220 'mirror_id' => $mirror->mirror_id,
+1 -3
app/Http/Controllers/Chat/ChatController.php
··· 272 272 $response['messages'] = []; 273 273 } 274 274 275 - $hasAny = array_first($response, fn ($val) => count($val) > 0) !== null; 276 - 277 - return $hasAny ? $response : response()->noContent(); 275 + return $response; 278 276 } 279 277 280 278 private function getSilences(?int $lastHistoryId, ?int $since)
+2 -2
app/Http/Controllers/FollowsController.php
··· 137 137 138 138 private function indexForumTopic() 139 139 { 140 - $topics = Topic::watchedByUser($this->user)->paginate(50); 140 + $topics = Topic::watchedByUser($this->user)->paginate(); 141 141 $topicReadStatus = TopicTrack::readStatus($this->user, $topics); 142 142 $topicWatchStatus = TopicWatch::watchStatus($this->user, $topics); 143 143 ··· 193 193 ->visible() 194 194 ->orderBy('last_notified', 'DESC') 195 195 ->with('beatmapset') 196 - ->paginate(50); 196 + ->paginate(); 197 197 $totalCount = $watches->total(); 198 198 $unreadCount = $this->user->beatmapsetWatches()->visible()->unread()->count(); 199 199 $openIssues = BeatmapDiscussion
+1 -1
app/Http/Controllers/Forum/ForumsController.php
··· 89 89 ->normal() 90 90 ->showDeleted($showDeleted) 91 91 ->recent(compact('sort', 'withReplies')) 92 - ->paginate(30); 92 + ->paginate(); 93 93 94 94 $allTopics = array_merge($pinnedTopics->all(), $topics->all()); 95 95 $topicReadStatus = TopicTrack::readStatus($user, $allTopics);
+1 -1
app/Http/Controllers/Forum/TopicLogsController.php
··· 19 19 $logs = $topic->logs() 20 20 ->where('log_type', Log::LOG_FORUM_MOD) 21 21 ->orderByDesc('log_time') 22 - ->paginate(30); 22 + ->paginate(); 23 23 24 24 return ext_view('forum.topics.logs.index', compact('logs', 'topic')); 25 25 }
+20 -9
app/Http/Controllers/Forum/TopicsController.php
··· 252 252 253 253 priv_check('ForumTopicReply', $topic)->ensureCan(); 254 254 255 - $post = Post::createNew($topic, auth()->user(), get_string(request('body'))); 255 + $user = \Auth::user(); 256 + $post = Post::createNew($topic, $user, get_string(request('body'))); 256 257 257 - $post->markRead(Auth::user()); 258 - (new ForumTopicReply($post, auth()->user()))->dispatch(); 258 + $post->markRead($user); 259 + (new ForumTopicReply($post, $user))->dispatch(); 260 + 261 + $watch = $user->user_notify 262 + ? TopicWatch::setState($topic, $user, 'watching_mail') 263 + : TopicWatch::lookup($topic, $user); 259 264 260 265 if (is_api_request()) { 261 266 return json_item($post, 'Forum\Post', ['body']); 262 267 } else { 263 - return ext_view('forum.topics._posts', [ 264 - 'firstPostPosition' => $topic->postPosition($post->post_id), 265 - 'posts' => collect([$post]), 266 - 'topic' => $topic, 267 - ]); 268 + return [ 269 + 'posts' => view('forum.topics._posts', [ 270 + 'firstPostPosition' => $topic->postPosition($post->post_id), 271 + 'posts' => collect([$post]), 272 + 'topic' => $topic, 273 + ])->render(), 274 + 'watch' => view('forum.topics._watch', [ 275 + 'state' => $watch, 276 + 'topic' => $topic, 277 + ])->render(), 278 + ]; 268 279 } 269 280 } 270 281 ··· 625 636 ], ['null_missing' => true]); 626 637 627 638 $params['skip_layout'] = $params['skip_layout'] ?? false; 628 - $params['limit'] = clamp($params['limit'] ?? 20, 1, 50); 639 + $params['limit'] = clamp($params['limit'] ?? Post::PER_PAGE, 1, 50); 629 640 630 641 if ($userCanModerate) { 631 642 $params['with_deleted'] ??= ($currentUser->userProfileCustomization ?? UserProfileCustomization::DEFAULTS)['forum_posts_show_deleted'];
+15 -4
app/Http/Controllers/Multiplayer/RoomsController.php
··· 6 6 namespace App\Http\Controllers\Multiplayer; 7 7 8 8 use App\Exceptions\InvariantException; 9 - use App\Http\Controllers\Controller as BaseController; 9 + use App\Http\Controllers\Controller; 10 + use App\Http\Controllers\Ranking\DailyChallengeController; 11 + use App\Models\Model; 10 12 use App\Models\Multiplayer\Room; 11 13 use App\Transformers\Multiplayer\RoomTransformer; 12 14 13 - class RoomsController extends BaseController 15 + class RoomsController extends Controller 14 16 { 15 17 public function __construct() 16 18 { ··· 114 116 115 117 public function leaderboard($roomId) 116 118 { 117 - $limit = clamp(get_int(request('limit')) ?? 50, 1, 50); 119 + $limit = clamp(get_int(request('limit')) ?? Model::PER_PAGE, 1, 50); 118 120 $room = Room::findOrFail($roomId); 119 121 120 122 // leaderboard currently requires auth so auth()->check() is not required. ··· 176 178 ); 177 179 } 178 180 181 + if ($room->category === 'daily_challenge') { 182 + return ujs_redirect(route('daily-challenge.show', DailyChallengeController::roomId($room))); 183 + } 184 + 179 185 $playlistItemsQuery = $room->playlist(); 180 186 if ($room->isRealtime()) { 181 187 $playlistItemsQuery->whereHas('scoreLinks'); 182 188 } 183 189 $beatmaps = $playlistItemsQuery->with('beatmap.beatmapset.beatmaps')->get()->pluck('beatmap'); 184 190 $beatmapsets = $beatmaps->pluck('beatmapset'); 185 - $highScores = $room->topScores()->paginate(50); 191 + $highScores = $room->topScores()->paginate(); 186 192 $spotlightRooms = Room::featured()->orderBy('id', 'DESC')->get(); 187 193 194 + $userScore = ($currentUser = \Auth::user()) === null 195 + ? null 196 + : $room->topScores()->whereBelongsTo($currentUser)->first(); 197 + 188 198 return ext_view('multiplayer.rooms.show', [ 189 199 'beatmaps' => $beatmaps, 190 200 'beatmapsets' => $beatmapsets, 191 201 'room' => $room, 192 202 'rooms' => $spotlightRooms, 193 203 'scores' => $highScores, 204 + 'userScore' => $userScore, 194 205 ]); 195 206 } 196 207
+70
app/Http/Controllers/Ranking/DailyChallengeController.php
··· 1 + <?php 2 + 3 + // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4 + // See the LICENCE file in the repository root for full licence text. 5 + 6 + declare(strict_types=1); 7 + 8 + namespace App\Http\Controllers\Ranking; 9 + 10 + use App\Http\Controllers\Controller; 11 + use App\Models\Multiplayer\Room; 12 + use Carbon\CarbonImmutable; 13 + use Carbon\Exceptions\InvalidFormatException; 14 + 15 + class DailyChallengeController extends Controller 16 + { 17 + private const string DATE_FORMAT = 'Y-m-d'; 18 + 19 + public static function roomId(Room $room): string 20 + { 21 + return $room->starts_at->format(static::DATE_FORMAT); 22 + } 23 + 24 + public function index() 25 + { 26 + $room = Room::dailyChallenges()->last() ?? abort(404); 27 + 28 + return ujs_redirect(route('daily-challenge.show', ['daily_challenge' => static::roomId($room)])); 29 + } 30 + 31 + public function show(string $dateString) 32 + { 33 + try { 34 + $date = CarbonImmutable::createFromFormat(static::DATE_FORMAT, $dateString); 35 + } catch (InvalidFormatException) { 36 + abort(404, 'invalid date'); 37 + } 38 + 39 + $room = Room::dailyChallengeFor($date) ?? abort(404); 40 + $playlist = $room->playlist[0]; 41 + 42 + $currentRoomOption = [ 43 + 'id' => $dateString, 44 + 'text' => $dateString, 45 + ]; 46 + $roomOptions = Room::dailyChallenges() 47 + ->orderByDesc('id') 48 + ->get() 49 + ->map(static::roomId(...)) 50 + ->map(fn (string $roomName): array => [ 51 + 'id' => $roomName, 52 + 'text' => $roomName, 53 + ]); 54 + 55 + $scores = $room->topScores()->paginate(); 56 + 57 + $userScore = ($currentUser = \Auth::user()) === null 58 + ? null 59 + : $room->topScores()->whereBelongsTo($currentUser)->first(); 60 + 61 + return ext_view('rankings.daily_challenge', compact( 62 + 'currentRoomOption', 63 + 'playlist', 64 + 'room', 65 + 'roomOptions', 66 + 'scores', 67 + 'userScore', 68 + )); 69 + } 70 + }
+16 -4
app/Http/Controllers/RankingController.php
··· 8 8 use App\Models\Beatmap; 9 9 use App\Models\Country; 10 10 use App\Models\CountryStatistics; 11 + use App\Models\Model; 11 12 use App\Models\Spotlight; 12 13 use App\Models\User; 13 14 use App\Models\UserStatistics; ··· 28 29 private $friendsOnly; 29 30 30 31 const MAX_RESULTS = 10000; 31 - const PAGE_SIZE = 50; 32 + const PAGE_SIZE = Model::PER_PAGE; 32 33 const RANKING_TYPES = ['performance', 'charts', 'score', 'country']; 33 34 const SPOTLIGHT_TYPES = ['charts']; 34 35 // in display order 35 - const TYPES = ['performance', 'score', 'country', 'multiplayer', 'seasons', 'charts', 'kudosu']; 36 + const TYPES = [ 37 + 'performance', 38 + 'score', 39 + 'country', 40 + 'multiplayer', 41 + 'daily_challenge', 42 + 'seasons', 43 + 'charts', 44 + 'kudosu', 45 + ]; 36 46 37 47 public function __construct() 38 48 { ··· 113 123 ): string { 114 124 return match ($type) { 115 125 'country' => route('rankings', ['mode' => $rulesetName, 'type' => $type]), 126 + 'daily_challenge' => route('daily-challenge.index'), 116 127 'kudosu' => route('rankings.kudosu'), 117 128 'multiplayer' => route('multiplayer.rooms.show', ['room' => 'latest']), 118 129 'seasons' => route('seasons.show', ['season' => 'latest']), ··· 353 364 354 365 $selectOptionTransformer = new SelectOptionTransformer(); 355 366 $selectOptions = [ 356 - 'selected' => json_item($spotlight, $selectOptionTransformer), 357 - 'options' => json_collection($spotlights, $selectOptionTransformer), 367 + 'currentItem' => json_item($spotlight, $selectOptionTransformer), 368 + 'items' => json_collection($spotlights, $selectOptionTransformer), 369 + 'type' => 'spotlight', 358 370 ]; 359 371 360 372 return ext_view(
+1
app/Http/Controllers/SessionsController.php
··· 92 92 $this->login($user, $remember); 93 93 94 94 return [ 95 + 'csrf_token' => csrf_token(), 95 96 'header' => view('layout._header_user')->render(), 96 97 'header_popup' => view('layout._popup_user')->render(), 97 98 'user' => json_item($user, new CurrentUserTransformer()),
+1 -1
app/Http/Controllers/Store/OrdersController.php
··· 40 40 $orders->where('status', '<>', 'incart'); 41 41 } 42 42 43 - $orders = $orders->paginate(20); 43 + $orders = $orders->paginate(); 44 44 45 45 return ext_view('store.orders.index', compact('orders')); 46 46 }
+1 -1
app/Http/Controllers/Users/LookupController.php
··· 31 31 if (ctype_digit($id)) { 32 32 $numericIds[] = $id; 33 33 } elseif (present($id)) { 34 - $stringIds[] = $id; 34 + $stringIds[] = $id[0] === '@' ? substr($id, 1) : $id; 35 35 } 36 36 } 37 37
-9
app/Http/Controllers/UsersController.php
··· 77 77 $this->middleware('guest', ['only' => ['create', 'store', 'storeWeb']]); 78 78 $this->middleware('auth', ['only' => [ 79 79 'checkUsernameAvailability', 80 - 'checkUsernameExists', 81 80 'report', 82 81 'me', 83 82 'posts', ··· 157 156 'cost' => $cost, 158 157 'costString' => currency($cost), 159 158 ]; 160 - } 161 - 162 - public function checkUsernameExists() 163 - { 164 - $username = get_string(request('username')); 165 - $user = User::lookup($username, 'username') ?? UserNotFound::instance(); 166 - 167 - return json_item($user, 'UserCompact', ['cover', 'country']); 168 159 } 169 160 170 161 public function extraPages($_id, $page)
+1
app/Http/Middleware/VerifyCsrfToken.php
··· 12 12 13 13 class VerifyCsrfToken extends BaseVerifier 14 14 { 15 + protected $addHttpCookie = false; 15 16 protected $except = [ 16 17 'home/changelog/github', 17 18 'oauth/authorize',
+10 -2
app/Models/BeatmapMirror.php
··· 5 5 6 6 namespace App\Models; 7 7 8 - use Auth; 8 + use Illuminate\Database\Eloquent\Builder; 9 9 10 10 /** 11 11 * @property string $base_url ··· 29 29 public $timestamps = false; 30 30 31 31 protected $hidden = ['secret_key']; 32 + protected array $macros = ['getDefault']; 32 33 33 34 const MIN_VERSION_TO_USE = 2; 34 35 ··· 65 66 return $regionalMirror ?? self::getRandom(); 66 67 } 67 68 69 + public function macroGetDefault(): callable 70 + { 71 + return fn (Builder $query): ?static => $query 72 + ->where('version', '>=', static::MIN_VERSION_TO_USE) 73 + ->where('is_master', true) 74 + ->first(); 75 + } 76 + 68 77 public function generateURL(Beatmapset $beatmapset, $skipVideo = false) 69 78 { 70 79 if ($beatmapset->download_disabled) { ··· 81 90 $serveFilename = str_replace(['"', '?'], ['', ''], $serveFilename); 82 91 83 92 $time = time(); 84 - $userId = Auth::check() ? Auth::user()->user_id : 0; 85 93 $checksum = md5("{$beatmapset->beatmapset_id}{$diskFilename}{$serveFilename}{$time}{$noVideo}{$this->secret_key}"); 86 94 87 95 $url = "{$this->base_url}d/{$beatmapset->beatmapset_id}?fs=".rawurlencode($serveFilename).'&fd='.rawurlencode($diskFilename)."&ts=$time&cs=$checksum&nv=$noVideo";
+31 -2
app/Models/DailyChallengeUserStats.php
··· 55 55 56 56 $highScoresByUserId = $playlist 57 57 ->highScores() 58 - ->where('total_score', '>', 0) 58 + ->passing() 59 59 ->get() 60 60 ->keyBy('user_id'); 61 61 $statsByUserId = static ··· 95 95 return $this->belongsTo(User::class, 'user_id'); 96 96 } 97 97 98 + public function fix(): void 99 + { 100 + $highScores = PlaylistItemUserHighScore 101 + ::where('user_id', $this->user_id) 102 + ->whereRelation('playlistItem.room', 'category', 'daily_challenge') 103 + ->passing() 104 + ->with('playlistItem.room') 105 + ->orderBy('created_at') 106 + ->get(); 107 + 108 + $this->fill(static::INITIAL_VALUES); 109 + 110 + foreach ($highScores as $highScore) { 111 + $playlistItem = $highScore->playlistItem; 112 + $room = $playlistItem->room; 113 + $startTime = $room->starts_at->toImmutable()->startOfDay(); 114 + $this->updateStreak(true, $startTime); 115 + if ($room->hasEnded()) { 116 + $this->updatePercentile($playlistItem->scorePercentile(), $highScore, $startTime); 117 + } 118 + } 119 + $streakBreakDay = CarbonImmutable::yesterday(); 120 + if ($this->last_update < $streakBreakDay) { 121 + $this->updateStreak(false, $streakBreakDay); 122 + } 123 + 124 + $this->saveOrExplode(); 125 + } 126 + 98 127 public function updateStreak( 99 128 bool $incrementing, 100 129 CarbonImmutable $startTime, ··· 132 161 } 133 162 } else { 134 163 $this->daily_streak_current = 0; 135 - if ($this->last_weekly_streak === null || $this->last_weekly_streak < $previousWeek) { 164 + if ($this->last_weekly_streak < $previousWeek) { 136 165 $this->weekly_streak_current = 0; 137 166 } 138 167 }
+2
app/Models/Model.php
··· 22 22 use HasFactory, Traits\FasterAttributes, Validatable; 23 23 24 24 const MAX_FIELD_LENGTHS = []; 25 + const int PER_PAGE = 50; 25 26 26 27 protected $connection = 'mysql'; 27 28 protected $guarded = []; 28 29 protected array $macros = []; 30 + protected $perPage = self::PER_PAGE; 29 31 protected $primaryKeys; 30 32 31 33 public static function booted()
+21 -13
app/Models/Multiplayer/PlaylistItem.php
··· 119 119 120 120 public function scorePercentile(): array 121 121 { 122 - $scores = $this->highScores() 123 - ->where('total_score', '>', 0) 124 - ->orderBy('total_score', 'DESC') 125 - ->pluck('total_score'); 126 - $count = count($scores); 122 + $key = "playlist_item_score_percentile:{$this->getKey()}"; 127 123 128 - return $count === 0 129 - ? [ 130 - '10p' => 0, 131 - '50p' => 0, 132 - ] : [ 133 - '10p' => $scores[max(0, (int) ($count * 0.1) - 1)], 134 - '50p' => $scores[max(0, (int) ($count * 0.5) - 1)], 135 - ]; 124 + if (!$this->expired && !$this->room->hasEnded()) { 125 + $key .= ':ongoing'; 126 + } 127 + 128 + return \Cache::remember($key, 600, function (): array { 129 + $scores = $this->highScores() 130 + ->passing() 131 + ->orderBy('total_score', 'DESC') 132 + ->pluck('total_score'); 133 + $count = count($scores); 134 + 135 + return $count === 0 136 + ? [ 137 + '10p' => 0, 138 + '50p' => 0, 139 + ] : [ 140 + '10p' => $scores[max(0, (int) ($count * 0.1) - 1)], 141 + '50p' => $scores[max(0, (int) ($count * 0.5) - 1)], 142 + ]; 143 + }); 136 144 } 137 145 138 146 private function assertValidMaxAttempts()
+6
app/Models/Multiplayer/PlaylistItemUserHighScore.php
··· 7 7 8 8 use App\Models\Model; 9 9 use App\Models\Traits\WithDbCursorHelper; 10 + use Illuminate\Database\Eloquent\Builder; 10 11 use Illuminate\Database\Eloquent\Relations\BelongsTo; 11 12 12 13 /** ··· 103 104 public function scoreLink() 104 105 { 105 106 return $this->belongsTo(ScoreLink::class, 'score_id'); 107 + } 108 + 109 + public function scopePassing(Builder $query): Builder 110 + { 111 + return $query->where('total_score', '>', 0); 106 112 } 107 113 108 114 public function updateUserAttempts()
+6 -1
app/Models/Multiplayer/Room.php
··· 226 226 public function macroDailyChallengeFor(): \Closure 227 227 { 228 228 return fn (Builder $query, CarbonImmutable $date): ?static 229 - => static::where('category', 'daily_challenge') 229 + => static::dailyChallenges() 230 230 ->whereBetween('starts_at', [$date->startOfDay(), $date->endOfDay()]) 231 231 ->last(); 232 232 } ··· 263 263 ->where(function ($q) { 264 264 $q->where('ends_at', '>', Carbon::now())->orWhereNull('ends_at'); 265 265 }); 266 + } 267 + 268 + public function scopeDailyChallenges(Builder $query): Builder 269 + { 270 + return $query->where('category', 'daily_challenge'); 266 271 } 267 272 268 273 public function scopeEnded($query)
+1 -5
app/Models/Store/Product.php
··· 115 115 116 116 public function getDescriptionAttribute($value) 117 117 { 118 - if ($this->masterProduct) { 119 - return $this->masterProduct->description; 120 - } else { 121 - return $value; 122 - } 118 + return presence($value) ?? $this->masterProduct?->description; 123 119 } 124 120 125 121 public function isAvailable(): bool
+3
app/Singletons/RouteSection.php
··· 132 132 'passport' => [ 133 133 '_' => 'user', 134 134 ], 135 + 'ranking' => [ 136 + '_' => 'rankings', 137 + ], 135 138 'store' => [ 136 139 '_' => 'store', 137 140 ],
+3 -2
app/helpers.php
··· 917 917 'main.artist_tracks_controller._' => 'main.artists_controller._', 918 918 'main.store_controller._' => 'store._', 919 919 'multiplayer.rooms_controller._' => 'main.ranking_controller._', 920 + 'ranking.daily_challenge_controller._' => 'main.ranking_controller._', 920 921 default => $controllerKey, 921 922 }; 922 923 $namespaceKey = "{$currentRoute['namespace']}._"; ··· 1815 1816 } 1816 1817 1817 1818 // formats a number as a percentage with a fixed number of precision 1818 - // e.g.: 98.3 -> 98.30% 1819 + // e.g.: 0.983 -> 98.30% 1819 1820 function format_percentage($number, $precision = 2) 1820 1821 { 1821 1822 // the formatter assumes decimal number while the function receives percentage number. 1822 - return i18n_number_format($number / 100, NumberFormatter::PERCENT, null, $precision); 1823 + return i18n_number_format($number, NumberFormatter::PERCENT, null, $precision); 1823 1824 } 1824 1825 1825 1826 // shorthand to return the filename of an open stream/handle
+2 -2
bin/run_dusk.sh
··· 2 2 3 3 if ! pgrep chromedriver > /dev/null; then 4 4 chromedriver_log=storage/logs/chromedriver.log 5 - chromedriver > "$chromedriver_log" 2>&1 & 5 + chromedriver --port=9515 > "$chromedriver_log" 2>&1 & 6 6 chromedriver_pid=$! 7 7 # wait for the driver to be ready 8 8 printf "Waiting for chromedriver to start..." 9 9 chromedriver_tries=0 10 - while ! grep -qF "ChromeDriver was started successfully." "$chromedriver_log"; do 10 + while ! grep -qF "ChromeDriver was started successfully on port 9515." "$chromedriver_log"; do 11 11 printf . 12 12 sleep 1 13 13 chromedriver_tries=$(($chromedriver_tries + 1))
+3 -1
config/session.php
··· 123 123 | 124 124 */ 125 125 126 - 'cookie' => 'osu_session', 126 + 'cookie' => (env('SESSION_PREFIX') ?? '').'osu_session', 127 127 128 128 /* 129 129 |-------------------------------------------------------------------------- ··· 163 163 */ 164 164 165 165 'secure' => env('SESSION_SECURE_COOKIE', false), 166 + 167 + 'same_site' => 'lax', 166 168 167 169 /* 168 170 |--------------------------------------------------------------------------
+9
docker-compose.yml
··· 47 47 <<: *x-web 48 48 command: ['job'] 49 49 50 + testjs: 51 + <<: *x-web 52 + volumes: 53 + - .:/app 54 + - .docker/js-build/assets:/app/public/assets 55 + - .docker/js-build/builds:/app/resources/builds 56 + profiles: ['testjs'] 57 + command: ['test', 'js'] 58 + 50 59 schedule: 51 60 <<: *x-web 52 61 command: ['schedule']
+1
docker/development/entrypoint.sh
··· 23 23 fi 24 24 25 25 usermod -d /app/.docker osuweb > /dev/null 26 + chown -f "${uid}:${gid}" .docker/js-build/assets .docker/js-build/builds || true 26 27 27 28 # helper functions 28 29 _rexec() {
+1 -3
package.json
··· 23 23 "@types/jquery.fileupload": "^9.22.1", 24 24 "@types/jquery.scrollto": "^1.4.29", 25 25 "@types/jqueryui": "^1.12.16", 26 - "@types/js-cookie": "^2.2.6", 27 26 "@types/lodash": "^4.14.185", 28 27 "@types/react": "^17.0.40", 29 28 "@types/react-dom": "^17.0.13", ··· 58 57 "jquery-ui-touch-punch": "^0.2.3", 59 58 "jquery-ujs": "^1.2.2", 60 59 "jquery.scrollto": "^2.1.2", 61 - "js-cookie": "^2.1.2", 62 60 "lang.js": "^1.1.14", 63 61 "less": "^3.9.0", 64 62 "less-loader": "^11.1.3", ··· 96 94 "typescript": "^5.2.2", 97 95 "unified": "^10.1.2", 98 96 "watchpack": "^2.4.0", 99 - "webpack": "^5.88.2", 97 + "webpack": "^5.94.0", 100 98 "webpack-cli": "^5.1.4", 101 99 "webpack-manifest-plugin": "^5.0.0", 102 100 "yargs": "^12.0.5",
+1
phpcs.xml
··· 16 16 <exclude-pattern>resources/docs/source/_tmp/*</exclude-pattern> 17 17 <exclude-pattern>resources/lang/(?!en)[^/]*/.*</exclude-pattern> 18 18 19 + <arg name="basepath" value="."/> 19 20 <arg name="extensions" value="php"/> 20 21 <arg name="report" value="code"/> 21 22 <arg value="npsv"/>
-1
resources/css/bem-index.less
··· 129 129 @import "bem/contest-art-list"; 130 130 @import "bem/contest-judge"; 131 131 @import "bem/contest-judge-entry"; 132 - @import "bem/contest-judge-entry-range-input"; 133 132 @import "bem/contest-judge-results"; 134 133 @import "bem/contest-judge-results-header"; 135 134 @import "bem/contest-judge-results-scores";
-1
resources/css/bem/beatmapset-header.less
··· 60 60 } 61 61 62 62 &__details-text { 63 - align-self: flex-start; 64 63 max-width: 100%; 65 64 word-break: break-word; 66 65
-44
resources/css/bem/contest-judge-entry-range-input.less
··· 1 - // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 - // See the LICENCE file in the repository root for full licence text. 3 - 4 - .contest-judge-entry-range-input { 5 - margin-top: 10px; 6 - max-width: 500px; 7 - 8 - input[type="range"] { 9 - -webkit-appearance: none; 10 - appearance: none; 11 - background: transparent; 12 - cursor: pointer; 13 - 14 - &::-webkit-slider-runnable-track { 15 - background: hsla(var(--hsl-pink-1), 50%); 16 - height: 8px; 17 - border-radius: @border-radius-base; 18 - } 19 - 20 - &::-moz-range-track { 21 - background: hsla(var(--hsl-pink-1), 50%); 22 - height: 8px; 23 - border-radius: @border-radius-base; 24 - } 25 - 26 - &::-webkit-slider-thumb { 27 - -webkit-appearance: none; 28 - appearance: none; 29 - margin-top: -4px; // initially slightly misaligned 30 - background-color: hsl(var(--hsl-pink-1)); 31 - width: 16px; 32 - height: 16px; 33 - border-radius: 9999px; 34 - } 35 - 36 - &::-moz-range-thumb { 37 - border: none; 38 - border-radius: 9999px; 39 - background-color: hsl(var(--hsl-pink-1)); 40 - width: 16px; 41 - height: 16px; 42 - } 43 - } 44 - }
+52 -21
resources/css/bem/contest-judge-entry.less
··· 2 2 // See the LICENCE file in the repository root for full licence text. 3 3 4 4 @margin: 10px; 5 - @max-width: 500px; 6 5 7 6 .contest-judge-entry { 8 7 margin-bottom: 20px; 8 + max-width: 500px; 9 9 10 10 &__button { 11 11 display: flex; 12 - max-width: @max-width; 13 12 justify-content: flex-end; 14 13 text-transform: lowercase; 15 14 } 16 15 16 + &__categories { 17 + display: flex; 18 + flex-direction: column; 19 + gap: 10px; 20 + } 21 + 22 + &__category { 23 + display: flex; 24 + flex-direction: column; 25 + gap: 10px; 26 + } 27 + 17 28 &__description-icon { 18 29 display: flex; 19 30 align-items: center; 20 - margin-right: 5px; 21 31 font-size: @font-size--small-2; 22 32 } 23 33 24 34 &__label { 25 35 display: flex; 36 + gap: 5px; 26 37 font-size: @font-size--normal; 27 - margin-top: @margin; 28 38 font-weight: bold; 29 39 } 30 40 41 + &__slider { 42 + -webkit-appearance: none; 43 + appearance: none; 44 + background: transparent; 45 + cursor: pointer; 46 + 47 + &::-webkit-slider-runnable-track { 48 + background: hsla(var(--hsl-pink-1), 50%); 49 + height: 8px; 50 + border-radius: @border-radius-base; 51 + } 52 + 53 + &::-moz-range-track { 54 + background: hsla(var(--hsl-pink-1), 50%); 55 + height: 8px; 56 + border-radius: @border-radius-base; 57 + } 58 + 59 + &::-webkit-slider-thumb { 60 + -webkit-appearance: none; 61 + appearance: none; 62 + margin-top: -4px; // initially slightly misaligned 63 + background-color: hsl(var(--hsl-pink-1)); 64 + width: 16px; 65 + height: 16px; 66 + border-radius: 9999px; 67 + } 68 + 69 + &::-moz-range-thumb { 70 + border: none; 71 + border-radius: 9999px; 72 + background-color: hsl(var(--hsl-pink-1)); 73 + width: 16px; 74 + height: 16px; 75 + } 76 + } 77 + 31 78 &__title { 32 79 margin-bottom: @margin; 33 80 font-size: @font-size--large; ··· 37 84 38 85 &__textarea { 39 86 .reset-input(); 40 - .default-border-radius(); 41 87 42 - flex: 1; 43 - background-color: hsl(var(--hsl-b3)); 44 - border: 2px solid transparent; 88 + resize: none; 45 89 color: #fff; 46 - padding: 5px; 47 - 48 - &:focus { 49 - border-color: hsl(var(--hsl-l1)); 50 - } 51 - } 52 - 53 - &__textarea-wrapper { 54 - display: flex; 55 - max-width: @max-width; 56 - margin: calc(@margin * 2) 0; 57 90 } 58 91 59 92 &__value { 60 - margin-top: @margin; 61 - max-width: @max-width; 62 93 display: flex; 63 94 justify-content: flex-end; 64 95 color: hsl(var(--hsl-c2));
+1
resources/css/bem/contest-judge-results-vote.less
··· 20 20 &__comment { 21 21 margin-top: 15px; 22 22 white-space: break-spaces; 23 + overflow-wrap: anywhere; 23 24 } 24 25 25 26 &__total-score {
+1 -1
resources/css/bem/daily-challenge-popup.less
··· 21 21 border-top-right-radius: inherit; 22 22 23 23 display: grid; 24 - grid-template-columns: 1fr 1fr; 24 + grid-template-columns: 1fr 1fr 1fr; 25 25 } 26 26 } 27 27
+13 -1
resources/css/bem/input-container.less
··· 47 47 } 48 48 49 49 &--error { 50 - border-color: hsl(var(--hsl-red-2)); 50 + border-color: hsl(var(--hsl-red-2)) !important; 51 51 } 52 52 53 53 &--fill { ··· 58 58 &--genre { 59 59 --label-colour: hsl(var(--hsl-c1)); 60 60 background: none; 61 + } 62 + 63 + &--judging { 64 + --input-bg: hsl(var(--hsl-b3)); 65 + 66 + border: 2px solid transparent; 67 + padding: 5px; 68 + margin: 20px 0; 69 + 70 + &:focus-within { 71 + border-color: hsl(var(--hsl-l1)); 72 + } 61 73 } 62 74 63 75 &__label {
+12
resources/css/bem/rankings-beatmapsets.less
··· 4 4 .rankings-beatmapsets { 5 5 margin-top: 40px; 6 6 margin-bottom: 10px; 7 + 8 + display: grid; 9 + gap: 10px; 10 + grid-template-columns: 1fr 1fr; 11 + 12 + &--daily-challenge { 13 + margin-top: 0; 14 + } 15 + 16 + &--single { 17 + grid-template-columns: 1fr; 18 + } 7 19 }
+3 -8
resources/css/bem/select-options.less
··· 9 9 --option-padding: 5px 10px; 10 10 --option-select-padding: 15px 10px; 11 11 --selector-display: none; 12 - --selector-max-height: auto; 12 + --selector-max-height: 400px; // arbitrary 13 13 --selector-overflow-y: auto; 14 14 15 - &--basic { 16 - --selector-max-height: 400px; // arbitrary 17 - --selector-overflow-y: scroll; 18 - } 19 - 20 15 &--beatmap-discussions-user-filter { 21 16 --decoration-colour: hsl(var(--hsl-c1)); 17 + --selector-max-height: auto; 22 18 23 19 @media @desktop { 24 20 width: 200px; ··· 26 22 } 27 23 28 24 &--ranking { 29 - --selector-max-height: 400px; // arbitrary 30 - --selector-overflow-y: scroll; 31 25 --option-select-padding: 5px 10px; 32 26 } 33 27 34 28 &--report { 29 + --selector-max-height: auto; 35 30 width: 100%; 36 31 } 37 32
+10 -5
resources/css/bem/sort.less
··· 5 5 @_top: sort; 6 6 @_item-margin: 5px; 7 7 8 + --item-button-colour: hsl(var(--hsl-l1)); 8 9 --item-hover-bg: hsl(var(--hsl-b3)); 9 10 padding: 0; 10 11 display: flex; ··· 30 31 --item-hover-bg: hsl(var(--hsl-b2)); 31 32 } 32 33 34 + &--ranking-header { 35 + --item-hover-bg: hsl(var(--hsl-b4)); 36 + } 37 + 33 38 &--user-list { 34 39 padding: 0; 35 40 } ··· 37 42 &__item { 38 43 .reset-input(); 39 44 margin: @_item-margin; 40 - color: white; 41 45 padding: 5px 10px; 42 46 .default-border-radius(); 43 47 44 48 &--button { 45 49 .link-plain(); 46 - .link-white(); 50 + color: var(--item-button-colour); 47 51 48 - &:hover { 52 + .link-hover({ 49 53 background-color: var(--item-hover-bg); 50 - } 54 + color: var(--item-button-colour); 55 + }); 51 56 } 52 57 53 58 &--contest-judge { ··· 61 66 62 67 // overrides --button 63 68 &--active { 69 + --item-button-colour: hsl(var(--hsl-c1)); 64 70 background-color: var(--item-hover-bg); 65 - color: @osu-colour-l1; 66 71 font-weight: 600; 67 72 } 68 73 }
+2 -2
resources/js/beatmap-discussions/subscribe.tsx
··· 7 7 import { action, makeObservable, observable } from 'mobx'; 8 8 import { observer } from 'mobx-react'; 9 9 import * as React from 'react'; 10 - import { onError } from 'utils/ajax'; 10 + import { onErrorWithCallback } from 'utils/ajax'; 11 11 import { trans } from 'utils/lang'; 12 12 import DiscussionsState from './discussions-state'; 13 13 ··· 64 64 this.xhr.done(() => { 65 65 this.props.discussionsState.update({ watching: !this.isWatching }); 66 66 }) 67 - .fail(onError) 67 + .fail(onErrorWithCallback(this.toggleWatch)) 68 68 .always(action(() => this.xhr = null)); 69 69 }; 70 70 }
+6 -2
resources/js/beatmaps/beatmapset-search-controller.ts
··· 11 11 import { trans, transArray } from 'utils/lang'; 12 12 import { popup } from 'utils/popup'; 13 13 import { currentUrl } from 'utils/turbolinks'; 14 + import { updateQueryString } from 'utils/url'; 14 15 15 16 16 17 const expandFilters: FilterKey[] = ['genre', 'language', 'extra', 'rank', 'played']; ··· 150 151 }); 151 152 } 152 153 154 + @action 153 155 private readonly filterChangedHandler = (change: IObjectDidChange<BeatmapsetSearchFilters>) => { 154 156 if (change.type === 'update' && change.oldValue === change.newValue) return; 155 - // FIXME: sort = null changes ignored because search triggered too early during filter update. 156 - if (change.type !== 'remove' && change.name === 'sort' && change.newValue == null) return; 157 157 158 158 this.searchStatus.state = 'input'; 159 159 this.debouncedFilterChangedSearch(); ··· 178 178 this.filtersObserver(); 179 179 } 180 180 this.filters = new BeatmapsetSearchFilters(url); 181 + 182 + // normalize url 183 + Turbolinks.controller.replaceHistory(updateQueryString(null, { ...this.filters.queryParams })); 184 + 181 185 this.filtersObserver = observe(this.filters, this.filterChangedHandler); 182 186 183 187 this.isExpanded = intersection(Object.keys(filtersFromUrl(url)), expandFilters).length > 0;
+3 -2
resources/js/beatmapset-search-filters.ts
··· 91 91 constructor(url: string) { 92 92 const filters = filtersFromUrl(url); 93 93 for (const key of keyNames) { 94 - this[key] = filters[key] ?? null; 94 + const value = filters[key] ?? null; 95 + this[key] = value === this.getDefault(key) ? null : value; 95 96 } 96 97 97 98 makeObservable(this); ··· 145 146 this.sort = null; 146 147 } 147 148 148 - this[key] = value; 149 + this[key] = value === this.getDefault(key) ? null : value; 149 150 } 150 151 }
+1 -1
resources/js/chat/chat-api.ts
··· 78 78 includes: ['presence', 'silences'], 79 79 since, 80 80 }, 81 - ) as JQuery.jqXHR<ChatUpdatesJson | null>; 81 + ) as JQuery.jqXHR<ChatUpdatesJson>; 82 82 } 83 83 84 84 export function joinChannel(channelId: number, userId: number) {
-1
resources/js/chat/chat-state-store.ts
··· 295 295 @action 296 296 private async updateChannelList() { 297 297 const json = await getUpdates(this.channelStore.lastReceivedMessageId, this.lastHistoryId); 298 - if (!json) return; // FIXME: fix response 299 298 300 299 runInAction(() => { 301 300 const newHistoryId = maxBy(json.silences, 'id')?.id;
+10 -13
resources/js/chat/create-announcement.tsx
··· 8 8 import UserJson from 'interfaces/user-json'; 9 9 import { action, computed, makeObservable, runInAction } from 'mobx'; 10 10 import { observer } from 'mobx-react'; 11 - import { isInputKey, maxLengths } from 'models/chat/create-announcement'; 11 + import { isInputKey } from 'models/chat/create-announcement'; 12 12 import core from 'osu-core-singleton'; 13 13 import * as React from 'react'; 14 14 import { trans } from 'utils/lang'; ··· 17 17 18 18 @observer 19 19 export default class CreateAnnouncement extends React.Component<Props> { 20 + private readonly usernameInputInitialProps; 21 + 20 22 @computed 21 23 private get canSend() { 22 24 return core.dataStore.chatState.isReady && !core.dataStore.chatState.isAddingChannel && this.model.isValid; ··· 35 37 runInAction(() => { 36 38 this.model.initialize(); 37 39 }); 40 + 41 + this.usernameInputInitialProps = runInAction(() => this.model.propsForUsernameInput); 38 42 } 39 43 40 44 render() { ··· 46 50 <div className='chat-form__title'>{trans('chat.form.title.announcement')}</div> 47 51 <InputContainer 48 52 labelKey='chat.form.labels.name' 49 - maxLength={maxLengths.name} 50 - model={this.model} 51 53 modifiers='chat' 52 - name='name' 54 + {...this.model.inputContainerPropsFor('name')} 53 55 > 54 56 <input 55 57 className='chat-form__input' ··· 61 63 </InputContainer> 62 64 <InputContainer 63 65 labelKey='chat.form.labels.description' 64 - maxLength={maxLengths.description} 65 - model={this.model} 66 66 modifiers='chat' 67 - name='description' 67 + {...this.model.inputContainerPropsFor('description')} 68 68 > 69 69 <input 70 70 className='chat-form__input' ··· 77 77 <InputContainer 78 78 for='chat-form-users' 79 79 labelKey='chat.form.labels.users' 80 - model={this.model} 81 80 modifiers='chat' 82 - name='users' 81 + {...this.model.inputContainerPropsFor('users')} 83 82 > 84 83 <div className='chat-form__users'> 85 84 <UserCardBrick user={core.currentUserOrFail} /> 86 85 <UsernameInput 87 86 id='chat-form-users' 88 87 ignoreCurrentUser 89 - initialValue={this.model.allUsers} 90 88 name='users' 91 89 onBlur={this.handleBlur} 92 90 onValidUsersChanged={this.handleValidUsersChanged} 93 91 onValueChanged={this.handleUsernameInputValueChanged} 92 + {...this.usernameInputInitialProps} 94 93 /> 95 94 </div> 96 95 </InputContainer> 97 96 <InputContainer 98 97 labelKey='chat.form.labels.message' 99 - maxLength={maxLengths.message} 100 - model={this.model} 101 98 modifiers={['chat', 'fill']} 102 - name='message' 99 + {...this.model.inputContainerPropsFor('message')} 103 100 > 104 101 <textarea 105 102 autoComplete='off'
+7 -2
resources/js/components/basic-select-options.tsx
··· 5 5 import SelectOptionJson from 'interfaces/select-option-json'; 6 6 import { route } from 'laroute'; 7 7 import * as React from 'react'; 8 + import { fail } from 'utils/fail'; 8 9 import { navigate } from 'utils/turbolinks'; 10 + import { updateQueryString } from 'utils/url'; 9 11 10 12 interface Props { 11 13 currentItem: SelectOptionJson; 12 14 items: SelectOptionJson[]; 13 - type: 'judge_results' | 'multiplayer' | 'seasons'; 15 + type: 'daily_challenge' | 'judge_results' | 'multiplayer' | 'seasons' | 'spotlight'; 14 16 } 15 17 16 18 export default class BasicSelectOptions extends React.PureComponent<Props> { 17 19 render() { 18 20 return ( 19 21 <SelectOptions 20 - modifiers='basic' 21 22 onChange={this.handleChange} 22 23 options={this.props.items} 23 24 renderOption={this.renderOption} ··· 32 33 33 34 private href(id: number | null) { 34 35 switch (this.props.type) { 36 + case 'daily_challenge': 37 + return route('daily-challenge.show', { daily_challenge: id ?? fail('missing id parameter') }); 35 38 case 'judge_results': 36 39 return route('contest-entries.judge-results', { contest_entry: id ?? 0 }); 37 40 case 'multiplayer': 38 41 return route('multiplayer.rooms.show', { room: id ?? 'latest' }); 39 42 case 'seasons': 40 43 return route('seasons.show', { season: id ?? 'latest' }); 44 + case 'spotlight': 45 + return updateQueryString(null, { spotlight: id?.toString() }); 41 46 } 42 47 } 43 48
+17 -18
resources/js/components/input-container.tsx
··· 9 9 10 10 interface CommonProps { 11 11 for?: string; 12 + hasError?: boolean; 12 13 labelKey?: string; 13 14 modifiers?: Modifiers; 15 + showError?: boolean; 14 16 } 15 17 16 - export interface FormWithErrors<T extends string> { 17 - errors: Record<T, boolean>; 18 - inputs: Record<T, string>; 19 - showError: Record<T, boolean>; 20 - } 21 - 22 - // extra props when error marking support is used. 23 - type Props<T extends string> = 24 - CommonProps & ( 25 - { maxLength?: number; model: FormWithErrors<T>; name: T } 26 - | { hasError?: boolean; model?: never; name?: never; showError?: boolean } 27 - ); 18 + type Props = CommonProps & ({ 19 + input: string; 20 + maxLength: number; 21 + } | { 22 + input?: string; 23 + maxLength?: never; 24 + }); 28 25 29 26 // TODO: look at combining with ValidatingInput 30 - const InputContainer = observer(<T extends string>(props: React.PropsWithChildren<Props<T>>) => { 31 - const error = props.model != null 32 - ? props.model.errors[props.name] && props.model.showError[props.name] 33 - : props.hasError && props.showError; 27 + // TODO: show error message 28 + const InputContainer = observer((props: React.PropsWithChildren<Props>) => { 29 + const error = props.hasError && props.showError; 34 30 35 31 return ( 36 32 <label className={classWithModifiers('input-container', { error }, props.modifiers)} htmlFor={props.for}> 37 33 {props.labelKey != null && ( 38 34 <div className='input-container__label'> 39 35 {trans(props.labelKey)} 40 - {props.model != null && props.maxLength != null && ( 41 - <MessageLengthCounter maxLength={props.maxLength} message={props.model.inputs[props.name]} /> 36 + {props.maxLength != null && ( 37 + <MessageLengthCounter 38 + maxLength={props.maxLength} 39 + message={props.input} 40 + /> 42 41 )} 43 42 </div> 44 43 )}
+1
resources/js/components/ranking-user-filter.tsx
··· 22 22 </div> 23 23 <Sort 24 24 currentValue={this.props.current ?? 'all'} 25 + modifiers='ranking-header' 25 26 onChange={this.onChange} 26 27 showTitle={false} 27 28 values={filters}
+1
resources/js/components/ranking-variant-filter.tsx
··· 23 23 </div> 24 24 <Sort 25 25 currentValue={this.props.current ?? 'all'} 26 + modifiers='ranking-header' 26 27 onChange={this.onChange} 27 28 showTitle={false} 28 29 transPrefix={`beatmaps.variant.${this.props.current_ruleset}.`}
-48
resources/js/components/spotlight-select-options.tsx
··· 1 - // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 - // See the LICENCE file in the repository root for full licence text. 3 - 4 - import SelectOptions, { OptionRenderProps } from 'components/select-options'; 5 - import SelectOptionJson from 'interfaces/select-option-json'; 6 - import * as React from 'react'; 7 - import { navigate } from 'utils/turbolinks'; 8 - import { updateQueryString } from 'utils/url'; 9 - 10 - function href(key: number) { 11 - return updateQueryString(null, { spotlight: key.toString() }); 12 - } 13 - 14 - interface Props { 15 - options: SelectOptionJson[]; 16 - selected: SelectOptionJson; 17 - } 18 - 19 - export default class SpotlightSelectOptions extends React.PureComponent<Props> { 20 - render() { 21 - return ( 22 - <SelectOptions 23 - modifiers='spotlight' 24 - onChange={this.handleChange} 25 - options={this.props.options} 26 - renderOption={this.renderOption} 27 - selected={this.props.selected} 28 - /> 29 - ); 30 - } 31 - 32 - private handleChange(this: void, option: SelectOptionJson) { 33 - navigate(href(option.id)); 34 - } 35 - 36 - private renderOption(this: void, { children, cssClasses, onClick, option }: OptionRenderProps<SelectOptionJson>) { 37 - return ( 38 - <a 39 - key={option.id} 40 - className={cssClasses} 41 - href={href(option.id)} 42 - onClick={onClick} 43 - > 44 - {children} 45 - </a> 46 - ); 47 - } 48 - }
+27 -25
resources/js/components/username-input.tsx
··· 2 2 // See the LICENCE file in the repository root for full licence text. 3 3 4 4 import UserJson, { UserJsonMinimum } from 'interfaces/user-json'; 5 - import { route } from 'laroute'; 6 5 import { debounce } from 'lodash'; 7 6 import { action, makeObservable, observable, runInAction } from 'mobx'; 8 7 import { observer } from 'mobx-react'; ··· 11 10 import { isJqXHR, onError } from 'utils/ajax'; 12 11 import { classWithModifiers, Modifiers } from 'utils/css'; 13 12 import { presence } from 'utils/string'; 13 + import { apiLookupUsers } from 'utils/user'; 14 14 import { Spinner } from './spinner'; 15 15 import UserCardBrick from './user-card-brick'; 16 16 ··· 36 36 37 37 @observer 38 38 export default class UsernameInput extends React.PureComponent<Props> { 39 - @observable users: string = ''; 40 - @observable validUsers = new Map<number, UserJson>(); 41 39 @observable private busy = false; 42 40 private readonly debouncedLookupUsers = debounce(() => this.lookupUsers(), 1000); 43 - private xhrLookupUsers?: JQuery.jqXHR<{ users: UserJson[] }>; 41 + @observable private input: string = ''; 42 + @observable private readonly validUsers = new Map<number, UserJson>(); 43 + private xhr?: ReturnType<typeof apiLookupUsers>; 44 44 45 45 constructor(props: Props) { 46 46 super(props); 47 47 48 48 makeObservable(this); 49 49 50 + // Does not accept input value updates outside of construction. 51 + // The component manages its own state so it can handle user and text 52 + // conversion without bouncing values back and forth. 50 53 if (this.props.initialUsers != null) { 51 54 for (const user of this.props.initialUsers) { 52 55 this.validUsers.set(user.id, user); ··· 60 63 61 64 componentWillUnmount() { 62 65 this.debouncedLookupUsers.cancel(); 63 - this.xhrLookupUsers?.abort(); 66 + this.xhr?.abort(); 64 67 } 65 68 66 69 render() { ··· 76 79 onKeyDown={this.handleUsersInputKeyDown} 77 80 onKeyUp={this.handleUsersInputKeyUp} 78 81 onPaste={this.handleUsersInputPaste} 79 - value={this.users} 82 + value={this.input} 80 83 /> 81 84 <BusySpinner busy={this.busy} /> 82 85 </div> ··· 88 91 */ 89 92 @action 90 93 private extractValidUsers(users: UserJson[]) { 91 - const userIds = this.users.split(','); 94 + const userIds = this.input.split(','); 92 95 93 96 for (const user of users) { 94 97 this.validUsers.set(user.id, user); ··· 99 102 for (const userId of userIds) { 100 103 const trimmedUserId = presence(userId.trim()); 101 104 102 - if (!this.validUsersContains(trimmedUserId)) { 105 + if (!this.validUsersContain(trimmedUserId)) { 103 106 invalidUsers.push(userId); 104 107 } 105 108 } 106 109 107 - this.users = invalidUsers.join(','); 110 + this.input = invalidUsers.join(','); 108 111 109 112 if (this.props.ignoreCurrentUser ?? false) { 110 113 this.validUsers.delete(core.currentUserOrFail.id); 111 114 } 112 115 113 - this.props.onValueChanged?.(this.users); 116 + this.props.onValueChanged?.(this.input); 114 117 this.props.onValidUsersChanged?.(this.validUsers); 115 118 } 116 119 ··· 153 156 154 157 @action 155 158 private async lookupUsers() { 156 - this.xhrLookupUsers?.abort(); 159 + this.xhr?.abort(); 157 160 this.debouncedLookupUsers.cancel(); 158 161 159 - const userIds = this.users.split(',').map((s) => presence(s.trim())).filter(Boolean); 162 + const userIds = this.input.split(',').map((s) => presence(s.trim())).filter(Boolean); 160 163 if (userIds.length === 0) { 161 164 this.busy = false; 162 165 return; 163 166 } 164 167 165 168 try { 166 - this.xhrLookupUsers = $.ajax(route('users.lookup-users'), { 167 - data: { ids: userIds }, 168 - method: 'POST', 169 - }); 170 - const response = await this.xhrLookupUsers; 169 + this.xhr = apiLookupUsers(userIds); 170 + const response = await this.xhr; 171 171 this.extractValidUsers(response.users); 172 172 } catch (error) { 173 173 if (!isJqXHR(error)) throw error; ··· 189 189 @action 190 190 private updateUsers(text: string, immediate: boolean) { 191 191 this.debouncedLookupUsers.cancel(); 192 - this.users = text; 192 + this.input = text; 193 193 194 - this.props.onValueChanged?.(this.users); 194 + this.props.onValueChanged?.(this.input); 195 195 196 196 // TODO: check if change is only whitespace. 197 197 if (text.trim().length === 0) { 198 - this.xhrLookupUsers?.abort(); 198 + this.xhr?.abort(); 199 199 this.busy = false; 200 200 201 201 return; ··· 210 210 } 211 211 } 212 212 213 - private validUsersContains(userId?: string | null) { 214 - if (userId == null) return false; 213 + private validUsersContain(userIdOrUsername?: string | null) { 214 + if (userIdOrUsername == null) return false; 215 215 216 - return this.validUsers.has(Number(userId)) 216 + return this.validUsers.has(Number(userIdOrUsername)) 217 217 // maybe it's a username 218 - || [...this.validUsers.values()].some((user) => user.username.toLowerCase() === userId.toLowerCase()); 218 + || [...this.validUsers.values()].some((user) => { 219 + const validUsernameLowercase = user.username.toLowerCase(); 220 + return [validUsernameLowercase, `@${validUsernameLowercase}`].includes(userIdOrUsername.toLowerCase()); 221 + }); 219 222 } 220 223 } 221 224 222 -
+6 -7
resources/js/contest-judge/current-user-judge-vote.ts
··· 5 5 import ContestJudgeVoteJson from 'interfaces/contest-judge-vote-json'; 6 6 import { action, makeObservable, observable } from 'mobx'; 7 7 8 - export class CurrentUserJudgeVote { 8 + export default class CurrentUserJudgeVote { 9 9 @observable comment = ''; 10 10 @observable scores = new Map<number, ContestJudgeScoreJson>(); 11 11 12 - constructor() { 12 + constructor(json?: ContestJudgeVoteJson) { 13 + if (json != null) { 14 + this.updateWithJson(json); 15 + } 16 + 13 17 makeObservable(this); 14 - } 15 - 16 - @action 17 - updateComment(content: string) { 18 - this.comment = content; 19 18 } 20 19 21 20 @action
+68 -62
resources/js/contest-judge/entry.tsx
··· 2 2 // See the LICENCE file in the repository root for full licence text. 3 3 4 4 import BigButton from 'components/big-button'; 5 + import InputContainer from 'components/input-container'; 6 + import TextareaAutosize from 'components/textarea-autosize'; 5 7 import ContestEntryJson from 'interfaces/contest-entry-json'; 6 8 import ContestScoringCategoryJson from 'interfaces/contest-scoring-category-json'; 7 9 import { route } from 'laroute'; ··· 12 14 import ContestJudgeStore from 'stores/contest-judge-store'; 13 15 import { onError } from 'utils/ajax'; 14 16 import { trans } from 'utils/lang'; 15 - import { CurrentUserJudgeVote } from './current-user-judge-vote'; 17 + import CurrentUserJudgeVote from './current-user-judge-vote'; 16 18 17 19 interface Props { 18 20 entry: ContestEntry; 19 21 store: ContestJudgeStore; 20 22 } 21 23 24 + const commentsMaxLength = 1000; 25 + 22 26 @observer 23 27 export default class Entry extends React.Component<Props> { 24 - @observable private readonly currentVote = new CurrentUserJudgeVote(); 25 - @observable private readonly initialVote = new CurrentUserJudgeVote(); 26 - @observable private posting = false; 27 - @observable private xhr?: JQuery.jqXHR; 28 + @observable private readonly currentVote; 29 + @observable private readonly initialVote; 30 + @observable private readonly store; 31 + @observable private xhr?: JQuery.jqXHR<ContestEntryJson>; 28 32 29 33 constructor(props: Props) { 30 34 super(props); 31 35 32 - const voteFromJson = props.entry.current_user_judge_vote; 33 - if (voteFromJson != null) { 34 - this.currentVote.updateWithJson(voteFromJson); 35 - this.initialVote.updateWithJson(voteFromJson); 36 - } 36 + this.store = this.props.store; 37 + 38 + const json = props.entry.current_user_judge_vote; 39 + this.currentVote = new CurrentUserJudgeVote(json); 40 + this.initialVote = new CurrentUserJudgeVote(json); 37 41 38 42 makeObservable(this); 39 43 } 40 44 41 45 @computed 42 - private get disabled() { 43 - const scoresHaveChanged = this.props.store.scoringCategories.some((category) => { 44 - const initialScore = this.initialVote.scores.get(category.id); 45 - const score = this.currentVote.scores.get(category.id); 46 + private get canSubmit() { 47 + return !this.commentTooLong 48 + && this.currentVote.scores.size === this.store.scoringCategories.length 49 + && (this.currentVote.comment !== this.initialVote.comment 50 + || this.store.scoringCategories.some((category) => ( 51 + this.initialVote.scores.get(category.id)?.value !== this.currentVote.scores.get(category.id)?.value 52 + )) 53 + ); 54 + } 46 55 47 - return initialScore?.value !== score?.value; 48 - }); 49 - 50 - return !( 51 - this.currentVote.scores.size === this.props.store.scoringCategories.length 52 - && (scoresHaveChanged || this.currentVote.comment !== this.initialVote.comment) 53 - ); 56 + private get commentTooLong() { 57 + return this.currentVote.comment.length > commentsMaxLength; 54 58 } 55 59 56 60 render() { ··· 65 69 {this.props.entry.title} 66 70 </div> 67 71 68 - {this.props.store.scoringCategories.map((category) => { 69 - const currentScore = this.currentVote.scores.get(category.id); 70 - 71 - return ( 72 - <div key={category.id}> 73 - <div className='contest-judge-entry__label'> 74 - <div className='contest-judge-entry__description-icon' title={category.description}> 75 - <i className='fas fa-question-circle' /> 76 - </div> 77 - 78 - {category.name} 79 - </div> 80 - 81 - {this.renderRangeInput(category, currentScore?.value ?? 0)} 82 - 83 - <div className='contest-judge-entry__value'> 84 - { 85 - currentScore != null 86 - ? `${currentScore.value}/${category.max_value}` 87 - : trans('contest.judge.no_current_vote') 88 - } 89 - </div> 90 - </div> 91 - ); 92 - })} 72 + <div className='contest-judge-entry__categories'> 73 + {this.store.scoringCategories.map(this.renderCategory)} 74 + </div> 93 75 94 - <div className='contest-judge-entry__textarea-wrapper'> 95 - <textarea 76 + <InputContainer 77 + hasError={this.commentTooLong} 78 + input={this.currentVote.comment} 79 + labelKey='contest.judge.comments' 80 + maxLength={commentsMaxLength} 81 + modifiers='judging' 82 + showError 83 + > 84 + <TextareaAutosize 96 85 className='contest-judge-entry__textarea' 86 + maxRows={20} 97 87 onChange={this.handleCommentChange} 98 88 rows={6} 99 89 value={this.currentVote.comment} 100 90 /> 101 - </div> 91 + </InputContainer> 102 92 103 93 <div className='contest-judge-entry__button'> 104 94 <BigButton 105 - disabled={this.disabled} 95 + disabled={!this.canSubmit} 106 96 icon='fas fa-check' 107 - isBusy={this.posting} 97 + isBusy={this.xhr != null} 108 98 props={{ onClick: this.submitVote }} 109 99 text={trans('contest.judge.update')} 110 100 /> ··· 115 105 116 106 @action 117 107 private readonly handleCommentChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { 118 - this.currentVote.updateComment(e.currentTarget.value); 108 + this.currentVote.comment = e.currentTarget.value; 119 109 }; 120 110 121 111 @action ··· 127 117 this.currentVote.scores.set(categoryId, score); 128 118 }; 129 119 130 - private renderRangeInput(category: ContestScoringCategoryJson, initialValue: number) { 120 + private readonly renderCategory = (category: ContestScoringCategoryJson) => { 121 + const currentScore = this.currentVote.scores.get(category.id); 122 + 131 123 return ( 132 - <div className='contest-judge-entry-range-input'> 124 + <div key={category.id} className='contest-judge-entry__category'> 125 + <div className='contest-judge-entry__label'> 126 + <div className='contest-judge-entry__description-icon' title={category.description}> 127 + <i className='fas fa-question-circle' /> 128 + </div> 129 + 130 + {category.name} 131 + </div> 132 + 133 133 <input 134 + className='contest-judge-entry__slider' 134 135 data-category-id={category.id} 135 136 max={category.max_value} 136 137 onChange={this.handleRangeInputChange} 137 138 type='range' 138 - value={initialValue} 139 + value={currentScore?.value ?? 0} 139 140 /> 141 + 142 + <div className='contest-judge-entry__value'> 143 + { 144 + currentScore != null 145 + ? `${currentScore.value}/${category.max_value}` 146 + : trans('contest.judge.no_current_vote') 147 + } 148 + </div> 140 149 </div> 141 150 ); 142 - } 151 + }; 143 152 144 153 @action 145 154 private readonly submitVote = () => { 146 - if (this.xhr != null) return; 147 - 148 - this.posting = true; 155 + if (this.xhr != null || !this.canSubmit) return; 149 156 150 157 this.xhr = $.ajax(route('contest-entries.judge-vote', { contest_entry: this.props.entry.id }), { 151 158 data: { ··· 157 164 158 165 this.xhr 159 166 .fail(onError) 160 - .done((json: ContestEntryJson) => runInAction(() => { 161 - this.props.store.updateEntry(json); 167 + .done((json) => runInAction(() => { 168 + this.store.updateEntry(json); 162 169 163 170 if (json.current_user_judge_vote != null) { 164 171 this.initialVote.updateWithJson(json.current_user_judge_vote); 165 172 } 166 173 })).always(action(() => { 167 - this.posting = false; 168 174 this.xhr = undefined; 169 175 })); 170 176 };
+1 -2
resources/js/contest-judge/main.tsx
··· 1 1 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 2 // See the LICENCE file in the repository root for full licence text. 3 3 4 - import { action, computed, makeObservable, observable } from 'mobx'; 4 + import { action, makeObservable, observable } from 'mobx'; 5 5 import { observer } from 'mobx-react'; 6 6 import * as React from 'react'; 7 7 import ContestJudgeStore from 'stores/contest-judge-store'; ··· 17 17 export default class Main extends React.Component<Props> { 18 18 @observable private hideJudged = false; 19 19 20 - @computed 21 20 private get filteredEntries() { 22 21 const entries = [...this.props.store.entries.values()]; 23 22
+3 -2
resources/js/core-legacy/forum-topic-reply.coffee
··· 102 102 input.value = '' 103 103 @bbcodePreview.hidePreview(target: input) 104 104 105 - $newPost = $(data) 105 + $newPost = $(data.posts) 106 106 107 107 needReload = (@forum.postPosition($newPost[0]) - 1) != @forum.postPosition(@forum.endPost()) || 108 108 e.target.dataset.forceReload == '1' ··· 110 110 if needReload 111 111 navigate $newPost.find('.js-post-url').attr('href') 112 112 else 113 + $('.js-forum-topic-watch').replaceWith(data.watch) 113 114 @forum.setTotalPosts(@forum.totalPosts() + 1) 114 - @forum.endPost().insertAdjacentHTML 'afterend', data 115 + @forum.endPost().insertAdjacentHTML 'afterend', data.posts 115 116 116 117 @forum.endPost().scrollIntoView() 117 118
+1 -4
resources/js/core/spoilerbox.ts
··· 1 1 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 2 // See the LICENCE file in the repository root for full licence text. 3 3 4 + import { fail } from 'utils/fail'; 4 5 import { htmlElementOrNull } from 'utils/html'; 5 - 6 - function fail(message: string): never { 7 - throw new Error(message); 8 - } 9 6 10 7 function expand(e: JQuery.ClickEvent) { 11 8 e.stopPropagation();
+3 -4
resources/js/core/user/user-login.ts
··· 3 3 4 4 import Captcha from 'core/captcha'; 5 5 import UserJson from 'interfaces/user-json'; 6 - import * as Cookies from 'js-cookie'; 7 6 import core from 'osu-core-singleton'; 8 7 import { xhrErrorMessage } from 'utils/ajax'; 9 8 import { createClickCallback } from 'utils/html'; ··· 21 20 } 22 21 23 22 interface LoginSuccessJson { 23 + csrf_token: string; 24 24 header: string; 25 25 header_popup: string; 26 26 user: UserJson; ··· 121 121 122 122 this.reset(); 123 123 124 - this.refreshToken(); 124 + this.refreshToken(data.csrf_token); 125 125 126 126 $.publish('user:update', data.user); 127 127 ··· 139 139 this.showOnError(xhr, createClickCallback(e.target)); 140 140 }; 141 141 142 - private readonly refreshToken = () => { 143 - const token = Cookies.get('XSRF-TOKEN') ?? null; 142 + private readonly refreshToken = (token: string) => { 144 143 $('[name="_token"]').attr('value', token); 145 144 $('[name="csrf-token"]').attr('content', token); 146 145 };
+25 -5
resources/js/core/user/user-preferences.ts
··· 7 7 import { action, makeObservable, observable } from 'mobx'; 8 8 import { onErrorWithCallback } from 'utils/ajax'; 9 9 10 + const localStorageKey = 'userPreferences'; 11 + 10 12 export default class UserPreferences { 11 13 @observable private current: UserPreferencesJson; 12 14 private updatingOptions = false; 13 15 private user?: CurrentUserJson; 14 16 15 17 constructor() { 16 - this.current = Object.assign({}, defaultUserPreferencesJson, this.fromStorage()); 18 + this.current = this.fromStorageWithDefaults(); 17 19 18 20 makeObservable(this); 21 + 22 + window.addEventListener('storage', this.updateFromStorage); 19 23 } 20 24 21 25 get<T extends keyof UserPreferencesJson>(key: T) { ··· 27 31 if (this.current[key] === value) return; 28 32 29 33 this.current[key] = value; 30 - localStorage.userPreferences = JSON.stringify(this.current); 34 + this.updateStorage(); 31 35 32 36 if (this.user == null) return; 33 37 ··· 50 54 setUser(user?: CurrentUserJson) { 51 55 this.user = user; 52 56 53 - if (user != null && !this.updatingOptions) { 54 - this.current = user?.user_preferences; 57 + if (!this.updatingOptions) { 58 + this.current = user?.user_preferences ?? defaultUserPreferencesJson(); 59 + this.updateStorage(); 55 60 } 56 61 } 57 62 58 63 private fromStorage(): Partial<UserPreferencesJson> { 59 64 try { 60 - const data = localStorage.getItem('userPreferences'); 65 + const data = localStorage.getItem(localStorageKey); 61 66 if (data != null) { 62 67 const preferences = JSON.parse(data) as unknown; 63 68 ··· 70 75 } 71 76 72 77 return {}; 78 + } 79 + 80 + private fromStorageWithDefaults() { 81 + return Object.assign(defaultUserPreferencesJson(), this.fromStorage()); 82 + } 83 + 84 + @action 85 + private readonly updateFromStorage = (event: StorageEvent) => { 86 + if (event.key == null || event.key === localStorageKey) { 87 + this.current = this.fromStorageWithDefaults(); 88 + } 89 + }; 90 + 91 + private updateStorage() { 92 + localStorage[localStorageKey] = JSON.stringify(this.current); 73 93 } 74 94 }
+12 -3
resources/js/core/user/user-verification.ts
··· 23 23 status: 401; 24 24 } 25 25 26 - const isUserVerificationXhr = (arg: JQuery.jqXHR): arg is UserVerificationXhr => ( 27 - arg.status === 401 && arg.responseJSON?.authentication === 'verify' 28 - ); 26 + function isUserVerificationJson(arg: unknown): arg is UserVerificationJson { 27 + return typeof arg === 'object' 28 + && arg != null 29 + && 'authentication' in arg 30 + && arg.authentication === 'verify' 31 + && 'box' in arg 32 + && typeof arg.box === 'string'; 33 + } 34 + 35 + export function isUserVerificationXhr(arg: JQuery.jqXHR<unknown>): arg is UserVerificationXhr { 36 + return arg.status === 401 && isUserVerificationJson(arg.responseJSON); 37 + } 29 38 30 39 export default class UserVerification { 31 40 // Used as callback on original action (where verification was required)
+20 -18
resources/js/interfaces/user-preferences-json.ts
··· 5 5 import { ViewMode } from 'components/user-card'; 6 6 import { Filter, SortMode } from 'components/user-list'; 7 7 8 - export const defaultUserPreferencesJson: UserPreferencesJson = { 9 - audio_autoplay: false, 10 - audio_muted: false, 11 - audio_volume: 0.45, 12 - beatmapset_card_size: 'normal', 13 - beatmapset_download: 'all', 14 - beatmapset_show_nsfw: false, 15 - beatmapset_title_show_original: false, 16 - comments_show_deleted: false, 17 - comments_sort: 'new', 18 - forum_posts_show_deleted: true, 19 - legacy_score_only: false, 20 - profile_cover_expanded: true, 21 - scoring_mode: 'standardised', 22 - user_list_filter: 'all', 23 - user_list_sort: 'last_visit', 24 - user_list_view: 'card', 25 - }; 8 + export function defaultUserPreferencesJson(): UserPreferencesJson { 9 + return { 10 + audio_autoplay: false, 11 + audio_muted: false, 12 + audio_volume: 0.45, 13 + beatmapset_card_size: 'normal', 14 + beatmapset_download: 'all', 15 + beatmapset_show_nsfw: false, 16 + beatmapset_title_show_original: false, 17 + comments_show_deleted: false, 18 + comments_sort: 'new', 19 + forum_posts_show_deleted: true, 20 + legacy_score_only: false, 21 + profile_cover_expanded: true, 22 + scoring_mode: 'standardised', 23 + user_list_filter: 'all', 24 + user_list_sort: 'last_visit', 25 + user_list_view: 'card', 26 + }; 27 + } 26 28 27 29 export default interface UserPreferencesJson { 28 30 audio_autoplay: boolean;
+18 -7
resources/js/models/chat/create-announcement.ts
··· 1 1 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 2 // See the LICENCE file in the repository root for full licence text. 3 3 4 - import { FormWithErrors } from 'components/input-container'; 5 4 import UserJson from 'interfaces/user-json'; 6 5 import { action, autorun, computed, makeObservable, observable } from 'mobx'; 7 6 import { uuid } from 'utils/seq'; ··· 21 20 description: 255, 22 21 message: maxMessageLength, 23 22 name: 50, 23 + users: undefined, 24 24 }); 25 25 26 26 export function isInputKey(key: string): key is InputKey { ··· 28 28 } 29 29 30 30 // This class is owned by ChatStateStore 31 - export default class CreateAnnouncement implements FormWithErrors<InputKey> { 31 + export default class CreateAnnouncement { 32 32 @observable inputs: Record<InputKey, string>; 33 33 @observable showError: Record<InputKey, boolean>; 34 34 @observable validUsers = new Map<number, UserJson>(); ··· 37 37 private readonly uuid = uuid(); 38 38 39 39 @computed 40 - get allUsers() { 41 - return [...this.validUsers.keys(), this.inputs.users].join(','); 42 - } 43 - 44 - @computed 45 40 get errors() { 46 41 return { 47 42 description: !this.isValidLength('description', true), ··· 57 52 return !Object.values(this.errors).some(Boolean); 58 53 } 59 54 55 + get propsForUsernameInput() { 56 + return { 57 + initialUsers: [...this.validUsers.values()], 58 + initialValue: this.inputs.users, 59 + }; 60 + } 61 + 60 62 constructor() { 61 63 this.inputs = this.resetInputs(); 62 64 this.showError = this.resetErrors(); ··· 103 105 }); 104 106 105 107 this.initialized = true; 108 + } 109 + 110 + inputContainerPropsFor(name: InputKey) { 111 + return { 112 + hasError: this.errors[name], 113 + input: this.inputs[name], 114 + maxLength: maxLengths[name], 115 + showError: this.showError[name], 116 + }; 106 117 } 107 118 108 119 toJson() {
+1 -2
resources/js/models/user.ts
··· 87 87 deletedUser.username = trans('users.deleted'); 88 88 Object.freeze(deletedUser); 89 89 90 - const deletedUserJson = deletedUser.toJson(); 91 - Object.freeze(deletedUserJson); 90 + const deletedUserJson = Object.freeze(deletedUser.toJson()); 92 91 93 92 export { 94 93 deletedUser,
+2 -2
resources/js/notifications/worker.ts
··· 3 3 4 4 import DispatcherAction from 'actions/dispatcher-action'; 5 5 import { dispatch, dispatchListener } from 'app-dispatcher'; 6 + import { isUserVerificationXhr } from 'core/user/user-verification'; 6 7 import DispatchListener from 'dispatch-listener'; 7 - import { isErrorJson } from 'interfaces/error-json'; 8 8 import { NotificationBundleJson } from 'interfaces/notification-json'; 9 9 import { route } from 'laroute'; 10 10 import { action, computed, makeObservable, observable, observe, runInAction } from 'mobx'; ··· 116 116 this.retryDelay.reset(); 117 117 })) 118 118 .fail((xhr) => runInAction(() => { 119 - if (isErrorJson(xhr.responseJSON) && xhr.responseJSON.error === 'verification') { 119 + if (isUserVerificationXhr(xhr)) { 120 120 this.waitingVerification = true; 121 121 122 122 return;
+26 -23
resources/js/profile-page/daily-challenge.tsx
··· 33 33 34 34 function tierStyle(days: number) { 35 35 return { 36 - '--colour': `var(--level-tier-${tier(days)}`, 36 + '--colour': `var(--level-tier-${tier(days)})`, 37 37 } as React.CSSProperties; 38 + } 39 + 40 + function tierStylePlaycount(count: number) { 41 + return tierStyle(count / 3); 38 42 } 39 43 40 44 function tierStyleWeekly(weeks: number) { ··· 67 71 return ( 68 72 <div className='daily-challenge-popup'> 69 73 <div className='daily-challenge-popup__content daily-challenge-popup__content--top'> 70 - <div className='daily-challenge-popup__top-entry'> 71 - <div className='daily-challenge-popup__top-title'> 72 - {trans('users.show.daily_challenge.daily_streak_current')} 74 + {([ 75 + ['playcount', tierStylePlaycount, 'day'], 76 + ['daily_streak_current', tierStyle, 'day'], 77 + ['weekly_streak_current', tierStyleWeekly, 'week'], 78 + ] as const).map(([key, tierFn, unit]) => ( 79 + <div key={key} className='daily-challenge-popup__top-entry'> 80 + <div className='daily-challenge-popup__top-title'> 81 + {trans(`users.show.daily_challenge.${key}`)} 82 + </div> 83 + <div 84 + className={classWithModifiers('daily-challenge-popup__value', ['fancy', 'top'])} 85 + style={tierFn(stats[key])} 86 + > 87 + {trans(`users.show.daily_challenge.unit.${unit}`, { value: formatNumber(stats[key]) })} 88 + </div> 73 89 </div> 74 - <div 75 - className={classWithModifiers('daily-challenge-popup__value', ['fancy', 'top'])} 76 - style={tierStyle(stats.daily_streak_current)} 77 - > 78 - {trans('users.show.daily_challenge.unit.day', { value: formatNumber(stats.daily_streak_current) })} 79 - </div> 80 - </div> 81 - <div className='daily-challenge-popup__top-entry'> 82 - <div className='daily-challenge-popup__top-title'> 83 - {trans('users.show.daily_challenge.weekly_streak_current')} 84 - </div> 85 - <div 86 - className={classWithModifiers('daily-challenge-popup__value', ['fancy', 'top'])} 87 - style={tierStyleWeekly(stats.weekly_streak_current)} 88 - > 89 - {trans('users.show.daily_challenge.unit.week', { value: formatNumber(stats.weekly_streak_current) })} 90 - </div> 91 - </div> 90 + ))} 92 91 </div> 93 92 <div className='daily-challenge-popup__content daily-challenge-popup__content--main'> 94 93 {values.map(([transKey, value, valueMods, valueStyle]) => ( ··· 119 118 } 120 119 121 120 render() { 121 + if (this.props.stats.playcount === 0) { 122 + return null; 123 + } 124 + 122 125 return ( 123 126 <div 124 127 ref={this.valueRef} ··· 133 136 <div className='daily-challenge__value-box'> 134 137 <div 135 138 className='daily-challenge__value' 136 - style={tierStyle(this.props.stats.playcount / 3)} 139 + style={tierStylePlaycount(this.props.stats.playcount)} 137 140 > 138 141 {trans( 139 142 'users.show.daily_challenge.unit.day',
+3 -5
resources/js/profile-page/detail.tsx
··· 68 68 <Rank highest={this.user.rank_highest} stats={this.user.statistics} type='global' /> 69 69 <Rank stats={this.user.statistics} type='country' /> 70 70 </div> 71 - {this.props.controller.currentMode === 'osu' && ( 72 - <div className='profile-detail__values'> 73 - <DailyChallenge stats={this.user.daily_challenge_user_stats} /> 74 - </div> 75 - )} 71 + <div className='profile-detail__values'> 72 + <DailyChallenge stats={this.user.daily_challenge_user_stats} /> 73 + </div> 76 74 </div> 77 75 78 76 <div className='profile-detail__chart'>
-5
resources/js/register-components.tsx
··· 14 14 import RankingUserFilter from 'components/ranking-user-filter'; 15 15 import RankingVariantFilter from 'components/ranking-variant-filter'; 16 16 import ScoringModeToggle from 'components/scoring-mode-toggle'; 17 - import SpotlightSelectOptions from 'components/spotlight-select-options'; 18 17 import { UserCard } from 'components/user-card'; 19 18 import { startListening, UserCardTooltip } from 'components/user-card-tooltip'; 20 19 import { UserCards } from 'components/user-cards'; ··· 69 68 70 69 core.reactTurbolinks.register('basic-select-options', () => ( 71 70 <BasicSelectOptions {...parseJson('json-basic-select-options')} /> 72 - )); 73 - 74 - core.reactTurbolinks.register('spotlight-select-options', () => ( 75 - <SpotlightSelectOptions {...parseJson('json-spotlight-select-options')} /> 76 71 )); 77 72 78 73 core.reactTurbolinks.register('chat-icon', (container) => (
+11 -10
resources/js/store/store-supporter-tag.tsx
··· 3 3 4 4 import { UserCard } from 'components/user-card'; 5 5 import UserJson from 'interfaces/user-json'; 6 - import { route } from 'laroute'; 7 6 import { debounce } from 'lodash'; 8 7 import { action, autorun, computed, makeObservable, observable, runInAction } from 'mobx'; 9 8 import { disposeOnUnmount, observer } from 'mobx-react'; 9 + import User from 'models/user'; 10 10 import core from 'osu-core-singleton'; 11 11 import React from 'react'; 12 12 import { onError } from 'utils/ajax'; ··· 15 15 import { trans, transChoice } from 'utils/lang'; 16 16 import { toggleCart } from 'utils/store-cart'; 17 17 import { currentUrlParams } from 'utils/turbolinks'; 18 + import { apiLookupUsers } from 'utils/user'; 18 19 19 20 const jsonId = 'json-store-supporter-tag'; 20 21 21 22 const maxValue = 52; 22 23 const minValue = 4; 24 + 25 + const userNotFound = new User(-1); 26 + userNotFound.username = trans('supporter_tag.user_search.not_found'); 27 + 28 + const userNotFoundJson = Object.freeze(userNotFound.toJson()); 23 29 24 30 interface Props { 25 31 maxMessageLength: number; ··· 55 61 @observable private sliderValue = minValue; 56 62 @observable private user: UserJson | null; 57 63 @observable private username = currentUrlParams().get('target') ?? ''; 58 - private xhr: JQuery.jqXHR<UserJson> | null = null; 64 + private xhr: ReturnType<typeof apiLookupUsers> | null = null; 59 65 60 66 @computed 61 67 get cost() { ··· 223 229 224 230 @action 225 231 private readonly getUser = (username: string) => { 226 - this.xhr = $.ajax({ 227 - data: { username }, 228 - dataType: 'json', 229 - type: 'POST', 230 - url: route('users.check-username-exists'), 231 - }); 232 + this.xhr = apiLookupUsers([`@${username}`]); 232 233 233 234 this.xhr 234 - .done((data) => runInAction(() => { 235 - this.user = data; 235 + .done((response) => runInAction(() => { 236 + this.user = response.users[0] ?? userNotFoundJson; 236 237 })) 237 238 .fail(onError) 238 239 .always(() => {
+6
resources/js/utils/fail.ts
··· 1 + // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 + // See the LICENCE file in the repository root for full licence text. 3 + 4 + export function fail(message: string): never { 5 + throw new Error(message); 6 + }
+13
resources/js/utils/user.ts
··· 1 + // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 + // See the LICENCE file in the repository root for full licence text. 3 + 4 + import UserJson from 'interfaces/user-json'; 5 + import { route } from 'laroute'; 6 + 7 + export function apiLookupUsers(idsOrUsernames: (string | null | undefined)[]) { 8 + return $.ajax(route('users.lookup-users'), { 9 + data: { ids: idsOrUsernames }, 10 + dataType: 'json', 11 + type: 'POST', 12 + }) as JQuery.jqXHR<{ users: UserJson[] }>; 13 + }
+1
resources/lang/ar/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'الصورة الشخصية', 13 + 'reset' => '', 13 14 'rules' => 'يرجى التأكد من ان صورتك تلتزم بـ:link<br/>هذا يعني انه يجب ان تكون <strong>مناسبة لجميع الأعمار</strong>. أي بلا تعري أو الفاظ نابية أو محتوى عنيف.', 14 15 'rules_link' => 'قوانين المجتمع', 15 16 ],
+1
resources/lang/ar/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'تَمهل, ألعب أكثر.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/ar/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'إخفاء المُدخلات المحكوم عليها', 18 19 'nav_title' => 'تحكيم', 19 20 'no_current_vote' => 'لم تصوت بعد.',
+1
resources/lang/ar/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+2 -1
resources/lang/be/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Аватар', 13 - 'rules' => 'Калі ласка, упэўніцеся, што ваш аватар прытрымліваецца :link.<br/>Гэта значыць, што ён павінен <strong>падыходзіць для любога ўзросту</strong>. То-бок: ніякай галізны, лаянкі або задзірлівага змесціва.', 13 + 'reset' => 'скінуць', 14 + 'rules' => 'Калі ласка, упэўніцеся, што ваш аватар прытрымліваецца :link.<br/>Гэта значыць, што ён павінен<strong>падыходзіць для любога ўзросту</strong>, то-бок: ніякай галізны, лаянкі або задзірлівага змесціва.', 14 15 'rules_link' => 'правіл супольнасці', 15 16 ], 16 17
+3 -3
resources/lang/be/artist.php
··· 46 46 '_' => 'пошук трэкаў', 47 47 48 48 'exclusive_only' => [ 49 - 'all' => '', 50 - 'exclusive_only' => '', 49 + 'all' => 'Усе', 50 + 'exclusive_only' => 'osu! арыгінальны', 51 51 ], 52 52 53 53 'form' => [ ··· 57 57 'bpm_gte' => 'BPM Мінімум', 58 58 'bpm_lte' => 'BPM Максімум', 59 59 'empty' => 'Не знойдзена трэкаў, супадаючых з гэтымі крытэрыямі пошука.', 60 - 'exclusive_only' => '', 60 + 'exclusive_only' => 'Тып', 61 61 'genre' => 'Жанр', 62 62 'genre_all' => 'Усё', 63 63 'length_gte' => 'Мінімальная даўжыня',
+3 -3
resources/lang/be/authorization.php
··· 81 81 ], 82 82 83 83 'contest' => [ 84 - 'judging_not_active' => '', 84 + 'judging_not_active' => 'Ацэньванне гэтага спаборніцтва неактыўна.', 85 85 'voting_over' => 'Немагчыма змяніць голас пасля сканчэння перыяду галасавання.', 86 86 87 87 'entry' => [ ··· 173 173 'score' => [ 174 174 'pin' => [ 175 175 'disabled_type' => "Немагчыма замацаваць гэты тып выніку", 176 - 'failed' => "", 176 + 'failed' => "Нельга замацаваць гэты вынік.", 177 177 'not_owner' => 'Толькі ўладальнік выніку можа яго замацаваць.', 178 178 'too_many' => 'Замацавана вельмі шмат вынікаў.', 179 179 ], ··· 188 188 ], 189 189 ], 190 190 'update_email' => [ 191 - 'locked' => '', 191 + 'locked' => 'адрас электроннай пошты заблакаваны', 192 192 ], 193 193 ], 194 194 ];
+12 -12
resources/lang/be/beatmaps.php
··· 25 25 'message_placeholder_silenced' => "Нельга размясціць дыскусію ў адключаным рэжыме.", 26 26 'message_type_select' => 'Выбраць тып каментарыя', 27 27 'reply_notice' => 'Каб адказаць, націсніце «Enter».', 28 - 'reply_resolve_notice' => '', 28 + 'reply_resolve_notice' => 'Націсніце enter для адказу. Націсніце ctrl+enter для адказу і рашэння праблемы.', 29 29 'reply_placeholder' => 'Напішыце свой адказ тут', 30 30 'require-login' => 'Увайдзіце, каб апублікаваць або адказаць', 31 31 'resolved' => 'Вырашана', 32 32 'restore' => 'аднавіць', 33 33 'show_deleted' => 'Паказ выдаленыя', 34 34 'title' => 'Абмеркаванні', 35 - 'unresolved_count' => '', 35 + 'unresolved_count' => ':count_delimited невырашаная праблема|:count_delimited невырашаных праблем', 36 36 37 37 'collapse' => [ 38 38 'all-collapse' => 'Згарнуць усё', ··· 81 81 ], 82 82 83 83 'message_type_title' => [ 84 - 'disqualify' => '', 85 - 'hype' => '', 84 + 'disqualify' => 'Адправіць дыскваліфікацыю', 85 + 'hype' => 'Адправіць хайп!', 86 86 'mapper_note' => '', 87 - 'nomination_reset' => '', 88 - 'praise' => '', 89 - 'problem' => '', 90 - 'problem_warning' => '', 91 - 'review' => '', 92 - 'suggestion' => '', 87 + 'nomination_reset' => 'Выдаліць усе намінацыі ', 88 + 'praise' => 'Адправіць пахвалу', 89 + 'problem' => 'Адправіць праблему', 90 + 'problem_warning' => 'Адправіць праблему', 91 + 'review' => 'Адправіць водгук', 92 + 'suggestion' => 'Адправіць прапанову', 93 93 ], 94 94 95 95 'mode' => [ ··· 216 216 'rank_estimate' => [ 217 217 '_' => 'Гэтая карта cможа маць рэйтынг :date, калі праблем не знойдзена. Гэта #:position у :queue.', 218 218 'unresolved_problems' => '', 219 - 'problems' => '', 219 + 'problems' => 'гэтыя праблемы', 220 220 'on' => ':date', 221 221 'queue' => 'чаргу ў рэйтынг', 222 222 'soon' => 'хутка', ··· 285 285 'taiko' => '', 286 286 'fruits' => '', 287 287 'mania' => '', 288 - 'undefined' => '', 288 + 'undefined' => 'не зададзены', 289 289 ], 290 290 'status' => [ 291 291 'any' => 'Усе',
+1
resources/lang/be/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Запавольвайце, гуляйце больш.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1 -1
resources/lang/be/common.php
··· 39 39 'pin' => 'замацаваць', 40 40 'post' => 'Размясціць', 41 41 'read_more' => 'чытаць далей', 42 - 'refresh' => '', 42 + 'refresh' => 'Абнавіць', 43 43 'reply' => 'Адказаць', 44 44 'reply_reopen' => 'Адказаць і пераадкрыць', 45 45 'reply_resolve' => 'Адказаць і вырашыць',
+3 -2
resources/lang/be/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 - 'no_current_vote' => '', 20 + 'no_current_vote' => 'вы яшчэ не прагаласавалі.', 20 21 'update' => 'абнавіць', 21 22 'validation' => [ 22 23 'missing_score' => 'адсутны вынік', ··· 27 28 28 29 'judge_results' => [ 29 30 '_' => '', 30 - 'creator' => '', 31 + 'creator' => 'аўтар', 31 32 'score' => 'Вынік', 32 33 'total_score' => '', 33 34 ],
+1
resources/lang/be/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/bg/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Аватар', 13 + 'reset' => '', 13 14 'rules' => 'Моля, уверете се че вашият аватар се придържа към :link.<br/>Това означава, че задължително трябва да бъде <strong>подходящ за всички възрасти</strong>. т.е. няма голота, ругатни или внушаващо съдържание.', 14 15 'rules_link' => 'обществените правила', 15 16 ],
+1
resources/lang/bg/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Забави малко, играй повече.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/bg/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'скрий гласуваните', 18 19 'nav_title' => 'жури', 19 20 'no_current_vote' => 'не сте гласували все още.',
+1
resources/lang/bg/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/ca/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => '', 13 14 'rules' => 'Si us plau asseguri\'s que el seu avatar s\'adhereix a :link. <br/> Això vol dir que ha de ser <strong>adequat per a totes les edats</strong>. És a dir, sense nuesa, blasfèmia o contingut suggestiu.', 14 15 'rules_link' => 'regles de la comunitat', 15 16 ],
+1
resources/lang/ca/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'A poc a poc, juga més.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/ca/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'amagar entrades avaluades', 18 19 'nav_title' => 'avaluar', 19 20 'no_current_vote' => 'encara no has votat.',
+1
resources/lang/ca/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/cs/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'resetovat', 13 14 'rules' => 'Ujisti se prosím, že tvůj avatar dodržuje :link.<br/>To znamená, že musí být <strong>vhodný pro všechny věkové kategorie</strong>. Tj. žádná nahota, žádný urážlivý či sugestivní obsah.', 14 15 'rules_link' => 'kritéria vizuálního obsahu', 15 16 ],
+1 -1
resources/lang/cs/beatmaps.php
··· 32 32 'restore' => 'obnovit', 33 33 'show_deleted' => 'Zobrazit smazané', 34 34 'title' => 'Diskuze', 35 - 'unresolved_count' => ':count_delimited nevyřešených problémů', 35 + 'unresolved_count' => ':count_delimited nevyřešený problém|:count_delimited nevyřešené problémy|:count_delimited nevyřešených problémů', 36 36 37 37 'collapse' => [ 38 38 'all-collapse' => 'Skrýt vše',
+1
resources/lang/cs/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Zpomal, více hraj.', 20 + 'no_mirrors' => 'Nejsou dostupné žádné servery pro stahování.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/cs/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'komentáře', 17 18 'hide_judged' => 'skrýt posuzované položky', 18 19 'nav_title' => 'soudce', 19 20 'no_current_vote' => 'ještě jsi nehlasoval.',
+12 -11
resources/lang/cs/users.php
··· 197 197 'to_1' => 'Zobrazit záhlaví', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Dnů v řadě', 201 + 'daily_streak_best' => 'Nejvíce dnů v řadě', 202 + 'daily_streak_current' => 'Aktuálně dnů v řadě', 203 + 'playcount' => '', 204 + 'title' => 'Denní\nvýzva', 205 + 'top_10p_placements' => 'Umístění v Top 10%', 206 + 'top_50p_placements' => 'Umístění v Top 50%', 207 + 'weekly' => 'Týdnů v řadě', 208 + 'weekly_streak_best' => 'Nejvíce týdnů v řadě', 209 + 'weekly_streak_current' => 'Aktuálně týdnů v řadě', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valued', 213 + 'week' => ':valuet', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/da/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Profilbillede', 13 + 'reset' => '', 13 14 'rules' => 'Vær sikker på at din avatar overholder :link.<br/>Dette betyder at den skal være <strong>passende for alle aldre</strong>. Det betyder ingen nøgenhed, skælsord eller suggestivt indhold.', 14 15 'rules_link' => 'fællesskabs-reglerne', 15 16 ],
+1
resources/lang/da/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Sæt farten ned, spil mere.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/da/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/da/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/de/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'Zurücksetzen', 13 14 'rules' => 'Bitte stelle sicher, dass sich dein Avatar an :link hält.<br/>Das heißt, er muss <strong>für alle Altersklassen geeignet</strong> sein und darf keine Nacktheit oder anstößigen Inhalte enthalten.', 14 15 'rules_link' => 'die Community-Regeln', 15 16 ],
+1
resources/lang/de/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Nur langsam, spiel mehr.', 20 + 'no_mirrors' => 'Keine Download-Server verfügbar.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/de/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'bewertete Einträge ausblenden', 18 19 'nav_title' => 'Bewerten', 19 20 'no_current_vote' => 'Du hast noch nicht abgestimmt.',
+12 -11
resources/lang/de/users.php
··· 197 197 'to_1' => 'Cover anzeigen', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Tägliche Serie', 201 + 'daily_streak_best' => 'Beste Tagesserie', 202 + 'daily_streak_current' => 'Aktuelle Tagesserie', 203 + 'playcount' => '', 204 + 'title' => 'Tägliche\nHerausforderung', 205 + 'top_10p_placements' => 'Platzierungen in den Top 10 %', 206 + 'top_50p_placements' => 'Platzierungen in den Top 50 %', 207 + 'weekly' => 'Wöchentliche Serie', 208 + 'weekly_streak_best' => 'Beste Wochenserie', 209 + 'weekly_streak_current' => 'Aktuelle Wochenserie', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':value T', 213 + 'week' => ':value W', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/el/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => '', 13 14 'rules' => 'Παρακαλώ βεβαιωθείτε ότι το avatar σας συμφωνεί με :link. <br/>Αυτό σημαίνει ότι πρέπει να είναι <strong>κατάλληλο για όλες τις ηλικές</strong>.', 14 15 'rules_link' => 'τους κανόνες κοινότητας', 15 16 ],
+1
resources/lang/el/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => '', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/el/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/el/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1 -1
resources/lang/en/accounts.php
··· 81 81 'beatmapset_disqualify' => 'receive notifications for when beatmaps of the following modes are disqualified', 82 82 'comment_reply' => 'receive notifications for replies to your comments', 83 83 'title' => 'Notifications', 84 - 'topic_auto_subscribe' => 'automatically enable notifications on new forum topics that you create', 84 + 'topic_auto_subscribe' => 'automatically enable notifications on new forum topics that you create or replied to', 85 85 86 86 'options' => [ 87 87 '_' => 'delivery options',
+1
resources/lang/en/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Slow down, play more.', 20 + 'no_mirrors' => 'No download servers available.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/en/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'comments', 17 18 'hide_judged' => 'hide judged entries', 18 19 'nav_title' => 'judge', 19 20 'no_current_vote' => 'you didn\'t vote yet.',
+7
resources/lang/en/rankings.php
··· 9 9 'title' => 'Country', 10 10 ], 11 11 12 + 'daily_challenge' => [ 13 + 'beatmap' => 'Difficulty', 14 + 'percentile_10' => '10th Percentile Score', 15 + 'percentile_50' => '50th Percentile Score', 16 + ], 17 + 12 18 'filter' => [ 13 19 'title' => 'Show', 14 20 ··· 30 36 'type' => [ 31 37 'charts' => 'spotlights (old)', 32 38 'country' => 'country', 39 + 'daily_challenge' => 'daily challenge', 33 40 'kudosu' => 'kudosu', 34 41 'multiplayer' => 'multiplayer', 35 42 'performance' => 'performance',
+1
resources/lang/en/users.php
··· 200 200 'daily' => 'Daily Streak', 201 201 'daily_streak_best' => 'Best Daily Streak', 202 202 'daily_streak_current' => 'Current Daily Streak', 203 + 'playcount' => 'Total Participation', 203 204 'title' => 'Daily\nChallenge', 204 205 'top_10p_placements' => 'Top 10% Placements', 205 206 'top_50p_placements' => 'Top 50% Placements',
+1
resources/lang/es-419/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'restablecer', 13 14 'rules' => 'Por favor, asegúrate de que tu avatar se adhiera a :link.<br/>Esto significa que debe ser <strong>adecuado para todas las edades</strong>. Es decir, sin desnudos, contenido ofensivo o sugerente.', 14 15 'rules_link' => 'las consideraciones de contenido visual', 15 16 ],
+1
resources/lang/es-419/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Más despacio, juega un poco.', 20 + 'no_mirrors' => 'No hay servidores de descarga disponibles.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/es-419/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'comentarios', 17 18 'hide_judged' => 'ocultar las inscripciones evaluadas', 18 19 'nav_title' => 'evaluar', 19 20 'no_current_vote' => 'aún no has votado.',
+12 -11
resources/lang/es-419/users.php
··· 197 197 'to_1' => 'Mostrar portada', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Racha diaria', 201 + 'daily_streak_best' => 'Mejor racha diaria', 202 + 'daily_streak_current' => 'Racha diaria actual', 203 + 'playcount' => '', 204 + 'title' => 'Desafío\ndiario', 205 + 'top_10p_placements' => 'Puestos en el top 10 %', 206 + 'top_50p_placements' => 'Puestos en el top 50 %', 207 + 'weekly' => 'Racha semanal', 208 + 'weekly_streak_best' => 'Mejor racha semanal', 209 + 'weekly_streak_current' => 'Racha semanal actual', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valued', 213 + 'week' => ':valuew', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/es/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'restablecer', 13 14 'rules' => 'Por favor, asegúrate de que tu avatar se adhiera a :link.<br/>Esto significa que debe ser <strong>adecuado para todas las edades</strong>. Es decir, sin desnudez, contenido ofensivo o sugerente.', 14 15 'rules_link' => 'las consideraciones de contenido visual', 15 16 ],
+1
resources/lang/es/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Más despacio, juega un poco.', 20 + 'no_mirrors' => 'No hay servidores de descarga disponibles.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/es/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'comentarios', 17 18 'hide_judged' => 'ocultar entradas evaluadas', 18 19 'nav_title' => 'evaluar', 19 20 'no_current_vote' => 'aún no has votado.',
+12 -11
resources/lang/es/users.php
··· 197 197 'to_1' => 'Mostrar portada', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Racha diaria', 201 + 'daily_streak_best' => 'Mejor racha diaria', 202 + 'daily_streak_current' => 'Racha diaria actual', 203 + 'playcount' => '', 204 + 'title' => 'Desafío\ndiario', 205 + 'top_10p_placements' => 'Puestos en el top 10 %', 206 + 'top_50p_placements' => 'Puestos en el top 50 %', 207 + 'weekly' => 'Racha semanal', 208 + 'weekly_streak_best' => 'Mejor racha semanal', 209 + 'weekly_streak_current' => 'Racha semanal actual', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valued', 213 + 'week' => ':valuew', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/fa-IR/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'اکس پرفایل', 13 + 'reset' => '', 13 14 'rules' => 'لطفا مطمئن شوید که تصویر نمایه شما به :link پایبند است.<br/>این بدین معنیست که باید <strong>برای تمامی سنین مناسب باشد</strong> یعنی بدون برهنگی ، فحاشی یا محتوای وسوسه انگیز.', 14 15 'rules_link' => 'قانون ها', 15 16 ],
+1
resources/lang/fa-IR/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => '', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/fa-IR/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/fa-IR/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/fi/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'nollaa', 13 14 'rules' => 'Pidäthän huolen, että profiilikuvasi noudattaa :link.<br/>Tämä tarkoittaa sitä, että sen on <strong>sovittava kaikenikäisille</strong>, eli ei alastomuutta tai muita hävyttömyyksiä.', 14 15 'rules_link' => 'yhteisön sääntöjä', 15 16 ],
+2 -2
resources/lang/fi/beatmaps.php
··· 25 25 'message_placeholder_silenced' => "Keskusteluun ei voi osallistua mykistettynä.", 26 26 'message_type_select' => 'Valitse kommentin tyyppi', 27 27 'reply_notice' => 'Vastaa painamalla enter-näppäintä.', 28 - 'reply_resolve_notice' => '', 28 + 'reply_resolve_notice' => 'Paina enteriä vastataksesi. Paina ctrl+enteriä vastataksesi ja ratkaistaksesi.', 29 29 'reply_placeholder' => 'Kirjoita vastauksesi tähän', 30 30 'require-login' => 'Kirjaudu sisään lähettääksesi viestejä tai vastauksia', 31 31 'resolved' => 'Ratkaistu', 32 32 'restore' => 'palauta', 33 33 'show_deleted' => 'Näytä poistetut', 34 34 'title' => 'Keskustelut', 35 - 'unresolved_count' => '', 35 + 'unresolved_count' => ':count_delimited ratkaisematon ongelma|:count_delimited ratkaisematonta ongelmaa', 36 36 37 37 'collapse' => [ 38 38 'all-collapse' => 'Sulje kaikki',
+1
resources/lang/fi/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Hidasta vähän, pelaa enemmän.', 20 + 'no_mirrors' => 'Latauspalvelimia ei saatavilla.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/fi/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'kommentit', 17 18 'hide_judged' => 'piilota arvioidut tuotokset', 18 19 'nav_title' => 'arvioi', 19 20 'no_current_vote' => 'et äänestänyt vielä.',
+1 -1
resources/lang/fi/errors.php
··· 29 29 'generic' => 'Ostoksesi valmistelussa tapahtui virhe.', 30 30 ], 31 31 'scores' => [ 32 - 'invalid_id' => '', 32 + 'invalid_id' => 'Virheellinen tulostunnus.', 33 33 ], 34 34 'search' => [ 35 35 'default' => 'Tuloksia ei saatu, yritä myöhemmin uudelleen.',
+1 -1
resources/lang/fi/layout.php
··· 199 199 'legacy_score_only_toggle_tooltip' => 'Lazer-tila näyttää uuden pisteytysalgoritmin avulla saadut tulokset', 200 200 'logout' => 'Kirjaudu ulos', 201 201 'profile' => 'Oma profiili', 202 - 'scoring_mode_toggle' => '', 202 + 'scoring_mode_toggle' => 'Klassinen pisteytys', 203 203 'scoring_mode_toggle_tooltip' => '', 204 204 ], 205 205 ],
+1 -1
resources/lang/fi/oauth.php
··· 7 7 'cancel' => 'Peruuta', 8 8 9 9 'authorise' => [ 10 - 'app_owner' => '', 10 + 'app_owner' => 'sovellus käyttäjältä: :owner', 11 11 'request' => 'pyytää lupaa yhdistää tilillesi.', 12 12 'scopes_title' => 'Tämä sovellus voi:', 13 13 'title' => 'Yhdistyspyyntö',
+17 -16
resources/lang/fi/users.php
··· 197 197 'to_1' => 'Näytä kansikuva', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Päivittäinen Putki', 201 + 'daily_streak_best' => 'Paras Päivittäinen Putki', 202 + 'daily_streak_current' => 'Nykyinen Päivittäinen Putki', 203 + 'playcount' => '', 204 + 'title' => 'Päivittäinen\nHaaste', 205 + 'top_10p_placements' => 'Top 10% -Sijoitukset', 206 + 'top_50p_placements' => 'Top 50% -Sijoitukset', 207 + 'weekly' => 'Viikoittainen putki', 208 + 'weekly_streak_best' => 'Paras Viikoittainen Putki', 209 + 'weekly_streak_current' => 'Nykyinen Viikoittainen Putki', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valued', 213 + 'week' => ':valuew', 213 214 ], 214 215 ], 215 216 'edit' => [ ··· 217 218 'button' => 'Muuta profiilin kansikuvaa', 218 219 'defaults_info' => 'Lisää kansikuvavaihtoehtoja tulee olemaan saatavilla tulevaisuudessa', 219 220 'holdover_remove_confirm' => "Edellinen valitsemasi kansikuva ei ole enää käytettävissä. Et voi valita sitä uudelleen, jos vaihdat toiseen kansikuvaan. Jatketaanko?", 220 - 'title' => '', 221 + 'title' => 'Kansi', 221 222 222 223 'upload' => [ 223 224 'broken_file' => 'Kuvan käsittely epäonnistui. Varmista lähetetty kuva ja kokeile uudestaan.', ··· 241 242 ], 242 243 243 244 'hue' => [ 244 - 'reset_no_supporter' => '', 245 - 'title' => '', 245 + 'reset_no_supporter' => 'Palauta oletusväri? Tukijamerkki vaaditaan värin vaihtamiseen.', 246 + 'title' => 'Väri', 246 247 247 248 'supporter' => [ 248 - '_' => '', 249 - 'link' => '', 249 + '_' => 'Muokatut väriteemat saatavilla vain :link', 250 + 'link' => 'osu!tukijat', 250 251 ], 251 252 ], 252 253 ],
+1
resources/lang/fil/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => '', 13 14 'rules' => 'Pakitiyak na ang iyong avatar ay sumusunod sa :link.<br/>Nangangahulugan ito na dapat ay <strong>angkop para sa lahat ng edad</strong>. i.e. walang kahubaran, kabastusan, o nagpapahiwatig na nilalaman.', 14 15 'rules_link' => 'ang patakaran ng komunidad 15 16
+1
resources/lang/fil/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Hinay lang, maglaro ka muna.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/fil/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'itago ang hinuhusgahang mga entry', 18 19 'nav_title' => 'maghusga', 19 20 'no_current_vote' => 'hindi ka pa nakaboto.',
+1
resources/lang/fil/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/fr/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'réinitialiser', 13 14 'rules' => 'Veuillez vous assurer que votre avatar correspond aux :link.<br/>Cela signifie qu\'il doit être <strong>adapté à tous les âges</strong>. C\'est-à-dire pas de nudité, de profanation ou de contenu suggestif.', 14 15 'rules_link' => 'Considérations relatives au contenu visuel', 15 16 ],
+1 -1
resources/lang/fr/beatmaps.php
··· 32 32 'restore' => 'restaurer', 33 33 'show_deleted' => 'Afficher le contenu supprimé', 34 34 'title' => 'Discussions', 35 - 'unresolved_count' => ':count_delimited problèmes non résolus', 35 + 'unresolved_count' => ':count_delimited problème non résolu|:count_delimited problèmes non résolus', 36 36 37 37 'collapse' => [ 38 38 'all-collapse' => 'Tout réduire',
+1
resources/lang/fr/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Ralentissez, jouez plus.', 20 + 'no_mirrors' => 'Aucun serveur de téléchargements disponible.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/fr/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'commentaires', 17 18 'hide_judged' => 'masquer les entrées jugées', 18 19 'nav_title' => 'juger', 19 20 'no_current_vote' => 'vous n\'avez pas encore voté.',
+12 -11
resources/lang/fr/users.php
··· 197 197 'to_1' => 'Afficher la bannière', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Série quotidienne', 201 + 'daily_streak_best' => 'Meilleure série quotidienne', 202 + 'daily_streak_current' => 'Série quotidienne actuelle', 203 + 'playcount' => '', 204 + 'title' => 'Défi\ndu Jour', 205 + 'top_10p_placements' => 'Placements dans le Top 10%', 206 + 'top_50p_placements' => 'Placements dans le Top 50%', 207 + 'weekly' => 'Série hebdomadaire', 208 + 'weekly_streak_best' => 'Meilleure série hebdomadaire', 209 + 'weekly_streak_current' => 'Série hebdomadaire actuelle', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':value j', 213 + 'week' => ':value sem', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/he/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'תמונת פרופיל', 13 + 'reset' => '', 13 14 'rules' => 'אנא וודא שהתמונה שלך קשורה ל :link<br/>זה אומר שזה צריך להיות <strong> מתאים לכל הגילים</strong> ובלי תוכן לא נעות, שפה לא נעותה או תוכן מרמז.', 14 15 'rules_link' => 'חוקי הקהילה', 15 16 ],
+1
resources/lang/he/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => '', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/he/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/he/users.php
··· 201 201 'daily' => '', 202 202 'daily_streak_best' => '', 203 203 'daily_streak_current' => '', 204 + 'playcount' => '', 204 205 'title' => '', 205 206 'top_10p_placements' => '', 206 207 'top_50p_placements' => '',
+1
resources/lang/hr-HR/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => '', 13 14 'rules' => 'Provjeri da li je tvoj avatar u skladu s :link.<br/>To znači da mora biti <strong>prikladno za sve uzraste</strong>. tj. bez golotinje, vulgarnosti ili sugestivnog sadržaja.', 14 15 'rules_link' => 'pravilima zajednice', 15 16 ],
+1
resources/lang/hr-HR/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Uspori, igraj više.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/hr-HR/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/hr-HR/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/hu/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatár', 13 + 'reset' => '', 13 14 'rules' => 'Kérjük, ellenőrizze, hogy az avatár illeszkedik-e ehhez :link.<br/>Ez azt jelenti, hogy <strong>minden korosztály számára alkalmasnak kell lennie</strong>. Vagyis nincs meztelenség, mások számára elfogadhatatlan vagy szuggesztív tartalom.', 14 15 'rules_link' => 'a közösségi szabályok', 15 16 ],
+1
resources/lang/hu/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Lassíts le, játssz többet.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/hu/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'elrejteni az elbírált bejegyzéseket', 18 19 'nav_title' => 'bíró', 19 20 'no_current_vote' => 'még nem szavaztál.',
+1
resources/lang/hu/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+4 -3
resources/lang/id/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'atur ulang', 13 14 'rules' => 'Pastikan avatarmu tunduk pada :link yang berlaku.<br/>Dengan kata lain, avatarmu harus <strong>cocok untuk segala usia</strong> tanpa mengandung unsur apa pun yang tidak dibenarkan seperti cacian, hinaan, atau hal yang bersifat sugestif.', 14 - 'rules_link' => 'peraturan komunitas', 15 + 'rules_link' => 'Pertimbangan konten visual', 15 16 ], 16 17 17 18 'email' => [ ··· 102 103 ], 103 104 104 105 'options' => [ 105 - 'beatmapset_show_nsfw' => 'nonaktifkan peringatan untuk beatmap berkonten eksplisit', 106 + 'beatmapset_show_nsfw' => 'sembunyikan peringatan untuk konten eksplisit pada beatmap', 106 107 'beatmapset_title_show_original' => 'tampilkan metadata beatmap dalam bahasa aslinya', 107 108 'title' => 'Pengaturan', 108 109 ··· 131 132 'security' => [ 132 133 'current_session' => 'saat ini', 133 134 'end_session' => 'Akhiri Sesi', 134 - 'end_session_confirmation' => 'Tindakan ini akan secara otomatis mengakhiri sesimu pada perangkat yang bersangkutan. Apakah kamu yakin?', 135 + 'end_session_confirmation' => 'Tindakan ini akan mengakhiri sesimu pada perangkat yang bersangkutan dengan segera. Apakah kamu yakin?', 135 136 'last_active' => 'Terakhir aktif:', 136 137 'title' => 'Keamanan', 137 138 'web_sessions' => 'sesi web',
+1 -1
resources/lang/id/api.php
··· 8 8 'chat' => [ 9 9 'empty' => 'Tidak dapat mengirim pesan kosong.', 10 10 'limit_exceeded' => 'Anda mengirim pesan terlalu cepat, harap tunggu sebentar sebelum mencoba lagi.', 11 - 'too_long' => 'Pesan yang ingin dikirim terlalu panjang.', 11 + 'too_long' => 'Pesan yang ingin kamu kirim terlalu panjang.', 12 12 ], 13 13 ], 14 14
+7 -7
resources/lang/id/authorization.php
··· 27 27 ], 28 28 29 29 'store' => [ 30 - 'mapper_note_wrong_user' => 'Hanya pembuat beatmap atau anggota BN/NAT yang dapat membubuhkan catatan pada halaman diskusi beatmap.', 30 + 'mapper_note_wrong_user' => 'Hanya pemilik beatmap atau anggota BN/NAT yang dapat mengirim catatan.', 31 31 ], 32 32 33 33 'vote' => [ ··· 62 62 63 63 'chat' => [ 64 64 'annnonce_only' => 'Kanal ini hanya dikhususkan untuk pengumuman.', 65 - 'blocked' => 'Pesan tidak dapat dikirim kepada pengguna yang kamu blokir atau memblokir dirimu.', 65 + 'blocked' => 'Kamu tidak dapat mengirim pesan kepada pengguna yang kamu blokir atau memblokir dirimu.', 66 66 'friends_only' => 'Pengguna ini memblokir pesan dari pengguna lain yang tidak berada dalam daftar temannya.', 67 67 'moderated' => 'Kanal percakapan ini sedang dimoderasi.', 68 68 'no_access' => 'Kamu tidak memiliki akses ke kanal percakapan ini.', 69 69 'receive_friends_only' => 'Pengguna ini mungkin tidak akan dapat membalas karena kamu hanya menerima pesan dari pengguna lain yang berada dalam daftar temanmu.', 70 - 'restricted' => 'Kamu tidak dapat mengirim pesan pada saat akunmu sedang di-silence, di-restrict, atau di-ban.', 71 - 'silenced' => 'Kamu tidak dapat mengirim pesan pada saat akunmu sedang di-silence, di-restrict, atau di-ban.', 70 + 'restricted' => 'Kamu tidak dapat mengirim pesan pada saat kamu sedang di-silence, di-restrict, atau di-ban.', 71 + 'silenced' => 'Kamu tidak dapat mengirim pesan pada saat kamu sedang di-silence, di-restrict, atau di-ban.', 72 72 ], 73 73 74 74 'comment' => [ ··· 105 105 106 106 'edit' => [ 107 107 'deleted' => 'Postingan yang telah dihapus tidak dapat disunting.', 108 - 'locked' => 'Penyuntingan pada postingan ini telah dikunci.', 108 + 'locked' => 'Postingan ini telah dikunci dari penyuntingan lebih lanjut.', 109 109 'no_forum_access' => 'Kamu tidak memiliki akses ke forum yang dituju.', 110 110 'not_owner' => 'Postingan ini hanya dapat disunting oleh pengirimnya.', 111 111 'topic_locked' => 'Postingan pada topik yang telah dikunci tidak dapat disunting.', 112 112 ], 113 113 114 114 'store' => [ 115 - 'play_more' => 'Kamu harus terlebih dahulu bermain sebelum kamu dapat membuat postingan pada forum! Apabila kamu mengalami masalah saat bermain, silakan kunjungi forum Help & Support.', 116 - 'too_many_help_posts' => "Kamu perlu untuk bermain lebih banyak sebelum kamu dapat membuat postingan tambahan. Apabila kamu masih menemui masalah dalam bermain, silakan kirim email ke support@ppy.sh", // FIXME: unhardcode email address. 115 + 'play_more' => 'Bermainlah terlebih dahulu sebelum membuat postingan pada forum! Apabila kamu mengalami masalah saat bermain, silakan kunjungi forum Help & Support.', 116 + 'too_many_help_posts' => "Kamu perlu untuk bermain lebih banyak sebelum kamu dapat membuat postingan tambahan. Apabila kamu masih menemui masalah saat bermain, silakan kirim email ke support@ppy.sh", // FIXME: unhardcode email address. 117 117 ], 118 118 ], 119 119
+1 -1
resources/lang/id/beatmap_discussions.php
··· 27 27 'mode' => 'Mode beatmap', 28 28 'only_unresolved' => 'Hanya tampilkan topik diskusi yang belum terjawab', 29 29 'show_review_embeds' => 'Tampilkan pos ulasan', 30 - 'types' => 'Tipe pesan', 30 + 'types' => 'Jenis pesan', 31 31 'username' => 'Nama Pengguna', 32 32 33 33 'beatmapset_status' => [
+8 -8
resources/lang/id/beatmaps.php
··· 27 27 'reply_notice' => 'Tekan enter untuk membalas.', 28 28 'reply_resolve_notice' => 'Tekan enter untuk membalas. Tekan ctrl+enter untuk membalas dan menutup topik diskusi.', 29 29 'reply_placeholder' => 'Ketik balasanmu di sini', 30 - 'require-login' => 'Silakan masuk untuk membuka topik diskusi baru atau membalas', 30 + 'require-login' => 'Silakan masuk untuk mengirim atau membalas postingan', 31 31 'resolved' => 'Terjawab', 32 32 'restore' => 'pulihkan', 33 33 'show_deleted' => 'Tampilkan yang telah dihapus', ··· 62 62 ], 63 63 64 64 'message_placeholder' => [ 65 - 'general' => 'Ketik di sini untuk membuka topik diskusi baru pada Umum (:version)', 66 - 'generalAll' => 'Ketik di sini untuk membuka topik diskusi baru pada Umum (Seluruh tingkat kesulitan)', 67 - 'review' => 'Ketik di sini untuk menulis kajian', 68 - 'timeline' => 'Ketik di sini untuk membuka topik diskusi baru pada Linimasa (:version)', 65 + 'general' => 'Ketik di sini untuk mengirimkan topik diskusi baru pada Umum (:version)', 66 + 'generalAll' => 'Ketik di sini untuk mengirimkan topik diskusi baru pada Umum (Seluruh tingkat kesulitan)', 67 + 'review' => 'Ketik di sini untuk mengirimkan kajian', 68 + 'timeline' => 'Ketik di sini untuk mengirimkan topik diskusi baru pada Linimasa (:version)', 69 69 ], 70 70 71 71 'message_type' => [ ··· 174 174 'hype' => [ 175 175 'button' => 'Berikan Hype!', 176 176 'button_done' => 'Telah di-Hype!', 177 - 'confirm' => "Apakah kamu yakin? Dengan ini, kamu akan memberikan 1 hype kepada beatmap ini dari :n hype yang kamu miliki saat ini. Tindakan ini tidak dapat diurungkan.", 177 + 'confirm' => "Apakah kamu yakin? Dengan ini, kamu akan memberikan 1 hype kepada beatmap ini dari :n hype yang kamu miliki saat ini. Tindakan ini tidak dapat dibatalkan.", 178 178 'explanation' => 'Berikan hype-mu untuk membawa beatmap ini lebih dekat menuju Ranked!', 179 179 'explanation_guest' => 'Masuk dan berikan hype kepada beatmap ini agar beatmap ini dapat segera dinominasikan dan di-rank!', 180 180 'new_time' => "Kamu akan memperoleh lebih banyak hype :new_time.", ··· 192 192 'already_nominated' => 'Kamu telah menominasikan beatmap ini.', 193 193 'cannot_nominate' => 'Kamu tidak dapat memberikan nominasi untuk mode permainan ini.', 194 194 'delete' => 'Hapus', 195 - 'delete_own_confirm' => 'Apakah kamu yakin? Beatmap yang dipilih akan dihapus dan kamu akan dialihkan kembali ke halaman profilmu.', 196 - 'delete_other_confirm' => 'Apakah kamu yakin? Beatmap yang dipilih akan dihapus dan kamu akan dialihkan kembali ke halaman profil pengguna yang bersangkutan.', 195 + 'delete_own_confirm' => 'Apakah kamu yakin? Beatmap ini akan dihapus dan kamu akan dialihkan kembali ke halaman profilmu.', 196 + 'delete_other_confirm' => 'Apakah kamu yakin? Beatmap ini akan dihapus dan kamu akan dialihkan kembali ke halaman profil pengguna yang bersangkutan.', 197 197 'disqualification_prompt' => 'Alasan diskualifikasi?', 198 198 'disqualified_at' => 'Didiskualifikasi pada :time_ago (:reason).', 199 199 'disqualified_no_reason' => 'tidak ada alasan yang diberikan',
+1 -1
resources/lang/id/beatmapset_events.php
··· 65 65 'discussion_post_restore' => 'Pemulihan pesan balasan', 66 66 'discussion_restore' => 'Pemulihan topik diskusi', 67 67 'disqualify' => 'Diskualifikasi', 68 - 'genre_edit' => 'Pengaturan aliran', 68 + 'genre_edit' => 'Penyuntingan aliran', 69 69 'issue_reopen' => 'Pembukaan ulang topik diskusi', 70 70 'issue_resolve' => 'Penutupan topik diskusi', 71 71 'kudosu_allow' => 'Pemberian izin kudosu',
+4 -3
resources/lang/id/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Jangan terlalu bernafsu dalam mengunduh. Mainkan beatmap yang telah kamu miliki terlebih dahulu.', 20 + 'no_mirrors' => 'Tidak ada server unduhan yang tersedia.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [ 23 - 'label' => 'Featured artist', 24 + 'label' => 'Featured Artist', 24 25 ], 25 26 26 27 'index' => [ ··· 52 53 'dialog' => [ 53 54 'confirmation' => 'Apakah kamu yakin untuk menominasikan beatmap ini?', 54 55 'header' => 'Nominasikan Beatmap', 55 - 'hybrid_warning' => 'catatan: kamu hanya dapat memberikan satu nominasi, sehingga pastikan kamu memberikan nominasi pada mode permainan yang memang kamu kehendaki', 56 + 'hybrid_warning' => 'catatan: kamu hanya dapat memberikan nominasi satu kali, sehingga pastikan kamu memberikan nominasi pada mode permainan yang memang kamu kehendaki', 56 57 'current_main_ruleset' => 'Ruleset utama saat ini: :ruleset', 57 58 'which_modes' => 'Mode permainan mana yang ingin dinominasikan?', 58 59 ], ··· 81 82 'logged-out' => 'kamu harus masuk untuk mengunduh beatmap!', 82 83 'mapped_by' => 'dibuat oleh :mapper', 83 84 'mapped_by_guest' => 'guest difficulty oleh :mapper', 84 - 'unfavourite' => 'hapus beatmap ini dari daftar beatmap favorit', 85 + 'unfavourite' => 'hapus beatmap ini dari daftar favorit', 85 86 'updated_timeago' => 'terakhir diperbarui :timeago', 86 87 87 88 'download' => [
+1 -1
resources/lang/id/chat.php
··· 58 58 ], 59 59 60 60 'no-conversations' => [ 61 - 'howto' => "Mulailah percakapan baru melalui tombol yang tertera pada laman profil atau kartu pop-up pengguna.", 61 + 'howto' => "Mulailah percakapan baru dari halaman profil atau kartu pop-up pengguna.", 62 62 'lazer' => 'Kanal percakapan publik yang kamu buka melalui <a href=":link">osu!lazer</a> juga akan terlihat di sini.', 63 63 'title' => 'belum ada percakapan', 64 64 ],
+1
resources/lang/id/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'komentar', 17 18 'hide_judged' => 'sembunyikan entri yang telah dinilai', 18 19 'nav_title' => 'juri', 19 20 'no_current_vote' => 'kamu belum memberikan suaramu.',
+1 -1
resources/lang/id/errors.php
··· 34 34 'search' => [ 35 35 'default' => 'Tidak ada hasil pencarian yang dapat diperoleh. Silakan coba lagi nanti.', 36 36 'invalid_cursor_exception' => 'Parameter kursor yang ditentukan tidak valid.', 37 - 'operation_timeout_exception' => 'Aktivitas pencarian saat ini sedang lebih sibuk dari biasanya. Mohon coba lagi nanti.', 37 + 'operation_timeout_exception' => 'Aktivitas pencarian saat ini sedang lebih sibuk dari biasanya. Silakan coba lagi nanti.', 38 38 ], 39 39 'user_report' => [ 40 40 'recently_reported' => "Kamu telah melaporkan hal ini baru-baru ini.",
+5 -5
resources/lang/id/forum.php
··· 85 85 'latest_post' => ':when oleh :user', 86 86 'latest_reply_by' => 'balasan terbaru oleh :user', 87 87 'new_topic' => 'Topik baru', 88 - 'new_topic_login' => 'Silakan masuk untuk membuat topik baru', 88 + 'new_topic_login' => 'Masuk untuk mengirimkan topik baru', 89 89 'post_reply' => 'Post', 90 90 'reply_box_placeholder' => 'Ketik di sini untuk membalas', 91 91 'reply_title_prefix' => 'Ttg', ··· 143 143 'announcement' => 'topik disematkan dan ditandai sebagai pengumuman', 144 144 'edit_topic' => 'menjadi :title', 145 145 'fork' => 'dari :topic', 146 - 'pin' => 'topik yang disematkan', 147 - 'post_operation' => 'di-post oleh :username', 146 + 'pin' => 'topik disematkan', 147 + 'post_operation' => 'diposting oleh :username', 148 148 'remove_tag' => 'tag ":tag" dihapus', 149 149 'source_forum_operation' => 'dari :forum', 150 - 'unpin' => 'topik yang tidak disematkan', 150 + 'unpin' => 'sematan topik dilepas', 151 151 ], 152 152 153 153 'no_results' => 'tidak ada rekaman aktivitas yang tercatat...', ··· 311 311 'moderate_pin' => [ 312 312 'to_0' => 'Lepas sematan topik', 313 313 'to_0_confirm' => 'Lepas sematan topik?', 314 - 'to_0_done' => 'Sematan topik telah dilepaskan', 314 + 'to_0_done' => 'Sematan topik dilepas', 315 315 'to_1' => 'Sematkan topik', 316 316 'to_1_confirm' => 'Sematkan topik?', 317 317 'to_1_done' => 'Topik telah disematkan',
+1 -1
resources/lang/id/home.php
··· 103 103 'steps' => [ 104 104 'register' => [ 105 105 'title' => 'buat akunnya', 106 - 'description' => 'ikuti petunjuk yang muncul pada awal permainan untuk masuk atau membuat akun baru', 106 + 'description' => 'ikuti petunjuk yang tertera pada saat memulai permainan untuk masuk atau membuat akun baru', 107 107 ], 108 108 'download' => [ 109 109 'title' => 'unduh permainannya',
+1 -1
resources/lang/id/store.php
··· 83 83 ], 84 84 'processing' => [ 85 85 'title' => 'Pembayaranmu belum terkonfirmasi!', 86 - 'line_1' => 'Apabila kamu telah membayar, ada kemungkinan sistem kami masih menunggu konfirmasi atas pembayaranmu. Silakan muat ulang halaman ini dalam beberapa menit!', 86 + 'line_1' => 'Apabila kamu telah membayar, kami mungkin masih menunggu konfirmasi atas pembayaranmu. Silakan muat ulang halaman ini dalam beberapa menit!', 87 87 'line_2' => [ 88 88 '_' => 'Apabila kamu menemui masalah dalam proses checkout, :link', 89 89 'link_text' => 'klik di sini untuk melanjutkan proses checkout',
+1 -1
resources/lang/id/tournament.php
··· 25 25 'show' => [ 26 26 'banner' => 'Dukung Tim Anda', 27 27 'entered' => 'Kamu telah terdaftar pada turnamen ini.<br><br>Mohon diperhatikan bahwa hal ini <b>tidak</b> berarti bahwa kamu telah ditempatkan ke dalam tim tertentu. <br><br>Kami akan mengirimkanmu instruksi lebih lanjut melalui email sebelum turnamen dimulai, jadi pastikan alamat email yang terhubung dengan akun osu! milikmu dapat dihubungi!', 28 - 'info_page' => 'Laman Informasi', 28 + 'info_page' => 'Halaman Informasi', 29 29 'login_to_register' => 'Harap :login untuk melihat rincian pendaftaran!', 30 30 'not_yet_entered' => 'Anda tidak terdaftar pada turnamen ini.', 31 31 'rank_too_low' => 'Maaf, kamu tidak berada dalam rentang peringkat yang dipersyaratkan oleh turnamen ini!',
+2 -2
resources/lang/id/user_cover_presets.php
··· 31 31 ], 32 32 ], 33 33 'store' => [ 34 - 'failed' => 'Terdapat masalah pada saat menghasilkan sampul: :error', 35 - 'ok' => 'Sampul dihasilkan', 34 + 'failed' => 'Terdapat masalah pada saat membuat sampul: :error', 35 + 'ok' => 'Sampul dibuat', 36 36 ], 37 37 ];
+14 -13
resources/lang/id/users.php
··· 106 106 '_' => 'Masuk', 107 107 'button' => 'Masuk', 108 108 'button_posting' => 'Mencoba masuk...', 109 - 'email_login_disabled' => 'Alamat email untuk saat ini tidak dapat digunakan untuk masuk. Silakan masuk dengan menggunakan nama pengguna.', 109 + 'email_login_disabled' => 'Entri masuk dengan email saat ini sedang dinonaktifkan. Silakan masuk dengan menggunakan nama pengguna.', 110 110 'failed' => 'Rincian masuk salah', 111 111 'forgot' => 'Lupa kata sandi?', 112 112 'info' => 'Silakan masuk untuk melanjutkan', ··· 197 197 'to_1' => 'Tampilkan sampul', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Rantai Permainan Harian', 201 + 'daily_streak_best' => 'Rantai Permainan Harian Terbaik', 202 + 'daily_streak_current' => 'Rantai Permainan Harian Saat Ini', 203 + 'playcount' => '', 204 + 'title' => 'Tantangan\nHarian', 205 + 'top_10p_placements' => 'Penempatan 10% Teratas', 206 + 'top_50p_placements' => 'Penempatan 50% Teratas', 207 + 'weekly' => 'Rantai Permainan Mingguan', 208 + 'weekly_streak_best' => 'Rantai Permainan Mingguan Terbaik', 209 + 'weekly_streak_current' => 'Rantai Permainan Mingguan Saat Ini', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valuehr', 213 + 'week' => ':valuemg', 213 214 ], 214 215 ], 215 216 'edit' => [ ··· 458 459 ], 459 460 'page' => [ 460 461 'button' => 'sunting halaman profil', 461 - 'description' => '<strong>saya!</strong> merupakan area pada halaman profilmu yang dapat kamu modifikasi sesuka hati.', 462 + 'description' => '<strong>saya!</strong> merupakan area pribadi pada halaman profilmu yang dapat kamu isi sesuka hati.', 462 463 'edit_big' => 'Sunting saya!', 463 464 'placeholder' => 'Ketik konten halaman di sini', 464 465
+1 -1
resources/lang/id/wiki.php
··· 5 5 6 6 return [ 7 7 'show' => [ 8 - 'fallback_translation' => 'Laman yang diminta belum diterjemahkan ke dalam bahasa yang dipilih (:language). Menampilkan versi Bahasa Inggris.', 8 + 'fallback_translation' => 'Halaman yang diminta belum diterjemahkan ke dalam bahasa yang dipilih (:language). Menampilkan versi Bahasa Inggris.', 9 9 'incomplete_or_outdated' => 'Informasi yang tertera pada halaman ini tidak lengkap atau telah kedaluwarsa. Apabila kamu berkenan, mohon bantu kami untuk memperbarui artikel ini!', 10 10 'missing' => 'Halaman ":keyword" yang diminta tidak dapat ditemukan.', 11 11 'missing_title' => 'Tidak Ditemukan',
+1
resources/lang/it/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'resetta', 13 14 'rules' => 'Assicurati che la tua immagine di profilo aderisca alle :link.<br/>Questo significa che dev\'essere <strong>adatta a tutte le età</strong> (quindi niente nudità, profanità o contenuti provocanti).', 14 15 'rules_link' => 'regole della comunità', 15 16 ],
+1 -1
resources/lang/it/api.php
··· 7 7 'error' => [ 8 8 'chat' => [ 9 9 'empty' => 'Non puoi inviare messaggi vuoti.', 10 - 'limit_exceeded' => 'Stai inviando messaggi troppo velocemente, per favore aspetta un po\' prima di riprovare.', 10 + 'limit_exceeded' => 'Stai inviando messaggi troppo velocemente, aspetta un po\' prima di riprovare.', 11 11 'too_long' => 'Il messaggio che vuoi inviare è troppo lungo.', 12 12 ], 13 13 ],
+1 -1
resources/lang/it/artist.php
··· 46 46 '_' => 'ricerca tracce', 47 47 48 48 'exclusive_only' => [ 49 - 'all' => '', 49 + 'all' => 'Qualsiasi', 50 50 'exclusive_only' => 'osu! original', 51 51 ], 52 52
+1 -1
resources/lang/it/authorization.php
··· 62 62 63 63 'chat' => [ 64 64 'annnonce_only' => 'Questo canale è solamente per gli annunci.', 65 - 'blocked' => 'Non puoi inviare messaggi ad un utente che ti sta bloccando o che hai bloccato.', 65 + 'blocked' => 'Non puoi inviare messaggi a un utente che ti sta bloccando o che hai bloccato.', 66 66 'friends_only' => 'L\'utente sta bloccando i messaggi da chi non è nella sua lista amici.', 67 67 'moderated' => 'Questo canale è attualmente moderato.', 68 68 'no_access' => 'Non hai accesso a quel canale.',
+1
resources/lang/it/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Rallenta, gioca di più.', 20 + 'no_mirrors' => 'Nessun server di download disponibile.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/it/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'commenti', 17 18 'hide_judged' => 'nascondi le voci valutate', 18 19 'nav_title' => 'giudice', 19 20 'no_current_vote' => 'non hai ancora votato.',
+8 -8
resources/lang/it/notifications.php
··· 5 5 6 6 return [ 7 7 'all_read' => 'Lette tutte le notifiche!', 8 - 'delete' => 'Elimina :type', 8 + 'delete' => 'Svuota ":type"', 9 9 'loading' => 'Caricamento notifiche non lette...', 10 10 'mark_read' => 'Segna :type come letto', 11 11 'none' => 'Nessuna notifica', ··· 14 14 'verifying' => 'Verifica la sessione per visualizzare le notifiche', 15 15 16 16 'action_type' => [ 17 - '_' => '"tutto"', 18 - 'beatmapset' => '"beatmap"', 19 - 'build' => '"versioni"', 20 - 'channel' => '"chat"', 21 - 'forum_topic' => '"forum"', 22 - 'news_post' => '"notizie"', 23 - 'user' => '"profilo"', 17 + '_' => 'tutto', 18 + 'beatmapset' => 'beatmap', 19 + 'build' => 'versioni', 20 + 'channel' => 'chat', 21 + 'forum_topic' => 'forum', 22 + 'news_post' => 'notizie', 23 + 'user' => 'profilo', 24 24 ], 25 25 26 26 'filters' => [
+4 -4
resources/lang/it/store.php
··· 56 56 'date' => 'Data:', 57 57 'echeck_delay' => 'Visto che il tuo pagamento era un eCheck, dovrai attendere altri 10 giorni per far passare il pagamento attraverso PayPal!', 58 58 'hide_from_activity' => 'I tag osu!supporter in questo ordine non verranno mostrati nella tua attività recente.', 59 - 'sent_via' => '', 60 - 'shipping_to' => '', 59 + 'sent_via' => 'Inviato con:', 60 + 'shipping_to' => 'Indirizzo di spedizione:', 61 61 'title' => 'Ricevuta', 62 62 'title_compact' => 'ricevuta', 63 63 ··· 91 91 ], 92 92 'shipped' => [ 93 93 'title' => 'Il tuo ordine è stato spedito!', 94 - 'tracking_details' => '', 94 + 'tracking_details' => 'Dettagli di tracciamento:', 95 95 'no_tracking_details' => [ 96 96 '_' => "Non disponiamo dei dettagli di tracciabilità poiché abbiamo inviato il tuo pacco tramite posta aerea, ma puoi aspettarti di riceverlo entro 1-3 settimane. Per l'Europa, a volte la dogana può ritardare l'ordine senza il nostro controllo. Se hai qualche dubbio, rispondi all'e-mail di conferma dell'ordine che hai ricevuto (o :link).", 97 97 'link_text' => 'inviaci un\'email', ··· 174 174 'add_to_cart' => 'Aggiungi al carrello', 175 175 'notify' => 'Avvisami quando è disponibile!', 176 176 177 - 'notification_success' => 'sarai avvisato quando sarà disponibile. clicca :link per annullare', 177 + 'notification_success' => 'verrai avvisato quando sarà disponibile. clicca :link per annullare', 178 178 'notification_remove_text' => 'qui', 179 179 180 180 'notification_in_stock' => 'Questo prodotto è già disponibile!',
+3 -3
resources/lang/it/user_cover_presets.php
··· 5 5 6 6 return [ 7 7 'index' => [ 8 - 'batch_disable' => '', 9 - 'batch_enable' => '', 8 + 'batch_disable' => 'Disabilita selezionati', 9 + 'batch_enable' => 'Abilita selezionati', 10 10 11 11 'batch_confirm' => [ 12 12 '_' => ':action :items?', ··· 27 27 'enabled' => 'Abilitato', 28 28 'disabled' => 'Disabilitato', 29 29 'image_store' => 'Imposta Immagine', 30 - 'image_update' => '', 30 + 'image_update' => 'Sostituisci Immagine', 31 31 ], 32 32 ], 33 33 'store' => [
+13 -12
resources/lang/it/users.php
··· 97 97 98 98 'force_reactivation' => [ 99 99 'reason' => [ 100 - 'inactive' => "", 100 + 'inactive' => "Il tuo account non viene usato da molto tempo.", 101 101 'inactive_different_country' => "Il tuo account non è stato utilizzato per molto tempo.", 102 102 ], 103 103 ], ··· 197 197 'to_1' => 'Mostra copertina', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Serie Giornaliera', 201 + 'daily_streak_best' => 'Migliore Serie Giornaliera', 202 + 'daily_streak_current' => 'Attuale Serie Giornaliera', 203 + 'playcount' => '', 204 + 'title' => 'Sfida\nGiornaliera', 205 + 'top_10p_placements' => 'Raggiungimenti del primo 10%', 206 + 'top_50p_placements' => 'Raggiungimenti del primo 50%', 207 + 'weekly' => 'Serie Settimanale', 208 + 'weekly_streak_best' => 'Migliore Serie Settimanale', 209 + 'weekly_streak_current' => 'Attuale Serie Settimanale', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valueg', 213 + 'week' => ':values', 213 214 ], 214 215 ], 215 216 'edit' => [
+2 -1
resources/lang/ja/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'プロフィール画像', 13 + 'reset' => 'リセット', 13 14 'rules' => 'あなたのプロフィール画像が公序良俗に反したもので無いか確認してください。 :link.<br/>易しく言えば<strong>全ての年齢に適した</strong>、つまりヌードや冒涜的な表現などを想起させるものを含んでいない事を確認してください。', 14 15 'rules_link' => 'コミュニティールール', 15 16 ], ··· 65 66 'github_user' => [ 66 67 'info' => "osu! のオープンソースリポジトリへのコントリビューターであれば、ここでGitHubアカウントをリンクすると、更新ログエントリがosu! プロフィールに関連付けられます。 osu! への貢献履歴がないGitHubアカウントはリンクできません。", 67 68 'link' => 'GitHubアカウントをリンク', 68 - 'title' => '', 69 + 'title' => 'GitHub', 69 70 'unlink' => 'GitHubアカウントのリンクを解除', 70 71 71 72 'error' => [
+2 -2
resources/lang/ja/api.php
··· 17 17 'identify' => 'あなたを識別し、一般公開プロフィールを読み取ります。', 18 18 19 19 'chat' => [ 20 - 'read' => '', 20 + 'read' => 'あなたの代わりにメッセージを読みます。', 21 21 'write' => 'あなたの代わりにメッセージを送信します。', 22 - 'write_manage' => '', 22 + 'write_manage' => 'あなたの代わりにチャンネルを出入りします。', 23 23 ], 24 24 25 25 'forum' => [
+1 -1
resources/lang/ja/beatmappacks.php
··· 32 32 'artist' => 'アーティスト/アルバム', 33 33 'chart' => 'スポットライト', 34 34 'featured' => '注目アーティスト', 35 - 'loved' => '', 35 + 'loved' => 'Project Loved', 36 36 'standard' => 'スタンダードパック', 37 37 'theme' => 'テーマ', 38 38 'tournament' => 'トーナメント',
+14 -14
resources/lang/ja/beatmaps.php
··· 25 25 'message_placeholder_silenced' => "サイレンス中はディスカッションへ投稿できません。", 26 26 'message_type_select' => 'コメントタイプを選択', 27 27 'reply_notice' => 'Enterキーを押して送信', 28 - 'reply_resolve_notice' => '', 28 + 'reply_resolve_notice' => 'Enterを押して返信します。Ctrl + Enter キーを押して返信し、解決済みにします。', 29 29 'reply_placeholder' => 'ここに入力してください', 30 30 'require-login' => '返信するにはログインが必要です。', 31 31 'resolved' => '解決済み', ··· 71 71 'message_type' => [ 72 72 'disqualify' => 'Disqualify', 73 73 'hype' => 'Hype!', 74 - 'mapper_note' => '注意', 74 + 'mapper_note' => 'メモ', 75 75 'nomination_reset' => 'ノミネーションをリセット', 76 76 'praise' => '称賛', 77 77 'problem' => '問題', ··· 82 82 83 83 'message_type_title' => [ 84 84 'disqualify' => '', 85 - 'hype' => '', 86 - 'mapper_note' => '', 85 + 'hype' => 'Hypeを投稿', 86 + 'mapper_note' => 'メモを投稿', 87 87 'nomination_reset' => '', 88 - 'praise' => '', 89 - 'problem' => '', 90 - 'problem_warning' => '', 91 - 'review' => '', 92 - 'suggestion' => '', 88 + 'praise' => '称賛を投稿', 89 + 'problem' => '問題を投稿', 90 + 'problem_warning' => '問題を投稿', 91 + 'review' => 'レビューを投稿', 92 + 'suggestion' => '提案を投稿', 93 93 ], 94 94 95 95 'mode' => [ ··· 190 190 191 191 'nominations' => [ 192 192 'already_nominated' => '既にこのビートマップをHypeしています。', 193 - 'cannot_nominate' => '', 193 + 'cannot_nominate' => 'このゲームモードをノミネートすることはできません。', 194 194 'delete' => '削除', 195 195 'delete_own_confirm' => '本当によろしいですか?ビートマップは削除され、プロフィール画面にリダイレクトされます。', 196 196 'delete_other_confirm' => '本当によろしいですか?ビートマップは削除され、ユーザーのプロフィール画面にリダイレクトされます。', ··· 215 215 216 216 'rank_estimate' => [ 217 217 '_' => 'このマップは、問題が見つからなければ :date にrankedされると推定されます。:queue 内の #:position ', 218 - 'unresolved_problems' => '', 219 - 'problems' => '', 220 - 'on' => '', 218 + 'unresolved_problems' => '現在このマップは :problems が解決されるまでQualified状態から離れることをブロックされています。', 219 + 'problems' => 'この問題', 220 + 'on' => ':date', 221 221 'queue' => 'ランキングキュー', 222 222 'soon' => '間もなく', 223 223 ], ··· 285 285 'taiko' => '', 286 286 'fruits' => '', 287 287 'mania' => '', 288 - 'undefined' => '', 288 + 'undefined' => '未設定', 289 289 ], 290 290 'status' => [ 291 291 'any' => '全て',
+5 -4
resources/lang/ja/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'スピードを落として、もっと遊ぼう。', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [ ··· 40 41 ], 41 42 42 43 'nominate' => [ 43 - 'bng_limited_too_many_rulesets' => '', 44 - 'full_nomination_required' => '', 44 + 'bng_limited_too_many_rulesets' => '試用期間のノミネーターは複数のゲームモードをノミネートすることはできません。', 45 + 'full_nomination_required' => 'このゲームモードの最後のノミネートを行うには、フルノミネーターである必要があります。', 45 46 'hybrid_requires_modes' => 'ハイブリッドビートマップセットでは、少なくとも1つのモードを選択してノミネートする必要があります。', 46 47 'incorrect_mode' => 'モード:modeでノミネートする権限がありません。', 47 48 'invalid_limited_nomination' => '', ··· 53 54 'confirmation' => 'このビートマップを本当にノミネートしますか?', 54 55 'header' => 'ビートマップをノミネート', 55 56 'hybrid_warning' => '注意: 一度しかノミネートできないので、ノミネートするゲームモードの全てにノミネートするようにしてください。', 56 - 'current_main_ruleset' => '', 57 + 'current_main_ruleset' => '現在のメインゲームモードは :ruleset です', 57 58 'which_modes' => 'どのモードをノミネートしますか?', 58 59 ], 59 60 ], ··· 66 67 'discussion' => 'ディスカッション', 67 68 68 69 'admin' => [ 69 - 'full_size_cover' => '', 70 + 'full_size_cover' => 'フルサイズのカバー画像を表示', 70 71 ], 71 72 72 73 'deleted_banner' => [
+4 -4
resources/lang/ja/chat.php
··· 16 16 ], 17 17 18 18 'channels' => [ 19 - 'confirm_part' => 'このチャンネルを隠したいです?まだこのチャンネルからメッセージが送れられています。', 19 + 'confirm_part' => 'このチャンネルを隠しますか?このチャンネルからは引き続きメッセージを受信します。', 20 20 'create' => 'お知らせを作成', 21 - 'join' => '', 22 - 'none' => '', 21 + 'join' => 'チャンネルに参加', 22 + 'none' => 'チャンネルがありません', 23 23 24 24 'list' => [ 25 25 'title' => [ ··· 64 64 ], 65 65 66 66 'join_channels' => [ 67 - 'loading' => '', 67 + 'loading' => 'チャンネル一覧を読み込んでいます...', 68 68 ], 69 69 ];
+1
resources/lang/ja/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => 'あなたはまだ投票していません。',
+1 -1
resources/lang/ja/layout.php
··· 195 195 'account-edit' => '設定', 196 196 'follows' => 'ウォッチリスト', 197 197 'friends' => 'フレンド', 198 - 'legacy_score_only_toggle' => '', 198 + 'legacy_score_only_toggle' => 'Lazerモード', 199 199 'legacy_score_only_toggle_tooltip' => 'Lazer nodeは、新しいスコアリングアルゴリズムを使用して、Lazerから提出されたスコアを表示します', 200 200 'logout' => 'ログアウト', 201 201 'profile' => 'プロフィール',
+1 -1
resources/lang/ja/models.php
··· 8 8 9 9 'name' => [ 10 10 'App\Models\Beatmap' => '', 11 - 'App\Models\Beatmapset' => '', 11 + 'App\Models\Beatmapset' => 'ビートマップ', 12 12 ], 13 13 ];
+1 -1
resources/lang/ja/oauth.php
··· 7 7 'cancel' => 'キャンセル', 8 8 9 9 'authorise' => [ 10 - 'app_owner' => '', 10 + 'app_owner' => ':owner によるアプリケーション', 11 11 'request' => 'アカウントへのアクセス許可を要求しています。', 12 12 'scopes_title' => 'このアプリケーションは次のことができます:', 13 13 'title' => '認証をリクエスト',
+1 -1
resources/lang/ja/rankings.php
··· 40 40 'seasons' => [ 41 41 'empty' => '', 42 42 'ongoing' => '', 43 - 'room_count' => '', 43 + 'room_count' => 'プレイリスト数', 44 44 'url' => '', 45 45 ], 46 46
+3 -3
resources/lang/ja/scores.php
··· 5 5 6 6 return [ 7 7 'show' => [ 8 - 'non_preserved' => '', 8 + 'non_preserved' => 'このスコアは削除対象としてマークされているので、まもなく削除されます。', 9 9 'title' => ':title[:version]の:username', 10 10 11 11 'beatmap' => [ ··· 25 25 26 26 'status' => [ 27 27 'non_best' => '個人のベストスコアのみppを与えます。', 28 - 'no_pp' => '', 28 + 'no_pp' => 'このスコアに対してppは授与されていません', 29 29 'processing' => 'このスコアはまだ計算中です。すぐに表示されます。', 30 - 'no_rank' => '', 30 + 'no_rank' => 'このスコアはUnranked、または削除対象のマップなのでランクはありません。', 31 31 ], 32 32 ];
+11 -11
resources/lang/ja/store.php
··· 49 49 ], 50 50 51 51 'discount' => ':percent%の割引', 52 - 'free' => '', 52 + 'free' => '無料', 53 53 54 54 'invoice' => [ 55 55 'contact' => '', ··· 110 110 'resume' => '支払いを再開', 111 111 'shipping_and_handling' => '', 112 112 'shopify_expired' => 'この注文の決済リンクは期限切れとなりました。', 113 - 'subtotal' => '', 114 - 'total' => '', 113 + 'subtotal' => '小計', 114 + 'total' => '合計', 115 115 116 116 'details' => [ 117 117 'order_number' => '注文 #', 118 - 'payment_terms' => '', 118 + 'payment_terms' => '支払い条件', 119 119 'salesperson' => '', 120 - 'shipping_method' => '', 121 - 'shipping_terms' => '', 122 - 'title' => '', 120 + 'shipping_method' => '配送方法', 121 + 'shipping_terms' => '配送条件', 122 + 'title' => '注文の詳細', 123 123 ], 124 124 125 125 'item' => [ ··· 151 151 'paid' => '支払い済み', 152 152 'processing' => '承認待ち', 153 153 'shipped' => '発送済み', 154 - 'title' => '', 154 + 'title' => '注文ステータス', 155 155 ], 156 156 157 157 'thanks' => [ 158 - 'title' => '', 158 + 'title' => 'ご注文ありがとうございました!', 159 159 'line_1' => [ 160 160 '_' => '', 161 161 'link_text' => '', ··· 194 194 'check' => '名前を入力して使用可能か確認しましょう!', 195 195 'checking' => ':usernameが使用可能か確認中・・・', 196 196 'placeholder' => '', 197 - 'label' => '', 198 - 'current' => '', 197 + 'label' => '新しいユーザー名', 198 + 'current' => '現在のあなたのユーザー名は ":username" です。', 199 199 200 200 'require_login' => [ 201 201 '_' => '名前を変えるには:linkが必要です!',
+15 -14
resources/lang/ja/users.php
··· 97 97 98 98 'force_reactivation' => [ 99 99 'reason' => [ 100 - 'inactive' => "", 100 + 'inactive' => "あなたのアカウントは長い間使用されていません。", 101 101 'inactive_different_country' => "あなたのアカウントは長期間使用されていません。", 102 102 ], 103 103 ], ··· 197 197 'to_1' => 'カバー画像を表示', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => '連続記録', 201 + 'daily_streak_best' => '最高連続記録', 202 + 'daily_streak_current' => '現在の連続記録', 203 + 'playcount' => '', 204 + 'title' => 'デイリー\nチャレンジ', 205 + 'top_10p_placements' => '上位10%', 206 + 'top_50p_placements' => '上位50%', 207 + 'weekly' => '週間連続記録', 208 + 'weekly_streak_best' => '最高週間連続記録', 209 + 'weekly_streak_current' => '現在の週間連続記録', 209 210 210 211 'unit' => [ 211 212 'day' => '', ··· 217 218 'button' => 'カバー画像の変更', 218 219 'defaults_info' => 'カバー画像の選択肢は増える予定です', 219 220 'holdover_remove_confirm' => "", 220 - 'title' => '', 221 + 'title' => 'カバー画像', 221 222 222 223 'upload' => [ 223 224 'broken_file' => '画像の処理に失敗しました。アップロードした画像を確認してもう一度やり直して下さい。', ··· 242 243 243 244 'hue' => [ 244 245 'reset_no_supporter' => '', 245 - 'title' => '', 246 + 'title' => 'カラー', 246 247 247 248 'supporter' => [ 248 - '_' => '', 249 - 'link' => '', 249 + '_' => 'カラーテーマをカスタムできるのは :link のみです', 250 + 'link' => 'osu!サポーター', 250 251 ], 251 252 ], 252 253 ],
+1
resources/lang/kk-KZ/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Аватар', 13 + 'reset' => '', 13 14 'rules' => 'Өтініш, аватарыңыз :link бойынша келуін қадағалаңыз.<br/>Ол <strong>барлық жастарға сай болуы керек</strong>, яғни жалаңаштық, бейпіл сөздер немесе ерсі контент болмауы тиіс.', 14 15 'rules_link' => 'қауымдастық ережелері', 15 16 ],
+1
resources/lang/kk-KZ/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Баяу болыңыз, көбірек ойнаңыз.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/kk-KZ/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => 'төреші', 19 20 'no_current_vote' => '',
+1
resources/lang/kk-KZ/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+3 -2
resources/lang/ko/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => '아바타', 13 + 'reset' => '초기화', 13 14 'rules' => '아바타가 :link을 따르고 있는지 확인하세요.<br/>이는 아바타가 <strong>모든 연령에 적합해야 하므로</strong> 과도한 노출, 욕설 혹은 이러한 것을 암시하는 내용이 없어야 한다는 의미입니다.', 14 15 'rules_link' => '커뮤니티 규칙', 15 16 ], ··· 102 103 ], 103 104 104 105 'options' => [ 105 - 'beatmapset_show_nsfw' => '부적절한 내용의 비트맵 경고 숨기기', 106 - 'beatmapset_title_show_original' => '원본 언어로 비트맵 메타데이터 표시', 106 + 'beatmapset_show_nsfw' => '부적절한 내용에 대한 비트맵 경고 숨기기', 107 + 'beatmapset_title_show_original' => '원본 언어로 비트맵 메타데이터 표시하기', 107 108 'title' => '설정', 108 109 109 110 'beatmapset_download' => [
+2 -2
resources/lang/ko/beatmaps.php
··· 25 25 'message_placeholder_silenced' => "침묵 상태에서는 토론 게시글을 게시할 수 없습니다.", 26 26 'message_type_select' => '게시할 답글의 형식을 선택하세요', 27 27 'reply_notice' => '답글을 올리려면 엔터를 누르세요.', 28 - 'reply_resolve_notice' => '', 28 + 'reply_resolve_notice' => '엔터를 눌러 답변하세요. ctrl+enter를 눌러 답변하고 종결지을 수 있습니다.', 29 29 'reply_placeholder' => '보내실 답변의 내용을 입력하세요.', 30 30 'require-login' => '글을 올리거나 답변하려면 로그인해 주세요', 31 31 'resolved' => '해결됨', 32 32 'restore' => '복구', 33 33 'show_deleted' => '삭제된 내용 표시', 34 34 'title' => '토론', 35 - 'unresolved_count' => '', 35 + 'unresolved_count' => ':count_delimited개의 미해결 이슈', 36 36 37 37 'collapse' => [ 38 38 'all-collapse' => '모두 축소하기',
+1
resources/lang/ko/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => '잠시 멈추시고, 좀 더 플레이해보세요.', 20 + 'no_mirrors' => '다운로드를 할 서버가 존재하지 않습니다.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/ko/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '코멘트', 17 18 'hide_judged' => '심사된 항목 숨기기', 18 19 'nav_title' => '심사', 19 20 'no_current_vote' => '아직은 투표할 수 없습니다.',
+2 -2
resources/lang/ko/layout.php
··· 199 199 'legacy_score_only_toggle_tooltip' => 'Lazer 모드는 osu!lazer에서 새로운 점수 알고리즘으로 등록한 점수를 표시합니다', 200 200 'logout' => '로그아웃', 201 201 'profile' => '내 프로필', 202 - 'scoring_mode_toggle' => '', 203 - 'scoring_mode_toggle_tooltip' => '', 202 + 'scoring_mode_toggle' => '클래식 점수', 203 + 'scoring_mode_toggle_tooltip' => '점숫값을 한계치가 없는 예전 클래식 점수처럼 느껴지도록 조정합니다.', 204 204 ], 205 205 ], 206 206
+1 -1
resources/lang/ko/oauth.php
··· 7 7 'cancel' => '취소', 8 8 9 9 'authorise' => [ 10 - 'app_owner' => '', 10 + 'app_owner' => ':owner 님의 앱', 11 11 'request' => '이(가) 당신의 계정에 접근할 수 있는 권한을 요청합니다.', 12 12 'scopes_title' => '이 애플리케이션은 다음 기능을 할 수 있습니다:', 13 13 'title' => '권한 요청',
+1 -1
resources/lang/ko/report.php
··· 26 26 27 27 'message' => [ 28 28 'button' => '메시지 신고하기', 29 - 'title' => '', 29 + 'title' => ':username님의 메시지를 신고하겠습니까?', 30 30 ], 31 31 32 32 'scores' => [
+16 -14
resources/lang/ko/users.php
··· 197 197 'to_1' => '커버 표시', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => '연속 진행일', 201 + 'daily_streak_best' => '최다 연속 진행일 202 + ', 203 + 'daily_streak_current' => '현재 연속 진행일', 204 + 'playcount' => '', 205 + 'title' => '일일미션', 206 + 'top_10p_placements' => '상위 10%', 207 + 'top_50p_placements' => '상위 50%', 208 + 'weekly' => '연속 진행주', 209 + 'weekly_streak_best' => '최다 연속 진행주', 210 + 'weekly_streak_current' => '현재 연속 진행주', 209 211 210 212 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 213 + 'day' => ':valued', 214 + 'week' => ':valuew', 213 215 ], 214 216 ], 215 217 'edit' => [ ··· 217 219 'button' => '프로필 표지 변경', 218 220 'defaults_info' => '이후에 더 많은 표지 설정이 추가됩니다', 219 221 'holdover_remove_confirm' => "", 220 - 'title' => '', 222 + 'title' => '표지', 221 223 222 224 'upload' => [ 223 225 'broken_file' => '이미지 처리 실패. 업로드하려는 이미지를 확인하시고 다시 시도해주세요.', ··· 242 244 243 245 'hue' => [ 244 246 'reset_no_supporter' => '', 245 - 'title' => '', 247 + 'title' => '색상', 246 248 247 249 'supporter' => [ 248 250 '_' => '', 249 - 'link' => '', 251 + 'link' => 'osu! 서포터', 250 252 ], 251 253 ], 252 254 ],
+1
resources/lang/lt/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avataras', 13 + 'reset' => '', 13 14 'rules' => 'Prašome užtikrinti, kad avataras atitinka :link.<br/>Reiškias jis turi būti<strong> tinkamas visiems amžiams </strong>. pvz. nėra nuogybių, nešvankybių ar kito pažeidžiamo tūrinio.', 14 15 'rules_link' => 'bendruomenės taisyklės', 15 16 ],
+1
resources/lang/lt/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Neskubėk, pažaisk daugiau.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/lt/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/lt/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/lv-LV/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatārs', 13 + 'reset' => '', 13 14 'rules' => 'Lūdzu, pārliecinieties, ka jūsu profila attēls atbilst :link.<br/>Tas nozīmē, ka attēlam jābūt <strong>piemērotam visiem vecumiem</strong>, t.i., bez kailuma, rupjībām vai ierosinoša satura.', 14 15 'rules_link' => 'kopienas noteikumi', 15 16 ],
+1
resources/lang/lv-LV/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Piebremzējiet, spēlējiet vairāk.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/lv-LV/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'paslēpt vērtētos ierakstus', 18 19 'nav_title' => 'tiesāt', 19 20 'no_current_vote' => 'tu vēl nebalsoji.',
+1
resources/lang/lv-LV/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+7 -6
resources/lang/ms-MY/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'set semula', 13 14 'rules' => 'Pastikan avatarmu akur pada :link yang berlaku.<br/>Dengan kata lain, avatarmu mestilah <strong>sesuai untuk segala usia</strong> tanpa mengandung unsur apa pun yang tidak dibenarkan seperti cacian, hinaan, atau hal yang tidak senonoh.', 14 15 'rules_link' => 'peraturan komuniti', 15 16 ], ··· 19 20 'new_confirmation' => 'pengesahan e-mel', 20 21 'title' => 'E-mel', 21 22 'locked' => [ 22 - '_' => '', 23 + '_' => 'Sila hubungi :accounts jika anda mahu emel anda dikemaskini.', 23 24 'accounts' => '', 24 25 ], 25 26 ], ··· 64 65 65 66 'github_user' => [ 66 67 'info' => "", 67 - 'link' => '', 68 - 'title' => '', 69 - 'unlink' => '', 68 + 'link' => 'Pautkan Akaun Github', 69 + 'title' => 'GitHub', 70 + 'unlink' => 'Nyahpautkan Akaun Github', 70 71 71 72 'error' => [ 72 - 'already_linked' => '', 73 + 'already_linked' => 'Akaun Github ini telah dipautkan dengan pengguna lain.', 73 74 'no_contribution' => '', 74 75 'unverified_email' => '', 75 76 ], ··· 85 86 'options' => [ 86 87 '_' => 'hantarkan pemberitahuan melalui', 87 88 'beatmap_owner_change' => 'kesukaran tamu', 88 - 'beatmapset:modding' => '', 89 + 'beatmapset:modding' => 'beatmap modding', 89 90 'channel_message' => 'pesanan peribadi', 90 91 'comment_new' => 'ulasan baharu', 91 92 'forum_topic_reply' => 'balasan pada topik',
+8 -8
resources/lang/ms-MY/artist.php
··· 8 8 'title' => 'Featured Artists', 9 9 10 10 'admin' => [ 11 - 'hidden' => 'ARTIS SAAT INI TERSEMBUNYI', 11 + 'hidden' => 'ARTIS INI TERSEMBUNYI', 12 12 ], 13 13 14 14 'beatmaps' => [ ··· 29 29 30 30 'songs' => [ 31 31 '_' => 'Lagu', 32 - 'count' => '', 32 + 'count' => ':count_delimited lagu|:count_delimited lagu', 33 33 'original' => 'osu! original', 34 34 'original_badge' => 'ASLI', 35 35 ], ··· 38 38 'title' => 'tajuk', 39 39 'length' => 'tempoh', 40 40 'bpm' => 'bpm', 41 - 'genre' => 'aliran', 41 + 'genre' => 'genre', 42 42 ], 43 43 44 44 'tracks' => [ ··· 46 46 '_' => 'carian lagu', 47 47 48 48 'exclusive_only' => [ 49 - 'all' => '', 50 - 'exclusive_only' => '', 49 + 'all' => 'Semua', 50 + 'exclusive_only' => 'osu! original', 51 51 ], 52 52 53 53 'form' => [ 54 - 'advanced' => 'Carian Lanjutan', 54 + 'advanced' => 'Carian Lanjut', 55 55 'album' => 'Album', 56 56 'artist' => 'Artis', 57 57 'bpm_gte' => 'BPM Minimum', 58 58 'bpm_lte' => 'BPM Maksimum', 59 59 'empty' => 'Tiada lagu yang sesuai dengan ukur tara pencarian yang ditentukan.', 60 - 'exclusive_only' => '', 61 - 'genre' => 'Aliran', 60 + 'exclusive_only' => 'Jenis', 61 + 'genre' => 'Genre', 62 62 'genre_all' => 'Semua', 63 63 'length_gte' => 'Tempoh Minimum', 64 64 'length_lte' => 'Tempoh Maksimum',
+21 -21
resources/lang/ms-MY/authorization.php
··· 53 53 ], 54 54 55 55 'beatmapset' => [ 56 - 'discussion_locked' => '', 56 + 'discussion_locked' => 'Beatmap ini dikunci bagi perbincangan.', 57 57 58 58 'metadata' => [ 59 59 'nominated' => '', ··· 61 61 ], 62 62 63 63 'chat' => [ 64 - 'annnonce_only' => '', 65 - 'blocked' => '', 66 - 'friends_only' => '', 67 - 'moderated' => '', 68 - 'no_access' => '', 69 - 'receive_friends_only' => '', 70 - 'restricted' => '', 71 - 'silenced' => '', 64 + 'annnonce_only' => 'Saluran ini hanya untuk pengumuman.', 65 + 'blocked' => 'Tidak boleh mesej pengguna yang telah menyekat anda atau yang anda sekat.', 66 + 'friends_only' => 'Pengguna menyekat pesanan dari orang yang tiada dalam senarai kawan.', 67 + 'moderated' => 'Saluran ini sedang diawas.', 68 + 'no_access' => 'Anda tiada kebenaran untuk mengakses saluran itu.', 69 + 'receive_friends_only' => 'Pengguna ini mungkin tidak boleh membalas kerana anda hanya menerima pesanan dari orang dalam senarai kawan anda.', 70 + 'restricted' => 'Anda tidak boleh menghantar pesanan ketika didiamkan, disekat atau dilarang.', 71 + 'silenced' => 'Anda tidak boleh menghantar pesanan ketika didiamkan, disekat atau dilarang.', 72 72 ], 73 73 74 74 'comment' => [ 75 75 'store' => [ 76 - 'disabled' => '', 76 + 'disabled' => 'Ruangan komen ditutup', 77 77 ], 78 78 'update' => [ 79 - 'deleted' => "", 79 + 'deleted' => "Ruangan komen ditutup", 80 80 ], 81 81 ], 82 82 83 83 'contest' => [ 84 84 'judging_not_active' => '', 85 - 'voting_over' => '', 85 + 'voting_over' => 'Anda tidak boleh tukar undian selepas tempoh mengundi untuk pertandingan ini telah tamat.', 86 86 87 87 'entry' => [ 88 - 'limit_reached' => '', 88 + 'limit_reached' => 'Anda telah mencapai had kemasukan untuk pertandingan ini', 89 89 'over' => '', 90 90 ], 91 91 ], 92 92 93 93 'forum' => [ 94 94 'moderate' => [ 95 - 'no_permission' => '', 95 + 'no_permission' => 'Tiada kebenaran untuk mengawas forum ini.', 96 96 ], 97 97 98 98 'post' => [ 99 99 'delete' => [ 100 - 'only_last_post' => '', 101 - 'locked' => '', 100 + 'only_last_post' => 'Hanya hantaran terakhir boleh dipadam.', 101 + 'locked' => 'Tidak boleh padam hantaran bagi topik yang dikunci.', 102 102 'no_forum_access' => '', 103 - 'not_owner' => '', 103 + 'not_owner' => 'Hanya penghantar boleh memadam hantaran ini.', 104 104 ], 105 105 106 106 'edit' => [ 107 - 'deleted' => '', 108 - 'locked' => '', 107 + 'deleted' => 'Tidak boleh sunting hantaran yang dipadam.', 108 + 'locked' => 'Hantaran ini dikunci daripada disunting.', 109 109 'no_forum_access' => '', 110 - 'not_owner' => '', 110 + 'not_owner' => 'Hanya penghantar boleh memadam hantaran ini.', 111 111 'topic_locked' => '', 112 112 ], 113 113 ··· 188 188 ], 189 189 ], 190 190 'update_email' => [ 191 - 'locked' => '', 191 + 'locked' => 'alamat emel terkunci', 192 192 ], 193 193 ], 194 194 ];
+16 -16
resources/lang/ms-MY/bbcode.php
··· 4 4 // See the LICENCE file in the repository root for full licence text. 5 5 6 6 return [ 7 - 'bold' => '', 8 - 'heading' => '', 9 - 'help' => '', 10 - 'image' => '', 11 - 'imagemap' => '', 12 - 'italic' => '', 13 - 'link' => '', 14 - 'list' => '', 15 - 'list_numbered' => '', 7 + 'bold' => 'Tebal', 8 + 'heading' => 'Header', 9 + 'help' => 'Tolong', 10 + 'image' => 'Tolong', 11 + 'imagemap' => 'Peta Imej', 12 + 'italic' => 'Condong', 13 + 'link' => 'Pautan', 14 + 'list' => 'Senarai', 15 + 'list_numbered' => 'Senarai bernombor', 16 16 'size' => [ 17 - '_' => '', 18 - 'tiny' => '', 19 - 'small' => '', 20 - 'normal' => '', 21 - 'large' => '', 17 + '_' => 'Saiz Fon', 18 + 'tiny' => 'Sangat kecil', 19 + 'small' => 'Kecil', 20 + 'normal' => 'Biasa', 21 + 'large' => 'Besar', 22 22 ], 23 - 'spoilerbox' => '', 24 - 'strikethrough' => '', 23 + 'spoilerbox' => 'Kotak "Spoiler"', 24 + 'strikethrough' => 'Pangkah', 25 25 ];
+2 -2
resources/lang/ms-MY/beatmap_discussion_posts.php
··· 9 9 ], 10 10 11 11 'item' => [ 12 - 'content' => '', 13 - 'modding_history_link' => '', 12 + 'content' => 'Kandungan', 13 + 'modding_history_link' => 'Lihat sejarah modding', 14 14 ], 15 15 ];
+27 -27
resources/lang/ms-MY/beatmap_discussions.php
··· 17 17 ], 18 18 19 19 'index' => [ 20 - 'deleted_beatmap' => '', 20 + 'deleted_beatmap' => 'dipadam', 21 21 'none_found' => '', 22 - 'title' => '', 22 + 'title' => 'Perbincangan Beatmap', 23 23 24 24 'form' => [ 25 - '_' => '', 25 + '_' => 'Cari', 26 26 'deleted' => '', 27 - 'mode' => '', 27 + 'mode' => 'Mod beatmap', 28 28 'only_unresolved' => '', 29 29 'show_review_embeds' => '', 30 - 'types' => '', 31 - 'username' => '', 30 + 'types' => 'Jenis mesej', 31 + 'username' => 'Nama penggua', 32 32 33 33 'beatmapset_status' => [ 34 - '_' => '', 35 - 'all' => '', 36 - 'disqualified' => '', 37 - 'never_qualified' => '', 38 - 'qualified' => '', 39 - 'ranked' => '', 34 + '_' => 'Status Beatmap', 35 + 'all' => 'Semua', 36 + 'disqualified' => 'Tersingkar', 37 + 'never_qualified' => 'Tidak Pernah Layak', 38 + 'qualified' => 'Layak', 39 + 'ranked' => 'Berkedudukan', 40 40 ], 41 41 42 42 'user' => [ 43 - 'label' => '', 44 - 'overview' => '', 43 + 'label' => 'Pengguna', 44 + 'overview' => 'Aktiviti keseluruhan', 45 45 ], 46 46 ], 47 47 ], 48 48 49 49 'item' => [ 50 - 'created_at' => '', 51 - 'deleted_at' => '', 52 - 'message_type' => '', 53 - 'permalink' => '', 50 + 'created_at' => 'Tarikh hantaran', 51 + 'deleted_at' => 'Tarikh dipadam', 52 + 'message_type' => 'Jenis', 53 + 'permalink' => 'Pautan Kekal', 54 54 ], 55 55 56 56 'nearby_posts' => [ ··· 62 62 'owner_editor' => [ 63 63 'button' => '', 64 64 'reset_confirm' => '', 65 - 'user' => '', 66 - 'version' => '', 65 + 'user' => 'Pemilik', 66 + 'version' => 'Kesukaran', 67 67 ], 68 68 69 69 'reply' => [ 70 70 'open' => [ 71 - 'guest' => '', 72 - 'user' => '', 71 + 'guest' => 'Daftar masuk untuk Maklum balas', 72 + 'user' => 'Maklum balas', 73 73 ], 74 74 ], 75 75 76 76 'review' => [ 77 77 'block_count' => '', 78 78 'go_to_parent' => '', 79 - 'go_to_child' => '', 79 + 'go_to_child' => 'Lihat Perbincangan', 80 80 'validation' => [ 81 81 'block_too_large' => '', 82 82 'external_references' => '', ··· 97 97 ], 98 98 99 99 'timestamp_display' => [ 100 - 'general' => '', 101 - 'general_all' => '', 100 + 'general' => 'umum', 101 + 'general_all' => 'umum (semua)', 102 102 ], 103 103 104 104 'user_filter' => [ 105 - 'everyone' => '', 106 - 'label' => '', 105 + 'everyone' => 'Semua orang', 106 + 'label' => 'Tapis mengikut pengguna', 107 107 ], 108 108 ];
+9 -9
resources/lang/ms-MY/beatmappacks.php
··· 6 6 return [ 7 7 'index' => [ 8 8 'description' => '', 9 - 'empty' => '', 10 - 'nav_title' => '', 9 + 'empty' => 'Akan datang!', 10 + 'nav_title' => 'senarai-senarai', 11 11 'title' => '', 12 12 13 13 'blurb' => [ ··· 17 17 ], 18 18 19 19 'show' => [ 20 - 'download' => '', 20 + 'download' => 'Muat turun', 21 21 'item' => [ 22 22 'cleared' => '', 23 23 'not_cleared' => '', ··· 29 29 ], 30 30 31 31 'mode' => [ 32 - 'artist' => '', 32 + 'artist' => 'Artis/Album', 33 33 'chart' => '', 34 - 'featured' => '', 35 - 'loved' => '', 36 - 'standard' => '', 37 - 'theme' => '', 38 - 'tournament' => '', 34 + 'featured' => 'Artis Terpilih', 35 + 'loved' => 'Projek Dicinta', 36 + 'standard' => 'Biasa', 37 + 'theme' => 'Tema', 38 + 'tournament' => 'Kejohanan', 39 39 ], 40 40 41 41 'require_login' => [
+138 -138
resources/lang/ms-MY/beatmaps.php
··· 13 13 'discussions' => [ 14 14 'allow_kudosu' => '', 15 15 'beatmap_information' => '', 16 - 'delete' => '', 17 - 'deleted' => '', 18 - 'deny_kudosu' => '', 19 - 'edit' => '', 20 - 'edited' => '', 16 + 'delete' => 'padam', 17 + 'deleted' => 'Dipadam oleh :editor :delete_time.', 18 + 'deny_kudosu' => 'tolak kudosu', 19 + 'edit' => 'sunting', 20 + 'edited' => 'Kali terakhir disunting oleh :editor :update_time.', 21 21 'guest' => '', 22 22 'kudosu_denied' => '', 23 23 'message_placeholder_deleted_beatmap' => '', 24 24 'message_placeholder_locked' => '', 25 25 'message_placeholder_silenced' => "", 26 - 'message_type_select' => '', 27 - 'reply_notice' => '', 28 - 'reply_resolve_notice' => '', 29 - 'reply_placeholder' => '', 26 + 'message_type_select' => 'Pilih Jenis Balasan', 27 + 'reply_notice' => 'Tekan "enter" untuk membalas.', 28 + 'reply_resolve_notice' => 'Tekan "enter" untuk membalas. Tekan ctrl+enter untuk membalas dan selesaikan.', 29 + 'reply_placeholder' => 'Tulis respon anda disini', 30 30 'require-login' => '', 31 - 'resolved' => '', 32 - 'restore' => '', 33 - 'show_deleted' => '', 34 - 'title' => '', 31 + 'resolved' => 'Selesai', 32 + 'restore' => 'pulihkan', 33 + 'show_deleted' => 'Tunjuk dipadam', 34 + 'title' => 'Perbincangan', 35 35 'unresolved_count' => '', 36 36 37 37 'collapse' => [ ··· 40 40 ], 41 41 42 42 'empty' => [ 43 - 'empty' => '', 43 + 'empty' => 'Tiada perbincangan buat masa sekarang!', 44 44 'hidden' => '', 45 45 ], 46 46 47 47 'lock' => [ 48 48 'button' => [ 49 - 'lock' => '', 50 - 'unlock' => '', 49 + 'lock' => 'Kunci perbincangan', 50 + 'unlock' => 'Nyahkunci perbincangan', 51 51 ], 52 52 53 53 'prompt' => [ 54 - 'lock' => '', 55 - 'unlock' => '', 54 + 'lock' => 'Alasan untuk mengunci', 55 + 'unlock' => 'Anda pasti mahu nyahkunci?', 56 56 ], 57 57 ], 58 58 ··· 69 69 ], 70 70 71 71 'message_type' => [ 72 - 'disqualify' => '', 73 - 'hype' => '', 74 - 'mapper_note' => '', 75 - 'nomination_reset' => '', 76 - 'praise' => '', 77 - 'problem' => '', 78 - 'problem_warning' => '', 79 - 'review' => '', 80 - 'suggestion' => '', 72 + 'disqualify' => 'Singkirkan', 73 + 'hype' => 'Hype!', 74 + 'mapper_note' => 'Nota', 75 + 'nomination_reset' => 'Set Semula Pencalonan', 76 + 'praise' => 'Puji', 77 + 'problem' => 'Masalah', 78 + 'problem_warning' => 'Laporkan Masalah', 79 + 'review' => 'Semak', 80 + 'suggestion' => 'Cadangan', 81 81 ], 82 82 83 83 'message_type_title' => [ 84 - 'disqualify' => '', 85 - 'hype' => '', 86 - 'mapper_note' => '', 87 - 'nomination_reset' => '', 88 - 'praise' => '', 89 - 'problem' => '', 90 - 'problem_warning' => '', 91 - 'review' => '', 92 - 'suggestion' => '', 84 + 'disqualify' => 'Hantar Penyingkiran', 85 + 'hype' => 'Hantar Hype!', 86 + 'mapper_note' => 'Hantar Nota', 87 + 'nomination_reset' => 'Buang semua Pencalonan', 88 + 'praise' => 'Hantar Pujian', 89 + 'problem' => 'Hantar Masalah', 90 + 'problem_warning' => 'Hantar Masalah', 91 + 'review' => 'Hantar Semakan', 92 + 'suggestion' => 'Hantar Cadangan', 93 93 ], 94 94 95 95 'mode' => [ 96 - 'events' => '', 97 - 'general' => '', 98 - 'reviews' => '', 99 - 'timeline' => '', 96 + 'events' => 'Sejarah', 97 + 'general' => 'Umum :scope', 98 + 'reviews' => 'Semakan', 99 + 'timeline' => 'Garis Masa', 100 100 'scopes' => [ 101 - 'general' => '', 102 - 'generalAll' => '', 101 + 'general' => 'Kesukaran ini', 102 + 'generalAll' => 'Semua kesukaran', 103 103 ], 104 104 ], 105 105 106 106 'new' => [ 107 - 'pin' => '', 107 + 'pin' => 'Semat', 108 108 'timestamp' => '', 109 109 'timestamp_missing' => '', 110 - 'title' => '', 111 - 'unpin' => '', 110 + 'title' => 'Perbincangan Baharu', 111 + 'unpin' => 'Nyahsemat', 112 112 ], 113 113 114 114 'review' => [ 115 - 'new' => '', 115 + 'new' => 'Semakan Baharu', 116 116 'embed' => [ 117 - 'delete' => '', 118 - 'missing' => '', 119 - 'unlink' => '', 120 - 'unsaved' => '', 117 + 'delete' => 'Padam', 118 + 'missing' => '[PERBINCANGAN DIPADAM]', 119 + 'unlink' => 'Nyahpaut', 120 + 'unsaved' => 'Nyahsimpan', 121 121 'timestamp' => [ 122 122 'all-diff' => '', 123 123 'diff' => '', ··· 127 127 'paragraph' => '', 128 128 'praise' => '', 129 129 'problem' => '', 130 - 'suggestion' => '', 130 + 'suggestion' => 'masukkan cadangan', 131 131 ], 132 132 ], 133 133 ··· 136 136 ], 137 137 138 138 'sort' => [ 139 - 'created_at' => '', 140 - 'timeline' => '', 141 - 'updated_at' => '', 139 + 'created_at' => 'Waktu direka', 140 + 'timeline' => 'Garis Masa', 141 + 'updated_at' => 'Kemas kini terakhir', 142 142 ], 143 143 144 144 'stats' => [ 145 - 'deleted' => '', 146 - 'mapper_notes' => '', 147 - 'mine' => '', 148 - 'pending' => '', 149 - 'praises' => '', 150 - 'resolved' => '', 151 - 'total' => '', 145 + 'deleted' => 'Dipadam', 146 + 'mapper_notes' => 'Nota', 147 + 'mine' => 'Saya', 148 + 'pending' => 'Belum Selesai', 149 + 'praises' => 'Pujian', 150 + 'resolved' => 'Selesai', 151 + 'total' => 'Semua', 152 152 ], 153 153 154 154 'status-messages' => [ 155 - 'approved' => '', 156 - 'graveyard' => "", 157 - 'loved' => '', 158 - 'ranked' => '', 159 - 'wip' => '', 155 + 'approved' => 'Beatmap ini diluluskan pada :date!', 156 + 'graveyard' => "Beatmap ini tidak dikemaskini sejak :date jadi ia telah dikuburkan...", 157 + 'loved' => 'Beatmap ini ditambah kepada digemari pada :date!', 158 + 'ranked' => 'Beatmap ini dipangkatkan pada :date!', 159 + 'wip' => 'Nota: Beatmap ini ditanda sebagai "dalam selenggara" oleh pencipta.', 160 160 ], 161 161 162 162 'votes' => [ ··· 185 185 ], 186 186 187 187 'feedback' => [ 188 - 'button' => '', 188 + 'button' => 'Tinggalkan Maklum Balas', 189 189 ], 190 190 191 191 'nominations' => [ 192 192 'already_nominated' => '', 193 193 'cannot_nominate' => '', 194 - 'delete' => '', 194 + 'delete' => 'Padam', 195 195 'delete_own_confirm' => '', 196 196 'delete_other_confirm' => '', 197 - 'disqualification_prompt' => '', 198 - 'disqualified_at' => '', 197 + 'disqualification_prompt' => 'Alasan untuk penyingkiran?', 198 + 'disqualified_at' => 'Tersingkir :time_ago (:reason).', 199 199 'disqualified_no_reason' => '', 200 - 'disqualify' => '', 200 + 'disqualify' => 'Singkirkan', 201 201 'incorrect_state' => '', 202 202 'love' => '', 203 203 'love_choose' => '', ··· 209 209 'remove_from_loved' => '', 210 210 'remove_from_loved_prompt' => '', 211 211 'required_text' => '', 212 - 'reset_message_deleted' => '', 212 + 'reset_message_deleted' => 'padam', 213 213 'title' => '', 214 214 'unresolved_issues' => '', 215 215 ··· 217 217 '_' => '', 218 218 'unresolved_problems' => '', 219 219 'problems' => '', 220 - 'on' => '', 220 + 'on' => 'pada :date', 221 221 'queue' => '', 222 - 'soon' => '', 222 + 'soon' => 'akan datang', 223 223 ], 224 224 225 225 'reset_at' => [ ··· 228 228 ], 229 229 230 230 'reset_confirm' => [ 231 - 'disqualify' => '', 231 + 'disqualify' => 'Anda pasti? Ini akan keluarkan beatmap ini dari kelayakan dan set semula proses pencalonan.', 232 232 'nomination_reset' => '', 233 233 'problem_warning' => '', 234 234 ], ··· 237 237 'listing' => [ 238 238 'search' => [ 239 239 'prompt' => '', 240 - 'login_required' => '', 240 + 'login_required' => 'Daftar masuk untuk cari.', 241 241 'options' => '', 242 242 'supporter_filter' => '', 243 - 'not-found' => '', 244 - 'not-found-quote' => '', 243 + 'not-found' => 'tiada hasil carian', 244 + 'not-found-quote' => '... tidak, tak jumpa apa-apa.', 245 245 'filters' => [ 246 - 'extra' => '', 247 - 'general' => '', 248 - 'genre' => '', 249 - 'language' => '', 250 - 'mode' => '', 251 - 'nsfw' => '', 252 - 'played' => '', 246 + 'extra' => 'Tambahan', 247 + 'general' => 'Umum', 248 + 'genre' => 'Genre', 249 + 'language' => 'Bahasa', 250 + 'mode' => 'Mod', 251 + 'nsfw' => 'Kandungan Sensitif', 252 + 'played' => 'Dimain', 253 253 'rank' => '', 254 - 'status' => '', 254 + 'status' => 'Kategori', 255 255 ], 256 256 'sorting' => [ 257 - 'title' => '', 258 - 'artist' => '', 259 - 'difficulty' => '', 260 - 'favourites' => '', 261 - 'updated' => '', 257 + 'title' => 'Judul', 258 + 'artist' => 'Artis', 259 + 'difficulty' => 'Kesukaran', 260 + 'favourites' => 'Kegemaran', 261 + 'updated' => 'Kemaskini', 262 262 'ranked' => '', 263 - 'rating' => '', 264 - 'plays' => '', 263 + 'rating' => 'Nilai', 264 + 'plays' => 'Mainan', 265 265 'relevance' => '', 266 - 'nominations' => '', 266 + 'nominations' => 'Pencalonan', 267 267 ], 268 268 'supporter_filter_quote' => [ 269 269 '_' => '', ··· 279 279 'spotlights' => '', 280 280 ], 281 281 'mode' => [ 282 - 'all' => '', 283 - 'any' => '', 282 + 'all' => 'Semua', 283 + 'any' => 'Mana-Mana', 284 284 'osu' => '', 285 285 'taiko' => '', 286 286 'fruits' => '', ··· 288 288 'undefined' => '', 289 289 ], 290 290 'status' => [ 291 - 'any' => '', 291 + 'any' => 'Mana-Mana', 292 292 'approved' => '', 293 - 'favourites' => '', 294 - 'graveyard' => '', 295 - 'leaderboard' => '', 296 - 'loved' => '', 293 + 'favourites' => 'Kegemaran', 294 + 'graveyard' => 'Kubur', 295 + 'leaderboard' => 'Ada Carta', 296 + 'loved' => 'Digemari', 297 297 'mine' => '', 298 298 'pending' => '', 299 - 'wip' => '', 299 + 'wip' => 'WIP', 300 300 'qualified' => '', 301 301 'ranked' => '', 302 302 ], 303 303 'genre' => [ 304 304 'any' => '', 305 305 'unspecified' => '', 306 - 'video-game' => '', 307 - 'anime' => '', 308 - 'rock' => '', 309 - 'pop' => '', 310 - 'other' => '', 311 - 'novelty' => '', 312 - 'hip-hop' => '', 313 - 'electronic' => '', 314 - 'metal' => '', 315 - 'classical' => '', 316 - 'folk' => '', 317 - 'jazz' => '', 306 + 'video-game' => 'Permainan Video', 307 + 'anime' => 'Anime', 308 + 'rock' => 'Rock', 309 + 'pop' => 'Pop', 310 + 'other' => 'Lain-Lain', 311 + 'novelty' => 'Noveliti', 312 + 'hip-hop' => 'Hip Hop', 313 + 'electronic' => 'Elektronik', 314 + 'metal' => 'Metal', 315 + 'classical' => 'Klasik', 316 + 'folk' => 'Rakyat', 317 + 'jazz' => 'Jaz', 318 318 ], 319 319 'language' => [ 320 - 'any' => '', 321 - 'english' => '', 322 - 'chinese' => '', 323 - 'french' => '', 324 - 'german' => '', 325 - 'italian' => '', 326 - 'japanese' => '', 327 - 'korean' => '', 328 - 'spanish' => '', 329 - 'swedish' => '', 330 - 'russian' => '', 331 - 'polish' => '', 332 - 'instrumental' => '', 333 - 'other' => '', 320 + 'any' => 'Mana-Mana', 321 + 'english' => 'Inggeris', 322 + 'chinese' => 'Cina', 323 + 'french' => 'Perancis', 324 + 'german' => 'German', 325 + 'italian' => 'Itali', 326 + 'japanese' => 'Jepun', 327 + 'korean' => 'Korea', 328 + 'spanish' => 'Sepanyol', 329 + 'swedish' => 'Sweden', 330 + 'russian' => 'Rusia', 331 + 'polish' => 'Poland', 332 + 'instrumental' => 'Instrumental', 333 + 'other' => 'Lain-Lain', 334 334 'unspecified' => '', 335 335 ], 336 336 337 337 'nsfw' => [ 338 - 'exclude' => '', 339 - 'include' => '', 338 + 'exclude' => 'Sorok', 339 + 'include' => 'Tunjuk', 340 340 ], 341 341 342 342 'played' => [ 343 - 'any' => '', 343 + 'any' => 'Mana-Mana', 344 344 'played' => '', 345 345 'unplayed' => '', 346 346 ], 347 347 'extra' => [ 348 - 'video' => '', 349 - 'storyboard' => '', 348 + 'video' => 'Ada Video', 349 + 'storyboard' => 'Ada Papan Cerita', 350 350 ], 351 351 'rank' => [ 352 - 'any' => '', 352 + 'any' => 'Mana-Mana', 353 353 'XH' => '', 354 354 'X' => '', 355 355 'SH' => '', ··· 360 360 'D' => '', 361 361 ], 362 362 'panel' => [ 363 - 'playcount' => '', 363 + 'playcount' => 'Kiraan main: :count', 364 364 'favourites' => '', 365 365 ], 366 366 'variant' => [ 367 367 'mania' => [ 368 - '4k' => '', 369 - '7k' => '', 370 - 'all' => '', 368 + '4k' => '4k', 369 + '7k' => '7k', 370 + 'all' => 'Semua', 371 371 ], 372 372 ], 373 373 ];
+1 -1
resources/lang/ms-MY/beatmapset_discussion_votes.php
··· 9 9 ], 10 10 11 11 'item' => [ 12 - 'score' => '', 12 + 'score' => 'Markah', 13 13 ], 14 14 ];
+97 -96
resources/lang/ms-MY/beatmapsets.php
··· 5 5 6 6 return [ 7 7 'availability' => [ 8 - 'disabled' => '', 9 - 'parts-removed' => '', 10 - 'more-info' => '', 11 - 'rule_violation' => '', 8 + 'disabled' => 'Beatmap ini tidak tersedia untuk muat turun ketika ini.', 9 + 'parts-removed' => 'Beberapa bahagian beatmap ini telah dibuang atas permintaan pencipta atau pemegang pihak ketiga.', 10 + 'more-info' => 'Periksa sini untuk lebih maklumat.', 11 + 'rule_violation' => 'Beberapa aset dalam peta ini telah dibuang selepas dipertimbangkan sebagai tidak sesuai untuk kegunaan dalam osu!.', 12 12 ], 13 13 14 14 'cover' => [ 15 - 'deleted' => '', 15 + 'deleted' => 'Beatmap yang dipadam', 16 16 ], 17 17 18 18 'download' => [ 19 - 'limit_exceeded' => '', 19 + 'limit_exceeded' => 'Sabar, main yang dah ada dulu.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [ 23 - 'label' => '', 24 + 'label' => 'Artis yang Ditampilkan', 24 25 ], 25 26 26 27 'index' => [ 27 - 'title' => '', 28 - 'guest_title' => '', 28 + 'title' => 'Senarai Beatmap', 29 + 'guest_title' => 'Beatmap', 29 30 ], 30 31 31 32 'panel' => [ 32 - 'empty' => '', 33 + 'empty' => 'tiada beatmap', 33 34 34 35 'download' => [ 35 - 'all' => '', 36 - 'video' => '', 37 - 'no_video' => '', 38 - 'direct' => '', 36 + 'all' => 'muat turun', 37 + 'video' => 'muat turun berserta video', 38 + 'no_video' => 'muat turun tanpa video', 39 + 'direct' => 'buka di osu!direct', 39 40 ], 40 41 ], 41 42 42 43 'nominate' => [ 43 - 'bng_limited_too_many_rulesets' => '', 44 - 'full_nomination_required' => '', 45 - 'hybrid_requires_modes' => '', 46 - 'incorrect_mode' => '', 47 - 'invalid_limited_nomination' => '', 48 - 'invalid_ruleset' => '', 49 - 'too_many' => '', 44 + 'bng_limited_too_many_rulesets' => 'Pencalon percubaan tidak boleh mencalonkan banyak set peraturan.', 45 + 'full_nomination_required' => 'Anda mesti menjadi pencalon penuh untuk melakukan pencalonan terakhir sesebuah set peraturan.', 46 + 'hybrid_requires_modes' => 'Satu beatmap hibrid memerlukan anda untuk memilih sekurang-kurangnya satu mod permainan untuk pencalonan.', 47 + 'incorrect_mode' => 'Anda tiada kebenaran untuk mencalonkan mod :mode', 48 + 'invalid_limited_nomination' => 'Beatmap ini mempunyai pencalonan tidak sah dan tidak boleh layak dalam keadaan ini.', 49 + 'invalid_ruleset' => 'Pencalonan ini mempunyai set peraturan tidak sah.', 50 + 'too_many' => 'Keperluan pencalonan telah dikabulkan.', 50 51 'too_many_non_main_ruleset' => '', 51 52 52 53 'dialog' => [ 53 - 'confirmation' => '', 54 - 'header' => '', 54 + 'confirmation' => 'Anda pasti mahu mencalonkan beatmap ini?', 55 + 'header' => 'Calonkan Beatmap', 55 56 'hybrid_warning' => '', 56 57 'current_main_ruleset' => '', 57 - 'which_modes' => '', 58 + 'which_modes' => 'Calonkan untuk mod apa?', 58 59 ], 59 60 ], 60 61 61 62 'nsfw_badge' => [ 62 - 'label' => '', 63 + 'label' => 'Sensitif', 63 64 ], 64 65 65 66 'show' => [ 66 - 'discussion' => '', 67 + 'discussion' => 'Perbincangan', 67 68 68 69 'admin' => [ 69 70 'full_size_cover' => '', ··· 85 86 'updated_timeago' => '', 86 87 87 88 'download' => [ 88 - '_' => '', 89 + '_' => 'Muat Turun', 89 90 'direct' => '', 90 - 'no-video' => '', 91 - 'video' => '', 91 + 'no-video' => 'tanpa Video', 92 + 'video' => 'berserta Video', 92 93 ], 93 94 94 95 'login_required' => [ 95 - 'bottom' => '', 96 - 'top' => '', 96 + 'bottom' => 'untuk akses lebih ciri-ciri', 97 + 'top' => 'Daftar Masuk', 97 98 ], 98 99 ], 99 100 ··· 114 115 'action' => '', 115 116 116 117 'current' => [ 117 - '_' => '', 118 + '_' => 'Peta ini mempunyai status :status.', 118 119 119 120 'status' => [ 120 121 'pending' => '', ··· 129 130 130 131 'report' => [ 131 132 '_' => '', 132 - 'button' => '', 133 - 'link' => '', 133 + 'button' => 'Laporkan Masalah', 134 + 'link' => 'sini', 134 135 ], 135 136 ], 136 137 137 138 'info' => [ 138 - 'description' => '', 139 - 'genre' => '', 140 - 'language' => '', 141 - 'no_scores' => '', 142 - 'nominators' => '', 143 - 'nsfw' => '', 139 + 'description' => 'Perihal', 140 + 'genre' => 'Genre', 141 + 'language' => 'Bahasa', 142 + 'no_scores' => 'Data masih lagi dikira...', 143 + 'nominators' => 'Pencalon', 144 + 'nsfw' => 'Kandungan sensitif', 144 145 'offset' => '', 145 - 'points-of-failure' => '', 146 - 'source' => '', 147 - 'storyboard' => '', 148 - 'success-rate' => '', 149 - 'tags' => '', 150 - 'video' => '', 146 + 'points-of-failure' => 'Titik Kegagalan', 147 + 'source' => 'Sumber', 148 + 'storyboard' => 'Beatmap ini mengandungi papan cerita', 149 + 'success-rate' => 'Kadar Berjaya', 150 + 'tags' => 'Tag', 151 + 'video' => 'Beatmap ini mengandungi video', 151 152 ], 152 153 153 154 'nsfw_warning' => [ 154 - 'details' => '', 155 - 'title' => '', 155 + 'details' => 'Beatmap ini mengandungi unsur sensitif, menyinggung perasaan dan tidak enak. Anda pasti mahu melihatnya?', 156 + 'title' => 'Kandungan Sensitif', 156 157 157 158 'buttons' => [ 158 - 'disable' => '', 159 - 'listing' => '', 160 - 'show' => '', 159 + 'disable' => 'Lumpuhkan amaran', 160 + 'listing' => 'Senarai Beatmap', 161 + 'show' => 'Tunjuk', 161 162 ], 162 163 ], 163 164 164 165 'scoreboard' => [ 165 - 'achieved' => '', 166 - 'country' => '', 167 - 'error' => '', 168 - 'friend' => '', 169 - 'global' => '', 170 - 'supporter-link' => '', 166 + 'achieved' => 'dicapai :when', 167 + 'country' => 'Peringkat Kebangsaan', 168 + 'error' => 'Peringkat gagal dimuat', 169 + 'friend' => 'Peringkat Rakan-Rakan', 170 + 'global' => 'Peringkat Dunia', 171 + 'supporter-link' => 'Tekan <a href=":link">sini</a> untuk lihat ciri-ciri menaik yang anda boleh dapat!', 171 172 'supporter-only' => '', 172 - 'title' => '', 173 + 'title' => 'Papan Markah', 173 174 174 175 'headers' => [ 175 - 'accuracy' => '', 176 - 'combo' => '', 177 - 'miss' => '', 178 - 'mods' => '', 179 - 'pin' => '', 180 - 'player' => '', 176 + 'accuracy' => 'Ketepatan', 177 + 'combo' => 'Kombo Maksima', 178 + 'miss' => 'Terlepas', 179 + 'mods' => 'Mod', 180 + 'pin' => 'Semat', 181 + 'player' => 'Pemain', 181 182 'pp' => '', 182 - 'rank' => '', 183 - 'score' => '', 184 - 'score_total' => '', 185 - 'time' => '', 183 + 'rank' => 'Kedudukan', 184 + 'score' => 'Markah', 185 + 'score_total' => 'Jumlah Markah', 186 + 'time' => 'Masa', 186 187 ], 187 188 188 189 'no_scores' => [ 189 - 'country' => '', 190 - 'friend' => '', 191 - 'global' => '', 192 - 'loading' => '', 190 + 'country' => 'Tiada orang dari negara anda telah menetapkan markah di peta ini!', 191 + 'friend' => 'Tiada kawan-kawan anda yang telah menetapkan markah di peta ini!', 192 + 'global' => 'Tiada markah. Mungkin kamu boleh cuba?', 193 + 'loading' => 'Memuatkan markah...', 193 194 'unranked' => '', 194 195 ], 195 196 'score' => [ 196 - 'first' => '', 197 + 'first' => 'Sedang Mendahului', 197 198 'own' => '', 198 199 ], 199 200 'supporter_link' => [ 200 201 '_' => '', 201 - 'here' => '', 202 + 'here' => 'sini', 202 203 ], 203 204 ], 204 205 205 206 'stats' => [ 206 - 'cs' => '', 207 - 'cs-mania' => '', 208 - 'drain' => '', 209 - 'accuracy' => '', 210 - 'ar' => '', 211 - 'stars' => '', 212 - 'total_length' => '', 213 - 'bpm' => '', 214 - 'count_circles' => '', 215 - 'count_sliders' => '', 207 + 'cs' => 'Besar Bulatan', 208 + 'cs-mania' => 'Kiraan Kekunci', 209 + 'drain' => 'Aliran Nyawa', 210 + 'accuracy' => 'Ketepatan', 211 + 'ar' => 'Kadar Penghampiran', 212 + 'stars' => 'Nilai Bintang', 213 + 'total_length' => 'Tempoh (Tempoh Aliran: :hit_length)', 214 + 'bpm' => 'BPM', 215 + 'count_circles' => 'Kiraan Bulatan', 216 + 'count_sliders' => 'Kiraan Peluncur', 216 217 'offset' => '', 217 - 'user-rating' => '', 218 - 'rating-spread' => '', 219 - 'nominations' => '', 220 - 'playcount' => '', 218 + 'user-rating' => 'Penilaian Pengguna', 219 + 'rating-spread' => 'Sebaran Penilaian', 220 + 'nominations' => 'Pencalonan', 221 + 'playcount' => 'Kiraan Mainan', 221 222 ], 222 223 223 224 'status' => [ 224 - 'ranked' => '', 225 - 'approved' => '', 226 - 'loved' => '', 227 - 'qualified' => '', 228 - 'wip' => '', 229 - 'pending' => '', 230 - 'graveyard' => '', 225 + 'ranked' => 'Diperingkat', 226 + 'approved' => 'Diluluskan', 227 + 'loved' => 'Dicintai', 228 + 'qualified' => 'Layak', 229 + 'wip' => 'WIP', 230 + 'pending' => 'Menunggu', 231 + 'graveyard' => 'Dikuburkan', 231 232 ], 232 233 ], 233 234 234 235 'spotlight_badge' => [ 235 - 'label' => '', 236 + 'label' => 'Sorotan', 236 237 ], 237 238 ];
+1
resources/lang/ms-MY/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+41 -41
resources/lang/ms-MY/forum.php
··· 4 4 // See the LICENCE file in the repository root for full licence text. 5 5 6 6 return [ 7 - 'pinned_topics' => '', 8 - 'slogan' => "", 9 - 'subforums' => '', 10 - 'title' => '', 7 + 'pinned_topics' => 'Topik Disemat', 8 + 'slogan' => "bahaya kalau main sendiri.", 9 + 'subforums' => 'Subforum', 10 + 'title' => 'Forum', 11 11 12 12 'covers' => [ 13 13 'edit' => '', ··· 25 25 ], 26 26 27 27 'forums' => [ 28 - 'forums' => '', 29 - 'latest_post' => '', 28 + 'forums' => 'Forum', 29 + 'latest_post' => 'Hantaran Terkini', 30 30 31 31 'index' => [ 32 - 'title' => '', 32 + 'title' => 'Indeks Forum', 33 33 ], 34 34 35 35 'topics' => [ 36 - 'empty' => '', 36 + 'empty' => 'Tiada topik!', 37 37 ], 38 38 ], 39 39 40 40 'mark_as_read' => [ 41 - 'forum' => '', 42 - 'forums' => '', 43 - 'busy' => '', 41 + 'forum' => 'Tanda forum sebagai sudah baca', 42 + 'forums' => 'Tanda forum sebagai sudah baca', 43 + 'busy' => 'Menanda sebagai sudah baca...', 44 44 ], 45 45 46 46 'post' => [ 47 - 'confirm_destroy' => '', 48 - 'confirm_restore' => '', 47 + 'confirm_destroy' => 'Betul nak padam hantaran?', 48 + 'confirm_restore' => 'Betul nak kembalikan hantaran?', 49 49 'edited' => '', 50 - 'posted_at' => '', 51 - 'posted_by_in' => '', 50 + 'posted_at' => 'dihantar :when', 51 + 'posted_by_in' => 'dihantar oleh :username di :forum', 52 52 53 53 'actions' => [ 54 - 'destroy' => '', 55 - 'edit' => '', 56 - 'report' => '', 57 - 'restore' => '', 54 + 'destroy' => 'Padam hantaran', 55 + 'edit' => 'Sunting hantaran', 56 + 'report' => 'Laporkan hantaran', 57 + 'restore' => 'Pulihkan hantaran', 58 58 ], 59 59 60 60 'create' => [ 61 61 'title' => [ 62 - 'reply' => '', 62 + 'reply' => 'Balasan baru', 63 63 ], 64 64 ], 65 65 66 66 'info' => [ 67 67 'post_count' => '', 68 - 'topic_starter' => '', 68 + 'topic_starter' => 'Topik Permulaan', 69 69 ], 70 70 ], 71 71 72 72 'search' => [ 73 - 'go_to_post' => '', 74 - 'post_number_input' => '', 75 - 'total_posts' => '', 73 + 'go_to_post' => 'Pergi ke hantaran', 74 + 'post_number_input' => 'masukkan nombor hantaran', 75 + 'total_posts' => ':posts_count jumlah hantaran', 76 76 ], 77 77 78 78 'topic' => [ 79 - 'confirm_destroy' => '', 80 - 'confirm_restore' => '', 81 - 'deleted' => '', 82 - 'go_to_latest' => '', 83 - 'has_replied' => '', 84 - 'in_forum' => '', 85 - 'latest_post' => '', 86 - 'latest_reply_by' => '', 87 - 'new_topic' => '', 88 - 'new_topic_login' => '', 89 - 'post_reply' => '', 90 - 'reply_box_placeholder' => '', 79 + 'confirm_destroy' => 'Betul nak padam topik?', 80 + 'confirm_restore' => 'Betul nak kembalikan topik?', 81 + 'deleted' => 'topik yang dipadam', 82 + 'go_to_latest' => 'kunjungi hantaran terkini', 83 + 'has_replied' => 'Anda telah hantar balasan ke topik ini', 84 + 'in_forum' => 'di forum :forum', 85 + 'latest_post' => ':when oleh :user', 86 + 'latest_reply_by' => 'balasan terakhir oleh :user', 87 + 'new_topic' => 'Topik baharu', 88 + 'new_topic_login' => 'Daftar masuk untuk hantar topik baru', 89 + 'post_reply' => 'Hantar', 90 + 'reply_box_placeholder' => 'Tulis sini untuk balas', 91 91 'reply_title_prefix' => '', 92 - 'started_by' => '', 93 - 'started_by_verbose' => '', 92 + 'started_by' => 'oleh :user', 93 + 'started_by_verbose' => 'dimulai oleh :user', 94 94 95 95 'actions' => [ 96 - 'destroy' => '', 97 - 'restore' => '', 96 + 'destroy' => 'Padam topik', 97 + 'restore' => 'Pulihkan topik', 98 98 ], 99 99 100 100 'create' => [ 101 - 'close' => '', 101 + 'close' => 'Tutup', 102 102 'preview' => '', 103 103 // TL note: this is used in the topic reply preview, when 104 104 // the user goes back from previewing to editing the reply
+5 -5
resources/lang/ms-MY/friends.php
··· 4 4 // See the LICENCE file in the repository root for full licence text. 5 5 6 6 return [ 7 - 'title_compact' => '', 8 - 'too_many' => '', 7 + 'title_compact' => 'kawan', 8 + 'too_many' => 'Had kawan dicapai', 9 9 10 10 'buttons' => [ 11 - 'add' => '', 12 - 'disabled' => '', 13 - 'remove' => '', 11 + 'add' => 'tambah kawan', 12 + 'disabled' => 'pengikut', 13 + 'remove' => 'keluarkan kawan', 14 14 ], 15 15 ];
+12 -12
resources/lang/ms-MY/multiplayer.php
··· 5 5 6 6 return [ 7 7 'empty' => [ 8 - '_' => '', 9 - 'playlists' => '', 10 - 'realtime' => '', 8 + '_' => 'Tiada permainan osu!(lazer) :type_group dimainkan lagi!', 9 + 'playlists' => 'senarai main', 10 + 'realtime' => 'main beramai-ramai', 11 11 ], 12 12 13 13 'room' => [ 14 - 'hosted_by' => '', 15 - 'invalid_password' => '', 16 - 'map_count' => '', 17 - 'player_count' => '', 18 - 'time_left' => '', 14 + 'hosted_by' => 'diacarakan oleh :user', 15 + 'invalid_password' => 'Kata laluan bilik tidak sah', 16 + 'map_count' => ':count_delimited peta|:count_delimited peta', 17 + 'player_count' => ':count_delimited pemain|:count_delimited pemain', 18 + 'time_left' => ':time tinggal', 19 19 20 20 'errors' => [ 21 - 'duration_too_long' => '', 21 + 'duration_too_long' => 'Tempoh terlalu panjang.', 22 22 ], 23 23 24 24 'status' => [ 25 - 'active' => '', 26 - 'ended' => '', 27 - 'soon' => '', 25 + 'active' => 'aktif', 26 + 'ended' => 'tamat', 27 + 'soon' => 'akan tamat', 28 28 ], 29 29 ], 30 30 ];
+15 -15
resources/lang/ms-MY/news.php
··· 5 5 6 6 return [ 7 7 'index' => [ 8 - 'title_page' => '', 8 + 'title_page' => 'wartaosu!', 9 9 10 10 'nav' => [ 11 - 'newer' => '', 12 - 'older' => '', 11 + 'newer' => 'Berita lebih terkini', 12 + 'older' => 'Berita lebih lapuk', 13 13 ], 14 14 15 15 'title' => [ 16 - '_' => '', 17 - 'info' => '', 16 + '_' => 'berita', 17 + 'info' => 'halaman utama', 18 18 ], 19 19 ], 20 20 21 21 'show' => [ 22 - 'by' => '', 22 + 'by' => 'oleh :user', 23 23 24 24 'nav' => [ 25 - 'newer' => '', 26 - 'older' => '', 25 + 'newer' => 'Berita lebih terkini', 26 + 'older' => 'Berita lebih lapuk', 27 27 ], 28 28 29 29 'title' => [ 30 - '_' => '', 31 - 'info' => '', 30 + '_' => 'berita', 31 + 'info' => 'topik berita', 32 32 ], 33 33 ], 34 34 35 35 'sidebar' => [ 36 - 'archive' => '', 36 + 'archive' => 'Pustaka Berita', 37 37 ], 38 38 39 39 'store' => [ 40 - 'button' => '', 41 - 'ok' => '', 40 + 'button' => 'Kemaskini', 41 + 'ok' => 'Senarai telah dikemaskini.', 42 42 ], 43 43 44 44 'update' => [ 45 - 'button' => '', 46 - 'ok' => '', 45 + 'button' => 'Kemaskini', 46 + 'ok' => 'Hantaran dikemaskini.', 47 47 ], 48 48 ];
+15 -15
resources/lang/ms-MY/rankings.php
··· 18 18 ], 19 19 20 20 'kudosu' => [ 21 - 'total' => '', 22 - 'available' => '', 23 - 'used' => '', 21 + 'total' => 'Diterima', 22 + 'available' => 'Tersedia', 23 + 'used' => 'Digunakan', 24 24 ], 25 25 26 26 'performance' => [ 27 - 'insufficient_history' => '', 27 + 'insufficient_history' => 'Pengguna ini mempunyai kurang dari 30 hari bagi sejarah peringkat terkini.', 28 28 ], 29 29 30 30 'type' => [ 31 - 'charts' => 'sorotan', 31 + 'charts' => 'sorotan (lama)', 32 32 'country' => 'negara', 33 - 'kudosu' => '', 34 - 'multiplayer' => 'pemainan beramai', 33 + 'kudosu' => 'kudosu', 34 + 'multiplayer' => 'pemainan beramai-ramai', 35 35 'performance' => 'pencapaian', 36 36 'score' => 'markah', 37 37 'seasons' => 'musim', 38 38 ], 39 39 40 40 'seasons' => [ 41 - 'empty' => 'Musim ini belum memiliki ruangan.', 42 - 'ongoing' => 'Musim ini sedang berlangsung (ke depannya, akan terdapat lebih banyak senarai untuk dimainkan).', 41 + 'empty' => 'Musim ini belum memiliki bilik.', 42 + 'ongoing' => 'Musim ini masih lagi berlangsung (lebih banyak senarai main akan ditambah).', 43 43 'room_count' => 'Jumlah senarai main', 44 - 'url' => 'Menampilkan maklumat lebih lanjut seputar musim yang dipilih.', 44 + 'url' => 'Paparan lebih banyak maklumat untuk musim itu.', 45 45 ], 46 46 47 47 'spotlight' => [ 48 48 'end_date' => 'Tarikh Akhir', 49 - 'map_count' => 'Kiraan Map', 49 + 'map_count' => 'Kiraan Peta', 50 50 'participants' => 'Peserta', 51 51 'start_date' => 'Tarikh Mula', 52 52 ], ··· 55 55 'accuracy' => 'Ketepatan', 56 56 'active_users' => 'Pengguna aktif', 57 57 'country' => 'Negara', 58 - 'play_count' => 'Kiraan Main', 58 + 'play_count' => 'Kiraan Mainan', 59 59 'performance' => 'Pencapaian', 60 - 'total_score' => 'Jumlah Skor', 61 - 'ranked_score' => 'Skor Ranked', 62 - 'average_score' => 'Skor Purata', 60 + 'total_score' => 'Jumlah Markah', 61 + 'ranked_score' => 'Markah Diperingkat', 62 + 'average_score' => 'Markah Purata', 63 63 'average_performance' => 'Prestasi Purata. ', 64 64 'ss' => '', 65 65 's' => '',
+10 -10
resources/lang/ms-MY/scores.php
··· 5 5 6 6 return [ 7 7 'show' => [ 8 - 'non_preserved' => '', 8 + 'non_preserved' => 'Markah ini ditanda untuk dipadam dan akan lenyap sebentar lagi.', 9 9 'title' => '', 10 10 11 11 'beatmap' => [ 12 - 'by' => '', 12 + 'by' => 'oleh :artist', 13 13 ], 14 14 15 15 'player' => [ 16 - 'by' => '', 17 - 'submitted_on' => '', 16 + 'by' => 'Dimain oleh', 17 + 'submitted_on' => 'Diserahkan oleh', 18 18 19 19 'rank' => [ 20 - 'country' => '', 21 - 'global' => '', 20 + 'country' => 'Kedudukan Kebangsaan', 21 + 'global' => 'Kedudukan Dunia', 22 22 ], 23 23 ], 24 24 ], 25 25 26 26 'status' => [ 27 - 'non_best' => '', 28 - 'no_pp' => '', 29 - 'processing' => '', 30 - 'no_rank' => '', 27 + 'non_best' => 'Hanya markah terbaik peribadi dianugerahkan pp', 28 + 'no_pp' => 'pp tidak dianugerahkan untuk markah ini', 29 + 'processing' => 'Markah ini masih dikira dan akan dipaparkan sebentar lagi', 30 + 'no_rank' => 'Markah ini tiada peringkat ekoran ianya tidak diperingkat atau ditanda untuk dipadam', 31 31 ], 32 32 ];
+29 -29
resources/lang/ms-MY/store.php
··· 5 5 6 6 return [ 7 7 'cart' => [ 8 - 'checkout' => '', 9 - 'empty_cart' => '', 10 - 'info' => '', 11 - 'more_goodies' => '', 12 - 'shipping_fees' => '', 13 - 'title' => '', 14 - 'total' => '', 8 + 'checkout' => 'Daftar keluar', 9 + 'empty_cart' => 'Buang semua barang dari kereta sorong', 10 + 'info' => ':count_delimited barang dalam kereta sorong ($:subtotal)|:count_delimited barang dalam kereta sorong ($:subtotal)', 11 + 'more_goodies' => 'Saya nak tengok lagi cenderahati sebelum habiskan pesanan', 12 + 'shipping_fees' => 'yuran hantaran', 13 + 'title' => 'Kereta Sorong Beli-Belah', 14 + 'total' => 'jumlah', 15 15 16 16 'errors_no_checkout' => [ 17 - 'line_1' => '', 18 - 'line_2' => '', 17 + 'line_1' => 'Alamak, ada masalah dengan barang awak yang menghalang daftar keluar!', 18 + 'line_2' => 'Buang atau kemaskini barang diatas untuk sambung.', 19 19 ], 20 20 21 21 'empty' => [ 22 - 'text' => '', 22 + 'text' => 'Kereta sorong anda kosong.', 23 23 'return_link' => [ 24 - '_' => '', 25 - 'link_text' => '', 24 + '_' => 'Kembali ke :link untuk cari beberapa cenderahati!', 25 + 'link_text' => 'senarai kedai', 26 26 ], 27 27 ], 28 28 ], 29 29 30 30 'checkout' => [ 31 - 'cart_problems' => '', 32 - 'cart_problems_edit' => '', 33 - 'declined' => '', 34 - 'delayed_shipping' => '', 35 - 'hide_from_activity' => '', 36 - 'old_cart' => '', 37 - 'pay' => '', 38 - 'title_compact' => '', 31 + 'cart_problems' => 'Alamak, ada masalah dengan barang awak!', 32 + 'cart_problems_edit' => 'Tekan sini untuk sunting ia.', 33 + 'declined' => 'Pembayaran telah dibatalkan.', 34 + 'delayed_shipping' => 'Kami sedang mengalami pesanan yang banyak! Anda dialu-alukan meletak pesanan anda tetapi sila jangkakan **kelewatan seminggu atau dua** sambil kami mengurus pesanan semasa.', 35 + 'hide_from_activity' => 'Sorokkan semua tag osu!supporter dalam pesanan ini dari aktiviti saya', 36 + 'old_cart' => 'Kereta sorong anda nampaknya telah tamat tempoh dan sudah dimuatkan semula, sila cuba lagi.', 37 + 'pay' => 'Daftar keluar dengan Paypal', 38 + 'title_compact' => 'daftar keluar', 39 39 40 40 'has_pending' => [ 41 - '_' => '', 42 - 'link_text' => '', 41 + '_' => 'Anda mempunyai daftar keluar tidak lengkap, tekan :link untuk melihatnya.', 42 + 'link_text' => 'sini', 43 43 ], 44 44 45 45 'pending_checkout' => [ 46 - 'line_1' => '', 47 - 'line_2' => '', 46 + 'line_1' => 'Daftar keluar dimulakan sebelum ini tetapi tidak dilunaskan.', 47 + 'line_2' => 'Sambung daftar keluar dengan memilih kaedah pembayaran.', 48 48 ], 49 49 ], 50 50 51 - 'discount' => '', 52 - 'free' => '', 51 + 'discount' => 'diskaun :percent%', 52 + 'free' => 'percuma!', 53 53 54 54 'invoice' => [ 55 - 'contact' => '', 56 - 'date' => '', 57 - 'echeck_delay' => '', 55 + 'contact' => 'Hubungi:', 56 + 'date' => 'Tarikh:', 57 + 'echeck_delay' => 'Oleh kerana bayaran anda berupa eCheck, sila benarkan sampai 10 hari tambahan untuk bayaran ini untuk diproses PayPal!', 58 58 'hide_from_activity' => '', 59 59 'sent_via' => '', 60 60 'shipping_to' => '',
+194 -193
resources/lang/ms-MY/users.php
··· 4 4 // See the LICENCE file in the repository root for full licence text. 5 5 6 6 return [ 7 - 'deleted' => '', 7 + 'deleted' => '[pengguna dipadam]', 8 8 9 9 'beatmapset_activities' => [ 10 - 'title' => "", 11 - 'title_compact' => '', 10 + 'title' => "Sejarah Ubahsuai :user", 11 + 'title_compact' => 'Ubahsuai', 12 12 13 13 'discussions' => [ 14 - 'title_recent' => '', 14 + 'title_recent' => 'Perbincangan baru bermula', 15 15 ], 16 16 17 17 'events' => [ 18 - 'title_recent' => '', 18 + 'title_recent' => 'Peristiwa semasa', 19 19 ], 20 20 21 21 'posts' => [ 22 - 'title_recent' => '', 22 + 'title_recent' => 'Hantaran semasa', 23 23 ], 24 24 25 25 'votes_received' => [ ··· 32 32 ], 33 33 34 34 'blocks' => [ 35 - 'banner_text' => '', 36 - 'comment_text' => '', 37 - 'blocked_count' => '', 38 - 'hide_profile' => '', 39 - 'hide_comment' => '', 40 - 'forum_post_text' => '', 41 - 'not_blocked' => '', 42 - 'show_profile' => '', 43 - 'show_comment' => '', 44 - 'too_many' => '', 35 + 'banner_text' => 'Anda telah menyekat pengguna ini.', 36 + 'comment_text' => 'Balasan ini disorok.', 37 + 'blocked_count' => 'pengguna disekat (:count)', 38 + 'hide_profile' => 'Sorok profil', 39 + 'hide_comment' => 'sorok', 40 + 'forum_post_text' => 'Hantaran ini disorok.', 41 + 'not_blocked' => 'Pengguna itu tidak disekat.', 42 + 'show_profile' => 'Tunjuk profil', 43 + 'show_comment' => 'tunjuk', 44 + 'too_many' => 'Had sekatan dicapai.', 45 45 'button' => [ 46 - 'block' => '', 47 - 'unblock' => '', 46 + 'block' => 'Sekat', 47 + 'unblock' => 'Nyahsekat', 48 48 ], 49 49 ], 50 50 51 51 'card' => [ 52 52 'gift_supporter' => '', 53 - 'loading' => '', 54 - 'send_message' => '', 53 + 'loading' => 'Memuatkan...', 54 + 'send_message' => 'Hantar mesej', 55 55 ], 56 56 57 57 'create' => [ 58 58 'form' => [ 59 - 'password' => '', 60 - 'password_confirmation' => '', 61 - 'submit' => '', 62 - 'user_email' => '', 63 - 'user_email_confirmation' => '', 64 - 'username' => '', 59 + 'password' => 'kata laluan', 60 + 'password_confirmation' => 'sahkan kata laluan', 61 + 'submit' => 'cipta akaun', 62 + 'user_email' => 'emel', 63 + 'user_email_confirmation' => 'sahkan emel', 64 + 'username' => 'nama pengguna', 65 65 66 66 'tos_notice' => [ 67 - '_' => '', 68 - 'link' => '', 67 + '_' => 'dengan mencipta akaun anda menerima :link', 68 + 'link' => 'syarat perkhidmatan', 69 69 ], 70 70 ], 71 71 ], 72 72 73 73 'disabled' => [ 74 - 'title' => '', 75 - 'warning' => "", 74 + 'title' => 'Alamak! Nampaknya akaun anda telah dilumpuhkan.', 75 + 'warning' => "Kalau begitu anda telah melanggar peraturan, sila ingat bahawa terdapat tempoh penyejukan selama sebulan dimana kami tidak akan pertimbangkan sebarang permintaan pengampunan. Selepas tempoh ini, anda boleh hubungi kami sekiranya perlu. Sila ingat bahawa mencipta akaun baru selepas yang ini dilumpuhkan akan mengakibatkan <strong>lanjutan kepada tempoh penyejukan sebulan ini</strong>. Sila ingat juga bahawa untuk <strong>setiap akaun baru yang dicipta, anda melanggar peraturan lagi</strong>. Kami sarankan supaya anda jangan mengikut langkah ini!", 76 76 77 77 'if_mistake' => [ 78 - '_' => '', 79 - 'email' => '', 78 + '_' => 'Jika anda rasa ini satu kesilapan, anda boleh hubungi kami (melalui :email atau menekan simbol "?" di bahagian bawah kanan bucu laman ini). Sila ingat bahawa kami sentiasa yakin sepenuhnya dengan tindakan kami, sebab ia berdasarkan data yang kukuh. Kami mempunyai hak untuk mengendah permintaan anda sekiranya kami berasa anda secara sengaja tidak jujur.', 79 + 'email' => 'emel', 80 80 ], 81 81 82 82 'reasons' => [ 83 - 'compromised' => '', 84 - 'opening' => '', 83 + 'compromised' => 'Akaun akan dianggap terjejas. Ia berkemungkinan akan dilumpuhkan sebentar sambil identitinya dikenalpasti.', 84 + 'opening' => 'Terdapat beberapa sebab yang akan menyebabkan akaun anda dilumpuh:', 85 85 86 86 'tos' => [ 87 - '_' => '', 88 - 'community_rules' => '', 89 - 'tos' => '', 87 + '_' => 'Anda telah melanggar satu atau lebih daripada :community_rules atau :tos kami.', 88 + 'community_rules' => 'peraturan komuniti', 89 + 'tos' => 'syarat perkhidmatan', 90 90 ], 91 91 ], 92 92 ], 93 93 94 94 'filtering' => [ 95 - 'by_game_mode' => '', 95 + 'by_game_mode' => 'Ahli-ahli berdasarkan mod permainan', 96 96 ], 97 97 98 98 'force_reactivation' => [ 99 99 'reason' => [ 100 - 'inactive' => "", 101 - 'inactive_different_country' => "", 100 + 'inactive' => "Akaun anda tidak digunakan untuk tempoh berpanjangan.", 101 + 'inactive_different_country' => "Akaun anda tidak digunakan untuk tempoh berpanjangan.", 102 102 ], 103 103 ], 104 104 105 105 'login' => [ 106 - '_' => '', 107 - 'button' => '', 108 - 'button_posting' => '', 109 - 'email_login_disabled' => '', 110 - 'failed' => '', 111 - 'forgot' => '', 112 - 'info' => '', 113 - 'invalid_captcha' => '', 114 - 'locked_ip' => '', 115 - 'password' => '', 116 - 'register' => "", 117 - 'remember' => '', 118 - 'title' => '', 119 - 'username' => '', 106 + '_' => 'Daftar masuk', 107 + 'button' => 'Daftar masuk', 108 + 'button_posting' => 'Mendaftar masuk...', 109 + 'email_login_disabled' => 'Mendaftar masuk dengan emel dilumpuhkan ketika ini. Sebaliknya, sila guna nama pengguna.', 110 + 'failed' => 'Daftar masuk yang salah', 111 + 'forgot' => 'Lupa kata laluan?', 112 + 'info' => 'Sila daftar masuk untuk sambung', 113 + 'invalid_captcha' => 'Terlalu banyak percubaan log masuk, sila siapkan captcha dan cuba lagi. (Segar semula laman jika captcha tidak dapat dilihat)', 114 + 'locked_ip' => 'Alamat IP anda dikunci. Sila tunggu beberapa minit.', 115 + 'password' => 'Kata Laluan', 116 + 'register' => "Tiada akaun osu!? Cipta satu sekarang", 117 + 'remember' => 'Ingat komputer ini', 118 + 'title' => 'Sila daftar masuk untuk teruskan', 119 + 'username' => 'Nama Pengguna', 120 120 121 121 'beta' => [ 122 - 'main' => '', 123 - 'small' => '', 122 + 'main' => 'Akses beta ketika ini dihadkan kepada pengguna istimewa.', 123 + 'small' => '(osu!supporters akan masuk sebentar lagi)', 124 124 ], 125 125 ], 126 126 127 127 'ogp' => [ 128 - 'modding_description' => '', 129 - 'modding_description_empty' => '', 128 + 'modding_description' => 'Beatmap: :counts', 129 + 'modding_description_empty' => 'Pengguna ini tidak mempunyai apa-apa beatmap...', 130 130 131 131 'description' => [ 132 - '_' => '', 133 - 'country' => '', 134 - 'global' => '', 132 + '_' => 'Peringkat (:ruleset): :global | :country', 133 + 'country' => 'Negara :rank', 134 + 'global' => 'Global :rank', 135 135 ], 136 136 ], 137 137 138 138 'posts' => [ 139 - 'title' => '', 139 + 'title' => 'Hantaran :username', 140 140 ], 141 141 142 142 'anonymous' => [ 143 - 'login_link' => '', 144 - 'login_text' => '', 145 - 'username' => '', 146 - 'error' => '', 143 + 'login_link' => 'tekan untuk daftar masuk', 144 + 'login_text' => 'daftar masuk', 145 + 'username' => 'Tetamu', 146 + 'error' => 'Anda harus daftar masuk untuk lakukan ini.', 147 147 ], 148 - 'logout_confirm' => '', 148 + 'logout_confirm' => 'Pastikah nak daftar keluar? :(', 149 149 'report' => [ 150 - 'button_text' => '', 151 - 'comments' => '', 152 - 'placeholder' => '', 153 - 'reason' => '', 154 - 'thanks' => '', 155 - 'title' => '', 150 + 'button_text' => 'Laporkan', 151 + 'comments' => 'Balasan', 152 + 'placeholder' => 'Sila berikan mana-mana maklumat yang anda rasa bermanfaat.', 153 + 'reason' => 'Sebab', 154 + 'thanks' => 'Terima kasih atas laporan anda!', 155 + 'title' => 'Laporkan :username?', 156 156 157 157 'actions' => [ 158 - 'send' => '', 159 - 'cancel' => '', 158 + 'send' => 'Hantar Laporan', 159 + 'cancel' => 'Batal', 160 160 ], 161 161 162 162 'options' => [ 163 - 'cheating' => '', 164 - 'multiple_accounts' => '', 165 - 'insults' => '', 166 - 'spam' => '', 167 - 'unwanted_content' => '', 168 - 'nonsense' => '', 169 - 'other' => '', 163 + 'cheating' => 'Menipu', 164 + 'multiple_accounts' => 'Mengguna lebih daripada satu akaun', 165 + 'insults' => 'Menghina saya / orang lain', 166 + 'spam' => 'Spam', 167 + 'unwanted_content' => 'Memaut kandungan tidak enak', 168 + 'nonsense' => 'Mengarut', 169 + 'other' => 'Lain-lain (tulis dibawah)', 170 170 ], 171 171 ], 172 172 'restricted_banner' => [ 173 - 'title' => '', 174 - 'message' => '', 175 - 'message_link' => '', 173 + 'title' => 'Akaun anda telah dihadkan!', 174 + 'message' => 'Ketika dihadkan, anda tidak boleh berinteraksi dengan pemain-pemain yang lain dan markah anda hanya dapat dilihat oleh anda. Ini selalunya kerana proses automatik dan akan ditarik balik dalam 24 jam. :link', 175 + 'message_link' => 'Periksa halaman ini untuk ketahui lebih lanjut.', 176 176 ], 177 177 'show' => [ 178 - 'age' => '', 179 - 'change_avatar' => '', 180 - 'first_members' => '', 178 + 'age' => ':age tahun', 179 + 'change_avatar' => 'tukar avatar anda!', 180 + 'first_members' => 'Di sini sejak permulaan', 181 181 'is_developer' => '', 182 182 'is_supporter' => '', 183 - 'joined_at' => '', 184 - 'lastvisit' => '', 185 - 'lastvisit_online' => '', 186 - 'missingtext' => '', 187 - 'origin_country' => '', 188 - 'previous_usernames' => '', 189 - 'plays_with' => '', 183 + 'joined_at' => 'Sertai :date', 184 + 'lastvisit' => 'Kali terakhir dilihat :date', 185 + 'lastvisit_online' => 'Sedang dalam talian', 186 + 'missingtext' => 'Anda mungkin telah salah tulis! (atau pengguna mungkin terlarang)', 187 + 'origin_country' => 'Dari :country', 188 + 'previous_usernames' => 'dahulunya dikenali sebagai', 189 + 'plays_with' => 'Bermain dengan :devices', 190 190 191 191 'comments_count' => [ 192 - '_' => '', 193 - 'count' => '', 192 + '_' => 'Dihantar :link', 193 + 'count' => ':count_delimited balasan|:count_delimited balasan', 194 194 ], 195 195 'cover' => [ 196 196 'to_0' => '', ··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '', ··· 208 209 'weekly_streak_current' => '', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 + 'day' => ':valued', 212 213 'week' => '', 213 214 ], 214 215 ], ··· 221 222 222 223 'upload' => [ 223 224 'broken_file' => '', 224 - 'button' => '', 225 - 'dropzone' => '', 226 - 'dropzone_info' => '', 225 + 'button' => 'Muatnaik gambar', 226 + 'dropzone' => 'Letak sini untuk muatnaik', 227 + 'dropzone_info' => 'Anda juga boleh letak imej di sini untuk muat naik', 227 228 'size_info' => '', 228 - 'too_large' => '', 229 - 'unsupported_format' => '', 229 + 'too_large' => 'Fail yang dimuatnaik terlalu besar.', 230 + 'unsupported_format' => 'Format tidak disokong.', 230 231 231 232 'restriction_info' => [ 232 233 '_' => '', ··· 242 243 243 244 'hue' => [ 244 245 'reset_no_supporter' => '', 245 - 'title' => '', 246 + 'title' => 'Warna', 246 247 247 248 'supporter' => [ 248 249 '_' => '', 249 - 'link' => '', 250 + 'link' => 'osu!supporter', 250 251 ], 251 252 ], 252 253 ], 253 254 254 255 'extra' => [ 255 - 'none' => '', 256 + 'none' => 'tiada', 256 257 'unranked' => '', 257 258 258 259 'achievements' => [ 259 260 'achieved-on' => '', 260 261 'locked' => '', 261 - 'title' => '', 262 + 'title' => 'Pencapaian', 262 263 ], 263 264 'beatmaps' => [ 264 265 'by_artist' => '', 265 - 'title' => '', 266 + 'title' => 'Beatmap', 266 267 267 268 'favourite' => [ 268 269 'title' => '', ··· 292 293 'show_more' => '', 293 294 ], 294 295 'events' => [ 295 - 'title' => '', 296 - 'title_longer' => '', 297 - 'show_more' => '', 296 + 'title' => 'Peristiwa', 297 + 'title_longer' => 'Peristiwa Semasa', 298 + 'show_more' => 'lihat lagi peristiwa', 298 299 ], 299 300 'historical' => [ 300 - 'title' => '', 301 + 'title' => 'Sejarah', 301 302 302 303 'monthly_playcounts' => [ 303 - 'title' => '', 304 - 'count_label' => '', 304 + 'title' => 'Sejarah Mainan', 305 + 'count_label' => 'Mainan', 305 306 ], 306 307 'most_played' => [ 307 - 'count' => '', 308 - 'title' => '', 308 + 'count' => 'kali dimain', 309 + 'title' => 'Beatmap Paling Kerap Dimain', 309 310 ], 310 311 'recent_plays' => [ 311 - 'accuracy' => '', 312 - 'title' => '', 312 + 'accuracy' => 'ketepatan: :percentage', 313 + 'title' => 'Mainan Semasa (24 jam)', 313 314 ], 314 315 'replays_watched_counts' => [ 315 316 'title' => '', ··· 317 318 ], 318 319 ], 319 320 'kudosu' => [ 320 - 'recent_entries' => '', 321 - 'title' => '', 322 - 'total' => '', 321 + 'recent_entries' => 'Sejarah Kudosu Semasa', 322 + 'title' => 'Kudosu!', 323 + 'total' => 'Jumlah Kudosu Diperoleh', 323 324 324 325 'entry' => [ 325 - 'amount' => '', 326 - 'empty' => "", 326 + 'amount' => ':amount kudosu', 327 + 'empty' => "Pengguna ini belum pernah menerima kudosu!", 327 328 328 329 'beatmap_discussion' => [ 329 330 'allow_kudosu' => [ ··· 362 363 363 364 'total_info' => [ 364 365 '_' => '', 365 - 'link' => '', 366 + 'link' => 'halaman ini', 366 367 ], 367 368 ], 368 369 'me' => [ 369 - 'title' => '', 370 + 'title' => 'saya!', 370 371 ], 371 372 'medals' => [ 372 373 'empty' => "", 373 374 'recent' => '', 374 - 'title' => '', 375 + 'title' => 'Pingat', 375 376 ], 376 377 'playlists' => [ 377 378 'title' => '', ··· 390 391 'top_ranks' => [ 391 392 'download_replay' => '', 392 393 'not_ranked' => '', 393 - 'pp_weight' => '', 394 - 'view_details' => '', 394 + 'pp_weight' => ':percentage wajaran', 395 + 'view_details' => 'Lihat Butiran', 395 396 'title' => '', 396 397 397 398 'best' => [ ··· 401 402 'title' => '', 402 403 ], 403 404 'pin' => [ 404 - 'to_0' => '', 405 - 'to_0_done' => '', 406 - 'to_1' => '', 407 - 'to_1_done' => '', 405 + 'to_0' => 'Nyahsemat', 406 + 'to_0_done' => 'Nyahsemat markah', 407 + 'to_1' => 'Semat', 408 + 'to_1_done' => 'Markah yang disemat', 408 409 ], 409 410 'pinned' => [ 410 - 'title' => '', 411 + 'title' => 'Markah yang Disemat', 411 412 ], 412 413 ], 413 414 'votes' => [ 414 - 'given' => '', 415 - 'received' => '', 416 - 'title' => '', 417 - 'title_longer' => '', 418 - 'vote_count' => '', 415 + 'given' => 'Undian diberi (3 bulan terakhir)', 416 + 'received' => 'Undian Diterima (3 bulan terakhir)', 417 + 'title' => 'Undian', 418 + 'title_longer' => 'Undian Terkini', 419 + 'vote_count' => ':count_delimited undi|:count_delimited undi', 419 420 ], 420 421 'account_standing' => [ 421 422 'title' => '', ··· 424 425 425 426 'recent_infringements' => [ 426 427 'title' => '', 427 - 'date' => '', 428 - 'action' => '', 429 - 'length' => '', 428 + 'date' => 'tarikh', 429 + 'action' => 'tindakan', 430 + 'length' => 'tempoh', 430 431 'length_indefinite' => '', 431 - 'description' => '', 432 + 'description' => 'perihal', 432 433 'actor' => '', 433 434 434 435 'actions' => [ 435 - 'restriction' => '', 436 - 'silence' => '', 437 - 'tournament_ban' => '', 438 - 'note' => '', 436 + 'restriction' => 'Dilarang', 437 + 'silence' => 'Diamkan', 438 + 'tournament_ban' => 'Larangan Kejohanan', 439 + 'note' => 'Nota', 439 440 ], 440 441 ], 441 442 ], ··· 443 444 444 445 'info' => [ 445 446 'discord' => '', 446 - 'interests' => '', 447 - 'location' => '', 448 - 'occupation' => '', 447 + 'interests' => 'Minat', 448 + 'location' => 'Lokasi Terkini', 449 + 'occupation' => 'Pekerjaan', 449 450 'twitter' => '', 450 - 'website' => '', 451 + 'website' => 'Laman Web', 451 452 ], 452 453 'not_found' => [ 453 - 'reason_1' => '', 454 - 'reason_2' => '', 455 - 'reason_3' => '', 456 - 'reason_header' => '', 457 - 'title' => '', 454 + 'reason_1' => 'Mereka mungkin telah menukar nama penggunanya.', 455 + 'reason_2' => 'Akaun ini mungkin tiada buat seketika ekoran masalah keselamatan atau penyalahgunaan.', 456 + 'reason_3' => 'Anda mungkin telah salah tulis!', 457 + 'reason_header' => 'Ada beberapa sebab kenapa:', 458 + 'title' => 'Pengguna tidak ditemui! ;_;', 458 459 ], 459 460 'page' => [ 460 - 'button' => '', 461 - 'description' => '', 462 - 'edit_big' => '', 463 - 'placeholder' => '', 461 + 'button' => 'sunting halaman profil', 462 + 'description' => '<strong>saya!</strong> ialah satu kawasan ubahsuai peribadi dalam halaman profil anda.', 463 + 'edit_big' => 'Sunting saya!', 464 + 'placeholder' => 'Tulis kandungan halaman di sini', 464 465 465 466 'restriction_info' => [ 466 - '_' => '', 467 - 'link' => '', 467 + '_' => 'Anda perlu menjadi :link untuk nyahkunci ciri ini.', 468 + 'link' => 'osu!supporter', 468 469 ], 469 470 ], 470 471 'post_count' => [ 471 - '_' => '', 472 - 'count' => '', 472 + '_' => 'Menyumbang :link', 473 + 'count' => ':count_delimited hantaran forum|:count_delimited hantaran forum', 473 474 ], 474 475 'rank' => [ 475 - 'country' => '', 476 - 'country_simple' => '', 477 - 'global' => '', 478 - 'global_simple' => '', 479 - 'highest' => '', 476 + 'country' => 'Peringkat kebangsaan untuk :mode', 477 + 'country_simple' => 'Peringkat Kebangsaan', 478 + 'global' => 'Peringkat dunia untuk :mode', 479 + 'global_simple' => 'Peringkat Dunia', 480 + 'highest' => 'Peringkat tertinggi: :rank pada :date', 480 481 ], 481 482 'stats' => [ 482 - 'hit_accuracy' => '', 483 - 'level' => '', 484 - 'level_progress' => '', 485 - 'maximum_combo' => '', 486 - 'medals' => '', 487 - 'play_count' => '', 488 - 'play_time' => '', 483 + 'hit_accuracy' => 'Ketepatan Pukulan', 484 + 'level' => 'Level :level', 485 + 'level_progress' => 'kemajuan ke level seterusnya', 486 + 'maximum_combo' => 'Kombo Maksimum', 487 + 'medals' => 'Pingat', 488 + 'play_count' => 'Kiraan Mainan', 489 + 'play_time' => 'Jumlah Masa Permainan', 489 490 'ranked_score' => '', 490 - 'replays_watched_by_others' => '', 491 + 'replays_watched_by_others' => 'Main Semula yang Ditonton Orang Lain', 491 492 'score_ranks' => '', 492 - 'total_hits' => '', 493 - 'total_score' => '', 493 + 'total_hits' => 'Jumlah Pukulan', 494 + 'total_score' => 'Jumlah Markah', 494 495 // modding stats 495 - 'graveyard_beatmapset_count' => '', 496 - 'loved_beatmapset_count' => '', 497 - 'pending_beatmapset_count' => '', 496 + 'graveyard_beatmapset_count' => 'Beatmap Dikuburkan', 497 + 'loved_beatmapset_count' => 'Beatmap Dicintai', 498 + 'pending_beatmapset_count' => 'Beatmap Menunggu Kelulusan', 498 499 'ranked_beatmapset_count' => '', 499 500 ], 500 501 ], 501 502 502 503 'silenced_banner' => [ 503 - 'title' => '', 504 - 'message' => '', 504 + 'title' => 'Anda sedang didiamkan.', 505 + 'message' => 'Sesetengah tindakan mungkin tidak tersedia.', 505 506 ], 506 507 507 508 'status' => [ 508 - 'all' => '', 509 - 'online' => '', 510 - 'offline' => '', 509 + 'all' => 'Semua', 510 + 'online' => 'Dalam Talian', 511 + 'offline' => 'Luar Talian', 511 512 ], 512 513 'store' => [ 513 - 'from_client' => '', 514 - 'from_web' => '', 515 - 'saved' => '', 514 + 'from_client' => 'sila daftar dari klien permainan!', 515 + 'from_web' => 'sila selesaikan pendaftaran melalui laman web osu!', 516 + 'saved' => 'Pengguna dicipta', 516 517 ], 517 518 'verify' => [ 518 - 'title' => '', 519 + 'title' => 'Pengesahan Akaun', 519 520 ], 520 521 521 522 'view_mode' => [ 522 - 'brick' => '', 523 - 'card' => '', 524 - 'list' => '', 523 + 'brick' => 'Penampilan batu-bata', 524 + 'card' => 'Penampilan kad', 525 + 'list' => 'Penampilan senarai', 525 526 ], 526 527 ];
+11 -11
resources/lang/ms-MY/wiki.php
··· 5 5 6 6 return [ 7 7 'show' => [ 8 - 'fallback_translation' => '', 9 - 'incomplete_or_outdated' => '', 10 - 'missing' => '', 11 - 'missing_title' => '', 12 - 'missing_translation' => '', 13 - 'needs_cleanup_or_rewrite' => '', 8 + 'fallback_translation' => 'Laman yang diminta belum lagi diterjemah kepada bahasa yang dipilih (:language). Tunjuk versi Inggeris.', 9 + 'incomplete_or_outdated' => 'Kandungan di laman ini tidak lengkap atau ketinggalan zaman. Jika anda boleh membantu, sila pertimbang untuk kemaskini rencana!', 10 + 'missing' => 'Laman yang diminta ":keyword" tidak dapat dijumpai.', 11 + 'missing_title' => 'Tidak Jumpa', 12 + 'missing_translation' => 'Laman yang diminta tidak dapat dijumpai untuk bahasa yang dipilih ketika ini.', 13 + 'needs_cleanup_or_rewrite' => 'Laman ini tidak mematuhi piawai wiki osu! dan memerlukan pembersihan atau ditulis semula. Jika anda boleh membantu, sila pertimbang untuk kemaskini rencana!', 14 14 'search' => '', 15 - 'stub' => '', 16 - 'toc' => '', 15 + 'stub' => 'Rencana ini tidak habis dan menunggu seseorang untuk mengembangkannya.', 16 + 'toc' => 'Kandungan', 17 17 18 18 'edit' => [ 19 - 'link' => '', 20 - 'refresh' => '', 19 + 'link' => 'Tunjuk di Github', 20 + 'refresh' => 'Segar Semula', 21 21 ], 22 22 23 23 'translation' => [ 24 24 'legal' => '', 25 25 'outdated' => '', 26 26 27 - 'default' => '', 27 + 'default' => 'Versi Inggeris', 28 28 ], 29 29 ], 30 30 ];
+1
resources/lang/nl/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => '', 13 14 'rules' => 'Zorg ervoor dat uw avatar voldoet aan :link. <br/> Dit betekent dat deze <strong> geschikt moet zijn voor alle leeftijden </strong>. d.w.z. geen naaktheid, godslastering of suggestieve inhoud.', 14 15 'rules_link' => 'de community regels', 15 16 ],
+1
resources/lang/nl/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Niet zo snel, speel meer.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/nl/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'verberg beoordeelde items', 18 19 'nav_title' => 'beoordeel', 19 20 'no_current_vote' => 'je hebt nog niet gestemd.',
+1
resources/lang/nl/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/no/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Profilbilde', 13 + 'reset' => '', 13 14 'rules' => 'Vennligst sørg for at profilbildet ditt følger :link<br/>Dette betyr at det må være <strong>passende for alle aldersgrupper</strong>. d.v.s. ingen nakenhet, upassende språk eller innhold.', 14 15 'rules_link' => 'Samfunns regler', 15 16 ],
+1
resources/lang/no/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Ro ned, spill mer.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/no/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'skjul dømmede innslag', 18 19 'nav_title' => 'dommer', 19 20 'no_current_vote' => 'du har ikke stemt enda.',
+1
resources/lang/no/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/pl/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Awatar', 13 + 'reset' => 'zresetuj', 13 14 'rules' => 'Upewnij się, że twój awatar jest zgodny z :link.<br/>Oznacza to, że musi być <strong>stosowny dla wszystkich grup wiekowych</strong> i nie może ukazywać nagości, wulgarności ani sugestywnej zawartości.', 14 15 'rules_link' => 'zasadami społeczności', 15 16 ],
+2 -2
resources/lang/pl/beatmaps.php
··· 25 25 'message_placeholder_silenced' => "Nie możesz zamieszczać dyskusji po tym, jak twoje konto zostało uciszone.", 26 26 'message_type_select' => 'Wybierz typ komentarza', 27 27 'reply_notice' => 'Naciśnij Enter, aby odpowiedzieć.', 28 - 'reply_resolve_notice' => '', 28 + 'reply_resolve_notice' => 'Wciśnij Enter, aby odpowiedzieć. Wciśnij ctrl+enter, aby i rozwiązać.', 29 29 'reply_placeholder' => 'Napisz tutaj swoją odpowiedź', 30 30 'require-login' => 'Zaloguj się, aby odpowiedzieć bądź opublikować uwagę', 31 31 'resolved' => 'Rozwiązane', ··· 285 285 'taiko' => '', 286 286 'fruits' => '', 287 287 'mania' => '', 288 - 'undefined' => '', 288 + 'undefined' => 'nie ustawiono', 289 289 ], 290 290 'status' => [ 291 291 'any' => 'Jakikolwiek',
+2 -1
resources/lang/pl/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Zwolnij, pograj więcej!', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [ ··· 45 46 'hybrid_requires_modes' => 'Beatmapa hybrydowa wymaga wybrania przynajmniej jednego trybu gry, dla którego chcesz ją nominować.', 46 47 'incorrect_mode' => 'Nie posiadasz uprawnień do nominowania beatmap dla tych trybów (:mode)', 47 48 'invalid_limited_nomination' => '', 48 - 'invalid_ruleset' => '', 49 + 'invalid_ruleset' => 'Ta nominacja ma niewłaściwy zestaw zasad.', 49 50 'too_many' => 'Osiągnięto już wystarczającą liczbę nominacji.', 50 51 'too_many_non_main_ruleset' => '', 51 52
+1
resources/lang/pl/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'ukryj ocenione zgłoszenia', 18 19 'nav_title' => 'oceniać', 19 20 'no_current_vote' => 'jeszcze nie zagłosowałeś.',
+2 -2
resources/lang/pl/errors.php
··· 29 29 'generic' => 'Wystąpił błąd podczas przygotowywania twojego zamówienia.', 30 30 ], 31 31 'scores' => [ 32 - 'invalid_id' => '', 32 + 'invalid_id' => 'Nieprawidłowy Identyfikator Wyniku.', 33 33 ], 34 34 'search' => [ 35 35 'default' => 'Nie udało się niczego znaleźć, spróbuj ponownie później.', ··· 37 37 'operation_timeout_exception' => 'Wyszukiwanie jest obecnie bardziej obciążone niż zwykle, spróbuj ponownie później.', 38 38 ], 39 39 'user_report' => [ 40 - 'recently_reported' => "", 40 + 'recently_reported' => "Już to niedawno zgłosiłeś.", 41 41 ], 42 42 ];
+1 -1
resources/lang/pl/layout.php
··· 199 199 'legacy_score_only_toggle_tooltip' => 'Tryb Lazer pokazuje wyniki ustalone z lazera z nowym algorytmem punktacji', 200 200 'logout' => 'Wyloguj się', 201 201 'profile' => 'Mój profil', 202 - 'scoring_mode_toggle' => '', 202 + 'scoring_mode_toggle' => 'Klasyczny wynik', 203 203 'scoring_mode_toggle_tooltip' => '', 204 204 ], 205 205 ],
+1 -1
resources/lang/pl/rankings.php
··· 24 24 ], 25 25 26 26 'performance' => [ 27 - 'insufficient_history' => '', 27 + 'insufficient_history' => 'Ten użytkownik ma mniej niż 30 dni najnowszej historii rankingu.', 28 28 ], 29 29 30 30 'type' => [
+13 -12
resources/lang/pl/users.php
··· 198 198 'to_1' => 'Pokaż tło', 199 199 ], 200 200 'daily_challenge' => [ 201 - 'daily' => '', 202 - 'daily_streak_best' => '', 203 - 'daily_streak_current' => '', 204 - 'title' => '', 205 - 'top_10p_placements' => '', 206 - 'top_50p_placements' => '', 207 - 'weekly' => '', 208 - 'weekly_streak_best' => '', 209 - 'weekly_streak_current' => '', 201 + 'daily' => 'Dzienna seria', 202 + 'daily_streak_best' => 'Najlepsza Dzienna seria', 203 + 'daily_streak_current' => 'Aktualna Dzienna Seria', 204 + 'playcount' => '', 205 + 'title' => 'Wyzwanie Dnia', 206 + 'top_10p_placements' => 'Top 10% Miejsc', 207 + 'top_50p_placements' => 'Top 50% Miejsc', 208 + 'weekly' => 'Tygodniowa Seria', 209 + 'weekly_streak_best' => 'Najlepsza Tygodniowa Seria', 210 + 'weekly_streak_current' => 'Aktualna tygodniowa seria', 210 211 211 212 'unit' => [ 212 - 'day' => '', 213 - 'week' => '', 213 + 'day' => ':valued', 214 + 'week' => ':valuew', 214 215 ], 215 216 ], 216 217 'edit' => [ ··· 242 243 ], 243 244 244 245 'hue' => [ 245 - 'reset_no_supporter' => '', 246 + 'reset_no_supporter' => 'Przywrócić domyślny kolor? Osu!Supporter będzie wymagany, aby go zmienić ponownie.', 246 247 'title' => 'Kolor', 247 248 248 249 'supporter' => [
+2 -1
resources/lang/pt-br/accounts.php
··· 5 5 6 6 return [ 7 7 'edit' => [ 8 - 'title_compact' => 'configurações de conta', 8 + 'title_compact' => 'opções da conta', 9 9 'username' => 'nome de usuário', 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'reiniciar', 13 14 'rules' => 'Por favor tenha certeza que seu avatar respeite :link.<br/>Isso significa que deve ser <strong>adequado para todas as idades</strong>. ou seja, sem nudez, palavrões ou conteúdo sugestivo.', 14 15 'rules_link' => 'as regras da comunidade', 15 16 ],
+1
resources/lang/pt-br/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Vá devagar, jogue mais.', 20 + 'no_mirrors' => 'Nenhum servidor de download disponível.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/pt-br/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'comentários', 17 18 'hide_judged' => 'esconder entradas julgadas', 18 19 'nav_title' => 'juiz', 19 20 'no_current_vote' => 'você ainda não votou.',
+12 -11
resources/lang/pt-br/users.php
··· 197 197 'to_1' => 'Mostrar capa', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Sequência diária', 201 + 'daily_streak_best' => 'Melhor sequência diária', 202 + 'daily_streak_current' => 'Sequência diária atual', 203 + 'playcount' => '', 204 + 'title' => 'Desafio\ndiário', 205 + 'top_10p_placements' => 'Melhores 10% nos colocados', 206 + 'top_50p_placements' => 'Melhores 50% nos colocados', 207 + 'weekly' => 'Sequência semanal', 208 + 'weekly_streak_best' => 'Melhor sequência semanal', 209 + 'weekly_streak_current' => 'Sequência semanal atual', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valued', 213 + 'week' => ':valuew', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/pt/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'reiniciar', 13 14 'rules' => 'Por favor, assegura-te de que o teu avatar respeita :link.<br/>Isto significa que deve ser <strong>adequado para todas as idades</strong>, ou seja, sem nudez, profanidade ou conteúdo estimulante.', 14 15 'rules_link' => 'as regras da comunidade', 15 16 ],
+1 -1
resources/lang/pt/beatmaps.php
··· 293 293 'approved' => 'Aprovados', 294 294 'favourites' => 'Favoritos', 295 295 'graveyard' => 'Cemitério', 296 - 'leaderboard' => 'Possui uma tabela de classificações', 296 + 'leaderboard' => 'Tem classificações', 297 297 'loved' => 'Adorados', 298 298 'mine' => 'Os meus mapas', 299 299 'pending' => 'Pendente',
+1
resources/lang/pt/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Abranda, joga mais.', 20 + 'no_mirrors' => 'Nenhum servidor de transferência disponível.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+3 -3
resources/lang/pt/community.php
··· 20 20 ], 21 21 'infra' => [ 22 22 'title' => 'Infraestrutura do servidor', 23 - 'description' => 'As contribuições vão para os servidores que correm o sítio web, serviços multijogador, tabelas de líderes online, etc.', 23 + 'description' => 'As contribuições vão para os servidores que executam o sítio web, serviços multijogadores, classificações online, etc.', 24 24 ], 25 25 'featured-artists' => [ 26 26 'title' => 'Artistas destacados', ··· 51 51 52 52 'friend_ranking' => [ 53 53 'title' => 'Classificação de amigos', 54 - 'description' => "Vê como te comparas contra os teus amigos numa tabela de classificações dum beatmap, dentro do jogo como também no sítio web.", 54 + 'description' => "Vê como te compara contra os teus amigos numa tabela de classificações do beatmap, no jogo como também no sítio web.", 55 55 ], 56 56 57 57 'country_ranking' => [ ··· 132 132 'description' => 'O número máximo de beatmaps não classificados que podes possuir é calculado dum valor base mais um bónus adicional para cada beatmap classificado que atualmente possuas (até a um certo limite).<br/><br/>Normalmente é 4 mais 1 por cada beatmap classificado (até 2). Com a osu!supporter, isto aumenta para 8 mais 1 por cada beatmap classificado (até 12).', 133 133 ], 134 134 'friend_filtering' => [ 135 - 'title' => 'Tabela de classificações de amigos', 135 + 'title' => 'Classificações de amigos', 136 136 'description' => 'Compete com os teus amigos e vê como te classificas contra eles!', 137 137 ], 138 138
+1
resources/lang/pt/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'comentários', 17 18 'hide_judged' => 'esconder inscrições avaliadas', 18 19 'nav_title' => 'avaliar', 19 20 'no_current_vote' => 'Ainda não votaste.',
+12 -11
resources/lang/pt/users.php
··· 197 197 'to_1' => 'Mostrar capa', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Série de vitórias diária', 201 + 'daily_streak_best' => 'Melhor série de vitórias diária', 202 + 'daily_streak_current' => 'Série de vitórias diária atual', 203 + 'playcount' => '', 204 + 'title' => 'Desafio\nDiário', 205 + 'top_10p_placements' => 'Os melhores 10%', 206 + 'top_50p_placements' => 'Os melhores 50%', 207 + 'weekly' => 'Série de vitórias semanal', 208 + 'weekly_streak_best' => 'Melhor série de vitórias semanal', 209 + 'weekly_streak_current' => 'Série de vitórias semanal atual', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valued', 213 + 'week' => ':valuew', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/ro/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'resetează', 13 14 'rules' => 'Te rugăm să te asiguri că avatar-ul tău respectă :link<br/>Asta înseamnă că trebuie să fie <strong>adecvat pentru toate vârstele</strong>. spre ex. fără nuditate, vulgarități sau conținut sugestiv.', 14 15 'rules_link' => 'regulile comunității', 15 16 ],
+2 -2
resources/lang/ro/beatmaps.php
··· 25 25 'message_placeholder_silenced' => "Nu poți posta atunci când ești mut.", 26 26 'message_type_select' => 'Selectează tipul comentariului', 27 27 'reply_notice' => 'Apasă enter pentru a răspunde.', 28 - 'reply_resolve_notice' => '', 28 + 'reply_resolve_notice' => 'Apăsați enter pentru a răspunde. Apăsați ctrl+enter pentru a răspunde și rezolva.', 29 29 'reply_placeholder' => 'Scrie-ți răspunsul aici', 30 30 'require-login' => 'Te rugăm să te autentifici pentru a posta sau a răspunde', 31 31 'resolved' => 'Rezolvat', 32 32 'restore' => 'restabilește', 33 33 'show_deleted' => 'Afișează șterse', 34 34 'title' => 'Discuții', 35 - 'unresolved_count' => '', 35 + 'unresolved_count' => 'o problemă nerezolvată|:count_delimited probleme nerezolvate|:count_delimited de probleme nerezolvate', 36 36 37 37 'collapse' => [ 38 38 'all-collapse' => 'Restrânge tot',
+1
resources/lang/ro/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Descarcă mai puțin, joacă mai mult.', 20 + 'no_mirrors' => 'Nu există servere de descărcare disponibile.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/ro/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'comentarii', 17 18 'hide_judged' => 'ascunde intrările evaluate', 18 19 'nav_title' => 'evaluator', 19 20 'no_current_vote' => 'nu ai votat încă.',
+1 -1
resources/lang/ro/errors.php
··· 29 29 'generic' => 'A apărut o eroare în timpul preparării comenzii tale.', 30 30 ], 31 31 'scores' => [ 32 - 'invalid_id' => '', 32 + 'invalid_id' => 'ID scor invalid.', 33 33 ], 34 34 'search' => [ 35 35 'default' => 'Nu s-au putut obține rezultate, încearcă mai târziu.',
+2 -2
resources/lang/ro/layout.php
··· 199 199 'legacy_score_only_toggle_tooltip' => 'Modul lazer afișează scoruri obținute din lazer folosind un algoritm nou de scor', 200 200 'logout' => 'Deconectare', 201 201 'profile' => 'Profilul Meu', 202 - 'scoring_mode_toggle' => '', 203 - 'scoring_mode_toggle_tooltip' => '', 202 + 'scoring_mode_toggle' => 'Mod scor clasic', 203 + 'scoring_mode_toggle_tooltip' => 'Ajustează valorile pentru o experiența mai apropiată de modul clasic de scor fără standardizare', 204 204 ], 205 205 ], 206 206
+1 -1
resources/lang/ro/oauth.php
··· 7 7 'cancel' => 'Anulează', 8 8 9 9 'authorise' => [ 10 - 'app_owner' => '', 10 + 'app_owner' => 'o aplicație realizată de :owner', 11 11 'request' => 'solicită permisiunea de a-ţi accesa contul.', 12 12 'scopes_title' => 'Această aplicaţie va putea să:', 13 13 'title' => 'Cerere de autorizare',
+18 -17
resources/lang/ro/users.php
··· 197 197 'to_1' => 'Afișează coperta', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Serie Zilnică', 201 + 'daily_streak_best' => 'Cea Mai Bună Serie Zilnică', 202 + 'daily_streak_current' => 'Serie Zilnică Actuală', 203 + 'playcount' => '', 204 + 'title' => 'Provocare\nZilnică', 205 + 'top_10p_placements' => 'Plasamente Top 10%', 206 + 'top_50p_placements' => 'Plasamente Top 50%', 207 + 'weekly' => 'Serie Săptămânală', 208 + 'weekly_streak_best' => 'Cea Mai Bună Serie Săptămânală', 209 + 'weekly_streak_current' => 'Serie Săptămânală Actuală', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valuez', 213 + 'week' => ':values', 213 214 ], 214 215 ], 215 216 'edit' => [ 216 217 'cover' => [ 217 - 'button' => 'Schimbă coperta de profil', 218 + 'button' => 'Schimbă Coperta de Profil', 218 219 'defaults_info' => 'Mai multe opțiuni pentru coperți vor fi disponibile în viitor', 219 220 'holdover_remove_confirm' => "Coperta selectată anterior nu mai este disponibilă pentru selecție. Nu o veți mai putea selecta înapoi după ce treceți la o copertă diferită. Continuați?", 220 - 'title' => '', 221 + 'title' => 'Copertă', 221 222 222 223 'upload' => [ 223 224 'broken_file' => 'Imposibil de procesat imaginea. Verifică imaginea încărcată și încearcă din nou.', ··· 241 242 ], 242 243 243 244 'hue' => [ 244 - 'reset_no_supporter' => '', 245 - 'title' => '', 245 + 'reset_no_supporter' => 'Resetați culoarea la cea implicită? Va fi necesar statusul de suporter pentru a o schimba la o culoare diferită.', 246 + 'title' => 'Culoare', 246 247 247 248 'supporter' => [ 248 - '_' => '', 249 - 'link' => '', 249 + '_' => 'Temele de culori personalizate sunt disponibile numai pentru :link', 250 + 'link' => 'suporteri osu!', 250 251 ], 251 252 ], 252 253 ],
+1
resources/lang/ru/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Аватар', 13 + 'reset' => 'удалить', 13 14 'rules' => 'Убедитесь, что ваш аватар соответствует :link.<br/>Это означает, что он обязан <strong>подходить для всех возрастов</strong>, т.е. не должен содержать наготы, ненормативной лексики или вызывающего контента.', 14 15 'rules_link' => 'критериям визуального содержания', 15 16 ],
+2 -2
resources/lang/ru/beatmaps.php
··· 32 32 'restore' => 'восстановить', 33 33 'show_deleted' => 'Показать удалённые', 34 34 'title' => 'Обсуждение', 35 - 'unresolved_count' => ':count_delimited нерешенных проблем', 35 + 'unresolved_count' => ':count_delimited нерешённых проблем|:count_delimited нерешённая проблема|:count_delimited нерешённые проблемы', 36 36 37 37 'collapse' => [ 38 38 'all-collapse' => 'Скрыть всё', ··· 211 211 'required_text' => 'Номинаций: :current/:required', 212 212 'reset_message_deleted' => 'удалено', 213 213 'title' => 'Статус номинации', 214 - 'unresolved_issues' => 'Ещё остались нерешенные проблемы, которые необходимо решить в первую очередь.', 214 + 'unresolved_issues' => 'Ещё остались нерешённые проблемы, которые необходимо решить в первую очередь.', 215 215 216 216 'rank_estimate' => [ 217 217 '_' => 'Эта карта станет рейтинговой :date, если не будет найдено проблем. Она #:position в :queue.',
+1
resources/lang/ru/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Меньше качай и больше играй.', 20 + 'no_mirrors' => 'Нет доступных загрузочных серверов.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/ru/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'комментарии', 17 18 'hide_judged' => 'скрыть оценённые заявки', 18 19 'nav_title' => 'судья', 19 20 'no_current_vote' => 'вы пока ещё не проголосовали.',
+12 -11
resources/lang/ru/users.php
··· 197 197 'to_1' => 'Показать обложку', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Серия в днях', 201 + 'daily_streak_best' => 'Лучшая серия в днях', 202 + 'daily_streak_current' => 'Текущая серия в днях', 203 + 'playcount' => '', 204 + 'title' => 'Карта\nдня', 205 + 'top_10p_placements' => 'Попаданий в топ 10%', 206 + 'top_50p_placements' => 'Попаданий в топ 50%', 207 + 'weekly' => 'Серия в неделях', 208 + 'weekly_streak_best' => 'Лучшая серия в неделях', 209 + 'weekly_streak_current' => 'Текущая серия в неделях', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valueд', 213 + 'week' => ':valueнед', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/si-LK/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => '', 13 + 'reset' => '', 13 14 'rules' => '', 14 15 'rules_link' => '', 15 16 ],
+1
resources/lang/si-LK/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => '', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/si-LK/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/si-LK/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/sk/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => '', 13 14 'rules' => 'Prosím uistite sa, že váš avatar sedí s :link.<br/>To znamená, že musí byť <strong>primeraný pre každý vek</strong>. To je žiadna nudita, vulgarizmy alebo sugestívny obsah.', 14 15 'rules_link' => 'pravidlá komunity', 15 16 ],
+1
resources/lang/sk/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Spomal, hraj viac.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/sk/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+7 -6
resources/lang/sk/users.php
··· 49 49 ], 50 50 51 51 'card' => [ 52 - 'gift_supporter' => '', 52 + 'gift_supporter' => 'Daruj štítok podporovateľa', 53 53 'loading' => 'Načitávanie...', 54 54 'send_message' => 'poslať správu', 55 55 ], ··· 72 72 73 73 'disabled' => [ 74 74 'title' => 'Ups! Vyzerá to tak, že tvoj účet bol zakázaný.', 75 - 'warning' => "", 75 + 'warning' => "V tom prípade, že ste porušili pravidlo, vezmite si prosím na vedomie, že všeobecne platí jednomesačné obdobie, počas ktorého nebudeme brať do úvahy žiadne žiadosti o amnestiu. Po tomto období nás môžete kontaktovať, ak to budete považovať za potrebné. Upozorňujeme, že vytváranie nových účtov po tom, čo ste mali jeden deaktivovný, bude mať za následok <strong>predĺženie tohto jednomesačného obmedzenia</strong>. Upozorňujeme tiež, že <strong>každým vytvoreným účtom ďalej porušujete pravidlá</strong>. Dôrazne vám odporúčame, aby ste sa nevydali touto cestou!", 76 76 77 77 'if_mistake' => [ 78 - '_' => '', 78 + '_' => 'Ak si myslíte, že ide o chybu, kontaktujte nás (prostredníctvom :email alebo kliknutím na „?“ v pravom dolnom rohu tejto stránky). Upozorňujeme, že vždy sme si plne istí našimi krokmi, pretože sú založené na veľmi spoľahlivých údajoch. Vyhradzujeme si právo nebrať do úvahy vašu žiadosť, ak budeme mať pocit, že ste úmyselne nečestní.', 79 79 'email' => 'e-mail', 80 80 ], 81 81 82 82 'reasons' => [ 83 - 'compromised' => '', 84 - 'opening' => '', 83 + 'compromised' => 'Váš účet bol považovaný za napadnutý. Môže byť dočasne deaktivovaný, kým sa potvrdí jeho totožnosť.', 84 + 'opening' => 'Existuje niekoľko dôvodov, ktoré môžu viesť k deaktivácii vášho účtu:', 85 85 86 86 'tos' => [ 87 - '_' => '', 87 + '_' => 'Porušili ste jedno alebo viacero našich pravidiel :community_rules alebo :tos.', 88 88 'community_rules' => 'pravidlá komunity', 89 89 'tos' => 'zmluvné podmienky', 90 90 ], ··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/sl/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => '', 13 14 'rules' => 'Prosimo, da naj se tvoj avatar drži :link.<br/>To pomeni, da mora biti <strong>primerno za vse starosti</strong>. t.j. Nič golote, kletvic ali druge neželene vsebine.', 14 15 'rules_link' => 'pravila skupnosti', 15 16 ],
+1
resources/lang/sl/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Upočasni se, igraj več.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/sl/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/sl/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+2 -1
resources/lang/sr/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Аватар', 13 + 'reset' => 'ресетуј', 13 14 'rules' => 'Молимо Вас да ваш аватар поштује :link. <br/> То значи да мора бити <strong>сутабилан за људе свих узраста</strong>. Аватари не смеју садржати голотињу, псовке и сугестиван садржај.', 14 15 'rules_link' => 'правила заједнице', 15 16 ], ··· 65 66 'github_user' => [ 66 67 'info' => "", 67 68 'link' => '', 68 - 'title' => '', 69 + 'title' => 'GitHub', 69 70 'unlink' => '', 70 71 71 72 'error' => [
+1 -1
resources/lang/sr/api.php
··· 17 17 'identify' => 'Да вас идентификује и да прочита ваш јавни профил.', 18 18 19 19 'chat' => [ 20 - 'read' => '', 20 + 'read' => 'Читајте поруке на своје име.', 21 21 'write' => 'Шаљите поруке у ваше име.', 22 22 'write_manage' => '', 23 23 ],
+3 -3
resources/lang/sr/artist.php
··· 46 46 '_' => 'тражење песме', 47 47 48 48 'exclusive_only' => [ 49 - 'all' => '', 50 - 'exclusive_only' => '', 49 + 'all' => 'Све', 50 + 'exclusive_only' => 'osu! оригинали', 51 51 ], 52 52 53 53 'form' => [ ··· 57 57 'bpm_gte' => 'BPM Минимум', 58 58 'bpm_lte' => 'BPM Максимум', 59 59 'empty' => 'Не постоји која песма која одговара вашем критеријуму.', 60 - 'exclusive_only' => '', 60 + 'exclusive_only' => 'Тип', 61 61 'genre' => 'Жанр', 62 62 'genre_all' => 'Све', 63 63 'length_gte' => 'Минимална Дужина',
+1 -1
resources/lang/sr/authorization.php
··· 188 188 ], 189 189 ], 190 190 'update_email' => [ 191 - 'locked' => '', 191 + 'locked' => 'адреса е-поште је закључана', 192 192 ], 193 193 ], 194 194 ];
+1
resources/lang/sr/beatmapsets.php
··· 18 18 19 19 'download' => [ 20 20 'limit_exceeded' => 'Успорите, играјте више.', 21 + 'no_mirrors' => '', 21 22 ], 22 23 23 24 'featured_artist_badge' => [
+3 -3
resources/lang/sr/chat.php
··· 18 18 'channels' => [ 19 19 'confirm_part' => 'Да ли желите да сакријете овај канал? И даље ће те примати поруке са овог канала.', 20 20 'create' => 'креирај најаву', 21 - 'join' => '', 22 - 'none' => '', 21 + 'join' => 'уђите у канал', 22 + 'none' => 'нема канала', 23 23 24 24 'list' => [ 25 25 'title' => [ ··· 64 64 ], 65 65 66 66 'join_channels' => [ 67 - 'loading' => '', 67 + 'loading' => 'Учитавање листа канала...', 68 68 ], 69 69 ];
+1 -1
resources/lang/sr/comments.php
··· 44 44 ], 45 45 46 46 'ogp' => [ 47 - 'title' => '', 47 + 'title' => 'коментар поставио :user', 48 48 ], 49 49 50 50 'placeholder' => [
+1 -1
resources/lang/sr/common.php
··· 39 39 'pin' => 'закачи', 40 40 'post' => 'Објавите', 41 41 'read_more' => 'прочитај више', 42 - 'refresh' => '', 42 + 'refresh' => 'Освежи', 43 43 'reply' => 'Одговорите', 44 44 'reply_reopen' => 'Одговорите и отворите поново', 45 45 'reply_resolve' => 'Одговорите и решите',
+1
resources/lang/sr/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => 'судија', 19 20 'no_current_vote' => 'ниси још гласао.',
+1 -1
resources/lang/sr/livestreams.php
··· 11 11 12 12 'top-headers' => [ 13 13 'headline' => 'Стримови Уживо', 14 - 'description' => 'Подаци су преузети са twitch.tv сваких пет минута на основу директоријума лајва. Слободно можете почети да стримујете и да будете наведени у списку! За више информација о томе како наместити лајв, молимо вас да погледате :link.', 14 + 'description' => 'Подаци су преузети са twitch.tv сваких пет минута на основу директоријума лајва. Слободно можете почети да стримујете и да будете наведени у списку! За више информација о томе како наместити лајв, молимо Вас да погледате :link.', 15 15 16 16 'link' => 'вики страница о лајву', 17 17 ],
+3 -3
resources/lang/sr/models.php
··· 4 4 // See the LICENCE file in the repository root for full licence text. 5 5 6 6 return [ 7 - 'not_found' => "", 7 + 'not_found' => "Наведени :model није пронађен.", 8 8 9 9 'name' => [ 10 - 'App\Models\Beatmap' => '', 11 - 'App\Models\Beatmapset' => '', 10 + 'App\Models\Beatmap' => 'тежина мапе', 11 + 'App\Models\Beatmapset' => 'мапа', 12 12 ], 13 13 ];
+3 -3
resources/lang/sr/notifications.php
··· 57 57 'beatmapset_discussion_unlock_compact' => 'Дискусија је откључана', 58 58 59 59 'review_count' => [ 60 - 'praises' => '', 61 - 'problems' => '', 62 - 'suggestions' => '', 60 + 'praises' => ':count_delimited похвала|:count_delimited похвале', 61 + 'problems' => ':count_delimited проблем|:count_delimited проблема', 62 + 'suggestions' => ':count_delimited сугестија|:count_delimited сугестије', 63 63 ], 64 64 ], 65 65
+5 -5
resources/lang/sr/user_cover_presets.php
··· 16 16 ], 17 17 18 18 'create_form' => [ 19 - 'files' => '', 20 - 'submit' => '', 21 - 'title' => '', 19 + 'files' => 'Фајлови', 20 + 'submit' => 'Сачувај', 21 + 'title' => 'Додај Нови', 22 22 ], 23 23 24 24 'item' => [ 25 - 'click_to_disable' => '', 26 - 'click_to_enable' => '', 25 + 'click_to_disable' => 'Кликните да бисте онемогућили', 26 + 'click_to_enable' => 'Кликните да бисте омогућили', 27 27 'enabled' => 'Омогућено', 28 28 'disabled' => 'Онемогућено', 29 29 'image_store' => '',
+12 -11
resources/lang/sr/users.php
··· 198 198 'to_1' => 'Прикажи позадину', 199 199 ], 200 200 'daily_challenge' => [ 201 - 'daily' => '', 202 - 'daily_streak_best' => '', 203 - 'daily_streak_current' => '', 204 - 'title' => '', 205 - 'top_10p_placements' => '', 206 - 'top_50p_placements' => '', 207 - 'weekly' => '', 208 - 'weekly_streak_best' => '', 209 - 'weekly_streak_current' => '', 201 + 'daily' => 'Дневна Серија', 202 + 'daily_streak_best' => 'Најбоља Дневна Серија', 203 + 'daily_streak_current' => 'Тренутна Дневна Серија', 204 + 'playcount' => '', 205 + 'title' => 'Дневни\nИзазов', 206 + 'top_10p_placements' => '10% Најбољих Места', 207 + 'top_50p_placements' => '50% Најбољих Места', 208 + 'weekly' => 'Недељна Серија', 209 + 'weekly_streak_best' => 'Најбоља Недељна Серија', 210 + 'weekly_streak_current' => 'Тренутна Недељна Серија', 210 211 211 212 'unit' => [ 212 - 'day' => '', 213 - 'week' => '', 213 + 'day' => ':valueд', 214 + 'week' => ':valueн', 214 215 ], 215 216 ], 216 217 'edit' => [
+1
resources/lang/sv/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'återställ', 13 14 'rules' => 'Se till att din avatar följer :link.<br/>Det betyder att den måste vara <strong>lämplig för alla åldrar</strong>. dvs. ingen nakenhet, svordomar eller suggestivt innehåll.', 14 15 'rules_link' => 'gemenskapsreglerna', 15 16 ],
+1 -1
resources/lang/sv/authorization.php
··· 173 173 'score' => [ 174 174 'pin' => [ 175 175 'disabled_type' => "Kan inte fästa den här typen av poäng", 176 - 'failed' => "", 176 + 'failed' => "Kan inte fästa icke-passerande poäng.", 177 177 'not_owner' => 'Endast resultatägaren kan fästa resultat.', 178 178 'too_many' => 'Fäst för många resultat.', 179 179 ],
+1 -1
resources/lang/sv/beatmap_discussions.php
··· 26 26 'deleted' => 'Inkludera raderade diskussioner', 27 27 'mode' => 'Beatmapläge', 28 28 'only_unresolved' => 'Visa bara olösta diskussioner', 29 - 'show_review_embeds' => '', 29 + 'show_review_embeds' => 'Visa recensionsinlägg', 30 30 'types' => 'Meddelandetyper', 31 31 'username' => 'Användarnamn', 32 32
+8 -8
resources/lang/sv/beatmaps.php
··· 25 25 'message_placeholder_silenced' => "Kan inte lägga upp diskussionen medan du är tystad.", 26 26 'message_type_select' => 'Välj kommentarstyp', 27 27 'reply_notice' => 'Tryck enter för att svara.', 28 - 'reply_resolve_notice' => '', 28 + 'reply_resolve_notice' => 'Tryck enter för att svara. Tryck ctrl+enter för att svara och lösa.', 29 29 'reply_placeholder' => 'Skriv ditt svar här', 30 30 'require-login' => 'Var vänlig logga in för att skicka inlägg eller svara', 31 31 'resolved' => 'Löst', 32 32 'restore' => 'återställ', 33 33 'show_deleted' => 'Visa borttagna', 34 34 'title' => 'Diskussioner', 35 - 'unresolved_count' => '', 35 + 'unresolved_count' => ':count_delimited olösta problem|:count_delimited olösta problem', 36 36 37 37 'collapse' => [ 38 38 'all-collapse' => 'Kollapsa allt', ··· 87 87 'nomination_reset' => 'Ta bort alla Nomineringar', 88 88 'praise' => 'Lägg ut Beröm', 89 89 'problem' => 'Lägg ut Problem', 90 - 'problem_warning' => '', 91 - 'review' => '', 92 - 'suggestion' => '', 90 + 'problem_warning' => 'Lägg Upp Problem', 91 + 'review' => 'Lägg Upp Recension', 92 + 'suggestion' => 'Lägg Upp Förslag', 93 93 ], 94 94 95 95 'mode' => [ ··· 215 215 216 216 'rank_estimate' => [ 217 217 '_' => 'Denna beatmap uppskattas vara rankad :date, så länge inga fel uppstår. Den är #:position i :queue.', 218 - 'unresolved_problems' => '', 219 - 'problems' => '', 218 + 'unresolved_problems' => 'Denna låt är för närvarande blockerad från att lämna den Kvalificerade sektionen tills :problems är löst.', 219 + 'problems' => 'dessa problem', 220 220 'on' => 'den :date', 221 221 'queue' => 'rankkö', 222 222 'soon' => 'snart', ··· 285 285 'taiko' => '', 286 286 'fruits' => '', 287 287 'mania' => '', 288 - 'undefined' => '', 288 + 'undefined' => 'inte inställt', 289 289 ], 290 290 'status' => [ 291 291 'any' => 'Alla',
+7 -6
resources/lang/sv/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Sakta ner, spela mer.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [ ··· 40 41 ], 41 42 42 43 'nominate' => [ 43 - 'bng_limited_too_many_rulesets' => '', 44 - 'full_nomination_required' => '', 44 + 'bng_limited_too_many_rulesets' => 'Probationära nominatörer kan ej nominera flera regelset.', 45 + 'full_nomination_required' => 'Du måste vara en fullständig nominatör för att utföra den slutliga nomineringen av ett regelset.', 45 46 'hybrid_requires_modes' => 'En hybrid beatmap kräver att du väljer minst ett spelläge att nominera för.', 46 47 'incorrect_mode' => 'Du har inte behörighet att nominera för läge: :mode', 47 - 'invalid_limited_nomination' => '', 48 - 'invalid_ruleset' => '', 48 + 'invalid_limited_nomination' => 'Denna beatmap har ogiltiga nomineringar och kan inte kvalificeras i detta tillstånd', 49 + 'invalid_ruleset' => 'Den här nomineringen har ogiltiga regelverk.', 49 50 'too_many' => 'Nomineringskravet är redan uppfyllt.', 50 - 'too_many_non_main_ruleset' => '', 51 + 'too_many_non_main_ruleset' => 'Nomineringskrav för icke-huvudregelset har redan uppfyllts.', 51 52 52 53 'dialog' => [ 53 54 'confirmation' => 'Är du säker på att du vill nominera denna beatmap?', 54 55 'header' => 'Nominera beatmap', 55 56 'hybrid_warning' => 'notera: du kan bara nominera en gång, så se till att du nominerar för alla spellägen som du tänker nominera för', 56 - 'current_main_ruleset' => '', 57 + 'current_main_ruleset' => 'Det huvudsakliga regelsettet är för närvarande :ruleset', 57 58 'which_modes' => 'Nominera för vilka spellägen?', 58 59 ], 59 60 ],
+3 -3
resources/lang/sv/chat.php
··· 18 18 'channels' => [ 19 19 'confirm_part' => 'Vill du dölja denna kanal? Du kommer fortfarande ta emot meddelanden från denna kanal.', 20 20 'create' => 'skapa meddelande', 21 - 'join' => '', 22 - 'none' => '', 21 + 'join' => 'gå med i kanal', 22 + 'none' => 'ingen kanal', 23 23 24 24 'list' => [ 25 25 'title' => [ ··· 64 64 ], 65 65 66 66 'join_channels' => [ 67 - 'loading' => '', 67 + 'loading' => 'Laddar kanallista...', 68 68 ], 69 69 ];
+2 -1
resources/lang/sv/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'dölj bedömda bidrag', 18 19 'nav_title' => 'bedöm', 19 20 'no_current_vote' => 'du har inte röstat ännu.', 20 21 'update' => 'uppdatera', 21 22 'validation' => [ 22 - 'missing_score' => '', 23 + 'missing_score' => 'saknar resultat', 23 24 'contest_vote_judged' => 'kan inte rösta i bedömda tävlingar', 24 25 ], 25 26 'voted' => 'Du har redan röstat på detta bidrag.',
+2 -2
resources/lang/sv/errors.php
··· 29 29 'generic' => 'Ett fel inträffade när din transaktion förbereddes.', 30 30 ], 31 31 'scores' => [ 32 - 'invalid_id' => '', 32 + 'invalid_id' => 'Ogiltigt poäng id.', 33 33 ], 34 34 'search' => [ 35 35 'default' => 'Kunde inte få några resultat, försök igen senare.', ··· 37 37 'operation_timeout_exception' => 'Sökfunktionen är för närvarande mer upptagen än vanligt, försök igen senare.', 38 38 ], 39 39 'user_report' => [ 40 - 'recently_reported' => "", 40 + 'recently_reported' => "Du har redan rapporterat det här nyligen.", 41 41 ], 42 42 ];
+1 -1
resources/lang/sv/events.php
··· 27 27 ], 28 28 29 29 'value' => [ 30 - 'rank' => '', 30 + 'rank' => 'rank #:rank', 31 31 ], 32 32 ];
+2 -2
resources/lang/sv/layout.php
··· 199 199 'legacy_score_only_toggle_tooltip' => 'Lazer läget visar resultat som är satta i lazer med den nya poängalgoritmen', 200 200 'logout' => 'Logga ut', 201 201 'profile' => 'Min profil', 202 - 'scoring_mode_toggle' => '', 203 - 'scoring_mode_toggle_tooltip' => '', 202 + 'scoring_mode_toggle' => 'Klassiskt resultat', 203 + 'scoring_mode_toggle_tooltip' => 'Justera poängvärden för att kännas mer som klassisk poängsättning utan tak', 204 204 ], 205 205 ], 206 206
+1 -1
resources/lang/sv/oauth.php
··· 7 7 'cancel' => 'Avbryt', 8 8 9 9 'authorise' => [ 10 - 'app_owner' => '', 10 + 'app_owner' => 'en app av :owner', 11 11 'request' => 'begär behörighet att komma åt ditt konto.', 12 12 'scopes_title' => 'Denna applikation kommer att kunna:', 13 13 'title' => 'Auktoriseringsbegäran.',
+2 -2
resources/lang/sv/store.php
··· 65 65 'cancelled' => [ 66 66 'title' => 'Din beställning har avbrutits', 67 67 'line_1' => [ 68 - '_' => "", 68 + '_' => "Om du inte bad om en avbrytning var god kontakta :link med ditt order nummer (#:order_number).", 69 69 'link_text' => 'osu!store support', 70 70 ], 71 71 ], ··· 93 93 'title' => 'Din beställning har skickats!', 94 94 'tracking_details' => 'Spårningsinformation följer:', 95 95 'no_tracking_details' => [ 96 - '_' => "", 96 + '_' => "Vi har inga spårningsuppgifter eftersom vi skickade paketet via Air Mail, men vi uppskattar att du kommer få det inom 1-3 veckor. I Europa kan tullen förlänga väntetiden, vilket är utom vår kontroll. Om du har några funderingar kan du svara på bekräftelse mejlet du fick av oss (eller :link).", 97 97 'link_text' => 'skicka oss ett e-post', 98 98 ], 99 99 ],
+14 -13
resources/lang/sv/users.php
··· 197 197 'to_1' => 'Visa omslagsbild', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 200 + 'daily' => 'Daglig Streak', 201 + 'daily_streak_best' => 'Bästa Dagliga Streak', 202 + 'daily_streak_current' => 'Nuvarande Dagliga Streak', 203 + 'playcount' => '', 203 204 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 205 + 'top_10p_placements' => 'Topp 10% Placeringar', 206 + 'top_50p_placements' => 'Topp 50% Placeringar', 207 + 'weekly' => 'Vecko Streak', 208 + 'weekly_streak_best' => 'Bästa Vecko Streak', 209 + 'weekly_streak_current' => 'Nuvarande Vecko Streak', 209 210 210 211 'unit' => [ 211 212 'day' => '', ··· 217 218 'button' => 'Ändra Profilomslag', 218 219 'defaults_info' => 'Fler omslagsalternativ kommer finnas i framtiden', 219 220 'holdover_remove_confirm' => "", 220 - 'title' => '', 221 + 'title' => 'Omslag', 221 222 222 223 'upload' => [ 223 224 'broken_file' => 'Misslyckades med att processa bilden. Verifiera uppladdad bild och försök igen.', ··· 241 242 ], 242 243 243 244 'hue' => [ 244 - 'reset_no_supporter' => '', 245 - 'title' => '', 245 + 'reset_no_supporter' => 'Återställ färger till standard? En supporter tagg behövs för att byta till en annan färg.', 246 + 'title' => 'Färg', 246 247 247 248 'supporter' => [ 248 - '_' => '', 249 - 'link' => '', 249 + '_' => 'Anpassade färgteman endast tillgängliga för :link', 250 + 'link' => 'osu!supportrar', 250 251 ], 251 252 ], 252 253 ],
+1
resources/lang/tg-TJ/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => '', 13 + 'reset' => '', 13 14 'rules' => '', 14 15 'rules_link' => '', 15 16 ],
+1
resources/lang/tg-TJ/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => '', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/tg-TJ/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/tg-TJ/users.php
··· 200 200 'daily' => '', 201 201 'daily_streak_best' => '', 202 202 'daily_streak_current' => '', 203 + 'playcount' => '', 203 204 'title' => '', 204 205 'top_10p_placements' => '', 205 206 'top_50p_placements' => '',
+1
resources/lang/th/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'รูปโปรไฟล์', 13 + 'reset' => '', 13 14 'rules' => 'โปรดตรวจสอบให้แน่ใจว่า avatar ของคุณเป็นไปตาม :link.<br/> ซึ่งหมายความว่ามันจะต้องเป็น <strong> เหมาะสำหรับทุกวัย </strong> เช่น ไม่มีภาพลามกหยาบคายหรือเนื้อหาที่มีการชักจูง', 14 15 'rules_link' => 'กฎของชุมชน', 15 16 ],
+1
resources/lang/th/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'ช้าลงหน่อย เล่นมากขึ้น', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/th/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'ความคิดเห็น', 17 18 'hide_judged' => '', 18 19 'nav_title' => '', 19 20 'no_current_vote' => '',
+1
resources/lang/th/users.php
··· 201 201 'daily' => '', 202 202 'daily_streak_best' => '', 203 203 'daily_streak_current' => '', 204 + 'playcount' => '', 204 205 'title' => '', 205 206 'top_10p_placements' => '', 206 207 'top_50p_placements' => '',
+1
resources/lang/tr/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Avatar', 13 + 'reset' => 'sıfırla', 13 14 'rules' => 'Lütfen avatarınızın :link uyduğundan emin olun.<br/>Bu, avatarın <strong>her yaş grubuna uygun olması</strong> gerektiği anlamına gelir. Yani çıplaklık, küfür veya müstehcen içerik bulunmamalıdır.', 14 15 'rules_link' => 'topluluk kurallarına', 15 16 ],
+1
resources/lang/tr/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Yavaş ol, daha çok oyna.', 20 + 'no_mirrors' => '', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/tr/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '', 17 18 'hide_judged' => 'değerlendirilen girişleri gizle', 18 19 'nav_title' => 'yargıç', 19 20 'no_current_vote' => 'henüz oy vermedin.',
+2 -2
resources/lang/tr/layout.php
··· 199 199 'legacy_score_only_toggle_tooltip' => 'Lazer modu yeni bir puanlama algoritmasıyla lazerden belirnenen skorları gösterir', 200 200 'logout' => 'Çıkış Yap', 201 201 'profile' => 'Profilim', 202 - 'scoring_mode_toggle' => '', 203 - 'scoring_mode_toggle_tooltip' => '', 202 + 'scoring_mode_toggle' => 'Klasik skorlama', 203 + 'scoring_mode_toggle_tooltip' => 'Skorları klasik sınırsız skorlamaya benzeyecek şekilde ayarla', 204 204 ], 205 205 ], 206 206
+12 -11
resources/lang/tr/users.php
··· 197 197 'to_1' => 'Kapağı göster', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Günlük Seri', 201 + 'daily_streak_best' => 'En İyi Günlük Seri', 202 + 'daily_streak_current' => 'Mevcut Günlük Seri', 203 + 'playcount' => '', 204 + 'title' => 'Günlük\nMeydan Okuma', 205 + 'top_10p_placements' => 'İlk %10 Sıralama', 206 + 'top_50p_placements' => 'İlk %50 Sıralama', 207 + 'weekly' => 'Haftalık Seri', 208 + 'weekly_streak_best' => 'En İyi Haftalık Seri', 209 + 'weekly_streak_current' => 'Mevcut Haftalık Seri', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':value', 213 + 'week' => ':value', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/uk/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Аватар', 13 + 'reset' => 'скинути', 13 14 'rules' => 'Будь ласка, переконайтесь що Ваш аватар відповідає :link.<br/>Це означає що він повинен <strong>підходити людям, будь-якого віку</strong>. Тобто: не містити наготи, нецензурної лексики або непристойного вмісту.', 14 15 'rules_link' => 'правилам спільноти', 15 16 ],
+1
resources/lang/uk/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Зменш темп, більше грай.', 20 + 'no_mirrors' => 'Немає доступних серверів для завантаження.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/uk/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'коментарі', 17 18 'hide_judged' => 'сховати оцінені заявки', 18 19 'nav_title' => 'суддя', 19 20 'no_current_vote' => 'ви ще не голосували.',
+12 -11
resources/lang/uk/users.php
··· 197 197 'to_1' => 'Розгорнути обкладинку профілю', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Щоденна серія', 201 + 'daily_streak_best' => 'Найкраща щоденна серія', 202 + 'daily_streak_current' => 'Поточна щоденна серія', 203 + 'playcount' => '', 204 + 'title' => 'Щоденний\nВиклик', 205 + 'top_10p_placements' => 'Топ 10% позицій', 206 + 'top_50p_placements' => 'Топ 50% позицій', 207 + 'weekly' => 'Тижнева серія', 208 + 'weekly_streak_best' => 'Найкраща тижнева серія', 209 + 'weekly_streak_current' => 'Поточна тижнева серія', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valueд', 213 + 'week' => ':valueтиж', 213 214 ], 214 215 ], 215 216 'edit' => [
+1
resources/lang/vi/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => 'Ảnh đại diện', 13 + 'reset' => 'đặt lại', 13 14 'rules' => 'Hãy chắc rằng ảnh đại diện của bạn tuân thủ :link.<br/>Điều này có nghĩa rằng ảnh phải <strong>phù hợp với mọi lứa tuổi</strong>. Ví dụ như không có nội dung khiêu gợi, thô tục hoặc gợi tưởng.', 14 15 'rules_link' => 'những tiêu chuẩn cộng đồng', 15 16 ],
+1
resources/lang/vi/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => 'Chậm lại, chơi nhiều hơn.', 20 + 'no_mirrors' => 'Không có sẵn máy chủ tải xuống nào cả.', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1 -1
resources/lang/vi/chat.php
··· 7 7 'loading_users' => 'đang chờ người dùng...', 8 8 'talking_in' => 'đang trò chuyện ở :channel', 9 9 'talking_with' => 'đang trò chuyện với :name', 10 - 'title_compact' => 'chat', 10 + 'title_compact' => 'tin nhắn', 11 11 'unread_messages' => 'tin nhắn chưa đọc', 12 12 13 13 'cannot_send' => [
+1
resources/lang/vi/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => 'bình luận', 17 18 'hide_judged' => 'ẩn các bài thi đã được đánh giá', 18 19 'nav_title' => 'đánh giá', 19 20 'no_current_vote' => 'bạn vẫn chưa bầu chọn.',
+1 -1
resources/lang/vi/rankings.php
··· 40 40 'seasons' => [ 41 41 'empty' => 'Hiện tại chưa có phòng nào ở mùa này.', 42 42 'ongoing' => 'Mùa đang diễn ra (sẽ có nhiều playlist được thêm vào).', 43 - 'room_count' => 'Số playlist', 43 + 'room_count' => 'Số danh sách phát', 44 44 'url' => 'Hiện thêm thông tin về mùa đó.', 45 45 ], 46 46
+16 -15
resources/lang/vi/users.php
··· 8 8 9 9 'beatmapset_activities' => [ 10 10 'title' => "Lịch Sử Modding Của :user", 11 - 'title_compact' => 'Modding', 11 + 'title_compact' => 'Sửa đổi', 12 12 13 13 'discussions' => [ 14 14 'title_recent' => 'Cuộc thảo luận gần đây', ··· 59 59 'password' => 'mật khẩu', 60 60 'password_confirmation' => 'xác nhận mật khẩu', 61 61 'submit' => 'tạo tài khoản', 62 - 'user_email' => 'email', 63 - 'user_email_confirmation' => 'xác nhận email', 62 + 'user_email' => 'thư điện tử', 63 + 'user_email_confirmation' => 'xác nhận thư điện tử', 64 64 'username' => 'tên người dùng', 65 65 66 66 'tos_notice' => [ ··· 197 197 'to_1' => 'Hiện ảnh bìa', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => 'Chuỗi chơi hằng ngày', 201 + 'daily_streak_best' => 'Chuỗi chơi hằng ngày tốt nhất', 202 + 'daily_streak_current' => 'Chuỗi chơi hằng ngày hiện tại', 203 + 'playcount' => '', 204 + 'title' => 'Thử thách\nhằng ngày', 205 + 'top_10p_placements' => '10% vị trí hàng đầu', 206 + 'top_50p_placements' => '50% vị trí hàng đầu', 207 + 'weekly' => 'Chuỗi chơi hàng tuần', 208 + 'weekly_streak_best' => 'Chuỗi chơi hàng tuần tốt nhất', 209 + 'weekly_streak_current' => 'Chuỗi chơi hàng tuần hiện tại', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valued', 213 + 'week' => ':valuew', 213 214 ], 214 215 ], 215 216 'edit' => [ ··· 388 389 'title' => 'Màn chơi nhiều người chơi', 389 390 ], 390 391 'top_ranks' => [ 391 - 'download_replay' => 'Tải Xuống Replay', 392 + 'download_replay' => 'Tải Xuống Phần Phát Lại', 392 393 'not_ranked' => 'Chỉ có beatmap được xếp hạng mới có pp.', 393 394 'pp_weight' => 'trọng số :percentage', 394 395 'view_details' => 'Xem chi tiết',
+6 -5
resources/lang/zh-tw/accounts.php
··· 5 5 6 6 return [ 7 7 'edit' => [ 8 - 'title_compact' => '設定', 8 + 'title_compact' => '帳號設定', 9 9 'username' => '使用者名稱', 10 10 11 11 'avatar' => [ 12 12 'title' => '編輯頭像', 13 - 'rules' => '請確保您的頭像符合 :link.<br/>這意味著必須 <strong>適合所有年齡</strong>. i.e. 沒有裸露,褻瀆或暗示性的內容。', 13 + 'reset' => '重置', 14 + 'rules' => '請確保您的頭像符合 :link.<br/>這意味着必須<strong>適合所有年齡</strong>,即沒有裸露、褻瀆或暗示性的內容。', 14 15 'rules_link' => '社群規則', 15 16 ], 16 17 17 18 'email' => [ 18 19 'new' => '新電子郵件地址', 19 - 'new_confirmation' => '再次輸入電子郵件地址', 20 + 'new_confirmation' => '再次輸入電郵地址', 20 21 'title' => '電子郵件', 21 22 'locked' => [ 22 23 '_' => '如欲修改你的電子郵件地址,請聯絡 :accounts。', ··· 85 86 'options' => [ 86 87 '_' => '傳送選項', 87 88 'beatmap_owner_change' => '客串難度', 88 - 'beatmapset:modding' => '圖譜製作', 89 - 'channel_message' => '私人訊息', 89 + 'beatmapset:modding' => '圖譜模圖', 90 + 'channel_message' => '私訊', 90 91 'comment_new' => '新評論', 91 92 'forum_topic_reply' => '主題回覆', 92 93 'mail' => '郵箱',
+1
resources/lang/zh-tw/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => '欲速則不達。', 20 + 'no_mirrors' => '沒有可用的下載伺服器。', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1
resources/lang/zh-tw/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '評論', 17 18 'hide_judged' => '隱藏已評分的項目', 18 19 'nav_title' => '評分', 19 20 'no_current_vote' => '您尚未投票',
+12 -11
resources/lang/zh-tw/users.php
··· 197 197 'to_1' => '顯示封面', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => '每日連續次數', 201 + 'daily_streak_best' => '最佳每日連續次數', 202 + 'daily_streak_current' => '目前每日連續次數', 203 + 'playcount' => '', 204 + 'title' => '每日挑戰', 205 + 'top_10p_placements' => '前10%名次', 206 + 'top_50p_placements' => '前50%名次', 207 + 'weekly' => '每周連續次數', 208 + 'weekly_streak_best' => '最佳每周連續次數', 209 + 'weekly_streak_current' => '目前每周連續次數', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':valued', 213 + 'week' => ':valuew', 213 214 ], 214 215 ], 215 216 'edit' => [
+2 -2
resources/lang/zh-tw/wiki.php
··· 12 12 'missing_translation' => '請求的頁面沒有當前語言的版本。', 13 13 'needs_cleanup_or_rewrite' => '該頁面並沒有達到 osu! wiki 的標準並需要整理或者修正。如果您可以幫助修正,請考慮更新這篇文章!', 14 14 'search' => '在 wiki 中搜索 :link 。', 15 - 'stub' => '這篇文章尚未完成,等待有人擴充。', 15 + 'stub' => '這篇文章尚未完成,正在等待擴充。', 16 16 'toc' => '目錄', 17 17 18 18 'edit' => [ 19 19 'link' => '在 GitHub 上顯示', 20 - 'refresh' => '刷新', 20 + 'refresh' => '重新整理', 21 21 ], 22 22 23 23 'translation' => [
+1
resources/lang/zh/accounts.php
··· 10 10 11 11 'avatar' => [ 12 12 'title' => '头像', 13 + 'reset' => '重置', 13 14 'rules' => '请确保你的头像符合 :link。<br/>这意味着头像内容必须是<strong>全年龄的</strong>,即没有裸露、亵渎或暗示的内容。', 14 15 'rules_link' => '社区规则', 15 16 ],
+4 -4
resources/lang/zh/api.php
··· 14 14 15 15 'scopes' => [ 16 16 'bot' => '作为聊天机器人。', 17 - 'identify' => '鉴别你的身份并读取你的公开个人资料', 17 + 'identify' => '鉴别你的身份并读取你的公开个人资料。', 18 18 19 19 'chat' => [ 20 - 'read' => '以您的名义阅读消息。', 21 - 'write' => '以您的名义发送消息。', 22 - 'write_manage' => '以您的名义加入、离开频道。', 20 + 'read' => '以你的名义阅读消息。', 21 + 'write' => '以你的名义发送消息。', 22 + 'write_manage' => '以你的名义加入、离开频道。', 23 23 ], 24 24 25 25 'forum' => [
+2 -2
resources/lang/zh/artist.php
··· 13 13 14 14 'beatmaps' => [ 15 15 '_' => '谱面', 16 - 'download' => '下载谱面模版', 17 - 'download-na' => '谱面模版暂时不可用', 16 + 'download' => '下载谱面模板', 17 + 'download-na' => '谱面模板尚不可用', 18 18 ], 19 19 20 20 'index' => [
+5 -5
resources/lang/zh/authorization.php
··· 32 32 33 33 'vote' => [ 34 34 'bot' => "不能对机器人的讨论投票", 35 - 'limit_exceeded' => '请稍等后再投票。', 35 + 'limit_exceeded' => '请稍等后再投票', 36 36 'owner' => "不能为自己的讨论投票!", 37 37 'wrong_beatmapset_state' => '只能给待定 (Pending) 谱面的讨论投票。', 38 38 ], ··· 42 42 'destroy' => [ 43 43 'not_owner' => '你只能删除你自己的帖子。', 44 44 'resolved' => '你不能删除已解决的讨论帖。', 45 - 'system_generated' => '自动生成的帖子无法删除。', 45 + 'system_generated' => '无法删除自动生成的帖子。', 46 46 ], 47 47 48 48 'edit' => [ 49 49 'not_owner' => '只有作者可以编辑。', 50 50 'resolved' => '你不能编辑已解决讨论里的帖子。', 51 - 'system_generated' => '自动生成的帖子无法被编辑。', 51 + 'system_generated' => '无法编辑自动生成的帖子。', 52 52 ], 53 53 ], 54 54 ··· 112 112 ], 113 113 114 114 'store' => [ 115 - 'play_more' => '在发帖之前先玩上两局吧!如果你在游戏时遇到问题,请在 Help 或 中文 版块发帖求助。', 115 + 'play_more' => '在发帖之前先玩上两局吧!如果你在游戏时遇到问题,请在“Help”或“中文”版块发帖求助。', 116 116 'too_many_help_posts' => "如果你想发更多的帖子,再多玩几局吧!如果你在游戏时仍遇到问题,请发送邮件至 support@ppy.sh", // FIXME: unhardcode email address. 117 117 ], 118 118 ], ··· 146 146 'user' => [ 147 147 'require_login' => '投票前请先登录。', 148 148 'restricted' => "账户处于限制模式,无法投票。", 149 - 'silenced' => "账户被禁言,无法投票。", 149 + 'silenced' => "账户禁言中,无法投票。", 150 150 ], 151 151 ], 152 152
+2 -2
resources/lang/zh/beatmap_discussions.php
··· 35 35 'all' => '所有', 36 36 'disqualified' => '下架 (DQ)', 37 37 'never_qualified' => '从未过审 (Qualified)', 38 - 'qualified' => '合格', 38 + 'qualified' => '过审 (Qualified)', 39 39 'ranked' => '上架 (Ranked)', 40 40 ], 41 41 ··· 84 84 'invalid_document' => '审阅无效', 85 85 'invalid_discussion_type' => '讨论类型无效', 86 86 'minimum_issues' => '审阅时必须指出最少 :count 个问题', 87 - 'missing_text' => '该版块缺少文本。', 87 + 'missing_text' => '该版块缺少文本', 88 88 'too_many_blocks' => '审阅只能包含 :count 个段落或问题', 89 89 ], 90 90 ],
+2 -2
resources/lang/zh/beatmappacks.php
··· 19 19 'show' => [ 20 20 'download' => '下载', 21 21 'item' => [ 22 - 'cleared' => '玩过', 23 - 'not_cleared' => '未玩过', 22 + 'cleared' => '已通过', 23 + 'not_cleared' => '未通过', 24 24 ], 25 25 'no_diff_reduction' => [ 26 26 '_' => '若要解锁成就,则不能使用:link游玩谱面。',
+3 -3
resources/lang/zh/beatmaps.php
··· 20 20 'edited' => ':editor 最后在 :update_time 编辑。', 21 21 'guest' => ':user 制作的客串难度', 22 22 'kudosu_denied' => 'kudosu 已收回', 23 - 'message_placeholder_deleted_beatmap' => '该难度已被删除,无法继续讨论', 23 + 'message_placeholder_deleted_beatmap' => '该难度已被删除,无法继续讨论。', 24 24 'message_placeholder_locked' => '该谱面下的讨论已关闭。', 25 25 'message_placeholder_silenced' => "禁言时无法发布讨论。", 26 26 'message_type_select' => '选择回复类型', ··· 95 95 'mode' => [ 96 96 'events' => '历史', 97 97 'general' => '常规 :scope', 98 - 'reviews' => '审阅记录', 98 + 'reviews' => '审阅', 99 99 'timeline' => '时间轴', 100 100 'scopes' => [ 101 101 'general' => '当前难度', ··· 120 120 'unsaved' => '尚未保存', 121 121 'timestamp' => [ 122 122 'all-diff' => '你不能在“所有难度”讨论区中发布时间戳。', 123 - 'diff' => '如果此 :type 以时间戳开头,它将显示在时间轴下。', 123 + 'diff' => '如果此帖子以时间戳开头,则会显示在时间轴下方。', 124 124 ], 125 125 ], 126 126 'insert-block' => [
+1
resources/lang/zh/beatmapsets.php
··· 17 17 18 18 'download' => [ 19 19 'limit_exceeded' => '慢一点,打几张图再回来吧。', 20 + 'no_mirrors' => '没有可用的下载服务器。', 20 21 ], 21 22 22 23 'featured_artist_badge' => [
+1 -1
resources/lang/zh/common.php
··· 4 4 // See the LICENCE file in the repository root for full licence text. 5 5 6 6 return [ 7 - 'confirmation' => '确定?', 7 + 'confirmation' => '你确定吗?', 8 8 'confirmation_unsaved' => '未保存的更改将丢失。您确定吗?', 9 9 'saved' => '已保存', 10 10
+1
resources/lang/zh/contest.php
··· 14 14 ], 15 15 16 16 'judge' => [ 17 + 'comments' => '评论', 17 18 'hide_judged' => '隐藏已打分的项目', 18 19 'nav_title' => '打分', 19 20 'no_current_vote' => '你尚未投票。',
+2 -2
resources/lang/zh/matches.php
··· 10 10 'header' => '多人游戏', 11 11 'in-progress' => '(游戏进行中)', 12 12 'in_progress_spinner_label' => '游戏进行中', 13 - 'loading-events' => '加载事件...', 13 + 'loading-events' => '加载事件中...', 14 14 'winner' => ':team 胜利', 15 15 'winner_by' => ':winner,分差 :difference', 16 16 ··· 27 27 'player-kicked-no-user' => '有玩家被踢出房间', 28 28 'match-created-no-user' => '创建了房间', 29 29 'match-disbanded-no-user' => '房间关闭', 30 - 'host-changed-no-user' => '房主已经变更', 30 + 'host-changed-no-user' => '房主已被更改', 31 31 ], 32 32 33 33 'score' => [
+1 -1
resources/lang/zh/model_validation.php
··· 140 140 'invalid_email' => "无效的邮箱地址。", 141 141 'invalid_twitter' => 'Twitter 用户名无效', 142 142 'too_short' => '新密码太短。', 143 - 'unknown_duplicate' => '已使用的用户名或邮箱。', 143 + 'unknown_duplicate' => '用户名或邮箱已被使用。', 144 144 'username_available_in' => '该用户名将在 :duration 后可用。', 145 145 'username_available_soon' => '该用户名即将可用!', 146 146 'username_invalid_characters' => '用户名中包含非法字符。',
+2 -2
resources/lang/zh/password_reset.php
··· 18 18 'missing_key' => '必填', 19 19 'too_many_tries' => '重试次数过多', 20 20 'user_not_found' => '请求的用户不存在', 21 - 'wrong_key' => '不正确的验证码', 21 + 'wrong_key' => '验证码不正确。', 22 22 ], 23 23 24 24 'notice' => [ ··· 37 37 'username' => '输入邮箱或用户名', 38 38 39 39 'reason' => [ 40 - 'inactive_different_country' => "您的帐户已经很长时间没有被使用。为了确保您的帐户安全,请重置您的密码。", 40 + 'inactive_different_country' => "您的账户已经很长时间没有被使用。为了确保您的账户安全,请重置密码。", 41 41 ], 42 42 'support' => [ 43 43 '_' => '需要进一步的帮助?通过我们的 :button 联系我们。',
+1 -1
resources/lang/zh/rankings.php
··· 28 28 ], 29 29 30 30 'type' => [ 31 - 'charts' => '高光', 31 + 'charts' => '季赛(旧版)', 32 32 'country' => '国家/地区', 33 33 'kudosu' => 'Kudosu', 34 34 'multiplayer' => '多人游戏',
+1 -1
resources/lang/zh/store.php
··· 31 31 'cart_problems' => '啊哦,您的购物车中存在问题!', 32 32 'cart_problems_edit' => '点击此处编辑。', 33 33 'declined' => '支付被取消。', 34 - 'delayed_shipping' => '欢迎购买,但是我们正在处理大量的订单,所以订单**可能会有 1-2 周的延迟**。', 34 + 'delayed_shipping' => '欢迎购买,但是我们正在处理大量的订单,所以订单可能会有 **1-2 周的延迟**。', 35 35 'hide_from_activity' => '不把此订单中的支持者标签购买同步到个人活动', 36 36 'old_cart' => '您的购物车已经过期,请重试。', 37 37 'pay' => '使用 Paypal 支付',
+15 -14
resources/lang/zh/users.php
··· 197 197 'to_1' => '显示封面', 198 198 ], 199 199 'daily_challenge' => [ 200 - 'daily' => '', 201 - 'daily_streak_best' => '', 202 - 'daily_streak_current' => '', 203 - 'title' => '', 204 - 'top_10p_placements' => '', 205 - 'top_50p_placements' => '', 206 - 'weekly' => '', 207 - 'weekly_streak_best' => '', 208 - 'weekly_streak_current' => '', 200 + 'daily' => '每日连续完成数', 201 + 'daily_streak_best' => '最佳每日完成数', 202 + 'daily_streak_current' => '当前每日完成数', 203 + 'playcount' => '', 204 + 'title' => '每日\n挑战', 205 + 'top_10p_placements' => '前 10% 位置', 206 + 'top_50p_placements' => '前 50% 位置', 207 + 'weekly' => '每周完成数', 208 + 'weekly_streak_best' => '最佳每周完成数', 209 + 'weekly_streak_current' => '当前每周完成数', 209 210 210 211 'unit' => [ 211 - 'day' => '', 212 - 'week' => '', 212 + 'day' => ':value 天', 213 + 'week' => ':value 周', 213 214 ], 214 215 ], 215 216 'edit' => [ ··· 519 520 ], 520 521 521 522 'view_mode' => [ 522 - 'brick' => '方块检视', 523 - 'card' => '卡片检视', 524 - 'list' => '列表检视', 523 + 'brick' => '方格视图', 524 + 'card' => '卡片视图', 525 + 'list' => '列表视图', 525 526 ], 526 527 ];
-2
resources/views/home/landing.blade.php
··· 152 152 153 153 @include('layout.footer', ['modifiers' => ['landing'], 'withLinks' => false]) 154 154 </footer> 155 - 156 - @include('layout.popup-container') 157 155 @endsection 158 156 159 157 @section ("script")
+18 -4
resources/views/multiplayer/rooms/_rankings_table.blade.php
··· 19 19 </tr> 20 20 </thead> 21 21 <tbody> 22 - @foreach ($scores as $index => $score) 22 + @foreach ([$userScore, ...$scores] as $index => $score) 23 + @if ($score === null) 24 + @continue 25 + @endif 26 + @php 27 + $rank = $loop->first 28 + ? $score->userRank() 29 + // -1 due to userScore being prepended 30 + : $scores->firstItem() + $index - 1; 31 + @endphp 23 32 <tr class="ranking-page-table__row{{$score->user->isActive() ? '' : ' ranking-page-table__row--inactive'}}"> 24 33 <td class="ranking-page-table__column ranking-page-table__column--rank"> 25 - #{{ $scores->firstItem() + $index }} 34 + #{{ $rank }} 26 35 </td> 27 36 <td class="ranking-page-table__column"> 28 37 <div class="ranking-page-table__user-link"> ··· 42 51 </div> 43 52 </td> 44 53 <td class="ranking-page-table__column ranking-page-table__column--dimmed"> 45 - {{ format_percentage($score->averageAccuracy() * 100) }} 54 + {{ format_percentage($score->averageAccuracy()) }} 46 55 </td> 47 56 <td class="ranking-page-table__column ranking-page-table__column--dimmed"> 48 57 {{ i18n_number_format($score->attempts) }} 49 58 </td> 50 59 <td class="ranking-page-table__column ranking-page-table__column--focused"> 51 - {!! suffixed_number_format_tag($score->total_score) !!} 60 + {!! i18n_number_format($score->total_score) !!} 52 61 </td> 53 62 </tr> 63 + @if ($loop->first) 64 + <tr> 65 + <td colspan="5">&nbsp;</td> 66 + </tr> 67 + @endif 54 68 @endforeach 55 69 </tbody> 56 70 </table>
+2 -2
resources/views/multiplayer/rooms/show.blade.php
··· 18 18 @section('ranking-header') 19 19 <div class="osu-page osu-page--ranking-info"> 20 20 <div class="js-react--basic-select-options"> 21 - <div class="select-options select-options--spotlight"> 21 + <div class="select-options"> 22 22 <div class="select-options__select"> 23 23 <span class="select-options__option"> 24 24 {{ $room->name }} ··· 67 67 {{ osu_trans('rankings.spotlight.participants') }} 68 68 </div> 69 69 <div class="counter-box__count"> 70 - {{ i18n_number_format($room->participant_count) }} 70 + {{ i18n_number_format($scores->total()) }} 71 71 </div> 72 72 </div> 73 73 </div>
+9 -11
resources/views/rankings/_beatmapsets.blade.php
··· 3 3 See the LICENCE file in the repository root for full licence text. 4 4 --}} 5 5 6 - <div class="rankings-beatmapsets"> 7 - <div class="osu-layout__col-container osu-layout__col-container--with-gutter"> 8 - @foreach ($beatmapsets as $beatmapset) 9 - <div class="osu-layout__col osu-layout__col--sm-6"> 10 - <div 11 - class="js-react--beatmapset-panel" 12 - data-beatmapset-panel="{{ json_encode(['beatmapset' => json_item($beatmapset, 'Beatmapset', ['beatmaps'])]) }}" 13 - ></div> 14 - </div> 15 - @endforeach 16 - </div> 6 + <div class="{{ class_with_modifiers('rankings-beatmapsets', $modifiers ?? null, ['single' => count($beatmapsets) === 1]) }}"> 7 + @foreach ($beatmapsets as $beatmapset) 8 + <div 9 + class="js-react--beatmapset-panel u-contents" 10 + data-beatmapset-panel="{{ json_encode(['beatmapset' => json_item($beatmapset, 'Beatmapset', ['beatmaps'])]) }}" 11 + > 12 + <div class="beatmapset-panel beatmapset-panel--size-normal"></div> 13 + </div> 14 + @endforeach 17 15 </div>
+1 -1
resources/views/rankings/_spotlight_rankings_table.blade.php
··· 54 54 </div> 55 55 </td> 56 56 <td class="ranking-page-table__column ranking-page-table__column--dimmed"> 57 - {{ format_percentage($score->hit_accuracy) }} 57 + {{ format_percentage($score->hit_accuracy / 100) }} 58 58 </td> 59 59 <td class="ranking-page-table__column ranking-page-table__column--dimmed"> 60 60 {{ i18n_number_format($score->playcount) }}
+1 -1
resources/views/rankings/_user_filter.blade.php
··· 8 8 <div class="ranking-filter__title"> 9 9 {{ osu_trans('rankings.filter.title') }} 10 10 </div> 11 - <div class="sort"> 11 + <div class="sort sort--ranking-header"> 12 12 <div class="sort__items"> 13 13 <button class="sort__item sort__item--button">{{ osu_trans('sort.all') }}</button> 14 14 <button class="sort__item sort__item--button">{{ osu_trans('sort.friends')}}</button>
+3 -3
resources/views/rankings/charts.blade.php
··· 6 6 7 7 @section('ranking-header') 8 8 <div class="osu-page osu-page--ranking-info"> 9 - <div class="js-react--spotlight-select-options"> 10 - <div class="select-options select-options--spotlight"> 9 + <div class="js-react--basic-select-options"> 10 + <div class="select-options"> 11 11 <div class="select-options__select"> 12 12 <span class="select-options__option"> 13 13 {{ $spotlight->name }} ··· 16 16 </div> 17 17 </div> 18 18 19 - <script id="json-spotlight-select-options" type="application/json"> 19 + <script id="json-basic-select-options" type="application/json"> 20 20 {!! json_encode($selectOptions) !!} 21 21 </script> 22 22
+79
resources/views/rankings/daily_challenge.blade.php
··· 1 + {{-- 2 + Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 3 + See the LICENCE file in the repository root for full licence text. 4 + --}} 5 + @extends('rankings.index', [ 6 + 'hasMode' => false, 7 + 'hasPager' => true, 8 + 'type' => 'daily_challenge', 9 + 'titlePrepend' => osu_trans('rankings.type.daily_challenge').': '.$currentRoomOption['text'], 10 + ]) 11 + 12 + @php 13 + $percentile = $playlist->scorePercentile(); 14 + @endphp 15 + @section('ranking-header') 16 + <div class="osu-page osu-page--ranking-info"> 17 + <div class="js-react--basic-select-options"> 18 + <div class="select-options"> 19 + <div class="select-options__select"> 20 + <span class="select-options__option"> 21 + {{ $currentRoomOption['text'] }} 22 + </span> 23 + </div> 24 + </div> 25 + </div> 26 + 27 + <script id="json-basic-select-options" type="application/json"> 28 + {!! json_encode([ 29 + 'currentItem' => $currentRoomOption, 30 + 'items' => $roomOptions, 31 + 'type' => 'daily_challenge', 32 + ]) !!} 33 + </script> 34 + 35 + <div class="grid-items grid-items--ranking-info-bar"> 36 + <div class="counter-box counter-box--ranking"> 37 + <div class="counter-box__title"> 38 + {{ osu_trans('rankings.daily_challenge.beatmap') }} 39 + </div> 40 + <div class="counter-box__count"> 41 + <span class="fal fa-extra-mode-{{ $playlist->beatmap->mode }}"></span> 42 + {{ $playlist->beatmap->version }} 43 + </div> 44 + </div> 45 + <div class="counter-box counter-box--ranking"> 46 + <div class="counter-box__title"> 47 + {{ osu_trans('rankings.spotlight.participants') }} 48 + </div> 49 + <div class="counter-box__count"> 50 + {{ i18n_number_format($scores->total()) }} 51 + </div> 52 + </div> 53 + <div class="counter-box counter-box--ranking"> 54 + <div class="counter-box__title"> 55 + {{ osu_trans('rankings.daily_challenge.percentile_10') }} 56 + </div> 57 + <div class="counter-box__count"> 58 + {{ i18n_number_format($percentile['10p']) }} 59 + </div> 60 + </div> 61 + <div class="counter-box counter-box--ranking"> 62 + <div class="counter-box__title"> 63 + {{ osu_trans('rankings.daily_challenge.percentile_50') }} 64 + </div> 65 + <div class="counter-box__count"> 66 + {{ i18n_number_format($percentile['50p']) }} 67 + </div> 68 + </div> 69 + </div> 70 + </div> 71 + @endsection 72 + 73 + @section('scores-header') 74 + @include('rankings._beatmapsets', ['beatmapsets' => [$playlist->beatmap->beatmapset], 'modifiers' => 'daily-challenge']) 75 + @endsection 76 + 77 + @section('scores') 78 + @include('multiplayer.rooms._rankings_table') 79 + @endsection
+14 -4
resources/views/rankings/index.blade.php
··· 31 31 'links' => $links, 32 32 'theme' => 'rankings', 33 33 ]]) 34 - @slot('linksAppend') 34 + @slot('contentAppend') 35 35 @if($hasMode) 36 36 @include('rankings._mode_selector') 37 37 @endif 38 + @endslot 38 39 40 + @slot('linksAppend') 39 41 @yield('additionalHeaderLinks') 42 + @if($hasMode) 43 + <div class="visible-xs"> 44 + @include('rankings._mode_selector') 45 + </div> 46 + @endif 40 47 @endslot 41 48 @endcomponent 42 49 43 50 @yield('ranking-header') 44 51 45 52 @if ($hasScores) 46 - <div class="osu-page osu-page--generic" id="scores"> 53 + <div class="osu-page osu-page--generic"> 54 + @yield('scores-header') 55 + 56 + <div id="scores"></div> 47 57 @if ($hasPager) 48 58 @include('objects._pagination_v2', [ 49 59 'object' => $scores ··· 56 66 @yield('scores') 57 67 </div> 58 68 59 - @yield('ranking-footer') 60 - 61 69 @if ($hasPager) 62 70 @include('objects._pagination_v2', [ 63 71 'object' => $scores ··· 65 73 ->fragment('scores') 66 74 ]) 67 75 @endif 76 + 77 + @yield('ranking-footer') 68 78 </div> 69 79 @endif 70 80 @endsection
+2 -2
resources/views/rankings/performance.blade.php
··· 25 25 <div class="ranking-filter__title"> 26 26 {{ osu_trans('rankings.filter.variant.title') }} 27 27 </div> 28 - <div class="sort"> 28 + <div class="sort sort--ranking-header"> 29 29 <div class="sort__items"> 30 30 @foreach ($variants as $v) 31 31 <button class="sort__item sort__item--button"> ··· 133 133 </div> 134 134 </td> 135 135 <td class="ranking-page-table__column ranking-page-table__column--dimmed"> 136 - {{ format_percentage($score->accuracy_new) }} 136 + {{ format_percentage($score->accuracy_new / 100) }} 137 137 </td> 138 138 <td class="ranking-page-table__column ranking-page-table__column--dimmed"> 139 139 {{ i18n_number_format($score->playcount) }}
+1 -1
resources/views/rankings/score.blade.php
··· 67 67 </div> 68 68 </td> 69 69 <td class="ranking-page-table__column ranking-page-table__column--dimmed"> 70 - {{ format_percentage($score->accuracy_new) }} 70 + {{ format_percentage($score->accuracy_new / 100) }} 71 71 </td> 72 72 <td class="ranking-page-table__column ranking-page-table__column--dimmed"> 73 73 {{ i18n_number_format($score->playcount) }}
+1 -1
routes/web.php
··· 281 281 }); 282 282 283 283 Route::get('rankings/kudosu', 'RankingController@kudosu')->name('rankings.kudosu'); 284 + Route::resource('rankings/daily-challenge', 'Ranking\DailyChallengeController', ['only' => ['index', 'show']]); 284 285 Route::get('rankings/{mode?}/{type?}', 'RankingController@index')->name('rankings'); 285 286 286 287 Route::resource('reports', 'ReportsController', ['only' => ['store']]); ··· 295 296 Route::resource('user-cover-presets', 'UserCoverPresetsController', ['only' => ['index', 'store', 'update']]); 296 297 297 298 Route::post('users/check-username-availability', 'UsersController@checkUsernameAvailability')->name('users.check-username-availability'); 298 - Route::post('users/check-username-exists', 'UsersController@checkUsernameExists')->name('users.check-username-exists'); 299 299 Route::post('users/lookup-users', 'Users\LookupController@lookup')->name('users.lookup-users'); 300 300 Route::get('users/disabled', 'UsersController@disabled')->name('users.disabled'); 301 301 Route::get('users/create', 'UsersController@create')->name('users.create');
+9 -1
tests/Browser/SanityTest.php
··· 5 5 6 6 namespace Tests\Browser; 7 7 8 + use App\Http\Controllers\Ranking\DailyChallengeController; 8 9 use App\Libraries\Session; 9 10 use App\Libraries\SessionVerification; 10 11 use App\Models\Artist; ··· 36 37 use App\Models\Language; 37 38 use App\Models\LegacyMatch; 38 39 use App\Models\LoginAttempt; 40 + use App\Models\Multiplayer\PlaylistItem; 39 41 use App\Models\Multiplayer\Room; 40 42 use App\Models\NewsPost; 41 43 use App\Models\Notification; ··· 269 271 self::$scaffolding['score'] = Score\Best\Osu::factory()->withReplay()->create(); 270 272 271 273 self::$scaffolding['room'] = Room::factory()->create(['category' => 'spotlight']); 274 + 275 + self::$scaffolding['daily_challenge_room'] = Room::factory()->create(['category' => 'daily_challenge']); 276 + PlaylistItem::factory()->create(['room_id' => self::$scaffolding['daily_challenge_room']]); 272 277 } 273 278 274 279 private static function filterLog(array $log) ··· 445 450 'changelog.show' => [ 446 451 'changelog' => self::$scaffolding['build']->version, 447 452 ], 453 + 'daily-challenge.show' => [ 454 + 'daily_challenge' => DailyChallengeController::roomId(self::$scaffolding['daily_challenge_room']), 455 + ], 448 456 'scores.download-legacy' => [ 449 457 'rulesetOrScore' => static::$scaffolding['score']->getMode(), 450 458 'score' => static::$scaffolding['score']->getKey(), ··· 511 519 512 520 private function checkAdminPermission(Browser $browser, LaravelRoute $route) 513 521 { 514 - $adminRestricted = ['chat.users.index', 'forum.topics.logs.index', 'user-cover-presets.index']; 522 + $adminRestricted = ['forum.topics.logs.index', 'user-cover-presets.index']; 515 523 516 524 if (starts_with($route->uri, 'admin') || in_array($route->getName(), $adminRestricted, true)) { 517 525 // TODO: retry and check page as admin? (will affect subsequent tests though, so figure out how to deal with that..)
+1 -1
tests/DuskTestCase.php
··· 30 30 } 31 31 32 32 if (!present(env('DUSK_WEBDRIVER_URL'))) { 33 - static::startChromeDriver(); 33 + static::startChromeDriver(['--port=9515']); 34 34 } 35 35 } 36 36
+88 -9
tests/Models/DailyChallengeUserStatsTest.php
··· 18 18 19 19 class DailyChallengeUserStatsTest extends TestCase 20 20 { 21 + protected static function roomAddPlay(User $user, PlaylistItem $playlistItem, array $scoreParams = []): ScoreLink 22 + { 23 + $room = $playlistItem->room; 24 + $origEndsAt = $room->ends_at; 25 + $room->update(['ends_at' => CarbonImmutable::now()->addDays(1)]); 26 + try { 27 + return parent::roomAddPlay($user, $playlistItem, ['passed' => true, ...$scoreParams]); 28 + } finally { 29 + $room->update(['ends_at' => $origEndsAt]); 30 + } 31 + } 32 + 21 33 private static function preparePlaylistItem(CarbonImmutable $playTime): PlaylistItem 22 34 { 23 35 return PlaylistItem::factory()->create([ 24 36 'room_id' => Room::factory()->create([ 25 37 'category' => 'daily_challenge', 26 - 'starts_at' => $playTime, 38 + 'starts_at' => $playTime->startOfDay(), 39 + 'ends_at' => $playTime->endOfDay(), 27 40 ]), 28 41 ]); 29 42 } 30 43 31 44 private static function startOfWeek(): CarbonImmutable 32 45 { 33 - return DailyChallengeUserStats::startOfWeek(CarbonImmutable::now()); 46 + return DailyChallengeUserStats::startOfWeek(CarbonImmutable::now()->subWeeks(1)); 34 47 } 35 48 36 49 public function testCalculateFromStart(): void ··· 64 77 public function testCalculateNoPlaysBreaksDailyStreak(): void 65 78 { 66 79 $playTime = static::startOfWeek(); 67 - $playlistItem = static::preparePlaylistItem($playTime); 80 + static::preparePlaylistItem($playTime); 68 81 69 82 $user = User::factory()->create(); 70 83 ··· 91 104 public function testCalculateNoPlaysOverAWeekBreaksWeeklyStreak(): void 92 105 { 93 106 $playTime = static::startOfWeek(); 94 - static::preparePlaylistItem($playTime); 107 + $playlistItem = static::preparePlaylistItem($playTime); 95 108 96 109 $user = User::factory()->create(); 97 110 ··· 146 159 } 147 160 } 148 161 162 + public function testFix(): void 163 + { 164 + $user = User::factory()->create(); 165 + 166 + foreach ([14, 13, 12, 11, 10, 9, 7, 6, 5] as $subDay) { 167 + $playTime = static::startOfWeek()->subDays($subDay); 168 + $playlistItem = static::preparePlaylistItem($playTime); 169 + $this->roomAddPlay($user, $playlistItem); 170 + DailyChallengeUserStats::calculate($playTime); 171 + } 172 + $this->travelTo($playTime->addDays(1)); 173 + 174 + $stats = DailyChallengeUserStats::find($user->getKey()); 175 + $expectedAttributes = $stats->getAttributes(); 176 + $stats->fill([...DailyChallengeUserStats::INITIAL_VALUES])->saveOrExplode(); 177 + $stats->fresh()->fix(); 178 + 179 + $stats->refresh(); 180 + $this->assertSame(9, $stats->playcount); 181 + $this->assertSame(3, $stats->daily_streak_current); 182 + $this->assertSame(6, $stats->daily_streak_best); 183 + $this->assertSame(2, $stats->weekly_streak_current); 184 + $this->assertSame(2, $stats->weekly_streak_best); 185 + $this->assertSame(9, $stats->top_10p_placements); 186 + $this->assertSame(9, $stats->top_50p_placements); 187 + 188 + $this->travelBack(); 189 + 190 + $stats->fresh()->fix(); 191 + 192 + $stats->refresh(); 193 + $this->assertSame(9, $stats->playcount); 194 + $this->assertSame(0, $stats->daily_streak_current); 195 + $this->assertSame(6, $stats->daily_streak_best); 196 + } 197 + 198 + public function testFixZeroTotalScore(): void 199 + { 200 + $user = User::factory()->create(); 201 + 202 + foreach ([3 => 100, 2 => 0, 1 => 100] as $subDay => $score) { 203 + $playTime = static::startOfWeek()->subDays($subDay); 204 + $playlistItem = static::preparePlaylistItem($playTime); 205 + $this->roomAddPlay($user, $playlistItem, ['total_score' => $score]); 206 + } 207 + $this->travelTo($playTime->addDays(1)); 208 + 209 + $stats = DailyChallengeUserStats::find($user->getKey()); 210 + $stats->fill([...DailyChallengeUserStats::INITIAL_VALUES])->saveOrExplode(); 211 + $stats->fix(); 212 + 213 + $stats->refresh(); 214 + $this->assertSame(2, $stats->playcount); 215 + $this->assertSame(1, $stats->daily_streak_current); 216 + $this->assertSame(1, $stats->daily_streak_best); 217 + $this->assertSame(1, $stats->weekly_streak_current); 218 + $this->assertSame(1, $stats->weekly_streak_best); 219 + } 220 + 149 221 public function testFlowFromStart(): void 150 222 { 151 223 $playTime = static::startOfWeek(); ··· 154 226 155 227 $this->expectCountChange(fn () => DailyChallengeUserStats::count(), 1); 156 228 157 - $this->roomAddPlay($user, $playlistItem, ['passed' => true]); 229 + $this->roomAddPlay($user, $playlistItem); 158 230 159 231 $stats = DailyChallengeUserStats::find($user->getKey()); 160 232 $this->assertSame(1, $stats->playcount); ··· 188 260 $playlistItem = static::preparePlaylistItem($playTime); 189 261 $user = User::factory()->create(); 190 262 191 - $this->roomAddPlay($user, $playlistItem, ['passed' => true]); 192 - $this->roomAddPlay($user, $playlistItem, ['passed' => true]); 263 + $this->roomAddPlay($user, $playlistItem); 264 + $this->roomAddPlay($user, $playlistItem); 193 265 194 266 DailyChallengeUserStats::calculate($playTime); 195 267 DailyChallengeUserStats::calculate($playTime); ··· 219 291 220 292 $this->expectCountChange(fn () => DailyChallengeUserStats::count(), 0); 221 293 222 - $this->roomAddPlay($user, $playlistItem, ['passed' => true]); 294 + $this->roomAddPlay($user, $playlistItem); 223 295 $stats = DailyChallengeUserStats::find($user->getKey()); 224 296 $this->assertSame(2, $stats->daily_streak_current); 225 297 $this->assertSame(2, $stats->daily_streak_best); ··· 257 329 'last_update' => $playTime->subDays(1), 258 330 ]); 259 331 260 - $this->roomAddPlay($user, $playlistItem, ['passed' => true]); 332 + $this->roomAddPlay($user, $playlistItem); 261 333 262 334 $stats = DailyChallengeUserStats::find($user->getKey()); 263 335 $this->assertSame(2, $stats->weekly_streak_current); ··· 315 387 316 388 DailyChallengeUserStats::calculate($playTime); 317 389 $assertValues(); 390 + } 391 + 392 + protected function setUp(): void 393 + { 394 + parent::setUp(); 395 + // prevent storing percentile cache 396 + config_set('cache.default', 'array'); 318 397 } 319 398 }
+2 -17
tests/karma/globals.js
··· 1 - /** 2 - * Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 3 - * 4 - * This file is part of osu!web. osu!web is distributed with the hope of 5 - * attracting more community contributions to the core ecosystem of osu!. 6 - * 7 - * osu!web is free software: you can redistribute it and/or modify 8 - * it under the terms of the Affero GNU General Public License version 3 9 - * as published by the Free Software Foundation. 10 - * 11 - * osu!web is distributed WITHOUT ANY WARRANTY; without even the implied 12 - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 - * See the GNU Affero General Public License for more details. 14 - * 15 - * You should have received a copy of the GNU Affero General Public License 16 - * along with osu!web. If not, see <http://www.gnu.org/licenses/>. 17 - */ 1 + // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 + // See the LICENCE file in the repository root for full licence text. 18 3 19 4 'use strict'; 20 5
+17 -24
tests/karma/osu-core.spec.ts
··· 1 1 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 2 // See the LICENCE file in the repository root for full licence text. 3 3 4 - import UserJson from 'interfaces/user-json'; 5 4 import User from 'models/user'; 6 5 import OsuCore from 'osu-core'; 6 + import testCurrentUserJson from './test-current-user-json'; 7 7 8 - describe('OsuCore user:update subscriber testing thing', () => { 9 - it('user:update should update the user store from a JSON value', () => { 8 + const expectedUser = new User(1); 9 + expectedUser.updateWithJson(testCurrentUserJson); 10 + 11 + describe('OsuCore user update', () => { 12 + it('.setCurrentUser should update the user store from a JSON value', () => { 10 13 const core = new OsuCore(); 14 + core.setCurrentUser(testCurrentUserJson); 11 15 12 - const json: UserJson = { 13 - avatar_url: '', 14 - country_code: '', 15 - cover: { custom_url: null, id: null, url: null }, 16 - default_group: '', 17 - id: 1, 18 - is_active: true, 19 - is_bot: false, 20 - is_deleted: false, 21 - is_online: true, 22 - is_supporter: true, 23 - last_visit: null, 24 - pm_friends_only: false, 25 - profile_colour: null, 26 - username: 'foo', 27 - }; 16 + expect(core.dataStore.userStore.users.get(1)).toEqual(expectedUser); 17 + expect(core.dataStore.userStore.users.size).toEqual(1); 18 + }); 28 19 29 - const user = new User(json.id); 30 - user.updateWithJson(json); 31 - 32 - $.publish('user:update', json); 20 + it('user:update subscriber should update the user store from a JSON value', () => { 21 + const core = new OsuCore(); 22 + $.publish('user:update', testCurrentUserJson); 33 23 34 - expect(core.dataStore.userStore.users.get(1)).toEqual(user); 24 + expect(core.dataStore.userStore.users.get(1)).toEqual(expectedUser); 35 25 expect(core.dataStore.userStore.users.size).toEqual(1); 26 + 27 + // unset the singleton 28 + $.publish('user:update', { id: undefined }); 36 29 }); 37 30 });
+64
tests/karma/test-current-user-json.ts
··· 1 + // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 2 + // See the LICENCE file in the repository root for full licence text. 3 + 4 + import CurrentUserJson from 'interfaces/current-user-json'; 5 + import { defaultUserPreferencesJson } from 'interfaces/user-preferences-json'; 6 + 7 + const testCurrentUserJson: CurrentUserJson = { 8 + avatar_url: '', 9 + blocks: [], 10 + country: { 11 + code: 'AU', 12 + name: 'Australia', 13 + }, 14 + country_code: 'AU', 15 + cover: { custom_url: null, id: null, url: null }, 16 + default_group: '', 17 + discord: null, 18 + follow_user_mapping: [], 19 + friends: [], 20 + groups: [], 21 + has_supported: false, 22 + id: 1, 23 + interests: null, 24 + is_active: true, 25 + is_admin: false, 26 + is_bng: false, 27 + is_bot: false, 28 + is_deleted: false, 29 + is_full_bn: false, 30 + is_gmt: false, 31 + is_limited_bn: false, 32 + is_moderator: false, 33 + is_nat: false, 34 + is_online: true, 35 + is_restricted: false, 36 + is_silenced: false, 37 + is_supporter: true, 38 + join_date: '2020-01-01T12:34:56+00:00', 39 + kudosu: { 40 + available: 0, 41 + total: 0, 42 + }, 43 + last_visit: null, 44 + location: null, 45 + max_blocks: 1, 46 + max_friends: 1, 47 + occupation: null, 48 + playmode: 'osu', 49 + playstyle: [], 50 + pm_friends_only: false, 51 + post_count: 0, 52 + profile_colour: null, 53 + profile_hue: null, 54 + profile_order: [], 55 + title: null, 56 + title_url: null, 57 + twitter: null, 58 + unread_pm_count: 0, 59 + user_preferences: defaultUserPreferencesJson(), 60 + username: 'foo', 61 + website: null, 62 + }; 63 + 64 + export default testCurrentUserJson;
+5 -23
tests/karma/utils/beatmapset-discussion-helper.spec.ts
··· 5 5 import GameMode from 'interfaces/ruleset'; 6 6 import UserGroupJson from 'interfaces/user-group-json'; 7 7 import UserJson from 'interfaces/user-json'; 8 - import User from 'models/user'; 9 8 import * as moment from 'moment'; 9 + import core from 'osu-core-singleton'; 10 10 import { discussionMode, isUserFullNominator, maxLengthTimeline, nearbyDiscussions, validMessageLength } from 'utils/beatmapset-discussion-helper'; 11 + import testCurrentUserJson from '../test-current-user-json'; 11 12 12 13 interface TestCase<T> { 13 14 description: string; ··· 33 34 user_id: 1, 34 35 }); 35 36 36 - const currentUser = new User(1); 37 - currentUser.updateWithJson({ 38 - avatar_url: '', 39 - country_code: '', 40 - cover: { custom_url: null, id: null, url: null }, 41 - default_group: '', 42 - id: 1, 43 - is_active: true, 44 - is_bot: false, 45 - is_deleted: false, 46 - is_online: true, 47 - is_supporter: true, 48 - last_visit: null, 49 - pm_friends_only: false, 50 - profile_colour: null, 51 - username: 'foo', 52 - }); 53 - 54 37 describe('utils/beatmapset-discussion-helper', () => { 55 38 describe('.discussionMode', () => { 56 39 const cases = [ ··· 89 72 }); 90 73 91 74 describe('.isUserFullNominator', () => { 92 - const userTemplate = currentUser.toJson(); 75 + const userTemplate = structuredClone(testCurrentUserJson); 93 76 const groupsTemplate: UserGroupJson = { 94 77 colour: null, 95 78 has_listing: true, ··· 184 167 }, 185 168 ]; 186 169 187 - // FIXME: need a better way of setting user in osu-core for tests. 188 170 beforeAll(() => { 189 - $.publish('user:update', currentUser); 171 + core.setCurrentUser(testCurrentUserJson); 190 172 }); 191 173 192 174 afterAll(() => { 193 - $.publish('user:update', {}); 175 + core.setCurrentUser({ id: undefined }); 194 176 }); 195 177 196 178 cases.forEach((test) => {
+283 -180
yarn.lock
··· 330 330 "@jridgewell/resolve-uri" "^3.1.0" 331 331 "@jridgewell/sourcemap-codec" "^1.4.14" 332 332 333 + "@jridgewell/trace-mapping@^0.3.20": 334 + version "0.3.25" 335 + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" 336 + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== 337 + dependencies: 338 + "@jridgewell/resolve-uri" "^3.1.0" 339 + "@jridgewell/sourcemap-codec" "^1.4.14" 340 + 333 341 "@mrmlnc/readdir-enhanced@^2.2.1": 334 342 version "2.2.1" 335 343 resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" ··· 633 641 dependencies: 634 642 "@types/ms" "*" 635 643 636 - "@types/eslint-scope@^3.7.3": 637 - version "3.7.4" 638 - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" 639 - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== 640 - dependencies: 641 - "@types/eslint" "*" 642 - "@types/estree" "*" 643 - 644 - "@types/eslint@*": 645 - version "8.44.2" 646 - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.2.tgz#0d21c505f98a89b8dd4d37fa162b09da6089199a" 647 - integrity sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg== 648 - dependencies: 649 - "@types/estree" "*" 650 - "@types/json-schema" "*" 651 - 652 - "@types/estree@*", "@types/estree@^1.0.0": 653 - version "1.0.1" 654 - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" 655 - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== 644 + "@types/estree@^1.0.5": 645 + version "1.0.5" 646 + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" 647 + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== 656 648 657 649 "@types/geojson@*": 658 650 version "7946.0.7" ··· 731 723 dependencies: 732 724 "@types/jquery" "*" 733 725 734 - "@types/js-cookie@^2.2.6": 735 - version "2.2.6" 736 - resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f" 737 - integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw== 738 - 739 - "@types/json-schema@*", "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": 726 + "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": 740 727 version "7.0.12" 741 728 resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" 742 729 integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== ··· 1023 1010 "@typescript-eslint/types" "6.6.0" 1024 1011 eslint-visitor-keys "^3.4.1" 1025 1012 1026 - "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": 1027 - version "1.11.6" 1028 - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" 1029 - integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== 1013 + "@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": 1014 + version "1.12.1" 1015 + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" 1016 + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== 1030 1017 dependencies: 1031 1018 "@webassemblyjs/helper-numbers" "1.11.6" 1032 1019 "@webassemblyjs/helper-wasm-bytecode" "1.11.6" ··· 1041 1028 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" 1042 1029 integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== 1043 1030 1044 - "@webassemblyjs/helper-buffer@1.11.6": 1045 - version "1.11.6" 1046 - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" 1047 - integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== 1031 + "@webassemblyjs/helper-buffer@1.12.1": 1032 + version "1.12.1" 1033 + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" 1034 + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== 1048 1035 1049 1036 "@webassemblyjs/helper-numbers@1.11.6": 1050 1037 version "1.11.6" ··· 1060 1047 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" 1061 1048 integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== 1062 1049 1063 - "@webassemblyjs/helper-wasm-section@1.11.6": 1064 - version "1.11.6" 1065 - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" 1066 - integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== 1050 + "@webassemblyjs/helper-wasm-section@1.12.1": 1051 + version "1.12.1" 1052 + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" 1053 + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== 1067 1054 dependencies: 1068 - "@webassemblyjs/ast" "1.11.6" 1069 - "@webassemblyjs/helper-buffer" "1.11.6" 1055 + "@webassemblyjs/ast" "1.12.1" 1056 + "@webassemblyjs/helper-buffer" "1.12.1" 1070 1057 "@webassemblyjs/helper-wasm-bytecode" "1.11.6" 1071 - "@webassemblyjs/wasm-gen" "1.11.6" 1058 + "@webassemblyjs/wasm-gen" "1.12.1" 1072 1059 1073 1060 "@webassemblyjs/ieee754@1.11.6": 1074 1061 version "1.11.6" ··· 1089 1076 resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" 1090 1077 integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== 1091 1078 1092 - "@webassemblyjs/wasm-edit@^1.11.5": 1093 - version "1.11.6" 1094 - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" 1095 - integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== 1079 + "@webassemblyjs/wasm-edit@^1.12.1": 1080 + version "1.12.1" 1081 + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" 1082 + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== 1096 1083 dependencies: 1097 - "@webassemblyjs/ast" "1.11.6" 1098 - "@webassemblyjs/helper-buffer" "1.11.6" 1084 + "@webassemblyjs/ast" "1.12.1" 1085 + "@webassemblyjs/helper-buffer" "1.12.1" 1099 1086 "@webassemblyjs/helper-wasm-bytecode" "1.11.6" 1100 - "@webassemblyjs/helper-wasm-section" "1.11.6" 1101 - "@webassemblyjs/wasm-gen" "1.11.6" 1102 - "@webassemblyjs/wasm-opt" "1.11.6" 1103 - "@webassemblyjs/wasm-parser" "1.11.6" 1104 - "@webassemblyjs/wast-printer" "1.11.6" 1087 + "@webassemblyjs/helper-wasm-section" "1.12.1" 1088 + "@webassemblyjs/wasm-gen" "1.12.1" 1089 + "@webassemblyjs/wasm-opt" "1.12.1" 1090 + "@webassemblyjs/wasm-parser" "1.12.1" 1091 + "@webassemblyjs/wast-printer" "1.12.1" 1105 1092 1106 - "@webassemblyjs/wasm-gen@1.11.6": 1107 - version "1.11.6" 1108 - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" 1109 - integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== 1093 + "@webassemblyjs/wasm-gen@1.12.1": 1094 + version "1.12.1" 1095 + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" 1096 + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== 1110 1097 dependencies: 1111 - "@webassemblyjs/ast" "1.11.6" 1098 + "@webassemblyjs/ast" "1.12.1" 1112 1099 "@webassemblyjs/helper-wasm-bytecode" "1.11.6" 1113 1100 "@webassemblyjs/ieee754" "1.11.6" 1114 1101 "@webassemblyjs/leb128" "1.11.6" 1115 1102 "@webassemblyjs/utf8" "1.11.6" 1116 1103 1117 - "@webassemblyjs/wasm-opt@1.11.6": 1118 - version "1.11.6" 1119 - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" 1120 - integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== 1104 + "@webassemblyjs/wasm-opt@1.12.1": 1105 + version "1.12.1" 1106 + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" 1107 + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== 1121 1108 dependencies: 1122 - "@webassemblyjs/ast" "1.11.6" 1123 - "@webassemblyjs/helper-buffer" "1.11.6" 1124 - "@webassemblyjs/wasm-gen" "1.11.6" 1125 - "@webassemblyjs/wasm-parser" "1.11.6" 1109 + "@webassemblyjs/ast" "1.12.1" 1110 + "@webassemblyjs/helper-buffer" "1.12.1" 1111 + "@webassemblyjs/wasm-gen" "1.12.1" 1112 + "@webassemblyjs/wasm-parser" "1.12.1" 1126 1113 1127 - "@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": 1128 - version "1.11.6" 1129 - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" 1130 - integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== 1114 + "@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": 1115 + version "1.12.1" 1116 + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" 1117 + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== 1131 1118 dependencies: 1132 - "@webassemblyjs/ast" "1.11.6" 1119 + "@webassemblyjs/ast" "1.12.1" 1133 1120 "@webassemblyjs/helper-api-error" "1.11.6" 1134 1121 "@webassemblyjs/helper-wasm-bytecode" "1.11.6" 1135 1122 "@webassemblyjs/ieee754" "1.11.6" 1136 1123 "@webassemblyjs/leb128" "1.11.6" 1137 1124 "@webassemblyjs/utf8" "1.11.6" 1138 1125 1139 - "@webassemblyjs/wast-printer@1.11.6": 1140 - version "1.11.6" 1141 - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" 1142 - integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== 1126 + "@webassemblyjs/wast-printer@1.12.1": 1127 + version "1.12.1" 1128 + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" 1129 + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== 1143 1130 dependencies: 1144 - "@webassemblyjs/ast" "1.11.6" 1131 + "@webassemblyjs/ast" "1.12.1" 1145 1132 "@xtuc/long" "4.2.2" 1146 1133 1147 1134 "@webpack-cli/configtest@^2.1.1": ··· 1177 1164 mime-types "~2.1.24" 1178 1165 negotiator "0.6.2" 1179 1166 1180 - acorn-import-assertions@^1.9.0: 1181 - version "1.9.0" 1182 - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" 1183 - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== 1167 + acorn-import-attributes@^1.9.5: 1168 + version "1.9.5" 1169 + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" 1170 + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== 1184 1171 1185 1172 acorn-jsx@^5.3.1: 1186 1173 version "5.3.1" ··· 1521 1508 integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== 1522 1509 1523 1510 body-parser@^1.19.0: 1524 - version "1.19.0" 1525 - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 1526 - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== 1511 + version "1.20.3" 1512 + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" 1513 + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== 1527 1514 dependencies: 1528 - bytes "3.1.0" 1529 - content-type "~1.0.4" 1515 + bytes "3.1.2" 1516 + content-type "~1.0.5" 1530 1517 debug "2.6.9" 1531 - depd "~1.1.2" 1532 - http-errors "1.7.2" 1518 + depd "2.0.0" 1519 + destroy "1.2.0" 1520 + http-errors "2.0.0" 1533 1521 iconv-lite "0.4.24" 1534 - on-finished "~2.3.0" 1535 - qs "6.7.0" 1536 - raw-body "2.4.0" 1537 - type-is "~1.6.17" 1522 + on-finished "2.4.1" 1523 + qs "6.13.0" 1524 + raw-body "2.5.2" 1525 + type-is "~1.6.18" 1526 + unpipe "1.0.0" 1538 1527 1539 1528 boolbase@^1.0.0: 1540 1529 version "1.0.0" ··· 1657 1646 dependencies: 1658 1647 pako "~1.0.5" 1659 1648 1660 - browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.21.10, browserslist@^4.21.4: 1649 + browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.21.4: 1661 1650 version "4.21.10" 1662 1651 resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" 1663 1652 integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== ··· 1690 1679 resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" 1691 1680 integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== 1692 1681 1693 - bytes@3.1.0: 1694 - version "3.1.0" 1695 - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" 1696 - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== 1682 + bytes@3.1.2: 1683 + version "3.1.2" 1684 + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" 1685 + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== 1697 1686 1698 1687 cache-base@^1.0.1: 1699 1688 version "1.0.1" ··· 1717 1706 dependencies: 1718 1707 function-bind "^1.1.1" 1719 1708 get-intrinsic "^1.0.2" 1709 + 1710 + call-bind@^1.0.7: 1711 + version "1.0.7" 1712 + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" 1713 + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== 1714 + dependencies: 1715 + es-define-property "^1.0.0" 1716 + es-errors "^1.3.0" 1717 + function-bind "^1.1.2" 1718 + get-intrinsic "^1.2.4" 1719 + set-function-length "^1.2.1" 1720 1720 1721 1721 call-me-maybe@^1.0.1: 1722 1722 version "1.0.1" ··· 2007 2007 resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" 2008 2008 integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== 2009 2009 2010 - content-type@~1.0.4: 2011 - version "1.0.4" 2012 - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 2013 - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 2010 + content-type@~1.0.5: 2011 + version "1.0.5" 2012 + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" 2013 + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== 2014 2014 2015 2015 convert-source-map@^1.7.0: 2016 2016 version "1.7.0" ··· 2602 2602 dependencies: 2603 2603 clone "^1.0.2" 2604 2604 2605 + define-data-property@^1.1.4: 2606 + version "1.1.4" 2607 + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" 2608 + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== 2609 + dependencies: 2610 + es-define-property "^1.0.0" 2611 + es-errors "^1.3.0" 2612 + gopd "^1.0.1" 2613 + 2605 2614 define-properties@^1.1.1, define-properties@^1.1.3: 2606 2615 version "1.1.3" 2607 2616 resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" ··· 2651 2660 dependencies: 2652 2661 robust-predicates "^3.0.0" 2653 2662 2654 - depd@~1.1.2: 2655 - version "1.1.2" 2656 - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 2657 - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 2663 + depd@2.0.0: 2664 + version "2.0.0" 2665 + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 2666 + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 2658 2667 2659 2668 dequal@^2.0.0: 2660 2669 version "2.0.3" ··· 2669 2678 inherits "^2.0.1" 2670 2679 minimalistic-assert "^1.0.0" 2671 2680 2681 + destroy@1.2.0: 2682 + version "1.2.0" 2683 + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" 2684 + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== 2685 + 2672 2686 di@^0.0.1: 2673 2687 version "0.0.1" 2674 2688 resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" ··· 2801 2815 integrity sha512-LF2IQit4B0VrUHFeQkWhZm97KuJSGF2WJqq1InpY+ECpFRkXd8yTIaTtJxsO0OKDmiBYwWqcrNaXOurn2T2wiA== 2802 2816 2803 2817 elliptic@^6.5.3, elliptic@^6.5.4: 2804 - version "6.5.4" 2805 - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" 2806 - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== 2818 + version "6.5.7" 2819 + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" 2820 + integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== 2807 2821 dependencies: 2808 2822 bn.js "^4.11.9" 2809 2823 brorand "^1.1.0" ··· 2861 2875 engine.io-parser "~5.2.1" 2862 2876 ws "~8.17.1" 2863 2877 2864 - enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0, enhanced-resolve@^5.7.0: 2865 - version "5.15.0" 2866 - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" 2867 - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== 2878 + enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.1, enhanced-resolve@^5.7.0: 2879 + version "5.17.1" 2880 + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" 2881 + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== 2868 2882 dependencies: 2869 2883 graceful-fs "^4.2.4" 2870 2884 tapable "^2.2.0" ··· 2930 2944 string.prototype.trimend "^1.0.4" 2931 2945 string.prototype.trimstart "^1.0.4" 2932 2946 unbox-primitive "^1.0.1" 2947 + 2948 + es-define-property@^1.0.0: 2949 + version "1.0.0" 2950 + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" 2951 + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== 2952 + dependencies: 2953 + get-intrinsic "^1.2.4" 2954 + 2955 + es-errors@^1.3.0: 2956 + version "1.3.0" 2957 + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" 2958 + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== 2933 2959 2934 2960 es-module-lexer@^1.2.1: 2935 2961 version "1.3.0" ··· 3466 3492 resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 3467 3493 integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 3468 3494 3495 + function-bind@^1.1.2: 3496 + version "1.1.2" 3497 + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" 3498 + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== 3499 + 3469 3500 functional-red-black-tree@^1.0.1: 3470 3501 version "1.0.1" 3471 3502 resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" ··· 3494 3525 function-bind "^1.1.1" 3495 3526 has "^1.0.3" 3496 3527 has-symbols "^1.0.1" 3528 + 3529 + get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: 3530 + version "1.2.4" 3531 + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" 3532 + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== 3533 + dependencies: 3534 + es-errors "^1.3.0" 3535 + function-bind "^1.1.2" 3536 + has-proto "^1.0.1" 3537 + has-symbols "^1.0.3" 3538 + hasown "^2.0.0" 3497 3539 3498 3540 get-stream@^4.0.0: 3499 3541 version "4.1.0" ··· 3636 3678 pify "^3.0.0" 3637 3679 slash "^1.0.0" 3638 3680 3639 - graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: 3681 + gopd@^1.0.1: 3682 + version "1.0.1" 3683 + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" 3684 + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== 3685 + dependencies: 3686 + get-intrinsic "^1.1.3" 3687 + 3688 + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: 3640 3689 version "4.2.11" 3641 3690 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" 3642 3691 integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== ··· 3666 3715 resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 3667 3716 integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 3668 3717 3718 + has-property-descriptors@^1.0.2: 3719 + version "1.0.2" 3720 + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" 3721 + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== 3722 + dependencies: 3723 + es-define-property "^1.0.0" 3724 + 3725 + has-proto@^1.0.1: 3726 + version "1.0.3" 3727 + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" 3728 + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== 3729 + 3669 3730 has-symbols@^1.0.1, has-symbols@^1.0.2: 3670 3731 version "1.0.2" 3671 3732 resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" 3672 3733 integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== 3734 + 3735 + has-symbols@^1.0.3: 3736 + version "1.0.3" 3737 + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 3738 + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 3673 3739 3674 3740 has-tostringtag@^1.0.0: 3675 3741 version "1.0.0" ··· 3733 3799 inherits "^2.0.3" 3734 3800 minimalistic-assert "^1.0.1" 3735 3801 3802 + hasown@^2.0.0: 3803 + version "2.0.2" 3804 + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" 3805 + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== 3806 + dependencies: 3807 + function-bind "^1.1.2" 3808 + 3736 3809 hast-util-whitespace@^2.0.0: 3737 3810 version "2.0.1" 3738 3811 resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz#0ec64e257e6fc216c7d14c8a1b74d27d650b4557" ··· 3762 3835 resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" 3763 3836 integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== 3764 3837 3765 - http-errors@1.7.2: 3766 - version "1.7.2" 3767 - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" 3768 - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== 3838 + http-errors@2.0.0: 3839 + version "2.0.0" 3840 + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" 3841 + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== 3769 3842 dependencies: 3770 - depd "~1.1.2" 3771 - inherits "2.0.3" 3772 - setprototypeof "1.1.1" 3773 - statuses ">= 1.5.0 < 2" 3774 - toidentifier "1.0.0" 3843 + depd "2.0.0" 3844 + inherits "2.0.4" 3845 + setprototypeof "1.2.0" 3846 + statuses "2.0.1" 3847 + toidentifier "1.0.1" 3775 3848 3776 3849 http-proxy@^1.18.1: 3777 3850 version "1.18.1" ··· 3892 3965 once "^1.3.0" 3893 3966 wrappy "1" 3894 3967 3895 - inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.4: 3968 + inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.4: 3896 3969 version "2.0.4" 3897 3970 resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 3898 3971 integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 3899 3972 3900 - inherits@2.0.3: 3901 - version "2.0.3" 3902 - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 3903 - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== 3904 - 3905 3973 inline-source-map@~0.6.0: 3906 3974 version "0.6.2" 3907 3975 resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5" ··· 4401 4469 version "3.6.0" 4402 4470 resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" 4403 4471 integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== 4404 - 4405 - js-cookie@^2.1.2: 4406 - version "2.2.0" 4407 - resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.0.tgz#1b2c279a6eece380a12168b92485265b35b1effb" 4408 - integrity sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s= 4409 4472 4410 4473 "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: 4411 4474 version "4.0.0" ··· 5521 5584 resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" 5522 5585 integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== 5523 5586 5587 + object-inspect@^1.13.1: 5588 + version "1.13.2" 5589 + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" 5590 + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== 5591 + 5524 5592 object-is@^1.0.1: 5525 5593 version "1.0.1" 5526 5594 resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" ··· 5590 5658 define-properties "^1.1.3" 5591 5659 es-abstract "^1.19.1" 5592 5660 5661 + on-finished@2.4.1: 5662 + version "2.4.1" 5663 + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" 5664 + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== 5665 + dependencies: 5666 + ee-first "1.1.1" 5667 + 5593 5668 on-finished@~2.3.0: 5594 5669 version "2.3.0" 5595 5670 resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" ··· 6243 6318 resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" 6244 6319 integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== 6245 6320 6246 - qs@6.7.0: 6247 - version "6.7.0" 6248 - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" 6249 - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== 6321 + qs@6.13.0: 6322 + version "6.13.0" 6323 + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" 6324 + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== 6325 + dependencies: 6326 + side-channel "^1.0.6" 6250 6327 6251 6328 qs@^6.11.0: 6252 6329 version "6.11.2" ··· 6297 6374 resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 6298 6375 integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 6299 6376 6300 - raw-body@2.4.0: 6301 - version "2.4.0" 6302 - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" 6303 - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== 6377 + raw-body@2.5.2: 6378 + version "2.5.2" 6379 + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" 6380 + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== 6304 6381 dependencies: 6305 - bytes "3.1.0" 6306 - http-errors "1.7.2" 6382 + bytes "3.1.2" 6383 + http-errors "2.0.0" 6307 6384 iconv-lite "0.4.24" 6308 6385 unpipe "1.0.0" 6309 6386 ··· 6703 6780 resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 6704 6781 integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 6705 6782 6783 + set-function-length@^1.2.1: 6784 + version "1.2.2" 6785 + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" 6786 + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== 6787 + dependencies: 6788 + define-data-property "^1.1.4" 6789 + es-errors "^1.3.0" 6790 + function-bind "^1.1.2" 6791 + get-intrinsic "^1.2.4" 6792 + gopd "^1.0.1" 6793 + has-property-descriptors "^1.0.2" 6794 + 6706 6795 set-value@^2.0.0, set-value@^2.0.1: 6707 6796 version "2.0.1" 6708 6797 resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" ··· 6718 6807 resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" 6719 6808 integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== 6720 6809 6721 - setprototypeof@1.1.1: 6722 - version "1.1.1" 6723 - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" 6724 - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== 6810 + setprototypeof@1.2.0: 6811 + version "1.2.0" 6812 + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" 6813 + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== 6725 6814 6726 6815 sha.js@^2.4.0, sha.js@^2.4.8: 6727 6816 version "2.4.11" ··· 6780 6869 call-bind "^1.0.0" 6781 6870 get-intrinsic "^1.0.2" 6782 6871 object-inspect "^1.9.0" 6872 + 6873 + side-channel@^1.0.6: 6874 + version "1.0.6" 6875 + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" 6876 + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== 6877 + dependencies: 6878 + call-bind "^1.0.7" 6879 + es-errors "^1.3.0" 6880 + get-intrinsic "^1.2.4" 6881 + object-inspect "^1.13.1" 6783 6882 6784 6883 signal-exit@^3.0.0: 6785 6884 version "3.0.7" ··· 7004 7103 define-property "^0.2.5" 7005 7104 object-copy "^0.1.0" 7006 7105 7007 - "statuses@>= 1.5.0 < 2", statuses@~1.5.0: 7106 + statuses@2.0.1: 7107 + version "2.0.1" 7108 + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" 7109 + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 7110 + 7111 + statuses@~1.5.0: 7008 7112 version "1.5.0" 7009 7113 resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 7010 7114 integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= ··· 7240 7344 resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" 7241 7345 integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== 7242 7346 7243 - terser-webpack-plugin@^5.3.7, terser-webpack-plugin@^5.3.9: 7244 - version "5.3.9" 7245 - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" 7246 - integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== 7347 + terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.9: 7348 + version "5.3.10" 7349 + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" 7350 + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== 7247 7351 dependencies: 7248 - "@jridgewell/trace-mapping" "^0.3.17" 7352 + "@jridgewell/trace-mapping" "^0.3.20" 7249 7353 jest-worker "^27.4.5" 7250 7354 schema-utils "^3.1.1" 7251 7355 serialize-javascript "^6.0.1" 7252 - terser "^5.16.8" 7356 + terser "^5.26.0" 7253 7357 7254 7358 terser@^4.8.1: 7255 7359 version "4.8.1" ··· 7260 7364 source-map "~0.6.1" 7261 7365 source-map-support "~0.5.12" 7262 7366 7263 - terser@^5.16.8: 7264 - version "5.19.2" 7265 - resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.2.tgz#bdb8017a9a4a8de4663a7983f45c506534f9234e" 7266 - integrity sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA== 7367 + terser@^5.26.0: 7368 + version "5.31.6" 7369 + resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" 7370 + integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== 7267 7371 dependencies: 7268 7372 "@jridgewell/source-map" "^0.3.3" 7269 7373 acorn "^8.8.2" ··· 7343 7447 regex-not "^1.0.2" 7344 7448 safe-regex "^1.1.0" 7345 7449 7346 - toidentifier@1.0.0: 7347 - version "1.0.0" 7348 - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" 7349 - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== 7450 + toidentifier@1.0.1: 7451 + version "1.0.1" 7452 + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" 7453 + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== 7350 7454 7351 7455 trim-lines@^3.0.0: 7352 7456 version "3.0.1" ··· 7436 7540 resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" 7437 7541 integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== 7438 7542 7439 - type-is@~1.6.17: 7543 + type-is@~1.6.18: 7440 7544 version "1.6.18" 7441 7545 resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 7442 7546 integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== ··· 7672 7776 resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" 7673 7777 integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= 7674 7778 7675 - watchpack@^2.4.0: 7676 - version "2.4.0" 7677 - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" 7678 - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== 7779 + watchpack@^2.4.0, watchpack@^2.4.1: 7780 + version "2.4.2" 7781 + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" 7782 + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== 7679 7783 dependencies: 7680 7784 glob-to-regexp "^0.4.1" 7681 7785 graceful-fs "^4.1.2" ··· 7750 7854 resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" 7751 7855 integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== 7752 7856 7753 - webpack@^5.88.2: 7754 - version "5.88.2" 7755 - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" 7756 - integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== 7857 + webpack@^5.94.0: 7858 + version "5.94.0" 7859 + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" 7860 + integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== 7757 7861 dependencies: 7758 - "@types/eslint-scope" "^3.7.3" 7759 - "@types/estree" "^1.0.0" 7760 - "@webassemblyjs/ast" "^1.11.5" 7761 - "@webassemblyjs/wasm-edit" "^1.11.5" 7762 - "@webassemblyjs/wasm-parser" "^1.11.5" 7862 + "@types/estree" "^1.0.5" 7863 + "@webassemblyjs/ast" "^1.12.1" 7864 + "@webassemblyjs/wasm-edit" "^1.12.1" 7865 + "@webassemblyjs/wasm-parser" "^1.12.1" 7763 7866 acorn "^8.7.1" 7764 - acorn-import-assertions "^1.9.0" 7765 - browserslist "^4.14.5" 7867 + acorn-import-attributes "^1.9.5" 7868 + browserslist "^4.21.10" 7766 7869 chrome-trace-event "^1.0.2" 7767 - enhanced-resolve "^5.15.0" 7870 + enhanced-resolve "^5.17.1" 7768 7871 es-module-lexer "^1.2.1" 7769 7872 eslint-scope "5.1.1" 7770 7873 events "^3.2.0" 7771 7874 glob-to-regexp "^0.4.1" 7772 - graceful-fs "^4.2.9" 7875 + graceful-fs "^4.2.11" 7773 7876 json-parse-even-better-errors "^2.3.1" 7774 7877 loader-runner "^4.2.0" 7775 7878 mime-types "^2.1.27" 7776 7879 neo-async "^2.6.2" 7777 7880 schema-utils "^3.2.0" 7778 7881 tapable "^2.1.1" 7779 - terser-webpack-plugin "^5.3.7" 7780 - watchpack "^2.4.0" 7882 + terser-webpack-plugin "^5.3.10" 7883 + watchpack "^2.4.1" 7781 7884 webpack-sources "^3.2.3" 7782 7885 7783 7886 which-boxed-primitive@^1.0.2: