diff --git a/.github/workflows/axolotl-ci.yml b/.github/workflows/axolotl-ci.yml index 5b3c736..4d53b2e 100644 --- a/.github/workflows/axolotl-ci.yml +++ b/.github/workflows/axolotl-ci.yml @@ -58,24 +58,34 @@ jobs: node-version-file: .nvmrc cache: pnpm - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable + - name: Restore Rust dependencies + uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3 + with: + shared-key: desktop-${{ runner.os }}-${{ runner.arch }} - name: Set up Rust compiler cache - if: runner.os == 'Windows' - uses: mozilla-actions/sccache-action@2df7dbab909c49ab7d3382d05da469f3f975c2d6 # v0.0.7 + id: sccache-setup + continue-on-error: true + uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11 + with: + version: v0.18.0 - name: Check Rust compiler cache availability id: sccache - if: runner.os == 'Windows' + if: steps.sccache-setup.outcome == 'success' continue-on-error: true shell: bash env: SCCACHE_GHA_ENABLED: 'true' - run: ${SCCACHE_PATH} rustc -vV + run: '"${SCCACHE_PATH}" "$(rustup which rustc)" -vV' - name: Enable Rust compiler cache - if: runner.os == 'Windows' && steps.sccache.outcome == 'success' + if: steps.sccache.outcome == 'success' shell: bash run: | echo 'RUSTC_WRAPPER=sccache' >> "$GITHUB_ENV" echo 'SCCACHE_GHA_ENABLED=true' >> "$GITHUB_ENV" - echo 'SCCACHE_CACHE_SIZE=4G' >> "$GITHUB_ENV" + - name: Report unavailable Rust compiler cache + if: steps.sccache-setup.outcome == 'failure' || steps.sccache.outcome == 'failure' + shell: bash + run: echo '::warning::Rust compiler cache is unavailable; this build will continue without compiler caching.' - if: runner.os == 'Linux' run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf - run: pnpm install --frozen-lockfile @@ -112,9 +122,10 @@ jobs: } Write-Output "Built native NSIS installer: $($installers[0].Name)" - name: Show Rust compiler cache statistics - if: runner.os == 'Windows' && steps.sccache.outcome == 'success' && always() + if: always() && steps.sccache.outcome == 'success' + continue-on-error: true shell: bash - run: ${SCCACHE_PATH} --show-stats + run: '"${SCCACHE_PATH}" --show-stats' website: needs: guardrails diff --git a/.github/workflows/build-on-tag.yml b/.github/workflows/build-on-tag.yml index a10e884..72ffa3a 100644 --- a/.github/workflows/build-on-tag.yml +++ b/.github/workflows/build-on-tag.yml @@ -131,26 +131,38 @@ jobs: - name: Set up Rust uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable + - name: Restore Rust dependencies + uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3 + with: + shared-key: desktop-${{ runner.os }}-${{ runner.arch }} + - name: Set up Rust compiler cache - if: runner.os == 'Windows' - uses: mozilla-actions/sccache-action@2df7dbab909c49ab7d3382d05da469f3f975c2d6 # v0.0.7 + id: sccache-setup + continue-on-error: true + uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11 + with: + version: v0.18.0 - name: Check Rust compiler cache availability id: sccache - if: runner.os == 'Windows' + if: steps.sccache-setup.outcome == 'success' continue-on-error: true shell: bash env: SCCACHE_GHA_ENABLED: 'true' - run: ${SCCACHE_PATH} rustc -vV + run: '"${SCCACHE_PATH}" "$(rustup which rustc)" -vV' - name: Enable Rust compiler cache - if: runner.os == 'Windows' && steps.sccache.outcome == 'success' + if: steps.sccache.outcome == 'success' shell: bash run: | echo 'RUSTC_WRAPPER=sccache' >> "$GITHUB_ENV" echo 'SCCACHE_GHA_ENABLED=true' >> "$GITHUB_ENV" - echo 'SCCACHE_CACHE_SIZE=4G' >> "$GITHUB_ENV" + + - name: Report unavailable Rust compiler cache + if: steps.sccache-setup.outcome == 'failure' || steps.sccache.outcome == 'failure' + shell: bash + run: echo '::warning::Rust compiler cache is unavailable; this build will continue without compiler caching.' - name: Add macOS universal targets if: runner.os == 'macOS' @@ -193,11 +205,6 @@ jobs: updaterJsonPreferNsis: true retryAttempts: 2 - - name: Show Rust compiler cache statistics - if: runner.os == 'Windows' && steps.sccache.outcome == 'success' && always() - shell: bash - run: ${SCCACHE_PATH} --show-stats - - name: Publish Windows distribution variants if: runner.os == 'Windows' env: @@ -283,6 +290,12 @@ jobs: throw "Binary not found at $appExe" } + - name: Show Rust compiler cache statistics + if: always() && steps.sccache.outcome == 'success' + continue-on-error: true + shell: bash + run: '"${SCCACHE_PATH}" --show-stats' + verify-and-publish: name: Verify and publish needs: build diff --git a/Cargo.lock b/Cargo.lock index eac8fb8..e8b4093 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6841,7 +6841,7 @@ dependencies = [ [[package]] name = "theseus" -version = "1.0.2-beta11" +version = "1.0.2-beta13" dependencies = [ "ariadne", "async-minecraft-ping", @@ -6945,7 +6945,7 @@ dependencies = [ [[package]] name = "theseus_gui" -version = "1.0.2-beta11" +version = "1.0.2-beta13" dependencies = [ "ashpd", "async_zip", diff --git a/apps/app-frontend/package.json b/apps/app-frontend/package.json index 08cca45..2c4b491 100644 --- a/apps/app-frontend/package.json +++ b/apps/app-frontend/package.json @@ -1,77 +1,77 @@ { - "name": "@modrinth/app-frontend", - "private": true, - "version": "1.0.2-beta11", - "type": "module", - "scripts": { - "dev": "vite", - "build": "vue-tsc --noEmit && vite build", - "tsc:check": "vue-tsc --noEmit", - "lint": "eslint . && prettier --check .", - "fix": "eslint . --fix && prettier --write .", - "intl:extract": "formatjs extract \"src/**/*.{vue,ts,tsx,js,jsx,mts,cts,mjs,cjs}\" --ignore \"**/*.d.ts\" --ignore node_modules --out-file src/locales/en-US/index.json --format crowdin --preserve-whitespace", - "intl:prune-local": "pnpm -w scripts i18n-icu-contract prune-local --scope apps/app-frontend", - "test": "vue-tsc --noEmit && node --test \"src/**/*.test.ts\"" - }, - "dependencies": { - "@dnd-kit/core": "6.3.1", - "@dnd-kit/utilities": "3.2.2", - "@dnd-kit/vue": "^0.5.0", - "@lobehub/icons-static-svg": "1.94.0", - "@modrinth/api-client": "workspace:^", - "@modrinth/assets": "workspace:*", - "@modrinth/server": "workspace:*", - "@modrinth/ui": "workspace:*", - "@modrinth/utils": "workspace:*", - "@sfirew/minecraft-motd-parser": "^1.1.6", - "@tanstack/vue-query": "5.90.7", - "@tauri-apps/api": "^2.5.0", - "@tauri-apps/plugin-dialog": "^2.2.1", - "@tauri-apps/plugin-fs": "^2.4.5", - "@tauri-apps/plugin-http": "~2.5.7", - "@tauri-apps/plugin-opener": "^2.2.6", - "@tauri-apps/plugin-os": "^2.2.1", - "@tauri-apps/plugin-updater": "^2.7.1", - "@tauri-apps/plugin-window-state": "^2.2.2", - "@types/three": "^0.172.0", - "@vueuse/core": "^11.1.0", - "dayjs": "^1.11.10", - "deepslate": "0.26.0", - "fflate": "0.8.2", - "floating-vue": "^5.2.2", - "fuse.js": "^6.6.2", - "intl-messageformat": "^10.7.7", - "monaco-editor": "^0.56.0", - "ofetch": "^1.3.4", - "overlayscrollbars": "^2.15.1", - "pinia": "^3.0.0", - "three": "^0.172.0", - "vite-svg-loader": "^5.1.0", - "vue": "^3.5.13", - "vue-i18n": "^10.0.0", - "vue-router": "^4.6.0", - "vuedraggable": "^4.1.0", - "xxhash-wasm": "1.1.0" - }, - "devDependencies": { - "@eslint/compat": "^1.1.1", - "@formatjs/cli": "^6.2.12", - "@modrinth/tooling-config": "workspace:*", - "@nuxt/eslint-config": "^0.5.6", - "@vitejs/plugin-vue": "^6.0.3", - "autoprefixer": "^10.4.19", - "eslint": "^9.9.1", - "eslint-plugin-turbo": "^2.5.4", - "postcss": "^8.4.39", - "prettier": "^3.2.5", - "sass": "^1.74.1", - "tailwindcss": "^3.4.4", - "typescript": "^5.5.4", - "vite": "^8.0.0", - "vite-plugin-vue-devtools": "^8.2.1", - "vue-component-type-helpers": "^3.1.8", - "vue-tsc": "^2.1.6" - }, - "packageManager": "pnpm@9.4.0", - "web-types": "../../web-types.json" + "name": "@modrinth/app-frontend", + "private": true, + "version": "1.0.2-beta13", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc --noEmit && vite build", + "tsc:check": "vue-tsc --noEmit", + "lint": "eslint . && prettier --check .", + "fix": "eslint . --fix && prettier --write .", + "intl:extract": "formatjs extract \"src/**/*.{vue,ts,tsx,js,jsx,mts,cts,mjs,cjs}\" --ignore \"**/*.d.ts\" --ignore node_modules --out-file src/locales/en-US/index.json --format crowdin --preserve-whitespace", + "intl:prune-local": "pnpm -w scripts i18n-icu-contract prune-local --scope apps/app-frontend", + "test": "vue-tsc --noEmit && node --test \"src/**/*.test.ts\"" + }, + "dependencies": { + "@dnd-kit/core": "6.3.1", + "@dnd-kit/utilities": "3.2.2", + "@dnd-kit/vue": "^0.5.0", + "@lobehub/icons-static-svg": "1.94.0", + "@modrinth/api-client": "workspace:^", + "@modrinth/assets": "workspace:*", + "@modrinth/server": "workspace:*", + "@modrinth/ui": "workspace:*", + "@modrinth/utils": "workspace:*", + "@sfirew/minecraft-motd-parser": "^1.1.6", + "@tanstack/vue-query": "5.90.7", + "@tauri-apps/api": "^2.5.0", + "@tauri-apps/plugin-dialog": "^2.2.1", + "@tauri-apps/plugin-fs": "^2.4.5", + "@tauri-apps/plugin-http": "~2.5.7", + "@tauri-apps/plugin-opener": "^2.2.6", + "@tauri-apps/plugin-os": "^2.2.1", + "@tauri-apps/plugin-updater": "^2.7.1", + "@tauri-apps/plugin-window-state": "^2.2.2", + "@types/three": "^0.172.0", + "@vueuse/core": "^11.1.0", + "dayjs": "^1.11.10", + "deepslate": "0.26.0", + "fflate": "0.8.2", + "floating-vue": "^5.2.2", + "fuse.js": "^6.6.2", + "intl-messageformat": "^10.7.7", + "monaco-editor": "^0.56.0", + "ofetch": "^1.3.4", + "overlayscrollbars": "^2.15.1", + "pinia": "^3.0.0", + "three": "^0.172.0", + "vite-svg-loader": "^5.1.0", + "vue": "^3.5.13", + "vue-i18n": "^10.0.0", + "vue-router": "^4.6.0", + "vuedraggable": "^4.1.0", + "xxhash-wasm": "1.1.0" + }, + "devDependencies": { + "@eslint/compat": "^1.1.1", + "@formatjs/cli": "^6.2.12", + "@modrinth/tooling-config": "workspace:*", + "@nuxt/eslint-config": "^0.5.6", + "@vitejs/plugin-vue": "^6.0.3", + "autoprefixer": "^10.4.19", + "eslint": "^9.9.1", + "eslint-plugin-turbo": "^2.5.4", + "postcss": "^8.4.39", + "prettier": "^3.2.5", + "sass": "^1.74.1", + "tailwindcss": "^3.4.4", + "typescript": "^5.5.4", + "vite": "^8.0.0", + "vite-plugin-vue-devtools": "^8.2.1", + "vue-component-type-helpers": "^3.1.8", + "vue-tsc": "^2.1.6" + }, + "packageManager": "pnpm@9.4.0", + "web-types": "../../web-types.json" } diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue index 61494f1..5194012 100644 --- a/apps/app-frontend/src/App.vue +++ b/apps/app-frontend/src/App.vue @@ -134,6 +134,7 @@ import { import { getSidebarExpanded, setSidebarExpanded } from '@/helpers/sidebar-state.ts' import { get_opening_command, initialize_state } from '@/helpers/state' import { installUiScale, setUiScale } from '@/helpers/ui-scale' +import { shouldDelayAppUpdate } from '@/helpers/app-update-policy' import { areUpdatesEnabled, backupAppDbForUpdate, @@ -1998,34 +1999,55 @@ function showDelayedUpdatePopup() { } let lastUpdateChannel = 'release' +let updateCheckRevision = 0 + +async function clearAvailableUpdate(isCurrent) { + const unlisten = unlistenUpdateDownload + unlistenUpdateDownload = null + await unlisten?.() + if (!isCurrent()) return + availableUpdate.value = null + updateSize.value = null + appUpdateDownload.progress.value = 0 + finishedDownloading.value = false + downloading.value = false + clearDelayedUpdatePopup() +} async function performUpdateCheck() { + const revision = ++updateCheckRevision + const isLatestCheck = () => revision === updateCheckRevision + const currentResult = () => (availableUpdate.value ? 'available' : 'up-to-date') const channel = await getUpdateChannel() const preferences = await getUpdatePreferences() + if (!isLatestCheck()) return currentResult() updatesPaused.value = preferences.updatesPaused if (updatesPaused.value) return 'paused' if (channel !== lastUpdateChannel) { - availableUpdate.value = null - updateSize.value = null - appUpdateDownload.progress.value = 0 - finishedDownloading.value = false - downloading.value = false + await clearAvailableUpdate(isLatestCheck) + if (!isLatestCheck()) return currentResult() lastUpdateChannel = channel } - const update = await checkAppUpdate(channel) + let update + try { + update = await checkAppUpdate(channel) + } catch (error) { + if (!isLatestCheck()) return currentResult() + throw error + } + if (!isLatestCheck()) return currentResult() + if (!update || update.version !== availableUpdate.value?.version) { + await clearAvailableUpdate(isLatestCheck) + } + if (!isLatestCheck()) return currentResult() if (!update) { console.log('No update available') return 'up-to-date' } const publishedAt = Date.parse(update.publishedAt ?? '') - if ( - channel === 'release' && - !preferences.immediateUpdateFetch && - !update.forceUpdate && - (!Number.isFinite(publishedAt) || Date.now() < publishedAt + 24 * 60 * 60 * 1000) - ) { + if (shouldDelayAppUpdate(update, channel, preferences.immediateUpdateFetch)) { console.warn( Number.isFinite(publishedAt) ? `Update ${update.version} is waiting for the release delay.` @@ -2042,6 +2064,9 @@ async function performUpdateCheck() { return 'available' } + const meteredNetwork = await isNetworkMetered() + if (!isLatestCheck()) return currentResult() + appUpdateDownload.progress.value = 0 finishedDownloading.value = false downloading.value = false @@ -2050,7 +2075,7 @@ async function performUpdateCheck() { console.log(`Update ${update.version} is available.`) - metered.value = await isNetworkMetered() + metered.value = meteredNetwork if (!metered.value) { console.log('Starting download of update') @@ -2062,7 +2087,9 @@ async function performUpdateCheck() { } getUpdateSize(update.rid) - .then((size) => (updateSize.value = size)) + .then((size) => { + if (availableUpdate.value?.rid === update.rid) updateSize.value = size + }) .catch((error) => console.warn('Failed to fetch update size', error)) return 'available' } @@ -2092,6 +2119,7 @@ async function downloadUpdate(versionToDownload) { handleError(`Failed to download update: no version available`) return } + if (availableUpdate.value?.rid !== versionToDownload.rid) return if (downloading.value || appUpdateDownload.progress.value !== 0) { console.error(`Update ${versionToDownload.version} already downloading`) @@ -2100,35 +2128,27 @@ async function downloadUpdate(versionToDownload) { console.log(`Downloading update ${versionToDownload.version} from Update Server`) downloading.value = true + const isCurrent = () => availableUpdate.value?.rid === versionToDownload.rid + let unlisten try { - enqueueUpdateForInstallation(versionToDownload.rid) - .then(() => { - downloading.value = false - finishedDownloading.value = true - unlistenUpdateDownload?.().then(() => { - unlistenUpdateDownload = null - }) - console.log('Finished downloading!') - markAppUpdateActionable(versionToDownload.version, 'downloaded') - scheduleDelayedUpdatePopup() - }) - .catch((error) => { - downloading.value = false - appUpdateDownload.progress.value = 0 - unlistenUpdateDownload?.().then(() => { - unlistenUpdateDownload = null - }) - handleError(error) - }) - unlistenUpdateDownload = await subscribeToDownloadProgress( - appUpdateDownload, - versionToDownload.version, - ) + unlisten = await subscribeToDownloadProgress(appUpdateDownload, versionToDownload.version) + if (!isCurrent()) return + unlistenUpdateDownload = unlisten + await enqueueUpdateForInstallation(versionToDownload.rid) + if (!isCurrent()) return + downloading.value = false + finishedDownloading.value = true + markAppUpdateActionable(versionToDownload.version, 'downloaded') + scheduleDelayedUpdatePopup() } catch (error) { + if (!isCurrent()) return downloading.value = false appUpdateDownload.progress.value = 0 handleError(error) + } finally { + await unlisten?.() + if (unlistenUpdateDownload === unlisten) unlistenUpdateDownload = null } } diff --git a/apps/app-frontend/src/announcements/catalog.ts b/apps/app-frontend/src/announcements/catalog.ts index 9df0a57..1d5f802 100644 --- a/apps/app-frontend/src/announcements/catalog.ts +++ b/apps/app-frontend/src/announcements/catalog.ts @@ -32,6 +32,61 @@ export const ANNOUNCEMENT_CHANGE_TYPES: readonly AnnouncementChangeType[] = [ ] export const launcherAnnouncements: readonly LauncherAnnouncement[] = [ + { + id: 'launcher-1.0.2-beta13', + version: '1.0.2-beta13', + publishedAt: '2026-10-21', + title: { + 'en-US': 'Starlight Launcher 1.0.2-beta13', + 'zh-CN': 'Starlight Launcher 1.0.2-beta13', + }, + changes: { + changed: [ + { + 'en-US': + 'The redesigned home page brings together the 3D skin preview, skin site and Microsoft player selection, announcements, donation acknowledgements and a compact navigation toolbar.', + 'zh-CN': + '新版首页集中展示 3D 皮肤预览、皮肤站与微软玩家切换、公告、捐赠鸣谢及底部功能工具栏。', + }, + ], + fixed: [ + { + 'en-US': + 'The home page keeps the current 3D skin preview stable when accounts or avatars refresh in the background, avoiding unnecessary texture reloads and model flicker.', + 'zh-CN': + '后台刷新账号或头像时保持当前 3D 皮肤预览稳定,避免无关刷新导致纹理重新加载和模型闪烁。', + }, + ], + }, + }, + { + id: 'launcher-1.0.2-beta12', + version: '1.0.2-beta12', + publishedAt: '2026-10-21', + title: { + 'en-US': 'Starlight Launcher 1.0.2-beta12', + 'zh-CN': 'Starlight Launcher 1.0.2-beta12', + }, + changes: { + fixed: [ + { + 'en-US': + 'Fixed automatic updates ignoring server rollbacks to an earlier launcher version.', + 'zh-CN': '修复启动器忽略服务端旧版本回滚的问题,回滚后可自动下载并在退出或重启时安装。', + }, + { + 'en-US': + 'Fixed outdated update checks and downloads overriding a newly selected update version.', + 'zh-CN': '修复旧的更新检查或下载结果覆盖新目标版本的问题。', + }, + ], + }, + notes: { + 'en-US': + 'Install this version once to enable automatic rollback support for subsequent updates.', + 'zh-CN': '需要先安装一次此版本,之后才能自动跟随服务端回滚。', + }, + }, { id: 'launcher-1.0.2-beta11', version: '1.0.2-beta11', diff --git a/apps/app-frontend/src/components/ui/AccountsCard.test.ts b/apps/app-frontend/src/components/ui/AccountsCard.test.ts index b3e8835..b895699 100644 --- a/apps/app-frontend/src/components/ui/AccountsCard.test.ts +++ b/apps/app-frontend/src/components/ui/AccountsCard.test.ts @@ -5,12 +5,6 @@ import test from 'node:test' import { createRenderer, h, nextTick, Suspense } from 'vue' -import { - receiveSkinSiteMessage, - resetSkinSiteSession, - setSkinSiteFrame, - SKIN_SITE_ORIGIN, -} from '../../composables/skin-site-session.ts' import { useNetworkStatus } from '../../composables/useNetworkStatus.ts' // Exercise the real component's setup and reactive account list. Only platform, @@ -19,6 +13,7 @@ const require = createRequire(import.meta.url) const { parse, compileScript } = require('vue/compiler-sfc') const componentUrl = new URL('./AccountsCard.vue', import.meta.url).href const stubs: Record = { + '@tauri-apps/plugin-http': `export const fetch=(...args)=>globalThis.accountTestFetch(...args)`, '@modrinth/assets': `export const CopyIcon={}, LogInIcon={}, PlusIcon={}, RadioButtonCheckedIcon={}, RadioButtonIcon={}, RefreshCwIcon={}, SpinnerIcon={}, TrashIcon={}`, '@modrinth/ui': `export const Accordion={}, Avatar={}, ButtonStyled={}; export const defineMessages=x=>x; export const injectNotificationManager=()=>({handleError:()=>{}}); export const useVIntl=()=>({formatMessage:x=>x.defaultMessage})`, '@tanstack/vue-query': `export const useQueryClient=()=>({refetchQueries:async()=>{}})`, @@ -26,6 +21,7 @@ const stubs: Record = { 'vue-router': `export const useRoute=()=>({fullPath:'/'}); export const useRouter=()=>({push:async()=>{}})`, '@/assets/netherstar.png': `export default 'logo'`, '@/components/ui/MinecraftLoginModal.vue': `export default {}`, + '@/components/ui/skin-site/SkinSiteLoginModal.vue': `export default {}`, '@/helpers/events': `export const process_listener=async()=>()=>{}`, '@/helpers/rendering/batch-skin-renderer.ts': `export const getPlayerHeadUrl=async()=> 'head'`, '@/helpers/skins': `export const get_available_skins=async()=>[]`, @@ -59,6 +55,13 @@ const hooks = registerHooks({ }, }) const { default: AccountsCard } = await import(componentUrl) +const { + resetSkinSiteSession, + signInSkinSite, + signOutSkinSite, + selectedSkinSitePlayerId, + SKIN_SITE_ORIGIN, +} = await import('../../composables/skin-site-session.ts') hooks.deregister() type TestNode = Record @@ -72,6 +75,7 @@ type CardState = { defaultUser: string | undefined selectedAccount: TestAccount | undefined setAccount: (account: TestAccount) => Promise + setSkinSitePlayer: (id: string) => Promise getAccountAvatarUrl: (account: TestAccount) => string | undefined } const renderer = createRenderer({ @@ -93,37 +97,39 @@ const flush = async () => { const firstId = '12345678-1234-1234-1234-123456789abc' const secondId = '22345678-1234-1234-1234-123456789abc' -async function fixture(hasOfficial = true) { +async function fixture(hasOfficial = true, officialId = 'official', linkedMojang = false) { const previousWindow = Object.getOwnPropertyDescriptor(globalThis, 'window') const previousNavigator = Object.getOwnPropertyDescriptor(globalThis, 'navigator') const stored: TestAccount[] = hasOfficial - ? [{ account_type: 'microsoft', profile: { id: 'official', name: 'Official' } }] + ? [{ account_type: 'microsoft', profile: { id: officialId, name: 'Official' } }] : [] - let selected: string | undefined = hasOfficial ? 'official' : undefined + let selected: string | undefined = hasOfficial ? officialId : undefined let rejectLogin = false let loginCalls = 0 - const frame = { - postMessage(data: { type: string; requestId: string }) { - if (data.type === 'starlight-pack-token-request') - message({ - type: 'starlight-pack-token-result', - requestId: data.requestId, - token: 'fixture.jwt', - }) - if (data.type === 'starlight-skin-players-request') - message({ - type: 'starlight-skin-players-result', - requestId: data.requestId, - ok: true, - players: [ - { uuid: firstId, name: 'First', isMojang: false, skinState: 'empty' }, - { uuid: secondId, name: 'Second', isMojang: false, skinState: 'empty' }, - ], - }) + const storage = new Map() + Object.defineProperty(globalThis, 'localStorage', { + configurable: true, + value: { + getItem: (key: string) => storage.get(key) ?? null, + setItem: (key: string, value: string) => storage.set(key, value), + removeItem: (key: string) => storage.delete(key), }, - } as unknown as Window - function message(data: unknown) { - receiveSkinSiteMessage({ origin: SKIN_SITE_ORIGIN, source: frame, data } as MessageEvent, frame) + }) + ;( + globalThis as unknown as { accountTestFetch: (url: string) => Promise } + ).accountTestFetch = async (url) => { + const path = new URL(url).pathname + const payload = path.endsWith('/login') + ? { username: 'Owner', jwt: 'fixture.jwt' } + : path.endsWith('/user') + ? { uuid: 'owner', username: 'Owner', permissions: [] } + : path.endsWith('/player') + ? [ + { uuid: firstId, name: 'First', isMojang: linkedMojang || firstId === officialId }, + { uuid: secondId, name: 'Second', isMojang: false }, + ] + : {} + return Response.json({ payload }) } Object.defineProperty(globalThis, 'navigator', { configurable: true, value: { onLine: true } }) useNetworkStatus().refreshBrowserOffline() @@ -163,22 +169,18 @@ async function fixture(hasOfficial = true) { }, }) resetSkinSiteSession() - setSkinSiteFrame(frame) const node = h({ ...AccountsCard, render: () => null }) const app = renderer.createApp({ render: () => h(Suspense, null, { default: () => node }) }) app.mount({}) await flush() return { state: (node.component! as unknown as { setupState: CardState }).setupState, - login() { - message({ - type: 'starlight-skin-session', - status: 'signed-in', - user: { uuid: 'owner', username: 'Owner' }, - }) + async login() { + await signInSkinSite({ username: 'Owner', password: 'password', clientId: 'test' }) + await flush() }, signOut() { - message({ type: 'starlight-skin-session', status: 'signed-out' }) + signOutSkinSite() }, failLogin(value: boolean) { rejectLogin = value @@ -192,7 +194,7 @@ async function fixture(hasOfficial = true) { close() { app.unmount() resetSkinSiteSession() - setSkinSiteFrame(null) + Reflect.deleteProperty(globalThis, 'localStorage') if (previousWindow) Object.defineProperty(globalThis, 'window', previousWindow) else Reflect.deleteProperty(globalThis, 'window') if (previousNavigator) Object.defineProperty(globalThis, 'navigator', previousNavigator) @@ -205,7 +207,7 @@ test('sidebar offers every skin-site player before any game authentication or la const view = await fixture(false) try { view.failLogin(true) - view.login() + await view.login() await flush() assert.deepEqual( view.state.accounts.map((account) => account.profile.id), @@ -221,7 +223,7 @@ test('sidebar offers every skin-site player before any game authentication or la test('choosing an unused skin-site player authenticates and persists the default without a launch', async () => { const view = await fixture() try { - view.login() + await view.login() await flush() await view.state.setAccount( view.state.accounts.find((account) => account.profile.id === secondId)!, @@ -238,7 +240,7 @@ test('choosing an unused skin-site player authenticates and persists the default test('failed player authentication preserves the default and allows retry', async () => { const view = await fixture() try { - view.login() + await view.login() await flush() view.failLogin(true) await view.state.setAccount( @@ -259,7 +261,7 @@ test('failed player authentication preserves the default and allows retry', asyn test('signing out removes unregistered choices while keeping saved accounts', async () => { const view = await fixture() try { - view.login() + await view.login() await flush() await view.state.setAccount( view.state.accounts.find((account) => account.profile.id === firstId)!, @@ -271,7 +273,7 @@ test('signing out removes unregistered choices while keeping saved accounts', as [firstId, 'official'], ) assert.equal(view.selected, firstId) - view.login() + await view.login() await flush() assert.equal(view.state.accounts.length, 3) assert.equal(view.loginCalls, 1) @@ -283,10 +285,71 @@ test('signing out removes unregistered choices while keeping saved accounts', as test('a new player without a skin can render the shared empty avatar', async () => { const view = await fixture(false) try { - view.login() + await view.login() await flush() assert.equal(view.state.getAccountAvatarUrl(view.state.accounts[0]), undefined) } finally { view.close() } }) + +test('choosing a player from the home avatar rail switches the persisted account and shared skin selection', async () => { + const view = await fixture() + try { + await view.login() + await view.state.setSkinSitePlayer(secondId) + assert.equal(view.selected, secondId) + assert.equal(view.state.selectedAccount?.profile.id, secondId) + assert.equal(selectedSkinSitePlayerId.value, secondId) + await view.state.setAccount( + view.state.accounts.find((account) => account.profile.id === 'official')!, + ) + assert.equal(view.selected, 'official') + assert.equal(selectedSkinSitePlayerId.value, null) + } finally { + view.close() + } +}) + +test('failed home player selection keeps the current skin selection as well as the account', async () => { + const view = await fixture() + try { + await view.login() + await view.state.setSkinSitePlayer(firstId) + view.failLogin(true) + await view.state.setSkinSitePlayer(secondId) + assert.equal(view.selected, firstId) + assert.equal(selectedSkinSitePlayerId.value, firstId) + } finally { + view.close() + } +}) + +test('a Microsoft player linked on the skin site keeps official skin and cape management', async () => { + const view = await fixture(true, firstId) + try { + await view.login() + assert.equal(selectedSkinSitePlayerId.value, null) + await view.state.setSkinSitePlayer(secondId) + await view.state.setAccount( + view.state.accounts.find((account) => account.profile.id === firstId)!, + ) + assert.equal(view.selected, firstId) + assert.equal(selectedSkinSitePlayerId.value, null) + } finally { + view.close() + } +}) + +test('site players linked to Mojang remain selectable without a saved Microsoft credential', async () => { + const view = await fixture(false, 'official', true) + try { + await view.login() + assert.equal(view.state.accounts.length, 2) + await view.state.setSkinSitePlayer(firstId) + assert.equal(view.selected, firstId) + assert.equal(selectedSkinSitePlayerId.value, firstId) + } finally { + view.close() + } +}) diff --git a/apps/app-frontend/src/components/ui/AccountsCard.vue b/apps/app-frontend/src/components/ui/AccountsCard.vue index 7727808..1623529 100644 --- a/apps/app-frontend/src/components/ui/AccountsCard.vue +++ b/apps/app-frontend/src/components/ui/AccountsCard.vue @@ -373,7 +373,6 @@ const accounts = computed(() => { ) if (skinSiteStatus.value === 'signed-in' && skinSiteUser.value) { for (const player of skinSitePlayers.value) { - if (player.isMojang) continue const id = player.uuid.replaceAll('-', '').toLowerCase() const stored = byId.get(id) if (stored && stored.account_type !== 'yggdrasil') continue @@ -409,8 +408,12 @@ async function refreshSkinSitePlayers() { await requestSkinSitePlayers().catch(() => {}) } -function setSkinSitePlayer(playerId: string) { - selectSkinSitePlayer(playerId) +async function setSkinSitePlayer(playerId: string) { + const normalizedId = playerId.replaceAll('-', '').toLowerCase() + const account = accounts.value.find( + (candidate) => candidate.profile.id.replaceAll('-', '').toLowerCase() === normalizedId, + ) + if (account) await setAccount(account) } const HEAD_REFRESH_RETRY_DELAYS = [1500, 5000, 15000, 30000] as const @@ -531,6 +534,12 @@ function setLoginDisabled(value: boolean) { } defineExpose({ + accounts, + defaultUser, + accountSelectionPending, + setAccount, + getAccountSkin, + getAccountAvatarUrl, accountChangeRevision, login, refreshValues, @@ -669,7 +678,15 @@ async function setAccount(account: MinecraftCredential) { }) } await persistDefaultUser(userId) - selectSkinSitePlayer(null) + const sitePlayer = + account.account_type === 'yggdrasil' + ? skinSitePlayers.value.find( + (player) => + player.uuid.replaceAll('-', '').toLowerCase() === + userId.replaceAll('-', '').toLowerCase(), + ) + : undefined + selectSkinSitePlayer(sitePlayer?.uuid ?? null) defaultUser.value = userId equippedSkin.value = null notifyAccountChange() @@ -682,9 +699,20 @@ async function setAccount(account: MinecraftCredential) { } watch( - [skinSitePlayers, defaultUser, skinSiteUser], + [skinSitePlayers, defaultUser, skinSiteUser, accounts], ([availablePlayers, selectedLocalUser]) => { - if (!selectedLocalUser && !selectedSkinSitePlayerId.value && availablePlayers.length > 0) { + if (selectedLocalUser) { + const account = accounts.value.find((candidate) => candidate.profile.id === selectedLocalUser) + const match = + account?.account_type === 'yggdrasil' + ? availablePlayers.find( + (player) => + player.uuid.replaceAll('-', '').toLowerCase() === + selectedLocalUser.replaceAll('-', '').toLowerCase(), + ) + : undefined + selectSkinSitePlayer(match?.uuid ?? null) + } else if (!selectedSkinSitePlayerId.value && availablePlayers.length > 0) { selectSkinSitePlayer(availablePlayers[0].uuid) } }, diff --git a/apps/app-frontend/src/components/ui/settings/settings-search.test.ts b/apps/app-frontend/src/components/ui/settings/settings-search.test.ts index 6e2803c..2fb08bf 100644 --- a/apps/app-frontend/src/components/ui/settings/settings-search.test.ts +++ b/apps/app-frontend/src/components/ui/settings/settings-search.test.ts @@ -21,6 +21,7 @@ import { const settingsComponentFiles = { interface: ['./AppearanceSettings.vue'], 'home-navigation': ['./AppearanceSettings.vue'], + 'shortcut-settings': ['./KeybindSettings.vue'], 'language-translation': ['./LanguageSettings.vue', './TranslationSettings.vue'], ai: ['./AISettings.vue'], 'java-performance': ['./JavaSettings.vue'], @@ -30,6 +31,7 @@ const settingsComponentFiles = { 'storage-backups': ['./ResourceManagementSettings.vue', './StorageSettings.vue'], updates: ['./UpdateSettings.vue'], about: ['./AboutSettings.vue'], + logs: ['./LogsSettings.vue'], 'feature-flags': ['./FeatureFlagSettings.vue'], } as const @@ -168,8 +170,7 @@ test('developer-only settings stay out of the normal search categories', () => { ) }) - - test('settings navigation groups preserve the intended Starlight information architecture', () => { +test('settings navigation groups preserve the intended Starlight information architecture', () => { const categoriesForGroup = ( group: 'launcher' | 'game' | 'data-privacy' | 'support' | 'developer', developerMode = false, @@ -181,6 +182,7 @@ test('developer-only settings stay out of the normal search categories', () => { assert.deepEqual(categoriesForGroup('launcher'), [ 'interface', 'home-navigation', + 'shortcut-settings', 'language-translation', 'ai', ]) @@ -191,7 +193,7 @@ test('developer-only settings stay out of the normal search categories', () => { 'network-multiplayer', ]) assert.deepEqual(categoriesForGroup('data-privacy'), ['storage-backups']) - assert.deepEqual(categoriesForGroup('support'), ['updates', 'about']) + assert.deepEqual(categoriesForGroup('support'), ['updates', 'about', 'logs']) assert.deepEqual(categoriesForGroup('developer'), []) assert.deepEqual(categoriesForGroup('developer', true), ['feature-flags']) }) diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSiteAnnouncements.test.ts b/apps/app-frontend/src/components/ui/skin-site/SkinSiteAnnouncements.test.ts index f98422d..18b0567 100644 --- a/apps/app-frontend/src/components/ui/skin-site/SkinSiteAnnouncements.test.ts +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSiteAnnouncements.test.ts @@ -18,7 +18,7 @@ const require = createRequire(import.meta.url) const { parse, compileScript } = require('vue/compiler-sfc') const componentUrl = new URL('./SkinSiteAnnouncements.vue', import.meta.url).href const stubs: Record = { - '@modrinth/assets': 'export const SpinnerIcon={}', + '@modrinth/assets': 'export const NewspaperIcon={}, SpinnerIcon={}, StarIcon={}', '@modrinth/ui': 'export const commonMessages={retryButton:{defaultMessage:"Retry"}}; export const defineMessages=x=>x; export const useVIntl=()=>({formatMessage:x=>x.defaultMessage})', '@/helpers/skin-site-api': diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSiteAnnouncements.vue b/apps/app-frontend/src/components/ui/skin-site/SkinSiteAnnouncements.vue index b5acbe0..af7951c 100644 --- a/apps/app-frontend/src/components/ui/skin-site/SkinSiteAnnouncements.vue +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSiteAnnouncements.vue @@ -1,5 +1,5 @@ + + diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationCard.vue b/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationCard.vue index 137f397..6013135 100644 --- a/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationCard.vue +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationCard.vue @@ -1,5 +1,5 @@ + + diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationModal.test.ts b/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationModal.test.ts new file mode 100644 index 0000000..d421279 --- /dev/null +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationModal.test.ts @@ -0,0 +1,133 @@ +import assert from 'node:assert/strict' +import { readFileSync } from 'node:fs' +import { createRequire, registerHooks, stripTypeScriptTypes } from 'node:module' +import test from 'node:test' + +import { createRenderer, nextTick } from 'vue' + +const testGlobal = globalThis as unknown as { + donationTestFetch: (offset: number) => Promise +} +const require = createRequire(import.meta.url) +const { parse, compileScript } = require('vue/compiler-sfc') +const componentUrl = new URL('./SkinSiteDonationModal.vue', import.meta.url).href +const stubs: Record = { + '@modrinth/assets': 'export const HeartIcon={}, SpinnerIcon={}, StarIcon={}', + '@modrinth/ui': + 'export const Avatar={}, ButtonStyled={}, NewModal={}, commonMessages={retryButton:{defaultMessage:"Retry"}}; export const defineMessages=x=>x; export const useVIntl=()=>({formatMessage:x=>x.defaultMessage})', + '@/helpers/skin-site-api': + 'export const skinSiteDonationList=offset=>globalThis.donationTestFetch(offset)', +} +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier in stubs) + return { + url: `data:text/javascript,${encodeURIComponent(stubs[specifier])}`, + shortCircuit: true, + } + if (specifier === './donation-format') + return nextResolve(new URL('./donation-format.ts', import.meta.url).href, context) + return nextResolve(specifier, context) + }, + load(url, context, nextLoad) { + if (url !== componentUrl) return nextLoad(url, context) + const { descriptor } = parse(readFileSync(new URL(url), 'utf8')) + return { + format: 'module', + source: stripTypeScriptTypes(compileScript(descriptor, { id: 'donation-test' }).content), + shortCircuit: true, + } + }, +}) +const { default: Donations } = await import(componentUrl) +hooks.deregister() +Donations.render = () => null +type Node = Record +const renderer = createRenderer({ + createElement: () => ({}), + createText: () => ({}), + createComment: () => ({}), + insert() {}, + remove() {}, + setText() {}, + setElementText() {}, + patchProp() {}, + parentNode: () => null, + nextSibling: () => null, +}) +type State = { + items: Array<{ id: number }> + loading: boolean + failed: boolean + hasMore: boolean + load: (reset?: boolean) => Promise + show: () => void +} +function mount(t: test.TestContext) { + const app = renderer.createApp(Donations) + const instance = app.mount({}) + t.after(() => app.unmount()) + return (instance.$ as unknown as { setupState: State }).setupState +} +const page = (id: number, hasMore = true) => ({ + success: true, + payload: { + items: [{ id, rank: id, username: 'Donor', avatar: null, amount: '12.50' }], + summary: { totalAmount: '12.50', donorCount: 1 }, + hasMore, + }, +}) +const flush = async () => { + await new Promise((resolve) => setImmediate(resolve)) + await nextTick() +} + +test('donations load on opening and a failed next page preserves the list and retries the same offset', async (t) => { + const offsets: number[] = [] + let fail = false + testGlobal.donationTestFetch = async (offset) => { + offsets.push(offset) + return fail ? { success: false, errorMessage: 'Offline' } : page(offset + 1, offset === 0) + } + const state = mount(t) + assert.deepEqual(offsets, []) + state.show() + await flush() + assert.deepEqual( + state.items.map((item) => item.id), + [1], + ) + fail = true + await state.load() + assert.equal(state.failed, true) + assert.deepEqual( + state.items.map((item) => item.id), + [1], + ) + fail = false + await state.load() + assert.deepEqual(offsets, [0, 1, 1]) + assert.deepEqual( + state.items.map((item) => item.id), + [1, 2], + ) + assert.equal(state.hasMore, false) +}) + +test('reopening the donation list discards an older in-flight page', async (t) => { + const finish: Array<(result: unknown) => void> = [] + testGlobal.donationTestFetch = () => new Promise((resolve) => finish.push(resolve)) + const state = mount(t) + state.show() + state.show() + finish[1](page(2, false)) + await flush() + finish[0](page(1)) + await flush() + assert.deepEqual( + state.items.map((item) => item.id), + [2], + ) + assert.equal(state.loading, false) + assert.equal(state.hasMore, false) +}) diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationModal.vue b/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationModal.vue new file mode 100644 index 0000000..1c3421f --- /dev/null +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSiteDonationModal.vue @@ -0,0 +1,190 @@ + + + + + diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSiteHome.vue b/apps/app-frontend/src/components/ui/skin-site/SkinSiteHome.vue index 23fe86a..6b5bd37 100644 --- a/apps/app-frontend/src/components/ui/skin-site/SkinSiteHome.vue +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSiteHome.vue @@ -1,9 +1,9 @@ + + diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSiteNavCards.vue b/apps/app-frontend/src/components/ui/skin-site/SkinSiteNavCards.vue index 6148490..6043798 100644 --- a/apps/app-frontend/src/components/ui/skin-site/SkinSiteNavCards.vue +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSiteNavCards.vue @@ -8,12 +8,16 @@ import { UserIcon, } from '@modrinth/assets' import { defineMessages, useVIntl } from '@modrinth/ui' -import type { Component } from 'vue' +import { computed } from 'vue' + +import SkinSiteSelectionRail from './SkinSiteSelectionRail.vue' + +defineProps<{ active: string }>() const { formatMessage } = useVIntl() const emit = defineEmits<{ - (e: 'navigate', view: 'downloads' | 'review' | 'bugs' | 'map' | 'wiki'): void + (e: 'navigate', view: 'downloads' | 'review' | 'bugs' | 'map' | 'wiki' | 'players'): void }>() const messages = defineMessages({ @@ -50,96 +54,56 @@ const messages = defineMessages({ }, }) -interface NavItem { - id: string - title: string - description: string - icon: Component - href: string -} - -const SKIN_SITE = 'https://skin.starlight.cool' - -const items: NavItem[] = [ +const destinations = ['downloads', 'review', 'wiki', 'bugs', 'map', 'players'] as const +const items = computed(() => [ { - id: 'download', - title: formatMessage(messages.download), + id: 'downloads', + label: formatMessage(messages.download), description: formatMessage(messages.downloadDesc), icon: DownloadIcon, - href: `${SKIN_SITE}/download`, }, { id: 'review', - title: formatMessage(messages.review), + label: formatMessage(messages.review), description: formatMessage(messages.reviewDesc), icon: ShieldCheckIcon, - href: `${SKIN_SITE}/review`, }, { id: 'wiki', - title: formatMessage(messages.wiki), + label: formatMessage(messages.wiki), description: formatMessage(messages.wikiDesc), icon: BookIcon, - href: `${SKIN_SITE}/wiki`, }, { id: 'bugs', - title: formatMessage(messages.bugs), + label: formatMessage(messages.bugs), description: formatMessage(messages.bugsDesc), icon: BugIcon, - href: `${SKIN_SITE}/bugs`, }, { id: 'map', - title: formatMessage(messages.map), + label: formatMessage(messages.map), description: formatMessage(messages.mapDesc), icon: MapIcon, - href: `${SKIN_SITE}/map`, }, { - id: 'profile', - title: formatMessage(messages.profile), + id: 'players', + label: formatMessage(messages.profile), description: formatMessage(messages.profileDesc), icon: UserIcon, - href: `${SKIN_SITE}/profile`, }, -] - -function open(item: NavItem) { - if ( - item.id === 'download' || - item.id === 'review' || - item.id === 'bugs' || - item.id === 'map' || - item.id === 'wiki' - ) { - emit( - 'navigate', - item.id === 'download' - ? 'downloads' - : (item.id as 'review' | 'bugs' | 'map' | 'wiki'), - ) - return - } - void import('@tauri-apps/plugin-opener').then(({ openUrl }) => openUrl(item.href)) +]) +function navigate(id: string) { + const destination = destinations.find((value) => value === id) + if (destination) emit('navigate', destination) } diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSitePlayerPreview.test.ts b/apps/app-frontend/src/components/ui/skin-site/SkinSitePlayerPreview.test.ts new file mode 100644 index 0000000..22e61c1 --- /dev/null +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSitePlayerPreview.test.ts @@ -0,0 +1,194 @@ +import assert from 'node:assert/strict' +import { readFileSync } from 'node:fs' +import { createRequire, registerHooks, stripTypeScriptTypes } from 'node:module' +import test from 'node:test' + +import { createRenderer, nextTick, ref } from 'vue' + +const session = { + skinSitePlayers: ref([]), + selectedSkinSitePlayerId: ref(null), + skinSiteStatus: ref('signed-in'), + skinSitePlayersStatus: ref('ready'), +} +const testGlobal = globalThis as unknown as { + previewTestSession: typeof session + previewNormalize: (skin: { texture: string }) => Promise +} +testGlobal.previewTestSession = session +const require = createRequire(import.meta.url) +const { parse, compileScript } = require('vue/compiler-sfc') +const componentUrl = new URL('./SkinSitePlayerPreview.vue', import.meta.url).href +const stubs: Record = { + '@modrinth/assets': 'export const RefreshCwIcon={}, SpinnerIcon={}, UserIcon={}', + '@modrinth/ui': + 'export const commonMessages={retryButton:{defaultMessage:"Retry"}}; export const defineMessages=x=>x; export const useVIntl=()=>({formatMessage:x=>x.defaultMessage})', + '@modrinth/ui/src/components/skin/SkinPreviewRenderer.vue': 'export default {}', + './SkinSiteSelectionRail.vue': 'export default {}', + '@/composables/skin-site-session': + 'export const {skinSitePlayers,selectedSkinSitePlayerId,skinSiteStatus,skinSitePlayersStatus}=globalThis.previewTestSession; export const requestSkinSitePlayers=async()=>[]', + '@/helpers/skins': + 'export const get_normalized_skin_texture=skin=>globalThis.previewNormalize(skin)', +} +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier in stubs) + return { + url: `data:text/javascript,${encodeURIComponent(stubs[specifier])}`, + shortCircuit: true, + } + return nextResolve(specifier, context) + }, + load(url, context, nextLoad) { + if (url !== componentUrl) return nextLoad(url, context) + const { descriptor } = parse(readFileSync(new URL(url), 'utf8')) + return { + format: 'module', + source: stripTypeScriptTypes( + compileScript(descriptor, { id: 'player-preview-test' }).content, + ), + shortCircuit: true, + } + }, +}) +const { default: Preview } = await import(componentUrl) +hooks.deregister() +Preview.render = () => null +type Node = Record +const renderer = createRenderer({ + createElement: () => ({}), + createText: () => ({}), + createComment: () => ({}), + insert() {}, + remove() {}, + setText() {}, + setElementText() {}, + patchProp() {}, + parentNode: () => null, + nextSibling: () => null, +}) +const flush = async () => { + await new Promise((resolve) => setImmediate(resolve)) + await nextTick() +} + +function mountPreview(t: test.TestContext, card: unknown) { + const app = renderer.createApp(Preview) + app.provide('accountsCard', card) + const instance = app.mount({}) + t.after(() => app.unmount()) + return (instance.$ as unknown as { setupState: { texture: string; textureLoading: boolean } }) + .setupState +} + +test('home normalizes official textures and ignores a late texture after switching players', async (t) => { + const accounts = [ + { profile: { id: 'first', name: 'First' }, account_type: 'microsoft' }, + { profile: { id: 'second', name: 'Second' }, account_type: 'microsoft' }, + ] + const card = ref({ + accounts, + defaultUser: 'first', + getAccountSkin: (account: (typeof accounts)[number]) => ({ + texture: `https://textures.test/${account.profile.id}.png`, + variant: 'CLASSIC', + }), + getAccountAvatarUrl: () => undefined, + }) + const requests: Array<{ texture: string; finish: (texture: string) => void }> = [] + testGlobal.previewNormalize = (skin) => + new Promise((resolve) => requests.push({ texture: skin.texture, finish: resolve })) + const state = mountPreview(t, card) + assert.equal(requests[0].texture, 'https://textures.test/first.png') + card.value.defaultUser = 'second' + await flush() + assert.equal(state.texture, '') + requests[1].finish('data:image/png;base64,normalized-second') + await flush() + requests[0].finish('data:image/png;base64,normalized-first') + await flush() + assert.equal(state.texture, 'data:image/png;base64,normalized-second') + assert.equal(state.textureLoading, false) +}) + +test('account polling, avatar updates and another player changing skin keep the current preview loaded', async (t) => { + const avatar = ref('first-head') + const skins = ref>({ + first: { texture: 'https://textures.test/first.png', variant: 'CLASSIC' }, + second: { texture: 'https://textures.test/second.png', variant: 'CLASSIC' }, + }) + const card = ref({ + accounts: [ + { profile: { id: 'first', name: 'First' }, account_type: 'microsoft' }, + { profile: { id: 'second', name: 'Second' }, account_type: 'microsoft' }, + ], + defaultUser: 'first', + getAccountSkin: (account: { profile: { id: string } }) => skins.value[account.profile.id], + getAccountAvatarUrl: () => avatar.value, + }) + const requests: string[] = [] + testGlobal.previewNormalize = (skin) => { + requests.push(skin.texture) + return requests.length === 1 + ? Promise.resolve('data:image/png;base64,current-skin') + : new Promise(() => {}) + } + const state = mountPreview(t, card) + await flush() + assert.equal(state.texture, 'data:image/png;base64,current-skin') + + card.value.accounts = card.value.accounts.map((account) => ({ + ...account, + profile: { ...account.profile }, + })) + await flush() + assert.equal( + state.texture, + 'data:image/png;base64,current-skin', + 'polling must not clear the visible skin', + ) + assert.equal(requests.length, 1, 'unchanged accounts must not normalize the skin again') + + avatar.value = 'updated-head' + await flush() + assert.equal(state.texture, 'data:image/png;base64,current-skin') + assert.equal(requests.length, 1, 'avatar-only changes must not reload the 3D skin') + + skins.value.second = { texture: 'https://textures.test/second-new.png', variant: 'SLIM' } + await flush() + assert.equal(state.texture, 'data:image/png;base64,current-skin') + assert.equal(state.textureLoading, false) + assert.equal( + requests.length, + 1, + 'another player changing skin must not reload the current preview', + ) +}) + +test('the current player changing texture or model still reloads the preview', async (t) => { + const skin = ref({ texture: 'https://textures.test/original.png', variant: 'CLASSIC' }) + const card = ref({ + accounts: [{ profile: { id: 'first', name: 'First' }, account_type: 'microsoft' }], + defaultUser: 'first', + getAccountSkin: () => skin.value, + getAccountAvatarUrl: () => undefined, + }) + const requests: string[] = [] + testGlobal.previewNormalize = async (current) => { + requests.push(current.texture) + return `data:image/png;base64,skin-${requests.length}` + } + const state = mountPreview(t, card) + await flush() + skin.value.texture = 'https://textures.test/updated.png' + await flush() + assert.equal(state.texture, 'data:image/png;base64,skin-2') + skin.value.variant = 'SLIM' + await flush() + assert.equal(state.texture, 'data:image/png;base64,skin-3') + assert.deepEqual(requests, [ + 'https://textures.test/original.png', + 'https://textures.test/updated.png', + 'https://textures.test/updated.png', + ]) +}) diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSitePlayerPreview.vue b/apps/app-frontend/src/components/ui/skin-site/SkinSitePlayerPreview.vue new file mode 100644 index 0000000..9e57033 --- /dev/null +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSitePlayerPreview.vue @@ -0,0 +1,238 @@ + + + + + diff --git a/apps/app-frontend/src/components/ui/skin-site/SkinSiteSelectionRail.vue b/apps/app-frontend/src/components/ui/skin-site/SkinSiteSelectionRail.vue new file mode 100644 index 0000000..0617e3c --- /dev/null +++ b/apps/app-frontend/src/components/ui/skin-site/SkinSiteSelectionRail.vue @@ -0,0 +1,190 @@ + + + + + diff --git a/apps/app-frontend/src/components/ui/skin-site/admin/AdminLauncherPage.vue b/apps/app-frontend/src/components/ui/skin-site/admin/AdminLauncherPage.vue index 5bf3987..d796023 100644 --- a/apps/app-frontend/src/components/ui/skin-site/admin/AdminLauncherPage.vue +++ b/apps/app-frontend/src/components/ui/skin-site/admin/AdminLauncherPage.vue @@ -5,6 +5,7 @@ import { computed, onMounted, ref } from 'vue' import { skinSiteActivateLauncherRelease, + skinSiteDeleteLauncherRelease, type SkinSiteLauncherAdminState, skinSiteLauncherAdminState, type SkinSiteLauncherRelease, @@ -32,6 +33,19 @@ const messages = defineMessages({ active: { id: 'app.skin-site.admin.launcher.active', defaultMessage: 'Active' }, activate: { id: 'app.skin-site.admin.launcher.activate', defaultMessage: 'Activate' }, activated: { id: 'app.skin-site.admin.launcher.activated', defaultMessage: 'Release activated.' }, + deleteRelease: { + id: 'app.skin-site.admin.launcher.delete', + defaultMessage: 'Delete release', + }, + confirmDelete: { + id: 'app.skin-site.admin.launcher.confirm-delete', + defaultMessage: + 'Permanently delete launcher {version} and all its installation files from the server? This version will no longer be available for download or rollback. Installed launchers will not be affected.', + }, + deleted: { + id: 'app.skin-site.admin.launcher.deleted', + defaultMessage: 'Release and its installation files deleted.', + }, upload: { id: 'app.skin-site.admin.launcher.upload', defaultMessage: 'Upload release' }, uploadHint: { id: 'app.skin-site.admin.launcher.upload-hint', @@ -64,6 +78,10 @@ const uploadPercent = ref(0) const forceUpdate = ref(false) const fileInput = ref(null) const activatingId = ref(null) +const deletingId = ref(null) +const mutating = computed( + () => uploading.value || activatingId.value !== null || deletingId.value !== null, +) const releases = computed(() => state.value?.releases ?? []) const total = computed(() => releases.value.length) @@ -105,7 +123,7 @@ function nextPage() { } async function activate(release: SkinSiteLauncherRelease) { - if (activatingId.value !== null) return + if (release.active || mutating.value || loading.value) return activatingId.value = release.id try { const result = await skinSiteActivateLauncherRelease(release.id) @@ -119,6 +137,24 @@ async function activate(release: SkinSiteLauncherRelease) { } } +async function remove(release: SkinSiteLauncherRelease) { + if (release.active || mutating.value || loading.value) return + if (!window.confirm(formatMessage(messages.confirmDelete, { version: release.version }))) return + deletingId.value = release.id + try { + const result = await skinSiteDeleteLauncherRelease(release.id) + if (!result.success) throw new Error(result.errorMessage) + if (state.value) + state.value.releases = state.value.releases.filter((item) => item.id !== release.id) + offset.value = Math.min(offset.value, Math.max(0, (pageCount.value - 1) * PAGE_SIZE)) + addNotification({ type: 'success', title: formatMessage(messages.deleted) }) + } catch (error) { + handleError(error) + } finally { + deletingId.value = null + } +} + function pickFile() { fileInput.value?.click() } @@ -127,7 +163,7 @@ async function onFileChosen(event: Event) { const input = event.target as HTMLInputElement const file = input.files?.[0] input.value = '' - if (!file || uploading.value) return + if (!file || mutating.value || loading.value) return uploading.value = true uploadPercent.value = 0 try { @@ -180,7 +216,7 @@ onMounted(() => void load()) +
diff --git a/apps/app-frontend/src/components/ui/skin-site/donation-format.test.ts b/apps/app-frontend/src/components/ui/skin-site/donation-format.test.ts new file mode 100644 index 0000000..4160fdb --- /dev/null +++ b/apps/app-frontend/src/components/ui/skin-site/donation-format.test.ts @@ -0,0 +1,20 @@ +import assert from 'node:assert/strict' +import test from 'node:test' + +import { formatDonationAmount } from './donation-format.ts' + +test('donation totals and individual amounts carry yuan and exactly two decimals', () => { + for (const [amount, expected] of [ + ['12794.57', '¥12794.57'], + ['300', '¥300.00'], + ['0.1', '¥0.10'], + ['1.005', '¥1.01'], + ['0', '¥0.00'], + ]) { + assert.equal(formatDonationAmount(amount), expected) + } +}) + +test('invalid amounts do not show a made-up zero donation', () => { + for (const amount of ['', 'unknown', 'Infinity']) assert.equal(formatDonationAmount(amount), '—') +}) diff --git a/apps/app-frontend/src/components/ui/skin-site/donation-format.ts b/apps/app-frontend/src/components/ui/skin-site/donation-format.ts new file mode 100644 index 0000000..6f82164 --- /dev/null +++ b/apps/app-frontend/src/components/ui/skin-site/donation-format.ts @@ -0,0 +1,10 @@ +const amountFormatter = new Intl.NumberFormat('zh-CN', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + useGrouping: false, +}) + +export function formatDonationAmount(amount: string): string { + const value = Number(amount) + return amount.trim() && Number.isFinite(value) ? `¥${amountFormatter.format(value)}` : '—' +} diff --git a/apps/app-frontend/src/composables/skin-site-session.test.ts b/apps/app-frontend/src/composables/skin-site-session.test.ts index 5b6980d..a70cb9b 100644 --- a/apps/app-frontend/src/composables/skin-site-session.test.ts +++ b/apps/app-frontend/src/composables/skin-site-session.test.ts @@ -3,9 +3,19 @@ import { registerHooks } from 'node:module' import test from 'node:test' type FetchHandler = (url: string, options: RequestInit) => Promise -const testGlobal = globalThis as unknown as { skinSiteTestFetch: FetchHandler } +const testGlobal = globalThis as unknown as { + skinSiteTestFetch: FetchHandler + skinSiteTestHead: (texture: string) => Promise +} const hooks = registerHooks({ resolve(specifier, context, nextResolve) { + if (specifier === '@/helpers/skin-site-render') { + const renderer = new URL('../helpers/skin-site-render.ts', import.meta.url).href + return { + url: `data:text/javascript,${encodeURIComponent(`export { fetchImageAsDataUrl } from ${JSON.stringify(renderer)}; export const renderSkinHead=texture=>globalThis.skinSiteTestHead(texture)`)}`, + shortCircuit: true, + } + } if (specifier === '@tauri-apps/plugin-http') { return { url: 'data:text/javascript,export const fetch=(...args)=>globalThis.skinSiteTestFetch(...args)', @@ -44,7 +54,7 @@ test.beforeEach(() => { if (url.endsWith('/user')) return ok(user) return ok([]) } - testGlobal.skinSiteTestFetch = async (url, options) => { + testGlobal.skinSiteTestFetch = async (url, options = {}) => { calls.push({ path: new URL(url).pathname, token: (options.headers as Record)?.Authorization, @@ -206,3 +216,50 @@ test('explicit sign-out discards a late successful login', async () => { assert.equal(session.skinSiteStatus.value, 'signed-out') assert.equal(storage.has(tokenKey), false) }) + +test('player heads are cropped from one downloaded local texture rather than a cross-origin image', async (t) => { + const textureUrl = 'https://skin.starlight.cool/yggdrasil/textures/test' + const textureData = 'data:image/png;base64,iVBORw==' + const previousReader = Object.getOwnPropertyDescriptor(globalThis, 'FileReader') + Object.defineProperty(globalThis, 'FileReader', { + configurable: true, + value: class { + result: string | null = null + onload?: () => void + readAsDataURL(blob: Blob) { + void blob.arrayBuffer().then((bytes) => { + this.result = `data:${blob.type};base64,${Buffer.from(bytes).toString('base64')}` + this.onload?.() + }) + } + }, + }) + t.after(() => { + if (previousReader) Object.defineProperty(globalThis, 'FileReader', previousReader) + else Reflect.deleteProperty(globalThis, 'FileReader') + }) + t.mock.method(globalThis, 'fetch', async () => { + throw new TypeError('Cross-origin image request blocked') + }) + testGlobal.skinSiteTestHead = async (source) => { + if (source !== textureData) throw new Error('Cross-origin canvas image blocked') + return 'data:image/png;base64,local-head' + } + respond = async (url) => { + if (url === textureUrl) + return new Response(new Uint8Array([137, 80, 78, 71]), { + headers: { 'Content-Type': 'image/png' }, + }) + if (url.endsWith('/player/skin/player')) return ok({ skin: textureUrl, model: 'slim' }) + if (url.endsWith('/player')) return ok([{ uuid: 'player', name: 'Player', isMojang: false }]) + return url.endsWith('/user') ? ok(user) : ok({ jwt: 'token' }) + } + storage.set(tokenKey, 'old-token') + await session.initSkinSiteSession() + const [player] = await session.requestSkinSitePlayers() + assert.equal(player.skinState, 'ready') + assert.equal(player.skinDataUrl, textureData) + assert.equal(player.headDataUrl, 'data:image/png;base64,local-head') + assert.equal(player.model, 'slim') + assert.equal(calls.filter((call) => call.path === '/yggdrasil/textures/test').length, 1) +}) diff --git a/apps/app-frontend/src/composables/skin-site-session.ts b/apps/app-frontend/src/composables/skin-site-session.ts index 739d796..03aef05 100644 --- a/apps/app-frontend/src/composables/skin-site-session.ts +++ b/apps/app-frontend/src/composables/skin-site-session.ts @@ -275,10 +275,8 @@ async function buildPlayer(entry: { if (!texture.skin) return base try { - const [headDataUrl, skinDataUrl] = await Promise.all([ - renderSkinHead(texture.skin), - fetchImageAsDataUrl(texture.skin), - ]) + const skinDataUrl = await fetchImageAsDataUrl(texture.skin) + const headDataUrl = await renderSkinHead(skinDataUrl) return { ...base, skinState: 'ready', diff --git a/apps/app-frontend/src/helpers/app-update-policy.test.ts b/apps/app-frontend/src/helpers/app-update-policy.test.ts new file mode 100644 index 0000000..006434a --- /dev/null +++ b/apps/app-frontend/src/helpers/app-update-policy.test.ts @@ -0,0 +1,27 @@ +import assert from 'node:assert/strict' +import test from 'node:test' + +import { shouldDelayAppUpdate } from './app-update-policy.ts' + +const now = Date.parse('2026-10-21T08:00:00Z') +const recent = { publishedAt: '2026-10-21T07:00:00Z' } + +test('administrator rollbacks bypass the normal release waiting period', () => { + assert.equal(shouldDelayAppUpdate({ ...recent, rollback: true }, 'release', false, now), false) + assert.equal(shouldDelayAppUpdate({ rollback: true }, 'release', false, now), false) +}) + +test('ordinary releases retain the 24-hour delay and missing dates remain delayed', () => { + assert.equal(shouldDelayAppUpdate(recent, 'release', false, now), true) + assert.equal(shouldDelayAppUpdate({}, 'release', false, now), true) + assert.equal( + shouldDelayAppUpdate({ publishedAt: '2026-10-20T08:00:00Z' }, 'release', false, now), + false, + ) +}) + +test('beta, forced updates and immediate fetching still bypass the delay', () => { + assert.equal(shouldDelayAppUpdate(recent, 'beta', false, now), false) + assert.equal(shouldDelayAppUpdate({ ...recent, forceUpdate: true }, 'release', false, now), false) + assert.equal(shouldDelayAppUpdate(recent, 'release', true, now), false) +}) diff --git a/apps/app-frontend/src/helpers/app-update-policy.ts b/apps/app-frontend/src/helpers/app-update-policy.ts new file mode 100644 index 0000000..2d63f1e --- /dev/null +++ b/apps/app-frontend/src/helpers/app-update-policy.ts @@ -0,0 +1,11 @@ +export function shouldDelayAppUpdate( + update: { publishedAt?: string; forceUpdate?: boolean; rollback?: boolean }, + channel: string, + immediateUpdateFetch: boolean, + now = Date.now(), +): boolean { + if (channel !== 'release' || immediateUpdateFetch || update.forceUpdate || update.rollback) + return false + const publishedAt = Date.parse(update.publishedAt ?? '') + return !Number.isFinite(publishedAt) || now < publishedAt + 24 * 60 * 60 * 1000 +} diff --git a/apps/app-frontend/src/helpers/instance-player.test.ts b/apps/app-frontend/src/helpers/instance-player.test.ts index 25c912c..3d8ee54 100644 --- a/apps/app-frontend/src/helpers/instance-player.test.ts +++ b/apps/app-frontend/src/helpers/instance-player.test.ts @@ -1,20 +1,32 @@ import assert from 'node:assert/strict' +import { registerHooks } from 'node:module' import test from 'node:test' -import { - receiveSkinSiteMessage, - resetSkinSiteSession, - setSkinSiteFrame, - SKIN_SITE_ORIGIN, -} from '../composables/skin-site-session.ts' +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier === '@tauri-apps/plugin-http') { + return { + url: `data:text/javascript,${encodeURIComponent(`export const fetch=async url=>Response.json({payload:url.endsWith('/user/refresh')?{jwt:'fixture.jwt'}:url.endsWith('/user')?{uuid:'owner',username:'Owner',permissions:[]}:[]})`)}`, + shortCircuit: true, + } + } + if (specifier.startsWith('@/')) { + return nextResolve(new URL(`../${specifier.slice(2)}.ts`, import.meta.url).href, context) + } + return nextResolve(specifier, context) + }, +}) +const { initSkinSiteSession, resetSkinSiteSession, setSkinSiteFrame } = + await import('../composables/skin-site-session.ts') +hooks.deregister() import { useNetworkStatus } from '../composables/useNetworkStatus.ts' -import { - type InstancePlayer, +const { onInstancePlayerChanged, prepareInstancePlayer, registerInstancePlayerPicker, saveInstancePlayer, -} from './instance-player.ts' +} = await import('./instance-player.ts') +import type { InstancePlayer } from './instance-player.ts' test('instance player selection persists independently from the globally selected account', async () => { const previousNavigator = Object.getOwnPropertyDescriptor(globalThis, 'navigator') @@ -84,23 +96,16 @@ test('signed-in skin site renews the saved player without prompting and only not } const calls: string[] = [] let failSave = false - const frame = { - postMessage(data: { type: string; requestId: string }) { - if (data.type === 'starlight-pack-token-request') - receiveSkinSiteMessage( - { - origin: SKIN_SITE_ORIGIN, - source: frame, - data: { - type: 'starlight-pack-token-result', - requestId: data.requestId, - token: 'fixture.jwt', - }, - } as unknown as MessageEvent, - frame, - ) + const previousStorage = Object.getOwnPropertyDescriptor(globalThis, 'localStorage') + const storage = new Map([['starlight-skin-site-token', 'old.jwt']]) + Object.defineProperty(globalThis, 'localStorage', { + configurable: true, + value: { + getItem: (key: string) => storage.get(key) ?? null, + setItem: (key: string, value: string) => storage.set(key, value), + removeItem: (key: string) => storage.delete(key), }, - } as unknown as Window + }) Object.defineProperty(globalThis, 'window', { configurable: true, value: { @@ -128,19 +133,7 @@ test('signed-in skin site renews the saved player without prompting and only not const stop = onInstancePlayerChanged((id) => changes.push(id)) try { resetSkinSiteSession() - setSkinSiteFrame(frame) - receiveSkinSiteMessage( - { - origin: SKIN_SITE_ORIGIN, - source: frame, - data: { - type: 'starlight-skin-session', - status: 'signed-in', - user: { uuid: 'owner', username: 'Owner' }, - }, - } as unknown as MessageEvent, - frame, - ) + await initSkinSiteSession() await prepareInstancePlayer('one') assert.equal(prompts, 0) assert.ok(calls.includes('plugin:auth|login_skin_site_player')) @@ -149,6 +142,7 @@ test('signed-in skin site renews the saved player without prompting and only not failSave = true await assert.rejects(saveInstancePlayer('two', player), /Save failed/) assert.deepEqual(changes, ['one']) + storage.clear() resetSkinSiteSession() await prepareInstancePlayer('one') assert.equal(prompts, 1) @@ -157,6 +151,8 @@ test('signed-in skin site renews the saved player without prompting and only not unregister() resetSkinSiteSession() setSkinSiteFrame(null) + if (previousStorage) Object.defineProperty(globalThis, 'localStorage', previousStorage) + else Reflect.deleteProperty(globalThis, 'localStorage') if (previous) Object.defineProperty(globalThis, 'window', previous) else Reflect.deleteProperty(globalThis, 'window') if (previousNavigator) Object.defineProperty(globalThis, 'navigator', previousNavigator) diff --git a/apps/app-frontend/src/helpers/post-upgrade-notice.test.ts b/apps/app-frontend/src/helpers/post-upgrade-notice.test.ts index 983a89e..adb1820 100644 --- a/apps/app-frontend/src/helpers/post-upgrade-notice.test.ts +++ b/apps/app-frontend/src/helpers/post-upgrade-notice.test.ts @@ -72,7 +72,7 @@ test('notice query uses the target instance value and registered Tauri command', ) const helperSource = readFileSync(new URL('./instance.ts', import.meta.url), 'utf8') const tauriSource = readFileSync( - new URL('../../../app/src/api/instance.rs', import.meta.url), + new URL('../../../app/src/api/instance/mod.rs', import.meta.url), 'utf8', ) assert.match(querySource, /\['post-upgrade-notice', instanceId\]/) diff --git a/apps/app-frontend/src/helpers/skin-armor-preview.test.ts b/apps/app-frontend/src/helpers/skin-armor-preview.test.ts index 531ac14..f4e3a9d 100644 --- a/apps/app-frontend/src/helpers/skin-armor-preview.test.ts +++ b/apps/app-frontend/src/helpers/skin-armor-preview.test.ts @@ -1,7 +1,23 @@ import assert from 'node:assert/strict' +import { registerHooks } from 'node:module' import test from 'node:test' -import { loadSkinArmorPreview, saveSkinArmorPreview } from './skin-armor-preview.ts' +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier === '@modrinth/ui') { + return nextResolve( + new URL( + '../../../../packages/ui/src/composables/skin-rendering/armor-preview-types.ts', + import.meta.url, + ).href, + context, + ) + } + return nextResolve(specifier, context) + }, +}) +const { loadSkinArmorPreview, saveSkinArmorPreview } = await import('./skin-armor-preview.ts') +hooks.deregister() const originalStorage = Object.getOwnPropertyDescriptor(globalThis, 'localStorage') diff --git a/apps/app-frontend/src/helpers/skin-site-api.ts b/apps/app-frontend/src/helpers/skin-site-api.ts index 626b8ec..3f55443 100644 --- a/apps/app-frontend/src/helpers/skin-site-api.ts +++ b/apps/app-frontend/src/helpers/skin-site-api.ts @@ -414,8 +414,8 @@ export function skinSitePublicDonationSummary(): Promise< return skinSiteRequest('donation/summary', { auth: false }) } -export function skinSiteDonationList(offset = 0): Promise> { - return skinSiteRequest(`donation/list?limit=20&offset=${offset}`, { +export function skinSiteDonationList(offset = 0): Promise> { + return skinSiteRequest(`donation/list?limit=20&offset=${offset}`, { auth: false, }) } @@ -1214,6 +1214,10 @@ export function skinSiteActivateLauncherRelease( }) } +export function skinSiteDeleteLauncherRelease(id: number): Promise> { + return skinSiteRequest('launcher/admin/' + id, { method: 'DELETE' }) +} + export interface SkinSiteLauncherUploadStatus { id: string chunkSize: number diff --git a/apps/app-frontend/src/helpers/skin-site-render.test.ts b/apps/app-frontend/src/helpers/skin-site-render.test.ts new file mode 100644 index 0000000..6e16a6e --- /dev/null +++ b/apps/app-frontend/src/helpers/skin-site-render.test.ts @@ -0,0 +1,65 @@ +import assert from 'node:assert/strict' +import { registerHooks } from 'node:module' +import test from 'node:test' + +const testGlobal = globalThis as unknown as { + skinImageTestFetch: (url: string) => Promise +} +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier === '@tauri-apps/plugin-http') { + return { + url: 'data:text/javascript,export const fetch=(...args)=>globalThis.skinImageTestFetch(...args)', + shortCircuit: true, + } + } + return nextResolve(specifier, context) + }, +}) +const { fetchImageAsDataUrl } = await import('./skin-site-render.ts') +hooks.deregister() + +test.beforeEach((t) => { + t.mock.method(globalThis, 'fetch', async () => { + throw new TypeError('Cross-origin image request blocked') + }) + const previousReader = Object.getOwnPropertyDescriptor(globalThis, 'FileReader') + Object.defineProperty(globalThis, 'FileReader', { + configurable: true, + value: class { + result: string | null = null + onload?: () => void + onerror?: () => void + readAsDataURL(blob: Blob) { + void blob.arrayBuffer().then( + (bytes) => { + this.result = `data:${blob.type};base64,${Buffer.from(bytes).toString('base64')}` + this.onload?.() + }, + () => this.onerror?.(), + ) + } + }, + }) + t.after(() => { + if (previousReader) Object.defineProperty(globalThis, 'FileReader', previousReader) + else Reflect.deleteProperty(globalThis, 'FileReader') + }) +}) + +test('skin textures download through the native client when browser CORS blocks the site', async () => { + testGlobal.skinImageTestFetch = async () => + new Response(new Uint8Array([137, 80, 78, 71]), { headers: { 'Content-Type': 'image/png' } }) + assert.equal( + await fetchImageAsDataUrl('https://skin.starlight.cool/yggdrasil/textures/test'), + 'data:image/png;base64,iVBORw==', + ) +}) + +test('failed image downloads report the HTTP error instead of accepting the response as a texture', async () => { + testGlobal.skinImageTestFetch = async () => new Response('Unavailable', { status: 503 }) + await assert.rejects( + fetchImageAsDataUrl('https://skin.starlight.cool/yggdrasil/textures/test'), + /HTTP 503/, + ) +}) diff --git a/apps/app-frontend/src/helpers/skin-site-render.ts b/apps/app-frontend/src/helpers/skin-site-render.ts index c1d8c91..a7b2751 100644 --- a/apps/app-frontend/src/helpers/skin-site-render.ts +++ b/apps/app-frontend/src/helpers/skin-site-render.ts @@ -1,3 +1,5 @@ +import { fetch as tauriFetch } from '@tauri-apps/plugin-http' + /** * Renders a player's skin into a base64 head image, mirroring the skin site's * own head cropper (front face at 8,8 plus the hat overlay at 40,8). @@ -28,9 +30,9 @@ function loadImage(src: string): Promise { }) } -/** Crop the head (and hat overlay) out of a skin image URL. Returns a data URL. */ -export async function renderSkinHead(skinUrl: string, scale = 2): Promise { - const img = await loadImage(skinUrl) +/** Crop the head (and hat overlay) from a locally downloaded skin data URL. */ +export async function renderSkinHead(skinDataUrl: string, scale = 2): Promise { + const img = await loadImage(skinDataUrl) const { canvas, ctx } = getBuffer() canvas.width = HEAD_BUFFER_SIZE @@ -74,7 +76,7 @@ export async function renderSkinHead(skinUrl: string, scale = 2): Promise { - const response = await fetch(url) + const response = await tauriFetch(url) if (!response.ok) throw new Error(`无法加载图片(HTTP ${response.status})`) const blob = await response.blob() return await new Promise((resolve, reject) => { diff --git a/apps/app-frontend/src/locales/en-US/index.json b/apps/app-frontend/src/locales/en-US/index.json index d701ebc..a2512e0 100644 --- a/apps/app-frontend/src/locales/en-US/index.json +++ b/apps/app-frontend/src/locales/en-US/index.json @@ -1,10 +1,211 @@ { + "app.hosted-packs.progress.pause": { "message": "Pause" }, + "app.hosted-packs.progress.resume": { "message": "Resume" }, + "app.hosted-packs.progress.stop": { "message": "Stop" }, + "app.downloads.status.paused": { "message": "Paused" }, + + "app.skin-site.captcha.loading": { "message": "Loading captcha…" }, + "app.skin-site.captcha.submit": { "message": "Submit" }, + "app.skin-site.captcha.subtitle": { + "message": "Drag the slider to rotate the image upright." + }, + "app.skin-site.captcha.title": { "message": "Let us check you are human" }, + "app.skin-site.downloads.all": { "message": "All" }, + "app.skin-site.downloads.back": { "message": "Back to home" }, + "app.skin-site.downloads.empty": { "message": "Nothing to download yet." }, + "app.skin-site.downloads.failed": { "message": "Could not load downloads." }, + "app.skin-site.downloads.go": { "message": "Download" }, + "app.skin-site.downloads.loading": { "message": "Loading…" }, + "app.skin-site.downloads.status.legacy": { "message": "Legacy" }, + "app.skin-site.downloads.status.new": { "message": "New" }, + "app.skin-site.downloads.status.ok": { "message": "OK" }, + "app.skin-site.downloads.status.outdated": { "message": "Outdated" }, + "app.skin-site.downloads.status.removal": { "message": "Removal" }, + "app.skin-site.downloads.subtitle": { + "message": "Files shared by the server. Pick a category to narrow the list." + }, + "app.skin-site.downloads.title": { "message": "Downloads" }, + "app.skin-site.downloads.uploader": { "message": "by {name}" }, + "app.skin-site.home.announcements.empty": { + "message": "No announcements right now." + }, + "app.skin-site.home.announcements.failed": { + "message": "Could not load announcements." + }, + "app.skin-site.home.announcements.loading": { "message": "Loading…" }, + "app.skin-site.home.announcements.title": { "message": "Announcements" }, + "app.skin-site.home.donation.donors": { "message": "{count} donors" }, + "app.skin-site.home.donation.loading": { "message": "Loading…" }, + "app.skin-site.home.donation.title": { "message": "Donation thanks" }, + "app.skin-site.home.donation.total": { "message": "Total raised" }, + "app.skin-site.home.donation.unavailable": { + "message": "Donation summary unavailable." + }, + "app.skin-site.login.forgot": { "message": "Forgot password?" }, + "app.skin-site.login.password": { "message": "Password" }, + "app.skin-site.login.password-hint": { + "message": "6–50 characters with upper case, lower case and a digit." + }, + "app.skin-site.login.register": { "message": "Create account" }, + "app.skin-site.login.sign-in": { "message": "Sign in" }, + "app.skin-site.login.signing-in": { "message": "Signing in…" }, + "app.skin-site.login.success": { "message": "Signed in to StarLight." }, + "app.skin-site.login.title": { "message": "Sign in to StarLight" }, + "app.skin-site.login.username": { "message": "Username or email" }, + "app.skin-site.login.username-hint": { + "message": "3–16 characters, or a registered email address." + }, + "app.skin-site.map.back": { "message": "Back to home" }, + "app.skin-site.map.empty": { "message": "No maps available." }, + "app.skin-site.map.external": { "message": "External" }, + "app.skin-site.map.failed": { "message": "Could not load maps." }, + "app.skin-site.map.internal": { "message": "Internal" }, + "app.skin-site.map.loading": { "message": "Loading maps…" }, + "app.skin-site.map.map": { "message": "Map" }, + "app.skin-site.map.open": { "message": "Open in browser" }, + "app.skin-site.map.server": { "message": "Server" }, + "app.skin-site.map.title": { "message": "Server map" }, + "app.skin-site.profile-view.back": { "message": "Back to home" }, + "app.skin-site.profile-view.cape": { "message": "Cape" }, + "app.skin-site.profile-view.elytra": { "message": "Elytra" }, + "app.skin-site.profile-view.loading": { "message": "Loading players…" }, + "app.skin-site.profile-view.no-players": { "message": "No players yet." }, + "app.skin-site.profile-view.readonly": { + "message": "Mojang accounts are managed by Mojang; textures cannot be edited here." + }, + "app.skin-site.profile-view.remove": { "message": "Remove" }, + "app.skin-site.profile-view.removed": { "message": "Texture removed." }, + "app.skin-site.profile-view.select-hint": { + "message": "Select a player to preview and edit its textures." + }, + "app.skin-site.profile-view.signed-out": { + "message": "Sign in to manage your players." + }, + "app.skin-site.profile-view.skin": { "message": "Skin" }, + "app.skin-site.profile-view.title": { "message": "Your players" }, + "app.skin-site.profile-view.upload": { "message": "Upload" }, + "app.skin-site.profile-view.uploaded": { "message": "Texture updated." }, + "app.skin-site.profile.avatar": { "message": "Avatar" }, + "app.skin-site.profile.avatar-hint": { + "message": "Square images work best; the centre is cropped to 256×256." + }, + "app.skin-site.profile.avatar-uploaded": { "message": "Avatar updated." }, + "app.skin-site.profile.basic": { "message": "Profile" }, + "app.skin-site.profile.choose-avatar": { "message": "Choose image" }, + "app.skin-site.profile.minecraft-password": { + "message": "Minecraft password" + }, + "app.skin-site.profile.minecraft-password-changed": { + "message": "Minecraft password updated." + }, + "app.skin-site.profile.minecraft-password-hint": { + "message": "Used by the launcher; defaults to the website password." + }, + "app.skin-site.profile.mismatch": { "message": "Passwords do not match." }, + "app.skin-site.profile.new-password": { "message": "New password" }, + "app.skin-site.profile.old-password": { "message": "Current password" }, + "app.skin-site.profile.password-changed": { "message": "Password updated." }, + "app.skin-site.profile.password-hint": { + "message": "6–50 characters with upper case, lower case and a digit." + }, + "app.skin-site.profile.repeat-password": { "message": "Repeat new password" }, + "app.skin-site.profile.reset-default": { + "message": "Reset to website password" + }, + "app.skin-site.profile.save": { "message": "Save" }, + "app.skin-site.profile.saved": { "message": "Saved." }, + "app.skin-site.profile.security": { "message": "Security" }, + "app.skin-site.profile.site-password-hint": { + "message": "This is the password used to sign in to the skin site." + }, + "app.skin-site.profile.submit-password": { "message": "Update password" }, + "app.skin-site.profile.title": { "message": "Account settings" }, + "app.skin-site.profile.username": { "message": "Username" }, + "app.skin-site.profile.username-hint": { "message": "3–16 characters." }, + "app.skin-site.register.closed": { + "message": "Registration is currently closed on this server." + }, + "app.skin-site.register.code": { "message": "Verification code" }, + "app.skin-site.register.email": { "message": "Email" }, + "app.skin-site.register.invite-code": { "message": "Invite code" }, + "app.skin-site.register.invite-required": { + "message": "This server requires an invite code." + }, + "app.skin-site.register.mismatch": { "message": "Passwords do not match." }, + "app.skin-site.register.password": { "message": "Password" }, + "app.skin-site.register.password-hint": { + "message": "6–50 characters with upper case, lower case and a digit." + }, + "app.skin-site.register.qq": { "message": "QQ (optional)" }, + "app.skin-site.register.repeat-password": { "message": "Repeat password" }, + "app.skin-site.register.resend-in": { "message": "Sent ({seconds}s)" }, + "app.skin-site.register.send-code": { "message": "Send code" }, + "app.skin-site.register.sending": { "message": "Sending…" }, + "app.skin-site.register.submit": { "message": "Create account" }, + "app.skin-site.register.success": { + "message": "Account created and signed in." + }, + "app.skin-site.register.title": { "message": "Create a StarLight account" }, + "app.skin-site.reset.code": { "message": "Verification code" }, + "app.skin-site.reset.email": { "message": "Email" }, + "app.skin-site.reset.email-hint": { + "message": "Use the address you registered with." + }, + "app.skin-site.reset.mismatch": { "message": "Passwords do not match." }, + "app.skin-site.reset.new-password": { "message": "New password" }, + "app.skin-site.reset.password-hint": { + "message": "6–50 characters with upper case, lower case and a digit." + }, + "app.skin-site.reset.repeat-password": { "message": "Repeat password" }, + "app.skin-site.reset.resend-in": { "message": "Sent ({seconds}s)" }, + "app.skin-site.reset.send-code": { "message": "Send code" }, + "app.skin-site.reset.sending": { "message": "Sending…" }, + "app.skin-site.reset.submit": { "message": "Reset password" }, + "app.skin-site.reset.success": { + "message": "Password updated. You can sign in now." + }, + "app.skin-site.reset.title": { "message": "Reset password" }, + "app.skin-site.review.back": { "message": "Back to home" }, + "app.skin-site.review.back-to-list": { "message": "Back to forms" }, + "app.skin-site.review.email": { "message": "Your email" }, + "app.skin-site.review.email-hint": { + "message": "Results are sent to this address." + }, + "app.skin-site.review.empty": { + "message": "No application forms are available right now." + }, + "app.skin-site.review.failed": { + "message": "Could not load the review forms." + }, + "app.skin-site.review.invite-code": { "message": "Invite code" }, + "app.skin-site.review.loading": { "message": "Loading…" }, + "app.skin-site.review.optional": { "message": "Optional" }, + "app.skin-site.review.required": { "message": "Required" }, + "app.skin-site.review.result.passed": { "message": "Approved" }, + "app.skin-site.review.result.pending": { "message": "Under review" }, + "app.skin-site.review.result.rejected": { "message": "Rejected" }, + "app.skin-site.review.submit": { "message": "Submit application" }, + "app.skin-site.review.submitted": { "message": "Application submitted." }, + "app.skin-site.review.submitting": { "message": "Submitting…" }, + "app.skin-site.review.subtitle": { + "message": "Pick an application form and answer its questions." + }, + "app.skin-site.review.title": { "message": "Player review" }, + "app.skin-site.home.announcements.signed-out": { + "message": "Sign in to view announcements." + }, + "app.skin-site.chat.user-picker.email": { "message": "Email" }, + "app.skin-site.chat.user-picker.registered": { "message": "Registered" }, + "app.skin-site.chat.user-picker.banned-status": { "message": "Banned" }, + "app.skin-site.chat.user-picker.active-status": { "message": "Active" }, + "app.skin-site.admin.wiki.policy-public": { "message": "Everyone" }, + "app.skin-site.admin.wiki.policy-member": { "message": "Members" }, + "app.skin-site.admin.wiki.policy-admin": { + "message": "Website administrators" + }, "app.account.signed-in-as": { "message": "Signed in as" }, - "app.action-bar.announcements": { - "message": "Announcements" - }, "app.action-bar.downloading-java": { "message": "Downloading Java {version}" }, @@ -368,9 +569,6 @@ "app.ai-settings.visit-website": { "message": "Visit website" }, - "app.anniversary.banner": { - "message": "Happy {ordinal} Anniversary, Starlight!" - }, "app.appearance-settings.accent-color.blue": { "message": "Blue" }, @@ -425,6 +623,57 @@ "app.appearance-settings.auto-hide-downloads-button.description": { "message": "Hide the downloads button in the sidebar when there are no active download tasks." }, + "app.appearance-settings.fonts.title": { + "message": "Fonts" + }, + "app.appearance-settings.fonts.description": { + "message": "Choose the fonts the launcher interface and its logs are rendered in." + }, + "app.appearance-settings.fonts.ui-font": { + "message": "Interface font" + }, + "app.appearance-settings.fonts.ui-font-description": { + "message": "Used across the launcher interface. Only fonts installed on this system are listed." + }, + "app.appearance-settings.fonts.mono-font": { + "message": "Monospace font" + }, + "app.appearance-settings.fonts.mono-font-description": { + "message": "Used for logs, the server console, and other monospace content." + }, + "app.appearance-settings.fonts.default": { + "message": "Launcher default" + }, + "app.appearance-settings.fonts.monospace": { + "message": "Monospace" + }, + "app.appearance-settings.fonts.missing": { + "message": "Not installed" + }, + "app.appearance-settings.fonts.search-placeholder": { + "message": "Search installed fonts" + }, + "app.appearance-settings.fonts.no-results": { + "message": "No matching fonts" + }, + "app.appearance-settings.fonts.load-failed": { + "message": "Couldn't read the list of installed fonts." + }, + "app.appearance-settings.fonts.retry": { + "message": "Retry" + }, + "app.appearance-settings.fonts.reset": { + "message": "Reset" + }, + "app.appearance-settings.fonts.preview": { + "message": "Preview" + }, + "app.appearance-settings.fonts.ui-preview-sample": { + "message": "The quick brown fox jumps over the lazy dog." + }, + "app.appearance-settings.fonts.mono-preview-sample": { + "message": "const x = () => 0; // monospace" + }, "app.appearance-settings.auto-hide-downloads-button.title": { "message": "Auto-hide downloads button" }, @@ -500,57 +749,6 @@ "app.appearance-settings.default-landing-page.title": { "message": "Default landing page" }, - "app.appearance-settings.fonts.default": { - "message": "Launcher default" - }, - "app.appearance-settings.fonts.description": { - "message": "Choose the fonts the launcher interface and its logs are rendered in." - }, - "app.appearance-settings.fonts.load-failed": { - "message": "Couldn't read the list of installed fonts." - }, - "app.appearance-settings.fonts.missing": { - "message": "Not installed" - }, - "app.appearance-settings.fonts.mono-font": { - "message": "Monospace font" - }, - "app.appearance-settings.fonts.mono-font-description": { - "message": "Used for logs, the server console, and other monospace content." - }, - "app.appearance-settings.fonts.mono-preview-sample": { - "message": "const x = () => 0; // monospace" - }, - "app.appearance-settings.fonts.monospace": { - "message": "Monospace" - }, - "app.appearance-settings.fonts.no-results": { - "message": "No matching fonts" - }, - "app.appearance-settings.fonts.preview": { - "message": "Preview" - }, - "app.appearance-settings.fonts.reset": { - "message": "Reset" - }, - "app.appearance-settings.fonts.retry": { - "message": "Retry" - }, - "app.appearance-settings.fonts.search-placeholder": { - "message": "Search installed fonts" - }, - "app.appearance-settings.fonts.title": { - "message": "Fonts" - }, - "app.appearance-settings.fonts.ui-font": { - "message": "Interface font" - }, - "app.appearance-settings.fonts.ui-font-description": { - "message": "Used across the launcher interface. Only fonts installed on this system are listed." - }, - "app.appearance-settings.fonts.ui-preview-sample": { - "message": "The quick brown fox jumps over the lazy dog." - }, "app.appearance-settings.hide-nametag.description": { "message": "Disables the nametag above your player on the skins page." }, @@ -1514,9 +1712,6 @@ "app.downloads.status.interrupted": { "message": "Interrupted" }, - "app.downloads.status.paused": { - "message": "Paused" - }, "app.downloads.status.queued": { "message": "Queued" }, @@ -2486,21 +2681,12 @@ "app.hosted-packs.progress.downloads": { "message": "View downloads" }, - "app.hosted-packs.progress.pause": { - "message": "Pause" - }, "app.hosted-packs.progress.preparing": { "message": "Preparing modpack installation…" }, - "app.hosted-packs.progress.resume": { - "message": "Resume" - }, "app.hosted-packs.progress.retry": { "message": "Return to the instance to retry" }, - "app.hosted-packs.progress.stop": { - "message": "Stop" - }, "app.hosted-packs.refresh": { "message": "Refresh" }, @@ -3437,24 +3623,9 @@ "app.instances.add-content": { "message": "Add content" }, - "app.instances.batch-edit-groups.add": { - "message": "Add" - }, - "app.instances.batch-edit-groups.add-to-group-title": { - "message": "Add instances to \"{groupName}\"" - }, - "app.instances.batch-edit-groups.added": { - "message": "Added" - }, "app.instances.batch-edit-groups.apply": { "message": "Apply" }, - "app.instances.batch-edit-groups.cancel": { - "message": "Cancel" - }, - "app.instances.batch-edit-groups.create": { - "message": "Create group" - }, "app.instances.batch-edit-groups.create-group": { "message": "Create new group" }, @@ -3464,24 +3635,9 @@ "app.instances.batch-edit-groups.enter-group-name": { "message": "Enter group name" }, - "app.instances.batch-edit-groups.group-name": { - "message": "Group name" - }, - "app.instances.batch-edit-groups.group-name-placeholder": { - "message": "Enter group name" - }, "app.instances.batch-edit-groups.header": { "message": "Edit groups" }, - "app.instances.batch-edit-groups.no-instances-found": { - "message": "No instances found" - }, - "app.instances.batch-edit-groups.save-changes": { - "message": "Save" - }, - "app.instances.batch-edit-groups.search-instance": { - "message": "Search instances" - }, "app.instances.copy-path": { "message": "Copy path" }, @@ -3497,27 +3653,6 @@ "app.instances.group-by": { "message": "Group by:" }, - "app.instances.group.add-to-group": { - "message": "Add to group" - }, - "app.instances.group.collapse": { - "message": "Collapse group" - }, - "app.instances.group.delete-description": { - "message": "Instances in this group will be ungrouped." - }, - "app.instances.group.delete-group": { - "message": "Delete group" - }, - "app.instances.group.edit-name": { - "message": "Edit group name" - }, - "app.instances.group.empty": { - "message": "Drag and drop to add instances." - }, - "app.instances.group.expand": { - "message": "Expand group" - }, "app.instances.group.game-version": { "message": "Game version" }, @@ -3527,30 +3662,9 @@ "app.instances.group.loader": { "message": "Loader" }, - "app.instances.group.move-down": { - "message": "Move group down" - }, - "app.instances.group.move-up": { - "message": "Move group up" - }, - "app.instances.group.name-empty": { - "message": "Group names cannot be empty." - }, - "app.instances.group.name-too-long": { - "message": "Group names cannot be longer than {maxLength} characters." - }, - "app.instances.group.new-instance": { - "message": "New instance" - }, "app.instances.group.none": { "message": "None" }, - "app.instances.group.pinned": { - "message": "Pinned" - }, - "app.instances.group.rename-group": { - "message": "Rename group" - }, "app.instances.group.ungrouped": { "message": "No group" }, @@ -3569,39 +3683,12 @@ "app.instances.selected-count": { "message": "{count, plural, one {# selected} other {# selected}}" }, - "app.instances.sort-by": { - "message": "Sort by" - }, "app.instances.sort.date-created": { "message": "Date created" }, "app.instances.sort.date-modified": { "message": "Date modified" }, - "app.instances.sort.direction.asc-alphabetical": { - "message": "A–Z" - }, - "app.instances.sort.direction.asc-date": { - "message": "Oldest first" - }, - "app.instances.sort.direction.asc-recency": { - "message": "Least recent first" - }, - "app.instances.sort.direction.asc-version": { - "message": "Oldest version first" - }, - "app.instances.sort.direction.desc-alphabetical": { - "message": "Z–A" - }, - "app.instances.sort.direction.desc-date": { - "message": "Newest first" - }, - "app.instances.sort.direction.desc-recency": { - "message": "Most recent first" - }, - "app.instances.sort.direction.desc-version": { - "message": "Newest version first" - }, "app.instances.sort.last-played": { "message": "Last played" }, @@ -5345,30 +5432,12 @@ "app.lab.tool-count-plural": { "message": "{count} tools" }, - "app.library.context-menu.pin-instance": { - "message": "Pin instance" - }, - "app.library.context-menu.remove-from-group": { - "message": "Remove from group" - }, - "app.library.context-menu.unpin-instance": { - "message": "Unpin instance" - }, "app.library.create-instance": { "message": "Create new instance" }, - "app.library.group.new": { - "message": "New group" - }, "app.library.no-instances": { "message": "No instances found" }, - "app.library.selection.new-group": { - "message": "New group" - }, - "app.library.selection.remove-from-group": { - "message": "Remove from group" - }, "app.library.tabs.all-instances": { "message": "All instances" }, @@ -5396,144 +5465,6 @@ "app.library.view.standard": { "message": "Standard grid" }, - "app.log-share.ai.action": { - "message": "Deep AI analysis" - }, - "app.log-share.ai.confidence": { - "message": "Diagnostic confidence" - }, - "app.log-share.ai.evidence": { - "message": "Supporting evidence" - }, - "app.log-share.ai.failed": { - "message": "LogAgent analysis failed: {message}" - }, - "app.log-share.ai.limit": { - "message": "Reached tool loop limit" - }, - "app.log-share.ai.queued": { - "message": "Queued, about {position} ahead" - }, - "app.log-share.ai.queued-front": { - "message": "Queued, waiting for a free slot" - }, - "app.log-share.ai.root-cause": { - "message": "Core root cause" - }, - "app.log-share.ai.steps": { - "message": "Recommended troubleshooting steps" - }, - "app.log-share.ai.tab": { - "message": "LogAgent detailed analysis" - }, - "app.log-share.ai.thinking": { - "message": "Thinking…" - }, - "app.log-share.ai.tool": { - "message": "Using tool: {name}" - }, - "app.log-share.ai.tool-result": { - "message": "Tool result received" - }, - "app.log-share.ai.unknown-tool": { - "message": "tool" - }, - "app.log-share.ai.working": { - "message": "Analyzing with LogAgent…" - }, - "app.log-share.settings.ai-source": { - "message": "AI analysis source" - }, - "app.log-share.settings.ai-source-custom": { - "message": "Custom AI provider" - }, - "app.log-share.settings.ai-source-description": { - "message": "Both sources send a sanitized and shortened crash context. AI output may be inaccurate." - }, - "app.log-share.settings.ai-source-logshare": { - "message": "LogShare AI" - }, - "app.log-share.settings.auto-upload": { - "message": "Upload to get a structured summary automatically" - }, - "app.log-share.settings.auto-upload-description": { - "message": "Only effective in LogShare AI mode." - }, - "app.log-share.settings.description": { - "message": "Share crash diagnostics with LogShare for a structured summary and optional AI analysis. LogShare is preferred; mclo.gs is used as a fallback." - }, - "app.log-share.settings.multi-file": { - "message": "Multi-file upload" - }, - "app.log-share.settings.multi-file-description": { - "message": "Upload latest.log, crash reports, hs_err and launcher logs together." - }, - "app.log-share.settings.no-storage": { - "message": "Analyze without storing logs" - }, - "app.log-share.settings.no-storage-description": { - "message": "Submit content directly for analysis and skip the stored upload. Disables the automatic summary." - }, - "app.log-share.settings.share-provider": { - "message": "Log sharing service" - }, - "app.log-share.settings.share-provider-description": { - "message": "Where the diagnostic link is uploaded when you share it." - }, - "app.log-share.settings.show-progress": { - "message": "Show AI analysis progress" - }, - "app.log-share.settings.show-progress-description": { - "message": "Display thinking, tool and limit status while LogShare AI is working." - }, - "app.log-share.settings.title": { - "message": "Log sharing & AI analysis" - }, - "app.log-share.shared-logs.delete": { - "message": "Delete" - }, - "app.log-share.shared-logs.delete-failed": { - "message": "Failed to delete the shared log." - }, - "app.log-share.shared-logs.deleted": { - "message": "Shared log removed." - }, - "app.log-share.shared-logs.deleting": { - "message": "Deleting…" - }, - "app.log-share.shared-logs.description": { - "message": "Every diagnostic you have shared is listed here. Delete an entry to remove it from your history and request its removal from the sharing service." - }, - "app.log-share.shared-logs.empty": { - "message": "No shared logs yet." - }, - "app.log-share.shared-logs.title": { - "message": "Shared logs" - }, - "app.log-share.shared-logs.truncated": { - "message": "Truncated" - }, - "app.log-share.summary.empty": { - "message": "LogShare did not return a structured summary for these logs." - }, - "app.log-share.summary.failed": { - "message": "Could not load the LogShare summary: {message}" - }, - "app.log-share.summary.information": { - "message": "Information" - }, - "app.log-share.summary.loading": { - "message": "Loading structured summary..." - }, - "app.log-share.summary.no-storage": { - "message": "Structured summary is unavailable while no-storage mode is enabled." - }, - "app.log-share.summary.problems": { - "message": "Problems" - }, - "app.log-share.summary.title": { - "message": "LogShare analysis" - }, "app.memory-display.available": { "message": "{memory} available" }, @@ -5705,21 +5636,6 @@ "app.minecraft-crash.launch-failure-hint": { "message": "Open the Minecraft logs to view the captured Java output. When asking for help, export and send the complete Minecraft diagnostic package." }, - "app.minecraft-crash.log-file.failed": { - "message": "Could not load this log file: {message}" - }, - "app.minecraft-crash.log-file.loading": { - "message": "Loading log file..." - }, - "app.minecraft-crash.logs.empty": { - "message": "No logs from this launch were found." - }, - "app.minecraft-crash.logs.failed": { - "message": "Could not load the crash logs: {message}" - }, - "app.minecraft-crash.logs.loading": { - "message": "Loading crash logs..." - }, "app.minecraft-crash.mod-changes-action": { "message": "Review the changed Mod files and restore the previous setup manually if the crash started after those changes." }, @@ -5780,9 +5696,6 @@ "app.minecraft-crash.share-failed": { "message": "Failed to share the diagnostic" }, - "app.minecraft-crash.share-fallback": { - "message": "LogShare is unavailable, so the diagnostic was shared via mclo.gs." - }, "app.minecraft-crash.share-ready": { "message": "Diagnostic link is ready to share" }, @@ -6182,9 +6095,6 @@ "app.navigation.multiplayer": { "message": "Multiplayer" }, - "app.navigation.screenshots": { - "message": "Screenshots" - }, "app.navigation.skin-selector": { "message": "Skin selector" }, @@ -6353,24 +6263,30 @@ "app.onboarding.instance-actions.title": { "message": "The main controls" }, - "app.onboarding.instance-content-tab.description": { - "message": "Manage this instance’s mods, resource packs, and shaders here. Search, enable or disable entries, check for updates, and browse for more." - }, "app.onboarding.instance-content-tab.title": { "message": "Content" }, - "app.onboarding.instance-files-tab.description": { - "message": "Browse the instance folder and open configs or logs in the built-in editor without leaving the launcher." + "app.onboarding.instance-content-tab.description": { + "message": "Manage this instance’s mods, resource packs, and shaders here. Search, enable or disable entries, check for updates, and browse for more." }, "app.onboarding.instance-files-tab.title": { "message": "Files" }, - "app.onboarding.instance-logs-tab.description": { - "message": "Read the instance’s live logs to trace crashes and errors without digging through files." + "app.onboarding.instance-files-tab.description": { + "message": "Browse the instance folder and open configs or logs in the built-in editor without leaving the launcher." + }, + "app.onboarding.instance-worlds-tab.title": { + "message": "Worlds" + }, + "app.onboarding.instance-worlds-tab.description": { + "message": "Manage saved worlds: back them up, rename, edit world settings, and open the world folder." }, "app.onboarding.instance-logs-tab.title": { "message": "Logs" }, + "app.onboarding.instance-logs-tab.description": { + "message": "Read the instance’s live logs to trace crashes and errors without digging through files." + }, "app.onboarding.instance-mode.description": { "message": "StarLight automatically installs the administrator-selected modpack and versions, then checks and completes updates before every launch. A StarLight login is required. Choose Local to select your own versions and modpacks for other servers or single-player." }, @@ -6383,12 +6299,6 @@ "app.onboarding.instance-tabs.title": { "message": "The rest of the workshop" }, - "app.onboarding.instance-worlds-tab.description": { - "message": "Manage saved worlds: back them up, rename, edit world settings, and open the world folder." - }, - "app.onboarding.instance-worlds-tab.title": { - "message": "Worlds" - }, "app.onboarding.lab-tools.description": { "message": "Create and edit skins, generate formatted text and recipes, explore seeds, inspect schematics, and translate mods locally." }, @@ -6587,33 +6497,6 @@ "app.project.versions.already-installed": { "message": "Already installed" }, - "app.remote-announcements.center-title": { - "message": "Announcements" - }, - "app.remote-announcements.empty": { - "message": "No announcements" - }, - "app.remote-announcements.preview-action": { - "message": "Visit website" - }, - "app.remote-announcements.preview-content": { - "message": "## Announcement preview\n\nThis is **sample content**, not a published announcement.\n\n- Supports headings, lists, and links\n- Close buttons are always available\n\n> Previewing does not change real announcement read status.\n\n| Type | Display |\n| --- | --- |\n| Modal | Full Markdown content |\n| Popup | Summary, then full content |\n\n[Visit the website](https://skin.starlight.cool/)" - }, - "app.remote-announcements.preview-summary": { - "message": "This is a local preview notification. Select View announcement to see the full Markdown content." - }, - "app.remote-announcements.preview-title": { - "message": "Announcement style preview" - }, - "app.remote-announcements.read-all": { - "message": "Mark all announcements as read" - }, - "app.remote-announcements.unread": { - "message": "Unread" - }, - "app.remote-announcements.view": { - "message": "View announcement" - }, "app.restarting": { "message": "Restarting..." }, @@ -7001,21 +6884,6 @@ "app.settings.defaults.width-placeholder": { "message": "Enter width..." }, - "app.settings.defaults.window-title.default": { - "message": "Default window title" - }, - "app.settings.defaults.window-title.default-description": { - "message": "Used when an instance does not provide its own title." - }, - "app.settings.defaults.window-title.default-placeholder": { - "message": "Enter the default window title..." - }, - "app.settings.defaults.window-title.enabled": { - "message": "Custom Minecraft window title" - }, - "app.settings.defaults.window-title.enabled-description": { - "message": "Allow instances to customize the Minecraft window title." - }, "app.settings.defaults.wrapper-description": { "message": "Wrapper command for launching Minecraft." }, @@ -7034,1014 +6902,6 @@ "app.settings.feature-flags.reset-to-default": { "message": "Reset to default" }, - "app.settings.game-options.category.accessibility.description": { - "message": "Accessibility preferences" - }, - "app.settings.game-options.category.accessibility.label": { - "message": "Accessibility" - }, - "app.settings.game-options.category.chat.description": { - "message": "Chat visibility and appearance" - }, - "app.settings.game-options.category.chat.label": { - "message": "Chat" - }, - "app.settings.game-options.category.controls.description": { - "message": "Mouse, movement, and key bindings" - }, - "app.settings.game-options.category.controls.label": { - "message": "Controls" - }, - "app.settings.game-options.category.custom.description": { - "message": "Settings added by mods" - }, - "app.settings.game-options.category.custom.label": { - "message": "Custom settings" - }, - "app.settings.game-options.category.language.description": { - "message": "Game language" - }, - "app.settings.game-options.category.language.label": { - "message": "Language" - }, - "app.settings.game-options.category.music-and-sound.description": { - "message": "Volume and audio preferences" - }, - "app.settings.game-options.category.music-and-sound.label": { - "message": "Music and sound" - }, - "app.settings.game-options.category.online.description": { - "message": "Online and Realms preferences" - }, - "app.settings.game-options.category.online.label": { - "message": "Online" - }, - "app.settings.game-options.category.skin-customization.description": { - "message": "Skin layers and main hand" - }, - "app.settings.game-options.category.skin-customization.label": { - "message": "Skin customization" - }, - "app.settings.game-options.category.video.description": { - "message": "Camera and display settings" - }, - "app.settings.game-options.category.video.label": { - "message": "Video" - }, - "app.settings.game-options.choice.all": { - "message": "All" - }, - "app.settings.game-options.choice.balanced": { - "message": "Balanced" - }, - "app.settings.game-options.choice.by-player": { - "message": "By player" - }, - "app.settings.game-options.choice.chat": { - "message": "Chat" - }, - "app.settings.game-options.choice.commands-only": { - "message": "Commands only" - }, - "app.settings.game-options.choice.constant": { - "message": "Constant" - }, - "app.settings.game-options.choice.crosshair": { - "message": "Crosshair" - }, - "app.settings.game-options.choice.custom": { - "message": "Custom" - }, - "app.settings.game-options.choice.decreased": { - "message": "Decreased" - }, - "app.settings.game-options.choice.default": { - "message": "Default" - }, - "app.settings.game-options.choice.fabulous": { - "message": "Fabulous" - }, - "app.settings.game-options.choice.fancy": { - "message": "Fancy" - }, - "app.settings.game-options.choice.far": { - "message": "Far" - }, - "app.settings.game-options.choice.fast": { - "message": "Fast" - }, - "app.settings.game-options.choice.frequent": { - "message": "Frequent" - }, - "app.settings.game-options.choice.hidden": { - "message": "Hidden" - }, - "app.settings.game-options.choice.hotbar": { - "message": "Hotbar" - }, - "app.settings.game-options.choice.left": { - "message": "Left" - }, - "app.settings.game-options.choice.limited": { - "message": "Limited" - }, - "app.settings.game-options.choice.max-fps": { - "message": "Max FPS" - }, - "app.settings.game-options.choice.maximum": { - "message": "Maximum" - }, - "app.settings.game-options.choice.minimal": { - "message": "Minimal" - }, - "app.settings.game-options.choice.minimum": { - "message": "Minimum" - }, - "app.settings.game-options.choice.nearby": { - "message": "Nearby" - }, - "app.settings.game-options.choice.never": { - "message": "Never" - }, - "app.settings.game-options.choice.none": { - "message": "None" - }, - "app.settings.game-options.choice.normal": { - "message": "Normal" - }, - "app.settings.game-options.choice.off": { - "message": "Off" - }, - "app.settings.game-options.choice.on": { - "message": "On" - }, - "app.settings.game-options.choice.opengl": { - "message": "OpenGL" - }, - "app.settings.game-options.choice.pause": { - "message": "Pause menu" - }, - "app.settings.game-options.choice.pause-and-toast": { - "message": "Pause menu and toast" - }, - "app.settings.game-options.choice.power-saver": { - "message": "Power saver" - }, - "app.settings.game-options.choice.right": { - "message": "Right" - }, - "app.settings.game-options.choice.short": { - "message": "Short" - }, - "app.settings.game-options.choice.shown": { - "message": "Shown" - }, - "app.settings.game-options.choice.system": { - "message": "System" - }, - "app.settings.game-options.choice.tiny": { - "message": "Tiny" - }, - "app.settings.game-options.choice.vulkan": { - "message": "Vulkan" - }, - "app.settings.game-options.choice.when-minimized": { - "message": "When minimized" - }, - "app.settings.game-options.choice.while-afk": { - "message": "While AFK" - }, - "app.settings.game-options.compatibility.none": { - "message": "Some of your instances cannot use this setting" - }, - "app.settings.game-options.compatibility.reason.launcher-controlled": { - "message": "This setting is managed by Modrinth’s launch settings." - }, - "app.settings.game-options.custom-value.placeholder": { - "message": "Enter a value" - }, - "app.settings.game-options.keybind.assigned-status": { - "message": "{setting} is now bound to {binding}." - }, - "app.settings.game-options.keybind.cancelled-status": { - "message": "Key binding change cancelled." - }, - "app.settings.game-options.keybind.change": { - "message": "{setting}: {binding}. Activate to change the binding." - }, - "app.settings.game-options.keybind.choose": { - "message": "Choose a key" - }, - "app.settings.game-options.keybind.conflict-description": { - "message": "This is already used by {settings}." - }, - "app.settings.game-options.keybind.key.arrow-down": { - "message": "Down Arrow" - }, - "app.settings.game-options.keybind.key.arrow-left": { - "message": "Left Arrow" - }, - "app.settings.game-options.keybind.key.arrow-right": { - "message": "Right Arrow" - }, - "app.settings.game-options.keybind.key.arrow-up": { - "message": "Up Arrow" - }, - "app.settings.game-options.keybind.key.backspace": { - "message": "Backspace" - }, - "app.settings.game-options.keybind.key.caps-lock": { - "message": "Caps Lock" - }, - "app.settings.game-options.keybind.key.delete": { - "message": "Delete" - }, - "app.settings.game-options.keybind.key.end": { - "message": "End" - }, - "app.settings.game-options.keybind.key.enter": { - "message": "Enter" - }, - "app.settings.game-options.keybind.key.escape": { - "message": "Escape" - }, - "app.settings.game-options.keybind.key.home": { - "message": "Home" - }, - "app.settings.game-options.keybind.key.insert": { - "message": "Insert" - }, - "app.settings.game-options.keybind.key.keypad-key": { - "message": "Numpad {key}" - }, - "app.settings.game-options.keybind.key.left-alt": { - "message": "Left Alt" - }, - "app.settings.game-options.keybind.key.left-command": { - "message": "Left Command" - }, - "app.settings.game-options.keybind.key.left-control": { - "message": "Left Ctrl" - }, - "app.settings.game-options.keybind.key.left-shift": { - "message": "Left Shift" - }, - "app.settings.game-options.keybind.key.left-super": { - "message": "Left Super" - }, - "app.settings.game-options.keybind.key.menu": { - "message": "Menu" - }, - "app.settings.game-options.keybind.key.num-lock": { - "message": "Num Lock" - }, - "app.settings.game-options.keybind.key.page-down": { - "message": "Page Down" - }, - "app.settings.game-options.keybind.key.page-up": { - "message": "Page Up" - }, - "app.settings.game-options.keybind.key.pause": { - "message": "Pause" - }, - "app.settings.game-options.keybind.key.print-screen": { - "message": "Print Screen" - }, - "app.settings.game-options.keybind.key.right-alt": { - "message": "Right Alt" - }, - "app.settings.game-options.keybind.key.right-command": { - "message": "Right Command" - }, - "app.settings.game-options.keybind.key.right-control": { - "message": "Right Ctrl" - }, - "app.settings.game-options.keybind.key.right-shift": { - "message": "Right Shift" - }, - "app.settings.game-options.keybind.key.right-super": { - "message": "Right Super" - }, - "app.settings.game-options.keybind.key.scroll-lock": { - "message": "Scroll Lock" - }, - "app.settings.game-options.keybind.key.space": { - "message": "Space" - }, - "app.settings.game-options.keybind.key.tab": { - "message": "Tab" - }, - "app.settings.game-options.keybind.key.unbound": { - "message": "Unbound" - }, - "app.settings.game-options.keybind.key.unknown": { - "message": "Unknown key" - }, - "app.settings.game-options.keybind.listen": { - "message": "Press a key…" - }, - "app.settings.game-options.keybind.listening-status": { - "message": "Listening for a key or mouse button. Press Escape to clear this binding." - }, - "app.settings.game-options.keybind.mixed": { - "message": "Different across instances" - }, - "app.settings.game-options.keybind.modifier.alt": { - "message": "Alt" - }, - "app.settings.game-options.keybind.modifier.command": { - "message": "Command" - }, - "app.settings.game-options.keybind.modifier.control": { - "message": "Ctrl" - }, - "app.settings.game-options.keybind.modifier.shift": { - "message": "Shift" - }, - "app.settings.game-options.keybind.modifier.super": { - "message": "Super" - }, - "app.settings.game-options.keybind.mouse.button": { - "message": "Mouse {button}" - }, - "app.settings.game-options.keybind.mouse.left": { - "message": "Left Mouse" - }, - "app.settings.game-options.keybind.mouse.middle": { - "message": "Middle Mouse" - }, - "app.settings.game-options.keybind.mouse.right": { - "message": "Right Mouse" - }, - "app.settings.game-options.keybind.recording-label": { - "message": "{setting}: listening for a key or mouse button. Press Escape to clear this binding." - }, - "app.settings.game-options.keybind.scancode": { - "message": "Scancode {code}" - }, - "app.settings.game-options.keybind.unsupported-status": { - "message": "That input cannot be used by Minecraft. Press another key." - }, - "app.settings.game-options.setting.advanced-opengl.label": { - "message": "Advanced OpenGL" - }, - "app.settings.game-options.setting.allow-cursor-changes.label": { - "message": "Allow cursor changes" - }, - "app.settings.game-options.setting.allow-server-listing.description": { - "message": "Allow the player's name to appear in server listings." - }, - "app.settings.game-options.setting.allow-server-listing.label": { - "message": "Server listings" - }, - "app.settings.game-options.setting.alternate-blocks.label": { - "message": "Alternate blocks" - }, - "app.settings.game-options.setting.ambient-occlusion.label": { - "message": "Smooth lighting" - }, - "app.settings.game-options.setting.ambient-volume.label": { - "message": "Ambient/Environment" - }, - "app.settings.game-options.setting.anaglyph-3d.label": { - "message": "3D anaglyph" - }, - "app.settings.game-options.setting.anisotropic-filtering.label": { - "message": "Anisotropic filtering" - }, - "app.settings.game-options.setting.anisotropy.label": { - "message": "Anisotropy" - }, - "app.settings.game-options.setting.attack-indicator.label": { - "message": "Attack indicator" - }, - "app.settings.game-options.setting.auto-jump.description": { - "message": "Automatically jump up one-block-high obstacles." - }, - "app.settings.game-options.setting.auto-jump.label": { - "message": "Auto-jump" - }, - "app.settings.game-options.setting.auto-suggestions.label": { - "message": "Command suggestions" - }, - "app.settings.game-options.setting.autosave-indicator.label": { - "message": "Autosave indicator" - }, - "app.settings.game-options.setting.biome-blend-radius.description": { - "message": "The distance over which biome colors transition." - }, - "app.settings.game-options.setting.biome-blend-radius.label": { - "message": "Biome blend" - }, - "app.settings.game-options.setting.blocks-volume.label": { - "message": "Blocks" - }, - "app.settings.game-options.setting.brightness.label": { - "message": "Brightness" - }, - "app.settings.game-options.setting.cape.description": { - "message": "Show the player's cape, including its elytra texture." - }, - "app.settings.game-options.setting.cape.label": { - "message": "Cape" - }, - "app.settings.game-options.setting.chat-background-only.label": { - "message": "Chat background only" - }, - "app.settings.game-options.setting.chat-colors.label": { - "message": "Chat colors" - }, - "app.settings.game-options.setting.chat-delay.label": { - "message": "Chat delay" - }, - "app.settings.game-options.setting.chat-line-spacing.label": { - "message": "Chat line spacing" - }, - "app.settings.game-options.setting.chat-links-prompt.description": { - "message": "Ask before opening links from chat." - }, - "app.settings.game-options.setting.chat-links-prompt.label": { - "message": "Prompt on links" - }, - "app.settings.game-options.setting.chat-links.description": { - "message": "Allow web links in chat to be opened." - }, - "app.settings.game-options.setting.chat-links.label": { - "message": "Web links" - }, - "app.settings.game-options.setting.chat-opacity.description": { - "message": "The opacity of chat text." - }, - "app.settings.game-options.setting.chat-opacity.label": { - "message": "Chat opacity" - }, - "app.settings.game-options.setting.chat-preview.label": { - "message": "Chat preview" - }, - "app.settings.game-options.setting.chat-scale.label": { - "message": "Chat scale" - }, - "app.settings.game-options.setting.chat-visibility.label": { - "message": "Chat visibility" - }, - "app.settings.game-options.setting.chat-width.label": { - "message": "Chat width" - }, - "app.settings.game-options.setting.chunk-fade-time.label": { - "message": "Chunk fade time" - }, - "app.settings.game-options.setting.cloud-range.label": { - "message": "Cloud distance" - }, - "app.settings.game-options.setting.clouds.label": { - "message": "Clouds" - }, - "app.settings.game-options.setting.ctrl-click-right-click.label": { - "message": "Control-click as right-click" - }, - "app.settings.game-options.setting.cutout-leaves.label": { - "message": "Cutout leaves" - }, - "app.settings.game-options.setting.damage-tilt.label": { - "message": "Damage tilt" - }, - "app.settings.game-options.setting.dark-splash.description": { - "message": "Change the Mojang Studios loading screen from red to black." - }, - "app.settings.game-options.setting.dark-splash.label": { - "message": "Monochrome logo" - }, - "app.settings.game-options.setting.darkness-pulsing.label": { - "message": "Darkness pulsing" - }, - "app.settings.game-options.setting.debug-gui-scale.label": { - "message": "Debug GUI scale" - }, - "app.settings.game-options.setting.directional-audio.label": { - "message": "Directional audio" - }, - "app.settings.game-options.setting.discrete-mouse-scroll.description": { - "message": "Treat each mouse-wheel input as a single scroll step." - }, - "app.settings.game-options.setting.discrete-mouse-scroll.label": { - "message": "Discrete scrolling" - }, - "app.settings.game-options.setting.entity-distance.label": { - "message": "Entity distance" - }, - "app.settings.game-options.setting.entity-shadows.label": { - "message": "Entity shadows" - }, - "app.settings.game-options.setting.exclusive-fullscreen.label": { - "message": "Exclusive fullscreen" - }, - "app.settings.game-options.setting.extra-telemetry.label": { - "message": "Optional telemetry" - }, - "app.settings.game-options.setting.focused-chat-height.label": { - "message": "Focused chat height" - }, - "app.settings.game-options.setting.force-unicode-font.label": { - "message": "Force Unicode font" - }, - "app.settings.game-options.setting.fov-effects.label": { - "message": "FOV effects" - }, - "app.settings.game-options.setting.fov.label": { - "message": "Field of view" - }, - "app.settings.game-options.setting.fullscreen.label": { - "message": "Fullscreen" - }, - "app.settings.game-options.setting.glint-speed.label": { - "message": "Glint speed" - }, - "app.settings.game-options.setting.glint-strength.label": { - "message": "Glint strength" - }, - "app.settings.game-options.setting.graphics-backend.label": { - "message": "Graphics backend" - }, - "app.settings.game-options.setting.graphics.description": { - "message": "Controls visual quality and performance." - }, - "app.settings.game-options.setting.graphics.label": { - "message": "Graphics" - }, - "app.settings.game-options.setting.gui-scale.description": { - "message": "The size of the game interface and HUD." - }, - "app.settings.game-options.setting.gui-scale.label": { - "message": "GUI scale" - }, - "app.settings.game-options.setting.hat.description": { - "message": "Show the hat skin layer." - }, - "app.settings.game-options.setting.hat.label": { - "message": "Hat" - }, - "app.settings.game-options.setting.held-item-tooltips.label": { - "message": "Held item tooltips" - }, - "app.settings.game-options.setting.hide-lightning-flashes.label": { - "message": "Hide lightning flashes" - }, - "app.settings.game-options.setting.hide-matched-names.label": { - "message": "Hide matched names" - }, - "app.settings.game-options.setting.hide-server-address.label": { - "message": "Hide server address" - }, - "app.settings.game-options.setting.hide-splash-texts.label": { - "message": "Hide splash texts" - }, - "app.settings.game-options.setting.high-contrast-outline.label": { - "message": "High contrast block outline" - }, - "app.settings.game-options.setting.high-contrast.description": { - "message": "Enhance the contrast of interface elements." - }, - "app.settings.game-options.setting.high-contrast.label": { - "message": "High contrast" - }, - "app.settings.game-options.setting.hostile-volume.label": { - "message": "Hostile creatures" - }, - "app.settings.game-options.setting.improved-transparency.label": { - "message": "Improved transparency" - }, - "app.settings.game-options.setting.in-game-notifications.label": { - "message": "In-game notifications" - }, - "app.settings.game-options.setting.inactivity-framerate-limit.label": { - "message": "Reduced framerate" - }, - "app.settings.game-options.setting.invert-horizontal-mouse.label": { - "message": "Invert horizontal mouse" - }, - "app.settings.game-options.setting.invert-mouse.description": { - "message": "Invert vertical mouse movement." - }, - "app.settings.game-options.setting.invert-mouse.label": { - "message": "Invert mouse" - }, - "app.settings.game-options.setting.jacket.description": { - "message": "Show the jacket skin layer." - }, - "app.settings.game-options.setting.jacket.label": { - "message": "Jacket" - }, - "app.settings.game-options.setting.japanese-glyph-variants.label": { - "message": "Japanese glyph variants" - }, - "app.settings.game-options.setting.key-advancements.label": { - "message": "Advancements" - }, - "app.settings.game-options.setting.key-attack.label": { - "message": "Attack" - }, - "app.settings.game-options.setting.key-back.label": { - "message": "Move backward" - }, - "app.settings.game-options.setting.key-chat.label": { - "message": "Open chat" - }, - "app.settings.game-options.setting.key-command.label": { - "message": "Command" - }, - "app.settings.game-options.setting.key-debug-advanced-tooltips.label": { - "message": "Show advanced tooltips" - }, - "app.settings.game-options.setting.key-debug-chunk-borders.label": { - "message": "Show chunk borders" - }, - "app.settings.game-options.setting.key-debug-clear-chat.label": { - "message": "Clear chat" - }, - "app.settings.game-options.setting.key-debug-copy-location.label": { - "message": "Copy location" - }, - "app.settings.game-options.setting.key-debug-copy-recreate-command.label": { - "message": "Copy recreate command" - }, - "app.settings.game-options.setting.key-debug-crash.label": { - "message": "Trigger debug crash" - }, - "app.settings.game-options.setting.key-debug-dump-dynamic-textures.label": { - "message": "Dump dynamic textures" - }, - "app.settings.game-options.setting.key-debug-dump-version.label": { - "message": "Dump version" - }, - "app.settings.game-options.setting.key-debug-focus-pause.label": { - "message": "Pause on lost focus" - }, - "app.settings.game-options.setting.key-debug-fps-charts.label": { - "message": "FPS charts" - }, - "app.settings.game-options.setting.key-debug-hitboxes.label": { - "message": "Show hitboxes" - }, - "app.settings.game-options.setting.key-debug-improved-transparency.label": { - "message": "Improved transparency debug view" - }, - "app.settings.game-options.setting.key-debug-lightmap-texture.label": { - "message": "Lightmap texture" - }, - "app.settings.game-options.setting.key-debug-modifier.label": { - "message": "Debug modifier" - }, - "app.settings.game-options.setting.key-debug-network-charts.label": { - "message": "Network charts" - }, - "app.settings.game-options.setting.key-debug-options.label": { - "message": "Debug options" - }, - "app.settings.game-options.setting.key-debug-overlay.label": { - "message": "Debug overlay" - }, - "app.settings.game-options.setting.key-debug-profiling-chart.label": { - "message": "Profiling chart" - }, - "app.settings.game-options.setting.key-debug-profiling.label": { - "message": "Start profiling" - }, - "app.settings.game-options.setting.key-debug-reload-chunks.label": { - "message": "Reload chunks" - }, - "app.settings.game-options.setting.key-debug-reload-resource-packs.label": { - "message": "Reload resource packs" - }, - "app.settings.game-options.setting.key-debug-spectate.label": { - "message": "Spectate entity" - }, - "app.settings.game-options.setting.key-debug-switch-game-mode.label": { - "message": "Switch game mode" - }, - "app.settings.game-options.setting.key-drop.label": { - "message": "Drop item" - }, - "app.settings.game-options.setting.key-forward.label": { - "message": "Move forward" - }, - "app.settings.game-options.setting.key-friends.label": { - "message": "Friends" - }, - "app.settings.game-options.setting.key-fullscreen.label": { - "message": "Toggle fullscreen" - }, - "app.settings.game-options.setting.key-hotbar-1.label": { - "message": "Hotbar 1" - }, - "app.settings.game-options.setting.key-hotbar-2.label": { - "message": "Hotbar 2" - }, - "app.settings.game-options.setting.key-hotbar-3.label": { - "message": "Hotbar 3" - }, - "app.settings.game-options.setting.key-hotbar-4.label": { - "message": "Hotbar 4" - }, - "app.settings.game-options.setting.key-hotbar-5.label": { - "message": "Hotbar 5" - }, - "app.settings.game-options.setting.key-hotbar-6.label": { - "message": "Hotbar 6" - }, - "app.settings.game-options.setting.key-hotbar-7.label": { - "message": "Hotbar 7" - }, - "app.settings.game-options.setting.key-hotbar-8.label": { - "message": "Hotbar 8" - }, - "app.settings.game-options.setting.key-hotbar-9.label": { - "message": "Hotbar 9" - }, - "app.settings.game-options.setting.key-inventory.label": { - "message": "Inventory" - }, - "app.settings.game-options.setting.key-jump.label": { - "message": "Jump" - }, - "app.settings.game-options.setting.key-left.label": { - "message": "Strafe left" - }, - "app.settings.game-options.setting.key-load-toolbar.label": { - "message": "Load toolbar" - }, - "app.settings.game-options.setting.key-perspective.label": { - "message": "Change perspective" - }, - "app.settings.game-options.setting.key-pick-item.label": { - "message": "Pick block" - }, - "app.settings.game-options.setting.key-player-list.label": { - "message": "Player list" - }, - "app.settings.game-options.setting.key-quick-actions.label": { - "message": "Quick actions" - }, - "app.settings.game-options.setting.key-right.label": { - "message": "Strafe right" - }, - "app.settings.game-options.setting.key-save-toolbar.label": { - "message": "Save toolbar" - }, - "app.settings.game-options.setting.key-screenshot.label": { - "message": "Screenshot" - }, - "app.settings.game-options.setting.key-smooth-camera.label": { - "message": "Toggle cinematic camera" - }, - "app.settings.game-options.setting.key-sneak.label": { - "message": "Sneak" - }, - "app.settings.game-options.setting.key-social-interactions.label": { - "message": "Social interactions" - }, - "app.settings.game-options.setting.key-spectator-hotbar.label": { - "message": "Spectator hotbar" - }, - "app.settings.game-options.setting.key-spectator-outlines.label": { - "message": "Highlight spectators" - }, - "app.settings.game-options.setting.key-sprint.label": { - "message": "Sprint" - }, - "app.settings.game-options.setting.key-swap-offhand.label": { - "message": "Swap offhand" - }, - "app.settings.game-options.setting.key-toggle-gui.label": { - "message": "Toggle HUD" - }, - "app.settings.game-options.setting.key-toggle-spectator-shader.label": { - "message": "Toggle spectator shader" - }, - "app.settings.game-options.setting.key-use.label": { - "message": "Use item" - }, - "app.settings.game-options.setting.language.label": { - "message": "Language" - }, - "app.settings.game-options.setting.left-pants-leg.label": { - "message": "Left pants leg" - }, - "app.settings.game-options.setting.left-sleeve.label": { - "message": "Left sleeve" - }, - "app.settings.game-options.setting.legacy-framerate-limit.label": { - "message": "Framerate limit" - }, - "app.settings.game-options.setting.legacy-view-distance.label": { - "message": "View distance" - }, - "app.settings.game-options.setting.mac-fullscreen-menu.label": { - "message": "Show macOS menu in fullscreen" - }, - "app.settings.game-options.setting.main-hand.description": { - "message": "Choose whether the main hand is left or right." - }, - "app.settings.game-options.setting.main-hand.label": { - "message": "Main hand" - }, - "app.settings.game-options.setting.master-volume.label": { - "message": "Master volume" - }, - "app.settings.game-options.setting.max-framerate.label": { - "message": "Maximum framerate" - }, - "app.settings.game-options.setting.menu-background-blur.label": { - "message": "Menu background blur" - }, - "app.settings.game-options.setting.mipmap-levels.description": { - "message": "Texture smoothing at a distance." - }, - "app.settings.game-options.setting.mipmap-levels.label": { - "message": "Mipmap levels" - }, - "app.settings.game-options.setting.mouse-wheel-sensitivity.label": { - "message": "Mouse wheel sensitivity" - }, - "app.settings.game-options.setting.music-frequency.label": { - "message": "Music frequency" - }, - "app.settings.game-options.setting.music-toast.description": { - "message": "Choose whether music titles appear in the pause menu and as toasts." - }, - "app.settings.game-options.setting.music-toast.label": { - "message": "Music notification" - }, - "app.settings.game-options.setting.music-volume.label": { - "message": "Music" - }, - "app.settings.game-options.setting.narrator-hotkey.label": { - "message": "Narrator hotkey" - }, - "app.settings.game-options.setting.narrator.description": { - "message": "Choose what the narrator reads." - }, - "app.settings.game-options.setting.narrator.label": { - "message": "Narrator" - }, - "app.settings.game-options.setting.neutral-volume.label": { - "message": "Friendly creatures" - }, - "app.settings.game-options.setting.notification-time.description": { - "message": "How long toast notifications remain visible." - }, - "app.settings.game-options.setting.notification-time.label": { - "message": "Notification time" - }, - "app.settings.game-options.setting.operator-items-tab.label": { - "message": "Operator items tab" - }, - "app.settings.game-options.setting.panorama-speed.label": { - "message": "Panorama speed" - }, - "app.settings.game-options.setting.particles.label": { - "message": "Particles" - }, - "app.settings.game-options.setting.players-volume.label": { - "message": "Players" - }, - "app.settings.game-options.setting.prioritize-chunk-updates.label": { - "message": "Prioritize chunk updates" - }, - "app.settings.game-options.setting.quit-shortcuts.label": { - "message": "Quit shortcuts" - }, - "app.settings.game-options.setting.raw-mouse-input.label": { - "message": "Raw mouse input" - }, - "app.settings.game-options.setting.realms-notifications.label": { - "message": "Realms notifications" - }, - "app.settings.game-options.setting.record-volume.label": { - "message": "Jukebox/Note Blocks" - }, - "app.settings.game-options.setting.reduced-debug-info.label": { - "message": "Reduced debug information" - }, - "app.settings.game-options.setting.render-distance.label": { - "message": "Render distance" - }, - "app.settings.game-options.setting.right-pants-leg.label": { - "message": "Right pants leg" - }, - "app.settings.game-options.setting.right-sleeve.label": { - "message": "Right sleeve" - }, - "app.settings.game-options.setting.rotate-with-minecart.label": { - "message": "Rotate with minecart" - }, - "app.settings.game-options.setting.save-chat-drafts.label": { - "message": "Save chat drafts" - }, - "app.settings.game-options.setting.screen-effects.label": { - "message": "Screen effects" - }, - "app.settings.game-options.setting.secure-chat-only.label": { - "message": "Only show secure chat" - }, - "app.settings.game-options.setting.sensitivity.label": { - "message": "Mouse sensitivity" - }, - "app.settings.game-options.setting.server-textures.label": { - "message": "Server textures" - }, - "app.settings.game-options.setting.share-presence.label": { - "message": "Share presence" - }, - "app.settings.game-options.setting.simulation-distance.description": { - "message": "How far away entities update and blocks and fluids tick." - }, - "app.settings.game-options.setting.simulation-distance.label": { - "message": "Simulation distance" - }, - "app.settings.game-options.setting.snooper.label": { - "message": "Snooper" - }, - "app.settings.game-options.setting.sprint-window.label": { - "message": "Sprint window" - }, - "app.settings.game-options.setting.subtitles.description": { - "message": "Show captions for sounds played in the game." - }, - "app.settings.game-options.setting.subtitles.label": { - "message": "Subtitles" - }, - "app.settings.game-options.setting.text-background-opacity.label": { - "message": "Text background opacity" - }, - "app.settings.game-options.setting.texture-filtering.label": { - "message": "Texture filtering" - }, - "app.settings.game-options.setting.toggle-attack.label": { - "message": "Toggle attack" - }, - "app.settings.game-options.setting.toggle-crouch.description": { - "message": "Press once to remain crouched." - }, - "app.settings.game-options.setting.toggle-crouch.label": { - "message": "Toggle crouch" - }, - "app.settings.game-options.setting.toggle-sprint.description": { - "message": "Press once to remain sprinting." - }, - "app.settings.game-options.setting.toggle-sprint.label": { - "message": "Toggle sprint" - }, - "app.settings.game-options.setting.toggle-use.label": { - "message": "Toggle use" - }, - "app.settings.game-options.setting.touchscreen.label": { - "message": "Touchscreen mode" - }, - "app.settings.game-options.setting.ui-volume.label": { - "message": "UI" - }, - "app.settings.game-options.setting.unfocused-chat-height.label": { - "message": "Unfocused chat height" - }, - "app.settings.game-options.setting.use-vbo.label": { - "message": "Use VBOs" - }, - "app.settings.game-options.setting.view-bobbing.description": { - "message": "Add a bobbing motion to the camera while walking." - }, - "app.settings.game-options.setting.view-bobbing.label": { - "message": "View bobbing" - }, - "app.settings.game-options.setting.vignette.label": { - "message": "Vignette" - }, - "app.settings.game-options.setting.voice-volume.label": { - "message": "Voice and speech" - }, - "app.settings.game-options.setting.vsync.description": { - "message": "Limit the frame rate to the display refresh rate to prevent screen tearing." - }, - "app.settings.game-options.setting.vsync.label": { - "message": "VSync" - }, - "app.settings.game-options.setting.weather-radius.label": { - "message": "Weather radius" - }, - "app.settings.game-options.setting.weather-volume.label": { - "message": "Weather" - }, - "app.settings.game-options.validation.changed-since-opened": { - "message": "This setting changed elsewhere. Check it and try again." - }, - "app.settings.game-options.validation.invalid-value": { - "message": "Choose a valid value." - }, - "app.settings.game-options.validation.missing-value": { - "message": "Choose a value first." - }, - "app.settings.game-options.validation.no-compatible-instances": { - "message": "Some of your instances cannot use this setting" - }, "app.settings.groups.data-privacy": { "message": "Data & privacy" }, @@ -8141,72 +7001,6 @@ "app.settings.java.view-installed": { "message": "View installed Java" }, - "app.settings.logs.export.button": { - "message": "Export logs…" - }, - "app.settings.logs.export.description": { - "message": "Package launcher logs with an optional environment summary, instance log, and crash analysis." - }, - "app.settings.logs.export.modal.cancel": { - "message": "Cancel" - }, - "app.settings.logs.export.modal.confirm": { - "message": "Export" - }, - "app.settings.logs.export.modal.crash-analysis": { - "message": "Crash analysis (when a crash is detected)" - }, - "app.settings.logs.export.modal.description": { - "message": "Choose how much detail to include. Exported logs have access tokens, Minecraft tokens, and IP addresses replaced with placeholders." - }, - "app.settings.logs.export.modal.extras": { - "message": "Additional information" - }, - "app.settings.logs.export.modal.instance-logs": { - "message": "Most recent instance log" - }, - "app.settings.logs.export.modal.level": { - "message": "Log level" - }, - "app.settings.logs.export.modal.level.all": { - "message": "All levels" - }, - "app.settings.logs.export.modal.level.debug": { - "message": "Debug and above" - }, - "app.settings.logs.export.modal.level.info": { - "message": "Info and above" - }, - "app.settings.logs.export.modal.range": { - "message": "Time range" - }, - "app.settings.logs.export.modal.range.2-hours": { - "message": "Last 2 hours" - }, - "app.settings.logs.export.modal.range.30-minutes": { - "message": "Last 30 minutes" - }, - "app.settings.logs.export.modal.range.all": { - "message": "All sessions" - }, - "app.settings.logs.export.modal.system-info": { - "message": "System and environment summary" - }, - "app.settings.logs.export.modal.title": { - "message": "Export logs" - }, - "app.settings.logs.export.notification-text": { - "message": "The log archive was saved to {path}" - }, - "app.settings.logs.export.notification-title": { - "message": "Logs exported" - }, - "app.settings.logs.export.title": { - "message": "Export logs" - }, - "app.settings.logs.open-folder": { - "message": "Open logs folder" - }, "app.settings.resources.add-minecraft-directory": { "message": "Add .minecraft directory" }, @@ -8561,255 +7355,6 @@ "app.settings.storage.world": { "message": "World" }, - "app.settings.synced-options.choose-sync-source.command-history-description": { - "message": "Choose which instance to copy your command history from. This history is only used for the initial sync, and you can edit it from any instance afterward." - }, - "app.settings.synced-options.choose-sync-source.command-history-title": { - "message": "Choose command history source" - }, - "app.settings.synced-options.choose-sync-source.creative-hotbars-description": { - "message": "Choose which instance to copy your saved creative hotbars from. These hotbars are only used for the initial sync, and you can edit them from any instance afterward." - }, - "app.settings.synced-options.choose-sync-source.creative-hotbars-title": { - "message": "Choose creative hotbars source" - }, - "app.settings.synced-options.choose-sync-source.data-packs-title": { - "message": "Choose data packs source" - }, - "app.settings.synced-options.choose-sync-source.game-settings-description": { - "message": "Choose which instance to copy your game settings from. These settings are only used for the initial sync, and you can edit them from any instance afterward." - }, - "app.settings.synced-options.choose-sync-source.game-settings-title": { - "message": "Choose game settings source" - }, - "app.settings.synced-options.choose-sync-source.ineligible": { - "message": "You cannot choose this instance as a sync source" - }, - "app.settings.synced-options.choose-sync-source.load-error": { - "message": "Could not load sync sources. Please try again." - }, - "app.settings.synced-options.choose-sync-source.multiplayer-servers-description": { - "message": "Choose which instance to copy your multiplayer servers from. These servers are only used for the initial sync, and you can edit them from any instance afterward." - }, - "app.settings.synced-options.choose-sync-source.multiplayer-servers-title": { - "message": "Choose multiplayer servers source" - }, - "app.settings.synced-options.choose-sync-source.no-instances-found": { - "message": "No instances found" - }, - "app.settings.synced-options.choose-sync-source.resource-packs-title": { - "message": "Choose resource packs source" - }, - "app.settings.synced-options.choose-sync-source.retry": { - "message": "Try again" - }, - "app.settings.synced-options.choose-sync-source.search-placeholder": { - "message": "Search instance" - }, - "app.settings.synced-options.choose-sync-source.sync": { - "message": "Sync" - }, - "app.settings.synced-options.command-history": { - "message": "Sync command history" - }, - "app.settings.synced-options.command-history.description": { - "message": "Use the same command history across your instances." - }, - "app.settings.synced-options.command-history.editor-title": { - "message": "Edit command history" - }, - "app.settings.synced-options.creative-hotbars": { - "message": "Sync saved creative hotbars" - }, - "app.settings.synced-options.creative-hotbars.description": { - "message": "Use the same saved creative hotbars across your instances." - }, - "app.settings.synced-options.data-packs": { - "message": "Sync data packs" - }, - "app.settings.synced-options.data-packs.description": { - "message": "Use the same datapacks across your instances" - }, - "app.settings.synced-options.data-packs.none-synced-yet": { - "message": "You haven't synced any data packs yet" - }, - "app.settings.synced-options.edit.no-instances": { - "message": "Add an instance before editing synced data." - }, - "app.settings.synced-options.edit.no-synced-data": { - "message": "Choose a sync source before editing this setting." - }, - "app.settings.synced-options.game-settings": { - "message": "Sync game options" - }, - "app.settings.synced-options.game-settings.button": { - "message": "Edit game settings" - }, - "app.settings.synced-options.game-settings.conflict-text": { - "message": "We loaded the latest settings. Check your changes, then save again." - }, - "app.settings.synced-options.game-settings.conflict-title": { - "message": "These settings changed elsewhere" - }, - "app.settings.synced-options.game-settings.custom-empty": { - "message": "Settings added by mods will appear here after Modrinth finds them in one of your instances." - }, - "app.settings.synced-options.game-settings.description": { - "message": "Use the same game options across your instances." - }, - "app.settings.synced-options.game-settings.disable-all": { - "message": "Unsync all" - }, - "app.settings.synced-options.game-settings.disabled-tooltip": { - "message": "Enable game settings sync before choosing individual settings." - }, - "app.settings.synced-options.game-settings.empty": { - "message": "No settings match your search or filter." - }, - "app.settings.synced-options.game-settings.enable-all": { - "message": "Sync all" - }, - "app.settings.synced-options.game-settings.load-failed": { - "message": "We couldn’t load your game settings." - }, - "app.settings.synced-options.game-settings.loading": { - "message": "Loading settings..." - }, - "app.settings.synced-options.game-settings.no-options-to-edit": { - "message": "You haven't got any options yet to edit" - }, - "app.settings.synced-options.game-settings.not-being-synced": { - "message": "Not being synced" - }, - "app.settings.synced-options.game-settings.retry": { - "message": "Retry" - }, - "app.settings.synced-options.game-settings.save": { - "message": "Save settings" - }, - "app.settings.synced-options.game-settings.search": { - "message": "Search settings..." - }, - "app.settings.synced-options.game-settings.sync-description": { - "message": "Synced options are applied to every instance and override the values included with a modpack." - }, - "app.settings.synced-options.game-settings.sync-setting": { - "message": "Sync {setting} across instances" - }, - "app.settings.synced-options.game-settings.sync-title": { - "message": "Sync game settings" - }, - "app.settings.synced-options.game-settings.synced-across-instances": { - "message": "Synced across instances" - }, - "app.settings.synced-options.game-settings.title": { - "message": "Game settings" - }, - "app.settings.synced-options.game-settings.unsaved-changes": { - "message": "You have unsaved changes." - }, - "app.settings.synced-options.game-settings.unsync-setting": { - "message": "Stop syncing {setting} across instances" - }, - "app.settings.synced-options.game-settings.value-mixed": { - "message": "Different across instances" - }, - "app.settings.synced-options.game-settings.value-off": { - "message": "Off" - }, - "app.settings.synced-options.game-settings.value-on": { - "message": "On" - }, - "app.settings.synced-options.game-settings.value-unset": { - "message": "Choose a value" - }, - "app.settings.synced-options.multiplayer-servers": { - "message": "Sync multiplayer servers" - }, - "app.settings.synced-options.multiplayer-servers.address": { - "message": "Server address" - }, - "app.settings.synced-options.multiplayer-servers.copy-address": { - "message": "Copy address" - }, - "app.settings.synced-options.multiplayer-servers.count": { - "message": "{count, plural, one {# server} other {# servers}}" - }, - "app.settings.synced-options.multiplayer-servers.description": { - "message": "Use the same multiplayer servers across your instances." - }, - "app.settings.synced-options.multiplayer-servers.editor-title": { - "message": "Edit synced servers" - }, - "app.settings.synced-options.multiplayer-servers.empty": { - "message": "No user-added servers are currently synced." - }, - "app.settings.synced-options.multiplayer-servers.filter-offline": { - "message": "Offline" - }, - "app.settings.synced-options.multiplayer-servers.filter-online": { - "message": "Online" - }, - "app.settings.synced-options.multiplayer-servers.more-options": { - "message": "More server options" - }, - "app.settings.synced-options.multiplayer-servers.name": { - "message": "Server name" - }, - "app.settings.synced-options.multiplayer-servers.no-results": { - "message": "No synced servers match your search or filters." - }, - "app.settings.synced-options.multiplayer-servers.none-synced-yet": { - "message": "You haven't synced any servers yet" - }, - "app.settings.synced-options.multiplayer-servers.players-online": { - "message": "{count, number} online" - }, - "app.settings.synced-options.multiplayer-servers.search": { - "message": "Search {count, number} {count, plural, one {synced server} other {synced servers}}..." - }, - "app.settings.synced-options.multiplayer-servers.status": { - "message": "Status" - }, - "app.settings.synced-options.packs.disabled": { - "message": "Enable syncing before editing shared packs." - }, - "app.settings.synced-options.resource-packs": { - "message": "Sync resource packs" - }, - "app.settings.synced-options.resource-packs.description": { - "message": "Use the same resource packs across your instances." - }, - "app.settings.synced-options.resource-packs.none-synced-yet": { - "message": "You haven't synced any resource packs yet" - }, - "app.settings.synced-options.title": { - "message": "Options synced across all instances" - }, - "app.settings.synced-packs.data-packs": { - "message": "Data packs" - }, - "app.settings.synced-packs.disable": { - "message": "Disable" - }, - "app.settings.synced-packs.empty": { - "message": "No synced packs" - }, - "app.settings.synced-packs.enable": { - "message": "Enable" - }, - "app.settings.synced-packs.remove": { - "message": "Remove" - }, - "app.settings.synced-packs.resource-packs": { - "message": "Resource packs" - }, - "app.settings.tabs.logs": { - "message": "Logs & diagnostics" - }, - "app.settings.tabs.shortcut-settings": { - "message": "Keyboard shortcuts" - }, "app.settings.tabs.storage": { "message": "Storage" }, @@ -8984,2865 +7529,12 @@ "app.settings.updates.up-to-date": { "message": "Starlight is up to date." }, - "app.shortcut-settings.change-shortcut": { - "message": "Change the shortcut for {action}" - }, - "app.shortcut-settings.enable": { - "message": "Enable quick scrolling" - }, - "app.shortcut-settings.end-action": { - "message": "Scroll to the bottom" - }, - "app.shortcut-settings.end-action-description": { - "message": "Moves the page you are reading to the bottom." - }, - "app.shortcut-settings.home-action": { - "message": "Scroll to the top" - }, - "app.shortcut-settings.home-action-description": { - "message": "Moves the page you are reading to the top." - }, - "app.shortcut-settings.nav-create": { - "message": "Create new instance" - }, - "app.shortcut-settings.nav-create-description": { - "message": "Jump to creating a new instance." - }, - "app.shortcut-settings.nav-description": { - "message": "Jump to a menu item with its shortcut. Each shortcut is off until enabled." - }, - "app.shortcut-settings.nav-discover": { - "message": "Discover content" - }, - "app.shortcut-settings.nav-discover-description": { - "message": "Jump to browsing content." - }, - "app.shortcut-settings.nav-downloads": { - "message": "Downloads" - }, - "app.shortcut-settings.nav-downloads-description": { - "message": "Jump to downloads." - }, - "app.shortcut-settings.nav-home": { - "message": "Home" - }, - "app.shortcut-settings.nav-home-description": { - "message": "Jump to the Home page." - }, - "app.shortcut-settings.nav-lab": { - "message": "Lab" - }, - "app.shortcut-settings.nav-lab-description": { - "message": "Jump to the Lab." - }, - "app.shortcut-settings.nav-library": { - "message": "Library" - }, - "app.shortcut-settings.nav-library-description": { - "message": "Jump to your library." - }, - "app.shortcut-settings.nav-multiplayer": { - "message": "Multiplayer" - }, - "app.shortcut-settings.nav-multiplayer-description": { - "message": "Jump to multiplayer." - }, - "app.shortcut-settings.nav-settings": { - "message": "Settings" - }, - "app.shortcut-settings.nav-settings-description": { - "message": "Jump to the settings." - }, - "app.shortcut-settings.nav-skins": { - "message": "Skin selector" - }, - "app.shortcut-settings.nav-skins-description": { - "message": "Jump to the skin selector." - }, - "app.shortcut-settings.nav-title": { - "message": "Navigation shortcuts" - }, - "app.shortcut-settings.nav-worlds": { - "message": "Worlds" - }, - "app.shortcut-settings.nav-worlds-description": { - "message": "Jump to your worlds." - }, - "app.shortcut-settings.page-down-action": { - "message": "Scroll down one screen" - }, - "app.shortcut-settings.page-down-action-description": { - "message": "Moves the page you are reading down by one screen." - }, - "app.shortcut-settings.page-up-action": { - "message": "Scroll up one screen" - }, - "app.shortcut-settings.page-up-action-description": { - "message": "Moves the page you are reading up by one screen." - }, - "app.shortcut-settings.scroll-description": { - "message": "Move through long pages with the keyboard." - }, - "app.shortcut-settings.scroll-title": { - "message": "Quick scrolling" - }, "app.sidebar.collapse": { "message": "Collapse sidebar" }, "app.sidebar.expand": { "message": "Expand sidebar" }, - "app.skin-site.admin.audit.action": { - "message": "Action" - }, - "app.skin-site.admin.audit.clear": { - "message": "Clear" - }, - "app.skin-site.admin.audit.count": { - "message": "Count" - }, - "app.skin-site.admin.audit.empty": { - "message": "No audit entries." - }, - "app.skin-site.admin.audit.failed": { - "message": "Could not load audit log." - }, - "app.skin-site.admin.audit.first-at": { - "message": "First seen" - }, - "app.skin-site.admin.audit.internal": { - "message": "Internal" - }, - "app.skin-site.admin.audit.last-at": { - "message": "Last seen" - }, - "app.skin-site.admin.audit.load-more": { - "message": "Load more" - }, - "app.skin-site.admin.audit.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.audit.proxy": { - "message": "Proxy" - }, - "app.skin-site.admin.audit.record-limit": { - "message": "Record limit" - }, - "app.skin-site.admin.audit.reported-ip": { - "message": "Reported player IP" - }, - "app.skin-site.admin.audit.retention": { - "message": "Retention (days)" - }, - "app.skin-site.admin.audit.retention-saved": { - "message": "Retention updated." - }, - "app.skin-site.admin.audit.save-retention": { - "message": "Save" - }, - "app.skin-site.admin.audit.search": { - "message": "Search" - }, - "app.skin-site.admin.audit.search-action": { - "message": "Action" - }, - "app.skin-site.admin.audit.search-ip": { - "message": "IP" - }, - "app.skin-site.admin.audit.search-subject": { - "message": "Subject" - }, - "app.skin-site.admin.audit.source-ip": { - "message": "Source IP" - }, - "app.skin-site.admin.audit.subject": { - "message": "Subject" - }, - "app.skin-site.admin.audit.title": { - "message": "Access audit" - }, - "app.skin-site.admin.back": { - "message": "Back to home" - }, - "app.skin-site.admin.broadcast.cancel": { - "message": "Cancel" - }, - "app.skin-site.admin.broadcast.confirm-delete": { - "message": "Delete “{title}”? This cannot be undone." - }, - "app.skin-site.admin.broadcast.content-field": { - "message": "Content" - }, - "app.skin-site.admin.broadcast.create": { - "message": "New announcement" - }, - "app.skin-site.admin.broadcast.created": { - "message": "Announcement created." - }, - "app.skin-site.admin.broadcast.deleted": { - "message": "Announcement deleted." - }, - "app.skin-site.admin.broadcast.edit": { - "message": "Edit" - }, - "app.skin-site.admin.broadcast.empty": { - "message": "No announcements yet." - }, - "app.skin-site.admin.broadcast.expire-at": { - "message": "Expires at" - }, - "app.skin-site.admin.broadcast.failed": { - "message": "Could not load." - }, - "app.skin-site.admin.broadcast.image": { - "message": "Image" - }, - "app.skin-site.admin.broadcast.level": { - "message": "Importance" - }, - "app.skin-site.admin.broadcast.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.broadcast.remove": { - "message": "Delete" - }, - "app.skin-site.admin.broadcast.remove-image": { - "message": "Remove image" - }, - "app.skin-site.admin.broadcast.save": { - "message": "Save" - }, - "app.skin-site.admin.broadcast.star": { - "message": "Highlight" - }, - "app.skin-site.admin.broadcast.subtitle-field": { - "message": "Subtitle" - }, - "app.skin-site.admin.broadcast.title": { - "message": "Announcements" - }, - "app.skin-site.admin.broadcast.title-field": { - "message": "Title" - }, - "app.skin-site.admin.broadcast.updated": { - "message": "Announcement updated." - }, - "app.skin-site.admin.broadcast.uploader": { - "message": "by {name}" - }, - "app.skin-site.admin.donations.amount": { - "message": "Amount" - }, - "app.skin-site.admin.donations.amount-field": { - "message": "Amount" - }, - "app.skin-site.admin.donations.append-mode": { - "message": "Append to existing amount" - }, - "app.skin-site.admin.donations.cancel": { - "message": "Cancel" - }, - "app.skin-site.admin.donations.confirm-delete": { - "message": "Delete the donation from “{name}”? This cannot be undone." - }, - "app.skin-site.admin.donations.create": { - "message": "Add donation" - }, - "app.skin-site.admin.donations.created": { - "message": "Donation created." - }, - "app.skin-site.admin.donations.deleted": { - "message": "Donation deleted." - }, - "app.skin-site.admin.donations.display-name": { - "message": "Display name" - }, - "app.skin-site.admin.donations.donor": { - "message": "Donor" - }, - "app.skin-site.admin.donations.donor-count": { - "message": "Donors" - }, - "app.skin-site.admin.donations.edit": { - "message": "Edit" - }, - "app.skin-site.admin.donations.empty": { - "message": "No donations yet." - }, - "app.skin-site.admin.donations.external": { - "message": "External" - }, - "app.skin-site.admin.donations.failed": { - "message": "Could not load donations." - }, - "app.skin-site.admin.donations.linked": { - "message": "Linked" - }, - "app.skin-site.admin.donations.load-more": { - "message": "Load more" - }, - "app.skin-site.admin.donations.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.donations.qq": { - "message": "QQ" - }, - "app.skin-site.admin.donations.remove": { - "message": "Delete" - }, - "app.skin-site.admin.donations.save": { - "message": "Save" - }, - "app.skin-site.admin.donations.title": { - "message": "Donations" - }, - "app.skin-site.admin.donations.total-amount": { - "message": "Total" - }, - "app.skin-site.admin.donations.updated": { - "message": "Donation updated." - }, - "app.skin-site.admin.donations.updated-at": { - "message": "Updated" - }, - "app.skin-site.admin.donations.user-uuid": { - "message": "User UUID" - }, - "app.skin-site.admin.downloads.add-category": { - "message": "Add" - }, - "app.skin-site.admin.downloads.add-item": { - "message": "New item" - }, - "app.skin-site.admin.downloads.add-route": { - "message": "Add route" - }, - "app.skin-site.admin.downloads.all": { - "message": "All items" - }, - "app.skin-site.admin.downloads.bind-category": { - "message": "Categories" - }, - "app.skin-site.admin.downloads.cancel": { - "message": "Cancel" - }, - "app.skin-site.admin.downloads.categories": { - "message": "Categories" - }, - "app.skin-site.admin.downloads.category-added": { - "message": "Category added." - }, - "app.skin-site.admin.downloads.category-deleted": { - "message": "Category deleted." - }, - "app.skin-site.admin.downloads.category-name": { - "message": "Category name" - }, - "app.skin-site.admin.downloads.confirm-delete-category": { - "message": "Delete category “{name}”?" - }, - "app.skin-site.admin.downloads.confirm-delete-item": { - "message": "Delete “{name}”? This cannot be undone." - }, - "app.skin-site.admin.downloads.created": { - "message": "Item created." - }, - "app.skin-site.admin.downloads.deleted": { - "message": "Item deleted." - }, - "app.skin-site.admin.downloads.description": { - "message": "Description" - }, - "app.skin-site.admin.downloads.edit": { - "message": "Edit" - }, - "app.skin-site.admin.downloads.empty": { - "message": "No download items." - }, - "app.skin-site.admin.downloads.failed": { - "message": "Could not load downloads." - }, - "app.skin-site.admin.downloads.filename": { - "message": "File name" - }, - "app.skin-site.admin.downloads.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.downloads.remove": { - "message": "Delete" - }, - "app.skin-site.admin.downloads.remove-category": { - "message": "Remove" - }, - "app.skin-site.admin.downloads.remove-route": { - "message": "Remove" - }, - "app.skin-site.admin.downloads.route-name": { - "message": "Name" - }, - "app.skin-site.admin.downloads.route-url": { - "message": "URL" - }, - "app.skin-site.admin.downloads.routes": { - "message": "Download routes" - }, - "app.skin-site.admin.downloads.save": { - "message": "Save" - }, - "app.skin-site.admin.downloads.statuses": { - "message": "Statuses" - }, - "app.skin-site.admin.downloads.title": { - "message": "Downloads" - }, - "app.skin-site.admin.downloads.total": { - "message": "{count} items" - }, - "app.skin-site.admin.downloads.updated": { - "message": "Item updated." - }, - "app.skin-site.admin.downloads.uploader": { - "message": "by {name}" - }, - "app.skin-site.admin.group.community": { - "message": "Community" - }, - "app.skin-site.admin.group.resources": { - "message": "Resources" - }, - "app.skin-site.admin.group.security": { - "message": "Security" - }, - "app.skin-site.admin.group.users": { - "message": "Users" - }, - "app.skin-site.admin.item.access-audit": { - "message": "Access audit" - }, - "app.skin-site.admin.item.broadcast": { - "message": "Broadcast" - }, - "app.skin-site.admin.item.chat": { - "message": "Chat rooms" - }, - "app.skin-site.admin.item.donations": { - "message": "Donations" - }, - "app.skin-site.admin.item.downloads": { - "message": "Downloads" - }, - "app.skin-site.admin.item.launcher": { - "message": "Launcher" - }, - "app.skin-site.admin.item.mods": { - "message": "Mods" - }, - "app.skin-site.admin.item.players": { - "message": "Players" - }, - "app.skin-site.admin.item.review": { - "message": "Player review" - }, - "app.skin-site.admin.item.servers": { - "message": "Servers" - }, - "app.skin-site.admin.item.summary": { - "message": "Summary" - }, - "app.skin-site.admin.item.users": { - "message": "Users" - }, - "app.skin-site.admin.item.wiki": { - "message": "Wiki" - }, - "app.skin-site.admin.launcher.activate": { - "message": "Activate" - }, - "app.skin-site.admin.launcher.activated": { - "message": "Release activated." - }, - "app.skin-site.admin.launcher.active": { - "message": "Active" - }, - "app.skin-site.admin.launcher.channel": { - "message": "Channel" - }, - "app.skin-site.admin.launcher.empty": { - "message": "No releases uploaded yet." - }, - "app.skin-site.admin.launcher.failed": { - "message": "Could not load releases." - }, - "app.skin-site.admin.launcher.force-flag": { - "message": "Force update" - }, - "app.skin-site.admin.launcher.force-update": { - "message": "Forced" - }, - "app.skin-site.admin.launcher.latest-url": { - "message": "Latest URL" - }, - "app.skin-site.admin.launcher.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.launcher.next": { - "message": "Next" - }, - "app.skin-site.admin.launcher.page": { - "message": "Page {page}" - }, - "app.skin-site.admin.launcher.prev": { - "message": "Previous" - }, - "app.skin-site.admin.launcher.published-at": { - "message": "Published" - }, - "app.skin-site.admin.launcher.title": { - "message": "Launcher releases" - }, - "app.skin-site.admin.launcher.total": { - "message": "{count} releases" - }, - "app.skin-site.admin.launcher.upload": { - "message": "Upload release" - }, - "app.skin-site.admin.launcher.upload-done": { - "message": "Release uploaded." - }, - "app.skin-site.admin.launcher.upload-hint": { - "message": "Choose a release ZIP (max 4 GiB)." - }, - "app.skin-site.admin.launcher.uploaded-at": { - "message": "Uploaded" - }, - "app.skin-site.admin.launcher.uploader": { - "message": "Uploaded by" - }, - "app.skin-site.admin.launcher.uploading": { - "message": "Uploading…" - }, - "app.skin-site.admin.launcher.version": { - "message": "Version" - }, - "app.skin-site.admin.mods.activate": { - "message": "Activate" - }, - "app.skin-site.admin.mods.activated": { - "message": "Runtime activated." - }, - "app.skin-site.admin.mods.active": { - "message": "Active" - }, - "app.skin-site.admin.mods.apply": { - "message": "Apply" - }, - "app.skin-site.admin.mods.available": { - "message": "Available" - }, - "app.skin-site.admin.mods.cancel": { - "message": "Cancel" - }, - "app.skin-site.admin.mods.clear": { - "message": "Clear" - }, - "app.skin-site.admin.mods.clear-selection": { - "message": "Clear selection" - }, - "app.skin-site.admin.mods.confirm-delete": { - "message": "Delete mod “{name}”? This cannot be undone." - }, - "app.skin-site.admin.mods.confirm-delete-multi": { - "message": "Delete {count} selected mods? This cannot be undone." - }, - "app.skin-site.admin.mods.confirm-delete-tag": { - "message": "Delete tag “{name}”?" - }, - "app.skin-site.admin.mods.delete-selected": { - "message": "Delete selected" - }, - "app.skin-site.admin.mods.deleted": { - "message": "Mod deleted." - }, - "app.skin-site.admin.mods.deleted-multi": { - "message": "Selected mods deleted." - }, - "app.skin-site.admin.mods.domain-rules": { - "message": "Domain rules" - }, - "app.skin-site.admin.mods.edit": { - "message": "Edit" - }, - "app.skin-site.admin.mods.empty": { - "message": "No mods found." - }, - "app.skin-site.admin.mods.exit-select": { - "message": "Done selecting" - }, - "app.skin-site.admin.mods.failed": { - "message": "Could not load mods." - }, - "app.skin-site.admin.mods.filter-all": { - "message": "All tags" - }, - "app.skin-site.admin.mods.loaders": { - "message": "Loaders" - }, - "app.skin-site.admin.mods.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.mods.manifest-url": { - "message": "Manifest URL" - }, - "app.skin-site.admin.mods.mod-id": { - "message": "Mod ID" - }, - "app.skin-site.admin.mods.name": { - "message": "Name" - }, - "app.skin-site.admin.mods.new-tag": { - "message": "New tag" - }, - "app.skin-site.admin.mods.next": { - "message": "Next" - }, - "app.skin-site.admin.mods.page": { - "message": "Page {page}" - }, - "app.skin-site.admin.mods.prev": { - "message": "Previous" - }, - "app.skin-site.admin.mods.remove": { - "message": "Delete" - }, - "app.skin-site.admin.mods.rule-tags": { - "message": "Rule tags" - }, - "app.skin-site.admin.mods.runtime": { - "message": "Runtime releases" - }, - "app.skin-site.admin.mods.runtime-uploaded": { - "message": "Runtime uploaded." - }, - "app.skin-site.admin.mods.runtime-version": { - "message": "Version" - }, - "app.skin-site.admin.mods.save": { - "message": "Save" - }, - "app.skin-site.admin.mods.search": { - "message": "Search by name" - }, - "app.skin-site.admin.mods.select-all": { - "message": "Select all" - }, - "app.skin-site.admin.mods.select-mode": { - "message": "Select multiple" - }, - "app.skin-site.admin.mods.selected-count": { - "message": "{count} selected" - }, - "app.skin-site.admin.mods.server-address": { - "message": "Server address" - }, - "app.skin-site.admin.mods.server-address-hint": { - "message": "Filter by server address" - }, - "app.skin-site.admin.mods.size": { - "message": "Size" - }, - "app.skin-site.admin.mods.tab-mods": { - "message": "Mod files" - }, - "app.skin-site.admin.mods.tab-runtime": { - "message": "Runtime" - }, - "app.skin-site.admin.mods.tab-tags": { - "message": "Rule tags" - }, - "app.skin-site.admin.mods.tag-created": { - "message": "Tag created." - }, - "app.skin-site.admin.mods.tag-deleted": { - "message": "Tag deleted." - }, - "app.skin-site.admin.mods.tag-name": { - "message": "Tag name" - }, - "app.skin-site.admin.mods.tag-rules": { - "message": "Rules" - }, - "app.skin-site.admin.mods.tag-rules-hint": { - "message": "One rule per line." - }, - "app.skin-site.admin.mods.tag-updated": { - "message": "Tag updated." - }, - "app.skin-site.admin.mods.title": { - "message": "Mods" - }, - "app.skin-site.admin.mods.total": { - "message": "{count} mods" - }, - "app.skin-site.admin.mods.unavailable": { - "message": "Unavailable" - }, - "app.skin-site.admin.mods.updated": { - "message": "Mod updated." - }, - "app.skin-site.admin.mods.upload": { - "message": "Upload" - }, - "app.skin-site.admin.mods.upload-all-done": { - "message": "All files processed." - }, - "app.skin-site.admin.mods.upload-checking": { - "message": "Checking…" - }, - "app.skin-site.admin.mods.upload-close": { - "message": "Close" - }, - "app.skin-site.admin.mods.upload-conflict": { - "message": "Name exists" - }, - "app.skin-site.admin.mods.upload-drop": { - "message": "Drag .jar files here, or click to choose" - }, - "app.skin-site.admin.mods.upload-error": { - "message": "Failed" - }, - "app.skin-site.admin.mods.upload-exists": { - "message": "This file already exists on the server." - }, - "app.skin-site.admin.mods.upload-name-conflict": { - "message": "A mod with the same file name already exists" - }, - "app.skin-site.admin.mods.upload-name-conflict-hint": { - "message": "Overwrite the existing mod, or skip this file." - }, - "app.skin-site.admin.mods.upload-overwrite": { - "message": "Overwrite" - }, - "app.skin-site.admin.mods.upload-pending": { - "message": "Pending" - }, - "app.skin-site.admin.mods.upload-queue": { - "message": "Files" - }, - "app.skin-site.admin.mods.upload-runtime": { - "message": "Upload runtime" - }, - "app.skin-site.admin.mods.upload-skip": { - "message": "Skip" - }, - "app.skin-site.admin.mods.upload-sub": { - "message": "Multiple files supported, up to {size} MB each" - }, - "app.skin-site.admin.mods.upload-success": { - "message": "Done" - }, - "app.skin-site.admin.mods.upload-tags": { - "message": "Attach rule tags" - }, - "app.skin-site.admin.mods.upload-title": { - "message": "Upload mods" - }, - "app.skin-site.admin.mods.upload-too-large": { - "message": "File too large: {name}" - }, - "app.skin-site.admin.mods.upload-uploading": { - "message": "Uploading…" - }, - "app.skin-site.admin.mods.uploader": { - "message": "by {name}" - }, - "app.skin-site.admin.mods.uploading": { - "message": "Uploading…" - }, - "app.skin-site.admin.mods.version": { - "message": "Version" - }, - "app.skin-site.admin.no-access": { - "message": "You do not have access." - }, - "app.skin-site.admin.no-access-hint": { - "message": "Sign in with an administrator account to use this console." - }, - "app.skin-site.admin.players.actions": { - "message": "Actions" - }, - "app.skin-site.admin.players.cancel": { - "message": "Cancel" - }, - "app.skin-site.admin.players.confirm-delete": { - "message": "Delete player “{name}”? This cannot be undone." - }, - "app.skin-site.admin.players.custom": { - "message": "Skin site" - }, - "app.skin-site.admin.players.deleted": { - "message": "Player deleted." - }, - "app.skin-site.admin.players.edit": { - "message": "Edit" - }, - "app.skin-site.admin.players.empty": { - "message": "No players found." - }, - "app.skin-site.admin.players.failed": { - "message": "Could not load players." - }, - "app.skin-site.admin.players.legacy": { - "message": "Legacy adapted" - }, - "app.skin-site.admin.players.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.players.mojang": { - "message": "Mojang" - }, - "app.skin-site.admin.players.name": { - "message": "Name" - }, - "app.skin-site.admin.players.next": { - "message": "Next" - }, - "app.skin-site.admin.players.owner": { - "message": "Owner" - }, - "app.skin-site.admin.players.page": { - "message": "Page {page}" - }, - "app.skin-site.admin.players.prev": { - "message": "Previous" - }, - "app.skin-site.admin.players.remove": { - "message": "Delete" - }, - "app.skin-site.admin.players.save": { - "message": "Save" - }, - "app.skin-site.admin.players.search": { - "message": "Search" - }, - "app.skin-site.admin.players.search-name": { - "message": "Name" - }, - "app.skin-site.admin.players.search-owner": { - "message": "Owner" - }, - "app.skin-site.admin.players.search-uuid": { - "message": "UUID" - }, - "app.skin-site.admin.players.source": { - "message": "Source" - }, - "app.skin-site.admin.players.title": { - "message": "Players" - }, - "app.skin-site.admin.players.total": { - "message": "{count} players" - }, - "app.skin-site.admin.players.updated": { - "message": "Player updated." - }, - "app.skin-site.admin.review.accept": { - "message": "Accept" - }, - "app.skin-site.admin.review.accept-done": { - "message": "Submission accepted." - }, - "app.skin-site.admin.review.activity": { - "message": "Activity" - }, - "app.skin-site.admin.review.add-option": { - "message": "Add option" - }, - "app.skin-site.admin.review.add-question": { - "message": "Add question" - }, - "app.skin-site.admin.review.answers": { - "message": "Answers" - }, - "app.skin-site.admin.review.applicant": { - "message": "Applicant" - }, - "app.skin-site.admin.review.auto-checks": { - "message": "Automatic checks" - }, - "app.skin-site.admin.review.context": { - "message": "Submission context" - }, - "app.skin-site.admin.review.copy-link": { - "message": "Copy link" - }, - "app.skin-site.admin.review.details": { - "message": "Details" - }, - "app.skin-site.admin.review.duration": { - "message": "Duration" - }, - "app.skin-site.admin.review.edit-paper": { - "message": "Edit" - }, - "app.skin-site.admin.review.empty": { - "message": "No submissions found." - }, - "app.skin-site.admin.review.failed": { - "message": "Could not load submissions." - }, - "app.skin-site.admin.review.filter-all": { - "message": "All" - }, - "app.skin-site.admin.review.filter-passed": { - "message": "Passed" - }, - "app.skin-site.admin.review.filter-pending": { - "message": "Pending" - }, - "app.skin-site.admin.review.filter-rejected": { - "message": "Rejected" - }, - "app.skin-site.admin.review.hidden-time": { - "message": "Hidden time" - }, - "app.skin-site.admin.review.hide": { - "message": "Hide" - }, - "app.skin-site.admin.review.history": { - "message": "Decision history" - }, - "app.skin-site.admin.review.invite-not-sent": { - "message": "Email not sent." - }, - "app.skin-site.admin.review.invite-regenerated": { - "message": "Invite code regenerated." - }, - "app.skin-site.admin.review.invite-sent": { - "message": "Email sent." - }, - "app.skin-site.admin.review.ip": { - "message": "IP" - }, - "app.skin-site.admin.review.link-copied": { - "message": "Link copied." - }, - "app.skin-site.admin.review.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.review.mail-enabled": { - "message": "Send mail on pass" - }, - "app.skin-site.admin.review.mail-extra": { - "message": "Extra text" - }, - "app.skin-site.admin.review.mail-include-invite": { - "message": "Include invite code" - }, - "app.skin-site.admin.review.mail-message": { - "message": "Body" - }, - "app.skin-site.admin.review.mail-message-required": { - "message": "Body is required when mail is enabled." - }, - "app.skin-site.admin.review.mail-subject": { - "message": "Subject" - }, - "app.skin-site.admin.review.mail-subject-required": { - "message": "Subject is required when mail is enabled." - }, - "app.skin-site.admin.review.mail-title": { - "message": "Pass mail" - }, - "app.skin-site.admin.review.mode-auto": { - "message": "Auto" - }, - "app.skin-site.admin.review.mode-manual": { - "message": "Manual" - }, - "app.skin-site.admin.review.move-down": { - "message": "Move down" - }, - "app.skin-site.admin.review.move-up": { - "message": "Move up" - }, - "app.skin-site.admin.review.new-paper": { - "message": "New paper" - }, - "app.skin-site.admin.review.next": { - "message": "Next" - }, - "app.skin-site.admin.review.no-answers": { - "message": "No answers." - }, - "app.skin-site.admin.review.option-correct": { - "message": "Correct" - }, - "app.skin-site.admin.review.option-description": { - "message": "Option text" - }, - "app.skin-site.admin.review.page": { - "message": "Page {page}" - }, - "app.skin-site.admin.review.paper-annotation": { - "message": "Description" - }, - "app.skin-site.admin.review.paper-created": { - "message": "Paper created." - }, - "app.skin-site.admin.review.paper-enabled": { - "message": "Enabled" - }, - "app.skin-site.admin.review.paper-mode": { - "message": "Mode" - }, - "app.skin-site.admin.review.paper-pass-score": { - "message": "Pass score" - }, - "app.skin-site.admin.review.paper-questions": { - "message": "Questions" - }, - "app.skin-site.admin.review.paper-saved": { - "message": "Paper saved." - }, - "app.skin-site.admin.review.paper-target-permissions": { - "message": "Target permissions" - }, - "app.skin-site.admin.review.paper-title": { - "message": "Title" - }, - "app.skin-site.admin.review.papers-empty": { - "message": "No review papers yet." - }, - "app.skin-site.admin.review.prev": { - "message": "Previous" - }, - "app.skin-site.admin.review.prevent-duplicate": { - "message": "Reject duplicate submissions" - }, - "app.skin-site.admin.review.question-annotation": { - "message": "Annotation" - }, - "app.skin-site.admin.review.question-no": { - "message": "Question {n}" - }, - "app.skin-site.admin.review.question-score": { - "message": "Score" - }, - "app.skin-site.admin.review.question-title": { - "message": "Question title" - }, - "app.skin-site.admin.review.question-type": { - "message": "Type" - }, - "app.skin-site.admin.review.reason": { - "message": "Reason" - }, - "app.skin-site.admin.review.regen-invite": { - "message": "Regenerate invite" - }, - "app.skin-site.admin.review.reject": { - "message": "Reject" - }, - "app.skin-site.admin.review.reject-done": { - "message": "Submission rejected." - }, - "app.skin-site.admin.review.remove-question": { - "message": "Remove" - }, - "app.skin-site.admin.review.result-passed": { - "message": "Passed" - }, - "app.skin-site.admin.review.result-pending": { - "message": "Pending" - }, - "app.skin-site.admin.review.result-rejected": { - "message": "Rejected" - }, - "app.skin-site.admin.review.reviewer": { - "message": "Reviewer" - }, - "app.skin-site.admin.review.score": { - "message": "Score" - }, - "app.skin-site.admin.review.screen-switches": { - "message": "Screen switches" - }, - "app.skin-site.admin.review.submitted-at": { - "message": "Submitted" - }, - "app.skin-site.admin.review.tab-list": { - "message": "Submissions" - }, - "app.skin-site.admin.review.tab-papers": { - "message": "Papers" - }, - "app.skin-site.admin.review.title": { - "message": "Player review" - }, - "app.skin-site.admin.review.total": { - "message": "{count} submissions" - }, - "app.skin-site.admin.review.user-agent": { - "message": "User agent" - }, - "app.skin-site.admin.servers.add-map": { - "message": "Add map" - }, - "app.skin-site.admin.servers.add-server": { - "message": "Add server" - }, - "app.skin-site.admin.servers.empty": { - "message": "No map servers configured." - }, - "app.skin-site.admin.servers.failed": { - "message": "Could not load servers." - }, - "app.skin-site.admin.servers.internal": { - "message": "Internal" - }, - "app.skin-site.admin.servers.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.servers.map-name": { - "message": "Map name" - }, - "app.skin-site.admin.servers.map-url": { - "message": "Map URL" - }, - "app.skin-site.admin.servers.maps": { - "message": "Maps" - }, - "app.skin-site.admin.servers.remove-map": { - "message": "Remove" - }, - "app.skin-site.admin.servers.remove-server": { - "message": "Remove server" - }, - "app.skin-site.admin.servers.save": { - "message": "Save changes" - }, - "app.skin-site.admin.servers.saved": { - "message": "Map servers saved." - }, - "app.skin-site.admin.servers.saving": { - "message": "Saving…" - }, - "app.skin-site.admin.servers.server-name": { - "message": "Server name" - }, - "app.skin-site.admin.servers.title": { - "message": "Map servers" - }, - "app.skin-site.admin.summary.failed": { - "message": "Could not load status." - }, - "app.skin-site.admin.summary.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.summary.memory": { - "message": "Memory usage" - }, - "app.skin-site.admin.summary.players": { - "message": "Players" - }, - "app.skin-site.admin.summary.realtime-hint": { - "message": "Live CPU and GC charts require the admin WebSocket, which is not connected yet." - }, - "app.skin-site.admin.summary.title": { - "message": "System overview" - }, - "app.skin-site.admin.summary.uptime": { - "message": "Uptime" - }, - "app.skin-site.admin.summary.users": { - "message": "Users" - }, - "app.skin-site.admin.title": { - "message": "Admin console" - }, - "app.skin-site.admin.users.actions": { - "message": "Actions" - }, - "app.skin-site.admin.users.audit": { - "message": "Audit" - }, - "app.skin-site.admin.users.audit-empty": { - "message": "No audit records yet." - }, - "app.skin-site.admin.users.audit-more": { - "message": "Load earlier" - }, - "app.skin-site.admin.users.audit-title": { - "message": "User management audit" - }, - "app.skin-site.admin.users.banned": { - "message": "Banned" - }, - "app.skin-site.admin.users.bot": { - "message": "Bot" - }, - "app.skin-site.admin.users.bot-active": { - "message": "Token valid" - }, - "app.skin-site.admin.users.bot-ban": { - "message": "Ban bot creation" - }, - "app.skin-site.admin.users.bot-creation-banned": { - "message": "Token creation banned" - }, - "app.skin-site.admin.users.bot-exists": { - "message": "Bot created" - }, - "app.skin-site.admin.users.bot-inactive": { - "message": "Token invalidated" - }, - "app.skin-site.admin.users.bot-invalidate": { - "message": "Invalidate token" - }, - "app.skin-site.admin.users.bot-not-exists": { - "message": "No bot yet" - }, - "app.skin-site.admin.users.bot-save-username": { - "message": "Save bot username" - }, - "app.skin-site.admin.users.bot-title": { - "message": "Bot management" - }, - "app.skin-site.admin.users.bot-token-hint": { - "message": "Token hint" - }, - "app.skin-site.admin.users.bot-unban": { - "message": "Unban bot creation" - }, - "app.skin-site.admin.users.bot-username": { - "message": "Bot username" - }, - "app.skin-site.admin.users.bound-players-title": { - "message": "Linked players" - }, - "app.skin-site.admin.users.cancel": { - "message": "Cancel" - }, - "app.skin-site.admin.users.confirm-delete": { - "message": "Delete user “{name}”? This cannot be undone." - }, - "app.skin-site.admin.users.deleted": { - "message": "User deleted." - }, - "app.skin-site.admin.users.edit": { - "message": "Edit" - }, - "app.skin-site.admin.users.email": { - "message": "Email" - }, - "app.skin-site.admin.users.empty": { - "message": "No users found." - }, - "app.skin-site.admin.users.failed": { - "message": "Could not load users." - }, - "app.skin-site.admin.users.frequency": { - "message": "Rate limit" - }, - "app.skin-site.admin.users.frequency-clear": { - "message": "Clear limit" - }, - "app.skin-site.admin.users.frequency-current": { - "message": "Currently {percent}%" - }, - "app.skin-site.admin.users.frequency-hint": { - "message": "Packets from this user will be dropped at the given rate." - }, - "app.skin-site.admin.users.frequency-none": { - "message": "Not enabled" - }, - "app.skin-site.admin.users.frequency-range": { - "message": "Only integer values from 10% to 100% are allowed." - }, - "app.skin-site.admin.users.frequency-save": { - "message": "Save limit" - }, - "app.skin-site.admin.users.frequency-title": { - "message": "Rate limit" - }, - "app.skin-site.admin.users.invite": { - "message": "Invite user" - }, - "app.skin-site.admin.users.invite-copied": { - "message": "Invite code copied." - }, - "app.skin-site.admin.users.invite-copy": { - "message": "Copy" - }, - "app.skin-site.admin.users.invite-email": { - "message": "Email" - }, - "app.skin-site.admin.users.invite-email-invalid": { - "message": "Enter a valid email address." - }, - "app.skin-site.admin.users.invite-generate": { - "message": "Generate invite code" - }, - "app.skin-site.admin.users.invite-title": { - "message": "Invite user" - }, - "app.skin-site.admin.users.legacy-adapted": { - "message": "Legacy internal adapted" - }, - "app.skin-site.admin.users.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.users.next": { - "message": "Next" - }, - "app.skin-site.admin.users.no-players": { - "message": "No linked players." - }, - "app.skin-site.admin.users.page": { - "message": "Page {page}" - }, - "app.skin-site.admin.users.password": { - "message": "New password" - }, - "app.skin-site.admin.users.password-hint": { - "message": "Leave empty to keep the current password." - }, - "app.skin-site.admin.users.permissions": { - "message": "Permissions" - }, - "app.skin-site.admin.users.permissions-hint": { - "message": "Comma separated, e.g. WEB_ADMIN, SERVER_ADMIN." - }, - "app.skin-site.admin.users.players": { - "message": "Players" - }, - "app.skin-site.admin.users.prev": { - "message": "Previous" - }, - "app.skin-site.admin.users.qq": { - "message": "QQ" - }, - "app.skin-site.admin.users.registered": { - "message": "Registered" - }, - "app.skin-site.admin.users.registered-at": { - "message": "Registered at" - }, - "app.skin-site.admin.users.remove": { - "message": "Delete" - }, - "app.skin-site.admin.users.save": { - "message": "Save" - }, - "app.skin-site.admin.users.search": { - "message": "Search" - }, - "app.skin-site.admin.users.search-email": { - "message": "Email" - }, - "app.skin-site.admin.users.search-name": { - "message": "Username" - }, - "app.skin-site.admin.users.search-uuid": { - "message": "UUID" - }, - "app.skin-site.admin.users.status": { - "message": "Status" - }, - "app.skin-site.admin.users.status-banned": { - "message": "Banned" - }, - "app.skin-site.admin.users.status-normal": { - "message": "Normal" - }, - "app.skin-site.admin.users.title": { - "message": "Users" - }, - "app.skin-site.admin.users.total": { - "message": "{count} users" - }, - "app.skin-site.admin.users.updated": { - "message": "User updated." - }, - "app.skin-site.admin.users.username": { - "message": "Username" - }, - "app.skin-site.admin.wiki.allow-private": { - "message": "Allow private network source" - }, - "app.skin-site.admin.wiki.allow-private-hint": { - "message": "Private sources may reach services inside the server network." - }, - "app.skin-site.admin.wiki.api-url": { - "message": "api.php URL" - }, - "app.skin-site.admin.wiki.audit-empty": { - "message": "No audit entries." - }, - "app.skin-site.admin.wiki.audit-target": { - "message": "Target" - }, - "app.skin-site.admin.wiki.author": { - "message": "Author" - }, - "app.skin-site.admin.wiki.auto-title": { - "message": "Read from MediaWiki API" - }, - "app.skin-site.admin.wiki.bot-password": { - "message": "Bot password (optional)" - }, - "app.skin-site.admin.wiki.bot-username": { - "message": "Bot username (optional)" - }, - "app.skin-site.admin.wiki.candidates": { - "message": "Candidate pages" - }, - "app.skin-site.admin.wiki.candidates-empty": { - "message": "Select a job to review its pages." - }, - "app.skin-site.admin.wiki.categories": { - "message": "Categories" - }, - "app.skin-site.admin.wiki.confirm-delete-job": { - "message": "Delete migration job #{id}? This cannot be undone." - }, - "app.skin-site.admin.wiki.confirm-rollback": { - "message": "Roll back this migration batch? Published pages will be reverted." - }, - "app.skin-site.admin.wiki.conflict": { - "message": "Title conflict" - }, - "app.skin-site.admin.wiki.credentials-hint": { - "message": "Credentials stay in memory for this job only. HTTPS is required when supplied." - }, - "app.skin-site.admin.wiki.decision-exclude": { - "message": "Exclude" - }, - "app.skin-site.admin.wiki.decision-import": { - "message": "Import" - }, - "app.skin-site.admin.wiki.decision-pending": { - "message": "Pending" - }, - "app.skin-site.admin.wiki.default-skin": { - "message": "Default skin" - }, - "app.skin-site.admin.wiki.delete-job": { - "message": "Delete job record" - }, - "app.skin-site.admin.wiki.deleted-updated": { - "message": "Page deletion state updated." - }, - "app.skin-site.admin.wiki.domains": { - "message": "Domains" - }, - "app.skin-site.admin.wiki.edit-policy": { - "message": "Edit policy" - }, - "app.skin-site.admin.wiki.exclude": { - "message": "Exclude" - }, - "app.skin-site.admin.wiki.home-page": { - "message": "Home page" - }, - "app.skin-site.admin.wiki.home-set": { - "message": "Home page updated." - }, - "app.skin-site.admin.wiki.import": { - "message": "Import" - }, - "app.skin-site.admin.wiki.imported-excluded": { - "message": "Imported {imported} · Excluded {excluded}" - }, - "app.skin-site.admin.wiki.job-deleted": { - "message": "Migration record deleted." - }, - "app.skin-site.admin.wiki.jobs": { - "message": "Migration jobs" - }, - "app.skin-site.admin.wiki.jobs-empty": { - "message": "No migration jobs yet." - }, - "app.skin-site.admin.wiki.last-updated": { - "message": "Updated {date}" - }, - "app.skin-site.admin.wiki.load-more": { - "message": "Load more" - }, - "app.skin-site.admin.wiki.load-page": { - "message": "Load page" - }, - "app.skin-site.admin.wiki.loading": { - "message": "Loading…" - }, - "app.skin-site.admin.wiki.maintainer-count": { - "message": "{count} maintainers" - }, - "app.skin-site.admin.wiki.maintainer-window": { - "message": "Maintainer window (days)" - }, - "app.skin-site.admin.wiki.max-attachment-bytes": { - "message": "Max attachment bytes" - }, - "app.skin-site.admin.wiki.max-maintainers": { - "message": "Max maintainers" - }, - "app.skin-site.admin.wiki.max-page-bytes": { - "message": "Max page bytes" - }, - "app.skin-site.admin.wiki.migration-hint": { - "message": "Migrated content lands in a hidden staging area and is published in one batch after every page is reviewed." - }, - "app.skin-site.admin.wiki.migration-started": { - "message": "Migration job created." - }, - "app.skin-site.admin.wiki.migration-title": { - "message": "MediaWiki migration" - }, - "app.skin-site.admin.wiki.overwrite": { - "message": "Overwrite" - }, - "app.skin-site.admin.wiki.page-not-found": { - "message": "Page not found." - }, - "app.skin-site.admin.wiki.page-path": { - "message": "Page path" - }, - "app.skin-site.admin.wiki.policy-admin": { - "message": "Website administrators" - }, - "app.skin-site.admin.wiki.policy-member": { - "message": "Members" - }, - "app.skin-site.admin.wiki.policy-public": { - "message": "Everyone" - }, - "app.skin-site.admin.wiki.protect-saved": { - "message": "Page policies updated." - }, - "app.skin-site.admin.wiki.publish": { - "message": "Publish batch" - }, - "app.skin-site.admin.wiki.published": { - "message": "Published {imported} pages, overwrote {overwritten}." - }, - "app.skin-site.admin.wiki.read-policy": { - "message": "Read policy" - }, - "app.skin-site.admin.wiki.refresh-jobs": { - "message": "Refresh" - }, - "app.skin-site.admin.wiki.reviewed-count": { - "message": "Reviewed {reviewed} / {total}" - }, - "app.skin-site.admin.wiki.revision": { - "message": "Revision" - }, - "app.skin-site.admin.wiki.rollback": { - "message": "Roll back" - }, - "app.skin-site.admin.wiki.rolled-back": { - "message": "Migration batch rolled back." - }, - "app.skin-site.admin.wiki.save-protect": { - "message": "Save policies" - }, - "app.skin-site.admin.wiki.save-settings": { - "message": "Save settings" - }, - "app.skin-site.admin.wiki.select-xml": { - "message": "Choose a MediaWiki XML file first." - }, - "app.skin-site.admin.wiki.set-deleted": { - "message": "Mark as deleted" - }, - "app.skin-site.admin.wiki.set-home": { - "message": "Set as home page" - }, - "app.skin-site.admin.wiki.set-restored": { - "message": "Restore page" - }, - "app.skin-site.admin.wiki.settings-hint": { - "message": "Comma separated domains." - }, - "app.skin-site.admin.wiki.settings-saved": { - "message": "Settings saved." - }, - "app.skin-site.admin.wiki.stale-days": { - "message": "Days without update" - }, - "app.skin-site.admin.wiki.stale-markers": { - "message": "Stale categories, templates or text" - }, - "app.skin-site.admin.wiki.stale-markers-hint": { - "message": "Comma separated" - }, - "app.skin-site.admin.wiki.stale-rules": { - "message": "Stale page detection rules" - }, - "app.skin-site.admin.wiki.start-auto": { - "message": "Create automatic migration job" - }, - "app.skin-site.admin.wiki.start-xml": { - "message": "Upload and stage" - }, - "app.skin-site.admin.wiki.state-failed": { - "message": "Failed" - }, - "app.skin-site.admin.wiki.state-importing": { - "message": "Importing" - }, - "app.skin-site.admin.wiki.state-published": { - "message": "Published" - }, - "app.skin-site.admin.wiki.state-publishing": { - "message": "Publishing" - }, - "app.skin-site.admin.wiki.state-review": { - "message": "Waiting review" - }, - "app.skin-site.admin.wiki.state-rolled-back": { - "message": "Rolled back" - }, - "app.skin-site.admin.wiki.tab-audit": { - "message": "Audit log" - }, - "app.skin-site.admin.wiki.tab-migration": { - "message": "Migration" - }, - "app.skin-site.admin.wiki.tab-page": { - "message": "Page" - }, - "app.skin-site.admin.wiki.tab-settings": { - "message": "Settings" - }, - "app.skin-site.admin.wiki.target-title": { - "message": "Target title" - }, - "app.skin-site.admin.wiki.title": { - "message": "Wiki" - }, - "app.skin-site.admin.wiki.updated-at": { - "message": "Updated" - }, - "app.skin-site.admin.wiki.view-job": { - "message": "View job" - }, - "app.skin-site.admin.wiki.xml-file": { - "message": "Export file" - }, - "app.skin-site.admin.wiki.xml-staged": { - "message": "XML parsed and staged for review." - }, - "app.skin-site.admin.wiki.xml-title": { - "message": "Import MediaWiki XML" - }, - "app.skin-site.bug-create.cancel": { - "message": "Cancel" - }, - "app.skin-site.bug-create.created": { - "message": "Issue created." - }, - "app.skin-site.bug-create.description": { - "message": "Description" - }, - "app.skin-site.bug-create.description-placeholder": { - "message": "What happened, and how can it be reproduced?" - }, - "app.skin-site.bug-create.images": { - "message": "Images" - }, - "app.skin-site.bug-create.images-hint": { - "message": "Optional, up to 5 images." - }, - "app.skin-site.bug-create.private": { - "message": "Private issue" - }, - "app.skin-site.bug-create.private-hint": { - "message": "Only you and the maintainers can see it." - }, - "app.skin-site.bug-create.submit": { - "message": "Create issue" - }, - "app.skin-site.bug-create.submitting": { - "message": "Creating…" - }, - "app.skin-site.bug-create.title": { - "message": "New issue" - }, - "app.skin-site.bug-create.title-field": { - "message": "Title" - }, - "app.skin-site.bug-create.title-placeholder": { - "message": "A short summary of the problem" - }, - "app.skin-site.bug-create.type": { - "message": "Type" - }, - "app.skin-site.bug-detail.assignee": { - "message": "Assignee: {name}" - }, - "app.skin-site.bug-detail.back": { - "message": "Back to list" - }, - "app.skin-site.bug-detail.by": { - "message": "by {name}" - }, - "app.skin-site.bug-detail.comment-deleted": { - "message": "Comment deleted." - }, - "app.skin-site.bug-detail.comment-empty-error": { - "message": "Comment cannot be empty." - }, - "app.skin-site.bug-detail.comment-placeholder": { - "message": "Write a comment…" - }, - "app.skin-site.bug-detail.comment-posted": { - "message": "Comment posted." - }, - "app.skin-site.bug-detail.comment-sending": { - "message": "Sending…" - }, - "app.skin-site.bug-detail.comment-submit": { - "message": "Comment" - }, - "app.skin-site.bug-detail.comments-empty": { - "message": "No comments yet. Be the first to reply." - }, - "app.skin-site.bug-detail.comments-loading": { - "message": "Loading comments…" - }, - "app.skin-site.bug-detail.comments-title": { - "message": "Comments" - }, - "app.skin-site.bug-detail.delete": { - "message": "Delete" - }, - "app.skin-site.bug-detail.deleting": { - "message": "Deleting…" - }, - "app.skin-site.bug-detail.description-empty": { - "message": "No description provided." - }, - "app.skin-site.bug-detail.failed": { - "message": "Could not load this issue." - }, - "app.skin-site.bug-detail.issue-no": { - "message": "Issue #{id}" - }, - "app.skin-site.bug-detail.loading": { - "message": "Loading…" - }, - "app.skin-site.bug-detail.resolution": { - "message": "Resolution: {name}" - }, - "app.skin-site.bug-detail.system": { - "message": "System" - }, - "app.skin-site.bug-detail.unassigned": { - "message": "Unassigned" - }, - "app.skin-site.bug-notifications.back": { - "message": "Back to home" - }, - "app.skin-site.bug-notifications.empty": { - "message": "No new notifications." - }, - "app.skin-site.bug-notifications.failed": { - "message": "Could not load notifications." - }, - "app.skin-site.bug-notifications.item": { - "message": "{name} updated issue #{id}" - }, - "app.skin-site.bug-notifications.loading": { - "message": "Loading…" - }, - "app.skin-site.bug-notifications.mark-all": { - "message": "Mark all as read" - }, - "app.skin-site.bug-notifications.marked-all": { - "message": "All notifications marked as read." - }, - "app.skin-site.bug-notifications.subtitle": { - "message": "Activity on issues you reported or follow." - }, - "app.skin-site.bug-notifications.title": { - "message": "Notifications" - }, - "app.skin-site.bugs.all": { - "message": "All" - }, - "app.skin-site.bugs.back": { - "message": "Back to home" - }, - "app.skin-site.bugs.comments": { - "message": "{count} comments" - }, - "app.skin-site.bugs.create": { - "message": "New issue" - }, - "app.skin-site.bugs.empty": { - "message": "No issues match these filters." - }, - "app.skin-site.bugs.failed": { - "message": "Could not load issues." - }, - "app.skin-site.bugs.loading": { - "message": "Loading…" - }, - "app.skin-site.bugs.more": { - "message": "Load more" - }, - "app.skin-site.bugs.notifications": { - "message": "Notifications" - }, - "app.skin-site.bugs.open-only": { - "message": "Open only" - }, - "app.skin-site.bugs.priority.critical": { - "message": "Critical" - }, - "app.skin-site.bugs.priority.high": { - "message": "High" - }, - "app.skin-site.bugs.priority.low": { - "message": "Low" - }, - "app.skin-site.bugs.priority.normal": { - "message": "Normal" - }, - "app.skin-site.bugs.resolution.by-design": { - "message": "By design" - }, - "app.skin-site.bugs.resolution.cannot-reproduce": { - "message": "Cannot reproduce" - }, - "app.skin-site.bugs.resolution.duplicate": { - "message": "Duplicate" - }, - "app.skin-site.bugs.resolution.fixed": { - "message": "Fixed" - }, - "app.skin-site.bugs.resolution.invalid": { - "message": "Invalid" - }, - "app.skin-site.bugs.resolution.wont-fix": { - "message": "Won’t fix" - }, - "app.skin-site.bugs.status.closed": { - "message": "Closed" - }, - "app.skin-site.bugs.status.confirmed": { - "message": "Confirmed" - }, - "app.skin-site.bugs.status.in-progress": { - "message": "In progress" - }, - "app.skin-site.bugs.status.needs-info": { - "message": "Needs info" - }, - "app.skin-site.bugs.status.pending": { - "message": "Pending" - }, - "app.skin-site.bugs.status.verifying": { - "message": "Verifying" - }, - "app.skin-site.bugs.subtitle": { - "message": "Report issues and follow their progress." - }, - "app.skin-site.bugs.title": { - "message": "Bugs & suggestions" - }, - "app.skin-site.bugs.type.bug": { - "message": "Bug" - }, - "app.skin-site.bugs.type.feature": { - "message": "Feature" - }, - "app.skin-site.bugs.type.improvement": { - "message": "Improvement" - }, - "app.skin-site.captcha.loading": { - "message": "Loading captcha…" - }, - "app.skin-site.captcha.submit": { - "message": "Submit" - }, - "app.skin-site.captcha.subtitle": { - "message": "Drag the slider to rotate the image upright." - }, - "app.skin-site.captcha.title": { - "message": "Let us check you are human" - }, - "app.skin-site.chat.admin.audit": { - "message": "Audit" - }, - "app.skin-site.chat.admin.audit-empty": { - "message": "No audit records yet." - }, - "app.skin-site.chat.admin.audit-target": { - "message": "Target: {name}" - }, - "app.skin-site.chat.admin.audit-title": { - "message": "Room audit" - }, - "app.skin-site.chat.admin.cancel": { - "message": "Cancel" - }, - "app.skin-site.chat.admin.close": { - "message": "Close" - }, - "app.skin-site.chat.admin.confirm-delete": { - "message": "Permanently delete room “{name}” and all its messages?" - }, - "app.skin-site.chat.admin.create-room": { - "message": "Create room" - }, - "app.skin-site.chat.admin.created": { - "message": "Room created." - }, - "app.skin-site.chat.admin.deleted": { - "message": "Room deleted." - }, - "app.skin-site.chat.admin.description": { - "message": "Description" - }, - "app.skin-site.chat.admin.edit": { - "message": "Edit" - }, - "app.skin-site.chat.admin.empty": { - "message": "No chat rooms yet." - }, - "app.skin-site.chat.admin.failed": { - "message": "Could not load rooms." - }, - "app.skin-site.chat.admin.grant": { - "message": "Grant" - }, - "app.skin-site.chat.admin.kind": { - "message": "Kind" - }, - "app.skin-site.chat.admin.kind-settlement": { - "message": "Settlement" - }, - "app.skin-site.chat.admin.kind-standard": { - "message": "Standard" - }, - "app.skin-site.chat.admin.listener-limit": { - "message": "Listener limit" - }, - "app.skin-site.chat.admin.loading": { - "message": "Loading…" - }, - "app.skin-site.chat.admin.manager-badge": { - "message": "Manager" - }, - "app.skin-site.chat.admin.manager-granted": { - "message": "Manager granted." - }, - "app.skin-site.chat.admin.manager-hint": { - "message": "Managers can moderate members, messages and files in this room." - }, - "app.skin-site.chat.admin.manager-revoked": { - "message": "Manager revoked." - }, - "app.skin-site.chat.admin.manager-title": { - "message": "Room manager" - }, - "app.skin-site.chat.admin.managers": { - "message": "Managers" - }, - "app.skin-site.chat.admin.name": { - "message": "Name" - }, - "app.skin-site.chat.admin.owner-assigned": { - "message": "Settlement owner assigned." - }, - "app.skin-site.chat.admin.owner-current": { - "message": "Current owner: {name}" - }, - "app.skin-site.chat.admin.owner-hint": { - "message": "Assign the first settlement owner for this room." - }, - "app.skin-site.chat.admin.owner-none": { - "message": "No settlement owner yet." - }, - "app.skin-site.chat.admin.owner-title": { - "message": "Settlement owner" - }, - "app.skin-site.chat.admin.participant-limit": { - "message": "Participant limit" - }, - "app.skin-site.chat.admin.prerequisite-all": { - "message": "All" - }, - "app.skin-site.chat.admin.prerequisite-any": { - "message": "Any" - }, - "app.skin-site.chat.admin.prerequisite-hint": { - "message": "Comma separated. Leave empty for no restriction." - }, - "app.skin-site.chat.admin.prerequisite-mode": { - "message": "Prerequisite mode" - }, - "app.skin-site.chat.admin.prerequisite-permissions": { - "message": "Required permissions" - }, - "app.skin-site.chat.admin.remove": { - "message": "Delete" - }, - "app.skin-site.chat.admin.revoke": { - "message": "Revoke" - }, - "app.skin-site.chat.admin.save": { - "message": "Save" - }, - "app.skin-site.chat.admin.subtitle": { - "message": "Create public or private rooms and hand daily moderation to trusted members." - }, - "app.skin-site.chat.admin.title": { - "message": "Chat rooms" - }, - "app.skin-site.chat.admin.updated": { - "message": "Room updated." - }, - "app.skin-site.chat.admin.visibility": { - "message": "Visibility" - }, - "app.skin-site.chat.admin.visibility-private": { - "message": "Private" - }, - "app.skin-site.chat.admin.visibility-public": { - "message": "Public" - }, - "app.skin-site.chat.admin.voice-badge": { - "message": "Voice" - }, - "app.skin-site.chat.admin.voice-bind": { - "message": "Bind address" - }, - "app.skin-site.chat.admin.voice-capacity": { - "message": "Voice capacity" - }, - "app.skin-site.chat.admin.voice-capacity-title": { - "message": "Voice capacity" - }, - "app.skin-site.chat.admin.voice-capacity-updated": { - "message": "Voice capacity updated." - }, - "app.skin-site.chat.admin.voice-config": { - "message": "Configure runtime" - }, - "app.skin-site.chat.admin.voice-config-title": { - "message": "Voice runtime configuration" - }, - "app.skin-site.chat.admin.voice-enabled": { - "message": "Enable realtime voice" - }, - "app.skin-site.chat.admin.voice-logs": { - "message": "View logs" - }, - "app.skin-site.chat.admin.voice-logs-auto-refresh": { - "message": "Auto refresh" - }, - "app.skin-site.chat.admin.voice-logs-empty": { - "message": "No logs yet." - }, - "app.skin-site.chat.admin.voice-logs-refresh": { - "message": "Refresh" - }, - "app.skin-site.chat.admin.voice-logs-title": { - "message": "LiveKit logs" - }, - "app.skin-site.chat.admin.voice-mirror": { - "message": "Mirror base URL" - }, - "app.skin-site.chat.admin.voice-node-ip": { - "message": "Node IP" - }, - "app.skin-site.chat.admin.voice-public-url": { - "message": "Public URL" - }, - "app.skin-site.chat.admin.voice-retry": { - "message": "Retry deployment" - }, - "app.skin-site.chat.admin.voice-rtc-tcp-port": { - "message": "Media TCP port" - }, - "app.skin-site.chat.admin.voice-rtc-udp-port": { - "message": "Media UDP port" - }, - "app.skin-site.chat.admin.voice-runtime-path": { - "message": "Runtime directory" - }, - "app.skin-site.chat.admin.voice-runtime-title": { - "message": "Realtime voice runtime" - }, - "app.skin-site.chat.admin.voice-saved": { - "message": "Voice configuration saved." - }, - "app.skin-site.chat.admin.voice-signal-port": { - "message": "Signal port" - }, - "app.skin-site.chat.admin.voice-startup-timeout": { - "message": "Startup timeout (s)" - }, - "app.skin-site.chat.admin.voice-use-external-ip": { - "message": "Use external IP" - }, - "app.skin-site.chat.avatar.bad-format": { - "message": "Only PNG, JPEG and WebP are supported." - }, - "app.skin-site.chat.avatar.hint": { - "message": "PNG, JPEG or WebP, up to 8192 px per side and 5 MB." - }, - "app.skin-site.chat.avatar.label": { - "message": "Room avatar" - }, - "app.skin-site.chat.avatar.not-image": { - "message": "Avatar must be an image." - }, - "app.skin-site.chat.avatar.remove": { - "message": "Remove avatar" - }, - "app.skin-site.chat.avatar.replace": { - "message": "Replace avatar" - }, - "app.skin-site.chat.avatar.too-large": { - "message": "Avatar must not exceed 5 MB." - }, - "app.skin-site.chat.avatar.upload": { - "message": "Upload avatar" - }, - "app.skin-site.chat.listener-limit": { - "message": "Listener limit" - }, - "app.skin-site.chat.participant-limit": { - "message": "Participant limit" - }, - "app.skin-site.chat.user-picker.active-status": { - "message": "Active" - }, - "app.skin-site.chat.user-picker.already-in": { - "message": "This user is already in the room." - }, - "app.skin-site.chat.user-picker.banned": { - "message": "This account is banned." - }, - "app.skin-site.chat.user-picker.banned-status": { - "message": "Banned" - }, - "app.skin-site.chat.user-picker.by-player": { - "message": "By player" - }, - "app.skin-site.chat.user-picker.by-user": { - "message": "By user" - }, - "app.skin-site.chat.user-picker.email": { - "message": "Email" - }, - "app.skin-site.chat.user-picker.empty": { - "message": "No matching user." - }, - "app.skin-site.chat.user-picker.guest": { - "message": "Guests cannot become a manager or settlement owner." - }, - "app.skin-site.chat.user-picker.hint": { - "message": "Fuzzy search on username and email, or search by account ID." - }, - "app.skin-site.chat.user-picker.id": { - "message": "ID" - }, - "app.skin-site.chat.user-picker.label": { - "message": "Pick a user" - }, - "app.skin-site.chat.user-picker.not-allowed": { - "message": "This user is outside the allowed range." - }, - "app.skin-site.chat.user-picker.placeholder": { - "message": "Search username, email or account ID" - }, - "app.skin-site.chat.user-picker.player-hint": { - "message": "Enter a player name to find the bound user." - }, - "app.skin-site.chat.user-picker.registered": { - "message": "Registered" - }, - "app.skin-site.chat.user-picker.select": { - "message": "Select" - }, - "app.skin-site.chat.user-picker.selected": { - "message": "Selected" - }, - "app.skin-site.chat.voice-bind": { - "message": "Bind address" - }, - "app.skin-site.chat.voice-capacity": { - "message": "Voice capacity" - }, - "app.skin-site.chat.voice-capacity-title": { - "message": "Voice capacity" - }, - "app.skin-site.chat.voice-capacity-updated": { - "message": "Voice capacity updated." - }, - "app.skin-site.chat.voice-config": { - "message": "Configure runtime" - }, - "app.skin-site.chat.voice-config-title": { - "message": "Voice runtime configuration" - }, - "app.skin-site.chat.voice-enabled": { - "message": "Enable realtime voice" - }, - "app.skin-site.chat.voice-logs": { - "message": "View logs" - }, - "app.skin-site.chat.voice-logs-auto-refresh": { - "message": "Auto refresh" - }, - "app.skin-site.chat.voice-logs-empty": { - "message": "No logs yet." - }, - "app.skin-site.chat.voice-logs-refresh": { - "message": "Refresh" - }, - "app.skin-site.chat.voice-logs-title": { - "message": "LiveKit logs" - }, - "app.skin-site.chat.voice-mirror": { - "message": "Mirror base URL" - }, - "app.skin-site.chat.voice-node-ip": { - "message": "Node IP" - }, - "app.skin-site.chat.voice-public-url": { - "message": "Public URL" - }, - "app.skin-site.chat.voice-retry": { - "message": "Retry deployment" - }, - "app.skin-site.chat.voice-rtc-tcp-port": { - "message": "Media TCP port" - }, - "app.skin-site.chat.voice-rtc-udp-port": { - "message": "Media UDP port" - }, - "app.skin-site.chat.voice-runtime-path": { - "message": "Runtime directory" - }, - "app.skin-site.chat.voice-runtime-title": { - "message": "Realtime voice runtime" - }, - "app.skin-site.chat.voice-saved": { - "message": "Voice configuration saved." - }, - "app.skin-site.chat.voice-signal-port": { - "message": "Signal port" - }, - "app.skin-site.chat.voice-startup-timeout": { - "message": "Startup timeout (s)" - }, - "app.skin-site.chat.voice-use-external-ip": { - "message": "Use external IP" - }, - "app.skin-site.downloads.all": { - "message": "All" - }, - "app.skin-site.downloads.back": { - "message": "Back to home" - }, - "app.skin-site.downloads.empty": { - "message": "Nothing to download yet." - }, - "app.skin-site.downloads.failed": { - "message": "Could not load downloads." - }, - "app.skin-site.downloads.go": { - "message": "Download" - }, - "app.skin-site.downloads.loading": { - "message": "Loading…" - }, - "app.skin-site.downloads.status.legacy": { - "message": "Legacy" - }, - "app.skin-site.downloads.status.new": { - "message": "New" - }, - "app.skin-site.downloads.status.ok": { - "message": "OK" - }, - "app.skin-site.downloads.status.outdated": { - "message": "Outdated" - }, - "app.skin-site.downloads.status.removal": { - "message": "Removal" - }, - "app.skin-site.downloads.subtitle": { - "message": "Files shared by the server. Pick a category to narrow the list." - }, - "app.skin-site.downloads.title": { - "message": "Downloads" - }, - "app.skin-site.downloads.uploader": { - "message": "by {name}" - }, - "app.skin-site.home.address": { - "message": "Skin site address" - }, - "app.skin-site.home.admin": { - "message": "Admin" - }, - "app.skin-site.home.announcements.empty": { - "message": "No announcements right now." - }, - "app.skin-site.home.announcements.failed": { - "message": "Could not load announcements." - }, - "app.skin-site.home.announcements.loading": { - "message": "Loading…" - }, - "app.skin-site.home.announcements.signed-out": { - "message": "Sign in to view announcements." - }, - "app.skin-site.home.announcements.title": { - "message": "Announcements" - }, - "app.skin-site.home.copied": { - "message": "Address copied." - }, - "app.skin-site.home.copy": { - "message": "Copy" - }, - "app.skin-site.home.donation.donors": { - "message": "{count} donors" - }, - "app.skin-site.home.donation.loading": { - "message": "Loading…" - }, - "app.skin-site.home.donation.title": { - "message": "Donation thanks" - }, - "app.skin-site.home.donation.total": { - "message": "Total raised" - }, - "app.skin-site.home.donation.unavailable": { - "message": "Donation summary unavailable." - }, - "app.skin-site.home.error": { - "message": "Could not load." - }, - "app.skin-site.home.loading": { - "message": "Loading…" - }, - "app.skin-site.home.luck": { - "message": "Luck" - }, - "app.skin-site.home.luck-unavailable": { - "message": "Unavailable" - }, - "app.skin-site.home.my-players": { - "message": "My players" - }, - "app.skin-site.home.nav.bugs": { - "message": "Bug tracker" - }, - "app.skin-site.home.nav.bugs-desc": { - "message": "Report issues and follow their progress." - }, - "app.skin-site.home.nav.download": { - "message": "Downloads" - }, - "app.skin-site.home.nav.download-desc": { - "message": "Browse files shared by the server." - }, - "app.skin-site.home.nav.map": { - "message": "Server map" - }, - "app.skin-site.home.nav.map-desc": { - "message": "Explore the live world map." - }, - "app.skin-site.home.nav.profile": { - "message": "Profile" - }, - "app.skin-site.home.nav.profile-desc": { - "message": "Manage your account and textures." - }, - "app.skin-site.home.nav.review": { - "message": "Player review" - }, - "app.skin-site.home.nav.review-desc": { - "message": "Submit and review player applications." - }, - "app.skin-site.home.nav.title": { - "message": "Skin site" - }, - "app.skin-site.home.nav.wiki": { - "message": "Server wiki" - }, - "app.skin-site.home.nav.wiki-desc": { - "message": "Guides and documentation for the server." - }, - "app.skin-site.home.no-players": { - "message": "No players linked yet." - }, - "app.skin-site.home.players": { - "message": "Players" - }, - "app.skin-site.home.settings": { - "message": "Account" - }, - "app.skin-site.home.sign-in": { - "message": "Sign in" - }, - "app.skin-site.home.signed-out-body": { - "message": "Sign in to manage your account and textures." - }, - "app.skin-site.home.signed-out-title": { - "message": "Not signed in" - }, - "app.skin-site.home.subtitle": { - "message": "The wardrobe for StarLight Server players." - }, - "app.skin-site.home.title": { - "message": "StarLight Skin Site" - }, - "app.skin-site.login.forgot": { - "message": "Forgot password?" - }, - "app.skin-site.login.password": { - "message": "Password" - }, - "app.skin-site.login.password-hint": { - "message": "6–50 characters with upper case, lower case and a digit." - }, - "app.skin-site.login.register": { - "message": "Create account" - }, - "app.skin-site.login.sign-in": { - "message": "Sign in" - }, - "app.skin-site.login.signing-in": { - "message": "Signing in…" - }, - "app.skin-site.login.success": { - "message": "Signed in to StarLight." - }, - "app.skin-site.login.title": { - "message": "Sign in to StarLight" - }, - "app.skin-site.login.username": { - "message": "Username or email" - }, - "app.skin-site.login.username-hint": { - "message": "3–16 characters, or a registered email address." - }, - "app.skin-site.map.back": { - "message": "Back to home" - }, - "app.skin-site.map.empty": { - "message": "No maps available." - }, - "app.skin-site.map.external": { - "message": "External" - }, - "app.skin-site.map.failed": { - "message": "Could not load maps." - }, - "app.skin-site.map.internal": { - "message": "Internal" - }, - "app.skin-site.map.loading": { - "message": "Loading maps…" - }, - "app.skin-site.map.map": { - "message": "Map" - }, - "app.skin-site.map.open": { - "message": "Open in browser" - }, - "app.skin-site.map.server": { - "message": "Server" - }, - "app.skin-site.map.title": { - "message": "Server map" - }, - "app.skin-site.profile-view.back": { - "message": "Back to home" - }, - "app.skin-site.profile-view.cape": { - "message": "Cape" - }, - "app.skin-site.profile-view.elytra": { - "message": "Elytra" - }, - "app.skin-site.profile-view.loading": { - "message": "Loading players…" - }, - "app.skin-site.profile-view.no-players": { - "message": "No players yet." - }, - "app.skin-site.profile-view.readonly": { - "message": "Mojang accounts are managed by Mojang; textures cannot be edited here." - }, - "app.skin-site.profile-view.remove": { - "message": "Remove" - }, - "app.skin-site.profile-view.removed": { - "message": "Texture removed." - }, - "app.skin-site.profile-view.select-hint": { - "message": "Select a player to preview and edit its textures." - }, - "app.skin-site.profile-view.signed-out": { - "message": "Sign in to manage your players." - }, - "app.skin-site.profile-view.skin": { - "message": "Skin" - }, - "app.skin-site.profile-view.title": { - "message": "Your players" - }, - "app.skin-site.profile-view.upload": { - "message": "Upload" - }, - "app.skin-site.profile-view.uploaded": { - "message": "Texture updated." - }, - "app.skin-site.profile.avatar": { - "message": "Avatar" - }, - "app.skin-site.profile.avatar-hint": { - "message": "Square images work best; the centre is cropped to 256×256." - }, - "app.skin-site.profile.avatar-uploaded": { - "message": "Avatar updated." - }, - "app.skin-site.profile.basic": { - "message": "Profile" - }, - "app.skin-site.profile.choose-avatar": { - "message": "Choose image" - }, - "app.skin-site.profile.minecraft-password": { - "message": "Minecraft password" - }, - "app.skin-site.profile.minecraft-password-changed": { - "message": "Minecraft password updated." - }, - "app.skin-site.profile.minecraft-password-hint": { - "message": "Used by the launcher; defaults to the website password." - }, - "app.skin-site.profile.mismatch": { - "message": "Passwords do not match." - }, - "app.skin-site.profile.new-password": { - "message": "New password" - }, - "app.skin-site.profile.old-password": { - "message": "Current password" - }, - "app.skin-site.profile.password-changed": { - "message": "Password updated." - }, - "app.skin-site.profile.password-hint": { - "message": "6–50 characters with upper case, lower case and a digit." - }, - "app.skin-site.profile.repeat-password": { - "message": "Repeat new password" - }, - "app.skin-site.profile.reset-default": { - "message": "Reset to website password" - }, - "app.skin-site.profile.save": { - "message": "Save" - }, - "app.skin-site.profile.saved": { - "message": "Saved." - }, - "app.skin-site.profile.security": { - "message": "Security" - }, - "app.skin-site.profile.site-password-hint": { - "message": "This is the password used to sign in to the skin site." - }, - "app.skin-site.profile.submit-password": { - "message": "Update password" - }, - "app.skin-site.profile.title": { - "message": "Account settings" - }, - "app.skin-site.profile.username": { - "message": "Username" - }, - "app.skin-site.profile.username-hint": { - "message": "3–16 characters." - }, - "app.skin-site.register.closed": { - "message": "Registration is currently closed on this server." - }, - "app.skin-site.register.code": { - "message": "Verification code" - }, - "app.skin-site.register.email": { - "message": "Email" - }, - "app.skin-site.register.invite-code": { - "message": "Invite code" - }, - "app.skin-site.register.invite-required": { - "message": "This server requires an invite code." - }, - "app.skin-site.register.mismatch": { - "message": "Passwords do not match." - }, - "app.skin-site.register.password": { - "message": "Password" - }, - "app.skin-site.register.password-hint": { - "message": "6–50 characters with upper case, lower case and a digit." - }, - "app.skin-site.register.qq": { - "message": "QQ (optional)" - }, - "app.skin-site.register.repeat-password": { - "message": "Repeat password" - }, - "app.skin-site.register.resend-in": { - "message": "Sent ({seconds}s)" - }, - "app.skin-site.register.send-code": { - "message": "Send code" - }, - "app.skin-site.register.sending": { - "message": "Sending…" - }, - "app.skin-site.register.submit": { - "message": "Create account" - }, - "app.skin-site.register.success": { - "message": "Account created and signed in." - }, - "app.skin-site.register.title": { - "message": "Create a StarLight account" - }, - "app.skin-site.reset.code": { - "message": "Verification code" - }, - "app.skin-site.reset.email": { - "message": "Email" - }, - "app.skin-site.reset.email-hint": { - "message": "Use the address you registered with." - }, - "app.skin-site.reset.mismatch": { - "message": "Passwords do not match." - }, - "app.skin-site.reset.new-password": { - "message": "New password" - }, - "app.skin-site.reset.password-hint": { - "message": "6–50 characters with upper case, lower case and a digit." - }, - "app.skin-site.reset.repeat-password": { - "message": "Repeat password" - }, - "app.skin-site.reset.resend-in": { - "message": "Sent ({seconds}s)" - }, - "app.skin-site.reset.send-code": { - "message": "Send code" - }, - "app.skin-site.reset.sending": { - "message": "Sending…" - }, - "app.skin-site.reset.submit": { - "message": "Reset password" - }, - "app.skin-site.reset.success": { - "message": "Password updated. You can sign in now." - }, - "app.skin-site.reset.title": { - "message": "Reset password" - }, - "app.skin-site.review.back": { - "message": "Back to home" - }, - "app.skin-site.review.back-to-list": { - "message": "Back to forms" - }, - "app.skin-site.review.email": { - "message": "Your email" - }, - "app.skin-site.review.email-hint": { - "message": "Results are sent to this address." - }, - "app.skin-site.review.empty": { - "message": "No application forms are available right now." - }, - "app.skin-site.review.failed": { - "message": "Could not load the review forms." - }, - "app.skin-site.review.invite-code": { - "message": "Invite code" - }, - "app.skin-site.review.loading": { - "message": "Loading…" - }, - "app.skin-site.review.optional": { - "message": "Optional" - }, - "app.skin-site.review.required": { - "message": "Required" - }, - "app.skin-site.review.result.passed": { - "message": "Approved" - }, - "app.skin-site.review.result.pending": { - "message": "Under review" - }, - "app.skin-site.review.result.rejected": { - "message": "Rejected" - }, - "app.skin-site.review.submit": { - "message": "Submit application" - }, - "app.skin-site.review.submitted": { - "message": "Application submitted." - }, - "app.skin-site.review.submitting": { - "message": "Submitting…" - }, - "app.skin-site.review.subtitle": { - "message": "Pick an application form and answer its questions." - }, - "app.skin-site.review.title": { - "message": "Player review" - }, - "app.skin-site.wiki.back": { - "message": "Back" - }, - "app.skin-site.wiki.browser.by-author": { - "message": "by {author}" - }, - "app.skin-site.wiki.browser.category-placeholder": { - "message": "Category name" - }, - "app.skin-site.wiki.browser.empty-list": { - "message": "Nothing here yet." - }, - "app.skin-site.wiki.browser.empty-search": { - "message": "No pages match your search." - }, - "app.skin-site.wiki.browser.hint-category": { - "message": "Enter a category name to browse." - }, - "app.skin-site.wiki.browser.hint-search": { - "message": "Type a keyword to search." - }, - "app.skin-site.wiki.browser.load-more": { - "message": "Load more" - }, - "app.skin-site.wiki.browser.search-placeholder": { - "message": "Search wiki pages…" - }, - "app.skin-site.wiki.browser.tab-category": { - "message": "Category" - }, - "app.skin-site.wiki.browser.tab-recent": { - "message": "Recent" - }, - "app.skin-site.wiki.browser.tab-search": { - "message": "Search" - }, - "app.skin-site.wiki.cancel": { - "message": "Cancel" - }, - "app.skin-site.wiki.categories": { - "message": "Categories" - }, - "app.skin-site.wiki.close-preview": { - "message": "Close preview" - }, - "app.skin-site.wiki.confirm-revert": { - "message": "Confirm revert" - }, - "app.skin-site.wiki.diff-title": { - "message": "Line diff against the current revision" - }, - "app.skin-site.wiki.empty": { - "message": "Enter a page title above to start reading." - }, - "app.skin-site.wiki.history": { - "message": "History" - }, - "app.skin-site.wiki.history-empty": { - "message": "No revisions yet." - }, - "app.skin-site.wiki.loading": { - "message": "Loading…" - }, - "app.skin-site.wiki.minor": { - "message": "Minor" - }, - "app.skin-site.wiki.move": { - "message": "Move" - }, - "app.skin-site.wiki.move-confirm": { - "message": "Confirm move" - }, - "app.skin-site.wiki.move-done": { - "message": "Page moved to {title}." - }, - "app.skin-site.wiki.move-target": { - "message": "New title" - }, - "app.skin-site.wiki.no-summary": { - "message": "No edit summary" - }, - "app.skin-site.wiki.not-found": { - "message": "Page not found." - }, - "app.skin-site.wiki.open": { - "message": "Open" - }, - "app.skin-site.wiki.read": { - "message": "Read" - }, - "app.skin-site.wiki.revert-done": { - "message": "Page reverted to the selected revision." - }, - "app.skin-site.wiki.revert-to": { - "message": "Revert to this" - }, - "app.skin-site.wiki.revision": { - "message": "Revision #{id}" - }, - "app.skin-site.wiki.revision-preview": { - "message": "Preview of revision #{id}" - }, - "app.skin-site.wiki.search-placeholder": { - "message": "Enter a page title" - }, - "app.skin-site.wiki.title": { - "message": "StarLight Wiki" - }, - "app.skin-site.wiki.unwatch": { - "message": "Unwatch" - }, - "app.skin-site.wiki.updated-at": { - "message": "Last edited {date} by {author}" - }, - "app.skin-site.wiki.view-revision": { - "message": "View" - }, - "app.skin-site.wiki.watch": { - "message": "Watch" - }, - "app.skin-site.wiki.watch-done": { - "message": "Watch state updated." - }, "app.skins.add-button": { "message": "Add skin" }, @@ -11852,27 +7544,6 @@ "app.skins.apply-button": { "message": "Apply" }, - "app.skins.armor.close": { - "message": "Close" - }, - "app.skins.armor.description": { - "message": "Try armour and trims on your skin. Nothing is stored until you save it." - }, - "app.skins.armor.reset-to-saved": { - "message": "Reset to saved" - }, - "app.skins.armor.restore-defaults": { - "message": "Restore defaults" - }, - "app.skins.armor.save": { - "message": "Save" - }, - "app.skins.armor.title": { - "message": "Armour and trims" - }, - "app.skins.armor.unsaved": { - "message": "Unsaved changes" - }, "app.skins.create-skin": { "message": "Create skin" }, @@ -12023,12 +7694,6 @@ "app.skins.skin-site-account.empty-title": { "message": "No players available" }, - "app.skins.skin-site-account.error-description": { - "message": "Check your connection and try again." - }, - "app.skins.skin-site-account.error-title": { - "message": "Could not load your players" - }, "app.skins.skin-site-account.loading-description": { "message": "The launcher is synchronizing the players attached to your account." }, @@ -12038,9 +7703,6 @@ "app.skins.skin-site-account.mojang-description": { "message": "{player} is an official Minecraft player. Its skin remains managed by the official account provider." }, - "app.skins.skin-site-account.retry": { - "message": "Retry" - }, "app.skins.skin-site-account.title": { "message": "StarLight skin site player" }, @@ -12092,12 +7754,6 @@ "app.symlink-warning.write.header": { "message": "Shared instance" }, - "app.sync-instances-update.choose-source.data-packs": { - "message": "Choose which instance to copy your data packs from. These packs are only used for the initial sync, and you can edit them from any instance afterward." - }, - "app.sync-instances-update.choose-source.resource-packs": { - "message": "Choose which instance to copy your resource packs from. These packs are only used for the initial sync, and you can edit them from any instance afterward." - }, "app.translation-settings.ai-model": { "message": "Text model" }, @@ -12872,141 +8528,6 @@ "instance.add-server.title": { "message": "Add a server" }, - "instance.backups.added-size": { - "message": "{size} newly stored" - }, - "instance.backups.all-included": { - "message": "All instance files and folders are included." - }, - "instance.backups.backup-now": { - "message": "Back up now" - }, - "instance.backups.cancel": { - "message": "Cancel backup" - }, - "instance.backups.choose": { - "message": "Everything is backed up by default. Add files or folders that should be excluded." - }, - "instance.backups.delete": { - "message": "Delete backup" - }, - "instance.backups.delete-body": { - "message": "This snapshot will be permanently deleted. Unused stored files will also be removed." - }, - "instance.backups.delete-title": { - "message": "Delete this backup?" - }, - "instance.backups.description": { - "message": "Create deduplicated snapshots of the whole instance while it is closed." - }, - "instance.backups.disable": { - "message": "Disable backups" - }, - "instance.backups.disable-blocked": { - "message": "Delete every snapshot before disabling backups." - }, - "instance.backups.edit-exclusions": { - "message": "Edit exclusions" - }, - "instance.backups.empty": { - "message": "No backups have been created yet." - }, - "instance.backups.enable": { - "message": "Enable backups" - }, - "instance.backups.excluded-paths": { - "message": "Excluded: {paths}" - }, - "instance.backups.exclusions.add-file": { - "message": "Add excluded file" - }, - "instance.backups.exclusions.add-folder": { - "message": "Add excluded folder" - }, - "instance.backups.exclusions.empty": { - "message": "No files or folders are excluded." - }, - "instance.backups.exclusions.remove": { - "message": "Remove {path} from exclusions" - }, - "instance.backups.loading": { - "message": "Loading backup settings..." - }, - "instance.backups.progress-bytes": { - "message": "{processed} of {total}" - }, - "instance.backups.restore": { - "message": "Restore backup" - }, - "instance.backups.restore-body": { - "message": "Upcoming operations: add {added, plural, one {# file} other {# files}}, modify {modified, plural, one {# file} other {# files}}, and delete {deleted, plural, one {# file} other {# files}}. Continue?" - }, - "instance.backups.restore-title": { - "message": "Restore this backup?" - }, - "instance.backups.save-exclusions": { - "message": "Save exclusions" - }, - "instance.backups.snapshot-meta": { - "message": "{files, plural, one {# file} other {# files}} · {size}" - }, - "instance.backups.snapshots": { - "message": "Snapshots" - }, - "instance.backups.stage.applying": { - "message": "Applying changed files" - }, - "instance.backups.stage.failed": { - "message": "Backup failed" - }, - "instance.backups.stage.hashing": { - "message": "Hashing files" - }, - "instance.backups.stage.interrupted": { - "message": "Backup operation was interrupted" - }, - "instance.backups.stage.materializing": { - "message": "Preparing changed files" - }, - "instance.backups.stage.preview": { - "message": "Analyzing restore changes" - }, - "instance.backups.stage.queued": { - "message": "Waiting to start" - }, - "instance.backups.stage.saving": { - "message": "Saving snapshot index" - }, - "instance.backups.stage.scanning": { - "message": "Scanning files" - }, - "instance.backups.stage.validating": { - "message": "Validating restore" - }, - "instance.backups.title": { - "message": "Instance backups" - }, - "instance.backups.unavailable": { - "message": "Backups are unavailable" - }, - "instance.backups.unavailable.direct-linked": { - "message": "Instances linked directly to another launcher cannot be backed up." - }, - "instance.backups.unavailable.external-directory": { - "message": "Instances that use an external game directory cannot be backed up." - }, - "instance.backups.unavailable.not-installed": { - "message": "Finish installing this instance before enabling backups." - }, - "instance.backups.unavailable.root-link": { - "message": "Instances whose root folder is a link cannot be backed up." - }, - "instance.backups.unavailable.root-missing": { - "message": "The instance folder is missing." - }, - "instance.backups.unavailable.symlink": { - "message": "Imported symbolic-link instances cannot be backed up." - }, "instance.edit-server.title": { "message": "Edit server" }, @@ -13148,9 +8669,6 @@ "instance.server-modal.resource-pack": { "message": "Resource pack" }, - "instance.settings.tabs.backups": { - "message": "Backups" - }, "instance.settings.tabs.core-components": { "message": "Core components" }, @@ -13418,9 +8936,6 @@ "instance.settings.tabs.java.optimize-memory-before-launch-description": { "message": "Waits for Windows memory optimization to finish before starting the game." }, - "instance.settings.tabs.sync": { - "message": "Synchronization" - }, "instance.settings.tabs.window": { "message": "Window" }, @@ -13460,15 +8975,6 @@ "instance.settings.tabs.window.width.enter": { "message": "Enter width..." }, - "instance.settings.tabs.window.window-title": { - "message": "Window title" - }, - "instance.settings.tabs.window.window-title.description": { - "message": "Customize the Minecraft window title. Leave empty to keep the default." - }, - "instance.settings.tabs.window.window-title.enter": { - "message": "Enter window title..." - }, "instance.upgrade.action.add-dependency": { "message": "Add dependency" }, @@ -14675,6 +10181,165 @@ "search.filter.locked.server-loader.title": { "message": "Loader is provided by the server" }, + "unknown-pack-warning-modal.body": { + "message": "A file is only reviewed if it’s uploaded to Modrinth, regardless of its file format (including .mrpack)." + }, + "unknown-pack-warning-modal.dont-show-again": { + "message": "Don't show this warning again" + }, + "unknown-pack-warning-modal.header": { + "message": "Confirm installation" + }, + "unknown-pack-warning-modal.install-anyway": { + "message": "Install anyway" + }, + "unknown-pack-warning-modal.malware-statement": { + "message": "Malware is often distributed through modpack files by sharing them on platforms like Discord." + }, + "unknown-pack-warning-modal.warning.body": { + "message": "We couldn't find this file on Modrinth. We strongly recommend only installing files from sources you trust." + }, + "unknown-pack-warning-modal.warning.title": { + "message": "Unknown file warning" + }, + "app.navigation.screenshots": { + "message": "Screenshots" + }, + "instance.backups.added-size": { + "message": "{size} newly stored" + }, + "instance.backups.all-included": { + "message": "All instance files and folders are included." + }, + "instance.backups.backup-now": { + "message": "Back up now" + }, + "instance.backups.cancel": { + "message": "Cancel backup" + }, + "instance.backups.choose": { + "message": "Everything is backed up by default. Add files or folders that should be excluded." + }, + "instance.backups.delete": { + "message": "Delete backup" + }, + "instance.backups.delete-body": { + "message": "This snapshot will be permanently deleted. Unused stored files will also be removed." + }, + "instance.backups.delete-title": { + "message": "Delete this backup?" + }, + "instance.backups.description": { + "message": "Create deduplicated snapshots of the whole instance while it is closed." + }, + "instance.backups.disable": { + "message": "Disable backups" + }, + "instance.backups.disable-blocked": { + "message": "Delete every snapshot before disabling backups." + }, + "instance.backups.edit-exclusions": { + "message": "Edit exclusions" + }, + "instance.backups.empty": { + "message": "No backups have been created yet." + }, + "instance.backups.enable": { + "message": "Enable backups" + }, + "instance.backups.excluded-paths": { + "message": "Excluded: {paths}" + }, + "instance.backups.exclusions.add-file": { + "message": "Add excluded file" + }, + "instance.backups.exclusions.add-folder": { + "message": "Add excluded folder" + }, + "instance.backups.exclusions.empty": { + "message": "No files or folders are excluded." + }, + "instance.backups.exclusions.remove": { + "message": "Remove {path} from exclusions" + }, + "instance.backups.loading": { + "message": "Loading backup settings..." + }, + "instance.backups.progress-bytes": { + "message": "{processed} of {total}" + }, + "instance.backups.restore": { + "message": "Restore backup" + }, + "instance.backups.restore-body": { + "message": "Upcoming operations: add {added, plural, one {# file} other {# files}}, modify {modified, plural, one {# file} other {# files}}, and delete {deleted, plural, one {# file} other {# files}}. Continue?" + }, + "instance.backups.restore-title": { + "message": "Restore this backup?" + }, + "instance.backups.save-exclusions": { + "message": "Save exclusions" + }, + "instance.backups.snapshot-meta": { + "message": "{files, plural, one {# file} other {# files}} · {size}" + }, + "instance.backups.snapshots": { + "message": "Snapshots" + }, + "instance.backups.stage.applying": { + "message": "Applying changed files" + }, + "instance.backups.stage.failed": { + "message": "Backup failed" + }, + "instance.backups.stage.hashing": { + "message": "Hashing files" + }, + "instance.backups.stage.interrupted": { + "message": "Backup operation was interrupted" + }, + "instance.backups.stage.materializing": { + "message": "Preparing changed files" + }, + "instance.backups.stage.preview": { + "message": "Analyzing restore changes" + }, + "instance.backups.stage.queued": { + "message": "Waiting to start" + }, + "instance.backups.stage.saving": { + "message": "Saving snapshot index" + }, + "instance.backups.stage.scanning": { + "message": "Scanning files" + }, + "instance.backups.stage.validating": { + "message": "Validating restore" + }, + "instance.backups.title": { + "message": "Instance backups" + }, + "instance.backups.unavailable": { + "message": "Backups are unavailable" + }, + "instance.backups.unavailable.direct-linked": { + "message": "Instances linked directly to another launcher cannot be backed up." + }, + "instance.backups.unavailable.external-directory": { + "message": "Instances that use an external game directory cannot be backed up." + }, + "instance.backups.unavailable.not-installed": { + "message": "Finish installing this instance before enabling backups." + }, + "instance.backups.unavailable.root-link": { + "message": "Instances whose root folder is a link cannot be backed up." + }, + "instance.backups.unavailable.root-missing": { + "message": "The instance folder is missing." + }, + "instance.backups.unavailable.symlink": { + "message": "Imported symbolic-link instances cannot be backed up." + }, "settings.backups.repository.change": { "message": "Change folder" }, @@ -14705,25 +10370,2730 @@ "settings.backups.repository.usage-description": { "message": "{stored} stored for {logical} of backup data across {count, plural, one {# snapshot} other {# snapshots}}." }, - "unknown-pack-warning-modal.body": { - "message": "A file is only reviewed if it’s uploaded to Modrinth, regardless of its file format (including .mrpack)." + "app.settings.synced-options.choose-sync-source.command-history-description": { + "message": "Choose which instance to copy your command history from. This history is only used for the initial sync, and you can edit it from any instance afterward." }, - "unknown-pack-warning-modal.dont-show-again": { - "message": "Don't show this warning again" + "app.settings.synced-options.choose-sync-source.command-history-title": { + "message": "Choose command history source" }, - "unknown-pack-warning-modal.header": { - "message": "Confirm installation" + "app.settings.synced-options.choose-sync-source.creative-hotbars-description": { + "message": "Choose which instance to copy your saved creative hotbars from. These hotbars are only used for the initial sync, and you can edit them from any instance afterward." }, - "unknown-pack-warning-modal.install-anyway": { - "message": "Install anyway" + "app.settings.synced-options.choose-sync-source.creative-hotbars-title": { + "message": "Choose creative hotbars source" }, - "unknown-pack-warning-modal.malware-statement": { - "message": "Malware is often distributed through modpack files by sharing them on platforms like Discord." + "app.settings.synced-options.choose-sync-source.data-packs-title": { + "message": "Choose data packs source" }, - "unknown-pack-warning-modal.warning.body": { - "message": "We couldn't find this file on Modrinth. We strongly recommend only installing files from sources you trust." + "app.settings.synced-options.choose-sync-source.game-settings-description": { + "message": "Choose which instance to copy your game settings from. These settings are only used for the initial sync, and you can edit them from any instance afterward." }, - "unknown-pack-warning-modal.warning.title": { - "message": "Unknown file warning" + "app.settings.synced-options.choose-sync-source.game-settings-title": { + "message": "Choose game settings source" + }, + "app.settings.synced-options.choose-sync-source.ineligible": { + "message": "You cannot choose this instance as a sync source" + }, + "app.settings.synced-options.choose-sync-source.load-error": { + "message": "Could not load sync sources. Please try again." + }, + "app.settings.synced-options.choose-sync-source.multiplayer-servers-description": { + "message": "Choose which instance to copy your multiplayer servers from. These servers are only used for the initial sync, and you can edit them from any instance afterward." + }, + "app.settings.synced-options.choose-sync-source.multiplayer-servers-title": { + "message": "Choose multiplayer servers source" + }, + "app.settings.synced-options.choose-sync-source.no-instances-found": { + "message": "No instances found" + }, + "app.settings.synced-options.choose-sync-source.resource-packs-title": { + "message": "Choose resource packs source" + }, + "app.settings.synced-options.choose-sync-source.retry": { + "message": "Try again" + }, + "app.settings.synced-options.choose-sync-source.search-placeholder": { + "message": "Search instance" + }, + "app.settings.synced-options.choose-sync-source.sync": { + "message": "Sync" + }, + "app.settings.synced-options.command-history": { + "message": "Sync command history" + }, + "app.settings.synced-options.command-history.description": { + "message": "Use the same command history across your instances." + }, + "app.settings.synced-options.command-history.editor-title": { + "message": "Edit command history" + }, + "app.settings.synced-options.creative-hotbars": { + "message": "Sync saved creative hotbars" + }, + "app.settings.synced-options.creative-hotbars.description": { + "message": "Use the same saved creative hotbars across your instances." + }, + "app.settings.synced-options.data-packs": { + "message": "Sync data packs" + }, + "app.settings.synced-options.data-packs.description": { + "message": "Use the same datapacks across your instances" + }, + "app.settings.synced-options.data-packs.none-synced-yet": { + "message": "You haven't synced any data packs yet" + }, + "app.settings.synced-options.edit.no-instances": { + "message": "Add an instance before editing synced data." + }, + "app.settings.synced-options.edit.no-synced-data": { + "message": "Choose a sync source before editing this setting." + }, + "app.settings.synced-options.game-settings": { + "message": "Sync game options" + }, + "app.settings.synced-options.game-settings.button": { + "message": "Edit game settings" + }, + "app.settings.synced-options.game-settings.description": { + "message": "Use the same game options across your instances." + }, + "app.settings.synced-options.game-settings.disabled-tooltip": { + "message": "Enable game settings sync before choosing individual settings." + }, + "app.settings.synced-options.game-settings.no-options-to-edit": { + "message": "You haven't got any options yet to edit" + }, + "app.settings.synced-options.multiplayer-servers": { + "message": "Sync multiplayer servers" + }, + "app.settings.synced-options.multiplayer-servers.address": { + "message": "Server address" + }, + "app.settings.synced-options.multiplayer-servers.copy-address": { + "message": "Copy address" + }, + "app.settings.synced-options.multiplayer-servers.count": { + "message": "{count, plural, one {# server} other {# servers}}" + }, + "app.settings.synced-options.multiplayer-servers.description": { + "message": "Use the same multiplayer servers across your instances." + }, + "app.settings.synced-options.multiplayer-servers.editor-title": { + "message": "Edit synced servers" + }, + "app.settings.synced-options.multiplayer-servers.empty": { + "message": "No user-added servers are currently synced." + }, + "app.settings.synced-options.multiplayer-servers.filter-offline": { + "message": "Offline" + }, + "app.settings.synced-options.multiplayer-servers.filter-online": { + "message": "Online" + }, + "app.settings.synced-options.multiplayer-servers.more-options": { + "message": "More server options" + }, + "app.settings.synced-options.multiplayer-servers.name": { + "message": "Server name" + }, + "app.settings.synced-options.multiplayer-servers.no-results": { + "message": "No synced servers match your search or filters." + }, + "app.settings.synced-options.multiplayer-servers.none-synced-yet": { + "message": "You haven't synced any servers yet" + }, + "app.settings.synced-options.multiplayer-servers.players-online": { + "message": "{count, number} online" + }, + "app.settings.synced-options.multiplayer-servers.search": { + "message": "Search {count, number} {count, plural, one {synced server} other {synced servers}}..." + }, + "app.settings.synced-options.multiplayer-servers.status": { + "message": "Status" + }, + "app.settings.synced-options.packs.disabled": { + "message": "Enable syncing before editing shared packs." + }, + "app.settings.synced-options.resource-packs": { + "message": "Sync resource packs" + }, + "app.settings.synced-options.resource-packs.description": { + "message": "Use the same resource packs across your instances." + }, + "app.settings.synced-options.resource-packs.none-synced-yet": { + "message": "You haven't synced any resource packs yet" + }, + "app.settings.synced-options.title": { + "message": "Options synced across all instances" + }, + "app.settings.synced-packs.data-packs": { + "message": "Data packs" + }, + "app.settings.synced-packs.disable": { + "message": "Disable" + }, + "app.settings.synced-packs.empty": { + "message": "No synced packs" + }, + "app.settings.synced-packs.enable": { + "message": "Enable" + }, + "app.settings.synced-packs.remove": { + "message": "Remove" + }, + "app.settings.synced-packs.resource-packs": { + "message": "Resource packs" + }, + "app.sync-instances-update.choose-source.data-packs": { + "message": "Choose which instance to copy your data packs from. These packs are only used for the initial sync, and you can edit them from any instance afterward." + }, + "app.sync-instances-update.choose-source.resource-packs": { + "message": "Choose which instance to copy your resource packs from. These packs are only used for the initial sync, and you can edit them from any instance afterward." + }, + "instance.settings.tabs.backups": { + "message": "Backups" + }, + "instance.settings.tabs.sync": { + "message": "Synchronization" + }, + "app.settings.game-options.category.accessibility.description": { + "message": "Accessibility preferences" + }, + "app.settings.game-options.category.accessibility.label": { + "message": "Accessibility" + }, + "app.settings.game-options.category.chat.description": { + "message": "Chat visibility and appearance" + }, + "app.settings.game-options.category.chat.label": { + "message": "Chat" + }, + "app.settings.game-options.category.controls.description": { + "message": "Mouse, movement, and key bindings" + }, + "app.settings.game-options.category.controls.label": { + "message": "Controls" + }, + "app.settings.game-options.category.custom.description": { + "message": "Settings added by mods" + }, + "app.settings.game-options.category.custom.label": { + "message": "Custom settings" + }, + "app.settings.game-options.category.language.description": { + "message": "Game language" + }, + "app.settings.game-options.category.language.label": { + "message": "Language" + }, + "app.settings.game-options.category.music-and-sound.description": { + "message": "Volume and audio preferences" + }, + "app.settings.game-options.category.music-and-sound.label": { + "message": "Music and sound" + }, + "app.settings.game-options.category.online.description": { + "message": "Online and Realms preferences" + }, + "app.settings.game-options.category.online.label": { + "message": "Online" + }, + "app.settings.game-options.category.skin-customization.description": { + "message": "Skin layers and main hand" + }, + "app.settings.game-options.category.skin-customization.label": { + "message": "Skin customization" + }, + "app.settings.game-options.category.video.description": { + "message": "Camera and display settings" + }, + "app.settings.game-options.category.video.label": { + "message": "Video" + }, + "app.settings.game-options.choice.all": { + "message": "All" + }, + "app.settings.game-options.choice.balanced": { + "message": "Balanced" + }, + "app.settings.game-options.choice.by-player": { + "message": "By player" + }, + "app.settings.game-options.choice.chat": { + "message": "Chat" + }, + "app.settings.game-options.choice.commands-only": { + "message": "Commands only" + }, + "app.settings.game-options.choice.constant": { + "message": "Constant" + }, + "app.settings.game-options.choice.crosshair": { + "message": "Crosshair" + }, + "app.settings.game-options.choice.custom": { + "message": "Custom" + }, + "app.settings.game-options.choice.decreased": { + "message": "Decreased" + }, + "app.settings.game-options.choice.default": { + "message": "Default" + }, + "app.settings.game-options.choice.fabulous": { + "message": "Fabulous" + }, + "app.settings.game-options.choice.fancy": { + "message": "Fancy" + }, + "app.settings.game-options.choice.far": { + "message": "Far" + }, + "app.settings.game-options.choice.fast": { + "message": "Fast" + }, + "app.settings.game-options.choice.frequent": { + "message": "Frequent" + }, + "app.settings.game-options.choice.hidden": { + "message": "Hidden" + }, + "app.settings.game-options.choice.hotbar": { + "message": "Hotbar" + }, + "app.settings.game-options.choice.left": { + "message": "Left" + }, + "app.settings.game-options.choice.limited": { + "message": "Limited" + }, + "app.settings.game-options.choice.max-fps": { + "message": "Max FPS" + }, + "app.settings.game-options.choice.maximum": { + "message": "Maximum" + }, + "app.settings.game-options.choice.minimal": { + "message": "Minimal" + }, + "app.settings.game-options.choice.minimum": { + "message": "Minimum" + }, + "app.settings.game-options.choice.nearby": { + "message": "Nearby" + }, + "app.settings.game-options.choice.never": { + "message": "Never" + }, + "app.settings.game-options.choice.none": { + "message": "None" + }, + "app.settings.game-options.choice.normal": { + "message": "Normal" + }, + "app.settings.game-options.choice.off": { + "message": "Off" + }, + "app.settings.game-options.choice.on": { + "message": "On" + }, + "app.settings.game-options.choice.opengl": { + "message": "OpenGL" + }, + "app.settings.game-options.choice.pause": { + "message": "Pause menu" + }, + "app.settings.game-options.choice.pause-and-toast": { + "message": "Pause menu and toast" + }, + "app.settings.game-options.choice.power-saver": { + "message": "Power saver" + }, + "app.settings.game-options.choice.right": { + "message": "Right" + }, + "app.settings.game-options.choice.short": { + "message": "Short" + }, + "app.settings.game-options.choice.shown": { + "message": "Shown" + }, + "app.settings.game-options.choice.system": { + "message": "System" + }, + "app.settings.game-options.choice.tiny": { + "message": "Tiny" + }, + "app.settings.game-options.choice.vulkan": { + "message": "Vulkan" + }, + "app.settings.game-options.choice.when-minimized": { + "message": "When minimized" + }, + "app.settings.game-options.choice.while-afk": { + "message": "While AFK" + }, + "app.settings.game-options.compatibility.none": { + "message": "Some of your instances cannot use this setting" + }, + "app.settings.game-options.compatibility.reason.launcher-controlled": { + "message": "This setting is managed by Modrinth’s launch settings." + }, + "app.settings.game-options.custom-value.placeholder": { + "message": "Enter a value" + }, + "app.settings.game-options.keybind.assigned-status": { + "message": "{setting} is now bound to {binding}." + }, + "app.settings.game-options.keybind.cancelled-status": { + "message": "Key binding change cancelled." + }, + "app.settings.game-options.keybind.change": { + "message": "{setting}: {binding}. Activate to change the binding." + }, + "app.settings.game-options.keybind.choose": { + "message": "Choose a key" + }, + "app.settings.game-options.keybind.conflict-description": { + "message": "This is already used by {settings}." + }, + "app.settings.game-options.keybind.key.arrow-down": { + "message": "Down Arrow" + }, + "app.settings.game-options.keybind.key.arrow-left": { + "message": "Left Arrow" + }, + "app.settings.game-options.keybind.key.arrow-right": { + "message": "Right Arrow" + }, + "app.settings.game-options.keybind.key.arrow-up": { + "message": "Up Arrow" + }, + "app.settings.game-options.keybind.key.backspace": { + "message": "Backspace" + }, + "app.settings.game-options.keybind.key.caps-lock": { + "message": "Caps Lock" + }, + "app.settings.game-options.keybind.key.delete": { + "message": "Delete" + }, + "app.settings.game-options.keybind.key.end": { + "message": "End" + }, + "app.settings.game-options.keybind.key.enter": { + "message": "Enter" + }, + "app.settings.game-options.keybind.key.escape": { + "message": "Escape" + }, + "app.settings.game-options.keybind.key.home": { + "message": "Home" + }, + "app.settings.game-options.keybind.key.insert": { + "message": "Insert" + }, + "app.settings.game-options.keybind.key.keypad-key": { + "message": "Numpad {key}" + }, + "app.settings.game-options.keybind.key.left-alt": { + "message": "Left Alt" + }, + "app.settings.game-options.keybind.key.left-command": { + "message": "Left Command" + }, + "app.settings.game-options.keybind.key.left-control": { + "message": "Left Ctrl" + }, + "app.settings.game-options.keybind.key.left-shift": { + "message": "Left Shift" + }, + "app.settings.game-options.keybind.key.left-super": { + "message": "Left Super" + }, + "app.settings.game-options.keybind.key.menu": { + "message": "Menu" + }, + "app.settings.game-options.keybind.key.num-lock": { + "message": "Num Lock" + }, + "app.settings.game-options.keybind.key.page-down": { + "message": "Page Down" + }, + "app.settings.game-options.keybind.key.page-up": { + "message": "Page Up" + }, + "app.settings.game-options.keybind.key.pause": { + "message": "Pause" + }, + "app.settings.game-options.keybind.key.print-screen": { + "message": "Print Screen" + }, + "app.settings.game-options.keybind.key.right-alt": { + "message": "Right Alt" + }, + "app.settings.game-options.keybind.key.right-command": { + "message": "Right Command" + }, + "app.settings.game-options.keybind.key.right-control": { + "message": "Right Ctrl" + }, + "app.settings.game-options.keybind.key.right-shift": { + "message": "Right Shift" + }, + "app.settings.game-options.keybind.key.right-super": { + "message": "Right Super" + }, + "app.settings.game-options.keybind.key.scroll-lock": { + "message": "Scroll Lock" + }, + "app.settings.game-options.keybind.key.space": { + "message": "Space" + }, + "app.settings.game-options.keybind.key.tab": { + "message": "Tab" + }, + "app.settings.game-options.keybind.key.unbound": { + "message": "Unbound" + }, + "app.settings.game-options.keybind.key.unknown": { + "message": "Unknown key" + }, + "app.settings.game-options.keybind.listen": { + "message": "Press a key…" + }, + "app.settings.game-options.keybind.listening-status": { + "message": "Listening for a key or mouse button. Press Escape to clear this binding." + }, + "app.settings.game-options.keybind.mixed": { + "message": "Different across instances" + }, + "app.settings.game-options.keybind.modifier.alt": { + "message": "Alt" + }, + "app.settings.game-options.keybind.modifier.command": { + "message": "Command" + }, + "app.settings.game-options.keybind.modifier.control": { + "message": "Ctrl" + }, + "app.settings.game-options.keybind.modifier.shift": { + "message": "Shift" + }, + "app.settings.game-options.keybind.modifier.super": { + "message": "Super" + }, + "app.settings.game-options.keybind.mouse.button": { + "message": "Mouse {button}" + }, + "app.settings.game-options.keybind.mouse.left": { + "message": "Left Mouse" + }, + "app.settings.game-options.keybind.mouse.middle": { + "message": "Middle Mouse" + }, + "app.settings.game-options.keybind.mouse.right": { + "message": "Right Mouse" + }, + "app.settings.game-options.keybind.recording-label": { + "message": "{setting}: listening for a key or mouse button. Press Escape to clear this binding." + }, + "app.settings.game-options.keybind.scancode": { + "message": "Scancode {code}" + }, + "app.settings.game-options.keybind.unsupported-status": { + "message": "That input cannot be used by Minecraft. Press another key." + }, + "app.settings.game-options.setting.advanced-opengl.label": { + "message": "Advanced OpenGL" + }, + "app.settings.game-options.setting.allow-cursor-changes.label": { + "message": "Allow cursor changes" + }, + "app.settings.game-options.setting.allow-server-listing.description": { + "message": "Allow the player's name to appear in server listings." + }, + "app.settings.game-options.setting.allow-server-listing.label": { + "message": "Server listings" + }, + "app.settings.game-options.setting.alternate-blocks.label": { + "message": "Alternate blocks" + }, + "app.settings.game-options.setting.ambient-occlusion.label": { + "message": "Smooth lighting" + }, + "app.settings.game-options.setting.ambient-volume.label": { + "message": "Ambient/Environment" + }, + "app.settings.game-options.setting.anaglyph-3d.label": { + "message": "3D anaglyph" + }, + "app.settings.game-options.setting.anisotropic-filtering.label": { + "message": "Anisotropic filtering" + }, + "app.settings.game-options.setting.anisotropy.label": { + "message": "Anisotropy" + }, + "app.settings.game-options.setting.attack-indicator.label": { + "message": "Attack indicator" + }, + "app.settings.game-options.setting.auto-jump.description": { + "message": "Automatically jump up one-block-high obstacles." + }, + "app.settings.game-options.setting.auto-jump.label": { + "message": "Auto-jump" + }, + "app.settings.game-options.setting.auto-suggestions.label": { + "message": "Command suggestions" + }, + "app.settings.game-options.setting.autosave-indicator.label": { + "message": "Autosave indicator" + }, + "app.settings.game-options.setting.biome-blend-radius.description": { + "message": "The distance over which biome colors transition." + }, + "app.settings.game-options.setting.biome-blend-radius.label": { + "message": "Biome blend" + }, + "app.settings.game-options.setting.blocks-volume.label": { + "message": "Blocks" + }, + "app.settings.game-options.setting.brightness.label": { + "message": "Brightness" + }, + "app.settings.game-options.setting.cape.description": { + "message": "Show the player's cape, including its elytra texture." + }, + "app.settings.game-options.setting.cape.label": { + "message": "Cape" + }, + "app.settings.game-options.setting.chat-background-only.label": { + "message": "Chat background only" + }, + "app.settings.game-options.setting.chat-colors.label": { + "message": "Chat colors" + }, + "app.settings.game-options.setting.chat-delay.label": { + "message": "Chat delay" + }, + "app.settings.game-options.setting.chat-line-spacing.label": { + "message": "Chat line spacing" + }, + "app.settings.game-options.setting.chat-links-prompt.description": { + "message": "Ask before opening links from chat." + }, + "app.settings.game-options.setting.chat-links-prompt.label": { + "message": "Prompt on links" + }, + "app.settings.game-options.setting.chat-links.description": { + "message": "Allow web links in chat to be opened." + }, + "app.settings.game-options.setting.chat-links.label": { + "message": "Web links" + }, + "app.settings.game-options.setting.chat-opacity.description": { + "message": "The opacity of chat text." + }, + "app.settings.game-options.setting.chat-opacity.label": { + "message": "Chat opacity" + }, + "app.settings.game-options.setting.chat-preview.label": { + "message": "Chat preview" + }, + "app.settings.game-options.setting.chat-scale.label": { + "message": "Chat scale" + }, + "app.settings.game-options.setting.chat-visibility.label": { + "message": "Chat visibility" + }, + "app.settings.game-options.setting.chat-width.label": { + "message": "Chat width" + }, + "app.settings.game-options.setting.chunk-fade-time.label": { + "message": "Chunk fade time" + }, + "app.settings.game-options.setting.cloud-range.label": { + "message": "Cloud distance" + }, + "app.settings.game-options.setting.clouds.label": { + "message": "Clouds" + }, + "app.settings.game-options.setting.ctrl-click-right-click.label": { + "message": "Control-click as right-click" + }, + "app.settings.game-options.setting.cutout-leaves.label": { + "message": "Cutout leaves" + }, + "app.settings.game-options.setting.damage-tilt.label": { + "message": "Damage tilt" + }, + "app.settings.game-options.setting.dark-splash.description": { + "message": "Change the Mojang Studios loading screen from red to black." + }, + "app.settings.game-options.setting.dark-splash.label": { + "message": "Monochrome logo" + }, + "app.settings.game-options.setting.darkness-pulsing.label": { + "message": "Darkness pulsing" + }, + "app.settings.game-options.setting.debug-gui-scale.label": { + "message": "Debug GUI scale" + }, + "app.settings.game-options.setting.directional-audio.label": { + "message": "Directional audio" + }, + "app.settings.game-options.setting.discrete-mouse-scroll.description": { + "message": "Treat each mouse-wheel input as a single scroll step." + }, + "app.settings.game-options.setting.discrete-mouse-scroll.label": { + "message": "Discrete scrolling" + }, + "app.settings.game-options.setting.entity-distance.label": { + "message": "Entity distance" + }, + "app.settings.game-options.setting.entity-shadows.label": { + "message": "Entity shadows" + }, + "app.settings.game-options.setting.exclusive-fullscreen.label": { + "message": "Exclusive fullscreen" + }, + "app.settings.game-options.setting.extra-telemetry.label": { + "message": "Optional telemetry" + }, + "app.settings.game-options.setting.focused-chat-height.label": { + "message": "Focused chat height" + }, + "app.settings.game-options.setting.force-unicode-font.label": { + "message": "Force Unicode font" + }, + "app.settings.game-options.setting.fov-effects.label": { + "message": "FOV effects" + }, + "app.settings.game-options.setting.fov.label": { + "message": "Field of view" + }, + "app.settings.game-options.setting.fullscreen.label": { + "message": "Fullscreen" + }, + "app.settings.game-options.setting.glint-speed.label": { + "message": "Glint speed" + }, + "app.settings.game-options.setting.glint-strength.label": { + "message": "Glint strength" + }, + "app.settings.game-options.setting.graphics-backend.label": { + "message": "Graphics backend" + }, + "app.settings.game-options.setting.graphics.description": { + "message": "Controls visual quality and performance." + }, + "app.settings.game-options.setting.graphics.label": { + "message": "Graphics" + }, + "app.settings.game-options.setting.gui-scale.description": { + "message": "The size of the game interface and HUD." + }, + "app.settings.game-options.setting.gui-scale.label": { + "message": "GUI scale" + }, + "app.settings.game-options.setting.hat.description": { + "message": "Show the hat skin layer." + }, + "app.settings.game-options.setting.hat.label": { + "message": "Hat" + }, + "app.settings.game-options.setting.held-item-tooltips.label": { + "message": "Held item tooltips" + }, + "app.settings.game-options.setting.hide-lightning-flashes.label": { + "message": "Hide lightning flashes" + }, + "app.settings.game-options.setting.hide-matched-names.label": { + "message": "Hide matched names" + }, + "app.settings.game-options.setting.hide-server-address.label": { + "message": "Hide server address" + }, + "app.settings.game-options.setting.hide-splash-texts.label": { + "message": "Hide splash texts" + }, + "app.settings.game-options.setting.high-contrast-outline.label": { + "message": "High contrast block outline" + }, + "app.settings.game-options.setting.high-contrast.description": { + "message": "Enhance the contrast of interface elements." + }, + "app.settings.game-options.setting.high-contrast.label": { + "message": "High contrast" + }, + "app.settings.game-options.setting.hostile-volume.label": { + "message": "Hostile creatures" + }, + "app.settings.game-options.setting.improved-transparency.label": { + "message": "Improved transparency" + }, + "app.settings.game-options.setting.in-game-notifications.label": { + "message": "In-game notifications" + }, + "app.settings.game-options.setting.inactivity-framerate-limit.label": { + "message": "Reduced framerate" + }, + "app.settings.game-options.setting.invert-horizontal-mouse.label": { + "message": "Invert horizontal mouse" + }, + "app.settings.game-options.setting.invert-mouse.description": { + "message": "Invert vertical mouse movement." + }, + "app.settings.game-options.setting.invert-mouse.label": { + "message": "Invert mouse" + }, + "app.settings.game-options.setting.jacket.description": { + "message": "Show the jacket skin layer." + }, + "app.settings.game-options.setting.jacket.label": { + "message": "Jacket" + }, + "app.settings.game-options.setting.japanese-glyph-variants.label": { + "message": "Japanese glyph variants" + }, + "app.settings.game-options.setting.key-advancements.label": { + "message": "Advancements" + }, + "app.settings.game-options.setting.key-attack.label": { + "message": "Attack" + }, + "app.settings.game-options.setting.key-back.label": { + "message": "Move backward" + }, + "app.settings.game-options.setting.key-chat.label": { + "message": "Open chat" + }, + "app.settings.game-options.setting.key-command.label": { + "message": "Command" + }, + "app.settings.game-options.setting.key-debug-advanced-tooltips.label": { + "message": "Show advanced tooltips" + }, + "app.settings.game-options.setting.key-debug-chunk-borders.label": { + "message": "Show chunk borders" + }, + "app.settings.game-options.setting.key-debug-clear-chat.label": { + "message": "Clear chat" + }, + "app.settings.game-options.setting.key-debug-copy-location.label": { + "message": "Copy location" + }, + "app.settings.game-options.setting.key-debug-copy-recreate-command.label": { + "message": "Copy recreate command" + }, + "app.settings.game-options.setting.key-debug-crash.label": { + "message": "Trigger debug crash" + }, + "app.settings.game-options.setting.key-debug-dump-dynamic-textures.label": { + "message": "Dump dynamic textures" + }, + "app.settings.game-options.setting.key-debug-dump-version.label": { + "message": "Dump version" + }, + "app.settings.game-options.setting.key-debug-focus-pause.label": { + "message": "Pause on lost focus" + }, + "app.settings.game-options.setting.key-debug-fps-charts.label": { + "message": "FPS charts" + }, + "app.settings.game-options.setting.key-debug-hitboxes.label": { + "message": "Show hitboxes" + }, + "app.settings.game-options.setting.key-debug-improved-transparency.label": { + "message": "Improved transparency debug view" + }, + "app.settings.game-options.setting.key-debug-lightmap-texture.label": { + "message": "Lightmap texture" + }, + "app.settings.game-options.setting.key-debug-modifier.label": { + "message": "Debug modifier" + }, + "app.settings.game-options.setting.key-debug-network-charts.label": { + "message": "Network charts" + }, + "app.settings.game-options.setting.key-debug-options.label": { + "message": "Debug options" + }, + "app.settings.game-options.setting.key-debug-overlay.label": { + "message": "Debug overlay" + }, + "app.settings.game-options.setting.key-debug-profiling-chart.label": { + "message": "Profiling chart" + }, + "app.settings.game-options.setting.key-debug-profiling.label": { + "message": "Start profiling" + }, + "app.settings.game-options.setting.key-debug-reload-chunks.label": { + "message": "Reload chunks" + }, + "app.settings.game-options.setting.key-debug-reload-resource-packs.label": { + "message": "Reload resource packs" + }, + "app.settings.game-options.setting.key-debug-spectate.label": { + "message": "Spectate entity" + }, + "app.settings.game-options.setting.key-debug-switch-game-mode.label": { + "message": "Switch game mode" + }, + "app.settings.game-options.setting.key-drop.label": { + "message": "Drop item" + }, + "app.settings.game-options.setting.key-forward.label": { + "message": "Move forward" + }, + "app.settings.game-options.setting.key-friends.label": { + "message": "Friends" + }, + "app.settings.game-options.setting.key-fullscreen.label": { + "message": "Toggle fullscreen" + }, + "app.settings.game-options.setting.key-hotbar-1.label": { + "message": "Hotbar 1" + }, + "app.settings.game-options.setting.key-hotbar-2.label": { + "message": "Hotbar 2" + }, + "app.settings.game-options.setting.key-hotbar-3.label": { + "message": "Hotbar 3" + }, + "app.settings.game-options.setting.key-hotbar-4.label": { + "message": "Hotbar 4" + }, + "app.settings.game-options.setting.key-hotbar-5.label": { + "message": "Hotbar 5" + }, + "app.settings.game-options.setting.key-hotbar-6.label": { + "message": "Hotbar 6" + }, + "app.settings.game-options.setting.key-hotbar-7.label": { + "message": "Hotbar 7" + }, + "app.settings.game-options.setting.key-hotbar-8.label": { + "message": "Hotbar 8" + }, + "app.settings.game-options.setting.key-hotbar-9.label": { + "message": "Hotbar 9" + }, + "app.settings.game-options.setting.key-inventory.label": { + "message": "Inventory" + }, + "app.settings.game-options.setting.key-jump.label": { + "message": "Jump" + }, + "app.settings.game-options.setting.key-left.label": { + "message": "Strafe left" + }, + "app.settings.game-options.setting.key-load-toolbar.label": { + "message": "Load toolbar" + }, + "app.settings.game-options.setting.key-perspective.label": { + "message": "Change perspective" + }, + "app.settings.game-options.setting.key-pick-item.label": { + "message": "Pick block" + }, + "app.settings.game-options.setting.key-player-list.label": { + "message": "Player list" + }, + "app.settings.game-options.setting.key-quick-actions.label": { + "message": "Quick actions" + }, + "app.settings.game-options.setting.key-right.label": { + "message": "Strafe right" + }, + "app.settings.game-options.setting.key-save-toolbar.label": { + "message": "Save toolbar" + }, + "app.settings.game-options.setting.key-screenshot.label": { + "message": "Screenshot" + }, + "app.settings.game-options.setting.key-smooth-camera.label": { + "message": "Toggle cinematic camera" + }, + "app.settings.game-options.setting.key-sneak.label": { + "message": "Sneak" + }, + "app.settings.game-options.setting.key-social-interactions.label": { + "message": "Social interactions" + }, + "app.settings.game-options.setting.key-spectator-hotbar.label": { + "message": "Spectator hotbar" + }, + "app.settings.game-options.setting.key-spectator-outlines.label": { + "message": "Highlight spectators" + }, + "app.settings.game-options.setting.key-sprint.label": { + "message": "Sprint" + }, + "app.settings.game-options.setting.key-swap-offhand.label": { + "message": "Swap offhand" + }, + "app.settings.game-options.setting.key-toggle-gui.label": { + "message": "Toggle HUD" + }, + "app.settings.game-options.setting.key-toggle-spectator-shader.label": { + "message": "Toggle spectator shader" + }, + "app.settings.game-options.setting.key-use.label": { + "message": "Use item" + }, + "app.settings.game-options.setting.language.label": { + "message": "Language" + }, + "app.settings.game-options.setting.left-pants-leg.label": { + "message": "Left pants leg" + }, + "app.settings.game-options.setting.left-sleeve.label": { + "message": "Left sleeve" + }, + "app.settings.game-options.setting.legacy-framerate-limit.label": { + "message": "Framerate limit" + }, + "app.settings.game-options.setting.legacy-view-distance.label": { + "message": "View distance" + }, + "app.settings.game-options.setting.mac-fullscreen-menu.label": { + "message": "Show macOS menu in fullscreen" + }, + "app.settings.game-options.setting.main-hand.description": { + "message": "Choose whether the main hand is left or right." + }, + "app.settings.game-options.setting.main-hand.label": { + "message": "Main hand" + }, + "app.settings.game-options.setting.master-volume.label": { + "message": "Master volume" + }, + "app.settings.game-options.setting.max-framerate.label": { + "message": "Maximum framerate" + }, + "app.settings.game-options.setting.menu-background-blur.label": { + "message": "Menu background blur" + }, + "app.settings.game-options.setting.mipmap-levels.description": { + "message": "Texture smoothing at a distance." + }, + "app.settings.game-options.setting.mipmap-levels.label": { + "message": "Mipmap levels" + }, + "app.settings.game-options.setting.mouse-wheel-sensitivity.label": { + "message": "Mouse wheel sensitivity" + }, + "app.settings.game-options.setting.music-frequency.label": { + "message": "Music frequency" + }, + "app.settings.game-options.setting.music-toast.description": { + "message": "Choose whether music titles appear in the pause menu and as toasts." + }, + "app.settings.game-options.setting.music-toast.label": { + "message": "Music notification" + }, + "app.settings.game-options.setting.music-volume.label": { + "message": "Music" + }, + "app.settings.game-options.setting.narrator-hotkey.label": { + "message": "Narrator hotkey" + }, + "app.settings.game-options.setting.narrator.description": { + "message": "Choose what the narrator reads." + }, + "app.settings.game-options.setting.narrator.label": { + "message": "Narrator" + }, + "app.settings.game-options.setting.neutral-volume.label": { + "message": "Friendly creatures" + }, + "app.settings.game-options.setting.notification-time.description": { + "message": "How long toast notifications remain visible." + }, + "app.settings.game-options.setting.notification-time.label": { + "message": "Notification time" + }, + "app.settings.game-options.setting.operator-items-tab.label": { + "message": "Operator items tab" + }, + "app.settings.game-options.setting.panorama-speed.label": { + "message": "Panorama speed" + }, + "app.settings.game-options.setting.particles.label": { + "message": "Particles" + }, + "app.settings.game-options.setting.players-volume.label": { + "message": "Players" + }, + "app.settings.game-options.setting.prioritize-chunk-updates.label": { + "message": "Prioritize chunk updates" + }, + "app.settings.game-options.setting.quit-shortcuts.label": { + "message": "Quit shortcuts" + }, + "app.settings.game-options.setting.raw-mouse-input.label": { + "message": "Raw mouse input" + }, + "app.settings.game-options.setting.realms-notifications.label": { + "message": "Realms notifications" + }, + "app.settings.game-options.setting.record-volume.label": { + "message": "Jukebox/Note Blocks" + }, + "app.settings.game-options.setting.reduced-debug-info.label": { + "message": "Reduced debug information" + }, + "app.settings.game-options.setting.render-distance.label": { + "message": "Render distance" + }, + "app.settings.game-options.setting.right-pants-leg.label": { + "message": "Right pants leg" + }, + "app.settings.game-options.setting.right-sleeve.label": { + "message": "Right sleeve" + }, + "app.settings.game-options.setting.rotate-with-minecart.label": { + "message": "Rotate with minecart" + }, + "app.settings.game-options.setting.save-chat-drafts.label": { + "message": "Save chat drafts" + }, + "app.settings.game-options.setting.screen-effects.label": { + "message": "Screen effects" + }, + "app.settings.game-options.setting.secure-chat-only.label": { + "message": "Only show secure chat" + }, + "app.settings.game-options.setting.sensitivity.label": { + "message": "Mouse sensitivity" + }, + "app.settings.game-options.setting.server-textures.label": { + "message": "Server textures" + }, + "app.settings.game-options.setting.share-presence.label": { + "message": "Share presence" + }, + "app.settings.game-options.setting.simulation-distance.description": { + "message": "How far away entities update and blocks and fluids tick." + }, + "app.settings.game-options.setting.simulation-distance.label": { + "message": "Simulation distance" + }, + "app.settings.game-options.setting.snooper.label": { + "message": "Snooper" + }, + "app.settings.game-options.setting.sprint-window.label": { + "message": "Sprint window" + }, + "app.settings.game-options.setting.subtitles.description": { + "message": "Show captions for sounds played in the game." + }, + "app.settings.game-options.setting.subtitles.label": { + "message": "Subtitles" + }, + "app.settings.game-options.setting.text-background-opacity.label": { + "message": "Text background opacity" + }, + "app.settings.game-options.setting.texture-filtering.label": { + "message": "Texture filtering" + }, + "app.settings.game-options.setting.toggle-attack.label": { + "message": "Toggle attack" + }, + "app.settings.game-options.setting.toggle-crouch.description": { + "message": "Press once to remain crouched." + }, + "app.settings.game-options.setting.toggle-crouch.label": { + "message": "Toggle crouch" + }, + "app.settings.game-options.setting.toggle-sprint.description": { + "message": "Press once to remain sprinting." + }, + "app.settings.game-options.setting.toggle-sprint.label": { + "message": "Toggle sprint" + }, + "app.settings.game-options.setting.toggle-use.label": { + "message": "Toggle use" + }, + "app.settings.game-options.setting.touchscreen.label": { + "message": "Touchscreen mode" + }, + "app.settings.game-options.setting.ui-volume.label": { + "message": "UI" + }, + "app.settings.game-options.setting.unfocused-chat-height.label": { + "message": "Unfocused chat height" + }, + "app.settings.game-options.setting.use-vbo.label": { + "message": "Use VBOs" + }, + "app.settings.game-options.setting.view-bobbing.description": { + "message": "Add a bobbing motion to the camera while walking." + }, + "app.settings.game-options.setting.view-bobbing.label": { + "message": "View bobbing" + }, + "app.settings.game-options.setting.vignette.label": { + "message": "Vignette" + }, + "app.settings.game-options.setting.voice-volume.label": { + "message": "Voice and speech" + }, + "app.settings.game-options.setting.vsync.description": { + "message": "Limit the frame rate to the display refresh rate to prevent screen tearing." + }, + "app.settings.game-options.setting.vsync.label": { + "message": "VSync" + }, + "app.settings.game-options.setting.weather-radius.label": { + "message": "Weather radius" + }, + "app.settings.game-options.setting.weather-volume.label": { + "message": "Weather" + }, + "app.settings.game-options.validation.changed-since-opened": { + "message": "This setting changed elsewhere. Check it and try again." + }, + "app.settings.game-options.validation.invalid-value": { + "message": "Choose a valid value." + }, + "app.settings.game-options.validation.missing-value": { + "message": "Choose a value first." + }, + "app.settings.game-options.validation.no-compatible-instances": { + "message": "Some of your instances cannot use this setting" + }, + "app.settings.synced-options.game-settings.conflict-text": { + "message": "We loaded the latest settings. Check your changes, then save again." + }, + "app.settings.synced-options.game-settings.conflict-title": { + "message": "These settings changed elsewhere" + }, + "app.settings.synced-options.game-settings.custom-empty": { + "message": "Settings added by mods will appear here after Modrinth finds them in one of your instances." + }, + "app.settings.synced-options.game-settings.disable-all": { + "message": "Unsync all" + }, + "app.settings.synced-options.game-settings.empty": { + "message": "No settings match your search or filter." + }, + "app.settings.synced-options.game-settings.enable-all": { + "message": "Sync all" + }, + "app.settings.synced-options.game-settings.load-failed": { + "message": "We couldn’t load your game settings." + }, + "app.settings.synced-options.game-settings.loading": { + "message": "Loading settings..." + }, + "app.settings.synced-options.game-settings.not-being-synced": { + "message": "Not being synced" + }, + "app.settings.synced-options.game-settings.retry": { + "message": "Retry" + }, + "app.settings.synced-options.game-settings.save": { + "message": "Save settings" + }, + "app.settings.synced-options.game-settings.search": { + "message": "Search settings..." + }, + "app.settings.synced-options.game-settings.sync-description": { + "message": "Synced options are applied to every instance and override the values included with a modpack." + }, + "app.settings.synced-options.game-settings.sync-setting": { + "message": "Sync {setting} across instances" + }, + "app.settings.synced-options.game-settings.sync-title": { + "message": "Sync game settings" + }, + "app.settings.synced-options.game-settings.synced-across-instances": { + "message": "Synced across instances" + }, + "app.settings.synced-options.game-settings.title": { + "message": "Game settings" + }, + "app.settings.synced-options.game-settings.unsaved-changes": { + "message": "You have unsaved changes." + }, + "app.settings.synced-options.game-settings.unsync-setting": { + "message": "Stop syncing {setting} across instances" + }, + "app.settings.synced-options.game-settings.value-mixed": { + "message": "Different across instances" + }, + "app.settings.synced-options.game-settings.value-off": { + "message": "Off" + }, + "app.settings.synced-options.game-settings.value-on": { + "message": "On" + }, + "app.settings.synced-options.game-settings.value-unset": { + "message": "Choose a value" + }, + "app.anniversary.banner": { + "message": "Happy {ordinal} Anniversary, Starlight!" + }, + "instance.settings.tabs.window.window-title": { + "message": "Window title" + }, + "instance.settings.tabs.window.window-title.description": { + "message": "Customize the Minecraft window title. Leave empty to keep the default." + }, + "instance.settings.tabs.window.window-title.enter": { + "message": "Enter window title..." + }, + "app.settings.defaults.window-title.enabled": { + "message": "Custom Minecraft window title" + }, + "app.settings.defaults.window-title.enabled-description": { + "message": "Allow instances to customize the Minecraft window title." + }, + "app.settings.defaults.window-title.default": { + "message": "Default window title" + }, + "app.settings.defaults.window-title.default-description": { + "message": "Used when an instance does not provide its own title." + }, + "app.settings.defaults.window-title.default-placeholder": { + "message": "Enter the default window title..." + }, + "app.action-bar.announcements": { + "message": "Announcements" + }, + "app.remote-announcements.center-title": { + "message": "Announcements" + }, + "app.remote-announcements.empty": { + "message": "No announcements" + }, + "app.remote-announcements.view": { + "message": "View announcement" + }, + "app.remote-announcements.unread": { + "message": "Unread" + }, + "app.remote-announcements.read-all": { + "message": "Mark all announcements as read" + }, + "app.remote-announcements.preview-title": { + "message": "Announcement style preview" + }, + "app.remote-announcements.preview-summary": { + "message": "This is a local preview notification. Select View announcement to see the full Markdown content." + }, + "app.remote-announcements.preview-content": { + "message": "## Announcement preview\n\nThis is **sample content**, not a published announcement.\n\n- Supports headings, lists, and links\n- Close buttons are always available\n\n> Previewing does not change real announcement read status.\n\n| Type | Display |\n| --- | --- |\n| Modal | Full Markdown content |\n| Popup | Summary, then full content |\n\n[Visit the website](https://skin.starlight.cool/)" + }, + "app.remote-announcements.preview-action": { + "message": "Visit website" + }, + "app.settings.tabs.logs": { + "message": "Logs & diagnostics" + }, + "app.settings.logs.export.title": { + "message": "Export logs" + }, + "app.settings.logs.export.description": { + "message": "Package launcher logs with an optional environment summary, instance log, and crash analysis." + }, + "app.settings.logs.export.button": { + "message": "Export logs…" + }, + "app.settings.logs.open-folder": { + "message": "Open logs folder" + }, + "app.settings.logs.export.modal.title": { + "message": "Export logs" + }, + "app.settings.logs.export.modal.description": { + "message": "Choose how much detail to include. Exported logs have access tokens, Minecraft tokens, and IP addresses replaced with placeholders." + }, + "app.settings.logs.export.modal.range": { + "message": "Time range" + }, + "app.settings.logs.export.modal.range.30-minutes": { + "message": "Last 30 minutes" + }, + "app.settings.logs.export.modal.range.2-hours": { + "message": "Last 2 hours" + }, + "app.settings.logs.export.modal.range.all": { + "message": "All sessions" + }, + "app.settings.logs.export.modal.level": { + "message": "Log level" + }, + "app.settings.logs.export.modal.level.all": { + "message": "All levels" + }, + "app.settings.logs.export.modal.level.debug": { + "message": "Debug and above" + }, + "app.settings.logs.export.modal.level.info": { + "message": "Info and above" + }, + "app.settings.logs.export.modal.extras": { + "message": "Additional information" + }, + "app.settings.logs.export.modal.system-info": { + "message": "System and environment summary" + }, + "app.settings.logs.export.modal.instance-logs": { + "message": "Most recent instance log" + }, + "app.settings.logs.export.modal.crash-analysis": { + "message": "Crash analysis (when a crash is detected)" + }, + "app.settings.logs.export.modal.cancel": { + "message": "Cancel" + }, + "app.settings.logs.export.modal.confirm": { + "message": "Export" + }, + "app.settings.logs.export.notification-title": { + "message": "Logs exported" + }, + "app.settings.logs.export.notification-text": { + "message": "The log archive was saved to {path}" + }, + "app.skins.armor.title": { "message": "Armour and trims" }, + "app.skins.armor.save": { "message": "Save" }, + "app.skins.armor.close": { "message": "Close" }, + "app.skins.armor.description": { + "message": "Try armour and trims on your skin. Nothing is stored until you save it." + }, + "app.skins.armor.unsaved": { "message": "Unsaved changes" }, + "app.skins.armor.reset-to-saved": { "message": "Reset to saved" }, + "app.skins.armor.restore-defaults": { "message": "Restore defaults" }, + "app.instances.batch-edit-groups.add": { "message": "Add" }, + "app.instances.batch-edit-groups.add-to-group-title": { + "message": "Add instances to \"{groupName}\"" + }, + "app.instances.batch-edit-groups.added": { "message": "Added" }, + "app.instances.batch-edit-groups.cancel": { "message": "Cancel" }, + "app.instances.batch-edit-groups.create": { "message": "Create group" }, + "app.instances.batch-edit-groups.group-name": { "message": "Group name" }, + "app.instances.batch-edit-groups.group-name-placeholder": { + "message": "Enter group name" + }, + "app.instances.batch-edit-groups.no-instances-found": { + "message": "No instances found" + }, + "app.instances.batch-edit-groups.save-changes": { "message": "Save" }, + "app.instances.batch-edit-groups.search-instance": { + "message": "Search instances" + }, + "app.instances.group.add-to-group": { "message": "Add to group" }, + "app.instances.group.collapse": { "message": "Collapse group" }, + "app.instances.group.delete-description": { + "message": "Instances in this group will be ungrouped." + }, + "app.instances.group.delete-group": { "message": "Delete group" }, + "app.instances.group.edit-name": { "message": "Edit group name" }, + "app.instances.group.empty": { "message": "Drag and drop to add instances." }, + "app.instances.group.expand": { "message": "Expand group" }, + "app.instances.group.move-down": { "message": "Move group down" }, + "app.instances.group.move-up": { "message": "Move group up" }, + "app.instances.group.name-empty": { + "message": "Group names cannot be empty." + }, + "app.instances.group.name-too-long": { + "message": "Group names cannot be longer than {maxLength} characters." + }, + "app.instances.group.new-instance": { "message": "New instance" }, + "app.instances.group.pinned": { "message": "Pinned" }, + "app.instances.group.rename-group": { "message": "Rename group" }, + "app.instances.sort-by": { "message": "Sort by" }, + "app.instances.sort.direction.asc-alphabetical": { "message": "A–Z" }, + "app.instances.sort.direction.asc-date": { "message": "Oldest first" }, + "app.instances.sort.direction.asc-recency": { + "message": "Least recent first" + }, + "app.instances.sort.direction.asc-version": { + "message": "Oldest version first" + }, + "app.instances.sort.direction.desc-alphabetical": { "message": "Z–A" }, + "app.instances.sort.direction.desc-date": { "message": "Newest first" }, + "app.instances.sort.direction.desc-recency": { + "message": "Most recent first" + }, + "app.instances.sort.direction.desc-version": { + "message": "Newest version first" + }, + "app.library.context-menu.pin-instance": { "message": "Pin instance" }, + "app.library.context-menu.remove-from-group": { + "message": "Remove from group" + }, + "app.library.context-menu.unpin-instance": { "message": "Unpin instance" }, + "app.library.group.new": { "message": "New group" }, + "app.library.selection.new-group": { "message": "New group" }, + "app.library.selection.remove-from-group": { "message": "Remove from group" }, + "app.log-share.settings.title": { "message": "Log sharing & AI analysis" }, + "app.log-share.settings.description": { + "message": "Share crash diagnostics with LogShare for a structured summary and optional AI analysis. LogShare is preferred; mclo.gs is used as a fallback." + }, + "app.log-share.settings.share-provider": { "message": "Log sharing service" }, + "app.log-share.settings.share-provider-description": { + "message": "Where the diagnostic link is uploaded when you share it." + }, + "app.log-share.settings.ai-source": { "message": "AI analysis source" }, + "app.log-share.settings.ai-source-logshare": { "message": "LogShare AI" }, + "app.log-share.settings.ai-source-custom": { + "message": "Custom AI provider" + }, + "app.log-share.settings.ai-source-description": { + "message": "Both sources send a sanitized and shortened crash context. AI output may be inaccurate." + }, + "app.log-share.settings.auto-upload": { + "message": "Upload to get a structured summary automatically" + }, + "app.log-share.settings.auto-upload-description": { + "message": "Only effective in LogShare AI mode." + }, + "app.log-share.settings.multi-file": { "message": "Multi-file upload" }, + "app.log-share.settings.multi-file-description": { + "message": "Upload latest.log, crash reports, hs_err and launcher logs together." + }, + "app.log-share.settings.no-storage": { + "message": "Analyze without storing logs" + }, + "app.log-share.settings.no-storage-description": { + "message": "Submit content directly for analysis and skip the stored upload. Disables the automatic summary." + }, + "app.log-share.settings.show-progress": { + "message": "Show AI analysis progress" + }, + "app.log-share.settings.show-progress-description": { + "message": "Display thinking, tool and limit status while LogShare AI is working." + }, + "app.log-share.shared-logs.title": { "message": "Shared logs" }, + "app.log-share.shared-logs.description": { + "message": "Every diagnostic you have shared is listed here. Delete an entry to remove it from your history and request its removal from the sharing service." + }, + "app.log-share.shared-logs.empty": { "message": "No shared logs yet." }, + "app.log-share.shared-logs.delete": { "message": "Delete" }, + "app.log-share.shared-logs.deleting": { "message": "Deleting…" }, + "app.log-share.shared-logs.deleted": { "message": "Shared log removed." }, + "app.log-share.shared-logs.delete-failed": { + "message": "Failed to delete the shared log." + }, + "app.log-share.shared-logs.truncated": { "message": "Truncated" }, + "app.minecraft-crash.share-fallback": { + "message": "LogShare is unavailable, so the diagnostic was shared via mclo.gs." + }, + "app.log-share.ai.action": { "message": "Deep AI analysis" }, + "app.log-share.summary.title": { "message": "LogShare analysis" }, + "app.log-share.summary.loading": { + "message": "Loading structured summary..." + }, + "app.log-share.summary.empty": { + "message": "LogShare did not return a structured summary for these logs." + }, + "app.log-share.summary.no-storage": { + "message": "Structured summary is unavailable while no-storage mode is enabled." + }, + "app.log-share.summary.failed": { + "message": "Could not load the LogShare summary: {message}" + }, + "app.log-share.summary.problems": { "message": "Problems" }, + "app.log-share.summary.information": { "message": "Information" }, + "app.minecraft-crash.logs.loading": { "message": "Loading crash logs..." }, + "app.minecraft-crash.logs.empty": { + "message": "No logs from this launch were found." + }, + "app.minecraft-crash.logs.failed": { + "message": "Could not load the crash logs: {message}" + }, + "app.minecraft-crash.log-file.loading": { "message": "Loading log file..." }, + "app.minecraft-crash.log-file.failed": { + "message": "Could not load this log file: {message}" + }, + "app.log-share.ai.tab": { "message": "LogAgent detailed analysis" }, + "app.log-share.ai.root-cause": { "message": "Core root cause" }, + "app.log-share.ai.confidence": { "message": "Diagnostic confidence" }, + "app.log-share.ai.steps": { "message": "Recommended troubleshooting steps" }, + "app.log-share.ai.evidence": { "message": "Supporting evidence" }, + "app.log-share.ai.thinking": { "message": "Thinking…" }, + "app.log-share.ai.queued": { "message": "Queued, about {position} ahead" }, + "app.log-share.ai.queued-front": { + "message": "Queued, waiting for a free slot" + }, + "app.log-share.ai.tool": { "message": "Using tool: {name}" }, + "app.log-share.ai.unknown-tool": { "message": "tool" }, + "app.log-share.ai.tool-result": { "message": "Tool result received" }, + "app.log-share.ai.limit": { "message": "Reached tool loop limit" }, + "app.log-share.ai.working": { "message": "Analyzing with LogAgent…" }, + "app.log-share.ai.failed": { + "message": "LogAgent analysis failed: {message}" + }, + "app.shortcut-settings.change-shortcut": { + "message": "Change the shortcut for {action}" + }, + "app.shortcut-settings.enable": { "message": "Enable quick scrolling" }, + "app.shortcut-settings.end-action": { "message": "Scroll to the bottom" }, + "app.shortcut-settings.end-action-description": { + "message": "Moves the page you are reading to the bottom." + }, + "app.shortcut-settings.home-action": { "message": "Scroll to the top" }, + "app.shortcut-settings.home-action-description": { + "message": "Moves the page you are reading to the top." + }, + "app.shortcut-settings.nav-create": { "message": "Create new instance" }, + "app.shortcut-settings.nav-create-description": { + "message": "Jump to creating a new instance." + }, + "app.shortcut-settings.nav-description": { + "message": "Jump to a menu item with its shortcut. Each shortcut is off until enabled." + }, + "app.shortcut-settings.nav-discover": { "message": "Discover content" }, + "app.shortcut-settings.nav-discover-description": { + "message": "Jump to browsing content." + }, + "app.shortcut-settings.nav-downloads": { "message": "Downloads" }, + "app.shortcut-settings.nav-downloads-description": { + "message": "Jump to downloads." + }, + "app.shortcut-settings.nav-home": { "message": "Home" }, + "app.shortcut-settings.nav-home-description": { + "message": "Jump to the Home page." + }, + "app.shortcut-settings.nav-lab": { "message": "Lab" }, + "app.shortcut-settings.nav-lab-description": { + "message": "Jump to the Lab." + }, + "app.shortcut-settings.nav-library": { "message": "Library" }, + "app.shortcut-settings.nav-library-description": { + "message": "Jump to your library." + }, + "app.shortcut-settings.nav-multiplayer": { "message": "Multiplayer" }, + "app.shortcut-settings.nav-multiplayer-description": { + "message": "Jump to multiplayer." + }, + "app.shortcut-settings.nav-settings": { "message": "Settings" }, + "app.shortcut-settings.nav-settings-description": { + "message": "Jump to the settings." + }, + "app.shortcut-settings.nav-skins": { "message": "Skin selector" }, + "app.shortcut-settings.nav-skins-description": { + "message": "Jump to the skin selector." + }, + "app.shortcut-settings.nav-title": { "message": "Navigation shortcuts" }, + "app.shortcut-settings.nav-worlds": { "message": "Worlds" }, + "app.shortcut-settings.nav-worlds-description": { + "message": "Jump to your worlds." + }, + "app.shortcut-settings.page-down-action": { + "message": "Scroll down one screen" + }, + "app.shortcut-settings.page-down-action-description": { + "message": "Moves the page you are reading down by one screen." + }, + "app.shortcut-settings.page-up-action": { "message": "Scroll up one screen" }, + "app.shortcut-settings.page-up-action-description": { + "message": "Moves the page you are reading up by one screen." + }, + "app.shortcut-settings.scroll-description": { + "message": "Move through long pages with the keyboard." + }, + "app.shortcut-settings.scroll-title": { "message": "Quick scrolling" }, + "app.settings.tabs.shortcut-settings": { "message": "Keyboard shortcuts" }, + "app.skin-site.bugs.title": { "message": "Bugs & suggestions" }, + "app.skin-site.bugs.back": { "message": "Back to home" }, + "app.skin-site.bugs.subtitle": { + "message": "Report issues and follow their progress." + }, + "app.skin-site.bugs.loading": { "message": "Loading…" }, + "app.skin-site.bugs.failed": { "message": "Could not load issues." }, + "app.skin-site.bugs.empty": { "message": "No issues match these filters." }, + "app.skin-site.bugs.all": { "message": "All" }, + "app.skin-site.bugs.more": { "message": "Load more" }, + "app.skin-site.bugs.open-only": { "message": "Open only" }, + "app.skin-site.bugs.comments": { "message": "{count} comments" }, + "app.skin-site.bugs.type.bug": { "message": "Bug" }, + "app.skin-site.bugs.type.feature": { "message": "Feature" }, + "app.skin-site.bugs.type.improvement": { "message": "Improvement" }, + "app.skin-site.bugs.status.pending": { "message": "Pending" }, + "app.skin-site.bugs.status.confirmed": { "message": "Confirmed" }, + "app.skin-site.bugs.status.needs-info": { "message": "Needs info" }, + "app.skin-site.bugs.status.in-progress": { "message": "In progress" }, + "app.skin-site.bugs.status.verifying": { "message": "Verifying" }, + "app.skin-site.bugs.status.closed": { "message": "Closed" }, + "app.skin-site.bugs.priority.critical": { "message": "Critical" }, + "app.skin-site.bugs.priority.high": { "message": "High" }, + "app.skin-site.bugs.priority.normal": { "message": "Normal" }, + "app.skin-site.bugs.priority.low": { "message": "Low" }, + "app.skin-site.bugs.resolution.fixed": { "message": "Fixed" }, + "app.skin-site.bugs.resolution.wont-fix": { "message": "Won’t fix" }, + "app.skin-site.bugs.resolution.by-design": { "message": "By design" }, + "app.skin-site.bugs.resolution.duplicate": { "message": "Duplicate" }, + "app.skin-site.bugs.resolution.cannot-reproduce": { + "message": "Cannot reproduce" + }, + "app.skin-site.bugs.resolution.invalid": { "message": "Invalid" }, + "app.skin-site.bug-detail.back": { "message": "Back to list" }, + "app.skin-site.bug-detail.loading": { "message": "Loading…" }, + "app.skin-site.bug-detail.failed": { + "message": "Could not load this issue." + }, + "app.skin-site.bug-detail.issue-no": { "message": "Issue #{id}" }, + "app.skin-site.bug-detail.by": { "message": "by {name}" }, + "app.skin-site.bug-detail.assignee": { "message": "Assignee: {name}" }, + "app.skin-site.bug-detail.unassigned": { "message": "Unassigned" }, + "app.skin-site.bug-detail.description-empty": { + "message": "No description provided." + }, + "app.skin-site.bug-detail.resolution": { "message": "Resolution: {name}" }, + "app.skin-site.bug-detail.comments-title": { "message": "Comments" }, + "app.skin-site.bug-detail.comments-empty": { + "message": "No comments yet. Be the first to reply." + }, + "app.skin-site.bug-detail.comments-loading": { + "message": "Loading comments…" + }, + "app.skin-site.bug-detail.comment-placeholder": { + "message": "Write a comment…" + }, + "app.skin-site.bug-detail.comment-submit": { "message": "Comment" }, + "app.skin-site.bug-detail.comment-sending": { "message": "Sending…" }, + "app.skin-site.bug-detail.comment-empty-error": { + "message": "Comment cannot be empty." + }, + "app.skin-site.bug-detail.comment-posted": { "message": "Comment posted." }, + "app.skin-site.bug-detail.comment-deleted": { "message": "Comment deleted." }, + "app.skin-site.bug-detail.delete": { "message": "Delete" }, + "app.skin-site.bug-detail.deleting": { "message": "Deleting…" }, + "app.skin-site.bug-detail.system": { "message": "System" }, + "app.skin-site.bug-create.title": { "message": "New issue" }, + "app.skin-site.bug-create.type": { "message": "Type" }, + "app.skin-site.bug-create.title-field": { "message": "Title" }, + "app.skin-site.bug-create.title-placeholder": { + "message": "A short summary of the problem" + }, + "app.skin-site.bug-create.description": { "message": "Description" }, + "app.skin-site.bug-create.description-placeholder": { + "message": "What happened, and how can it be reproduced?" + }, + "app.skin-site.bug-create.private": { "message": "Private issue" }, + "app.skin-site.bug-create.private-hint": { + "message": "Only you and the maintainers can see it." + }, + "app.skin-site.bug-create.images": { "message": "Images" }, + "app.skin-site.bug-create.images-hint": { + "message": "Optional, up to 5 images." + }, + "app.skin-site.bug-create.submit": { "message": "Create issue" }, + "app.skin-site.bug-create.submitting": { "message": "Creating…" }, + "app.skin-site.bug-create.created": { "message": "Issue created." }, + "app.skin-site.bug-create.cancel": { "message": "Cancel" }, + "app.skin-site.bug-notifications.title": { "message": "Notifications" }, + "app.skin-site.bug-notifications.back": { "message": "Back to home" }, + "app.skin-site.bug-notifications.subtitle": { + "message": "Activity on issues you reported or follow." + }, + "app.skin-site.bug-notifications.loading": { "message": "Loading…" }, + "app.skin-site.bug-notifications.failed": { + "message": "Could not load notifications." + }, + "app.skin-site.bug-notifications.empty": { + "message": "No new notifications." + }, + "app.skin-site.bug-notifications.item": { + "message": "{name} updated issue #{id}" + }, + "app.skin-site.bug-notifications.mark-all": { "message": "Mark all as read" }, + "app.skin-site.bug-notifications.marked-all": { + "message": "All notifications marked as read." + }, + "app.skin-site.bugs.create": { "message": "New issue" }, + "app.skin-site.bugs.notifications": { "message": "Notifications" }, + "app.skin-site.home.title": { "message": "StarLight Skin Site" }, + "app.skin-site.home.subtitle": { + "message": "The wardrobe for StarLight Server players." + }, + "app.skin-site.home.address": { "message": "Skin site address" }, + "app.skin-site.home.copied": { "message": "Address copied." }, + "app.skin-site.home.copy": { "message": "Copy" }, + "app.skin-site.admin.title": { "message": "Admin console" }, + "app.skin-site.admin.back": { "message": "Back to home" }, + "app.skin-site.admin.no-access": { "message": "You do not have access." }, + "app.skin-site.admin.no-access-hint": { + "message": "Sign in with an administrator account to use this console." + }, + "app.skin-site.admin.group.security": { "message": "Security" }, + "app.skin-site.admin.group.users": { "message": "Users" }, + "app.skin-site.admin.group.community": { "message": "Community" }, + "app.skin-site.admin.group.resources": { "message": "Resources" }, + "app.skin-site.admin.item.servers": { "message": "Servers" }, + "app.skin-site.admin.item.summary": { "message": "Summary" }, + "app.skin-site.admin.item.access-audit": { "message": "Access audit" }, + "app.skin-site.admin.item.users": { "message": "Users" }, + "app.skin-site.admin.item.players": { "message": "Players" }, + "app.skin-site.admin.item.review": { "message": "Player review" }, + "app.skin-site.admin.item.broadcast": { "message": "Broadcast" }, + "app.skin-site.admin.item.chat": { "message": "Chat rooms" }, + "app.skin-site.admin.item.wiki": { "message": "Wiki" }, + "app.skin-site.admin.item.donations": { "message": "Donations" }, + "app.skin-site.admin.item.mods": { "message": "Mods" }, + "app.skin-site.admin.item.launcher": { "message": "Launcher" }, + "app.skin-site.admin.item.downloads": { "message": "Downloads" }, + "app.skin-site.home.admin": { "message": "Admin" }, + "app.skin-site.home.settings": { "message": "Account" }, + "app.skin-site.home.sign-in": { "message": "Sign in" }, + "app.skin-site.home.players": { "message": "Players" }, + "app.skin-site.home.my-players": { "message": "My players" }, + "app.skin-site.home.no-players": { "message": "No players linked yet." }, + "app.skin-site.home.loading": { "message": "Loading…" }, + "app.skin-site.home.error": { "message": "Could not load." }, + "app.skin-site.home.luck": { "message": "Luck" }, + "app.skin-site.home.luck-unavailable": { "message": "Unavailable" }, + "app.skin-site.home.signed-out-title": { "message": "Not signed in" }, + "app.skin-site.home.signed-out-body": { + "message": "Sign in to manage your account and textures." + }, + "app.skin-site.admin.summary.title": { "message": "System overview" }, + "app.skin-site.admin.summary.loading": { "message": "Loading…" }, + "app.skin-site.admin.summary.failed": { "message": "Could not load status." }, + "app.skin-site.admin.summary.uptime": { "message": "Uptime" }, + "app.skin-site.admin.summary.memory": { "message": "Memory usage" }, + "app.skin-site.admin.summary.users": { "message": "Users" }, + "app.skin-site.admin.summary.players": { "message": "Players" }, + "app.skin-site.admin.summary.realtime-hint": { + "message": "Live CPU and GC charts require the admin WebSocket, which is not connected yet." + }, + "app.skin-site.admin.broadcast.title": { "message": "Announcements" }, + "app.skin-site.admin.broadcast.loading": { "message": "Loading…" }, + "app.skin-site.admin.broadcast.failed": { "message": "Could not load." }, + "app.skin-site.admin.broadcast.empty": { "message": "No announcements yet." }, + "app.skin-site.admin.broadcast.create": { "message": "New announcement" }, + "app.skin-site.admin.broadcast.save": { "message": "Save" }, + "app.skin-site.admin.broadcast.cancel": { "message": "Cancel" }, + "app.skin-site.admin.broadcast.edit": { "message": "Edit" }, + "app.skin-site.admin.broadcast.remove": { "message": "Delete" }, + "app.skin-site.admin.broadcast.title-field": { "message": "Title" }, + "app.skin-site.admin.broadcast.subtitle-field": { "message": "Subtitle" }, + "app.skin-site.admin.broadcast.content-field": { "message": "Content" }, + "app.skin-site.admin.broadcast.expire-at": { "message": "Expires at" }, + "app.skin-site.admin.broadcast.star": { "message": "Highlight" }, + "app.skin-site.admin.broadcast.level": { "message": "Importance" }, + "app.skin-site.admin.broadcast.image": { "message": "Image" }, + "app.skin-site.admin.broadcast.remove-image": { "message": "Remove image" }, + "app.skin-site.admin.broadcast.created": { + "message": "Announcement created." + }, + "app.skin-site.admin.broadcast.updated": { + "message": "Announcement updated." + }, + "app.skin-site.admin.broadcast.deleted": { + "message": "Announcement deleted." + }, + "app.skin-site.admin.broadcast.confirm-delete": { + "message": "Delete “{title}”? This cannot be undone." + }, + "app.skin-site.admin.broadcast.uploader": { "message": "by {name}" }, + "app.skin-site.admin.players.title": { "message": "Players" }, + "app.skin-site.admin.players.loading": { "message": "Loading…" }, + "app.skin-site.admin.players.failed": { + "message": "Could not load players." + }, + "app.skin-site.admin.players.empty": { "message": "No players found." }, + "app.skin-site.admin.players.search": { "message": "Search" }, + "app.skin-site.admin.players.search-name": { "message": "Name" }, + "app.skin-site.admin.players.search-owner": { "message": "Owner" }, + "app.skin-site.admin.players.search-uuid": { "message": "UUID" }, + "app.skin-site.admin.players.total": { "message": "{count} players" }, + "app.skin-site.admin.players.prev": { "message": "Previous" }, + "app.skin-site.admin.players.next": { "message": "Next" }, + "app.skin-site.admin.players.page": { "message": "Page {page}" }, + "app.skin-site.admin.players.name": { "message": "Name" }, + "app.skin-site.admin.players.owner": { "message": "Owner" }, + "app.skin-site.admin.players.source": { "message": "Source" }, + "app.skin-site.admin.players.legacy": { "message": "Legacy adapted" }, + "app.skin-site.admin.players.actions": { "message": "Actions" }, + "app.skin-site.admin.players.edit": { "message": "Edit" }, + "app.skin-site.admin.players.save": { "message": "Save" }, + "app.skin-site.admin.players.cancel": { "message": "Cancel" }, + "app.skin-site.admin.players.remove": { "message": "Delete" }, + "app.skin-site.admin.players.updated": { "message": "Player updated." }, + "app.skin-site.admin.players.deleted": { "message": "Player deleted." }, + "app.skin-site.admin.players.confirm-delete": { + "message": "Delete player “{name}”? This cannot be undone." + }, + "app.skin-site.admin.players.mojang": { "message": "Mojang" }, + "app.skin-site.admin.players.custom": { "message": "Skin site" }, + "app.skin-site.admin.users.title": { "message": "Users" }, + "app.skin-site.admin.users.loading": { "message": "Loading…" }, + "app.skin-site.admin.users.failed": { "message": "Could not load users." }, + "app.skin-site.admin.users.empty": { "message": "No users found." }, + "app.skin-site.admin.users.search": { "message": "Search" }, + "app.skin-site.admin.users.search-name": { "message": "Username" }, + "app.skin-site.admin.users.search-email": { "message": "Email" }, + "app.skin-site.admin.users.search-uuid": { "message": "UUID" }, + "app.skin-site.admin.users.total": { "message": "{count} users" }, + "app.skin-site.admin.users.prev": { "message": "Previous" }, + "app.skin-site.admin.users.next": { "message": "Next" }, + "app.skin-site.admin.users.page": { "message": "Page {page}" }, + "app.skin-site.admin.users.edit": { "message": "Edit" }, + "app.skin-site.admin.users.save": { "message": "Save" }, + "app.skin-site.admin.users.cancel": { "message": "Cancel" }, + "app.skin-site.admin.users.remove": { "message": "Delete" }, + "app.skin-site.admin.users.players": { "message": "Players" }, + "app.skin-site.admin.users.updated": { "message": "User updated." }, + "app.skin-site.admin.users.deleted": { "message": "User deleted." }, + "app.skin-site.admin.users.confirm-delete": { + "message": "Delete user “{name}”? This cannot be undone." + }, + "app.skin-site.admin.users.username": { "message": "Username" }, + "app.skin-site.admin.users.email": { "message": "Email" }, + "app.skin-site.admin.users.qq": { "message": "QQ" }, + "app.skin-site.admin.users.password": { "message": "New password" }, + "app.skin-site.admin.users.password-hint": { + "message": "Leave empty to keep the current password." + }, + "app.skin-site.admin.users.banned": { "message": "Banned" }, + "app.skin-site.admin.users.permissions": { "message": "Permissions" }, + "app.skin-site.admin.users.permissions-hint": { + "message": "Comma separated, e.g. WEB_ADMIN, SERVER_ADMIN." + }, + "app.skin-site.admin.users.no-players": { "message": "No linked players." }, + "app.skin-site.admin.users.registered": { "message": "Registered" }, + "app.skin-site.admin.review.title": { "message": "Player review" }, + "app.skin-site.admin.review.loading": { "message": "Loading…" }, + "app.skin-site.admin.review.failed": { + "message": "Could not load submissions." + }, + "app.skin-site.admin.review.empty": { "message": "No submissions found." }, + "app.skin-site.admin.review.total": { "message": "{count} submissions" }, + "app.skin-site.admin.review.filter-all": { "message": "All" }, + "app.skin-site.admin.review.filter-pending": { "message": "Pending" }, + "app.skin-site.admin.review.filter-passed": { "message": "Passed" }, + "app.skin-site.admin.review.filter-rejected": { "message": "Rejected" }, + "app.skin-site.admin.review.result-pending": { "message": "Pending" }, + "app.skin-site.admin.review.result-passed": { "message": "Passed" }, + "app.skin-site.admin.review.result-rejected": { "message": "Rejected" }, + "app.skin-site.admin.review.mode-auto": { "message": "Auto" }, + "app.skin-site.admin.review.mode-manual": { "message": "Manual" }, + "app.skin-site.admin.review.applicant": { "message": "Applicant" }, + "app.skin-site.admin.review.submitted-at": { "message": "Submitted" }, + "app.skin-site.admin.review.score": { "message": "Score" }, + "app.skin-site.admin.review.reviewer": { "message": "Reviewer" }, + "app.skin-site.admin.review.details": { "message": "Details" }, + "app.skin-site.admin.review.hide": { "message": "Hide" }, + "app.skin-site.admin.review.answers": { "message": "Answers" }, + "app.skin-site.admin.review.no-answers": { "message": "No answers." }, + "app.skin-site.admin.review.auto-checks": { "message": "Automatic checks" }, + "app.skin-site.admin.review.context": { "message": "Submission context" }, + "app.skin-site.admin.review.ip": { "message": "IP" }, + "app.skin-site.admin.review.user-agent": { "message": "User agent" }, + "app.skin-site.admin.review.activity": { "message": "Activity" }, + "app.skin-site.admin.review.duration": { "message": "Duration" }, + "app.skin-site.admin.review.hidden-time": { "message": "Hidden time" }, + "app.skin-site.admin.review.screen-switches": { + "message": "Screen switches" + }, + "app.skin-site.admin.review.history": { "message": "Decision history" }, + "app.skin-site.admin.review.accept": { "message": "Accept" }, + "app.skin-site.admin.review.reject": { "message": "Reject" }, + "app.skin-site.admin.review.reason": { "message": "Reason" }, + "app.skin-site.admin.review.accept-done": { + "message": "Submission accepted." + }, + "app.skin-site.admin.review.reject-done": { + "message": "Submission rejected." + }, + "app.skin-site.admin.review.regen-invite": { "message": "Regenerate invite" }, + "app.skin-site.admin.review.invite-regenerated": { + "message": "Invite code regenerated." + }, + "app.skin-site.admin.review.invite-sent": { "message": "Email sent." }, + "app.skin-site.admin.review.invite-not-sent": { + "message": "Email not sent." + }, + "app.skin-site.admin.review.prev": { "message": "Previous" }, + "app.skin-site.admin.review.next": { "message": "Next" }, + "app.skin-site.admin.review.page": { "message": "Page {page}" }, + "app.skin-site.admin.launcher.title": { "message": "Launcher releases" }, + "app.skin-site.admin.launcher.loading": { "message": "Loading…" }, + "app.skin-site.admin.launcher.failed": { + "message": "Could not load releases." + }, + "app.skin-site.admin.launcher.empty": { + "message": "No releases uploaded yet." + }, + "app.skin-site.admin.launcher.latest-url": { "message": "Latest URL" }, + "app.skin-site.admin.launcher.version": { "message": "Version" }, + "app.skin-site.admin.launcher.channel": { "message": "Channel" }, + "app.skin-site.admin.launcher.uploader": { "message": "Uploaded by" }, + "app.skin-site.admin.launcher.uploaded-at": { "message": "Uploaded" }, + "app.skin-site.admin.launcher.published-at": { "message": "Published" }, + "app.skin-site.admin.launcher.force-update": { "message": "Forced" }, + "app.skin-site.admin.launcher.active": { "message": "Active" }, + "app.skin-site.admin.launcher.activate": { "message": "Activate" }, + "app.skin-site.admin.launcher.activated": { "message": "Release activated." }, + "app.skin-site.admin.launcher.delete": { "message": "Delete release" }, + "app.skin-site.admin.launcher.confirm-delete": { + "message": "Permanently delete launcher {version} and all its installation files from the server? This version will no longer be available for download or rollback. Installed launchers will not be affected." + }, + "app.skin-site.admin.launcher.deleted": { + "message": "Release and its installation files deleted." + }, + "app.skin-site.admin.launcher.upload": { "message": "Upload release" }, + "app.skin-site.admin.launcher.upload-hint": { + "message": "Choose a release ZIP (max 4 GiB)." + }, + "app.skin-site.admin.launcher.uploading": { "message": "Uploading…" }, + "app.skin-site.admin.launcher.upload-done": { + "message": "Release uploaded." + }, + "app.skin-site.admin.launcher.force-flag": { "message": "Force update" }, + "app.skin-site.admin.launcher.prev": { "message": "Previous" }, + "app.skin-site.admin.launcher.next": { "message": "Next" }, + "app.skin-site.admin.launcher.page": { "message": "Page {page}" }, + "app.skin-site.admin.launcher.total": { "message": "{count} releases" }, + "app.skin-site.admin.downloads.title": { "message": "Downloads" }, + "app.skin-site.admin.downloads.loading": { "message": "Loading…" }, + "app.skin-site.admin.downloads.failed": { + "message": "Could not load downloads." + }, + "app.skin-site.admin.downloads.empty": { "message": "No download items." }, + "app.skin-site.admin.downloads.categories": { "message": "Categories" }, + "app.skin-site.admin.downloads.all": { "message": "All items" }, + "app.skin-site.admin.downloads.add-category": { "message": "Add" }, + "app.skin-site.admin.downloads.category-name": { "message": "Category name" }, + "app.skin-site.admin.downloads.remove-category": { "message": "Remove" }, + "app.skin-site.admin.downloads.total": { "message": "{count} items" }, + "app.skin-site.admin.downloads.add-item": { "message": "New item" }, + "app.skin-site.admin.downloads.save": { "message": "Save" }, + "app.skin-site.admin.downloads.cancel": { "message": "Cancel" }, + "app.skin-site.admin.downloads.edit": { "message": "Edit" }, + "app.skin-site.admin.downloads.remove": { "message": "Delete" }, + "app.skin-site.admin.downloads.filename": { "message": "File name" }, + "app.skin-site.admin.downloads.description": { "message": "Description" }, + "app.skin-site.admin.downloads.routes": { "message": "Download routes" }, + "app.skin-site.admin.downloads.route-name": { "message": "Name" }, + "app.skin-site.admin.downloads.route-url": { "message": "URL" }, + "app.skin-site.admin.downloads.add-route": { "message": "Add route" }, + "app.skin-site.admin.downloads.remove-route": { "message": "Remove" }, + "app.skin-site.admin.downloads.statuses": { "message": "Statuses" }, + "app.skin-site.admin.downloads.bind-category": { "message": "Categories" }, + "app.skin-site.admin.downloads.uploader": { "message": "by {name}" }, + "app.skin-site.admin.downloads.created": { "message": "Item created." }, + "app.skin-site.admin.downloads.updated": { "message": "Item updated." }, + "app.skin-site.admin.downloads.deleted": { "message": "Item deleted." }, + "app.skin-site.admin.downloads.category-added": { + "message": "Category added." + }, + "app.skin-site.admin.downloads.category-deleted": { + "message": "Category deleted." + }, + "app.skin-site.admin.downloads.confirm-delete-item": { + "message": "Delete “{name}”? This cannot be undone." + }, + "app.skin-site.admin.downloads.confirm-delete-category": { + "message": "Delete category “{name}”?" + }, + "app.skin-site.admin.servers.title": { "message": "Map servers" }, + "app.skin-site.admin.servers.loading": { "message": "Loading…" }, + "app.skin-site.admin.servers.failed": { + "message": "Could not load servers." + }, + "app.skin-site.admin.servers.empty": { + "message": "No map servers configured." + }, + "app.skin-site.admin.servers.server-name": { "message": "Server name" }, + "app.skin-site.admin.servers.internal": { "message": "Internal" }, + "app.skin-site.admin.servers.maps": { "message": "Maps" }, + "app.skin-site.admin.servers.map-name": { "message": "Map name" }, + "app.skin-site.admin.servers.map-url": { "message": "Map URL" }, + "app.skin-site.admin.servers.add-map": { "message": "Add map" }, + "app.skin-site.admin.servers.remove-map": { "message": "Remove" }, + "app.skin-site.admin.servers.add-server": { "message": "Add server" }, + "app.skin-site.admin.servers.remove-server": { "message": "Remove server" }, + "app.skin-site.admin.servers.save": { "message": "Save changes" }, + "app.skin-site.admin.servers.saving": { "message": "Saving…" }, + "app.skin-site.admin.servers.saved": { "message": "Map servers saved." }, + "app.skin-site.admin.audit.title": { "message": "Access audit" }, + "app.skin-site.admin.audit.loading": { "message": "Loading…" }, + "app.skin-site.admin.audit.failed": { + "message": "Could not load audit log." + }, + "app.skin-site.admin.audit.empty": { "message": "No audit entries." }, + "app.skin-site.admin.audit.subject": { "message": "Subject" }, + "app.skin-site.admin.audit.action": { "message": "Action" }, + "app.skin-site.admin.audit.source-ip": { "message": "Source IP" }, + "app.skin-site.admin.audit.reported-ip": { "message": "Reported player IP" }, + "app.skin-site.admin.audit.count": { "message": "Count" }, + "app.skin-site.admin.audit.first-at": { "message": "First seen" }, + "app.skin-site.admin.audit.last-at": { "message": "Last seen" }, + "app.skin-site.admin.audit.proxy": { "message": "Proxy" }, + "app.skin-site.admin.audit.internal": { "message": "Internal" }, + "app.skin-site.admin.audit.search-subject": { "message": "Subject" }, + "app.skin-site.admin.audit.search-ip": { "message": "IP" }, + "app.skin-site.admin.audit.search-action": { "message": "Action" }, + "app.skin-site.admin.audit.search": { "message": "Search" }, + "app.skin-site.admin.audit.clear": { "message": "Clear" }, + "app.skin-site.admin.audit.load-more": { "message": "Load more" }, + "app.skin-site.admin.audit.retention": { "message": "Retention (days)" }, + "app.skin-site.admin.audit.record-limit": { "message": "Record limit" }, + "app.skin-site.admin.audit.save-retention": { "message": "Save" }, + "app.skin-site.admin.audit.retention-saved": { + "message": "Retention updated." + }, + "app.skin-site.admin.donations.title": { "message": "Donations" }, + "app.skin-site.admin.donations.loading": { "message": "Loading…" }, + "app.skin-site.admin.donations.failed": { + "message": "Could not load donations." + }, + "app.skin-site.admin.donations.empty": { "message": "No donations yet." }, + "app.skin-site.admin.donations.total-amount": { "message": "Total" }, + "app.skin-site.admin.donations.donor-count": { "message": "Donors" }, + "app.skin-site.admin.donations.donor": { "message": "Donor" }, + "app.skin-site.admin.donations.amount": { "message": "Amount" }, + "app.skin-site.admin.donations.updated-at": { "message": "Updated" }, + "app.skin-site.admin.donations.external": { "message": "External" }, + "app.skin-site.admin.donations.linked": { "message": "Linked" }, + "app.skin-site.admin.donations.create": { "message": "Add donation" }, + "app.skin-site.admin.donations.save": { "message": "Save" }, + "app.skin-site.admin.donations.cancel": { "message": "Cancel" }, + "app.skin-site.admin.donations.edit": { "message": "Edit" }, + "app.skin-site.admin.donations.remove": { "message": "Delete" }, + "app.skin-site.admin.donations.amount-field": { "message": "Amount" }, + "app.skin-site.admin.donations.display-name": { "message": "Display name" }, + "app.skin-site.admin.donations.user-uuid": { "message": "User UUID" }, + "app.skin-site.admin.donations.qq": { "message": "QQ" }, + "app.skin-site.admin.donations.append-mode": { + "message": "Append to existing amount" + }, + "app.skin-site.admin.donations.created": { "message": "Donation created." }, + "app.skin-site.admin.donations.updated": { "message": "Donation updated." }, + "app.skin-site.admin.donations.deleted": { "message": "Donation deleted." }, + "app.skin-site.admin.donations.confirm-delete": { + "message": "Delete the donation from “{name}”? This cannot be undone." + }, + "app.skin-site.admin.donations.load-more": { "message": "Load more" }, + "app.skin-site.admin.mods.title": { "message": "Mods" }, + "app.skin-site.admin.mods.tab-mods": { "message": "Mod files" }, + "app.skin-site.admin.mods.tab-tags": { "message": "Rule tags" }, + "app.skin-site.admin.mods.tab-runtime": { "message": "Runtime" }, + "app.skin-site.admin.mods.loading": { "message": "Loading…" }, + "app.skin-site.admin.mods.failed": { "message": "Could not load mods." }, + "app.skin-site.admin.mods.empty": { "message": "No mods found." }, + "app.skin-site.admin.mods.total": { "message": "{count} mods" }, + "app.skin-site.admin.mods.search": { "message": "Search by name" }, + "app.skin-site.admin.mods.filter-all": { "message": "All tags" }, + "app.skin-site.admin.mods.prev": { "message": "Previous" }, + "app.skin-site.admin.mods.next": { "message": "Next" }, + "app.skin-site.admin.mods.page": { "message": "Page {page}" }, + "app.skin-site.admin.mods.name": { "message": "Name" }, + "app.skin-site.admin.mods.version": { "message": "Version" }, + "app.skin-site.admin.mods.mod-id": { "message": "Mod ID" }, + "app.skin-site.admin.mods.size": { "message": "Size" }, + "app.skin-site.admin.mods.loaders": { "message": "Loaders" }, + "app.skin-site.admin.mods.domain-rules": { "message": "Domain rules" }, + "app.skin-site.admin.mods.edit": { "message": "Edit" }, + "app.skin-site.admin.mods.save": { "message": "Save" }, + "app.skin-site.admin.mods.cancel": { "message": "Cancel" }, + "app.skin-site.admin.mods.remove": { "message": "Delete" }, + "app.skin-site.admin.mods.updated": { "message": "Mod updated." }, + "app.skin-site.admin.mods.deleted": { "message": "Mod deleted." }, + "app.skin-site.admin.mods.confirm-delete": { + "message": "Delete mod “{name}”? This cannot be undone." + }, + "app.skin-site.admin.mods.rule-tags": { "message": "Rule tags" }, + "app.skin-site.admin.mods.tag-name": { "message": "Tag name" }, + "app.skin-site.admin.mods.tag-rules": { "message": "Rules" }, + "app.skin-site.admin.mods.tag-rules-hint": { + "message": "One rule per line." + }, + "app.skin-site.admin.mods.new-tag": { "message": "New tag" }, + "app.skin-site.admin.mods.tag-created": { "message": "Tag created." }, + "app.skin-site.admin.mods.tag-updated": { "message": "Tag updated." }, + "app.skin-site.admin.mods.tag-deleted": { "message": "Tag deleted." }, + "app.skin-site.admin.mods.confirm-delete-tag": { + "message": "Delete tag “{name}”?" + }, + "app.skin-site.admin.mods.runtime": { "message": "Runtime releases" }, + "app.skin-site.admin.mods.manifest-url": { "message": "Manifest URL" }, + "app.skin-site.admin.mods.upload-runtime": { "message": "Upload runtime" }, + "app.skin-site.admin.mods.runtime-version": { "message": "Version" }, + "app.skin-site.admin.mods.uploading": { "message": "Uploading…" }, + "app.skin-site.admin.mods.runtime-uploaded": { + "message": "Runtime uploaded." + }, + "app.skin-site.admin.mods.activate": { "message": "Activate" }, + "app.skin-site.admin.mods.activated": { "message": "Runtime activated." }, + "app.skin-site.admin.mods.available": { "message": "Available" }, + "app.skin-site.admin.mods.unavailable": { "message": "Unavailable" }, + "app.skin-site.admin.mods.active": { "message": "Active" }, + "app.skin-site.admin.mods.uploader": { "message": "by {name}" }, + "app.skin-site.home.nav.title": { "message": "Skin site" }, + "app.skin-site.home.nav.download": { "message": "Downloads" }, + "app.skin-site.home.nav.download-desc": { + "message": "Browse files shared by the server." + }, + "app.skin-site.home.nav.review": { "message": "Player review" }, + "app.skin-site.home.nav.review-desc": { + "message": "Submit and review player applications." + }, + "app.skin-site.home.nav.wiki": { "message": "Server wiki" }, + "app.skin-site.home.nav.wiki-desc": { + "message": "Guides and documentation for the server." + }, + "app.skin-site.home.nav.bugs": { "message": "Bug tracker" }, + "app.skin-site.home.nav.bugs-desc": { + "message": "Report issues and follow their progress." + }, + "app.skin-site.home.nav.map": { "message": "Server map" }, + "app.skin-site.home.nav.map-desc": { + "message": "Explore the live world map." + }, + "app.skin-site.home.nav.profile": { "message": "Profile" }, + "app.skin-site.home.nav.profile-desc": { + "message": "Manage your account and textures." + }, + "app.skin-site.admin.wiki.title": { "message": "Wiki" }, + "app.skin-site.admin.wiki.tab-page": { "message": "Page" }, + "app.skin-site.admin.wiki.tab-audit": { "message": "Audit log" }, + "app.skin-site.admin.wiki.tab-settings": { "message": "Settings" }, + "app.skin-site.admin.wiki.loading": { "message": "Loading…" }, + "app.skin-site.admin.wiki.page-path": { "message": "Page path" }, + "app.skin-site.admin.wiki.load-page": { "message": "Load page" }, + "app.skin-site.admin.wiki.page-not-found": { "message": "Page not found." }, + "app.skin-site.admin.wiki.revision": { "message": "Revision" }, + "app.skin-site.admin.wiki.author": { "message": "Author" }, + "app.skin-site.admin.wiki.updated-at": { "message": "Updated" }, + "app.skin-site.admin.wiki.categories": { "message": "Categories" }, + "app.skin-site.admin.wiki.read-policy": { "message": "Read policy" }, + "app.skin-site.admin.wiki.edit-policy": { "message": "Edit policy" }, + "app.skin-site.admin.wiki.save-protect": { "message": "Save policies" }, + "app.skin-site.admin.wiki.protect-saved": { + "message": "Page policies updated." + }, + "app.skin-site.admin.wiki.set-home": { "message": "Set as home page" }, + "app.skin-site.admin.wiki.home-set": { "message": "Home page updated." }, + "app.skin-site.admin.wiki.set-deleted": { "message": "Mark as deleted" }, + "app.skin-site.admin.wiki.set-restored": { "message": "Restore page" }, + "app.skin-site.admin.wiki.deleted-updated": { + "message": "Page deletion state updated." + }, + "app.skin-site.admin.wiki.audit-empty": { "message": "No audit entries." }, + "app.skin-site.admin.wiki.audit-target": { "message": "Target" }, + "app.skin-site.admin.wiki.load-more": { "message": "Load more" }, + "app.skin-site.admin.wiki.settings-hint": { + "message": "Comma separated domains." + }, + "app.skin-site.admin.wiki.domains": { "message": "Domains" }, + "app.skin-site.admin.wiki.home-page": { "message": "Home page" }, + "app.skin-site.admin.wiki.default-skin": { "message": "Default skin" }, + "app.skin-site.admin.wiki.max-page-bytes": { "message": "Max page bytes" }, + "app.skin-site.admin.wiki.max-attachment-bytes": { + "message": "Max attachment bytes" + }, + "app.skin-site.admin.wiki.save-settings": { "message": "Save settings" }, + "app.skin-site.admin.wiki.settings-saved": { "message": "Settings saved." }, + "app.skin-site.admin.review.tab-list": { "message": "Submissions" }, + "app.skin-site.admin.review.tab-papers": { "message": "Papers" }, + "app.skin-site.admin.review.papers-empty": { + "message": "No review papers yet." + }, + "app.skin-site.admin.review.new-paper": { "message": "New paper" }, + "app.skin-site.admin.review.edit-paper": { "message": "Edit" }, + "app.skin-site.admin.review.paper-title": { "message": "Title" }, + "app.skin-site.admin.review.paper-annotation": { "message": "Description" }, + "app.skin-site.admin.review.paper-enabled": { "message": "Enabled" }, + "app.skin-site.admin.review.paper-mode": { "message": "Mode" }, + "app.skin-site.admin.review.paper-pass-score": { "message": "Pass score" }, + "app.skin-site.admin.review.paper-target-permissions": { + "message": "Target permissions" + }, + "app.skin-site.admin.review.paper-questions": { "message": "Questions" }, + "app.skin-site.admin.review.add-question": { "message": "Add question" }, + "app.skin-site.admin.review.question-title": { "message": "Question title" }, + "app.skin-site.admin.review.question-type": { "message": "Type" }, + "app.skin-site.admin.review.question-score": { "message": "Score" }, + "app.skin-site.admin.review.question-annotation": { "message": "Annotation" }, + "app.skin-site.admin.review.add-option": { "message": "Add option" }, + "app.skin-site.admin.review.option-description": { "message": "Option text" }, + "app.skin-site.admin.review.option-correct": { "message": "Correct" }, + "app.skin-site.admin.review.remove-question": { "message": "Remove" }, + "app.skin-site.admin.review.question-no": { "message": "Question {n}" }, + "app.skin-site.admin.review.paper-created": { "message": "Paper created." }, + "app.skin-site.admin.review.paper-saved": { "message": "Paper saved." }, + "app.skin-site.admin.review.mail-title": { "message": "Pass mail" }, + "app.skin-site.admin.review.mail-enabled": { "message": "Send mail on pass" }, + "app.skin-site.admin.review.mail-subject": { "message": "Subject" }, + "app.skin-site.admin.review.mail-message": { "message": "Body" }, + "app.skin-site.admin.review.mail-extra": { "message": "Extra text" }, + "app.skin-site.admin.review.mail-include-invite": { + "message": "Include invite code" + }, + "app.skin-site.admin.review.prevent-duplicate": { + "message": "Reject duplicate submissions" + }, + "app.skin-site.admin.review.copy-link": { "message": "Copy link" }, + "app.skin-site.admin.review.link-copied": { "message": "Link copied." }, + "app.skin-site.admin.review.move-up": { "message": "Move up" }, + "app.skin-site.admin.review.move-down": { "message": "Move down" }, + "app.skin-site.admin.review.mail-subject-required": { + "message": "Subject is required when mail is enabled." + }, + "app.skin-site.admin.review.mail-message-required": { + "message": "Body is required when mail is enabled." + }, + "app.skin-site.admin.users.actions": { "message": "Actions" }, + "app.skin-site.admin.users.audit": { "message": "Audit" }, + "app.skin-site.admin.users.audit-empty": { + "message": "No audit records yet." + }, + "app.skin-site.admin.users.audit-more": { "message": "Load earlier" }, + "app.skin-site.admin.users.audit-title": { + "message": "User management audit" + }, + "app.skin-site.admin.users.bot": { "message": "Bot" }, + "app.skin-site.admin.users.bot-active": { "message": "Token valid" }, + "app.skin-site.admin.users.bot-ban": { "message": "Ban bot creation" }, + "app.skin-site.admin.users.bot-creation-banned": { + "message": "Token creation banned" + }, + "app.skin-site.admin.users.bot-exists": { "message": "Bot created" }, + "app.skin-site.admin.users.bot-inactive": { "message": "Token invalidated" }, + "app.skin-site.admin.users.bot-invalidate": { "message": "Invalidate token" }, + "app.skin-site.admin.users.bot-not-exists": { "message": "No bot yet" }, + "app.skin-site.admin.users.bot-save-username": { + "message": "Save bot username" + }, + "app.skin-site.admin.users.bot-title": { "message": "Bot management" }, + "app.skin-site.admin.users.bot-token-hint": { "message": "Token hint" }, + "app.skin-site.admin.users.bot-unban": { "message": "Unban bot creation" }, + "app.skin-site.admin.users.bot-username": { "message": "Bot username" }, + "app.skin-site.admin.users.bound-players-title": { + "message": "Linked players" + }, + "app.skin-site.admin.users.frequency": { "message": "Rate limit" }, + "app.skin-site.admin.users.frequency-clear": { "message": "Clear limit" }, + "app.skin-site.admin.users.frequency-current": { + "message": "Currently {percent}%" + }, + "app.skin-site.admin.users.frequency-hint": { + "message": "Packets from this user will be dropped at the given rate." + }, + "app.skin-site.admin.users.frequency-none": { "message": "Not enabled" }, + "app.skin-site.admin.users.frequency-range": { + "message": "Only integer values from 10% to 100% are allowed." + }, + "app.skin-site.admin.users.frequency-save": { "message": "Save limit" }, + "app.skin-site.admin.users.frequency-title": { "message": "Rate limit" }, + "app.skin-site.admin.users.invite": { "message": "Invite user" }, + "app.skin-site.admin.users.invite-copied": { + "message": "Invite code copied." + }, + "app.skin-site.admin.users.invite-copy": { "message": "Copy" }, + "app.skin-site.admin.users.invite-email": { "message": "Email" }, + "app.skin-site.admin.users.invite-email-invalid": { + "message": "Enter a valid email address." + }, + "app.skin-site.admin.users.invite-generate": { + "message": "Generate invite code" + }, + "app.skin-site.admin.users.invite-title": { "message": "Invite user" }, + "app.skin-site.admin.users.legacy-adapted": { + "message": "Legacy internal adapted" + }, + "app.skin-site.admin.users.registered-at": { "message": "Registered at" }, + "app.skin-site.admin.users.status": { "message": "Status" }, + "app.skin-site.admin.users.status-banned": { "message": "Banned" }, + "app.skin-site.admin.users.status-normal": { "message": "Normal" }, + "app.skin-site.admin.mods.upload": { "message": "Upload" }, + "app.skin-site.admin.mods.select-mode": { "message": "Select multiple" }, + "app.skin-site.admin.mods.exit-select": { "message": "Done selecting" }, + "app.skin-site.admin.mods.select-all": { "message": "Select all" }, + "app.skin-site.admin.mods.clear-selection": { "message": "Clear selection" }, + "app.skin-site.admin.mods.selected-count": { "message": "{count} selected" }, + "app.skin-site.admin.mods.delete-selected": { "message": "Delete selected" }, + "app.skin-site.admin.mods.confirm-delete-multi": { + "message": "Delete {count} selected mods? This cannot be undone." + }, + "app.skin-site.admin.mods.deleted-multi": { + "message": "Selected mods deleted." + }, + "app.skin-site.admin.mods.server-address": { "message": "Server address" }, + "app.skin-site.admin.mods.server-address-hint": { + "message": "Filter by server address" + }, + "app.skin-site.admin.mods.apply": { "message": "Apply" }, + "app.skin-site.admin.mods.clear": { "message": "Clear" }, + "app.skin-site.admin.mods.upload-title": { "message": "Upload mods" }, + "app.skin-site.admin.mods.upload-drop": { + "message": "Drag .jar files here, or click to choose" + }, + "app.skin-site.admin.mods.upload-sub": { + "message": "Multiple files supported, up to {size} MB each" + }, + "app.skin-site.admin.mods.upload-tags": { "message": "Attach rule tags" }, + "app.skin-site.admin.mods.upload-queue": { "message": "Files" }, + "app.skin-site.admin.mods.upload-pending": { "message": "Pending" }, + "app.skin-site.admin.mods.upload-checking": { "message": "Checking…" }, + "app.skin-site.admin.mods.upload-uploading": { "message": "Uploading…" }, + "app.skin-site.admin.mods.upload-conflict": { "message": "Name exists" }, + "app.skin-site.admin.mods.upload-success": { "message": "Done" }, + "app.skin-site.admin.mods.upload-error": { "message": "Failed" }, + "app.skin-site.admin.mods.upload-exists": { + "message": "This file already exists on the server." + }, + "app.skin-site.admin.mods.upload-name-conflict": { + "message": "A mod with the same file name already exists" + }, + "app.skin-site.admin.mods.upload-name-conflict-hint": { + "message": "Overwrite the existing mod, or skip this file." + }, + "app.skin-site.admin.mods.upload-overwrite": { "message": "Overwrite" }, + "app.skin-site.admin.mods.upload-skip": { "message": "Skip" }, + "app.skin-site.admin.mods.upload-close": { "message": "Close" }, + "app.skin-site.admin.mods.upload-all-done": { + "message": "All files processed." + }, + "app.skin-site.admin.mods.upload-too-large": { + "message": "File too large: {name}" + }, + "app.skin-site.chat.avatar.label": { "message": "Room avatar" }, + "app.skin-site.chat.avatar.upload": { "message": "Upload avatar" }, + "app.skin-site.chat.avatar.replace": { "message": "Replace avatar" }, + "app.skin-site.chat.avatar.remove": { "message": "Remove avatar" }, + "app.skin-site.chat.avatar.hint": { + "message": "PNG, JPEG or WebP, up to 8192 px per side and 5 MB." + }, + "app.skin-site.chat.avatar.bad-format": { + "message": "Only PNG, JPEG and WebP are supported." + }, + "app.skin-site.chat.avatar.too-large": { + "message": "Avatar must not exceed 5 MB." + }, + "app.skin-site.chat.avatar.not-image": { + "message": "Avatar must be an image." + }, + "app.skin-site.chat.admin.title": { "message": "Chat rooms" }, + "app.skin-site.chat.admin.subtitle": { + "message": "Create public or private rooms and hand daily moderation to trusted members." + }, + "app.skin-site.chat.admin.create-room": { "message": "Create room" }, + "app.skin-site.chat.admin.loading": { "message": "Loading…" }, + "app.skin-site.chat.admin.failed": { "message": "Could not load rooms." }, + "app.skin-site.chat.admin.empty": { "message": "No chat rooms yet." }, + "app.skin-site.chat.admin.edit": { "message": "Edit" }, + "app.skin-site.chat.admin.remove": { "message": "Delete" }, + "app.skin-site.chat.admin.save": { "message": "Save" }, + "app.skin-site.chat.admin.cancel": { "message": "Cancel" }, + "app.skin-site.chat.admin.name": { "message": "Name" }, + "app.skin-site.chat.admin.description": { "message": "Description" }, + "app.skin-site.chat.admin.visibility": { "message": "Visibility" }, + "app.skin-site.chat.admin.visibility-public": { "message": "Public" }, + "app.skin-site.chat.admin.visibility-private": { "message": "Private" }, + "app.skin-site.chat.admin.kind": { "message": "Kind" }, + "app.skin-site.chat.admin.kind-standard": { "message": "Standard" }, + "app.skin-site.chat.admin.kind-settlement": { "message": "Settlement" }, + "app.skin-site.chat.admin.prerequisite-mode": { + "message": "Prerequisite mode" + }, + "app.skin-site.chat.admin.prerequisite-any": { "message": "Any" }, + "app.skin-site.chat.admin.prerequisite-all": { "message": "All" }, + "app.skin-site.chat.admin.prerequisite-permissions": { + "message": "Required permissions" + }, + "app.skin-site.chat.admin.prerequisite-hint": { + "message": "Comma separated. Leave empty for no restriction." + }, + "app.skin-site.chat.admin.created": { "message": "Room created." }, + "app.skin-site.chat.admin.updated": { "message": "Room updated." }, + "app.skin-site.chat.admin.deleted": { "message": "Room deleted." }, + "app.skin-site.chat.admin.confirm-delete": { + "message": "Permanently delete room “{name}” and all its messages?" + }, + "app.skin-site.chat.admin.manager-badge": { "message": "Manager" }, + "app.skin-site.chat.admin.voice-badge": { "message": "Voice" }, + "app.skin-site.chat.user-picker.label": { "message": "Pick a user" }, + "app.skin-site.chat.user-picker.placeholder": { + "message": "Search username, email or account ID" + }, + "app.skin-site.chat.user-picker.by-user": { "message": "By user" }, + "app.skin-site.chat.user-picker.by-player": { "message": "By player" }, + "app.skin-site.chat.user-picker.hint": { + "message": "Fuzzy search on username and email, or search by account ID." + }, + "app.skin-site.chat.user-picker.player-hint": { + "message": "Enter a player name to find the bound user." + }, + "app.skin-site.chat.user-picker.empty": { "message": "No matching user." }, + "app.skin-site.chat.user-picker.banned": { + "message": "This account is banned." + }, + "app.skin-site.chat.user-picker.guest": { + "message": "Guests cannot become a manager or settlement owner." + }, + "app.skin-site.chat.user-picker.already-in": { + "message": "This user is already in the room." + }, + "app.skin-site.chat.user-picker.not-allowed": { + "message": "This user is outside the allowed range." + }, + "app.skin-site.chat.user-picker.select": { "message": "Select" }, + "app.skin-site.chat.user-picker.selected": { "message": "Selected" }, + "app.skin-site.chat.user-picker.id": { "message": "ID" }, + "app.skin-site.chat.admin.managers": { "message": "Managers" }, + "app.skin-site.chat.admin.manager-title": { "message": "Room manager" }, + "app.skin-site.chat.admin.manager-hint": { + "message": "Managers can moderate members, messages and files in this room." + }, + "app.skin-site.chat.admin.grant": { "message": "Grant" }, + "app.skin-site.chat.admin.revoke": { "message": "Revoke" }, + "app.skin-site.chat.admin.manager-granted": { "message": "Manager granted." }, + "app.skin-site.chat.admin.manager-revoked": { "message": "Manager revoked." }, + "app.skin-site.chat.admin.owner-title": { "message": "Settlement owner" }, + "app.skin-site.chat.admin.owner-hint": { + "message": "Assign the first settlement owner for this room." + }, + "app.skin-site.chat.admin.owner-assigned": { + "message": "Settlement owner assigned." + }, + "app.skin-site.chat.admin.owner-current": { + "message": "Current owner: {name}" + }, + "app.skin-site.chat.admin.owner-none": { + "message": "No settlement owner yet." + }, + "app.skin-site.chat.admin.audit": { "message": "Audit" }, + "app.skin-site.chat.admin.audit-title": { "message": "Room audit" }, + "app.skin-site.chat.admin.audit-empty": { + "message": "No audit records yet." + }, + "app.skin-site.chat.admin.audit-target": { "message": "Target: {name}" }, + "app.skin-site.chat.admin.close": { "message": "Close" }, + "app.skin-site.chat.voice-runtime-title": { + "message": "Realtime voice runtime" + }, + "app.skin-site.chat.voice-logs": { "message": "View logs" }, + "app.skin-site.chat.voice-config": { "message": "Configure runtime" }, + "app.skin-site.chat.voice-retry": { "message": "Retry deployment" }, + "app.skin-site.chat.voice-config-title": { + "message": "Voice runtime configuration" + }, + "app.skin-site.chat.voice-logs-title": { "message": "LiveKit logs" }, + "app.skin-site.chat.voice-capacity-title": { "message": "Voice capacity" }, + "app.skin-site.chat.voice-capacity": { "message": "Voice capacity" }, + "app.skin-site.chat.participant-limit": { "message": "Participant limit" }, + "app.skin-site.chat.listener-limit": { "message": "Listener limit" }, + "app.skin-site.chat.voice-capacity-updated": { + "message": "Voice capacity updated." + }, + "app.skin-site.chat.voice-enabled": { "message": "Enable realtime voice" }, + "app.skin-site.chat.voice-runtime-path": { "message": "Runtime directory" }, + "app.skin-site.chat.voice-mirror": { "message": "Mirror base URL" }, + "app.skin-site.chat.voice-public-url": { "message": "Public URL" }, + "app.skin-site.chat.voice-bind": { "message": "Bind address" }, + "app.skin-site.chat.voice-signal-port": { "message": "Signal port" }, + "app.skin-site.chat.voice-rtc-tcp-port": { "message": "Media TCP port" }, + "app.skin-site.chat.voice-rtc-udp-port": { "message": "Media UDP port" }, + "app.skin-site.chat.voice-startup-timeout": { + "message": "Startup timeout (s)" + }, + "app.skin-site.chat.voice-use-external-ip": { "message": "Use external IP" }, + "app.skin-site.chat.voice-node-ip": { "message": "Node IP" }, + "app.skin-site.chat.voice-saved": { "message": "Voice configuration saved." }, + "app.skin-site.chat.voice-logs-auto-refresh": { "message": "Auto refresh" }, + "app.skin-site.chat.voice-logs-refresh": { "message": "Refresh" }, + "app.skin-site.chat.voice-logs-empty": { "message": "No logs yet." }, + "app.skin-site.chat.admin.voice-runtime-title": { + "message": "Realtime voice runtime" + }, + "app.skin-site.chat.admin.voice-logs": { "message": "View logs" }, + "app.skin-site.chat.admin.voice-config": { "message": "Configure runtime" }, + "app.skin-site.chat.admin.voice-retry": { "message": "Retry deployment" }, + "app.skin-site.chat.admin.voice-config-title": { + "message": "Voice runtime configuration" + }, + "app.skin-site.chat.admin.voice-logs-title": { "message": "LiveKit logs" }, + "app.skin-site.chat.admin.voice-capacity-title": { + "message": "Voice capacity" + }, + "app.skin-site.chat.admin.voice-capacity": { "message": "Voice capacity" }, + "app.skin-site.chat.admin.participant-limit": { + "message": "Participant limit" + }, + "app.skin-site.chat.admin.listener-limit": { "message": "Listener limit" }, + "app.skin-site.chat.admin.voice-capacity-updated": { + "message": "Voice capacity updated." + }, + "app.skin-site.chat.admin.voice-enabled": { + "message": "Enable realtime voice" + }, + "app.skin-site.chat.admin.voice-runtime-path": { + "message": "Runtime directory" + }, + "app.skin-site.chat.admin.voice-mirror": { "message": "Mirror base URL" }, + "app.skin-site.chat.admin.voice-public-url": { "message": "Public URL" }, + "app.skin-site.chat.admin.voice-bind": { "message": "Bind address" }, + "app.skin-site.chat.admin.voice-signal-port": { "message": "Signal port" }, + "app.skin-site.chat.admin.voice-rtc-tcp-port": { + "message": "Media TCP port" + }, + "app.skin-site.chat.admin.voice-rtc-udp-port": { + "message": "Media UDP port" + }, + "app.skin-site.chat.admin.voice-startup-timeout": { + "message": "Startup timeout (s)" + }, + "app.skin-site.chat.admin.voice-use-external-ip": { + "message": "Use external IP" + }, + "app.skin-site.chat.admin.voice-node-ip": { "message": "Node IP" }, + "app.skin-site.chat.admin.voice-saved": { + "message": "Voice configuration saved." + }, + "app.skin-site.chat.admin.voice-logs-auto-refresh": { + "message": "Auto refresh" + }, + "app.skin-site.chat.admin.voice-logs-refresh": { "message": "Refresh" }, + "app.skin-site.chat.admin.voice-logs-empty": { "message": "No logs yet." }, + "app.skin-site.admin.wiki.tab-migration": { "message": "Migration" }, + "app.skin-site.admin.wiki.migration-title": { + "message": "MediaWiki migration" + }, + "app.skin-site.admin.wiki.migration-hint": { + "message": "Migrated content lands in a hidden staging area and is published in one batch after every page is reviewed." + }, + "app.skin-site.admin.wiki.auto-title": { + "message": "Read from MediaWiki API" + }, + "app.skin-site.admin.wiki.api-url": { "message": "api.php URL" }, + "app.skin-site.admin.wiki.bot-username": { + "message": "Bot username (optional)" + }, + "app.skin-site.admin.wiki.bot-password": { + "message": "Bot password (optional)" + }, + "app.skin-site.admin.wiki.credentials-hint": { + "message": "Credentials stay in memory for this job only. HTTPS is required when supplied." + }, + "app.skin-site.admin.wiki.allow-private": { + "message": "Allow private network source" + }, + "app.skin-site.admin.wiki.allow-private-hint": { + "message": "Private sources may reach services inside the server network." + }, + "app.skin-site.admin.wiki.start-auto": { + "message": "Create automatic migration job" + }, + "app.skin-site.admin.wiki.xml-title": { "message": "Import MediaWiki XML" }, + "app.skin-site.admin.wiki.xml-file": { "message": "Export file" }, + "app.skin-site.admin.wiki.start-xml": { "message": "Upload and stage" }, + "app.skin-site.admin.wiki.stale-rules": { + "message": "Stale page detection rules" + }, + "app.skin-site.admin.wiki.stale-days": { "message": "Days without update" }, + "app.skin-site.admin.wiki.maintainer-window": { + "message": "Maintainer window (days)" + }, + "app.skin-site.admin.wiki.max-maintainers": { "message": "Max maintainers" }, + "app.skin-site.admin.wiki.stale-markers": { + "message": "Stale categories, templates or text" + }, + "app.skin-site.admin.wiki.stale-markers-hint": { + "message": "Comma separated" + }, + "app.skin-site.admin.wiki.jobs": { "message": "Migration jobs" }, + "app.skin-site.admin.wiki.refresh-jobs": { "message": "Refresh" }, + "app.skin-site.admin.wiki.jobs-empty": { + "message": "No migration jobs yet." + }, + "app.skin-site.admin.wiki.reviewed-count": { + "message": "Reviewed {reviewed} / {total}" + }, + "app.skin-site.admin.wiki.imported-excluded": { + "message": "Imported {imported} · Excluded {excluded}" + }, + "app.skin-site.admin.wiki.view-job": { "message": "View job" }, + "app.skin-site.admin.wiki.delete-job": { "message": "Delete job record" }, + "app.skin-site.admin.wiki.confirm-delete-job": { + "message": "Delete migration job #{id}? This cannot be undone." + }, + "app.skin-site.admin.wiki.candidates": { "message": "Candidate pages" }, + "app.skin-site.admin.wiki.candidates-empty": { + "message": "Select a job to review its pages." + }, + "app.skin-site.admin.wiki.last-updated": { "message": "Updated {date}" }, + "app.skin-site.admin.wiki.maintainer-count": { + "message": "{count} maintainers" + }, + "app.skin-site.admin.wiki.conflict": { "message": "Title conflict" }, + "app.skin-site.admin.wiki.target-title": { "message": "Target title" }, + "app.skin-site.admin.wiki.overwrite": { "message": "Overwrite" }, + "app.skin-site.admin.wiki.import": { "message": "Import" }, + "app.skin-site.admin.wiki.exclude": { "message": "Exclude" }, + "app.skin-site.admin.wiki.publish": { "message": "Publish batch" }, + "app.skin-site.admin.wiki.rollback": { "message": "Roll back" }, + "app.skin-site.admin.wiki.confirm-rollback": { + "message": "Roll back this migration batch? Published pages will be reverted." + }, + "app.skin-site.admin.wiki.state-importing": { "message": "Importing" }, + "app.skin-site.admin.wiki.state-review": { "message": "Waiting review" }, + "app.skin-site.admin.wiki.state-publishing": { "message": "Publishing" }, + "app.skin-site.admin.wiki.state-published": { "message": "Published" }, + "app.skin-site.admin.wiki.state-failed": { "message": "Failed" }, + "app.skin-site.admin.wiki.state-rolled-back": { "message": "Rolled back" }, + "app.skin-site.admin.wiki.decision-pending": { "message": "Pending" }, + "app.skin-site.admin.wiki.decision-import": { "message": "Import" }, + "app.skin-site.admin.wiki.decision-exclude": { "message": "Exclude" }, + "app.skin-site.admin.wiki.migration-started": { + "message": "Migration job created." + }, + "app.skin-site.admin.wiki.xml-staged": { + "message": "XML parsed and staged for review." + }, + "app.skin-site.admin.wiki.published": { + "message": "Published {imported} pages, overwrote {overwritten}." + }, + "app.skin-site.admin.wiki.rolled-back": { + "message": "Migration batch rolled back." + }, + "app.skin-site.admin.wiki.job-deleted": { + "message": "Migration record deleted." + }, + "app.skin-site.admin.wiki.select-xml": { + "message": "Choose a MediaWiki XML file first." + }, + "app.skin-site.wiki.title": { "message": "StarLight Wiki" }, + "app.skin-site.wiki.search-placeholder": { "message": "Enter a page title" }, + "app.skin-site.wiki.open": { "message": "Open" }, + "app.skin-site.wiki.loading": { "message": "Loading…" }, + "app.skin-site.wiki.not-found": { "message": "Page not found." }, + "app.skin-site.wiki.empty": { + "message": "Enter a page title above to start reading." + }, + "app.skin-site.wiki.updated-at": { + "message": "Last edited {date} by {author}" + }, + "app.skin-site.wiki.revision": { "message": "Revision #{id}" }, + "app.skin-site.wiki.categories": { "message": "Categories" }, + "app.skin-site.wiki.back": { "message": "Back" }, + "app.skin-site.home.donation.thanks": { + "message": "Thank you to everyone who helps keep StarLight running." + }, + "app.skin-site.home.donation.empty": { "message": "No donations yet." }, + "app.skin-site.home.donation.list-failed": { + "message": "Could not load donations." + }, + "app.skin-site.home.donation.more": { "message": "Load more" }, + "app.skin-site.home.preview.players": { "message": "Players" }, + "app.skin-site.home.preview.empty": { "message": "No players yet" }, + "app.skin-site.home.preview.empty-hint": { + "message": "Sign in or add a Minecraft account in the sidebar to see your skin here." + }, + "app.skin-site.home.preview.unavailable": { + "message": "This player has no skin to preview." + }, + "app.skin-site.home.preview.loading": { "message": "Loading players…" }, + "app.skin-site.home.preview.failed": { + "message": "Could not load skin-site players." } } diff --git a/apps/app-frontend/src/locales/zh-CN/index.json b/apps/app-frontend/src/locales/zh-CN/index.json index c436fe2..dcba070 100644 --- a/apps/app-frontend/src/locales/zh-CN/index.json +++ b/apps/app-frontend/src/locales/zh-CN/index.json @@ -1,10 +1,451 @@ { + "app.hosted-packs.progress.pause": { "message": "暂停" }, + "app.hosted-packs.progress.resume": { "message": "继续" }, + "app.hosted-packs.progress.stop": { "message": "停止" }, + "app.downloads.status.paused": { "message": "已暂停" }, + + "app.skin-site.captcha.loading": { "message": "正在加载验证码…" }, + "app.skin-site.captcha.submit": { "message": "验证" }, + "app.skin-site.captcha.subtitle": { + "message": "拖动滑块,将图片旋转至正向。" + }, + "app.skin-site.captcha.title": { "message": "请完成人机验证" }, + "app.skin-site.downloads.all": { "message": "全部" }, + "app.skin-site.downloads.back": { "message": "返回主页" }, + "app.skin-site.downloads.empty": { "message": "暂无可下载的资源。" }, + "app.skin-site.downloads.failed": { "message": "加载下载资源失败。" }, + "app.skin-site.downloads.go": { "message": "下载" }, + "app.skin-site.downloads.loading": { "message": "正在加载…" }, + "app.skin-site.downloads.status.legacy": { "message": "旧版" }, + "app.skin-site.downloads.status.new": { "message": "新增" }, + "app.skin-site.downloads.status.ok": { "message": "可用" }, + "app.skin-site.downloads.status.outdated": { "message": "已过时" }, + "app.skin-site.downloads.status.removal": { "message": "待移除" }, + "app.skin-site.downloads.subtitle": { + "message": "服务器分享的文件,可选择分类筛选。" + }, + "app.skin-site.downloads.title": { "message": "资源下载" }, + "app.skin-site.downloads.uploader": { "message": "上传者:{name}" }, + "app.skin-site.home.announcements.empty": { "message": "暂无公告。" }, + "app.skin-site.home.announcements.failed": { "message": "加载公告失败。" }, + "app.skin-site.home.announcements.loading": { "message": "正在加载…" }, + "app.skin-site.home.announcements.title": { "message": "公告" }, + "app.skin-site.home.donation.donors": { "message": "{count} 位捐赠者" }, + "app.skin-site.home.donation.loading": { "message": "正在加载…" }, + "app.skin-site.home.donation.title": { "message": "鸣谢捐赠" }, + "app.skin-site.home.donation.total": { "message": "累计捐赠" }, + "app.skin-site.home.donation.unavailable": { + "message": "暂时无法获取捐赠统计。" + }, + "app.skin-site.login.forgot": { "message": "忘记密码?" }, + "app.skin-site.login.password": { "message": "密码" }, + "app.skin-site.login.password-hint": { + "message": "6~50 个字符,须包含大写字母、小写字母和数字。" + }, + "app.skin-site.login.register": { "message": "注册账号" }, + "app.skin-site.login.sign-in": { "message": "登录" }, + "app.skin-site.login.signing-in": { "message": "正在登录…" }, + "app.skin-site.login.success": { "message": "已登录 StarLight。" }, + "app.skin-site.login.title": { "message": "登录 StarLight" }, + "app.skin-site.login.username": { "message": "用户名或邮箱" }, + "app.skin-site.login.username-hint": { + "message": "3~16 个字符,或已注册的邮箱地址。" + }, + "app.skin-site.map.back": { "message": "返回主页" }, + "app.skin-site.map.empty": { "message": "暂无可用地图。" }, + "app.skin-site.map.external": { "message": "外部地图" }, + "app.skin-site.map.failed": { "message": "加载地图失败。" }, + "app.skin-site.map.internal": { "message": "内部地图" }, + "app.skin-site.map.loading": { "message": "正在加载地图…" }, + "app.skin-site.map.map": { "message": "地图" }, + "app.skin-site.map.open": { "message": "在浏览器中打开" }, + "app.skin-site.map.server": { "message": "服务器" }, + "app.skin-site.map.title": { "message": "服务器地图" }, + "app.skin-site.profile-view.back": { "message": "返回主页" }, + "app.skin-site.profile-view.cape": { "message": "披风" }, + "app.skin-site.profile-view.elytra": { "message": "鞘翅" }, + "app.skin-site.profile-view.loading": { "message": "正在加载角色…" }, + "app.skin-site.profile-view.no-players": { "message": "暂无角色。" }, + "app.skin-site.profile-view.readonly": { + "message": "Mojang 账号由 Mojang 管理,无法在此修改材质。" + }, + "app.skin-site.profile-view.remove": { "message": "移除" }, + "app.skin-site.profile-view.removed": { "message": "材质已移除。" }, + "app.skin-site.profile-view.select-hint": { + "message": "选择角色以预览和修改其材质。" + }, + "app.skin-site.profile-view.signed-out": { + "message": "登录后管理你的角色。" + }, + "app.skin-site.profile-view.skin": { "message": "皮肤" }, + "app.skin-site.profile-view.title": { "message": "我的角色" }, + "app.skin-site.profile-view.upload": { "message": "上传" }, + "app.skin-site.profile-view.uploaded": { "message": "材质已更新。" }, + "app.skin-site.profile.avatar": { "message": "头像" }, + "app.skin-site.profile.avatar-hint": { + "message": "建议使用正方形图片,系统会将中心区域裁剪为 256×256。" + }, + "app.skin-site.profile.avatar-uploaded": { "message": "头像已更新。" }, + "app.skin-site.profile.basic": { "message": "个人资料" }, + "app.skin-site.profile.choose-avatar": { "message": "选择图片" }, + "app.skin-site.profile.minecraft-password": { "message": "Minecraft 密码" }, + "app.skin-site.profile.minecraft-password-changed": { + "message": "Minecraft 密码已更新。" + }, + "app.skin-site.profile.minecraft-password-hint": { + "message": "用于启动器登录,默认与网站密码相同。" + }, + "app.skin-site.profile.mismatch": { "message": "两次输入的密码不一致。" }, + "app.skin-site.profile.new-password": { "message": "新密码" }, + "app.skin-site.profile.old-password": { "message": "当前密码" }, + "app.skin-site.profile.password-changed": { "message": "密码已更新。" }, + "app.skin-site.profile.password-hint": { + "message": "6~50 个字符,须包含大写字母、小写字母和数字。" + }, + "app.skin-site.profile.repeat-password": { "message": "再次输入新密码" }, + "app.skin-site.profile.reset-default": { "message": "重置为网站密码" }, + "app.skin-site.profile.save": { "message": "保存" }, + "app.skin-site.profile.saved": { "message": "已保存。" }, + "app.skin-site.profile.security": { "message": "安全设置" }, + "app.skin-site.profile.site-password-hint": { + "message": "用于登录皮肤站的密码。" + }, + "app.skin-site.profile.submit-password": { "message": "修改密码" }, + "app.skin-site.profile.title": { "message": "账号设置" }, + "app.skin-site.profile.username": { "message": "用户名" }, + "app.skin-site.profile.username-hint": { "message": "3~16 个字符。" }, + "app.skin-site.register.closed": { "message": "当前服务器暂未开放注册。" }, + "app.skin-site.register.code": { "message": "验证码" }, + "app.skin-site.register.email": { "message": "邮箱" }, + "app.skin-site.register.invite-code": { "message": "邀请码" }, + "app.skin-site.register.invite-required": { + "message": "此服务器需要邀请码才能注册。" + }, + "app.skin-site.register.mismatch": { "message": "两次输入的密码不一致。" }, + "app.skin-site.register.password": { "message": "密码" }, + "app.skin-site.register.password-hint": { + "message": "6~50 个字符,须包含大写字母、小写字母和数字。" + }, + "app.skin-site.register.qq": { "message": "QQ(选填)" }, + "app.skin-site.register.repeat-password": { "message": "再次输入密码" }, + "app.skin-site.register.resend-in": { "message": "已发送({seconds} 秒)" }, + "app.skin-site.register.send-code": { "message": "发送验证码" }, + "app.skin-site.register.sending": { "message": "正在发送…" }, + "app.skin-site.register.submit": { "message": "注册账号" }, + "app.skin-site.register.success": { "message": "账号已创建并登录。" }, + "app.skin-site.register.title": { "message": "注册 StarLight 账号" }, + "app.skin-site.reset.code": { "message": "验证码" }, + "app.skin-site.reset.email": { "message": "邮箱" }, + "app.skin-site.reset.email-hint": { + "message": "请输入注册时使用的邮箱地址。" + }, + "app.skin-site.reset.mismatch": { "message": "两次输入的密码不一致。" }, + "app.skin-site.reset.new-password": { "message": "新密码" }, + "app.skin-site.reset.password-hint": { + "message": "6~50 个字符,须包含大写字母、小写字母和数字。" + }, + "app.skin-site.reset.repeat-password": { "message": "再次输入密码" }, + "app.skin-site.reset.resend-in": { "message": "已发送({seconds} 秒)" }, + "app.skin-site.reset.send-code": { "message": "发送验证码" }, + "app.skin-site.reset.sending": { "message": "正在发送…" }, + "app.skin-site.reset.submit": { "message": "重置密码" }, + "app.skin-site.reset.success": { "message": "密码已更新,现在可以登录。" }, + "app.skin-site.reset.title": { "message": "重置密码" }, + "app.skin-site.review.back": { "message": "返回主页" }, + "app.skin-site.review.back-to-list": { "message": "返回申请列表" }, + "app.skin-site.review.email": { "message": "你的邮箱" }, + "app.skin-site.review.email-hint": { "message": "审核结果将发送至此邮箱。" }, + "app.skin-site.review.empty": { "message": "暂无开放的申请表。" }, + "app.skin-site.review.failed": { "message": "加载审核申请表失败。" }, + "app.skin-site.review.invite-code": { "message": "邀请码" }, + "app.skin-site.review.loading": { "message": "正在加载…" }, + "app.skin-site.review.optional": { "message": "选填" }, + "app.skin-site.review.required": { "message": "必填" }, + "app.skin-site.review.result.passed": { "message": "已通过" }, + "app.skin-site.review.result.pending": { "message": "审核中" }, + "app.skin-site.review.result.rejected": { "message": "未通过" }, + "app.skin-site.review.submit": { "message": "提交申请" }, + "app.skin-site.review.submitted": { "message": "申请已提交。" }, + "app.skin-site.review.submitting": { "message": "正在提交…" }, + "app.skin-site.review.subtitle": { + "message": "选择申请表并回答其中的问题。" + }, + "app.skin-site.review.title": { "message": "玩家审核" }, + "app.skin-site.home.announcements.signed-out": { + "message": "登录后查看公告。" + }, + "app.skin-site.chat.user-picker.email": { "message": "邮箱" }, + "app.skin-site.chat.user-picker.registered": { "message": "注册时间" }, + "app.skin-site.chat.user-picker.banned-status": { "message": "已封禁" }, + "app.skin-site.chat.user-picker.active-status": { "message": "正常" }, + "app.skin-site.admin.wiki.policy-public": { "message": "所有人" }, + "app.skin-site.admin.wiki.policy-member": { "message": "已登录成员" }, + "app.skin-site.admin.wiki.policy-admin": { "message": "网站管理员" }, + "app.instance-player.title": { "message": "选择实例玩家" }, + "app.instance-player.remember": { + "message": "选择后,此实例将一直使用该玩家。可在实例设置中切换。" + }, + "app.instance-player.restore": { + "message": "请重新登录 {name};要更换玩家,请前往实例设置。" + }, + "app.instance-player.loading": { "message": "正在读取已登录的玩家…" }, + "app.instance-player.licensed": { "message": "正版玩家" }, + "app.instance-player.skin": { "message": "皮肤站玩家" }, + "app.instance-player.offline": { "message": "离线玩家" }, + "app.instance-player.empty": { + "message": "当前账号没有可用的皮肤站玩家,可在皮肤站创建玩家。" + }, + "app.instance-player.sign-in": { "message": "请登录账号后选择玩家。" }, + "app.instance-player.retry": { "message": "重试" }, + "app.instance-player.skin-login": { "message": "登录皮肤站" }, + "app.instance-player.or": { "message": "或者" }, + "app.instance-player.use-microsoft": { "message": "使用正版账号" }, + "app.instance-player.saving": { "message": "正在保存实例玩家…" }, + "app.instance-player.setting": { "message": "实例玩家" }, + "app.instance-player.first-launch": { "message": "首次启动时选择玩家" }, + "app.instance-player.change": { "message": "切换实例玩家" }, + "app.hosted-mods.title": { "message": "正在更新服务器 Mod" }, + "app.hosted-mods.description": { + "message": "所有更新安装完成后将继续启动游戏。" + }, + "app.hosted-mods.complete": { "message": "下载完成" }, + "app.hosted-mods.downloads": { "message": "查看下载" }, + "app.hosted-mods.close": { "message": "关闭" }, + "app.hosted-packs.progress.retry": { "message": "返回实例重试" }, + "app.hosted-packs.progress.preparing": { "message": "正在准备整合包安装…" }, + "app.hosted-packs.progress.downloads": { "message": "查看下载" }, + "app.hosted-packs.open-instance": { "message": "打开已安装实例" }, + "app.hosted-packs.retry-install": { "message": "重试安装" }, + "app.hosted-packs.auto-installing": { + "message": "正在下载并安装服务器整合包…" + }, + "app.hosted-packs.auto-description": { + "message": "从StarLight服务器获取整合包并自动安装,可一键游玩StarLight服务器" + }, + "app.hosted-packs.auto-install": { "message": "安装 StarLight 官方整合包" }, + "app.hosted-install.game-dir.header": { "message": "选择游戏目录" }, + "app.hosted-install.game-dir.description": { + "message": "StarLight 实例的游戏数据(mods、存档、配置、资源包)会存放在外部游戏目录中。请选择一个根目录,整合包会在其中单独建一个子文件夹。" + }, + "app.hosted-install.game-dir.label": { "message": "游戏目录根路径" }, + "app.hosted-install.game-dir.browse": { "message": "浏览" }, + "app.hosted-install.game-dir.no-selection": { "message": "尚未选择文件夹" }, + "app.hosted-install.game-dir.reset-default": { "message": "使用默认位置" }, + "app.hosted-install.game-dir.preview": { + "message": "游戏文件将安装到:{path}" + }, + "app.hosted-install.game-dir.confirm": { "message": "安装" }, + "app.onboarding.instance-mode.title": { "message": "选择实例类型" }, + "app.onboarding.instance-mode.description": { + "message": "StarLight 实例自动安装管理员指定的整合包和版本,每次启动先检查并完成更新,需要登录 StarLight 账号。本地实例可自选版本和整合包,适合第三方服务器与单人游玩。" + }, + "app.instance-mode.title": { "message": "实例类型" }, + "app.instance-mode.starlight": { "message": "StarLight 实例" }, + "app.instance-mode.local": { "message": "本地实例" }, + "app.instance-mode.starlight-description": { + "message": "游玩 StarLight 服务器必选。自动安装服务器指定的整合包、游戏版本和加载器。每次启动需要登录 StarLight,检查并完成更新后再进入游戏。" + }, + "app.instance-mode.local-description": { + "message": "不会同步 StarLight 服务器的变更。跳过同步检查,启动更快,可自选整合包安装,更适合第三方服务器与本地个人游玩。" + }, + "app.instance-mode.saving": { + "message": "正在应用实例类型,并按需安装服务器整合包…" + }, + "app.instance-mode.loading": { "message": "正在读取实例类型…" }, + "app.instance-mode.retry": { "message": "重试" }, + "app.instance-mode.local-packs-title": { "message": "本地整合包" }, + "app.instance-mode.local-packs": { + "message": "可以自选整合包并安装为本地实例。切换为本地后保留现有游戏文件和存档,之后不再同步 StarLight 的变更。" + }, + "app.instance-mode.browse": { "message": "浏览整合包" }, + "app.instance-mode.import": { "message": "导入为本地实例" }, + "app.hosted-packs.management": { "message": "内容管理" }, + "app.hosted-packs.mods": { "message": "管理 Mod" }, + "app.hosted-packs.packs": { "message": "管理整合包" }, + "app.hosted-packs.title": { "message": "服务器管理的整合包" }, + "app.hosted-packs.description": { + "message": "整合包和版本由管理员指定。每次启动都会检查服务器更新,有变更时先下载并安装,再启动游戏。需要有效的 StarLight 登录状态和网络连接。" + }, + "app.hosted-packs.refresh": { "message": "刷新" }, + "app.hosted-packs.loading": { "message": "正在获取已发布整合包…" }, + "app.hosted-packs.bound": { "message": "已安装:{name} · {version}" }, + "app.hosted-packs.syncing": { "message": "正在比对文件并同步变动…" }, + "app.hosted-packs.complete": { + "message": "已同步至 {version},变更 {count} 个文件,下载 {size} MiB。" + }, + "app.hosted-packs.preserved": { + "message": "保留了 {count} 个本地修改或个人文件" + }, + "app.hosted-packs.empty": { "message": "暂无审核通过的整合包。" }, + "app.hosted-packs.update": { "message": "立即同步" }, + "app.hosted-packs.install": { "message": "重试自动安装" }, + "app.home.luck.title": { "message": "每日幸运指数" }, + "app.home.luck.get": { "message": "一键获取" }, + "app.home.luck.login-to-get": { "message": "登录后获取" }, + "app.home.luck.loading": { "message": "正在询问小精灵..." }, + "app.home.luck.error": { "message": "小精灵暂时没有回应,请稍后重试。" }, + "app.home.luck.out-of": { "message": "满分 100" }, + "minecraft-account.skin-site.signed-in": { + "message": "已登录 StarLight皮肤站" + }, + "minecraft-account.skin-site.checking": { + "message": "正在验证皮肤站登录状态…" + }, + "minecraft-account.skin-site.sync-error": { + "message": "暂时无法验证皮肤站登录状态,将自动重试。" + }, + "minecraft-account.skin-site.players": { "message": "皮肤站玩家({count})" }, + "minecraft-account.skin-site.players.retry": { "message": "重试" }, + "minecraft-account.skin-site.players.empty": { + "message": "这个皮肤站账号还没有玩家。" + }, + "minecraft-account.skin-site.players.error": { + "message": "暂时无法刷新玩家列表,已保留上一次结果。" + }, + "app.easteregg.color-mine.title": { + "message": "星光矿井:彩域" + }, + "app.easteregg.color-mine.easy": { + "message": "简单" + }, + "app.easteregg.color-mine.normal": { + "message": "普通" + }, + "app.easteregg.color-mine.hard": { + "message": "困难" + }, + "app.easteregg.color-mine.newGame": { + "message": "新的一局" + }, + "app.easteregg.color-mine.close": { + "message": "关闭" + }, + "app.easteregg.color-mine.choose": { + "message": "先点击已揭示的色块取色,再给灰格染色。" + }, + "app.easteregg.color-mine.selected": { + "message": "已取色 {color} · 点击其他色块切换画笔。" + }, + "app.easteregg.color-mine.rulesTitle": { + "message": "玩法说明" + }, + "app.easteregg.color-mine.rules": { + "message": "数字表示周围八格中同色格的数量,不含自身。每种颜色必须组成一个上下左右连通的区域,斜角不算连接。点击已揭示的格子取色,染对会显示新数字,染错则本局结束。每局均经过逐步推理验证,无需猜测。" + }, + "app.easteregg.color-mine.loading": { + "message": "正在生成色域并校验推理路径…" + }, + "app.easteregg.color-mine.generateError": { + "message": "棋盘生成失败,请重试。" + }, + "app.easteregg.color-mine.retry": { + "message": "重试" + }, + "app.easteregg.color-mine.progress": { + "message": "已揭示 {count} / {total}" + }, + "app.easteregg.color-mine.best": { + "message": "最佳 · {time}" + }, + "app.easteregg.color-mine.won": { + "message": "全部色域已还原!" + }, + "app.easteregg.color-mine.lost": { + "message": "第 {row} 行、第 {column} 列染错了:选择了 {selected},正确颜色为 {correct}。本局结束。" + }, + "app.easteregg.color-mine.review": { + "message": "未揭示的答案已淡色显示,可查看棋盘复盘。" + }, + "app.easteregg.color-mine.leaveTitle": { + "message": "要离开当前棋盘吗?" + }, + "app.easteregg.color-mine.leaveText": { + "message": "可以保存,下次从这里继续;也可以放弃本局。" + }, + "app.easteregg.color-mine.saveLeave": { + "message": "保存并离开" + }, + "app.easteregg.color-mine.discard": { + "message": "放弃本局" + }, + "app.easteregg.color-mine.continue": { + "message": "继续这局" + }, + "app.easteregg.color-mine.replaceTitle": { + "message": "开始新的一局?" + }, + "app.easteregg.color-mine.replaceText": { + "message": "当前这局的进度将被放弃。" + }, + "app.easteregg.color-mine.savedTitle": { + "message": "有一局尚未完成的棋盘" + }, + "app.easteregg.color-mine.resume": { + "message": "继续上次的棋盘" + }, + "app.easteregg.color-mine.storageError": { + "message": "无法读取或保存存档,当前棋盘已保留。可重试,或选择放弃存档。" + }, + "app.easteregg.color-mine.recordError": { + "message": "已完成,但最佳成绩未能保存。" + }, + "app.easteregg.color-mine.zoomIn": { + "message": "放大" + }, + "app.easteregg.color-mine.zoomOut": { + "message": "缩小" + }, + "app.easteregg.color-mine.map": { + "message": "棋盘总览,点击定位" + }, + "app.easteregg.color-mine.board": { + "message": "{size} × {size} 彩色推理棋盘" + }, + "app.easteregg.color-mine.hidden": { + "message": "第 {row} 行,第 {column} 列,未揭示" + }, + "app.easteregg.color-mine.revealed": { + "message": "第 {row} 行,第 {column} 列,颜色 {color},周围同色 {number} 格" + }, + "app.settings.developer.announcement-preview": { + "message": "公告样式预览" + }, + "app.settings.developer.announcement-preview-description": { + "message": "使用本地示例预览真实公告组件,不请求远端公告,也不改变真实公告的已读状态。" + }, + "app.settings.developer.preview-with-action": { + "message": "显示可选的外部链接按钮" + }, + "app.settings.developer.preview-announcement-modal": { + "message": "预览启动弹窗" + }, + "app.settings.developer.preview-announcement-popup": { + "message": "预览 Popup 通知" + }, + "app.remote-announcements.preview-title": { + "message": "公告样式预览" + }, + "app.remote-announcements.preview-summary": { + "message": "这是一条本地预览通知,点击“查看公告”可查看完整 Markdown 正文。" + }, + "app.remote-announcements.preview-action": { + "message": "访问官网" + }, + "app.remote-announcements.preview-content": { + "message": "## 公告预览\n\n这是**示例正文**,不是已发布公告。\n\n- 支持标题、列表和链接\n- 默认自带关闭按钮\n\n> 预览不会影响真实公告的已读状态。\n\n| 类型 | 展示方式 |\n| --- | --- |\n| 启动弹窗 | 完整 Markdown 正文 |\n| Popup 通知 | 先显示摘要,再查看全文 |\n\n[访问官网](https://axlmc.org)" + }, + "app.remote-announcements.view": { + "message": "查看公告" + }, + "app.remote-announcements.unread": { + "message": "未读" + }, + "app.remote-announcements.read-all": { + "message": "将所有公告标为已读" + }, "app.account.signed-in-as": { "message": "登录身份:" }, - "app.action-bar.announcements": { - "message": "公告" - }, "app.action-bar.downloading-java": { "message": "正在下载 Java {version}" }, @@ -14,6 +455,18 @@ "app.action-bar.downloads": { "message": "下载" }, + "app.action-bar.notifications": { + "message": "通知" + }, + "app.action-bar.notifications.clear": { + "message": "清除全部" + }, + "app.action-bar.notifications.dismiss": { + "message": "忽略通知" + }, + "app.action-bar.notifications.empty": { + "message": "暂无通知" + }, "app.action-bar.exporting-modpack": { "message": "正在导出整合包" }, @@ -134,18 +587,6 @@ "app.action-bar.no-instances-running": { "message": "没有运行中的实例" }, - "app.action-bar.notifications": { - "message": "通知" - }, - "app.action-bar.notifications.clear": { - "message": "清除全部" - }, - "app.action-bar.notifications.dismiss": { - "message": "忽略通知" - }, - "app.action-bar.notifications.empty": { - "message": "暂无通知" - }, "app.action-bar.offline": { "message": "离线" }, @@ -173,9 +614,6 @@ "app.action-bar.view-logs": { "message": "查看日志" }, - "app.action-bar.window-started": { - "message": "{time, time, medium} 启动" - }, "app.ai-settings.add-model": { "message": "添加模型" }, @@ -368,9 +806,6 @@ "app.ai-settings.visit-website": { "message": "访问官网" }, - "app.anniversary.banner": { - "message": "Starlight {ordinal} 周年快乐!" - }, "app.appearance-settings.accent-color.blue": { "message": "蓝色" }, @@ -425,6 +860,57 @@ "app.appearance-settings.auto-hide-downloads-button.description": { "message": "没有进行中的下载任务时隐藏侧边栏中的下载按钮,有任务时自动显示。" }, + "app.appearance-settings.fonts.title": { + "message": "字体" + }, + "app.appearance-settings.fonts.description": { + "message": "选择启动器界面与日志使用的字体。" + }, + "app.appearance-settings.fonts.ui-font": { + "message": "界面字体" + }, + "app.appearance-settings.fonts.ui-font-description": { + "message": "应用于启动器界面。仅列出系统已安装的字体。" + }, + "app.appearance-settings.fonts.mono-font": { + "message": "等宽字体" + }, + "app.appearance-settings.fonts.mono-font-description": { + "message": "用于日志、服务器控制台等等宽内容。" + }, + "app.appearance-settings.fonts.default": { + "message": "启动器默认" + }, + "app.appearance-settings.fonts.monospace": { + "message": "等宽" + }, + "app.appearance-settings.fonts.missing": { + "message": "未安装" + }, + "app.appearance-settings.fonts.search-placeholder": { + "message": "搜索已安装的字体" + }, + "app.appearance-settings.fonts.no-results": { + "message": "没有匹配的字体" + }, + "app.appearance-settings.fonts.load-failed": { + "message": "无法读取已安装的字体列表。" + }, + "app.appearance-settings.fonts.retry": { + "message": "重试" + }, + "app.appearance-settings.fonts.reset": { + "message": "重置" + }, + "app.appearance-settings.fonts.preview": { + "message": "预览" + }, + "app.appearance-settings.fonts.ui-preview-sample": { + "message": "永和九年,岁在癸丑,暮春之初。" + }, + "app.appearance-settings.fonts.mono-preview-sample": { + "message": "const x = () => 0; // 等宽" + }, "app.appearance-settings.auto-hide-downloads-button.title": { "message": "自动隐藏下载按钮" }, @@ -500,57 +986,6 @@ "app.appearance-settings.default-landing-page.title": { "message": "默认起始页" }, - "app.appearance-settings.fonts.default": { - "message": "启动器默认" - }, - "app.appearance-settings.fonts.description": { - "message": "选择启动器界面与日志使用的字体。" - }, - "app.appearance-settings.fonts.load-failed": { - "message": "无法读取已安装的字体列表。" - }, - "app.appearance-settings.fonts.missing": { - "message": "未安装" - }, - "app.appearance-settings.fonts.mono-font": { - "message": "等宽字体" - }, - "app.appearance-settings.fonts.mono-font-description": { - "message": "用于日志、服务器控制台等等宽内容。" - }, - "app.appearance-settings.fonts.mono-preview-sample": { - "message": "const x = () => 0; // 等宽" - }, - "app.appearance-settings.fonts.monospace": { - "message": "等宽" - }, - "app.appearance-settings.fonts.no-results": { - "message": "没有匹配的字体" - }, - "app.appearance-settings.fonts.preview": { - "message": "预览" - }, - "app.appearance-settings.fonts.reset": { - "message": "重置" - }, - "app.appearance-settings.fonts.retry": { - "message": "重试" - }, - "app.appearance-settings.fonts.search-placeholder": { - "message": "搜索已安装的字体" - }, - "app.appearance-settings.fonts.title": { - "message": "字体" - }, - "app.appearance-settings.fonts.ui-font": { - "message": "界面字体" - }, - "app.appearance-settings.fonts.ui-font-description": { - "message": "应用于启动器界面。仅列出系统已安装的字体。" - }, - "app.appearance-settings.fonts.ui-preview-sample": { - "message": "永和九年,岁在癸丑,暮春之初。" - }, "app.appearance-settings.hide-nametag.description": { "message": "在皮肤页面中禁用你玩家头顶上的名牌。" }, @@ -641,12 +1076,12 @@ "app.appearance-settings.transparent-background.title": { "message": "透明背景" }, - "app.appearance-settings.ui-scale.description": { - "message": "缩放整个启动器界面。缩小后能显示更多内容,适合内嵌网页被裁切的情况。" - }, "app.appearance-settings.ui-scale.title": { "message": "启动器缩放" }, + "app.appearance-settings.ui-scale.description": { + "message": "缩放整个启动器界面。缩小后能显示更多内容,适合内嵌网页被裁切的情况。" + }, "app.appearance-settings.unknown-pack-warning.description": { "message": "如果你尝试安装一个未托管在 Modrinth 上的 Modrinth 整合包文件(.mrpack),我们会确保你在安装之前了解相关风险。" }, @@ -710,12 +1145,6 @@ "app.browse.display-mode.switch": { "message": "切换视图" }, - "app.browse.fuzzy-search.prefix": { - "message": "未找到「{original}」的结果,已为您显示" - }, - "app.browse.fuzzy-search.suffix": { - "message": "的相关结果" - }, "app.browse.hide-added-servers": { "message": "隐藏已添加的服务器" }, @@ -773,6 +1202,12 @@ "app.browse.maps-unavailable-description": { "message": "请配置 CurseForge API Key 以浏览和安装地图。" }, + "app.browse.fuzzy-search.prefix": { + "message": "未找到「{original}」的结果,已为您显示" + }, + "app.browse.fuzzy-search.suffix": { + "message": "的相关结果" + }, "app.browse.no-compatible-version": { "message": "未找到与所选实例兼容的版本。" }, @@ -1586,9 +2021,6 @@ "app.downloads.status.interrupted": { "message": "已中断" }, - "app.downloads.status.paused": { - "message": "已暂停" - }, "app.downloads.status.queued": { "message": "排队中" }, @@ -1790,111 +2222,6 @@ "app.drop.world-imported-title": { "message": "存档已导入" }, - "app.easteregg.color-mine.best": { - "message": "最佳 · {time}" - }, - "app.easteregg.color-mine.board": { - "message": "{size} × {size} 彩色推理棋盘" - }, - "app.easteregg.color-mine.choose": { - "message": "先点击已揭示的色块取色,再给灰格染色。" - }, - "app.easteregg.color-mine.close": { - "message": "关闭" - }, - "app.easteregg.color-mine.continue": { - "message": "继续这局" - }, - "app.easteregg.color-mine.discard": { - "message": "放弃本局" - }, - "app.easteregg.color-mine.easy": { - "message": "简单" - }, - "app.easteregg.color-mine.generateError": { - "message": "棋盘生成失败,请重试。" - }, - "app.easteregg.color-mine.hard": { - "message": "困难" - }, - "app.easteregg.color-mine.hidden": { - "message": "第 {row} 行,第 {column} 列,未揭示" - }, - "app.easteregg.color-mine.leaveText": { - "message": "可以保存,下次从这里继续;也可以放弃本局。" - }, - "app.easteregg.color-mine.leaveTitle": { - "message": "要离开当前棋盘吗?" - }, - "app.easteregg.color-mine.loading": { - "message": "正在生成色域并校验推理路径…" - }, - "app.easteregg.color-mine.lost": { - "message": "第 {row} 行、第 {column} 列染错了:选择了 {selected},正确颜色为 {correct}。本局结束。" - }, - "app.easteregg.color-mine.map": { - "message": "棋盘总览,点击定位" - }, - "app.easteregg.color-mine.newGame": { - "message": "新的一局" - }, - "app.easteregg.color-mine.normal": { - "message": "普通" - }, - "app.easteregg.color-mine.progress": { - "message": "已揭示 {count} / {total}" - }, - "app.easteregg.color-mine.recordError": { - "message": "已完成,但最佳成绩未能保存。" - }, - "app.easteregg.color-mine.replaceText": { - "message": "当前这局的进度将被放弃。" - }, - "app.easteregg.color-mine.replaceTitle": { - "message": "开始新的一局?" - }, - "app.easteregg.color-mine.resume": { - "message": "继续上次的棋盘" - }, - "app.easteregg.color-mine.retry": { - "message": "重试" - }, - "app.easteregg.color-mine.revealed": { - "message": "第 {row} 行,第 {column} 列,颜色 {color},周围同色 {number} 格" - }, - "app.easteregg.color-mine.review": { - "message": "未揭示的答案已淡色显示,可查看棋盘复盘。" - }, - "app.easteregg.color-mine.rules": { - "message": "数字表示周围八格中同色格的数量,不含自身。每种颜色必须组成一个上下左右连通的区域,斜角不算连接。点击已揭示的格子取色,染对会显示新数字,染错则本局结束。每局均经过逐步推理验证,无需猜测。" - }, - "app.easteregg.color-mine.rulesTitle": { - "message": "玩法说明" - }, - "app.easteregg.color-mine.saveLeave": { - "message": "保存并离开" - }, - "app.easteregg.color-mine.savedTitle": { - "message": "有一局尚未完成的棋盘" - }, - "app.easteregg.color-mine.selected": { - "message": "已取色 {color} · 点击其他色块切换画笔。" - }, - "app.easteregg.color-mine.storageError": { - "message": "无法读取或保存存档,当前棋盘已保留。可重试,或选择放弃存档。" - }, - "app.easteregg.color-mine.title": { - "message": "星光矿井:彩域" - }, - "app.easteregg.color-mine.won": { - "message": "全部色域已还原!" - }, - "app.easteregg.color-mine.zoomIn": { - "message": "放大" - }, - "app.easteregg.color-mine.zoomOut": { - "message": "缩小" - }, "app.error.account-description": { "message": "请确认登录的是正确账号。你可能在另一个 Microsoft 账号上拥有 Minecraft。" }, @@ -2234,12 +2561,6 @@ "app.home.instances.view-all": { "message": "查看全部实例" }, - "app.home.launch-progress.empty": { - "message": "启动游戏后,这里会显示进度。" - }, - "app.home.launch-progress.title": { - "message": "启动进度" - }, "app.home.layout.switch-to-information": { "message": "切换到信息主页" }, @@ -2249,24 +2570,6 @@ "app.home.layout.toggle": { "message": "极简主页" }, - "app.home.luck.error": { - "message": "小精灵暂时没有回应,请稍后重试。" - }, - "app.home.luck.get": { - "message": "一键获取" - }, - "app.home.luck.loading": { - "message": "正在询问小精灵..." - }, - "app.home.luck.login-to-get": { - "message": "登录后获取" - }, - "app.home.luck.out-of": { - "message": "满分 100" - }, - "app.home.luck.title": { - "message": "每日幸运指数" - }, "app.home.minimal.change-instance": { "message": "更换主页实例" }, @@ -2501,120 +2804,6 @@ "app.home.worlds.pinned": { "message": "固定的世界" }, - "app.hosted-install.game-dir.browse": { - "message": "浏览" - }, - "app.hosted-install.game-dir.confirm": { - "message": "安装" - }, - "app.hosted-install.game-dir.description": { - "message": "StarLight 实例的游戏数据(mods、存档、配置、资源包)会存放在外部游戏目录中。请选择一个根目录,整合包会在其中单独建一个子文件夹。" - }, - "app.hosted-install.game-dir.header": { - "message": "选择游戏目录" - }, - "app.hosted-install.game-dir.label": { - "message": "游戏目录根路径" - }, - "app.hosted-install.game-dir.no-selection": { - "message": "尚未选择文件夹" - }, - "app.hosted-install.game-dir.preview": { - "message": "游戏文件将安装到:{path}" - }, - "app.hosted-install.game-dir.reset-default": { - "message": "使用默认位置" - }, - "app.hosted-mods.close": { - "message": "关闭" - }, - "app.hosted-mods.complete": { - "message": "下载完成" - }, - "app.hosted-mods.description": { - "message": "所有更新安装完成后将继续启动游戏。" - }, - "app.hosted-mods.downloads": { - "message": "查看下载" - }, - "app.hosted-mods.title": { - "message": "正在更新服务器 Mod" - }, - "app.hosted-packs.auto-description": { - "message": "从StarLight服务器获取整合包并自动安装,可一键游玩StarLight服务器" - }, - "app.hosted-packs.auto-install": { - "message": "安装 StarLight 官方整合包" - }, - "app.hosted-packs.auto-installing": { - "message": "正在下载并安装服务器整合包…" - }, - "app.hosted-packs.bound": { - "message": "已安装:{name} · {version}" - }, - "app.hosted-packs.complete": { - "message": "已同步至 {version},变更 {count} 个文件,下载 {size} MiB。" - }, - "app.hosted-packs.description": { - "message": "整合包和版本由管理员指定。每次启动都会检查服务器更新,有变更时先下载并安装,再启动游戏。需要有效的 StarLight 登录状态和网络连接。" - }, - "app.hosted-packs.empty": { - "message": "暂无审核通过的整合包。" - }, - "app.hosted-packs.install": { - "message": "重试自动安装" - }, - "app.hosted-packs.loading": { - "message": "正在获取已发布整合包…" - }, - "app.hosted-packs.management": { - "message": "内容管理" - }, - "app.hosted-packs.mods": { - "message": "管理 Mod" - }, - "app.hosted-packs.open-instance": { - "message": "打开已安装实例" - }, - "app.hosted-packs.packs": { - "message": "管理整合包" - }, - "app.hosted-packs.preserved": { - "message": "保留了 {count} 个本地修改或个人文件" - }, - "app.hosted-packs.progress.downloads": { - "message": "查看下载" - }, - "app.hosted-packs.progress.pause": { - "message": "暂停" - }, - "app.hosted-packs.progress.preparing": { - "message": "正在准备整合包安装…" - }, - "app.hosted-packs.progress.resume": { - "message": "继续" - }, - "app.hosted-packs.progress.retry": { - "message": "返回实例重试" - }, - "app.hosted-packs.progress.stop": { - "message": "停止" - }, - "app.hosted-packs.refresh": { - "message": "刷新" - }, - "app.hosted-packs.retry-install": { - "message": "重试安装" - }, - "app.hosted-packs.syncing": { - "message": "正在比对文件并同步变动…" - }, - "app.hosted-packs.title": { - "message": "服务器管理的整合包" - }, - "app.hosted-packs.update": { - "message": "立即同步" - }, "app.install.phase.downloading_content": { "message": "正在下载内容" }, @@ -2681,93 +2870,6 @@ "app.instance-item.view-instance": { "message": "查看实例" }, - "app.instance-mode.browse": { - "message": "浏览整合包" - }, - "app.instance-mode.import": { - "message": "导入为本地实例" - }, - "app.instance-mode.loading": { - "message": "正在读取实例类型…" - }, - "app.instance-mode.local": { - "message": "本地实例" - }, - "app.instance-mode.local-description": { - "message": "不会同步 StarLight 服务器的变更。跳过同步检查,启动更快,可自选整合包安装,更适合第三方服务器与本地个人游玩。" - }, - "app.instance-mode.local-packs": { - "message": "可以自选整合包并安装为本地实例。切换为本地后保留现有游戏文件和存档,之后不再同步 StarLight 的变更。" - }, - "app.instance-mode.local-packs-title": { - "message": "本地整合包" - }, - "app.instance-mode.retry": { - "message": "重试" - }, - "app.instance-mode.saving": { - "message": "正在应用实例类型,并按需安装服务器整合包…" - }, - "app.instance-mode.starlight": { - "message": "StarLight 实例" - }, - "app.instance-mode.starlight-description": { - "message": "游玩 StarLight 服务器必选。自动安装服务器指定的整合包、游戏版本和加载器。每次启动需要登录 StarLight,检查并完成更新后再进入游戏。" - }, - "app.instance-mode.title": { - "message": "实例类型" - }, - "app.instance-player.change": { - "message": "切换实例玩家" - }, - "app.instance-player.empty": { - "message": "当前账号没有可用的皮肤站玩家,可在皮肤站创建玩家。" - }, - "app.instance-player.first-launch": { - "message": "首次启动时选择玩家" - }, - "app.instance-player.licensed": { - "message": "正版玩家" - }, - "app.instance-player.loading": { - "message": "正在读取已登录的玩家…" - }, - "app.instance-player.offline": { - "message": "离线玩家" - }, - "app.instance-player.or": { - "message": "或者" - }, - "app.instance-player.remember": { - "message": "选择后,此实例将一直使用该玩家。可在实例设置中切换。" - }, - "app.instance-player.restore": { - "message": "请重新登录 {name};要更换玩家,请前往实例设置。" - }, - "app.instance-player.retry": { - "message": "重试" - }, - "app.instance-player.saving": { - "message": "正在保存实例玩家…" - }, - "app.instance-player.setting": { - "message": "实例玩家" - }, - "app.instance-player.sign-in": { - "message": "请登录账号后选择玩家。" - }, - "app.instance-player.skin": { - "message": "皮肤站玩家" - }, - "app.instance-player.skin-login": { - "message": "登录皮肤站" - }, - "app.instance-player.title": { - "message": "选择实例玩家" - }, - "app.instance-player.use-microsoft": { - "message": "使用正版账号" - }, "app.instance.back": { "message": "返回实例" }, @@ -3221,11 +3323,17 @@ "app.instance.join-server": { "message": "加入服务器" }, + "app.instance.launch-instance": { + "message": "启动实例" + }, "app.instance.launch-another": { "message": "再开一个窗口" }, - "app.instance.launch-instance": { - "message": "启动实例" + "app.action-bar.window-started": { + "message": "{time, time, medium} 启动" + }, + "app.instance.stop-all": { + "message": "停止此实例全部窗口" }, "app.instance.linked-to": { "message": "关联到" @@ -3449,9 +3557,6 @@ "app.instance.starting": { "message": "正在启动…… {seconds, number} 秒" }, - "app.instance.stop-all": { - "message": "停止此实例全部窗口" - }, "app.instance.stopping": { "message": "正在停止……" }, @@ -3539,24 +3644,9 @@ "app.instances.add-content": { "message": "添加内容" }, - "app.instances.batch-edit-groups.add": { - "message": "添加" - }, - "app.instances.batch-edit-groups.add-to-group-title": { - "message": "添加实例到「{groupName}」" - }, - "app.instances.batch-edit-groups.added": { - "message": "已添加" - }, "app.instances.batch-edit-groups.apply": { "message": "应用" }, - "app.instances.batch-edit-groups.cancel": { - "message": "取消" - }, - "app.instances.batch-edit-groups.create": { - "message": "创建分组" - }, "app.instances.batch-edit-groups.create-group": { "message": "创建新分组" }, @@ -3566,24 +3656,9 @@ "app.instances.batch-edit-groups.enter-group-name": { "message": "分组名称" }, - "app.instances.batch-edit-groups.group-name": { - "message": "分组名称" - }, - "app.instances.batch-edit-groups.group-name-placeholder": { - "message": "输入分组名称" - }, "app.instances.batch-edit-groups.header": { "message": "编辑分组" }, - "app.instances.batch-edit-groups.no-instances-found": { - "message": "未找到实例" - }, - "app.instances.batch-edit-groups.save-changes": { - "message": "保存" - }, - "app.instances.batch-edit-groups.search-instance": { - "message": "搜索实例" - }, "app.instances.copy-path": { "message": "复制路径" }, @@ -3599,27 +3674,6 @@ "app.instances.group-by": { "message": "分组方式:" }, - "app.instances.group.add-to-group": { - "message": "添加到分组" - }, - "app.instances.group.collapse": { - "message": "折叠分组" - }, - "app.instances.group.delete-description": { - "message": "此分组中的实例将被取消分组。" - }, - "app.instances.group.delete-group": { - "message": "删除分组" - }, - "app.instances.group.edit-name": { - "message": "编辑分组名称" - }, - "app.instances.group.empty": { - "message": "拖放实例到此处添加。" - }, - "app.instances.group.expand": { - "message": "展开分组" - }, "app.instances.group.game-version": { "message": "游戏版本" }, @@ -3629,30 +3683,9 @@ "app.instances.group.loader": { "message": "加载器" }, - "app.instances.group.move-down": { - "message": "下移分组" - }, - "app.instances.group.move-up": { - "message": "上移分组" - }, - "app.instances.group.name-empty": { - "message": "分组名称不能为空。" - }, - "app.instances.group.name-too-long": { - "message": "分组名称不能超过 {maxLength} 个字符。" - }, - "app.instances.group.new-instance": { - "message": "新建实例" - }, "app.instances.group.none": { "message": "无" }, - "app.instances.group.pinned": { - "message": "已置顶" - }, - "app.instances.group.rename-group": { - "message": "重命名分组" - }, "app.instances.group.ungrouped": { "message": "无分组" }, @@ -3671,39 +3704,12 @@ "app.instances.selected-count": { "message": "已选择 {count} 个" }, - "app.instances.sort-by": { - "message": "排序方式" - }, "app.instances.sort.date-created": { "message": "创建日期" }, "app.instances.sort.date-modified": { "message": "修改日期" }, - "app.instances.sort.direction.asc-alphabetical": { - "message": "A–Z 正序" - }, - "app.instances.sort.direction.asc-date": { - "message": "最早的在前" - }, - "app.instances.sort.direction.asc-recency": { - "message": "最早游玩在前" - }, - "app.instances.sort.direction.asc-version": { - "message": "旧版本在前" - }, - "app.instances.sort.direction.desc-alphabetical": { - "message": "Z–A 倒序" - }, - "app.instances.sort.direction.desc-date": { - "message": "最新的在前" - }, - "app.instances.sort.direction.desc-recency": { - "message": "最近游玩在前" - }, - "app.instances.sort.direction.desc-version": { - "message": "新版本在前" - }, "app.instances.sort.last-played": { "message": "上次游玩" }, @@ -5429,12 +5435,12 @@ "app.lab.skin-editor.loading": { "message": "正在加载皮肤编辑器" }, - "app.lab.skin-editor.resource-error": { - "message": "皮肤编辑器文件缺失或损坏,请重新安装启动器,或完整解压便携版。" - }, "app.lab.skin-editor.retry": { "message": "重试" }, + "app.lab.skin-editor.resource-error": { + "message": "皮肤编辑器文件缺失或损坏,请重新安装启动器,或完整解压便携版。" + }, "app.lab.skin-editor.title": { "message": "皮肤编辑器" }, @@ -5447,30 +5453,12 @@ "app.lab.tool-count-plural": { "message": "{count} 个工具" }, - "app.library.context-menu.pin-instance": { - "message": "置顶实例" - }, - "app.library.context-menu.remove-from-group": { - "message": "移出分组" - }, - "app.library.context-menu.unpin-instance": { - "message": "取消置顶" - }, "app.library.create-instance": { "message": "创建新实例" }, - "app.library.group.new": { - "message": "新建分组" - }, "app.library.no-instances": { "message": "未找到实例" }, - "app.library.selection.new-group": { - "message": "新建分组" - }, - "app.library.selection.remove-from-group": { - "message": "移出分组" - }, "app.library.tabs.all-instances": { "message": "全部实例" }, @@ -5501,144 +5489,6 @@ "app.library.view.standard": { "message": "标准网格" }, - "app.log-share.ai.action": { - "message": "AI 深度分析" - }, - "app.log-share.ai.confidence": { - "message": "诊断置信度" - }, - "app.log-share.ai.evidence": { - "message": "支撑证据链" - }, - "app.log-share.ai.failed": { - "message": "LogAgent 分析失败:{message}" - }, - "app.log-share.ai.limit": { - "message": "已达到工具调用上限" - }, - "app.log-share.ai.queued": { - "message": "排队中,前方约 {position} 个任务" - }, - "app.log-share.ai.queued-front": { - "message": "排队中,正在等待空闲槽位" - }, - "app.log-share.ai.root-cause": { - "message": "核心根因" - }, - "app.log-share.ai.steps": { - "message": "推荐排障步骤" - }, - "app.log-share.ai.tab": { - "message": "LogAgent 深度分析" - }, - "app.log-share.ai.thinking": { - "message": "思考中…" - }, - "app.log-share.ai.tool": { - "message": "正在使用工具:{name}" - }, - "app.log-share.ai.tool-result": { - "message": "已收到工具结果" - }, - "app.log-share.ai.unknown-tool": { - "message": "工具" - }, - "app.log-share.ai.working": { - "message": "正在使用 LogAgent 分析…" - }, - "app.log-share.settings.ai-source": { - "message": "AI 分析来源" - }, - "app.log-share.settings.ai-source-custom": { - "message": "自定义 AI 服务商" - }, - "app.log-share.settings.ai-source-description": { - "message": "LogShare AI 在云端分析;自定义则使用下方配置的服务商。" - }, - "app.log-share.settings.ai-source-logshare": { - "message": "LogShare AI" - }, - "app.log-share.settings.auto-upload": { - "message": "自动上传以获取结构化摘要" - }, - "app.log-share.settings.auto-upload-description": { - "message": "仅在 LogShare 模式下生效。" - }, - "app.log-share.settings.description": { - "message": "将崩溃诊断分享到 LogShare,获取结构化摘要与可选的 AI 分析。优先使用 LogShare,不可用时回退到 mclo.gs。" - }, - "app.log-share.settings.multi-file": { - "message": "多文件上传" - }, - "app.log-share.settings.multi-file-description": { - "message": "同时上传 latest.log、崩溃报告、hs_err 以及启动器日志。" - }, - "app.log-share.settings.no-storage": { - "message": "不落盘直接分析" - }, - "app.log-share.settings.no-storage-description": { - "message": "直接提交内容进行分析并跳过存储上传。会关闭自动摘要。" - }, - "app.log-share.settings.share-provider": { - "message": "日志分享服务" - }, - "app.log-share.settings.share-provider-description": { - "message": "分享诊断链接时上传到的目标服务。" - }, - "app.log-share.settings.show-progress": { - "message": "显示 AI 分析进度" - }, - "app.log-share.settings.show-progress-description": { - "message": "展示 LogAgent 运行期间的思考、工具及上限状态。" - }, - "app.log-share.settings.title": { - "message": "日志分享与 AI 分析" - }, - "app.log-share.shared-logs.delete": { - "message": "删除" - }, - "app.log-share.shared-logs.delete-failed": { - "message": "删除已分享日志失败。" - }, - "app.log-share.shared-logs.deleted": { - "message": "已删除共享日志。" - }, - "app.log-share.shared-logs.deleting": { - "message": "删除中…" - }, - "app.log-share.shared-logs.description": { - "message": "你分享过的所有诊断都记录在这里。删除条目会将其从记录中移除,并向分享服务请求删除。" - }, - "app.log-share.shared-logs.empty": { - "message": "暂无已分享的日志。" - }, - "app.log-share.shared-logs.title": { - "message": "已分享日志" - }, - "app.log-share.shared-logs.truncated": { - "message": "已截断" - }, - "app.log-share.summary.empty": { - "message": "LogShare 未返回这些日志的结构化摘要。" - }, - "app.log-share.summary.failed": { - "message": "无法加载 LogShare 摘要:{message}" - }, - "app.log-share.summary.information": { - "message": "信息" - }, - "app.log-share.summary.loading": { - "message": "正在加载结构化摘要…" - }, - "app.log-share.summary.no-storage": { - "message": "启用不落盘模式时无法获取结构化摘要。" - }, - "app.log-share.summary.problems": { - "message": "问题" - }, - "app.log-share.summary.title": { - "message": "LogShare 分析" - }, "app.memory-display.available": { "message": "可用 {memory}" }, @@ -5810,21 +5660,6 @@ "app.minecraft-crash.launch-failure-hint": { "message": "打开 Minecraft 日志可以查看已捕获的 Java 输出。寻求帮助时,请导出并发送完整的 Minecraft 诊断包。" }, - "app.minecraft-crash.log-file.failed": { - "message": "无法加载此日志文件:{message}" - }, - "app.minecraft-crash.log-file.loading": { - "message": "正在加载日志文件…" - }, - "app.minecraft-crash.logs.empty": { - "message": "未找到本次启动产生的日志。" - }, - "app.minecraft-crash.logs.failed": { - "message": "无法加载崩溃日志:{message}" - }, - "app.minecraft-crash.logs.loading": { - "message": "正在加载崩溃日志…" - }, "app.minecraft-crash.mod-changes-action": { "message": "请检查发生变化的 Mod;如果崩溃从这些变化后开始,可手动恢复之前的配置。" }, @@ -5885,9 +5720,6 @@ "app.minecraft-crash.share-failed": { "message": "导出分享失败" }, - "app.minecraft-crash.share-fallback": { - "message": "LogShare 不可用,已改用 mclo.gs 分享诊断信息。" - }, "app.minecraft-crash.share-ready": { "message": "诊断链接已准备好分享" }, @@ -6290,9 +6122,6 @@ "app.navigation.multiplayer": { "message": "多人游戏" }, - "app.navigation.screenshots": { - "message": "截图" - }, "app.navigation.skin-selector": { "message": "皮肤选择器" }, @@ -6305,12 +6134,6 @@ "app.notification.warning": { "message": "警告" }, - "app.onboarding.account-login.description": { - "message": "在这里登录 StarLight 皮肤站,即可使用皮肤站玩家、安装托管整合包并同步你的账号。" - }, - "app.onboarding.account-login.title": { - "message": "登录 StarLight" - }, "app.onboarding.action.click-create": { "message": "点击创建新实例,继续" }, @@ -6353,12 +6176,6 @@ "app.onboarding.action.start": { "message": "带我逛逛" }, - "app.onboarding.announcement.description": { - "message": "打开侧栏的公告入口,查看最新消息、服规与服务器通知。" - }, - "app.onboarding.announcement.title": { - "message": "最新公告" - }, "app.onboarding.appearance.description": { "message": "主题、强调色、背景和窗口效果都在这里。把启动器调成你熟悉的样子。" }, @@ -6371,12 +6188,6 @@ "app.onboarding.browse.title": { "message": "搜索,不靠玄学" }, - "app.onboarding.create-starlight.description": { - "message": "点击这里的“创建新实例”。StarLight 实例会安装服务器指定的整合包与版本,并在每次启动前保持更新。" - }, - "app.onboarding.create-starlight.title": { - "message": "创建 StarLight 实例" - }, "app.onboarding.create.description": { "message": "从零开始,或导入已有实例或整合包。你说了算。" }, @@ -6443,12 +6254,6 @@ "app.onboarding.favorites.title": { "message": "留个清单" }, - "app.onboarding.home-intro.description": { - "message": "这里是你的主页,展示你的实例、最近活动和快速开始游戏的入口。" - }, - "app.onboarding.home-intro.title": { - "message": "欢迎回家" - }, "app.onboarding.home-layout.description": { "message": "使用右下角控件在 StarLight 皮肤站主页与专注的实例启动页之间切换。" }, @@ -6461,29 +6266,29 @@ "app.onboarding.instance-actions.title": { "message": "主操作台" }, - "app.onboarding.instance-content-tab.description": { - "message": "在这里管理实例的 Mod、资源包与光影。可搜索、启用或禁用条目、检查更新,也能继续浏览安装新内容。" - }, "app.onboarding.instance-content-tab.title": { "message": "内容" }, - "app.onboarding.instance-files-tab.description": { - "message": "浏览实例目录,用内置编辑器直接打开配置文件或日志,无需离开启动器。" + "app.onboarding.instance-content-tab.description": { + "message": "在这里管理实例的 Mod、资源包与光影。可搜索、启用或禁用条目、检查更新,也能继续浏览安装新内容。" }, "app.onboarding.instance-files-tab.title": { "message": "文件" }, - "app.onboarding.instance-logs-tab.description": { - "message": "查看实例的实时日志,排查崩溃与报错,不必再翻找文件。" + "app.onboarding.instance-files-tab.description": { + "message": "浏览实例目录,用内置编辑器直接打开配置文件或日志,无需离开启动器。" + }, + "app.onboarding.instance-worlds-tab.title": { + "message": "世界" + }, + "app.onboarding.instance-worlds-tab.description": { + "message": "管理存档世界:备份、重命名、编辑世界设置,或打开世界所在文件夹。" }, "app.onboarding.instance-logs-tab.title": { "message": "日志" }, - "app.onboarding.instance-mode.description": { - "message": "StarLight 实例自动安装管理员指定的整合包和版本,每次启动先检查并完成更新,需要登录 StarLight 账号。本地实例可自选版本和整合包,适合第三方服务器与单人游玩。" - }, - "app.onboarding.instance-mode.title": { - "message": "选择实例类型" + "app.onboarding.instance-logs-tab.description": { + "message": "查看实例的实时日志,排查崩溃与报错,不必再翻找文件。" }, "app.onboarding.instance-tabs.description": { "message": "内容、文件、截图、世界和日志都在这些标签里。乱中有序。" @@ -6491,12 +6296,6 @@ "app.onboarding.instance-tabs.title": { "message": "剩下的工作台" }, - "app.onboarding.instance-worlds-tab.description": { - "message": "管理存档世界:备份、重命名、编辑世界设置,或打开世界所在文件夹。" - }, - "app.onboarding.instance-worlds-tab.title": { - "message": "世界" - }, "app.onboarding.lab-tools.description": { "message": "在本地编辑皮肤、生成格式文字与配方、探索种子、检查投影并翻译模组。" }, @@ -6530,12 +6329,6 @@ "app.onboarding.resources.title": { "message": "别把电脑烤熟" }, - "app.onboarding.settings-updates.description": { - "message": "“更新”页用于设置更新通道、检查启动器新版本并查看更新日志。" - }, - "app.onboarding.settings-updates.title": { - "message": "保持最新" - }, "app.onboarding.settings.description": { "message": "这里集中管理启动器偏好、游戏启动、内容下载和隐私设置。" }, @@ -6563,6 +6356,36 @@ "app.onboarding.welcome.title": { "message": "一切就绪" }, + "app.onboarding.home-intro.title": { + "message": "欢迎回家" + }, + "app.onboarding.home-intro.description": { + "message": "这里是你的主页,展示你的实例、最近活动和快速开始游戏的入口。" + }, + "app.onboarding.account-login.title": { + "message": "登录 StarLight" + }, + "app.onboarding.account-login.description": { + "message": "在这里登录 StarLight 皮肤站,即可使用皮肤站玩家、安装托管整合包并同步你的账号。" + }, + "app.onboarding.announcement.title": { + "message": "最新公告" + }, + "app.onboarding.announcement.description": { + "message": "打开侧栏的公告入口,查看最新消息、服规与服务器通知。" + }, + "app.onboarding.create-starlight.title": { + "message": "创建 StarLight 实例" + }, + "app.onboarding.create-starlight.description": { + "message": "点击这里的“创建新实例”。StarLight 实例会安装服务器指定的整合包与版本,并在每次启动前保持更新。" + }, + "app.onboarding.settings-updates.title": { + "message": "保持最新" + }, + "app.onboarding.settings-updates.description": { + "message": "“更新”页用于设置更新通道、检查启动器新版本并查看更新日志。" + }, "app.project.curseforge.loading": { "message": "正在加载 CurseForge 项目…" }, @@ -6590,6 +6413,18 @@ "app.project.install-context.install-content-to-instance": { "message": "将内容安装到实例中" }, + "app.project.modpack-server.created-description": { + "message": "{name} 已就绪。请在多人游戏中配置并启动。" + }, + "app.project.modpack-server.created-title": { + "message": "服务器已创建" + }, + "app.project.modpack-server.open": { + "message": "打开服务器" + }, + "app.project.modpack-server.start": { + "message": "开服" + }, "app.project.mcarchive.install": { "message": "安装" }, @@ -6629,18 +6464,6 @@ "app.project.mcarchive.versions": { "message": "版本" }, - "app.project.modpack-server.created-description": { - "message": "{name} 已就绪。请在多人游戏中配置并启动。" - }, - "app.project.modpack-server.created-title": { - "message": "服务器已创建" - }, - "app.project.modpack-server.open": { - "message": "打开服务器" - }, - "app.project.modpack-server.start": { - "message": "开服" - }, "app.project.open-in-mcmod": { "message": "在 MC 百科中打开" }, @@ -6710,189 +6533,9 @@ "app.project.versions.start-server": { "message": "开服" }, - "app.remote-announcements.center-title": { - "message": "公告" - }, - "app.remote-announcements.empty": { - "message": "暂无公告" - }, - "app.remote-announcements.preview-action": { - "message": "访问官网" - }, - "app.remote-announcements.preview-content": { - "message": "## 公告预览\n\n这是**示例正文**,不是已发布公告。\n\n- 支持标题、列表和链接\n- 默认自带关闭按钮\n\n> 预览不会影响真实公告的已读状态。\n\n| 类型 | 展示方式 |\n| --- | --- |\n| 启动弹窗 | 完整 Markdown 正文 |\n| Popup 通知 | 先显示摘要,再查看全文 |\n\n[访问官网](https://axlmc.org)" - }, - "app.remote-announcements.preview-summary": { - "message": "这是一条本地预览通知,点击“查看公告”可查看完整 Markdown 正文。" - }, - "app.remote-announcements.preview-title": { - "message": "公告样式预览" - }, - "app.remote-announcements.read-all": { - "message": "将所有公告标为已读" - }, - "app.remote-announcements.unread": { - "message": "未读" - }, - "app.remote-announcements.view": { - "message": "查看公告" - }, "app.restarting": { "message": "正在重启……" }, - "app.screenshots.copied": { - "message": "已复制" - }, - "app.screenshots.copy": { - "message": "复制图像" - }, - "app.screenshots.delete-description": { - "message": "永久删除 {name}?此操作无法撤销。" - }, - "app.screenshots.delete-success": { - "message": "截图已删除" - }, - "app.screenshots.delete-title": { - "message": "删除截图" - }, - "app.screenshots.deselect": { - "message": "取消选择 {name}" - }, - "app.screenshots.edit": { - "message": "编辑截图" - }, - "app.screenshots.empty-description": { - "message": "你在游戏中拍摄的截图会显示在这里。" - }, - "app.screenshots.empty-heading": { - "message": "还没有截图" - }, - "app.screenshots.error-heading": { - "message": "加载截图失败" - }, - "app.screenshots.go-to-instance": { - "message": "前往实例" - }, - "app.screenshots.group-by": { - "message": "分组方式" - }, - "app.screenshots.group.all-screenshots": { - "message": "全部截图" - }, - "app.screenshots.group.collapse": { - "message": "折叠分组" - }, - "app.screenshots.group.custom": { - "message": "自定义分组" - }, - "app.screenshots.group.date": { - "message": "日期" - }, - "app.screenshots.group.delete": { - "message": "删除分组" - }, - "app.screenshots.group.delete-description": { - "message": "此分组中的截图将变为未分组。" - }, - "app.screenshots.group.edit": { - "message": "编辑分组名称" - }, - "app.screenshots.group.empty": { - "message": "拖放以添加截图。" - }, - "app.screenshots.group.expand": { - "message": "展开分组" - }, - "app.screenshots.group.instance": { - "message": "实例" - }, - "app.screenshots.group.new": { - "message": "新建分组" - }, - "app.screenshots.group.none": { - "message": "不分组" - }, - "app.screenshots.group.this-month": { - "message": "本月" - }, - "app.screenshots.group.this-week": { - "message": "本周" - }, - "app.screenshots.group.today": { - "message": "今天" - }, - "app.screenshots.group.ungrouped": { - "message": "未分组" - }, - "app.screenshots.group.yesterday": { - "message": "昨天" - }, - "app.screenshots.heading": { - "message": "截图" - }, - "app.screenshots.more-actions": { - "message": "更多操作" - }, - "app.screenshots.no-results-description": { - "message": "请尝试其他搜索或筛选条件。" - }, - "app.screenshots.no-results-heading": { - "message": "没有匹配的截图" - }, - "app.screenshots.preview.instance-and-date": { - "message": "{instance} · {date}" - }, - "app.screenshots.search": { - "message": "搜索" - }, - "app.screenshots.select": { - "message": "选择 {name}" - }, - "app.screenshots.selection.aria-label": { - "message": "已选中的截图" - }, - "app.screenshots.selection.delete-description": { - "message": "删除 {count, plural, one {# 张截图} other {# 张截图}}?此操作无法撤销。" - }, - "app.screenshots.selection.delete-success": { - "message": "{count, plural, one {已删除 # 张截图} other {已删除 # 张截图}}" - }, - "app.screenshots.selection.delete-title": { - "message": "删除选中的截图" - }, - "app.screenshots.selection.export-zip": { - "message": "导出 ZIP" - }, - "app.screenshots.selection.global-export-filename": { - "message": "Modrinth screenshots.zip" - }, - "app.screenshots.selection.instance-export-filename": { - "message": "{instance} screenshots.zip" - }, - "app.screenshots.selection.remove-from-group": { - "message": "从分组中移除" - }, - "app.screenshots.selection.selected-count": { - "message": "已选中 {count} 张" - }, - "app.screenshots.selection.zip-archive": { - "message": "ZIP 压缩包" - }, - "app.screenshots.show-in-folder": { - "message": "在文件夹中显示" - }, - "app.screenshots.sort-by": { - "message": "排序方式" - }, - "app.screenshots.sort.name": { - "message": "名称" - }, - "app.screenshots.sort.newest": { - "message": "最新" - }, - "app.screenshots.sort.oldest": { - "message": "最旧" - }, "app.server.add": { "message": "添加" }, @@ -7010,33 +6653,6 @@ "app.servers.loading": { "message": "加载中" }, - "app.servers.modpack.background-hint": { - "message": "您可以关闭此窗口,下载将在后台继续进行。" - }, - "app.servers.modpack.current-file": { - "message": "正在安装 {file}" - }, - "app.servers.modpack.done": { - "message": "安装完成" - }, - "app.servers.modpack.download-in-background": { - "message": "后台下载" - }, - "app.servers.modpack.downloading": { - "message": "正在下载整合包文件..." - }, - "app.servers.modpack.first-run-crashed": { - "message": "服务器在首次启动时崩溃。请检查所选 Java 版本是否兼容,然后重试。" - }, - "app.servers.modpack.preparing": { - "message": "正在准备服务器..." - }, - "app.servers.modpack.unsupported-loader-description": { - "message": "此整合包使用 {loader},但 Starlight 目前仅支持原版、Fabric 和 Quilt 整合包服务端。{loader} 支持即将推出。" - }, - "app.servers.modpack.unsupported-loader-title": { - "message": "{loader} 服务端暂不支持" - }, "app.servers.port.change": { "message": "修改端口" }, @@ -7382,9 +6998,6 @@ "app.servers.status.crashed": { "message": "已崩溃" }, - "app.servers.status.created": { - "message": "未配置" - }, "app.servers.status.download-failed": { "message": "下载失败" }, @@ -7394,6 +7007,9 @@ "app.servers.status.downloading": { "message": "下载中" }, + "app.servers.status.created": { + "message": "未配置" + }, "app.servers.status.eula-pending": { "message": "待同意 EULA" }, @@ -7406,18 +7022,6 @@ "app.servers.status.starting": { "message": "启动中" }, - "app.servers.type.fabric": { - "message": "Fabric" - }, - "app.servers.type.forge": { - "message": "Forge" - }, - "app.servers.type.paper": { - "message": "Paper" - }, - "app.servers.type.vanilla": { - "message": "原版" - }, "app.servers.wizard.background-hint": { "message": "您可以关闭此窗口,下载将在后台继续进行。" }, @@ -7490,6 +7094,45 @@ "app.servers.wizard.type-title": { "message": "服务器类型" }, + "app.servers.type.vanilla": { + "message": "原版" + }, + "app.servers.type.fabric": { + "message": "Fabric" + }, + "app.servers.type.paper": { + "message": "Paper" + }, + "app.servers.type.forge": { + "message": "Forge" + }, + "app.servers.modpack.background-hint": { + "message": "您可以关闭此窗口,下载将在后台继续进行。" + }, + "app.servers.modpack.current-file": { + "message": "正在安装 {file}" + }, + "app.servers.modpack.download-in-background": { + "message": "后台下载" + }, + "app.servers.modpack.downloading": { + "message": "正在下载整合包文件..." + }, + "app.servers.modpack.first-run-crashed": { + "message": "服务器在首次启动时崩溃。请检查所选 Java 版本是否兼容,然后重试。" + }, + "app.servers.modpack.preparing": { + "message": "正在准备服务器..." + }, + "app.servers.modpack.done": { + "message": "安装完成" + }, + "app.servers.modpack.unsupported-loader-description": { + "message": "此整合包使用 {loader},但 Starlight 目前仅支持原版、Fabric 和 Quilt 整合包服务端。{loader} 支持即将推出。" + }, + "app.servers.modpack.unsupported-loader-title": { + "message": "{loader} 服务端暂不支持" + }, "app.settings.about.afdian": { "message": "在爱发电赞助" }, @@ -7514,9 +7157,6 @@ "app.settings.about.copy-qq-group": { "message": "复制群号" }, - "app.settings.about.copyright": { - "message": "版权所有 © StarLight 保留所有权利。" - }, "app.settings.about.description": { "message": "你的最后一款启动器。" }, @@ -7526,72 +7166,6 @@ "app.settings.about.development-team": { "message": "开发组" }, - "app.settings.about.easteregg.click-hint": { - "message": "点击以打开彩蛋小游戏" - }, - "app.settings.about.easteregg.contributors-title": { - "message": "贡献者彩蛋" - }, - "app.settings.about.easteregg.game-title": { - "message": "彩蛋小游戏" - }, - "app.settings.about.game.best": { - "message": "最佳:{score}" - }, - "app.settings.about.game.best-label": { - "message": "最佳" - }, - "app.settings.about.game.completed": { - "message": "下界之星!" - }, - "app.settings.about.game.exit": { - "message": "退出游戏" - }, - "app.settings.about.game.game-over": { - "message": "群星坠落!" - }, - "app.settings.about.game.highest-level": { - "message": "最高:等级 {level}" - }, - "app.settings.about.game.level-label": { - "message": "最高等级" - }, - "app.settings.about.game.new-record": { - "message": "新纪录!" - }, - "app.settings.about.game.overtime": { - "message": "涨潮!" - }, - "app.settings.about.game.overtime-detail": { - "message": "潮水涌回——继续合成!" - }, - "app.settings.about.game.overtimes-label": { - "message": "加时次数" - }, - "app.settings.about.game.restart": { - "message": "重新开始" - }, - "app.settings.about.game.score": { - "message": "得分:{score}" - }, - "app.settings.about.game.score-label": { - "message": "得分" - }, - "app.settings.about.game.settle": { - "message": "稳定" - }, - "app.settings.about.game.settle-title": { - "message": "本局已稳定!" - }, - "app.settings.about.game.tap-to-drop": { - "message": "点击投放一颗星" - }, - "app.settings.about.game.tide-hint": { - "message": "天空正在坠落——继续合成!" - }, - "app.settings.about.game.title": { - "message": "Starlight 合成" - }, "app.settings.about.license-attribution": { "message": "许可证与来源声明" }, @@ -7676,6 +7250,15 @@ "app.settings.defaults.fullscreen-description": { "message": "启动时覆盖 options.txt 文件,使游戏以全屏模式运行。" }, + "app.settings.defaults.maximize-window": { + "message": "最大化窗口" + }, + "app.settings.defaults.maximize-window-description": { + "message": "启动时最大化 Minecraft 窗口。" + }, + "app.settings.defaults.maximize-window.unsupported": { + "message": "当前操作系统暂不支持。" + }, "app.settings.defaults.height": { "message": "高度" }, @@ -7691,15 +7274,6 @@ "app.settings.defaults.java-arguments-placeholder": { "message": "输入 Java 参数……" }, - "app.settings.defaults.maximize-window": { - "message": "最大化窗口" - }, - "app.settings.defaults.maximize-window-description": { - "message": "启动时最大化 Minecraft 窗口。" - }, - "app.settings.defaults.maximize-window.unsupported": { - "message": "当前操作系统暂不支持。" - }, "app.settings.defaults.memory": { "message": "分配内存" }, @@ -7739,21 +7313,6 @@ "app.settings.defaults.width-placeholder": { "message": "输入宽度……" }, - "app.settings.defaults.window-title.default": { - "message": "默认窗口标题" - }, - "app.settings.defaults.window-title.default-description": { - "message": "当实例未提供自己的标题时使用。" - }, - "app.settings.defaults.window-title.default-placeholder": { - "message": "输入默认窗口标题..." - }, - "app.settings.defaults.window-title.enabled": { - "message": "自定义 Minecraft 窗口标题" - }, - "app.settings.defaults.window-title.enabled-description": { - "message": "允许实例自定义 Minecraft 窗口标题。" - }, "app.settings.defaults.wrapper-description": { "message": "用于启动 Minecraft 的包装器命令。" }, @@ -7766,1035 +7325,12 @@ "app.settings.developer-mode-enabled": { "message": "开发者模式已启用。" }, - "app.settings.developer.announcement-preview": { - "message": "公告样式预览" - }, - "app.settings.developer.announcement-preview-description": { - "message": "使用本地示例预览真实公告组件,不请求远端公告,也不改变真实公告的已读状态。" - }, - "app.settings.developer.preview-announcement-modal": { - "message": "预览启动弹窗" - }, - "app.settings.developer.preview-announcement-popup": { - "message": "预览 Popup 通知" - }, - "app.settings.developer.preview-with-action": { - "message": "显示可选的外部链接按钮" - }, "app.settings.downloading": { "message": "正在下载 v{version}" }, "app.settings.feature-flags.reset-to-default": { "message": "恢复默认值" }, - "app.settings.game-options.category.accessibility.description": { - "message": "无障碍设置" - }, - "app.settings.game-options.category.accessibility.label": { - "message": "无障碍" - }, - "app.settings.game-options.category.chat.description": { - "message": "聊天显示与外观" - }, - "app.settings.game-options.category.chat.label": { - "message": "聊天" - }, - "app.settings.game-options.category.controls.description": { - "message": "鼠标、移动与按键绑定" - }, - "app.settings.game-options.category.controls.label": { - "message": "控制" - }, - "app.settings.game-options.category.custom.description": { - "message": "由模组添加的设置" - }, - "app.settings.game-options.category.custom.label": { - "message": "自定义设置" - }, - "app.settings.game-options.category.language.description": { - "message": "游戏语言" - }, - "app.settings.game-options.category.language.label": { - "message": "语言" - }, - "app.settings.game-options.category.music-and-sound.description": { - "message": "音量与音频偏好" - }, - "app.settings.game-options.category.music-and-sound.label": { - "message": "音乐和声音" - }, - "app.settings.game-options.category.online.description": { - "message": "在线与 Realms 偏好" - }, - "app.settings.game-options.category.online.label": { - "message": "在线" - }, - "app.settings.game-options.category.skin-customization.description": { - "message": "皮肤层与主手" - }, - "app.settings.game-options.category.skin-customization.label": { - "message": "皮肤自定义" - }, - "app.settings.game-options.category.video.description": { - "message": "镜头与显示设置" - }, - "app.settings.game-options.category.video.label": { - "message": "视频" - }, - "app.settings.game-options.choice.all": { - "message": "全部" - }, - "app.settings.game-options.choice.balanced": { - "message": "平衡" - }, - "app.settings.game-options.choice.by-player": { - "message": "按玩家" - }, - "app.settings.game-options.choice.chat": { - "message": "聊天" - }, - "app.settings.game-options.choice.commands-only": { - "message": "仅命令" - }, - "app.settings.game-options.choice.constant": { - "message": "持续" - }, - "app.settings.game-options.choice.crosshair": { - "message": "准星" - }, - "app.settings.game-options.choice.custom": { - "message": "自定义" - }, - "app.settings.game-options.choice.decreased": { - "message": "降低" - }, - "app.settings.game-options.choice.default": { - "message": "默认" - }, - "app.settings.game-options.choice.fabulous": { - "message": "极佳" - }, - "app.settings.game-options.choice.fancy": { - "message": "精美" - }, - "app.settings.game-options.choice.far": { - "message": "远" - }, - "app.settings.game-options.choice.fast": { - "message": "快速" - }, - "app.settings.game-options.choice.frequent": { - "message": "频繁" - }, - "app.settings.game-options.choice.hidden": { - "message": "隐藏" - }, - "app.settings.game-options.choice.hotbar": { - "message": "快捷栏" - }, - "app.settings.game-options.choice.left": { - "message": "左" - }, - "app.settings.game-options.choice.limited": { - "message": "有限" - }, - "app.settings.game-options.choice.max-fps": { - "message": "最高 FPS" - }, - "app.settings.game-options.choice.maximum": { - "message": "最大" - }, - "app.settings.game-options.choice.minimal": { - "message": "最少" - }, - "app.settings.game-options.choice.minimum": { - "message": "最小" - }, - "app.settings.game-options.choice.nearby": { - "message": "附近" - }, - "app.settings.game-options.choice.never": { - "message": "从不" - }, - "app.settings.game-options.choice.none": { - "message": "无" - }, - "app.settings.game-options.choice.normal": { - "message": "正常" - }, - "app.settings.game-options.choice.off": { - "message": "关闭" - }, - "app.settings.game-options.choice.on": { - "message": "开启" - }, - "app.settings.game-options.choice.opengl": { - "message": "OpenGL 渲染器" - }, - "app.settings.game-options.choice.pause": { - "message": "暂停菜单" - }, - "app.settings.game-options.choice.pause-and-toast": { - "message": "暂停菜单和提示" - }, - "app.settings.game-options.choice.power-saver": { - "message": "省电" - }, - "app.settings.game-options.choice.right": { - "message": "右" - }, - "app.settings.game-options.choice.short": { - "message": "短" - }, - "app.settings.game-options.choice.shown": { - "message": "显示" - }, - "app.settings.game-options.choice.system": { - "message": "系统" - }, - "app.settings.game-options.choice.tiny": { - "message": "极小" - }, - "app.settings.game-options.choice.vulkan": { - "message": "Vulkan 渲染器" - }, - "app.settings.game-options.choice.when-minimized": { - "message": "最小化时" - }, - "app.settings.game-options.choice.while-afk": { - "message": "挂机时" - }, - "app.settings.game-options.compatibility.none": { - "message": "部分实例无法使用此设置" - }, - "app.settings.game-options.compatibility.reason.launcher-controlled": { - "message": "此设置由启动器设置管理" - }, - "app.settings.game-options.custom-value.placeholder": { - "message": "输入值" - }, - "app.settings.game-options.keybind.assigned-status": { - "message": "已将 {setting} 绑定为 {binding}。" - }, - "app.settings.game-options.keybind.cancelled-status": { - "message": "已取消按键绑定更改。" - }, - "app.settings.game-options.keybind.change": { - "message": "{setting}:{binding}。激活以更改绑定。" - }, - "app.settings.game-options.keybind.choose": { - "message": "选择按键" - }, - "app.settings.game-options.keybind.conflict-description": { - "message": "{settings} 已使用此按键。" - }, - "app.settings.game-options.keybind.key.arrow-down": { - "message": "向下箭头" - }, - "app.settings.game-options.keybind.key.arrow-left": { - "message": "向左箭头" - }, - "app.settings.game-options.keybind.key.arrow-right": { - "message": "向右箭头" - }, - "app.settings.game-options.keybind.key.arrow-up": { - "message": "向上箭头" - }, - "app.settings.game-options.keybind.key.backspace": { - "message": "退格" - }, - "app.settings.game-options.keybind.key.caps-lock": { - "message": "大写锁定" - }, - "app.settings.game-options.keybind.key.delete": { - "message": "删除" - }, - "app.settings.game-options.keybind.key.end": { - "message": "End 键" - }, - "app.settings.game-options.keybind.key.enter": { - "message": "回车" - }, - "app.settings.game-options.keybind.key.escape": { - "message": "Esc 键" - }, - "app.settings.game-options.keybind.key.home": { - "message": "Home 键" - }, - "app.settings.game-options.keybind.key.insert": { - "message": "Insert 键" - }, - "app.settings.game-options.keybind.key.keypad-key": { - "message": "数字键盘 {key}" - }, - "app.settings.game-options.keybind.key.left-alt": { - "message": "左 Alt" - }, - "app.settings.game-options.keybind.key.left-command": { - "message": "左 Command" - }, - "app.settings.game-options.keybind.key.left-control": { - "message": "左 Ctrl" - }, - "app.settings.game-options.keybind.key.left-shift": { - "message": "左 Shift" - }, - "app.settings.game-options.keybind.key.left-super": { - "message": "左 Super" - }, - "app.settings.game-options.keybind.key.menu": { - "message": "菜单" - }, - "app.settings.game-options.keybind.key.num-lock": { - "message": "数字锁定" - }, - "app.settings.game-options.keybind.key.page-down": { - "message": "Page Down 键" - }, - "app.settings.game-options.keybind.key.page-up": { - "message": "Page Up 键" - }, - "app.settings.game-options.keybind.key.pause": { - "message": "暂停" - }, - "app.settings.game-options.keybind.key.print-screen": { - "message": "截图" - }, - "app.settings.game-options.keybind.key.right-alt": { - "message": "右 Alt" - }, - "app.settings.game-options.keybind.key.right-command": { - "message": "右 Command" - }, - "app.settings.game-options.keybind.key.right-control": { - "message": "右 Ctrl" - }, - "app.settings.game-options.keybind.key.right-shift": { - "message": "右 Shift" - }, - "app.settings.game-options.keybind.key.right-super": { - "message": "右 Super" - }, - "app.settings.game-options.keybind.key.scroll-lock": { - "message": "滚动锁定" - }, - "app.settings.game-options.keybind.key.space": { - "message": "空格" - }, - "app.settings.game-options.keybind.key.tab": { - "message": "Tab 键" - }, - "app.settings.game-options.keybind.key.unbound": { - "message": "未绑定" - }, - "app.settings.game-options.keybind.key.unknown": { - "message": "未知按键" - }, - "app.settings.game-options.keybind.listen": { - "message": "请按下一个按键……" - }, - "app.settings.game-options.keybind.listening-status": { - "message": "正在监听按键或鼠标按钮。按 Esc 清除绑定。" - }, - "app.settings.game-options.keybind.mixed": { - "message": "各实例不同" - }, - "app.settings.game-options.keybind.modifier.alt": { - "message": "Alt 键" - }, - "app.settings.game-options.keybind.modifier.command": { - "message": "Command 键" - }, - "app.settings.game-options.keybind.modifier.control": { - "message": "Ctrl 键" - }, - "app.settings.game-options.keybind.modifier.shift": { - "message": "Shift 键" - }, - "app.settings.game-options.keybind.modifier.super": { - "message": "Super 键" - }, - "app.settings.game-options.keybind.mouse.button": { - "message": "鼠标 {button}" - }, - "app.settings.game-options.keybind.mouse.left": { - "message": "鼠标左键" - }, - "app.settings.game-options.keybind.mouse.middle": { - "message": "鼠标中键" - }, - "app.settings.game-options.keybind.mouse.right": { - "message": "鼠标右键" - }, - "app.settings.game-options.keybind.recording-label": { - "message": "{setting}:正在监听按键或鼠标按钮。按 Esc 清除绑定。" - }, - "app.settings.game-options.keybind.scancode": { - "message": "扫描码 {code}" - }, - "app.settings.game-options.keybind.unsupported-status": { - "message": "Minecraft 无法使用此输入,请尝试其他按键。" - }, - "app.settings.game-options.setting.advanced-opengl.label": { - "message": "高级 OpenGL" - }, - "app.settings.game-options.setting.allow-cursor-changes.label": { - "message": "允许光标变化" - }, - "app.settings.game-options.setting.allow-server-listing.description": { - "message": "允许玩家名称出现在服务器列表中。" - }, - "app.settings.game-options.setting.allow-server-listing.label": { - "message": "服务器列表" - }, - "app.settings.game-options.setting.alternate-blocks.label": { - "message": "备用方块" - }, - "app.settings.game-options.setting.ambient-occlusion.label": { - "message": "平滑光照" - }, - "app.settings.game-options.setting.ambient-volume.label": { - "message": "环境" - }, - "app.settings.game-options.setting.anaglyph-3d.label": { - "message": "3D 红蓝立体" - }, - "app.settings.game-options.setting.anisotropic-filtering.label": { - "message": "各向异性过滤" - }, - "app.settings.game-options.setting.anisotropy.label": { - "message": "各向异性" - }, - "app.settings.game-options.setting.attack-indicator.label": { - "message": "攻击指示器" - }, - "app.settings.game-options.setting.auto-jump.description": { - "message": "自动跳过一格高的障碍物。" - }, - "app.settings.game-options.setting.auto-jump.label": { - "message": "自动跳跃" - }, - "app.settings.game-options.setting.auto-suggestions.label": { - "message": "命令建议" - }, - "app.settings.game-options.setting.autosave-indicator.label": { - "message": "自动保存指示器" - }, - "app.settings.game-options.setting.biome-blend-radius.description": { - "message": "生物群系颜色过渡的距离。" - }, - "app.settings.game-options.setting.biome-blend-radius.label": { - "message": "生物群系混合" - }, - "app.settings.game-options.setting.blocks-volume.label": { - "message": "方块" - }, - "app.settings.game-options.setting.brightness.label": { - "message": "亮度" - }, - "app.settings.game-options.setting.cape.description": { - "message": "显示玩家的披风,包括鞘翅纹理。" - }, - "app.settings.game-options.setting.cape.label": { - "message": "披风" - }, - "app.settings.game-options.setting.chat-background-only.label": { - "message": "仅聊天背景" - }, - "app.settings.game-options.setting.chat-colors.label": { - "message": "聊天颜色" - }, - "app.settings.game-options.setting.chat-delay.label": { - "message": "聊天延迟" - }, - "app.settings.game-options.setting.chat-line-spacing.label": { - "message": "聊天行间距" - }, - "app.settings.game-options.setting.chat-links-prompt.description": { - "message": "打开聊天链接前询问" - }, - "app.settings.game-options.setting.chat-links-prompt.label": { - "message": "打开链接前询问" - }, - "app.settings.game-options.setting.chat-links.description": { - "message": "允许打开聊天中的网页链接。" - }, - "app.settings.game-options.setting.chat-links.label": { - "message": "网页链接" - }, - "app.settings.game-options.setting.chat-opacity.description": { - "message": "聊天文字的不透明度。" - }, - "app.settings.game-options.setting.chat-opacity.label": { - "message": "聊天不透明度" - }, - "app.settings.game-options.setting.chat-preview.label": { - "message": "聊天预览" - }, - "app.settings.game-options.setting.chat-scale.label": { - "message": "聊天缩放" - }, - "app.settings.game-options.setting.chat-visibility.label": { - "message": "聊天可见性" - }, - "app.settings.game-options.setting.chat-width.label": { - "message": "聊天宽度" - }, - "app.settings.game-options.setting.chunk-fade-time.label": { - "message": "区块淡出时间" - }, - "app.settings.game-options.setting.cloud-range.label": { - "message": "云层距离" - }, - "app.settings.game-options.setting.clouds.label": { - "message": "云" - }, - "app.settings.game-options.setting.ctrl-click-right-click.label": { - "message": "按住 Control 点击代替右键点击" - }, - "app.settings.game-options.setting.cutout-leaves.label": { - "message": "半透明树叶" - }, - "app.settings.game-options.setting.damage-tilt.label": { - "message": "受伤倾斜" - }, - "app.settings.game-options.setting.dark-splash.description": { - "message": "将 Mojang Studios 加载界面从红色改为黑色。" - }, - "app.settings.game-options.setting.dark-splash.label": { - "message": "单色徽标" - }, - "app.settings.game-options.setting.darkness-pulsing.label": { - "message": "黑暗脉动" - }, - "app.settings.game-options.setting.debug-gui-scale.label": { - "message": "调试界面缩放" - }, - "app.settings.game-options.setting.directional-audio.label": { - "message": "方向性音频" - }, - "app.settings.game-options.setting.discrete-mouse-scroll.description": { - "message": "将每次鼠标滚轮输入视为一个滚动步进。" - }, - "app.settings.game-options.setting.discrete-mouse-scroll.label": { - "message": "离散滚动" - }, - "app.settings.game-options.setting.entity-distance.label": { - "message": "实体距离" - }, - "app.settings.game-options.setting.entity-shadows.label": { - "message": "实体阴影" - }, - "app.settings.game-options.setting.exclusive-fullscreen.label": { - "message": "独占全屏" - }, - "app.settings.game-options.setting.extra-telemetry.label": { - "message": "可选遥测" - }, - "app.settings.game-options.setting.focused-chat-height.label": { - "message": "聚焦时聊天高度" - }, - "app.settings.game-options.setting.force-unicode-font.label": { - "message": "强制 Unicode 字体" - }, - "app.settings.game-options.setting.fov-effects.label": { - "message": "视野效果" - }, - "app.settings.game-options.setting.fov.label": { - "message": "视野" - }, - "app.settings.game-options.setting.fullscreen.label": { - "message": "全屏" - }, - "app.settings.game-options.setting.glint-speed.label": { - "message": "附魔光效速度" - }, - "app.settings.game-options.setting.glint-strength.label": { - "message": "附魔光效强度" - }, - "app.settings.game-options.setting.graphics-backend.label": { - "message": "图形后端" - }, - "app.settings.game-options.setting.graphics.description": { - "message": "控制画面质量和性能。" - }, - "app.settings.game-options.setting.graphics.label": { - "message": "画面" - }, - "app.settings.game-options.setting.gui-scale.description": { - "message": "游戏界面和 HUD 的大小。" - }, - "app.settings.game-options.setting.gui-scale.label": { - "message": "界面缩放" - }, - "app.settings.game-options.setting.hat.description": { - "message": "显示帽子皮肤层。" - }, - "app.settings.game-options.setting.hat.label": { - "message": "帽子" - }, - "app.settings.game-options.setting.held-item-tooltips.label": { - "message": "手持物品提示" - }, - "app.settings.game-options.setting.hide-lightning-flashes.label": { - "message": "隐藏闪电闪光" - }, - "app.settings.game-options.setting.hide-matched-names.label": { - "message": "隐藏匹配的名称" - }, - "app.settings.game-options.setting.hide-server-address.label": { - "message": "隐藏服务器地址" - }, - "app.settings.game-options.setting.hide-splash-texts.label": { - "message": "隐藏启动标语" - }, - "app.settings.game-options.setting.high-contrast-outline.label": { - "message": "高对比度方块轮廓" - }, - "app.settings.game-options.setting.high-contrast.description": { - "message": "增强界面元素的对比度。" - }, - "app.settings.game-options.setting.high-contrast.label": { - "message": "高对比度" - }, - "app.settings.game-options.setting.hostile-volume.label": { - "message": "敌对生物" - }, - "app.settings.game-options.setting.improved-transparency.label": { - "message": "改进透明度" - }, - "app.settings.game-options.setting.in-game-notifications.label": { - "message": "游戏内通知" - }, - "app.settings.game-options.setting.inactivity-framerate-limit.label": { - "message": "降低帧率" - }, - "app.settings.game-options.setting.invert-horizontal-mouse.label": { - "message": "反转水平鼠标" - }, - "app.settings.game-options.setting.invert-mouse.description": { - "message": "反转垂直鼠标移动。" - }, - "app.settings.game-options.setting.invert-mouse.label": { - "message": "反转鼠标" - }, - "app.settings.game-options.setting.jacket.description": { - "message": "显示夹克皮肤层。" - }, - "app.settings.game-options.setting.jacket.label": { - "message": "夹克" - }, - "app.settings.game-options.setting.japanese-glyph-variants.label": { - "message": "日文字符变体" - }, - "app.settings.game-options.setting.key-advancements.label": { - "message": "进度" - }, - "app.settings.game-options.setting.key-attack.label": { - "message": "攻击" - }, - "app.settings.game-options.setting.key-back.label": { - "message": "后退" - }, - "app.settings.game-options.setting.key-chat.label": { - "message": "打开聊天" - }, - "app.settings.game-options.setting.key-command.label": { - "message": "命令" - }, - "app.settings.game-options.setting.key-debug-advanced-tooltips.label": { - "message": "显示高级提示" - }, - "app.settings.game-options.setting.key-debug-chunk-borders.label": { - "message": "显示区块边界" - }, - "app.settings.game-options.setting.key-debug-clear-chat.label": { - "message": "清空聊天" - }, - "app.settings.game-options.setting.key-debug-copy-location.label": { - "message": "复制位置" - }, - "app.settings.game-options.setting.key-debug-copy-recreate-command.label": { - "message": "复制重建命令" - }, - "app.settings.game-options.setting.key-debug-crash.label": { - "message": "触发调试崩溃" - }, - "app.settings.game-options.setting.key-debug-dump-dynamic-textures.label": { - "message": "转储动态纹理" - }, - "app.settings.game-options.setting.key-debug-dump-version.label": { - "message": "转储版本" - }, - "app.settings.game-options.setting.key-debug-focus-pause.label": { - "message": "失去焦点时暂停" - }, - "app.settings.game-options.setting.key-debug-fps-charts.label": { - "message": "FPS 图表" - }, - "app.settings.game-options.setting.key-debug-hitboxes.label": { - "message": "显示碰撞箱" - }, - "app.settings.game-options.setting.key-debug-improved-transparency.label": { - "message": "改进透明度调试视图" - }, - "app.settings.game-options.setting.key-debug-lightmap-texture.label": { - "message": "光照贴图纹理" - }, - "app.settings.game-options.setting.key-debug-modifier.label": { - "message": "调试修饰键" - }, - "app.settings.game-options.setting.key-debug-network-charts.label": { - "message": "网络图表" - }, - "app.settings.game-options.setting.key-debug-options.label": { - "message": "调试选项" - }, - "app.settings.game-options.setting.key-debug-overlay.label": { - "message": "调试覆盖层" - }, - "app.settings.game-options.setting.key-debug-profiling-chart.label": { - "message": "性能分析图表" - }, - "app.settings.game-options.setting.key-debug-profiling.label": { - "message": "开始性能分析" - }, - "app.settings.game-options.setting.key-debug-reload-chunks.label": { - "message": "重新加载区块" - }, - "app.settings.game-options.setting.key-debug-reload-resource-packs.label": { - "message": "重新加载资源包" - }, - "app.settings.game-options.setting.key-debug-spectate.label": { - "message": "旁观实体" - }, - "app.settings.game-options.setting.key-debug-switch-game-mode.label": { - "message": "切换游戏模式" - }, - "app.settings.game-options.setting.key-drop.label": { - "message": "丢弃物品" - }, - "app.settings.game-options.setting.key-forward.label": { - "message": "前进" - }, - "app.settings.game-options.setting.key-friends.label": { - "message": "好友" - }, - "app.settings.game-options.setting.key-fullscreen.label": { - "message": "切换全屏" - }, - "app.settings.game-options.setting.key-hotbar-1.label": { - "message": "快捷栏 1" - }, - "app.settings.game-options.setting.key-hotbar-2.label": { - "message": "快捷栏 2" - }, - "app.settings.game-options.setting.key-hotbar-3.label": { - "message": "快捷栏 3" - }, - "app.settings.game-options.setting.key-hotbar-4.label": { - "message": "快捷栏 4" - }, - "app.settings.game-options.setting.key-hotbar-5.label": { - "message": "快捷栏 5" - }, - "app.settings.game-options.setting.key-hotbar-6.label": { - "message": "快捷栏 6" - }, - "app.settings.game-options.setting.key-hotbar-7.label": { - "message": "快捷栏 7" - }, - "app.settings.game-options.setting.key-hotbar-8.label": { - "message": "快捷栏 8" - }, - "app.settings.game-options.setting.key-hotbar-9.label": { - "message": "快捷栏 9" - }, - "app.settings.game-options.setting.key-inventory.label": { - "message": "物品栏" - }, - "app.settings.game-options.setting.key-jump.label": { - "message": "跳跃" - }, - "app.settings.game-options.setting.key-left.label": { - "message": "向左平移" - }, - "app.settings.game-options.setting.key-load-toolbar.label": { - "message": "加载工具栏" - }, - "app.settings.game-options.setting.key-perspective.label": { - "message": "切换视角" - }, - "app.settings.game-options.setting.key-pick-item.label": { - "message": "选取方块" - }, - "app.settings.game-options.setting.key-player-list.label": { - "message": "玩家列表" - }, - "app.settings.game-options.setting.key-quick-actions.label": { - "message": "快捷操作" - }, - "app.settings.game-options.setting.key-right.label": { - "message": "向右平移" - }, - "app.settings.game-options.setting.key-save-toolbar.label": { - "message": "保存工具栏" - }, - "app.settings.game-options.setting.key-screenshot.label": { - "message": "截图" - }, - "app.settings.game-options.setting.key-smooth-camera.label": { - "message": "切换电影视角" - }, - "app.settings.game-options.setting.key-sneak.label": { - "message": "潜行" - }, - "app.settings.game-options.setting.key-social-interactions.label": { - "message": "社交互动" - }, - "app.settings.game-options.setting.key-spectator-hotbar.label": { - "message": "旁观者快捷栏" - }, - "app.settings.game-options.setting.key-spectator-outlines.label": { - "message": "高亮旁观者" - }, - "app.settings.game-options.setting.key-sprint.label": { - "message": "疾跑" - }, - "app.settings.game-options.setting.key-swap-offhand.label": { - "message": "交换副手" - }, - "app.settings.game-options.setting.key-toggle-gui.label": { - "message": "切换 HUD" - }, - "app.settings.game-options.setting.key-toggle-spectator-shader.label": { - "message": "切换旁观者着色器" - }, - "app.settings.game-options.setting.key-use.label": { - "message": "使用物品" - }, - "app.settings.game-options.setting.language.label": { - "message": "语言" - }, - "app.settings.game-options.setting.left-pants-leg.label": { - "message": "左裤腿" - }, - "app.settings.game-options.setting.left-sleeve.label": { - "message": "左袖" - }, - "app.settings.game-options.setting.legacy-framerate-limit.label": { - "message": "帧率上限" - }, - "app.settings.game-options.setting.legacy-view-distance.label": { - "message": "视距" - }, - "app.settings.game-options.setting.mac-fullscreen-menu.label": { - "message": "全屏时显示 macOS 菜单" - }, - "app.settings.game-options.setting.main-hand.description": { - "message": "选择主手为左手还是右手。" - }, - "app.settings.game-options.setting.main-hand.label": { - "message": "主手" - }, - "app.settings.game-options.setting.master-volume.label": { - "message": "主音量" - }, - "app.settings.game-options.setting.max-framerate.label": { - "message": "最大帧率" - }, - "app.settings.game-options.setting.menu-background-blur.label": { - "message": "菜单背景模糊" - }, - "app.settings.game-options.setting.mipmap-levels.description": { - "message": "平滑远处纹理。" - }, - "app.settings.game-options.setting.mipmap-levels.label": { - "message": "Mipmap 级别" - }, - "app.settings.game-options.setting.mouse-wheel-sensitivity.label": { - "message": "鼠标滚轮灵敏度" - }, - "app.settings.game-options.setting.music-frequency.label": { - "message": "音乐频率" - }, - "app.settings.game-options.setting.music-toast.description": { - "message": "选择是否在暂停菜单和提示中显示音乐标题。" - }, - "app.settings.game-options.setting.music-toast.label": { - "message": "音乐通知" - }, - "app.settings.game-options.setting.music-volume.label": { - "message": "音乐" - }, - "app.settings.game-options.setting.narrator-hotkey.label": { - "message": "旁白快捷键" - }, - "app.settings.game-options.setting.narrator.description": { - "message": "选择旁白朗读的内容。" - }, - "app.settings.game-options.setting.narrator.label": { - "message": "旁白" - }, - "app.settings.game-options.setting.neutral-volume.label": { - "message": "友好生物" - }, - "app.settings.game-options.setting.notification-time.description": { - "message": "提示通知保持显示的时长。" - }, - "app.settings.game-options.setting.notification-time.label": { - "message": "通知时长" - }, - "app.settings.game-options.setting.operator-items-tab.label": { - "message": "管理员物品栏标签" - }, - "app.settings.game-options.setting.panorama-speed.label": { - "message": "全景图速度" - }, - "app.settings.game-options.setting.particles.label": { - "message": "粒子" - }, - "app.settings.game-options.setting.players-volume.label": { - "message": "玩家" - }, - "app.settings.game-options.setting.prioritize-chunk-updates.label": { - "message": "区块更新优先级" - }, - "app.settings.game-options.setting.quit-shortcuts.label": { - "message": "退出快捷键" - }, - "app.settings.game-options.setting.raw-mouse-input.label": { - "message": "原始鼠标输入" - }, - "app.settings.game-options.setting.realms-notifications.label": { - "message": "Realms 通知" - }, - "app.settings.game-options.setting.record-volume.label": { - "message": "唱片机/音符盒" - }, - "app.settings.game-options.setting.reduced-debug-info.label": { - "message": "减少调试信息" - }, - "app.settings.game-options.setting.render-distance.label": { - "message": "渲染距离" - }, - "app.settings.game-options.setting.right-pants-leg.label": { - "message": "右裤腿" - }, - "app.settings.game-options.setting.right-sleeve.label": { - "message": "右袖" - }, - "app.settings.game-options.setting.rotate-with-minecart.label": { - "message": "随矿车旋转" - }, - "app.settings.game-options.setting.save-chat-drafts.label": { - "message": "保存聊天草稿" - }, - "app.settings.game-options.setting.screen-effects.label": { - "message": "屏幕效果" - }, - "app.settings.game-options.setting.secure-chat-only.label": { - "message": "仅显示安全聊天" - }, - "app.settings.game-options.setting.sensitivity.label": { - "message": "鼠标灵敏度" - }, - "app.settings.game-options.setting.server-textures.label": { - "message": "服务器纹理" - }, - "app.settings.game-options.setting.share-presence.label": { - "message": "共享在线状态" - }, - "app.settings.game-options.setting.simulation-distance.description": { - "message": "实体更新以及方块和流体更新的距离。" - }, - "app.settings.game-options.setting.simulation-distance.label": { - "message": "模拟距离" - }, - "app.settings.game-options.setting.snooper.label": { - "message": "数据收集" - }, - "app.settings.game-options.setting.sprint-window.label": { - "message": "疾跑窗口" - }, - "app.settings.game-options.setting.subtitles.description": { - "message": "显示游戏声音的字幕。" - }, - "app.settings.game-options.setting.subtitles.label": { - "message": "字幕" - }, - "app.settings.game-options.setting.text-background-opacity.label": { - "message": "文字背景不透明度" - }, - "app.settings.game-options.setting.texture-filtering.label": { - "message": "纹理过滤" - }, - "app.settings.game-options.setting.toggle-attack.label": { - "message": "切换攻击" - }, - "app.settings.game-options.setting.toggle-crouch.description": { - "message": "按一次即可保持潜行。" - }, - "app.settings.game-options.setting.toggle-crouch.label": { - "message": "切换潜行" - }, - "app.settings.game-options.setting.toggle-sprint.description": { - "message": "按一次即可保持疾跑。" - }, - "app.settings.game-options.setting.toggle-sprint.label": { - "message": "切换疾跑" - }, - "app.settings.game-options.setting.toggle-use.label": { - "message": "切换使用" - }, - "app.settings.game-options.setting.touchscreen.label": { - "message": "触屏模式" - }, - "app.settings.game-options.setting.ui-volume.label": { - "message": "界面" - }, - "app.settings.game-options.setting.unfocused-chat-height.label": { - "message": "未聚焦时聊天高度" - }, - "app.settings.game-options.setting.use-vbo.label": { - "message": "使用 VBO" - }, - "app.settings.game-options.setting.view-bobbing.description": { - "message": "行走时为镜头添加摇摆效果。" - }, - "app.settings.game-options.setting.view-bobbing.label": { - "message": "视角摇摆" - }, - "app.settings.game-options.setting.vignette.label": { - "message": "晕影" - }, - "app.settings.game-options.setting.voice-volume.label": { - "message": "语音和语音朗读" - }, - "app.settings.game-options.setting.vsync.description": { - "message": "将帧率限制为显示器刷新率,以防止画面撕裂。" - }, - "app.settings.game-options.setting.vsync.label": { - "message": "垂直同步" - }, - "app.settings.game-options.setting.weather-radius.label": { - "message": "天气范围" - }, - "app.settings.game-options.setting.weather-volume.label": { - "message": "天气" - }, - "app.settings.game-options.validation.changed-since-opened": { - "message": "此设置已在其他位置更改,请检查后重试。" - }, - "app.settings.game-options.validation.invalid-value": { - "message": "请选择有效值。" - }, - "app.settings.game-options.validation.missing-value": { - "message": "请先选择一个值。" - }, - "app.settings.game-options.validation.no-compatible-instances": { - "message": "部分实例无法使用此设置" - }, "app.settings.groups.data-privacy": { "message": "数据与隐私" }, @@ -8894,75 +7430,6 @@ "app.settings.java.view-installed": { "message": "查看已安装 Java" }, - "app.settings.logs.export.button": { - "message": "导出日志…" - }, - "app.settings.logs.export.description": { - "message": "将启动器日志打包,可附带环境摘要、最近的实例日志与崩溃分析。" - }, - "app.settings.logs.export.modal.cancel": { - "message": "取消" - }, - "app.settings.logs.export.modal.confirm": { - "message": "导出" - }, - "app.settings.logs.export.modal.crash-analysis": { - "message": "崩溃分析(检测到崩溃时)" - }, - "app.settings.logs.export.modal.description": { - "message": "选择要包含的详细程度。导出的日志会把访问令牌、Minecraft 令牌与 IP 地址替换为占位符。" - }, - "app.settings.logs.export.modal.extras": { - "message": "附加信息" - }, - "app.settings.logs.export.modal.instance-logs": { - "message": "最近的实例日志" - }, - "app.settings.logs.export.modal.level": { - "message": "日志等级" - }, - "app.settings.logs.export.modal.level.all": { - "message": "全部等级" - }, - "app.settings.logs.export.modal.level.debug": { - "message": "DEBUG 及以上" - }, - "app.settings.logs.export.modal.level.info": { - "message": "INFO 及以上" - }, - "app.settings.logs.export.modal.range": { - "message": "时间范围" - }, - "app.settings.logs.export.modal.range.2-hours": { - "message": "最近 2 小时" - }, - "app.settings.logs.export.modal.range.30-minutes": { - "message": "最近 30 分钟" - }, - "app.settings.logs.export.modal.range.all": { - "message": "全部会话" - }, - "app.settings.logs.export.modal.system-info": { - "message": "系统与环境摘要" - }, - "app.settings.logs.export.modal.title": { - "message": "导出日志" - }, - "app.settings.logs.export.notification-text": { - "message": "日志压缩包已保存到 {path}" - }, - "app.settings.logs.export.notification-title": { - "message": "日志已导出" - }, - "app.settings.logs.export.title": { - "message": "导出日志" - }, - "app.settings.logs.open-folder": { - "message": "打开日志文件夹" - }, - "app.settings.resources.add-minecraft-directory": { - "message": "添加 .minecraft 目录" - }, "app.settings.resources.app-cache": { "message": "应用缓存" }, @@ -8972,14 +7439,41 @@ "app.settings.resources.app-directory": { "message": "应用目录" }, + "app.settings.resources.axolotl-data-directory": { + "message": "Starlight 数据目录" + }, "app.settings.resources.app-directory-description": { "message": "启动器用于存储全部游戏文件的目录。更改将在重启启动器后生效。" }, "app.settings.resources.app-directory-description-portable": { "message": "正在以便携模式运行,所有数据已固定在程序目录下,无法修改。" }, - "app.settings.resources.axolotl-data-directory": { - "message": "Starlight 数据目录" + "app.settings.resources.minecraft-directories": { + "message": "Minecraft 目录" + }, + "app.settings.resources.minecraft-directories-description": { + "message": "添加一个或多个供实例使用的外部 .minecraft 文件夹。这些文件夹与 Starlight 数据分开保存。" + }, + "app.settings.resources.minecraft-directory-mode": { + "message": "游戏目录模式" + }, + "app.settings.resources.minecraft-directory-mode.isolated": { + "message": "版本隔离" + }, + "app.settings.resources.minecraft-directory-mode.shared": { + "message": "共享 .minecraft 目录" + }, + "app.settings.resources.add-minecraft-directory": { + "message": "添加 .minecraft 目录" + }, + "app.settings.resources.select-minecraft-directory": { + "message": "选择 .minecraft 目录" + }, + "app.settings.resources.remove-minecraft-directory": { + "message": "删除 .minecraft 目录" + }, + "app.settings.resources.minecraft-directory-must-end-with": { + "message": "所选文件夹名称必须是 .minecraft。" }, "app.settings.resources.concurrency.manual": { "message": "手动" @@ -8996,6 +7490,12 @@ "app.settings.resources.curseforge-restriction-bypass-description": { "message": "当 CurseForge 不提供下载地址时,根据文件信息推导其 CDN 地址并尝试自动下载。关闭后将使用手动下载流程。" }, + "app.settings.resources.ignore-ssl-errors": { + "message": "忽略 SSL 证书错误" + }, + "app.settings.resources.ignore-ssl-errors-description": { + "message": "跳过启动器网络请求的 TLS 证书校验。仅当你信任当前网络并了解其安全风险时才启用。" + }, "app.settings.resources.database-backups": { "message": "应用数据库备份" }, @@ -9020,12 +7520,6 @@ "app.settings.resources.download-mirrors-description": { "message": "自动模式会根据本地环境和近期连接质量,在官方源与镜像源之间选择。" }, - "app.settings.resources.ignore-ssl-errors": { - "message": "忽略 SSL 证书错误" - }, - "app.settings.resources.ignore-ssl-errors-description": { - "message": "跳过启动器网络请求的 TLS 证书校验。仅当你信任当前网络并了解其安全风险时才启用。" - }, "app.settings.resources.maximum-downloads": { "message": "最大并发下载数" }, @@ -9038,24 +7532,6 @@ "app.settings.resources.maximum-writes-description": { "message": "启动器同时写入磁盘的最大文件数。如果经常出现 I/O 错误,请降低此值;更改需要重启应用后生效。" }, - "app.settings.resources.minecraft-directories": { - "message": "Minecraft 目录" - }, - "app.settings.resources.minecraft-directories-description": { - "message": "添加一个或多个供实例使用的外部 .minecraft 文件夹。这些文件夹与 Starlight 数据分开保存。" - }, - "app.settings.resources.minecraft-directory-mode": { - "message": "游戏目录模式" - }, - "app.settings.resources.minecraft-directory-mode.isolated": { - "message": "版本隔离" - }, - "app.settings.resources.minecraft-directory-mode.shared": { - "message": "共享 .minecraft 目录" - }, - "app.settings.resources.minecraft-directory-must-end-with": { - "message": "所选文件夹名称必须是 .minecraft。" - }, "app.settings.resources.minecraft-file-source": { "message": "Minecraft 文件、加载器与 Java" }, @@ -9158,9 +7634,6 @@ "app.settings.resources.purge-confirm-title": { "message": "确定要清除缓存吗?" }, - "app.settings.resources.remove-minecraft-directory": { - "message": "删除 .minecraft 目录" - }, "app.settings.resources.reset-import-directory": { "message": "使用系统 Downloads 文件夹" }, @@ -9170,9 +7643,6 @@ "app.settings.resources.select-import-directory": { "message": "选择监控目录" }, - "app.settings.resources.select-minecraft-directory": { - "message": "选择 .minecraft 目录" - }, "app.settings.resources.source.automatic": { "message": "自动(推荐)" }, @@ -9320,249 +7790,6 @@ "app.settings.storage.world": { "message": "世界" }, - "app.settings.synced-options.choose-sync-source.command-history-description": { - "message": "选择要从哪个实例复制命令历史记录。这些记录仅用于初始同步,之后可从任意实例编辑。" - }, - "app.settings.synced-options.choose-sync-source.command-history-title": { - "message": "选择命令历史记录来源" - }, - "app.settings.synced-options.choose-sync-source.creative-hotbars-description": { - "message": "选择要从哪个实例复制保存的创造模式快捷栏。这些快捷栏仅用于初始同步,之后可从任意实例编辑。" - }, - "app.settings.synced-options.choose-sync-source.creative-hotbars-title": { - "message": "选择创造模式快捷栏来源" - }, - "app.settings.synced-options.choose-sync-source.data-packs-title": { - "message": "选择数据包来源" - }, - "app.settings.synced-options.choose-sync-source.game-settings-description": { - "message": "选择要从哪个实例复制游戏设置。这些设置仅用于初始同步,之后可从任意实例编辑。" - }, - "app.settings.synced-options.choose-sync-source.game-settings-title": { - "message": "选择游戏设置来源" - }, - "app.settings.synced-options.choose-sync-source.ineligible": { - "message": "无法选择此实例作为同步来源" - }, - "app.settings.synced-options.choose-sync-source.load-error": { - "message": "无法加载同步来源,请重试。" - }, - "app.settings.synced-options.choose-sync-source.multiplayer-servers-description": { - "message": "选择要从哪个实例复制多人服务器列表。这些服务器仅用于初始同步,之后可从任意实例编辑。" - }, - "app.settings.synced-options.choose-sync-source.multiplayer-servers-title": { - "message": "选择多人服务器来源" - }, - "app.settings.synced-options.choose-sync-source.no-instances-found": { - "message": "没有找到实例" - }, - "app.settings.synced-options.choose-sync-source.resource-packs-title": { - "message": "选择资源包来源" - }, - "app.settings.synced-options.choose-sync-source.retry": { - "message": "重试" - }, - "app.settings.synced-options.choose-sync-source.search-placeholder": { - "message": "搜索实例" - }, - "app.settings.synced-options.choose-sync-source.sync": { - "message": "同步" - }, - "app.settings.synced-options.command-history": { - "message": "同步命令记录" - }, - "app.settings.synced-options.command-history.description": { - "message": "在不同的实例之间同步命令记录。" - }, - "app.settings.synced-options.command-history.editor-title": { - "message": "编辑指令历史记录" - }, - "app.settings.synced-options.creative-hotbars": { - "message": "同步保存的创造模式物品栏" - }, - "app.settings.synced-options.creative-hotbars.description": { - "message": "在不同的实例之间同步创造模式物品栏。" - }, - "app.settings.synced-options.data-packs": { - "message": "同步数据包" - }, - "app.settings.synced-options.data-packs.description": { - "message": "在所有实例间使用相同的数据包" - }, - "app.settings.synced-options.data-packs.none-synced-yet": { - "message": "尚未同步任何数据包" - }, - "app.settings.synced-options.edit.no-instances": { - "message": "请先添加实例,再编辑同步数据。" - }, - "app.settings.synced-options.edit.no-synced-data": { - "message": "请先选择同步来源,再编辑此设置。" - }, - "app.settings.synced-options.game-settings": { - "message": "同步游戏设置" - }, - "app.settings.synced-options.game-settings.button": { - "message": "编辑游戏设置" - }, - "app.settings.synced-options.game-settings.conflict-text": { - "message": "我们已加载最新设置。请检查更改后再次保存。" - }, - "app.settings.synced-options.game-settings.conflict-title": { - "message": "这些设置已在其他地方更改" - }, - "app.settings.synced-options.game-settings.custom-empty": { - "message": "Modrinth 在某个实例中找到模组添加的设置后,它们会显示在这里。" - }, - "app.settings.synced-options.game-settings.description": { - "message": "在所有实例间使用相同的游戏设置。" - }, - "app.settings.synced-options.game-settings.disable-all": { - "message": "取消同步全部" - }, - "app.settings.synced-options.game-settings.disabled-tooltip": { - "message": "请先启用游戏设置同步,再选择单个设置。" - }, - "app.settings.synced-options.game-settings.empty": { - "message": "没有匹配当前搜索或筛选条件的设置。" - }, - "app.settings.synced-options.game-settings.enable-all": { - "message": "同步全部" - }, - "app.settings.synced-options.game-settings.load-failed": { - "message": "无法加载游戏设置。" - }, - "app.settings.synced-options.game-settings.loading": { - "message": "正在加载设置……" - }, - "app.settings.synced-options.game-settings.no-options-to-edit": { - "message": "目前没有可编辑的设置" - }, - "app.settings.synced-options.game-settings.not-being-synced": { - "message": "未同步" - }, - "app.settings.synced-options.game-settings.retry": { - "message": "重试" - }, - "app.settings.synced-options.game-settings.save": { - "message": "保存设置" - }, - "app.settings.synced-options.game-settings.search": { - "message": "搜索设置……" - }, - "app.settings.synced-options.game-settings.sync-description": { - "message": "同步的选项会应用到每个实例,并覆盖整合包中包含的值。" - }, - "app.settings.synced-options.game-settings.sync-setting": { - "message": "在所有实例间同步{setting}" - }, - "app.settings.synced-options.game-settings.sync-title": { - "message": "同步游戏设置" - }, - "app.settings.synced-options.game-settings.synced-across-instances": { - "message": "已在所有实例间同步" - }, - "app.settings.synced-options.game-settings.title": { - "message": "游戏设置" - }, - "app.settings.synced-options.game-settings.unsaved-changes": { - "message": "你有未保存的更改。" - }, - "app.settings.synced-options.game-settings.unsync-setting": { - "message": "停止在所有实例间同步{setting}" - }, - "app.settings.synced-options.game-settings.value-mixed": { - "message": "各实例不同" - }, - "app.settings.synced-options.game-settings.value-off": { - "message": "关闭" - }, - "app.settings.synced-options.game-settings.value-on": { - "message": "开启" - }, - "app.settings.synced-options.game-settings.value-unset": { - "message": "选择一个值" - }, - "app.settings.synced-options.multiplayer-servers": { - "message": "同步多人模式服务器列表" - }, - "app.settings.synced-options.multiplayer-servers.address": { - "message": "服务器地址" - }, - "app.settings.synced-options.multiplayer-servers.copy-address": { - "message": "复制地址" - }, - "app.settings.synced-options.multiplayer-servers.count": { - "message": "{count, number} 个服务器" - }, - "app.settings.synced-options.multiplayer-servers.description": { - "message": "在不同的实例直接同步多人模式服务器列表。" - }, - "app.settings.synced-options.multiplayer-servers.editor-title": { - "message": "编辑同步的服务器" - }, - "app.settings.synced-options.multiplayer-servers.empty": { - "message": "当前未同步任何用户添加的服务器。" - }, - "app.settings.synced-options.multiplayer-servers.filter-offline": { - "message": "离线" - }, - "app.settings.synced-options.multiplayer-servers.filter-online": { - "message": "在线" - }, - "app.settings.synced-options.multiplayer-servers.more-options": { - "message": "更多服务器选项" - }, - "app.settings.synced-options.multiplayer-servers.name": { - "message": "服务器名称" - }, - "app.settings.synced-options.multiplayer-servers.no-results": { - "message": "没有匹配搜索或筛选条件的已同步服务器。" - }, - "app.settings.synced-options.multiplayer-servers.none-synced-yet": { - "message": "暂无已同步的服务器" - }, - "app.settings.synced-options.multiplayer-servers.players-online": { - "message": "{count, number} 人在线" - }, - "app.settings.synced-options.multiplayer-servers.search": { - "message": "搜索 {count, number} 个已同步服务器……" - }, - "app.settings.synced-options.multiplayer-servers.status": { - "message": "状态" - }, - "app.settings.synced-options.packs.disabled": { - "message": "请先启用同步,再编辑共享包。" - }, - "app.settings.synced-options.resource-packs": { - "message": "同步资源包" - }, - "app.settings.synced-options.resource-packs.description": { - "message": "在所有实例间使用相同的资源包" - }, - "app.settings.synced-options.resource-packs.none-synced-yet": { - "message": "尚未同步任何资源包" - }, - "app.settings.synced-options.title": { - "message": "跨所有实例同步的选项" - }, - "app.settings.synced-packs.data-packs": { - "message": "数据包" - }, - "app.settings.synced-packs.disable": { - "message": "禁用" - }, - "app.settings.synced-packs.empty": { - "message": "没有已同步的包" - }, - "app.settings.synced-packs.enable": { - "message": "启用" - }, - "app.settings.synced-packs.remove": { - "message": "移除" - }, - "app.settings.synced-packs.resource-packs": { - "message": "资源包" - }, "app.settings.tabs.about": { "message": "关于" }, @@ -9596,18 +7823,12 @@ "app.settings.tabs.launch-defaults": { "message": "启动与实例默认值" }, - "app.settings.tabs.logs": { - "message": "日志与诊断" - }, "app.settings.tabs.network-multiplayer": { "message": "网络与多人游戏" }, "app.settings.tabs.resource-management": { "message": "资源管理" }, - "app.settings.tabs.shortcut-settings": { - "message": "键盘快捷键" - }, "app.settings.tabs.storage": { "message": "存储" }, @@ -9680,21 +7901,6 @@ "app.settings.updates.channel.title": { "message": "更新通道" }, - "app.settings.updates.check": { - "message": "检查更新" - }, - "app.settings.updates.check.title": { - "message": "检查更新" - }, - "app.settings.updates.checking": { - "message": "正在检查更新……" - }, - "app.settings.updates.cnb": { - "message": "CNB 渠道" - }, - "app.settings.updates.current-version": { - "message": "当前版本 {version}" - }, "app.settings.updates.database-isolation.active": { "message": "正在使用" }, @@ -9743,6 +7949,30 @@ "app.settings.updates.database-operation.success": { "message": "已成功将 {source} 复制到 {target}。" }, + "app.settings.updates.check": { + "message": "检查更新" + }, + "app.settings.updates.check.title": { + "message": "检查更新" + }, + "app.settings.updates.checking": { + "message": "正在检查更新……" + }, + "app.settings.updates.cnb": { + "message": "CNB 渠道" + }, + "app.settings.updates.current-version": { + "message": "当前版本 {version}" + }, + "app.settings.updates.latest-version": { + "message": "最新 {channel} 版本:{version}" + }, + "app.settings.updates.latest-version-unavailable": { + "message": "最新版本暂不可用" + }, + "app.settings.updates.latest-version-loading": { + "message": "正在获取" + }, "app.settings.updates.description": { "message": "选择 Starlight 检查启动器更新的渠道。" }, @@ -9752,9 +7982,6 @@ "app.settings.updates.failed": { "message": "无法检查更新。" }, - "app.settings.updates.github": { - "message": "GitHub 渠道" - }, "app.settings.updates.immediate-fetch": { "message": "最新更新可用后立即获取" }, @@ -9764,14 +7991,8 @@ "app.settings.updates.immediate-fetch.beta-description": { "message": "Beta 更新始终立即可用。" }, - "app.settings.updates.latest-version": { - "message": "最新 {channel} 版本:{version}" - }, - "app.settings.updates.latest-version-loading": { - "message": "正在获取" - }, - "app.settings.updates.latest-version-unavailable": { - "message": "最新版本暂不可用" + "app.settings.updates.github": { + "message": "GitHub 渠道" }, "app.settings.updates.miawa": { "message": "柠泽资源站" @@ -9806,2865 +8027,12 @@ "app.settings.updates.up-to-date": { "message": "Starlight 已是最新版本。" }, - "app.shortcut-settings.change-shortcut": { - "message": "更改「{action}」的快捷键" - }, - "app.shortcut-settings.enable": { - "message": "启用快捷滚动" - }, - "app.shortcut-settings.end-action": { - "message": "滚动到页面底部" - }, - "app.shortcut-settings.end-action-description": { - "message": "将当前页面移动到底部。" - }, - "app.shortcut-settings.home-action": { - "message": "滚动到页面顶部" - }, - "app.shortcut-settings.home-action-description": { - "message": "将当前页面移动到顶部。" - }, - "app.shortcut-settings.nav-create": { - "message": "新建实例" - }, - "app.shortcut-settings.nav-create-description": { - "message": "前往新建实例。" - }, - "app.shortcut-settings.nav-description": { - "message": "使用各自的快捷键跳转到对应菜单项。每个快捷键默认关闭,需逐个启用。" - }, - "app.shortcut-settings.nav-discover": { - "message": "发现内容" - }, - "app.shortcut-settings.nav-discover-description": { - "message": "前往浏览内容。" - }, - "app.shortcut-settings.nav-downloads": { - "message": "下载" - }, - "app.shortcut-settings.nav-downloads-description": { - "message": "前往下载。" - }, - "app.shortcut-settings.nav-home": { - "message": "首页" - }, - "app.shortcut-settings.nav-home-description": { - "message": "前往首页。" - }, - "app.shortcut-settings.nav-lab": { - "message": "实验室" - }, - "app.shortcut-settings.nav-lab-description": { - "message": "前往实验室。" - }, - "app.shortcut-settings.nav-library": { - "message": "内容库" - }, - "app.shortcut-settings.nav-library-description": { - "message": "前往内容库。" - }, - "app.shortcut-settings.nav-multiplayer": { - "message": "多人游戏" - }, - "app.shortcut-settings.nav-multiplayer-description": { - "message": "前往多人游戏。" - }, - "app.shortcut-settings.nav-settings": { - "message": "设置" - }, - "app.shortcut-settings.nav-settings-description": { - "message": "前往设置。" - }, - "app.shortcut-settings.nav-skins": { - "message": "皮肤选择器" - }, - "app.shortcut-settings.nav-skins-description": { - "message": "前往皮肤选择器。" - }, - "app.shortcut-settings.nav-title": { - "message": "导航快捷键" - }, - "app.shortcut-settings.nav-worlds": { - "message": "世界" - }, - "app.shortcut-settings.nav-worlds-description": { - "message": "前往你的世界。" - }, - "app.shortcut-settings.page-down-action": { - "message": "向下滚动一屏" - }, - "app.shortcut-settings.page-down-action-description": { - "message": "将当前页面向下移动一屏。" - }, - "app.shortcut-settings.page-up-action": { - "message": "向上滚动一屏" - }, - "app.shortcut-settings.page-up-action-description": { - "message": "将当前页面向上移动一屏。" - }, - "app.shortcut-settings.scroll-description": { - "message": "使用键盘在长页面中快速滚动。" - }, - "app.shortcut-settings.scroll-title": { - "message": "快速滚动" - }, "app.sidebar.collapse": { "message": "收起边栏" }, "app.sidebar.expand": { "message": "展开边栏" }, - "app.skin-site.admin.audit.action": { - "message": "操作" - }, - "app.skin-site.admin.audit.clear": { - "message": "清空" - }, - "app.skin-site.admin.audit.count": { - "message": "次数" - }, - "app.skin-site.admin.audit.empty": { - "message": "没有审计记录。" - }, - "app.skin-site.admin.audit.failed": { - "message": "无法加载审计日志。" - }, - "app.skin-site.admin.audit.first-at": { - "message": "首次出现" - }, - "app.skin-site.admin.audit.internal": { - "message": "内部" - }, - "app.skin-site.admin.audit.last-at": { - "message": "最近出现" - }, - "app.skin-site.admin.audit.load-more": { - "message": "加载更多" - }, - "app.skin-site.admin.audit.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.audit.proxy": { - "message": "代理" - }, - "app.skin-site.admin.audit.record-limit": { - "message": "记录上限" - }, - "app.skin-site.admin.audit.reported-ip": { - "message": "上报玩家 IP" - }, - "app.skin-site.admin.audit.retention": { - "message": "保留天数" - }, - "app.skin-site.admin.audit.retention-saved": { - "message": "保留天数已更新。" - }, - "app.skin-site.admin.audit.save-retention": { - "message": "保存" - }, - "app.skin-site.admin.audit.search": { - "message": "搜索" - }, - "app.skin-site.admin.audit.search-action": { - "message": "操作" - }, - "app.skin-site.admin.audit.search-ip": { - "message": "IP" - }, - "app.skin-site.admin.audit.search-subject": { - "message": "主体" - }, - "app.skin-site.admin.audit.source-ip": { - "message": "来源 IP" - }, - "app.skin-site.admin.audit.subject": { - "message": "主体" - }, - "app.skin-site.admin.audit.title": { - "message": "登录与认证审计" - }, - "app.skin-site.admin.back": { - "message": "返回主页" - }, - "app.skin-site.admin.broadcast.cancel": { - "message": "取消" - }, - "app.skin-site.admin.broadcast.confirm-delete": { - "message": "确定删除「{title}」吗?此操作不可撤销。" - }, - "app.skin-site.admin.broadcast.content-field": { - "message": "内容" - }, - "app.skin-site.admin.broadcast.create": { - "message": "发布新公告" - }, - "app.skin-site.admin.broadcast.created": { - "message": "公告已发布。" - }, - "app.skin-site.admin.broadcast.deleted": { - "message": "公告已删除。" - }, - "app.skin-site.admin.broadcast.edit": { - "message": "编辑" - }, - "app.skin-site.admin.broadcast.empty": { - "message": "尚未发布过任何公告。" - }, - "app.skin-site.admin.broadcast.expire-at": { - "message": "过期时间" - }, - "app.skin-site.admin.broadcast.failed": { - "message": "加载失败。" - }, - "app.skin-site.admin.broadcast.image": { - "message": "图片" - }, - "app.skin-site.admin.broadcast.level": { - "message": "重要程度" - }, - "app.skin-site.admin.broadcast.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.broadcast.remove": { - "message": "删除" - }, - "app.skin-site.admin.broadcast.remove-image": { - "message": "移除图片" - }, - "app.skin-site.admin.broadcast.save": { - "message": "保存" - }, - "app.skin-site.admin.broadcast.star": { - "message": "标星" - }, - "app.skin-site.admin.broadcast.subtitle-field": { - "message": "副标题" - }, - "app.skin-site.admin.broadcast.title": { - "message": "公告" - }, - "app.skin-site.admin.broadcast.title-field": { - "message": "标题" - }, - "app.skin-site.admin.broadcast.updated": { - "message": "公告已更新。" - }, - "app.skin-site.admin.broadcast.uploader": { - "message": "由 {name} 发布" - }, - "app.skin-site.admin.donations.amount": { - "message": "金额" - }, - "app.skin-site.admin.donations.amount-field": { - "message": "金额" - }, - "app.skin-site.admin.donations.append-mode": { - "message": "在原有金额上累加" - }, - "app.skin-site.admin.donations.cancel": { - "message": "取消" - }, - "app.skin-site.admin.donations.confirm-delete": { - "message": "确定删除「{name}」的捐赠记录吗?此操作不可撤销。" - }, - "app.skin-site.admin.donations.create": { - "message": "新增捐赠" - }, - "app.skin-site.admin.donations.created": { - "message": "捐赠记录已创建。" - }, - "app.skin-site.admin.donations.deleted": { - "message": "捐赠记录已删除。" - }, - "app.skin-site.admin.donations.display-name": { - "message": "显示名称" - }, - "app.skin-site.admin.donations.donor": { - "message": "捐赠者" - }, - "app.skin-site.admin.donations.donor-count": { - "message": "捐赠人数" - }, - "app.skin-site.admin.donations.edit": { - "message": "编辑" - }, - "app.skin-site.admin.donations.empty": { - "message": "暂无捐赠记录。" - }, - "app.skin-site.admin.donations.external": { - "message": "外部" - }, - "app.skin-site.admin.donations.failed": { - "message": "无法加载捐赠列表。" - }, - "app.skin-site.admin.donations.linked": { - "message": "已绑定" - }, - "app.skin-site.admin.donations.load-more": { - "message": "加载更多" - }, - "app.skin-site.admin.donations.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.donations.qq": { - "message": "QQ" - }, - "app.skin-site.admin.donations.remove": { - "message": "删除" - }, - "app.skin-site.admin.donations.save": { - "message": "保存" - }, - "app.skin-site.admin.donations.title": { - "message": "捐赠管理" - }, - "app.skin-site.admin.donations.total-amount": { - "message": "总额" - }, - "app.skin-site.admin.donations.updated": { - "message": "捐赠记录已更新。" - }, - "app.skin-site.admin.donations.updated-at": { - "message": "更新时间" - }, - "app.skin-site.admin.donations.user-uuid": { - "message": "用户 UUID" - }, - "app.skin-site.admin.downloads.add-category": { - "message": "添加" - }, - "app.skin-site.admin.downloads.add-item": { - "message": "新建条目" - }, - "app.skin-site.admin.downloads.add-route": { - "message": "添加线路" - }, - "app.skin-site.admin.downloads.all": { - "message": "全部条目" - }, - "app.skin-site.admin.downloads.bind-category": { - "message": "所属分类" - }, - "app.skin-site.admin.downloads.cancel": { - "message": "取消" - }, - "app.skin-site.admin.downloads.categories": { - "message": "分类" - }, - "app.skin-site.admin.downloads.category-added": { - "message": "分类已添加。" - }, - "app.skin-site.admin.downloads.category-deleted": { - "message": "分类已删除。" - }, - "app.skin-site.admin.downloads.category-name": { - "message": "分类名称" - }, - "app.skin-site.admin.downloads.confirm-delete-category": { - "message": "确定删除分类「{name}」吗?" - }, - "app.skin-site.admin.downloads.confirm-delete-item": { - "message": "确定删除「{name}」吗?此操作不可撤销。" - }, - "app.skin-site.admin.downloads.created": { - "message": "条目已创建。" - }, - "app.skin-site.admin.downloads.deleted": { - "message": "条目已删除。" - }, - "app.skin-site.admin.downloads.description": { - "message": "描述" - }, - "app.skin-site.admin.downloads.edit": { - "message": "编辑" - }, - "app.skin-site.admin.downloads.empty": { - "message": "没有下载条目。" - }, - "app.skin-site.admin.downloads.failed": { - "message": "无法加载资源列表。" - }, - "app.skin-site.admin.downloads.filename": { - "message": "文件名" - }, - "app.skin-site.admin.downloads.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.downloads.remove": { - "message": "删除" - }, - "app.skin-site.admin.downloads.remove-category": { - "message": "移除" - }, - "app.skin-site.admin.downloads.remove-route": { - "message": "移除" - }, - "app.skin-site.admin.downloads.route-name": { - "message": "名称" - }, - "app.skin-site.admin.downloads.route-url": { - "message": "URL" - }, - "app.skin-site.admin.downloads.routes": { - "message": "下载线路" - }, - "app.skin-site.admin.downloads.save": { - "message": "保存" - }, - "app.skin-site.admin.downloads.statuses": { - "message": "状态" - }, - "app.skin-site.admin.downloads.title": { - "message": "资源下载" - }, - "app.skin-site.admin.downloads.total": { - "message": "共 {count} 个条目" - }, - "app.skin-site.admin.downloads.updated": { - "message": "条目已更新。" - }, - "app.skin-site.admin.downloads.uploader": { - "message": "由 {name} 上传" - }, - "app.skin-site.admin.group.community": { - "message": "社区管理" - }, - "app.skin-site.admin.group.resources": { - "message": "资源分发" - }, - "app.skin-site.admin.group.security": { - "message": "系统安全" - }, - "app.skin-site.admin.group.users": { - "message": "用户管理" - }, - "app.skin-site.admin.item.access-audit": { - "message": "登录与认证审计" - }, - "app.skin-site.admin.item.broadcast": { - "message": "公告操作" - }, - "app.skin-site.admin.item.chat": { - "message": "聊天室管理" - }, - "app.skin-site.admin.item.donations": { - "message": "捐赠管理" - }, - "app.skin-site.admin.item.downloads": { - "message": "下载管理" - }, - "app.skin-site.admin.item.launcher": { - "message": "启动器管理" - }, - "app.skin-site.admin.item.mods": { - "message": "Mod 管理" - }, - "app.skin-site.admin.item.players": { - "message": "玩家信息" - }, - "app.skin-site.admin.item.review": { - "message": "玩家审核" - }, - "app.skin-site.admin.item.servers": { - "message": "服务器管理" - }, - "app.skin-site.admin.item.summary": { - "message": "状态概览" - }, - "app.skin-site.admin.item.users": { - "message": "用户信息" - }, - "app.skin-site.admin.item.wiki": { - "message": "维基管理" - }, - "app.skin-site.admin.launcher.activate": { - "message": "设为当前" - }, - "app.skin-site.admin.launcher.activated": { - "message": "已设为当前版本。" - }, - "app.skin-site.admin.launcher.active": { - "message": "当前版本" - }, - "app.skin-site.admin.launcher.channel": { - "message": "渠道" - }, - "app.skin-site.admin.launcher.empty": { - "message": "尚未上传任何版本。" - }, - "app.skin-site.admin.launcher.failed": { - "message": "无法加载版本列表。" - }, - "app.skin-site.admin.launcher.force-flag": { - "message": "强制更新" - }, - "app.skin-site.admin.launcher.force-update": { - "message": "强制更新" - }, - "app.skin-site.admin.launcher.latest-url": { - "message": "最新版本地址" - }, - "app.skin-site.admin.launcher.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.launcher.next": { - "message": "下一页" - }, - "app.skin-site.admin.launcher.page": { - "message": "第 {page} 页" - }, - "app.skin-site.admin.launcher.prev": { - "message": "上一页" - }, - "app.skin-site.admin.launcher.published-at": { - "message": "发布时间" - }, - "app.skin-site.admin.launcher.title": { - "message": "启动器版本" - }, - "app.skin-site.admin.launcher.total": { - "message": "共 {count} 个版本" - }, - "app.skin-site.admin.launcher.upload": { - "message": "上传版本" - }, - "app.skin-site.admin.launcher.upload-done": { - "message": "版本已上传。" - }, - "app.skin-site.admin.launcher.upload-hint": { - "message": "选择发布包 ZIP(最大 4 GiB)。" - }, - "app.skin-site.admin.launcher.uploaded-at": { - "message": "上传时间" - }, - "app.skin-site.admin.launcher.uploader": { - "message": "上传者" - }, - "app.skin-site.admin.launcher.uploading": { - "message": "上传中…" - }, - "app.skin-site.admin.launcher.version": { - "message": "版本" - }, - "app.skin-site.admin.mods.activate": { - "message": "设为当前" - }, - "app.skin-site.admin.mods.activated": { - "message": "运行时已启用。" - }, - "app.skin-site.admin.mods.active": { - "message": "当前版本" - }, - "app.skin-site.admin.mods.apply": { - "message": "应用" - }, - "app.skin-site.admin.mods.available": { - "message": "可用" - }, - "app.skin-site.admin.mods.cancel": { - "message": "取消" - }, - "app.skin-site.admin.mods.clear": { - "message": "清除" - }, - "app.skin-site.admin.mods.clear-selection": { - "message": "取消全选" - }, - "app.skin-site.admin.mods.confirm-delete": { - "message": "确定删除 Mod「{name}」吗?此操作不可撤销。" - }, - "app.skin-site.admin.mods.confirm-delete-multi": { - "message": "确定删除选中的 {count} 个 Mod?此操作不可撤销。" - }, - "app.skin-site.admin.mods.confirm-delete-tag": { - "message": "确定删除标签「{name}」吗?" - }, - "app.skin-site.admin.mods.delete-selected": { - "message": "删除所选" - }, - "app.skin-site.admin.mods.deleted": { - "message": "Mod 已删除。" - }, - "app.skin-site.admin.mods.deleted-multi": { - "message": "已删除所选 Mod。" - }, - "app.skin-site.admin.mods.domain-rules": { - "message": "域名规则" - }, - "app.skin-site.admin.mods.edit": { - "message": "编辑" - }, - "app.skin-site.admin.mods.empty": { - "message": "没有找到 Mod。" - }, - "app.skin-site.admin.mods.exit-select": { - "message": "完成选择" - }, - "app.skin-site.admin.mods.failed": { - "message": "无法加载 Mod 列表。" - }, - "app.skin-site.admin.mods.filter-all": { - "message": "全部标签" - }, - "app.skin-site.admin.mods.loaders": { - "message": "加载器" - }, - "app.skin-site.admin.mods.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.mods.manifest-url": { - "message": "清单地址" - }, - "app.skin-site.admin.mods.mod-id": { - "message": "Mod ID" - }, - "app.skin-site.admin.mods.name": { - "message": "名称" - }, - "app.skin-site.admin.mods.new-tag": { - "message": "新建标签" - }, - "app.skin-site.admin.mods.next": { - "message": "下一页" - }, - "app.skin-site.admin.mods.page": { - "message": "第 {page} 页" - }, - "app.skin-site.admin.mods.prev": { - "message": "上一页" - }, - "app.skin-site.admin.mods.remove": { - "message": "删除" - }, - "app.skin-site.admin.mods.rule-tags": { - "message": "规则标签" - }, - "app.skin-site.admin.mods.runtime": { - "message": "运行时版本" - }, - "app.skin-site.admin.mods.runtime-uploaded": { - "message": "运行时已上传。" - }, - "app.skin-site.admin.mods.runtime-version": { - "message": "版本" - }, - "app.skin-site.admin.mods.save": { - "message": "保存" - }, - "app.skin-site.admin.mods.search": { - "message": "按名称搜索" - }, - "app.skin-site.admin.mods.select-all": { - "message": "全选本页" - }, - "app.skin-site.admin.mods.select-mode": { - "message": "选择多个" - }, - "app.skin-site.admin.mods.selected-count": { - "message": "已选择 {count} 项" - }, - "app.skin-site.admin.mods.server-address": { - "message": "服务器地址" - }, - "app.skin-site.admin.mods.server-address-hint": { - "message": "按服务器地址过滤" - }, - "app.skin-site.admin.mods.size": { - "message": "大小" - }, - "app.skin-site.admin.mods.tab-mods": { - "message": "Mod 文件" - }, - "app.skin-site.admin.mods.tab-runtime": { - "message": "运行时" - }, - "app.skin-site.admin.mods.tab-tags": { - "message": "规则标签" - }, - "app.skin-site.admin.mods.tag-created": { - "message": "标签已创建。" - }, - "app.skin-site.admin.mods.tag-deleted": { - "message": "标签已删除。" - }, - "app.skin-site.admin.mods.tag-name": { - "message": "标签名称" - }, - "app.skin-site.admin.mods.tag-rules": { - "message": "规则" - }, - "app.skin-site.admin.mods.tag-rules-hint": { - "message": "每行一条规则。" - }, - "app.skin-site.admin.mods.tag-updated": { - "message": "标签已更新。" - }, - "app.skin-site.admin.mods.title": { - "message": "Mod 管理" - }, - "app.skin-site.admin.mods.total": { - "message": "共 {count} 个 Mod" - }, - "app.skin-site.admin.mods.unavailable": { - "message": "不可用" - }, - "app.skin-site.admin.mods.updated": { - "message": "Mod 已更新。" - }, - "app.skin-site.admin.mods.upload": { - "message": "上传" - }, - "app.skin-site.admin.mods.upload-all-done": { - "message": "全部文件处理完成。" - }, - "app.skin-site.admin.mods.upload-checking": { - "message": "检查中…" - }, - "app.skin-site.admin.mods.upload-close": { - "message": "关闭" - }, - "app.skin-site.admin.mods.upload-conflict": { - "message": "名称已存在" - }, - "app.skin-site.admin.mods.upload-drop": { - "message": "拖拽 .jar 文件到此处,或点击选择" - }, - "app.skin-site.admin.mods.upload-error": { - "message": "失败" - }, - "app.skin-site.admin.mods.upload-exists": { - "message": "该文件已存在于服务器。" - }, - "app.skin-site.admin.mods.upload-name-conflict": { - "message": "已存在同名 Mod" - }, - "app.skin-site.admin.mods.upload-name-conflict-hint": { - "message": "覆盖已有 Mod,或跳过此文件。" - }, - "app.skin-site.admin.mods.upload-overwrite": { - "message": "覆盖" - }, - "app.skin-site.admin.mods.upload-pending": { - "message": "等待中" - }, - "app.skin-site.admin.mods.upload-queue": { - "message": "文件列表" - }, - "app.skin-site.admin.mods.upload-runtime": { - "message": "上传运行时" - }, - "app.skin-site.admin.mods.upload-skip": { - "message": "跳过" - }, - "app.skin-site.admin.mods.upload-sub": { - "message": "支持多文件,单个不超过 {size} MB" - }, - "app.skin-site.admin.mods.upload-success": { - "message": "完成" - }, - "app.skin-site.admin.mods.upload-tags": { - "message": "附加规则标签" - }, - "app.skin-site.admin.mods.upload-title": { - "message": "上传 Mod" - }, - "app.skin-site.admin.mods.upload-too-large": { - "message": "文件过大:{name}" - }, - "app.skin-site.admin.mods.upload-uploading": { - "message": "上传中…" - }, - "app.skin-site.admin.mods.uploader": { - "message": "由 {name} 上传" - }, - "app.skin-site.admin.mods.uploading": { - "message": "上传中…" - }, - "app.skin-site.admin.mods.version": { - "message": "版本" - }, - "app.skin-site.admin.no-access": { - "message": "你没有访问权限。" - }, - "app.skin-site.admin.no-access-hint": { - "message": "请使用管理员账号登录后使用本控制台。" - }, - "app.skin-site.admin.players.actions": { - "message": "操作" - }, - "app.skin-site.admin.players.cancel": { - "message": "取消" - }, - "app.skin-site.admin.players.confirm-delete": { - "message": "确定删除玩家「{name}」吗?此操作不可撤销。" - }, - "app.skin-site.admin.players.custom": { - "message": "皮肤站" - }, - "app.skin-site.admin.players.deleted": { - "message": "玩家已删除。" - }, - "app.skin-site.admin.players.edit": { - "message": "编辑" - }, - "app.skin-site.admin.players.empty": { - "message": "没有找到玩家。" - }, - "app.skin-site.admin.players.failed": { - "message": "无法加载玩家列表。" - }, - "app.skin-site.admin.players.legacy": { - "message": "旧版适配" - }, - "app.skin-site.admin.players.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.players.mojang": { - "message": "正版" - }, - "app.skin-site.admin.players.name": { - "message": "名称" - }, - "app.skin-site.admin.players.next": { - "message": "下一页" - }, - "app.skin-site.admin.players.owner": { - "message": "所有者" - }, - "app.skin-site.admin.players.page": { - "message": "第 {page} 页" - }, - "app.skin-site.admin.players.prev": { - "message": "上一页" - }, - "app.skin-site.admin.players.remove": { - "message": "删除" - }, - "app.skin-site.admin.players.save": { - "message": "保存" - }, - "app.skin-site.admin.players.search": { - "message": "搜索" - }, - "app.skin-site.admin.players.search-name": { - "message": "名称" - }, - "app.skin-site.admin.players.search-owner": { - "message": "所有者" - }, - "app.skin-site.admin.players.search-uuid": { - "message": "UUID" - }, - "app.skin-site.admin.players.source": { - "message": "来源" - }, - "app.skin-site.admin.players.title": { - "message": "玩家" - }, - "app.skin-site.admin.players.total": { - "message": "共 {count} 名玩家" - }, - "app.skin-site.admin.players.updated": { - "message": "玩家已更新。" - }, - "app.skin-site.admin.review.accept": { - "message": "通过" - }, - "app.skin-site.admin.review.accept-done": { - "message": "申请已通过。" - }, - "app.skin-site.admin.review.activity": { - "message": "行为记录" - }, - "app.skin-site.admin.review.add-option": { - "message": "添加选项" - }, - "app.skin-site.admin.review.add-question": { - "message": "添加题目" - }, - "app.skin-site.admin.review.answers": { - "message": "作答内容" - }, - "app.skin-site.admin.review.applicant": { - "message": "申请人" - }, - "app.skin-site.admin.review.auto-checks": { - "message": "自动检查" - }, - "app.skin-site.admin.review.context": { - "message": "提交环境" - }, - "app.skin-site.admin.review.copy-link": { - "message": "复制直链" - }, - "app.skin-site.admin.review.details": { - "message": "详情" - }, - "app.skin-site.admin.review.duration": { - "message": "时长" - }, - "app.skin-site.admin.review.edit-paper": { - "message": "编辑" - }, - "app.skin-site.admin.review.empty": { - "message": "没有找到申请。" - }, - "app.skin-site.admin.review.failed": { - "message": "无法加载申请列表。" - }, - "app.skin-site.admin.review.filter-all": { - "message": "全部" - }, - "app.skin-site.admin.review.filter-passed": { - "message": "已通过" - }, - "app.skin-site.admin.review.filter-pending": { - "message": "待处理" - }, - "app.skin-site.admin.review.filter-rejected": { - "message": "已拒绝" - }, - "app.skin-site.admin.review.hidden-time": { - "message": "切出时长" - }, - "app.skin-site.admin.review.hide": { - "message": "收起" - }, - "app.skin-site.admin.review.history": { - "message": "审核记录" - }, - "app.skin-site.admin.review.invite-not-sent": { - "message": "邮件未发送。" - }, - "app.skin-site.admin.review.invite-regenerated": { - "message": "邀请码已重新生成。" - }, - "app.skin-site.admin.review.invite-sent": { - "message": "邮件已发送。" - }, - "app.skin-site.admin.review.ip": { - "message": "IP" - }, - "app.skin-site.admin.review.link-copied": { - "message": "直链已复制。" - }, - "app.skin-site.admin.review.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.review.mail-enabled": { - "message": "审核通过后发送邮件" - }, - "app.skin-site.admin.review.mail-extra": { - "message": "邮件补充说明" - }, - "app.skin-site.admin.review.mail-include-invite": { - "message": "附带邀请码" - }, - "app.skin-site.admin.review.mail-message": { - "message": "邮件正文" - }, - "app.skin-site.admin.review.mail-message-required": { - "message": "开启邮件后必须填写邮件正文。" - }, - "app.skin-site.admin.review.mail-subject": { - "message": "邮件标题" - }, - "app.skin-site.admin.review.mail-subject-required": { - "message": "开启邮件后必须填写邮件标题。" - }, - "app.skin-site.admin.review.mail-title": { - "message": "通过邮件" - }, - "app.skin-site.admin.review.mode-auto": { - "message": "自动" - }, - "app.skin-site.admin.review.mode-manual": { - "message": "人工" - }, - "app.skin-site.admin.review.move-down": { - "message": "下移" - }, - "app.skin-site.admin.review.move-up": { - "message": "上移" - }, - "app.skin-site.admin.review.new-paper": { - "message": "新建试卷" - }, - "app.skin-site.admin.review.next": { - "message": "下一页" - }, - "app.skin-site.admin.review.no-answers": { - "message": "没有作答记录。" - }, - "app.skin-site.admin.review.option-correct": { - "message": "正确" - }, - "app.skin-site.admin.review.option-description": { - "message": "选项文本" - }, - "app.skin-site.admin.review.page": { - "message": "第 {page} 页" - }, - "app.skin-site.admin.review.paper-annotation": { - "message": "描述" - }, - "app.skin-site.admin.review.paper-created": { - "message": "试卷已创建。" - }, - "app.skin-site.admin.review.paper-enabled": { - "message": "启用" - }, - "app.skin-site.admin.review.paper-mode": { - "message": "阅卷模式" - }, - "app.skin-site.admin.review.paper-pass-score": { - "message": "通过分数" - }, - "app.skin-site.admin.review.paper-questions": { - "message": "题目" - }, - "app.skin-site.admin.review.paper-saved": { - "message": "试卷已保存。" - }, - "app.skin-site.admin.review.paper-target-permissions": { - "message": "通过后获得的身份" - }, - "app.skin-site.admin.review.paper-title": { - "message": "试卷标题" - }, - "app.skin-site.admin.review.papers-empty": { - "message": "还没有审核试卷。" - }, - "app.skin-site.admin.review.prev": { - "message": "上一页" - }, - "app.skin-site.admin.review.prevent-duplicate": { - "message": "禁止重复作答" - }, - "app.skin-site.admin.review.question-annotation": { - "message": "题目注解" - }, - "app.skin-site.admin.review.question-no": { - "message": "第 {n} 题" - }, - "app.skin-site.admin.review.question-score": { - "message": "分数" - }, - "app.skin-site.admin.review.question-title": { - "message": "题目" - }, - "app.skin-site.admin.review.question-type": { - "message": "题型" - }, - "app.skin-site.admin.review.reason": { - "message": "理由" - }, - "app.skin-site.admin.review.regen-invite": { - "message": "重发邀请码" - }, - "app.skin-site.admin.review.reject": { - "message": "拒绝" - }, - "app.skin-site.admin.review.reject-done": { - "message": "申请已拒绝。" - }, - "app.skin-site.admin.review.remove-question": { - "message": "删除" - }, - "app.skin-site.admin.review.result-passed": { - "message": "已通过" - }, - "app.skin-site.admin.review.result-pending": { - "message": "待处理" - }, - "app.skin-site.admin.review.result-rejected": { - "message": "已拒绝" - }, - "app.skin-site.admin.review.reviewer": { - "message": "审核人" - }, - "app.skin-site.admin.review.score": { - "message": "得分" - }, - "app.skin-site.admin.review.screen-switches": { - "message": "切屏次数" - }, - "app.skin-site.admin.review.submitted-at": { - "message": "提交时间" - }, - "app.skin-site.admin.review.tab-list": { - "message": "申请列表" - }, - "app.skin-site.admin.review.tab-papers": { - "message": "试卷管理" - }, - "app.skin-site.admin.review.title": { - "message": "玩家审核" - }, - "app.skin-site.admin.review.total": { - "message": "共 {count} 份申请" - }, - "app.skin-site.admin.review.user-agent": { - "message": "浏览器标识" - }, - "app.skin-site.admin.servers.add-map": { - "message": "添加地图" - }, - "app.skin-site.admin.servers.add-server": { - "message": "添加服务器" - }, - "app.skin-site.admin.servers.empty": { - "message": "尚未配置地图服务器。" - }, - "app.skin-site.admin.servers.failed": { - "message": "无法加载服务器列表。" - }, - "app.skin-site.admin.servers.internal": { - "message": "内部" - }, - "app.skin-site.admin.servers.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.servers.map-name": { - "message": "地图名称" - }, - "app.skin-site.admin.servers.map-url": { - "message": "地图地址" - }, - "app.skin-site.admin.servers.maps": { - "message": "地图" - }, - "app.skin-site.admin.servers.remove-map": { - "message": "移除" - }, - "app.skin-site.admin.servers.remove-server": { - "message": "删除服务器" - }, - "app.skin-site.admin.servers.save": { - "message": "保存更改" - }, - "app.skin-site.admin.servers.saved": { - "message": "地图服务器已保存。" - }, - "app.skin-site.admin.servers.saving": { - "message": "保存中…" - }, - "app.skin-site.admin.servers.server-name": { - "message": "服务器名称" - }, - "app.skin-site.admin.servers.title": { - "message": "地图服务器" - }, - "app.skin-site.admin.summary.failed": { - "message": "无法加载状态。" - }, - "app.skin-site.admin.summary.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.summary.memory": { - "message": "内存占用" - }, - "app.skin-site.admin.summary.players": { - "message": "玩家数量" - }, - "app.skin-site.admin.summary.realtime-hint": { - "message": "实时 CPU 与 GC 图表依赖管理端 WebSocket,目前尚未接入。" - }, - "app.skin-site.admin.summary.title": { - "message": "系统概况" - }, - "app.skin-site.admin.summary.uptime": { - "message": "运行时长" - }, - "app.skin-site.admin.summary.users": { - "message": "用户数量" - }, - "app.skin-site.admin.title": { - "message": "管理控制台" - }, - "app.skin-site.admin.users.actions": { - "message": "操作" - }, - "app.skin-site.admin.users.audit": { - "message": "审计" - }, - "app.skin-site.admin.users.audit-empty": { - "message": "暂无管理审计记录。" - }, - "app.skin-site.admin.users.audit-more": { - "message": "加载更早记录" - }, - "app.skin-site.admin.users.audit-title": { - "message": "用户管理审计" - }, - "app.skin-site.admin.users.banned": { - "message": "封禁" - }, - "app.skin-site.admin.users.bot": { - "message": "机器人" - }, - "app.skin-site.admin.users.bot-active": { - "message": "Token 有效" - }, - "app.skin-site.admin.users.bot-ban": { - "message": "封禁 Bot 创建" - }, - "app.skin-site.admin.users.bot-creation-banned": { - "message": "禁止创建 Token" - }, - "app.skin-site.admin.users.bot-exists": { - "message": "已创建 Bot" - }, - "app.skin-site.admin.users.bot-inactive": { - "message": "Token 已失效" - }, - "app.skin-site.admin.users.bot-invalidate": { - "message": "使 Token 失效" - }, - "app.skin-site.admin.users.bot-not-exists": { - "message": "尚未创建 Bot" - }, - "app.skin-site.admin.users.bot-save-username": { - "message": "保存机器人用户名" - }, - "app.skin-site.admin.users.bot-title": { - "message": "Bot 管理" - }, - "app.skin-site.admin.users.bot-token-hint": { - "message": "Token 标识" - }, - "app.skin-site.admin.users.bot-unban": { - "message": "解除 Bot 封禁" - }, - "app.skin-site.admin.users.bot-username": { - "message": "机器人用户名" - }, - "app.skin-site.admin.users.bound-players-title": { - "message": "绑定玩家" - }, - "app.skin-site.admin.users.cancel": { - "message": "取消" - }, - "app.skin-site.admin.users.confirm-delete": { - "message": "确定删除用户「{name}」吗?此操作不可撤销。" - }, - "app.skin-site.admin.users.deleted": { - "message": "用户已删除。" - }, - "app.skin-site.admin.users.edit": { - "message": "编辑" - }, - "app.skin-site.admin.users.email": { - "message": "邮箱" - }, - "app.skin-site.admin.users.empty": { - "message": "没有找到用户。" - }, - "app.skin-site.admin.users.failed": { - "message": "无法加载用户列表。" - }, - "app.skin-site.admin.users.frequency": { - "message": "频率限制" - }, - "app.skin-site.admin.users.frequency-clear": { - "message": "取消限制" - }, - "app.skin-site.admin.users.frequency-current": { - "message": "当前 {percent}%" - }, - "app.skin-site.admin.users.frequency-hint": { - "message": "以下列频率对指定用户进行丢包处理,限制其进入服务器的频率。" - }, - "app.skin-site.admin.users.frequency-none": { - "message": "当前未启用" - }, - "app.skin-site.admin.users.frequency-range": { - "message": "仅允许设置 10% 至 100% 的整数。" - }, - "app.skin-site.admin.users.frequency-save": { - "message": "保存限制" - }, - "app.skin-site.admin.users.frequency-title": { - "message": "频率限制" - }, - "app.skin-site.admin.users.invite": { - "message": "邀请用户" - }, - "app.skin-site.admin.users.invite-copied": { - "message": "邀请码已复制。" - }, - "app.skin-site.admin.users.invite-copy": { - "message": "复制" - }, - "app.skin-site.admin.users.invite-email": { - "message": "邮箱" - }, - "app.skin-site.admin.users.invite-email-invalid": { - "message": "请输入正确格式的邮箱。" - }, - "app.skin-site.admin.users.invite-generate": { - "message": "生成邀请码" - }, - "app.skin-site.admin.users.invite-title": { - "message": "邀请用户" - }, - "app.skin-site.admin.users.legacy-adapted": { - "message": "已适配旧内服" - }, - "app.skin-site.admin.users.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.users.next": { - "message": "下一页" - }, - "app.skin-site.admin.users.no-players": { - "message": "没有绑定的角色。" - }, - "app.skin-site.admin.users.page": { - "message": "第 {page} 页" - }, - "app.skin-site.admin.users.password": { - "message": "新密码" - }, - "app.skin-site.admin.users.password-hint": { - "message": "留空则保持原密码不变。" - }, - "app.skin-site.admin.users.permissions": { - "message": "权限" - }, - "app.skin-site.admin.users.permissions-hint": { - "message": "以逗号分隔,例如 WEB_ADMIN, SERVER_ADMIN。" - }, - "app.skin-site.admin.users.players": { - "message": "角色" - }, - "app.skin-site.admin.users.prev": { - "message": "上一页" - }, - "app.skin-site.admin.users.qq": { - "message": "QQ" - }, - "app.skin-site.admin.users.registered": { - "message": "注册时间" - }, - "app.skin-site.admin.users.registered-at": { - "message": "注册时间" - }, - "app.skin-site.admin.users.remove": { - "message": "删除" - }, - "app.skin-site.admin.users.save": { - "message": "保存" - }, - "app.skin-site.admin.users.search": { - "message": "搜索" - }, - "app.skin-site.admin.users.search-email": { - "message": "邮箱" - }, - "app.skin-site.admin.users.search-name": { - "message": "用户名" - }, - "app.skin-site.admin.users.search-uuid": { - "message": "UUID" - }, - "app.skin-site.admin.users.status": { - "message": "状态" - }, - "app.skin-site.admin.users.status-banned": { - "message": "已封禁" - }, - "app.skin-site.admin.users.status-normal": { - "message": "正常" - }, - "app.skin-site.admin.users.title": { - "message": "用户" - }, - "app.skin-site.admin.users.total": { - "message": "共 {count} 名用户" - }, - "app.skin-site.admin.users.updated": { - "message": "用户已更新。" - }, - "app.skin-site.admin.users.username": { - "message": "用户名" - }, - "app.skin-site.admin.wiki.allow-private": { - "message": "明确允许访问内网来源" - }, - "app.skin-site.admin.wiki.allow-private-hint": { - "message": "内网来源可能访问皮肤站所在网络中的服务,请只对可信地址启用。" - }, - "app.skin-site.admin.wiki.api-url": { - "message": "api.php 地址" - }, - "app.skin-site.admin.wiki.audit-empty": { - "message": "没有审计记录。" - }, - "app.skin-site.admin.wiki.audit-target": { - "message": "目标" - }, - "app.skin-site.admin.wiki.author": { - "message": "作者" - }, - "app.skin-site.admin.wiki.auto-title": { - "message": "从 MediaWiki API 自动读取" - }, - "app.skin-site.admin.wiki.bot-password": { - "message": "Bot 密码(选填)" - }, - "app.skin-site.admin.wiki.bot-username": { - "message": "Bot 用户名(选填)" - }, - "app.skin-site.admin.wiki.candidates": { - "message": "候选页面" - }, - "app.skin-site.admin.wiki.candidates-empty": { - "message": "选择任务后查看其页面。" - }, - "app.skin-site.admin.wiki.categories": { - "message": "分类" - }, - "app.skin-site.admin.wiki.confirm-delete-job": { - "message": "确认删除迁移任务 #{id}?此操作不可恢复。" - }, - "app.skin-site.admin.wiki.confirm-rollback": { - "message": "确认回滚本批迁移?已发布的页面将被还原。" - }, - "app.skin-site.admin.wiki.conflict": { - "message": "标题冲突" - }, - "app.skin-site.admin.wiki.credentials-hint": { - "message": "凭据只存在于本次后台任务的内存中,携带凭据时必须使用 HTTPS。" - }, - "app.skin-site.admin.wiki.decision-exclude": { - "message": "排除" - }, - "app.skin-site.admin.wiki.decision-import": { - "message": "导入" - }, - "app.skin-site.admin.wiki.decision-pending": { - "message": "待审核" - }, - "app.skin-site.admin.wiki.default-skin": { - "message": "默认皮肤" - }, - "app.skin-site.admin.wiki.delete-job": { - "message": "删除迁移记录" - }, - "app.skin-site.admin.wiki.deleted-updated": { - "message": "页面删除状态已更新。" - }, - "app.skin-site.admin.wiki.domains": { - "message": "域名" - }, - "app.skin-site.admin.wiki.edit-policy": { - "message": "编辑权限" - }, - "app.skin-site.admin.wiki.exclude": { - "message": "排除" - }, - "app.skin-site.admin.wiki.home-page": { - "message": "首页" - }, - "app.skin-site.admin.wiki.home-set": { - "message": "首页已更新。" - }, - "app.skin-site.admin.wiki.import": { - "message": "导入" - }, - "app.skin-site.admin.wiki.imported-excluded": { - "message": "导入 {imported} · 排除 {excluded}" - }, - "app.skin-site.admin.wiki.job-deleted": { - "message": "迁移记录已删除。" - }, - "app.skin-site.admin.wiki.jobs": { - "message": "迁移任务" - }, - "app.skin-site.admin.wiki.jobs-empty": { - "message": "还没有迁移任务。" - }, - "app.skin-site.admin.wiki.last-updated": { - "message": "更新于 {date}" - }, - "app.skin-site.admin.wiki.load-more": { - "message": "加载更多" - }, - "app.skin-site.admin.wiki.load-page": { - "message": "加载页面" - }, - "app.skin-site.admin.wiki.loading": { - "message": "加载中…" - }, - "app.skin-site.admin.wiki.maintainer-count": { - "message": "{count} 位维护者" - }, - "app.skin-site.admin.wiki.maintainer-window": { - "message": "维护者统计天数" - }, - "app.skin-site.admin.wiki.max-attachment-bytes": { - "message": "附件最大字节数" - }, - "app.skin-site.admin.wiki.max-maintainers": { - "message": "维护者人数不超过" - }, - "app.skin-site.admin.wiki.max-page-bytes": { - "message": "页面最大字节数" - }, - "app.skin-site.admin.wiki.migration-hint": { - "message": "迁移内容会先进入不可见暂存区,所有页面完成导入或排除审核后才能整批发布。" - }, - "app.skin-site.admin.wiki.migration-started": { - "message": "迁移任务已创建。" - }, - "app.skin-site.admin.wiki.migration-title": { - "message": "MediaWiki 迁移" - }, - "app.skin-site.admin.wiki.overwrite": { - "message": "覆盖" - }, - "app.skin-site.admin.wiki.page-not-found": { - "message": "未找到该页面。" - }, - "app.skin-site.admin.wiki.page-path": { - "message": "页面路径" - }, - "app.skin-site.admin.wiki.policy-admin": { - "message": "网站管理员" - }, - "app.skin-site.admin.wiki.policy-member": { - "message": "已登录成员" - }, - "app.skin-site.admin.wiki.policy-public": { - "message": "所有人" - }, - "app.skin-site.admin.wiki.protect-saved": { - "message": "页面权限已更新。" - }, - "app.skin-site.admin.wiki.publish": { - "message": "整批发布" - }, - "app.skin-site.admin.wiki.published": { - "message": "已发布 {imported} 个页面,覆盖 {overwritten} 个。" - }, - "app.skin-site.admin.wiki.read-policy": { - "message": "阅读权限" - }, - "app.skin-site.admin.wiki.refresh-jobs": { - "message": "刷新" - }, - "app.skin-site.admin.wiki.reviewed-count": { - "message": "已审核 {reviewed} / {total}" - }, - "app.skin-site.admin.wiki.revision": { - "message": "版本" - }, - "app.skin-site.admin.wiki.rollback": { - "message": "回滚" - }, - "app.skin-site.admin.wiki.rolled-back": { - "message": "迁移批次已安全回滚。" - }, - "app.skin-site.admin.wiki.save-protect": { - "message": "保存权限" - }, - "app.skin-site.admin.wiki.save-settings": { - "message": "保存设置" - }, - "app.skin-site.admin.wiki.select-xml": { - "message": "请先选择 MediaWiki XML 文件。" - }, - "app.skin-site.admin.wiki.set-deleted": { - "message": "标记为已删除" - }, - "app.skin-site.admin.wiki.set-home": { - "message": "设为首页" - }, - "app.skin-site.admin.wiki.set-restored": { - "message": "恢复页面" - }, - "app.skin-site.admin.wiki.settings-hint": { - "message": "以逗号分隔域名。" - }, - "app.skin-site.admin.wiki.settings-saved": { - "message": "设置已保存。" - }, - "app.skin-site.admin.wiki.stale-days": { - "message": "未更新天数" - }, - "app.skin-site.admin.wiki.stale-markers": { - "message": "过时分类、模板或文字标记" - }, - "app.skin-site.admin.wiki.stale-markers-hint": { - "message": "使用逗号分隔" - }, - "app.skin-site.admin.wiki.stale-rules": { - "message": "疑似过时页面筛选规则" - }, - "app.skin-site.admin.wiki.start-auto": { - "message": "创建自动迁移任务" - }, - "app.skin-site.admin.wiki.start-xml": { - "message": "上传并建立暂存任务" - }, - "app.skin-site.admin.wiki.state-failed": { - "message": "失败" - }, - "app.skin-site.admin.wiki.state-importing": { - "message": "正在读取" - }, - "app.skin-site.admin.wiki.state-published": { - "message": "已发布" - }, - "app.skin-site.admin.wiki.state-publishing": { - "message": "正在发布" - }, - "app.skin-site.admin.wiki.state-review": { - "message": "等待审核" - }, - "app.skin-site.admin.wiki.state-rolled-back": { - "message": "已回滚" - }, - "app.skin-site.admin.wiki.tab-audit": { - "message": "审计日志" - }, - "app.skin-site.admin.wiki.tab-migration": { - "message": "迁移中心" - }, - "app.skin-site.admin.wiki.tab-page": { - "message": "页面" - }, - "app.skin-site.admin.wiki.tab-settings": { - "message": "设置" - }, - "app.skin-site.admin.wiki.target-title": { - "message": "目标标题" - }, - "app.skin-site.admin.wiki.title": { - "message": "维基管理" - }, - "app.skin-site.admin.wiki.updated-at": { - "message": "更新时间" - }, - "app.skin-site.admin.wiki.view-job": { - "message": "查看任务" - }, - "app.skin-site.admin.wiki.xml-file": { - "message": "导出文件" - }, - "app.skin-site.admin.wiki.xml-staged": { - "message": "XML 已解析并进入逐页审核阶段。" - }, - "app.skin-site.admin.wiki.xml-title": { - "message": "导入 MediaWiki XML" - }, - "app.skin-site.bug-create.cancel": { - "message": "取消" - }, - "app.skin-site.bug-create.created": { - "message": "问题已创建。" - }, - "app.skin-site.bug-create.description": { - "message": "描述" - }, - "app.skin-site.bug-create.description-placeholder": { - "message": "发生了什么?如何复现?" - }, - "app.skin-site.bug-create.images": { - "message": "图片" - }, - "app.skin-site.bug-create.images-hint": { - "message": "可选,最多 5 张图片。" - }, - "app.skin-site.bug-create.private": { - "message": "私密问题" - }, - "app.skin-site.bug-create.private-hint": { - "message": "仅你和维护者可见。" - }, - "app.skin-site.bug-create.submit": { - "message": "创建问题" - }, - "app.skin-site.bug-create.submitting": { - "message": "创建中…" - }, - "app.skin-site.bug-create.title": { - "message": "新建问题" - }, - "app.skin-site.bug-create.title-field": { - "message": "标题" - }, - "app.skin-site.bug-create.title-placeholder": { - "message": "简要描述问题" - }, - "app.skin-site.bug-create.type": { - "message": "类型" - }, - "app.skin-site.bug-detail.assignee": { - "message": "负责人:{name}" - }, - "app.skin-site.bug-detail.back": { - "message": "返回列表" - }, - "app.skin-site.bug-detail.by": { - "message": "由 {name} 提交" - }, - "app.skin-site.bug-detail.comment-deleted": { - "message": "评论已删除。" - }, - "app.skin-site.bug-detail.comment-empty-error": { - "message": "评论内容不能为空。" - }, - "app.skin-site.bug-detail.comment-placeholder": { - "message": "写下你的评论…" - }, - "app.skin-site.bug-detail.comment-posted": { - "message": "评论已发表。" - }, - "app.skin-site.bug-detail.comment-sending": { - "message": "发送中…" - }, - "app.skin-site.bug-detail.comment-submit": { - "message": "发表评论" - }, - "app.skin-site.bug-detail.comments-empty": { - "message": "还没有评论,来抢沙发吧。" - }, - "app.skin-site.bug-detail.comments-loading": { - "message": "加载评论中…" - }, - "app.skin-site.bug-detail.comments-title": { - "message": "评论" - }, - "app.skin-site.bug-detail.delete": { - "message": "删除" - }, - "app.skin-site.bug-detail.deleting": { - "message": "删除中…" - }, - "app.skin-site.bug-detail.description-empty": { - "message": "未提供描述。" - }, - "app.skin-site.bug-detail.failed": { - "message": "无法加载该问题。" - }, - "app.skin-site.bug-detail.issue-no": { - "message": "问题 #{id}" - }, - "app.skin-site.bug-detail.loading": { - "message": "加载中…" - }, - "app.skin-site.bug-detail.resolution": { - "message": "处理结果:{name}" - }, - "app.skin-site.bug-detail.system": { - "message": "系统" - }, - "app.skin-site.bug-detail.unassigned": { - "message": "未分配" - }, - "app.skin-site.bug-notifications.back": { - "message": "返回主页" - }, - "app.skin-site.bug-notifications.empty": { - "message": "暂无新通知。" - }, - "app.skin-site.bug-notifications.failed": { - "message": "无法加载通知。" - }, - "app.skin-site.bug-notifications.item": { - "message": "{name} 更新了问题 #{id}" - }, - "app.skin-site.bug-notifications.loading": { - "message": "加载中…" - }, - "app.skin-site.bug-notifications.mark-all": { - "message": "全部标为已读" - }, - "app.skin-site.bug-notifications.marked-all": { - "message": "已将全部通知标为已读。" - }, - "app.skin-site.bug-notifications.subtitle": { - "message": "你提交或关注的问题动态。" - }, - "app.skin-site.bug-notifications.title": { - "message": "通知" - }, - "app.skin-site.bugs.all": { - "message": "全部" - }, - "app.skin-site.bugs.back": { - "message": "返回主页" - }, - "app.skin-site.bugs.comments": { - "message": "{count} 条评论" - }, - "app.skin-site.bugs.create": { - "message": "新建问题" - }, - "app.skin-site.bugs.empty": { - "message": "没有符合筛选条件的问题。" - }, - "app.skin-site.bugs.failed": { - "message": "无法加载问题列表。" - }, - "app.skin-site.bugs.loading": { - "message": "加载中…" - }, - "app.skin-site.bugs.more": { - "message": "加载更多" - }, - "app.skin-site.bugs.notifications": { - "message": "通知" - }, - "app.skin-site.bugs.open-only": { - "message": "仅显示未关闭" - }, - "app.skin-site.bugs.priority.critical": { - "message": "紧急" - }, - "app.skin-site.bugs.priority.high": { - "message": "高" - }, - "app.skin-site.bugs.priority.low": { - "message": "低" - }, - "app.skin-site.bugs.priority.normal": { - "message": "普通" - }, - "app.skin-site.bugs.resolution.by-design": { - "message": "设计如此" - }, - "app.skin-site.bugs.resolution.cannot-reproduce": { - "message": "无法复现" - }, - "app.skin-site.bugs.resolution.duplicate": { - "message": "重复问题" - }, - "app.skin-site.bugs.resolution.fixed": { - "message": "已修复" - }, - "app.skin-site.bugs.resolution.invalid": { - "message": "无效" - }, - "app.skin-site.bugs.resolution.wont-fix": { - "message": "不予修复" - }, - "app.skin-site.bugs.status.closed": { - "message": "已关闭" - }, - "app.skin-site.bugs.status.confirmed": { - "message": "已确认" - }, - "app.skin-site.bugs.status.in-progress": { - "message": "处理中" - }, - "app.skin-site.bugs.status.needs-info": { - "message": "待补充信息" - }, - "app.skin-site.bugs.status.pending": { - "message": "待处理" - }, - "app.skin-site.bugs.status.verifying": { - "message": "验证中" - }, - "app.skin-site.bugs.subtitle": { - "message": "反馈问题并跟踪处理进度。" - }, - "app.skin-site.bugs.title": { - "message": "问题与建议" - }, - "app.skin-site.bugs.type.bug": { - "message": "缺陷" - }, - "app.skin-site.bugs.type.feature": { - "message": "功能建议" - }, - "app.skin-site.bugs.type.improvement": { - "message": "改进" - }, - "app.skin-site.captcha.loading": { - "message": "正在加载验证码…" - }, - "app.skin-site.captcha.submit": { - "message": "验证" - }, - "app.skin-site.captcha.subtitle": { - "message": "拖动滑块,将图片旋转至正向。" - }, - "app.skin-site.captcha.title": { - "message": "请完成人机验证" - }, - "app.skin-site.chat.admin.audit": { - "message": "审计" - }, - "app.skin-site.chat.admin.audit-empty": { - "message": "暂无审计记录。" - }, - "app.skin-site.chat.admin.audit-target": { - "message": "对象:{name}" - }, - "app.skin-site.chat.admin.audit-title": { - "message": "房间审计" - }, - "app.skin-site.chat.admin.cancel": { - "message": "取消" - }, - "app.skin-site.chat.admin.close": { - "message": "关闭" - }, - "app.skin-site.chat.admin.confirm-delete": { - "message": "确认永久删除房间“{name}”及其中全部消息吗?" - }, - "app.skin-site.chat.admin.create-room": { - "message": "创建房间" - }, - "app.skin-site.chat.admin.created": { - "message": "房间已创建。" - }, - "app.skin-site.chat.admin.deleted": { - "message": "房间已删除。" - }, - "app.skin-site.chat.admin.description": { - "message": "房间简介" - }, - "app.skin-site.chat.admin.edit": { - "message": "编辑" - }, - "app.skin-site.chat.admin.empty": { - "message": "还没有聊天室。" - }, - "app.skin-site.chat.admin.failed": { - "message": "无法加载房间列表。" - }, - "app.skin-site.chat.admin.grant": { - "message": "任命" - }, - "app.skin-site.chat.admin.kind": { - "message": "房间类型" - }, - "app.skin-site.chat.admin.kind-settlement": { - "message": "聚落房间" - }, - "app.skin-site.chat.admin.kind-standard": { - "message": "普通房间" - }, - "app.skin-site.chat.admin.listener-limit": { - "message": "旁听人数上限" - }, - "app.skin-site.chat.admin.loading": { - "message": "加载中…" - }, - "app.skin-site.chat.admin.manager-badge": { - "message": "管理" - }, - "app.skin-site.chat.admin.manager-granted": { - "message": "已任命房管。" - }, - "app.skin-site.chat.admin.manager-hint": { - "message": "房管可以管理该房间的成员、消息与文件。" - }, - "app.skin-site.chat.admin.manager-revoked": { - "message": "已撤销房管。" - }, - "app.skin-site.chat.admin.manager-title": { - "message": "任命房管" - }, - "app.skin-site.chat.admin.managers": { - "message": "房管" - }, - "app.skin-site.chat.admin.name": { - "message": "房间名称" - }, - "app.skin-site.chat.admin.owner-assigned": { - "message": "已任命聚落主。" - }, - "app.skin-site.chat.admin.owner-current": { - "message": "当前聚落主:{name}" - }, - "app.skin-site.chat.admin.owner-hint": { - "message": "为该房间任命首任聚落主。" - }, - "app.skin-site.chat.admin.owner-none": { - "message": "尚未设置聚落主。" - }, - "app.skin-site.chat.admin.owner-title": { - "message": "聚落主" - }, - "app.skin-site.chat.admin.participant-limit": { - "message": "参与人数上限" - }, - "app.skin-site.chat.admin.prerequisite-all": { - "message": "满足全部" - }, - "app.skin-site.chat.admin.prerequisite-any": { - "message": "满足任一" - }, - "app.skin-site.chat.admin.prerequisite-hint": { - "message": "以逗号分隔;留空表示无限制。" - }, - "app.skin-site.chat.admin.prerequisite-mode": { - "message": "前置条件判定" - }, - "app.skin-site.chat.admin.prerequisite-permissions": { - "message": "所需权限" - }, - "app.skin-site.chat.admin.remove": { - "message": "删除" - }, - "app.skin-site.chat.admin.revoke": { - "message": "撤销" - }, - "app.skin-site.chat.admin.save": { - "message": "保存" - }, - "app.skin-site.chat.admin.subtitle": { - "message": "创建公开或私有房间,并将日常管理权限交给合适的成员。" - }, - "app.skin-site.chat.admin.title": { - "message": "聊天室管理" - }, - "app.skin-site.chat.admin.updated": { - "message": "房间资料已更新。" - }, - "app.skin-site.chat.admin.visibility": { - "message": "可见性" - }, - "app.skin-site.chat.admin.visibility-private": { - "message": "私有" - }, - "app.skin-site.chat.admin.visibility-public": { - "message": "公开" - }, - "app.skin-site.chat.admin.voice-badge": { - "message": "语音" - }, - "app.skin-site.chat.admin.voice-bind": { - "message": "监听地址" - }, - "app.skin-site.chat.admin.voice-capacity": { - "message": "语音容量" - }, - "app.skin-site.chat.admin.voice-capacity-title": { - "message": "语音容量" - }, - "app.skin-site.chat.admin.voice-capacity-updated": { - "message": "语音容量已更新。" - }, - "app.skin-site.chat.admin.voice-config": { - "message": "配置语音库" - }, - "app.skin-site.chat.admin.voice-config-title": { - "message": "语音库配置" - }, - "app.skin-site.chat.admin.voice-enabled": { - "message": "启用实时语音" - }, - "app.skin-site.chat.admin.voice-logs": { - "message": "查看日志" - }, - "app.skin-site.chat.admin.voice-logs-auto-refresh": { - "message": "自动刷新" - }, - "app.skin-site.chat.admin.voice-logs-empty": { - "message": "暂无日志。" - }, - "app.skin-site.chat.admin.voice-logs-refresh": { - "message": "刷新" - }, - "app.skin-site.chat.admin.voice-logs-title": { - "message": "LiveKit 日志" - }, - "app.skin-site.chat.admin.voice-mirror": { - "message": "镜像基础地址" - }, - "app.skin-site.chat.admin.voice-node-ip": { - "message": "节点 IP" - }, - "app.skin-site.chat.admin.voice-public-url": { - "message": "公网访问地址" - }, - "app.skin-site.chat.admin.voice-retry": { - "message": "重新部署" - }, - "app.skin-site.chat.admin.voice-rtc-tcp-port": { - "message": "媒体 TCP 端口" - }, - "app.skin-site.chat.admin.voice-rtc-udp-port": { - "message": "媒体 UDP 端口" - }, - "app.skin-site.chat.admin.voice-runtime-path": { - "message": "语音库目录" - }, - "app.skin-site.chat.admin.voice-runtime-title": { - "message": "实时语音库" - }, - "app.skin-site.chat.admin.voice-saved": { - "message": "语音库配置已保存。" - }, - "app.skin-site.chat.admin.voice-signal-port": { - "message": "信令端口" - }, - "app.skin-site.chat.admin.voice-startup-timeout": { - "message": "启动等待时间(秒)" - }, - "app.skin-site.chat.admin.voice-use-external-ip": { - "message": "使用外部 IP" - }, - "app.skin-site.chat.avatar.bad-format": { - "message": "房间头像仅支持 PNG、JPEG 和 WebP 格式。" - }, - "app.skin-site.chat.avatar.hint": { - "message": "支持 PNG、JPEG、WebP,单边不超过 8192 像素,文件不超过 5 MB。" - }, - "app.skin-site.chat.avatar.label": { - "message": "房间头像" - }, - "app.skin-site.chat.avatar.not-image": { - "message": "房间头像必须是图片。" - }, - "app.skin-site.chat.avatar.remove": { - "message": "移除头像" - }, - "app.skin-site.chat.avatar.replace": { - "message": "更换头像" - }, - "app.skin-site.chat.avatar.too-large": { - "message": "房间头像大小不能超过 5 MB。" - }, - "app.skin-site.chat.avatar.upload": { - "message": "上传头像" - }, - "app.skin-site.chat.listener-limit": { - "message": "旁听人数上限" - }, - "app.skin-site.chat.participant-limit": { - "message": "参与人数上限" - }, - "app.skin-site.chat.user-picker.active-status": { - "message": "正常" - }, - "app.skin-site.chat.user-picker.already-in": { - "message": "该用户已经在当前房间中。" - }, - "app.skin-site.chat.user-picker.banned": { - "message": "该账号已被封禁,不能执行此操作。" - }, - "app.skin-site.chat.user-picker.banned-status": { - "message": "已封禁" - }, - "app.skin-site.chat.user-picker.by-player": { - "message": "按玩家 ID" - }, - "app.skin-site.chat.user-picker.by-user": { - "message": "按用户信息" - }, - "app.skin-site.chat.user-picker.email": { - "message": "邮箱" - }, - "app.skin-site.chat.user-picker.empty": { - "message": "没有找到匹配的用户" - }, - "app.skin-site.chat.user-picker.guest": { - "message": "游客不能成为房管、聚落主或聚落成员。" - }, - "app.skin-site.chat.user-picker.hint": { - "message": "支持按用户名、邮箱模糊搜索,也可输入账号 ID 搜索。" - }, - "app.skin-site.chat.user-picker.id": { - "message": "ID" - }, - "app.skin-site.chat.user-picker.label": { - "message": "选择用户" - }, - "app.skin-site.chat.user-picker.not-allowed": { - "message": "该用户不在当前允许选择的范围内" - }, - "app.skin-site.chat.user-picker.placeholder": { - "message": "搜索用户名、邮箱或账号 ID" - }, - "app.skin-site.chat.user-picker.player-hint": { - "message": "输入玩家名称,查找绑定该玩家 ID 的用户。" - }, - "app.skin-site.chat.user-picker.registered": { - "message": "注册时间" - }, - "app.skin-site.chat.user-picker.select": { - "message": "选择此用户" - }, - "app.skin-site.chat.user-picker.selected": { - "message": "已选择此用户" - }, - "app.skin-site.chat.voice-bind": { - "message": "监听地址" - }, - "app.skin-site.chat.voice-capacity": { - "message": "语音容量" - }, - "app.skin-site.chat.voice-capacity-title": { - "message": "语音容量" - }, - "app.skin-site.chat.voice-capacity-updated": { - "message": "语音容量已更新。" - }, - "app.skin-site.chat.voice-config": { - "message": "配置语音库" - }, - "app.skin-site.chat.voice-config-title": { - "message": "语音库配置" - }, - "app.skin-site.chat.voice-enabled": { - "message": "启用实时语音" - }, - "app.skin-site.chat.voice-logs": { - "message": "查看日志" - }, - "app.skin-site.chat.voice-logs-auto-refresh": { - "message": "自动刷新" - }, - "app.skin-site.chat.voice-logs-empty": { - "message": "暂无日志。" - }, - "app.skin-site.chat.voice-logs-refresh": { - "message": "刷新" - }, - "app.skin-site.chat.voice-logs-title": { - "message": "LiveKit 日志" - }, - "app.skin-site.chat.voice-mirror": { - "message": "镜像基础地址" - }, - "app.skin-site.chat.voice-node-ip": { - "message": "节点 IP" - }, - "app.skin-site.chat.voice-public-url": { - "message": "公网访问地址" - }, - "app.skin-site.chat.voice-retry": { - "message": "重新部署" - }, - "app.skin-site.chat.voice-rtc-tcp-port": { - "message": "媒体 TCP 端口" - }, - "app.skin-site.chat.voice-rtc-udp-port": { - "message": "媒体 UDP 端口" - }, - "app.skin-site.chat.voice-runtime-path": { - "message": "语音库目录" - }, - "app.skin-site.chat.voice-runtime-title": { - "message": "实时语音库" - }, - "app.skin-site.chat.voice-saved": { - "message": "语音库配置已保存。" - }, - "app.skin-site.chat.voice-signal-port": { - "message": "信令端口" - }, - "app.skin-site.chat.voice-startup-timeout": { - "message": "启动等待时间(秒)" - }, - "app.skin-site.chat.voice-use-external-ip": { - "message": "使用外部 IP" - }, - "app.skin-site.downloads.all": { - "message": "全部" - }, - "app.skin-site.downloads.back": { - "message": "返回主页" - }, - "app.skin-site.downloads.empty": { - "message": "暂无可下载的资源。" - }, - "app.skin-site.downloads.failed": { - "message": "加载下载资源失败。" - }, - "app.skin-site.downloads.go": { - "message": "下载" - }, - "app.skin-site.downloads.loading": { - "message": "正在加载…" - }, - "app.skin-site.downloads.status.legacy": { - "message": "旧版" - }, - "app.skin-site.downloads.status.new": { - "message": "新增" - }, - "app.skin-site.downloads.status.ok": { - "message": "可用" - }, - "app.skin-site.downloads.status.outdated": { - "message": "已过时" - }, - "app.skin-site.downloads.status.removal": { - "message": "待移除" - }, - "app.skin-site.downloads.subtitle": { - "message": "服务器分享的文件,可选择分类筛选。" - }, - "app.skin-site.downloads.title": { - "message": "资源下载" - }, - "app.skin-site.downloads.uploader": { - "message": "上传者:{name}" - }, - "app.skin-site.home.address": { - "message": "皮肤站地址" - }, - "app.skin-site.home.admin": { - "message": "管理" - }, - "app.skin-site.home.announcements.empty": { - "message": "暂无公告。" - }, - "app.skin-site.home.announcements.failed": { - "message": "加载公告失败。" - }, - "app.skin-site.home.announcements.loading": { - "message": "正在加载…" - }, - "app.skin-site.home.announcements.signed-out": { - "message": "登录后查看公告。" - }, - "app.skin-site.home.announcements.title": { - "message": "公告" - }, - "app.skin-site.home.copied": { - "message": "地址已复制。" - }, - "app.skin-site.home.copy": { - "message": "复制" - }, - "app.skin-site.home.donation.donors": { - "message": "{count} 位捐赠者" - }, - "app.skin-site.home.donation.loading": { - "message": "正在加载…" - }, - "app.skin-site.home.donation.title": { - "message": "鸣谢捐赠" - }, - "app.skin-site.home.donation.total": { - "message": "累计捐赠" - }, - "app.skin-site.home.donation.unavailable": { - "message": "暂时无法获取捐赠统计。" - }, - "app.skin-site.home.error": { - "message": "加载失败。" - }, - "app.skin-site.home.loading": { - "message": "加载中…" - }, - "app.skin-site.home.luck": { - "message": "幸运值" - }, - "app.skin-site.home.luck-unavailable": { - "message": "不可用" - }, - "app.skin-site.home.my-players": { - "message": "我的角色" - }, - "app.skin-site.home.nav.bugs": { - "message": "问题追踪" - }, - "app.skin-site.home.nav.bugs-desc": { - "message": "反馈问题并跟踪处理进度。" - }, - "app.skin-site.home.nav.download": { - "message": "资源下载" - }, - "app.skin-site.home.nav.download-desc": { - "message": "浏览服务器分享的文件。" - }, - "app.skin-site.home.nav.map": { - "message": "服务器地图" - }, - "app.skin-site.home.nav.map-desc": { - "message": "探索实时世界地图。" - }, - "app.skin-site.home.nav.profile": { - "message": "个人资料" - }, - "app.skin-site.home.nav.profile-desc": { - "message": "管理你的账号与皮肤。" - }, - "app.skin-site.home.nav.review": { - "message": "玩家审核" - }, - "app.skin-site.home.nav.review-desc": { - "message": "提交并审核玩家申请。" - }, - "app.skin-site.home.nav.title": { - "message": "皮肤站" - }, - "app.skin-site.home.nav.wiki": { - "message": "服务器维基" - }, - "app.skin-site.home.nav.wiki-desc": { - "message": "服务器的指南与文档。" - }, - "app.skin-site.home.no-players": { - "message": "尚未绑定角色。" - }, - "app.skin-site.home.players": { - "message": "角色" - }, - "app.skin-site.home.settings": { - "message": "账号" - }, - "app.skin-site.home.sign-in": { - "message": "登录" - }, - "app.skin-site.home.signed-out-body": { - "message": "登录后可管理你的账号与皮肤。" - }, - "app.skin-site.home.signed-out-title": { - "message": "未登录" - }, - "app.skin-site.home.subtitle": { - "message": "星光服务器玩家的衣柜。" - }, - "app.skin-site.home.title": { - "message": "星光皮肤站" - }, - "app.skin-site.login.forgot": { - "message": "忘记密码?" - }, - "app.skin-site.login.password": { - "message": "密码" - }, - "app.skin-site.login.password-hint": { - "message": "6~50 个字符,须包含大写字母、小写字母和数字。" - }, - "app.skin-site.login.register": { - "message": "注册账号" - }, - "app.skin-site.login.sign-in": { - "message": "登录" - }, - "app.skin-site.login.signing-in": { - "message": "正在登录…" - }, - "app.skin-site.login.success": { - "message": "已登录 StarLight。" - }, - "app.skin-site.login.title": { - "message": "登录 StarLight" - }, - "app.skin-site.login.username": { - "message": "用户名或邮箱" - }, - "app.skin-site.login.username-hint": { - "message": "3~16 个字符,或已注册的邮箱地址。" - }, - "app.skin-site.map.back": { - "message": "返回主页" - }, - "app.skin-site.map.empty": { - "message": "暂无可用地图。" - }, - "app.skin-site.map.external": { - "message": "外部地图" - }, - "app.skin-site.map.failed": { - "message": "加载地图失败。" - }, - "app.skin-site.map.internal": { - "message": "内部地图" - }, - "app.skin-site.map.loading": { - "message": "正在加载地图…" - }, - "app.skin-site.map.map": { - "message": "地图" - }, - "app.skin-site.map.open": { - "message": "在浏览器中打开" - }, - "app.skin-site.map.server": { - "message": "服务器" - }, - "app.skin-site.map.title": { - "message": "服务器地图" - }, - "app.skin-site.profile-view.back": { - "message": "返回主页" - }, - "app.skin-site.profile-view.cape": { - "message": "披风" - }, - "app.skin-site.profile-view.elytra": { - "message": "鞘翅" - }, - "app.skin-site.profile-view.loading": { - "message": "正在加载角色…" - }, - "app.skin-site.profile-view.no-players": { - "message": "暂无角色。" - }, - "app.skin-site.profile-view.readonly": { - "message": "Mojang 账号由 Mojang 管理,无法在此修改材质。" - }, - "app.skin-site.profile-view.remove": { - "message": "移除" - }, - "app.skin-site.profile-view.removed": { - "message": "材质已移除。" - }, - "app.skin-site.profile-view.select-hint": { - "message": "选择角色以预览和修改其材质。" - }, - "app.skin-site.profile-view.signed-out": { - "message": "登录后管理你的角色。" - }, - "app.skin-site.profile-view.skin": { - "message": "皮肤" - }, - "app.skin-site.profile-view.title": { - "message": "我的角色" - }, - "app.skin-site.profile-view.upload": { - "message": "上传" - }, - "app.skin-site.profile-view.uploaded": { - "message": "材质已更新。" - }, - "app.skin-site.profile.avatar": { - "message": "头像" - }, - "app.skin-site.profile.avatar-hint": { - "message": "建议使用正方形图片,系统会将中心区域裁剪为 256×256。" - }, - "app.skin-site.profile.avatar-uploaded": { - "message": "头像已更新。" - }, - "app.skin-site.profile.basic": { - "message": "个人资料" - }, - "app.skin-site.profile.choose-avatar": { - "message": "选择图片" - }, - "app.skin-site.profile.minecraft-password": { - "message": "Minecraft 密码" - }, - "app.skin-site.profile.minecraft-password-changed": { - "message": "Minecraft 密码已更新。" - }, - "app.skin-site.profile.minecraft-password-hint": { - "message": "用于启动器登录,默认与网站密码相同。" - }, - "app.skin-site.profile.mismatch": { - "message": "两次输入的密码不一致。" - }, - "app.skin-site.profile.new-password": { - "message": "新密码" - }, - "app.skin-site.profile.old-password": { - "message": "当前密码" - }, - "app.skin-site.profile.password-changed": { - "message": "密码已更新。" - }, - "app.skin-site.profile.password-hint": { - "message": "6~50 个字符,须包含大写字母、小写字母和数字。" - }, - "app.skin-site.profile.repeat-password": { - "message": "再次输入新密码" - }, - "app.skin-site.profile.reset-default": { - "message": "重置为网站密码" - }, - "app.skin-site.profile.save": { - "message": "保存" - }, - "app.skin-site.profile.saved": { - "message": "已保存。" - }, - "app.skin-site.profile.security": { - "message": "安全设置" - }, - "app.skin-site.profile.site-password-hint": { - "message": "用于登录皮肤站的密码。" - }, - "app.skin-site.profile.submit-password": { - "message": "修改密码" - }, - "app.skin-site.profile.title": { - "message": "账号设置" - }, - "app.skin-site.profile.username": { - "message": "用户名" - }, - "app.skin-site.profile.username-hint": { - "message": "3~16 个字符。" - }, - "app.skin-site.register.closed": { - "message": "当前服务器暂未开放注册。" - }, - "app.skin-site.register.code": { - "message": "验证码" - }, - "app.skin-site.register.email": { - "message": "邮箱" - }, - "app.skin-site.register.invite-code": { - "message": "邀请码" - }, - "app.skin-site.register.invite-required": { - "message": "此服务器需要邀请码才能注册。" - }, - "app.skin-site.register.mismatch": { - "message": "两次输入的密码不一致。" - }, - "app.skin-site.register.password": { - "message": "密码" - }, - "app.skin-site.register.password-hint": { - "message": "6~50 个字符,须包含大写字母、小写字母和数字。" - }, - "app.skin-site.register.qq": { - "message": "QQ(选填)" - }, - "app.skin-site.register.repeat-password": { - "message": "再次输入密码" - }, - "app.skin-site.register.resend-in": { - "message": "已发送({seconds} 秒)" - }, - "app.skin-site.register.send-code": { - "message": "发送验证码" - }, - "app.skin-site.register.sending": { - "message": "正在发送…" - }, - "app.skin-site.register.submit": { - "message": "注册账号" - }, - "app.skin-site.register.success": { - "message": "账号已创建并登录。" - }, - "app.skin-site.register.title": { - "message": "注册 StarLight 账号" - }, - "app.skin-site.reset.code": { - "message": "验证码" - }, - "app.skin-site.reset.email": { - "message": "邮箱" - }, - "app.skin-site.reset.email-hint": { - "message": "请输入注册时使用的邮箱地址。" - }, - "app.skin-site.reset.mismatch": { - "message": "两次输入的密码不一致。" - }, - "app.skin-site.reset.new-password": { - "message": "新密码" - }, - "app.skin-site.reset.password-hint": { - "message": "6~50 个字符,须包含大写字母、小写字母和数字。" - }, - "app.skin-site.reset.repeat-password": { - "message": "再次输入密码" - }, - "app.skin-site.reset.resend-in": { - "message": "已发送({seconds} 秒)" - }, - "app.skin-site.reset.send-code": { - "message": "发送验证码" - }, - "app.skin-site.reset.sending": { - "message": "正在发送…" - }, - "app.skin-site.reset.submit": { - "message": "重置密码" - }, - "app.skin-site.reset.success": { - "message": "密码已更新,现在可以登录。" - }, - "app.skin-site.reset.title": { - "message": "重置密码" - }, - "app.skin-site.review.back": { - "message": "返回主页" - }, - "app.skin-site.review.back-to-list": { - "message": "返回申请列表" - }, - "app.skin-site.review.email": { - "message": "你的邮箱" - }, - "app.skin-site.review.email-hint": { - "message": "审核结果将发送至此邮箱。" - }, - "app.skin-site.review.empty": { - "message": "暂无开放的申请表。" - }, - "app.skin-site.review.failed": { - "message": "加载审核申请表失败。" - }, - "app.skin-site.review.invite-code": { - "message": "邀请码" - }, - "app.skin-site.review.loading": { - "message": "正在加载…" - }, - "app.skin-site.review.optional": { - "message": "选填" - }, - "app.skin-site.review.required": { - "message": "必填" - }, - "app.skin-site.review.result.passed": { - "message": "已通过" - }, - "app.skin-site.review.result.pending": { - "message": "审核中" - }, - "app.skin-site.review.result.rejected": { - "message": "未通过" - }, - "app.skin-site.review.submit": { - "message": "提交申请" - }, - "app.skin-site.review.submitted": { - "message": "申请已提交。" - }, - "app.skin-site.review.submitting": { - "message": "正在提交…" - }, - "app.skin-site.review.subtitle": { - "message": "选择申请表并回答其中的问题。" - }, - "app.skin-site.review.title": { - "message": "玩家审核" - }, - "app.skin-site.wiki.back": { - "message": "返回" - }, - "app.skin-site.wiki.browser.by-author": { - "message": "由 {author} 编辑" - }, - "app.skin-site.wiki.browser.category-placeholder": { - "message": "分类名称" - }, - "app.skin-site.wiki.browser.empty-list": { - "message": "这里还没有内容。" - }, - "app.skin-site.wiki.browser.empty-search": { - "message": "没有匹配的页面。" - }, - "app.skin-site.wiki.browser.hint-category": { - "message": "输入分类名称开始浏览。" - }, - "app.skin-site.wiki.browser.hint-search": { - "message": "输入关键词开始搜索。" - }, - "app.skin-site.wiki.browser.load-more": { - "message": "加载更多" - }, - "app.skin-site.wiki.browser.search-placeholder": { - "message": "搜索 Wiki 页面…" - }, - "app.skin-site.wiki.browser.tab-category": { - "message": "分类" - }, - "app.skin-site.wiki.browser.tab-recent": { - "message": "最近" - }, - "app.skin-site.wiki.browser.tab-search": { - "message": "搜索" - }, - "app.skin-site.wiki.cancel": { - "message": "取消" - }, - "app.skin-site.wiki.categories": { - "message": "分类" - }, - "app.skin-site.wiki.close-preview": { - "message": "关闭预览" - }, - "app.skin-site.wiki.confirm-revert": { - "message": "确认撤销" - }, - "app.skin-site.wiki.diff-title": { - "message": "与当前版本的逐行差异" - }, - "app.skin-site.wiki.empty": { - "message": "在上方输入页面标题开始阅读。" - }, - "app.skin-site.wiki.history": { - "message": "历史" - }, - "app.skin-site.wiki.history-empty": { - "message": "暂无修订记录。" - }, - "app.skin-site.wiki.loading": { - "message": "加载中…" - }, - "app.skin-site.wiki.minor": { - "message": "小修改" - }, - "app.skin-site.wiki.move": { - "message": "移动" - }, - "app.skin-site.wiki.move-confirm": { - "message": "确认移动" - }, - "app.skin-site.wiki.move-done": { - "message": "页面已移动到 {title}。" - }, - "app.skin-site.wiki.move-target": { - "message": "新标题" - }, - "app.skin-site.wiki.no-summary": { - "message": "未填写编辑摘要" - }, - "app.skin-site.wiki.not-found": { - "message": "页面不存在。" - }, - "app.skin-site.wiki.open": { - "message": "打开" - }, - "app.skin-site.wiki.read": { - "message": "阅读" - }, - "app.skin-site.wiki.revert-done": { - "message": "页面已撤销到指定修订。" - }, - "app.skin-site.wiki.revert-to": { - "message": "撤销至此版本" - }, - "app.skin-site.wiki.revision": { - "message": "修订 #{id}" - }, - "app.skin-site.wiki.revision-preview": { - "message": "修订 #{id} 预览" - }, - "app.skin-site.wiki.search-placeholder": { - "message": "输入页面标题" - }, - "app.skin-site.wiki.title": { - "message": "StarLight 维基" - }, - "app.skin-site.wiki.unwatch": { - "message": "取消关注" - }, - "app.skin-site.wiki.updated-at": { - "message": "最后编辑于 {date},编辑者 {author}" - }, - "app.skin-site.wiki.view-revision": { - "message": "查看" - }, - "app.skin-site.wiki.watch": { - "message": "关注" - }, - "app.skin-site.wiki.watch-done": { - "message": "关注状态已更新。" - }, "app.skins.add-button": { "message": "添加皮肤" }, @@ -12674,27 +8042,6 @@ "app.skins.apply-button": { "message": "应用" }, - "app.skins.armor.close": { - "message": "关闭" - }, - "app.skins.armor.description": { - "message": "在皮肤上试穿盔甲与纹饰。未保存前不会写入任何内容。" - }, - "app.skins.armor.reset-to-saved": { - "message": "重置为已保存" - }, - "app.skins.armor.restore-defaults": { - "message": "恢复默认" - }, - "app.skins.armor.save": { - "message": "保存" - }, - "app.skins.armor.title": { - "message": "盔甲与纹饰" - }, - "app.skins.armor.unsaved": { - "message": "有未保存的更改" - }, "app.skins.create-skin": { "message": "创建皮肤" }, @@ -12824,6 +8171,27 @@ "app.skins.section.tiny-takeover": { "message": "小鬼当家" }, + "app.skins.skin-site-account.description": { + "message": "在下方选择皮肤后,可直接应用到 {player}。" + }, + "app.skins.skin-site-account.empty-description": { + "message": "这个皮肤站账号暂时没有可用的玩家角色。" + }, + "app.skins.skin-site-account.empty-title": { + "message": "暂无可用玩家" + }, + "app.skins.skin-site-account.loading-description": { + "message": "启动器正在同步此账号绑定的玩家。" + }, + "app.skins.skin-site-account.loading-title": { + "message": "正在加载皮肤站玩家……" + }, + "app.skins.skin-site-account.mojang-description": { + "message": "{player} 是正版 Minecraft 玩家,其皮肤仍由正版账号服务管理。" + }, + "app.skins.skin-site-account.title": { + "message": "StarLight 皮肤站玩家" + }, "app.skins.sign-in.axolotl-alt": { "message": "Starlight Launcher" }, @@ -12836,36 +8204,6 @@ "app.skins.sign-in.title": { "message": "请登录" }, - "app.skins.skin-site-account.description": { - "message": "在下方选择皮肤后,可直接应用到 {player}。" - }, - "app.skins.skin-site-account.empty-description": { - "message": "这个皮肤站账号暂时没有可用的玩家角色。" - }, - "app.skins.skin-site-account.empty-title": { - "message": "暂无可用玩家" - }, - "app.skins.skin-site-account.error-description": { - "message": "请检查网络后重试。" - }, - "app.skins.skin-site-account.error-title": { - "message": "无法加载皮肤站玩家" - }, - "app.skins.skin-site-account.loading-description": { - "message": "启动器正在同步此账号绑定的玩家。" - }, - "app.skins.skin-site-account.loading-title": { - "message": "正在加载皮肤站玩家……" - }, - "app.skins.skin-site-account.mojang-description": { - "message": "{player} 是正版 Minecraft 玩家,其皮肤仍由正版账号服务管理。" - }, - "app.skins.skin-site-account.retry": { - "message": "重试" - }, - "app.skins.skin-site-account.title": { - "message": "StarLight 皮肤站玩家" - }, "app.skins.tabs.default": { "message": "官方皮肤" }, @@ -12887,9 +8225,6 @@ "app.splash.updating-app-directory": { "message": "正在更新应用目录……" }, - "app.starlight-skin.frame-title": { - "message": "StarLight 皮肤站" - }, "app.survey-promotion.defer-hint": { "message": "关闭此弹窗后,你仍可以随时在“设置 → 关于”页面中找到并填写问卷。" }, @@ -12929,12 +8264,6 @@ "app.symlink-warning.write.header": { "message": "共享实例" }, - "app.sync-instances-update.choose-source.data-packs": { - "message": "选择要从哪个实例复制数据包。这些包仅用于初始化同步,之后可从任意实例进行编辑。" - }, - "app.sync-instances-update.choose-source.resource-packs": { - "message": "选择要从哪个实例复制资源包。这些包仅用于初始化同步,之后可从任意实例进行编辑。" - }, "app.translation-settings.ai-model": { "message": "文本模型" }, @@ -13112,9 +8441,6 @@ "app.update-announcement.version": { "message": "版本 {version}" }, - "app.update-popup.apt-update": { - "message": "更新" - }, "app.update-popup.body.download-complete": { "message": "Starlight Launcher v{version} 更新已下载完成!立即重启更新,或退出时自动安装。" }, @@ -13130,6 +8456,9 @@ "app.update-popup.download": { "message": "下载({size})" }, + "app.update-popup.apt-update": { + "message": "更新" + }, "app.update-popup.download-complete": { "message": "下载完成" }, @@ -13514,12 +8843,15 @@ "app.worlds.title": { "message": "世界" }, - "create.add-minecraft-folder": { - "message": "添加 .minecraft 文件夹" - }, "create.back": { "message": "返回库" }, + "create.pcl-hmcl-hint": { + "message": "正在使用 PCL / HMCL?" + }, + "create.add-minecraft-folder": { + "message": "添加 .minecraft 文件夹" + }, "create.import.description": { "message": "从其他启动器导入实例,或安装整合包。" }, @@ -13532,9 +8864,6 @@ "create.new.title": { "message": "全新创建" }, - "create.pcl-hmcl-hint": { - "message": "正在使用 PCL / HMCL?" - }, "create.subtitle": { "message": "实例是带有特定加载器、游戏版本和模组的一套 Minecraft 配置。" }, @@ -13718,141 +9047,6 @@ "instance.add-server.title": { "message": "添加服务器" }, - "instance.backups.added-size": { - "message": "新增存储 {size}" - }, - "instance.backups.all-included": { - "message": "实例中的所有文件和文件夹都会纳入备份。" - }, - "instance.backups.backup-now": { - "message": "立即备份" - }, - "instance.backups.cancel": { - "message": "取消备份" - }, - "instance.backups.choose": { - "message": "默认备份实例中的全部内容,请添加不需要备份的文件或文件夹。" - }, - "instance.backups.delete": { - "message": "删除备份" - }, - "instance.backups.delete-body": { - "message": "此快照将被永久删除,不再使用的仓库文件也会一并清理。" - }, - "instance.backups.delete-title": { - "message": "删除此备份?" - }, - "instance.backups.description": { - "message": "在实例关闭时,为整个实例创建去重快照。" - }, - "instance.backups.disable": { - "message": "关闭备份" - }, - "instance.backups.disable-blocked": { - "message": "必须先删除全部快照才能关闭备份。" - }, - "instance.backups.edit-exclusions": { - "message": "编辑排除项" - }, - "instance.backups.empty": { - "message": "尚未创建任何备份。" - }, - "instance.backups.enable": { - "message": "启用备份" - }, - "instance.backups.excluded-paths": { - "message": "不备份:{paths}" - }, - "instance.backups.exclusions.add-file": { - "message": "添加忽略文件" - }, - "instance.backups.exclusions.add-folder": { - "message": "添加忽略文件夹" - }, - "instance.backups.exclusions.empty": { - "message": "没有忽略任何文件或文件夹。" - }, - "instance.backups.exclusions.remove": { - "message": "从排除项中移除 {path}" - }, - "instance.backups.loading": { - "message": "正在加载备份设置……" - }, - "instance.backups.progress-bytes": { - "message": "已处理 {processed},共 {total}" - }, - "instance.backups.restore": { - "message": "恢复备份" - }, - "instance.backups.restore-body": { - "message": "即将进行的操作:新增 {added} 个文件,修改 {modified} 个文件,删除 {deleted} 个文件。是否继续?" - }, - "instance.backups.restore-title": { - "message": "恢复此备份?" - }, - "instance.backups.save-exclusions": { - "message": "保存排除项" - }, - "instance.backups.snapshot-meta": { - "message": "{files, plural, other {# 个文件}} · {size}" - }, - "instance.backups.snapshots": { - "message": "快照" - }, - "instance.backups.stage.applying": { - "message": "正在应用变更文件" - }, - "instance.backups.stage.failed": { - "message": "备份失败" - }, - "instance.backups.stage.hashing": { - "message": "正在计算文件哈希" - }, - "instance.backups.stage.interrupted": { - "message": "备份任务已中断" - }, - "instance.backups.stage.materializing": { - "message": "正在准备变更文件" - }, - "instance.backups.stage.preview": { - "message": "正在分析恢复变更" - }, - "instance.backups.stage.queued": { - "message": "等待开始" - }, - "instance.backups.stage.saving": { - "message": "正在保存快照索引" - }, - "instance.backups.stage.scanning": { - "message": "正在扫描文件" - }, - "instance.backups.stage.validating": { - "message": "正在验证恢复任务" - }, - "instance.backups.title": { - "message": "实例备份" - }, - "instance.backups.unavailable": { - "message": "备份不可用" - }, - "instance.backups.unavailable.direct-linked": { - "message": "不支持备份直接关联到其他启动器的实例。" - }, - "instance.backups.unavailable.external-directory": { - "message": "不支持备份使用外部游戏目录的实例。" - }, - "instance.backups.unavailable.not-installed": { - "message": "请先完成实例安装,再启用备份。" - }, - "instance.backups.unavailable.root-link": { - "message": "不支持备份根文件夹为链接的实例。" - }, - "instance.backups.unavailable.root-missing": { - "message": "实例文件夹不存在。" - }, - "instance.backups.unavailable.symlink": { - "message": "不支持备份以符号链接导入的实例。" - }, "instance.edit-server.title": { "message": "编辑服务器" }, @@ -13994,9 +9188,6 @@ "instance.server-modal.resource-pack": { "message": "资源包" }, - "instance.settings.tabs.backups": { - "message": "备份" - }, "instance.settings.tabs.core-components": { "message": "核心组件" }, @@ -14120,20 +9311,20 @@ "instance.settings.tabs.general.game-dir.description": { "message": "将一个独立的文件夹作为此实例的工作目录。游戏会从该文件夹读取模组、存档、配置和资源包,而不是托管的实例文件夹。适用于共用 .minecraft 目录的非版本隔离实例。" }, - "instance.settings.tabs.general.game-dir.external-note": { - "message": "此实例使用外部 .minecraft 目录,文件会直接在原位置管理。" - }, "instance.settings.tabs.general.game-dir.isolated": { "message": "版本隔离(存放于 versions/)" }, - "instance.settings.tabs.general.game-dir.managed-note": { - "message": "此实例使用 Starlight 托管目录。" + "instance.settings.tabs.general.game-dir.not-isolated": { + "message": "版本共享(.minecraft/)" }, "instance.settings.tabs.general.game-dir.move-note": { "message": "切换隔离仅更新启动器路径。请自行移动模组、存档和配置文件夹以保持一致。" }, - "instance.settings.tabs.general.game-dir.not-isolated": { - "message": "版本共享(.minecraft/)" + "instance.settings.tabs.general.game-dir.managed-note": { + "message": "此实例使用 Starlight 托管目录。" + }, + "instance.settings.tabs.general.game-dir.external-note": { + "message": "此实例使用外部 .minecraft 目录,文件会直接在原位置管理。" }, "instance.settings.tabs.general.icon": { "message": "图标" @@ -14264,9 +9455,6 @@ "instance.settings.tabs.java.optimize-memory-before-launch-description": { "message": "等待 Windows 内存优化完成后再启动游戏。" }, - "instance.settings.tabs.sync": { - "message": "同步" - }, "instance.settings.tabs.window": { "message": "游戏窗口" }, @@ -14279,15 +9467,6 @@ "instance.settings.tabs.window.fullscreen.description": { "message": "以全屏模式启动游戏(使用options.txt)。" }, - "instance.settings.tabs.window.height": { - "message": "高度" - }, - "instance.settings.tabs.window.height.description": { - "message": "游戏启动时的窗口高度。" - }, - "instance.settings.tabs.window.height.enter": { - "message": "输入高度……" - }, "instance.settings.tabs.window.maximize-window": { "message": "最大化窗口" }, @@ -14297,6 +9476,15 @@ "instance.settings.tabs.window.maximize-window.unsupported": { "message": "当前操作系统暂不支持。" }, + "instance.settings.tabs.window.height": { + "message": "高度" + }, + "instance.settings.tabs.window.height.description": { + "message": "游戏启动时的窗口高度。" + }, + "instance.settings.tabs.window.height.enter": { + "message": "输入高度……" + }, "instance.settings.tabs.window.width": { "message": "宽度" }, @@ -14306,15 +9494,6 @@ "instance.settings.tabs.window.width.enter": { "message": "输入宽度……" }, - "instance.settings.tabs.window.window-title": { - "message": "窗口标题" - }, - "instance.settings.tabs.window.window-title.description": { - "message": "自定义 Minecraft 窗口标题。留空则使用默认标题。" - }, - "instance.settings.tabs.window.window-title.enter": { - "message": "输入窗口标题..." - }, "instance.upgrade.action.add-dependency": { "message": "添加依赖" }, @@ -15353,6 +10532,9 @@ "minecraft-account.add-offline-account": { "message": "添加离线账户" }, + "minecraft-account.sign-in-starlight": { + "message": "登录 StarLight皮肤站" + }, "minecraft-account.copy-uuid": { "message": "复制 UUID" }, @@ -15431,30 +10613,6 @@ "minecraft-account.sign-in": { "message": "登录 Minecraft" }, - "minecraft-account.sign-in-starlight": { - "message": "登录 StarLight皮肤站" - }, - "minecraft-account.skin-site.checking": { - "message": "正在验证皮肤站登录状态…" - }, - "minecraft-account.skin-site.players": { - "message": "皮肤站玩家({count})" - }, - "minecraft-account.skin-site.players.empty": { - "message": "这个皮肤站账号还没有玩家。" - }, - "minecraft-account.skin-site.players.error": { - "message": "暂时无法刷新玩家列表,已保留上一次结果。" - }, - "minecraft-account.skin-site.players.retry": { - "message": "重试" - }, - "minecraft-account.skin-site.signed-in": { - "message": "已登录 StarLight皮肤站" - }, - "minecraft-account.skin-site.sync-error": { - "message": "暂时无法验证皮肤站登录状态,将自动重试。" - }, "minecraft-account.third-party-account": { "message": "StarLight 皮肤站账号" }, @@ -15569,6 +10727,399 @@ "search.filter.locked.server-loader.title": { "message": "加载器由服务器提供" }, + "settings.feature-flags.title": { + "message": "功能开关" + }, + "unknown-pack-warning-modal.body": { + "message": "只有上传到 Modrinth 的文件才会经过审核,无论其文件格式如何(包括 .mrpack)。" + }, + "unknown-pack-warning-modal.dont-show-again": { + "message": "不再显示此警告" + }, + "unknown-pack-warning-modal.header": { + "message": "确认安装" + }, + "unknown-pack-warning-modal.install-anyway": { + "message": "仍然安装" + }, + "unknown-pack-warning-modal.malware-statement": { + "message": "恶意软件常常通过整合包文件在 Discord 等平台上分享而传播。" + }, + "unknown-pack-warning-modal.warning.body": { + "message": "我们在 Modrinth 上找不到此文件。强烈建议你仅从可信来源安装文件。" + }, + "unknown-pack-warning-modal.warning.title": { + "message": "未知文件警告" + }, + "app.settings.about.easteregg.click-hint": { + "message": "点击以打开彩蛋小游戏" + }, + "app.settings.about.easteregg.contributors-title": { + "message": "贡献者彩蛋" + }, + "app.settings.about.easteregg.game-title": { + "message": "彩蛋小游戏" + }, + "app.home.launch-progress.empty": { + "message": "启动游戏后,这里会显示进度。" + }, + "app.home.launch-progress.title": { + "message": "启动进度" + }, + "app.screenshots.copied": { + "message": "已复制" + }, + "app.screenshots.copy": { + "message": "复制图像" + }, + "app.screenshots.delete-description": { + "message": "永久删除 {name}?此操作无法撤销。" + }, + "app.screenshots.delete-success": { + "message": "截图已删除" + }, + "app.screenshots.delete-title": { + "message": "删除截图" + }, + "app.screenshots.deselect": { + "message": "取消选择 {name}" + }, + "app.screenshots.edit": { + "message": "编辑截图" + }, + "app.screenshots.empty-description": { + "message": "你在游戏中拍摄的截图会显示在这里。" + }, + "app.screenshots.empty-heading": { + "message": "还没有截图" + }, + "app.screenshots.error-heading": { + "message": "加载截图失败" + }, + "app.screenshots.go-to-instance": { + "message": "前往实例" + }, + "app.screenshots.group-by": { + "message": "分组方式" + }, + "app.screenshots.group.all-screenshots": { + "message": "全部截图" + }, + "app.screenshots.group.collapse": { + "message": "折叠分组" + }, + "app.screenshots.group.custom": { + "message": "自定义分组" + }, + "app.screenshots.group.date": { + "message": "日期" + }, + "app.screenshots.group.delete": { + "message": "删除分组" + }, + "app.screenshots.group.delete-description": { + "message": "此分组中的截图将变为未分组。" + }, + "app.screenshots.group.edit": { + "message": "编辑分组名称" + }, + "app.screenshots.group.empty": { + "message": "拖放以添加截图。" + }, + "app.screenshots.group.expand": { + "message": "展开分组" + }, + "app.screenshots.group.instance": { + "message": "实例" + }, + "app.screenshots.group.new": { + "message": "新建分组" + }, + "app.screenshots.group.none": { + "message": "不分组" + }, + "app.screenshots.group.this-month": { + "message": "本月" + }, + "app.screenshots.group.this-week": { + "message": "本周" + }, + "app.screenshots.group.today": { + "message": "今天" + }, + "app.screenshots.group.ungrouped": { + "message": "未分组" + }, + "app.screenshots.group.yesterday": { + "message": "昨天" + }, + "app.screenshots.heading": { + "message": "截图" + }, + "app.screenshots.more-actions": { + "message": "更多操作" + }, + "app.screenshots.no-results-description": { + "message": "请尝试其他搜索或筛选条件。" + }, + "app.screenshots.no-results-heading": { + "message": "没有匹配的截图" + }, + "app.screenshots.preview.instance-and-date": { + "message": "{instance} · {date}" + }, + "app.screenshots.search": { + "message": "搜索" + }, + "app.screenshots.select": { + "message": "选择 {name}" + }, + "app.screenshots.selection.aria-label": { + "message": "已选中的截图" + }, + "app.screenshots.selection.delete-description": { + "message": "删除 {count, plural, one {# 张截图} other {# 张截图}}?此操作无法撤销。" + }, + "app.screenshots.selection.delete-success": { + "message": "{count, plural, one {已删除 # 张截图} other {已删除 # 张截图}}" + }, + "app.screenshots.selection.delete-title": { + "message": "删除选中的截图" + }, + "app.screenshots.selection.export-zip": { + "message": "导出 ZIP" + }, + "app.screenshots.selection.global-export-filename": { + "message": "Modrinth screenshots.zip" + }, + "app.screenshots.selection.instance-export-filename": { + "message": "{instance} screenshots.zip" + }, + "app.screenshots.selection.remove-from-group": { + "message": "从分组中移除" + }, + "app.screenshots.selection.selected-count": { + "message": "已选中 {count} 张" + }, + "app.screenshots.selection.zip-archive": { + "message": "ZIP 压缩包" + }, + "app.screenshots.show-in-folder": { + "message": "在文件夹中显示" + }, + "app.screenshots.sort-by": { + "message": "排序方式" + }, + "app.screenshots.sort.name": { + "message": "名称" + }, + "app.screenshots.sort.newest": { + "message": "最新" + }, + "app.screenshots.sort.oldest": { + "message": "最旧" + }, + "app.settings.about.copyright": { + "message": "版权所有 © StarLight 保留所有权利。" + }, + "app.settings.about.game.best": { + "message": "最佳:{score}" + }, + "app.settings.about.game.best-label": { + "message": "最佳" + }, + "app.settings.about.game.completed": { + "message": "下界之星!" + }, + "app.settings.about.game.exit": { + "message": "退出游戏" + }, + "app.settings.about.game.game-over": { + "message": "群星坠落!" + }, + "app.settings.about.game.highest-level": { + "message": "最高:等级 {level}" + }, + "app.settings.about.game.level-label": { + "message": "最高等级" + }, + "app.settings.about.game.new-record": { + "message": "新纪录!" + }, + "app.settings.about.game.overtime": { + "message": "涨潮!" + }, + "app.settings.about.game.overtime-detail": { + "message": "潮水涌回——继续合成!" + }, + "app.settings.about.game.overtimes-label": { + "message": "加时次数" + }, + "app.settings.about.game.restart": { + "message": "重新开始" + }, + "app.settings.about.game.score": { + "message": "得分:{score}" + }, + "app.settings.about.game.score-label": { + "message": "得分" + }, + "app.settings.about.game.settle": { + "message": "稳定" + }, + "app.settings.about.game.settle-title": { + "message": "本局已稳定!" + }, + "app.settings.about.game.tap-to-drop": { + "message": "点击投放一颗星" + }, + "app.settings.about.game.tide-hint": { + "message": "天空正在坠落——继续合成!" + }, + "app.settings.about.game.title": { + "message": "Starlight 合成" + }, + "app.starlight-skin.frame-title": { + "message": "StarLight 皮肤站" + }, + "app.navigation.screenshots": { + "message": "截图" + }, + "instance.backups.added-size": { + "message": "新增存储 {size}" + }, + "instance.backups.all-included": { + "message": "实例中的所有文件和文件夹都会纳入备份。" + }, + "instance.backups.backup-now": { + "message": "立即备份" + }, + "instance.backups.cancel": { + "message": "取消备份" + }, + "instance.backups.choose": { + "message": "默认备份实例中的全部内容,请添加不需要备份的文件或文件夹。" + }, + "instance.backups.delete": { + "message": "删除备份" + }, + "instance.backups.delete-body": { + "message": "此快照将被永久删除,不再使用的仓库文件也会一并清理。" + }, + "instance.backups.delete-title": { + "message": "删除此备份?" + }, + "instance.backups.description": { + "message": "在实例关闭时,为整个实例创建去重快照。" + }, + "instance.backups.disable": { + "message": "关闭备份" + }, + "instance.backups.disable-blocked": { + "message": "必须先删除全部快照才能关闭备份。" + }, + "instance.backups.edit-exclusions": { + "message": "编辑排除项" + }, + "instance.backups.empty": { + "message": "尚未创建任何备份。" + }, + "instance.backups.enable": { + "message": "启用备份" + }, + "instance.backups.excluded-paths": { + "message": "不备份:{paths}" + }, + "instance.backups.exclusions.add-file": { + "message": "添加忽略文件" + }, + "instance.backups.exclusions.add-folder": { + "message": "添加忽略文件夹" + }, + "instance.backups.exclusions.empty": { + "message": "没有忽略任何文件或文件夹。" + }, + "instance.backups.exclusions.remove": { + "message": "从排除项中移除 {path}" + }, + "instance.backups.loading": { + "message": "正在加载备份设置……" + }, + "instance.backups.progress-bytes": { + "message": "已处理 {processed},共 {total}" + }, + "instance.backups.restore": { + "message": "恢复备份" + }, + "instance.backups.restore-body": { + "message": "即将进行的操作:新增 {added} 个文件,修改 {modified} 个文件,删除 {deleted} 个文件。是否继续?" + }, + "instance.backups.restore-title": { + "message": "恢复此备份?" + }, + "instance.backups.save-exclusions": { + "message": "保存排除项" + }, + "instance.backups.snapshot-meta": { + "message": "{files, plural, other {# 个文件}} · {size}" + }, + "instance.backups.snapshots": { + "message": "快照" + }, + "instance.backups.stage.applying": { + "message": "正在应用变更文件" + }, + "instance.backups.stage.failed": { + "message": "备份失败" + }, + "instance.backups.stage.hashing": { + "message": "正在计算文件哈希" + }, + "instance.backups.stage.interrupted": { + "message": "备份任务已中断" + }, + "instance.backups.stage.materializing": { + "message": "正在准备变更文件" + }, + "instance.backups.stage.preview": { + "message": "正在分析恢复变更" + }, + "instance.backups.stage.queued": { + "message": "等待开始" + }, + "instance.backups.stage.saving": { + "message": "正在保存快照索引" + }, + "instance.backups.stage.scanning": { + "message": "正在扫描文件" + }, + "instance.backups.stage.validating": { + "message": "正在验证恢复任务" + }, + "instance.backups.title": { + "message": "实例备份" + }, + "instance.backups.unavailable": { + "message": "备份不可用" + }, + "instance.backups.unavailable.direct-linked": { + "message": "不支持备份直接关联到其他启动器的实例。" + }, + "instance.backups.unavailable.external-directory": { + "message": "不支持备份使用外部游戏目录的实例。" + }, + "instance.backups.unavailable.not-installed": { + "message": "请先完成实例安装,再启用备份。" + }, + "instance.backups.unavailable.root-link": { + "message": "不支持备份根文件夹为链接的实例。" + }, + "instance.backups.unavailable.root-missing": { + "message": "实例文件夹不存在。" + }, + "instance.backups.unavailable.symlink": { + "message": "不支持备份以符号链接导入的实例。" + }, "settings.backups.repository.change": { "message": "更改文件夹" }, @@ -15599,28 +11150,2205 @@ "settings.backups.repository.usage-description": { "message": "实际存储 {stored},对应 {logical} 的备份数据,共 {count, plural, other {# 个快照}}。" }, - "settings.feature-flags.title": { - "message": "功能开关" + "app.settings.synced-options.choose-sync-source.command-history-description": { + "message": "选择要从哪个实例复制命令历史记录。这些记录仅用于初始同步,之后可从任意实例编辑。" }, - "unknown-pack-warning-modal.body": { - "message": "只有上传到 Modrinth 的文件才会经过审核,无论其文件格式如何(包括 .mrpack)。" + "app.settings.synced-options.choose-sync-source.command-history-title": { + "message": "选择命令历史记录来源" }, - "unknown-pack-warning-modal.dont-show-again": { - "message": "不再显示此警告" + "app.settings.synced-options.choose-sync-source.creative-hotbars-description": { + "message": "选择要从哪个实例复制保存的创造模式快捷栏。这些快捷栏仅用于初始同步,之后可从任意实例编辑。" }, - "unknown-pack-warning-modal.header": { - "message": "确认安装" + "app.settings.synced-options.choose-sync-source.creative-hotbars-title": { + "message": "选择创造模式快捷栏来源" }, - "unknown-pack-warning-modal.install-anyway": { - "message": "仍然安装" + "app.settings.synced-options.choose-sync-source.data-packs-title": { + "message": "选择数据包来源" }, - "unknown-pack-warning-modal.malware-statement": { - "message": "恶意软件常常通过整合包文件在 Discord 等平台上分享而传播。" + "app.settings.synced-options.choose-sync-source.game-settings-description": { + "message": "选择要从哪个实例复制游戏设置。这些设置仅用于初始同步,之后可从任意实例编辑。" }, - "unknown-pack-warning-modal.warning.body": { - "message": "我们在 Modrinth 上找不到此文件。强烈建议你仅从可信来源安装文件。" + "app.settings.synced-options.choose-sync-source.game-settings-title": { + "message": "选择游戏设置来源" }, - "unknown-pack-warning-modal.warning.title": { - "message": "未知文件警告" - } + "app.settings.synced-options.choose-sync-source.ineligible": { + "message": "无法选择此实例作为同步来源" + }, + "app.settings.synced-options.choose-sync-source.load-error": { + "message": "无法加载同步来源,请重试。" + }, + "app.settings.synced-options.choose-sync-source.multiplayer-servers-description": { + "message": "选择要从哪个实例复制多人服务器列表。这些服务器仅用于初始同步,之后可从任意实例编辑。" + }, + "app.settings.synced-options.choose-sync-source.multiplayer-servers-title": { + "message": "选择多人服务器来源" + }, + "app.settings.synced-options.choose-sync-source.no-instances-found": { + "message": "没有找到实例" + }, + "app.settings.synced-options.choose-sync-source.resource-packs-title": { + "message": "选择资源包来源" + }, + "app.settings.synced-options.choose-sync-source.retry": { "message": "重试" }, + "app.settings.synced-options.choose-sync-source.search-placeholder": { + "message": "搜索实例" + }, + "app.settings.synced-options.choose-sync-source.sync": { "message": "同步" }, + "app.settings.synced-options.command-history": { "message": "同步命令记录" }, + "app.settings.synced-options.command-history.description": { + "message": "在不同的实例之间同步命令记录。" + }, + "app.settings.synced-options.command-history.editor-title": { + "message": "编辑指令历史记录" + }, + "app.settings.synced-options.creative-hotbars": { + "message": "同步保存的创造模式物品栏" + }, + "app.settings.synced-options.creative-hotbars.description": { + "message": "在不同的实例之间同步创造模式物品栏。" + }, + "app.settings.synced-options.data-packs": { "message": "同步数据包" }, + "app.settings.synced-options.data-packs.description": { + "message": "在所有实例间使用相同的数据包" + }, + "app.settings.synced-options.data-packs.none-synced-yet": { + "message": "尚未同步任何数据包" + }, + "app.settings.synced-options.edit.no-instances": { + "message": "请先添加实例,再编辑同步数据。" + }, + "app.settings.synced-options.edit.no-synced-data": { + "message": "请先选择同步来源,再编辑此设置。" + }, + "app.settings.synced-options.game-settings": { "message": "同步游戏设置" }, + "app.settings.synced-options.game-settings.button": { + "message": "编辑游戏设置" + }, + "app.settings.synced-options.game-settings.description": { + "message": "在所有实例间使用相同的游戏设置。" + }, + "app.settings.synced-options.game-settings.disabled-tooltip": { + "message": "请先启用游戏设置同步,再选择单个设置。" + }, + "app.settings.synced-options.game-settings.no-options-to-edit": { + "message": "目前没有可编辑的设置" + }, + "app.settings.synced-options.multiplayer-servers": { + "message": "同步多人模式服务器列表" + }, + "app.settings.synced-options.multiplayer-servers.address": { + "message": "服务器地址" + }, + "app.settings.synced-options.multiplayer-servers.copy-address": { + "message": "复制地址" + }, + "app.settings.synced-options.multiplayer-servers.count": { + "message": "{count, number} 个服务器" + }, + "app.settings.synced-options.multiplayer-servers.description": { + "message": "在不同的实例直接同步多人模式服务器列表。" + }, + "app.settings.synced-options.multiplayer-servers.editor-title": { + "message": "编辑同步的服务器" + }, + "app.settings.synced-options.multiplayer-servers.empty": { + "message": "当前未同步任何用户添加的服务器。" + }, + "app.settings.synced-options.multiplayer-servers.filter-offline": { + "message": "离线" + }, + "app.settings.synced-options.multiplayer-servers.filter-online": { + "message": "在线" + }, + "app.settings.synced-options.multiplayer-servers.more-options": { + "message": "更多服务器选项" + }, + "app.settings.synced-options.multiplayer-servers.name": { + "message": "服务器名称" + }, + "app.settings.synced-options.multiplayer-servers.no-results": { + "message": "没有匹配搜索或筛选条件的已同步服务器。" + }, + "app.settings.synced-options.multiplayer-servers.none-synced-yet": { + "message": "暂无已同步的服务器" + }, + "app.settings.synced-options.multiplayer-servers.players-online": { + "message": "{count, number} 人在线" + }, + "app.settings.synced-options.multiplayer-servers.search": { + "message": "搜索 {count, number} 个已同步服务器……" + }, + "app.settings.synced-options.multiplayer-servers.status": { + "message": "状态" + }, + "app.settings.synced-options.packs.disabled": { + "message": "请先启用同步,再编辑共享包。" + }, + "app.settings.synced-options.resource-packs": { "message": "同步资源包" }, + "app.settings.synced-options.resource-packs.description": { + "message": "在所有实例间使用相同的资源包" + }, + "app.settings.synced-options.resource-packs.none-synced-yet": { + "message": "尚未同步任何资源包" + }, + "app.settings.synced-options.title": { "message": "跨所有实例同步的选项" }, + "app.settings.synced-packs.data-packs": { "message": "数据包" }, + "app.settings.synced-packs.disable": { "message": "禁用" }, + "app.settings.synced-packs.empty": { "message": "没有已同步的包" }, + "app.settings.synced-packs.enable": { "message": "启用" }, + "app.settings.synced-packs.remove": { "message": "移除" }, + "app.settings.synced-packs.resource-packs": { "message": "资源包" }, + "app.sync-instances-update.choose-source.data-packs": { + "message": "选择要从哪个实例复制数据包。这些包仅用于初始化同步,之后可从任意实例进行编辑。" + }, + "app.sync-instances-update.choose-source.resource-packs": { + "message": "选择要从哪个实例复制资源包。这些包仅用于初始化同步,之后可从任意实例进行编辑。" + }, + "instance.settings.tabs.backups": { "message": "备份" }, + "instance.settings.tabs.sync": { "message": "同步" }, + "app.settings.game-options.category.accessibility.description": { + "message": "无障碍设置" + }, + "app.settings.game-options.category.accessibility.label": { + "message": "无障碍" + }, + "app.settings.game-options.category.chat.description": { + "message": "聊天显示与外观" + }, + "app.settings.game-options.category.chat.label": { "message": "聊天" }, + "app.settings.game-options.category.controls.description": { + "message": "鼠标、移动与按键绑定" + }, + "app.settings.game-options.category.controls.label": { "message": "控制" }, + "app.settings.game-options.category.custom.description": { + "message": "由模组添加的设置" + }, + "app.settings.game-options.category.custom.label": { + "message": "自定义设置" + }, + "app.settings.game-options.category.language.description": { + "message": "游戏语言" + }, + "app.settings.game-options.category.language.label": { "message": "语言" }, + "app.settings.game-options.category.music-and-sound.description": { + "message": "音量与音频偏好" + }, + "app.settings.game-options.category.music-and-sound.label": { + "message": "音乐和声音" + }, + "app.settings.game-options.category.online.description": { + "message": "在线与 Realms 偏好" + }, + "app.settings.game-options.category.online.label": { "message": "在线" }, + "app.settings.game-options.category.skin-customization.description": { + "message": "皮肤层与主手" + }, + "app.settings.game-options.category.skin-customization.label": { + "message": "皮肤自定义" + }, + "app.settings.game-options.category.video.description": { + "message": "镜头与显示设置" + }, + "app.settings.game-options.category.video.label": { "message": "视频" }, + "app.settings.game-options.choice.all": { "message": "全部" }, + "app.settings.game-options.choice.balanced": { "message": "平衡" }, + "app.settings.game-options.choice.by-player": { "message": "按玩家" }, + "app.settings.game-options.choice.chat": { "message": "聊天" }, + "app.settings.game-options.choice.commands-only": { "message": "仅命令" }, + "app.settings.game-options.choice.constant": { "message": "持续" }, + "app.settings.game-options.choice.crosshair": { "message": "准星" }, + "app.settings.game-options.choice.custom": { "message": "自定义" }, + "app.settings.game-options.choice.decreased": { "message": "降低" }, + "app.settings.game-options.choice.default": { "message": "默认" }, + "app.settings.game-options.choice.fabulous": { "message": "极佳" }, + "app.settings.game-options.choice.fancy": { "message": "精美" }, + "app.settings.game-options.choice.far": { "message": "远" }, + "app.settings.game-options.choice.fast": { "message": "快速" }, + "app.settings.game-options.choice.frequent": { "message": "频繁" }, + "app.settings.game-options.choice.hidden": { "message": "隐藏" }, + "app.settings.game-options.choice.hotbar": { "message": "快捷栏" }, + "app.settings.game-options.choice.left": { "message": "左" }, + "app.settings.game-options.choice.limited": { "message": "有限" }, + "app.settings.game-options.choice.max-fps": { "message": "最高 FPS" }, + "app.settings.game-options.choice.maximum": { "message": "最大" }, + "app.settings.game-options.choice.minimal": { "message": "最少" }, + "app.settings.game-options.choice.minimum": { "message": "最小" }, + "app.settings.game-options.choice.nearby": { "message": "附近" }, + "app.settings.game-options.choice.never": { "message": "从不" }, + "app.settings.game-options.choice.none": { "message": "无" }, + "app.settings.game-options.choice.normal": { "message": "正常" }, + "app.settings.game-options.choice.off": { "message": "关闭" }, + "app.settings.game-options.choice.on": { "message": "开启" }, + "app.settings.game-options.choice.opengl": { "message": "OpenGL 渲染器" }, + "app.settings.game-options.choice.pause": { "message": "暂停菜单" }, + "app.settings.game-options.choice.pause-and-toast": { + "message": "暂停菜单和提示" + }, + "app.settings.game-options.choice.power-saver": { "message": "省电" }, + "app.settings.game-options.choice.right": { "message": "右" }, + "app.settings.game-options.choice.short": { "message": "短" }, + "app.settings.game-options.choice.shown": { "message": "显示" }, + "app.settings.game-options.choice.system": { "message": "系统" }, + "app.settings.game-options.choice.tiny": { "message": "极小" }, + "app.settings.game-options.choice.vulkan": { "message": "Vulkan 渲染器" }, + "app.settings.game-options.choice.when-minimized": { "message": "最小化时" }, + "app.settings.game-options.choice.while-afk": { "message": "挂机时" }, + "app.settings.game-options.compatibility.none": { + "message": "部分实例无法使用此设置" + }, + "app.settings.game-options.compatibility.reason.launcher-controlled": { + "message": "此设置由启动器设置管理" + }, + "app.settings.game-options.custom-value.placeholder": { "message": "输入值" }, + "app.settings.game-options.keybind.assigned-status": { + "message": "已将 {setting} 绑定为 {binding}。" + }, + "app.settings.game-options.keybind.cancelled-status": { + "message": "已取消按键绑定更改。" + }, + "app.settings.game-options.keybind.change": { + "message": "{setting}:{binding}。激活以更改绑定。" + }, + "app.settings.game-options.keybind.choose": { "message": "选择按键" }, + "app.settings.game-options.keybind.conflict-description": { + "message": "{settings} 已使用此按键。" + }, + "app.settings.game-options.keybind.key.arrow-down": { "message": "向下箭头" }, + "app.settings.game-options.keybind.key.arrow-left": { "message": "向左箭头" }, + "app.settings.game-options.keybind.key.arrow-right": { + "message": "向右箭头" + }, + "app.settings.game-options.keybind.key.arrow-up": { "message": "向上箭头" }, + "app.settings.game-options.keybind.key.backspace": { "message": "退格" }, + "app.settings.game-options.keybind.key.caps-lock": { "message": "大写锁定" }, + "app.settings.game-options.keybind.key.delete": { "message": "删除" }, + "app.settings.game-options.keybind.key.end": { "message": "End 键" }, + "app.settings.game-options.keybind.key.enter": { "message": "回车" }, + "app.settings.game-options.keybind.key.escape": { "message": "Esc 键" }, + "app.settings.game-options.keybind.key.home": { "message": "Home 键" }, + "app.settings.game-options.keybind.key.insert": { "message": "Insert 键" }, + "app.settings.game-options.keybind.key.keypad-key": { + "message": "数字键盘 {key}" + }, + "app.settings.game-options.keybind.key.left-alt": { "message": "左 Alt" }, + "app.settings.game-options.keybind.key.left-command": { + "message": "左 Command" + }, + "app.settings.game-options.keybind.key.left-control": { + "message": "左 Ctrl" + }, + "app.settings.game-options.keybind.key.left-shift": { "message": "左 Shift" }, + "app.settings.game-options.keybind.key.left-super": { "message": "左 Super" }, + "app.settings.game-options.keybind.key.menu": { "message": "菜单" }, + "app.settings.game-options.keybind.key.num-lock": { "message": "数字锁定" }, + "app.settings.game-options.keybind.key.page-down": { + "message": "Page Down 键" + }, + "app.settings.game-options.keybind.key.page-up": { "message": "Page Up 键" }, + "app.settings.game-options.keybind.key.pause": { "message": "暂停" }, + "app.settings.game-options.keybind.key.print-screen": { "message": "截图" }, + "app.settings.game-options.keybind.key.right-alt": { "message": "右 Alt" }, + "app.settings.game-options.keybind.key.right-command": { + "message": "右 Command" + }, + "app.settings.game-options.keybind.key.right-control": { + "message": "右 Ctrl" + }, + "app.settings.game-options.keybind.key.right-shift": { + "message": "右 Shift" + }, + "app.settings.game-options.keybind.key.right-super": { + "message": "右 Super" + }, + "app.settings.game-options.keybind.key.scroll-lock": { + "message": "滚动锁定" + }, + "app.settings.game-options.keybind.key.space": { "message": "空格" }, + "app.settings.game-options.keybind.key.tab": { "message": "Tab 键" }, + "app.settings.game-options.keybind.key.unbound": { "message": "未绑定" }, + "app.settings.game-options.keybind.key.unknown": { "message": "未知按键" }, + "app.settings.game-options.keybind.listen": { "message": "请按下一个按键……" }, + "app.settings.game-options.keybind.listening-status": { + "message": "正在监听按键或鼠标按钮。按 Esc 清除绑定。" + }, + "app.settings.game-options.keybind.mixed": { "message": "各实例不同" }, + "app.settings.game-options.keybind.modifier.alt": { "message": "Alt 键" }, + "app.settings.game-options.keybind.modifier.command": { + "message": "Command 键" + }, + "app.settings.game-options.keybind.modifier.control": { + "message": "Ctrl 键" + }, + "app.settings.game-options.keybind.modifier.shift": { "message": "Shift 键" }, + "app.settings.game-options.keybind.modifier.super": { "message": "Super 键" }, + "app.settings.game-options.keybind.mouse.button": { + "message": "鼠标 {button}" + }, + "app.settings.game-options.keybind.mouse.left": { "message": "鼠标左键" }, + "app.settings.game-options.keybind.mouse.middle": { "message": "鼠标中键" }, + "app.settings.game-options.keybind.mouse.right": { "message": "鼠标右键" }, + "app.settings.game-options.keybind.recording-label": { + "message": "{setting}:正在监听按键或鼠标按钮。按 Esc 清除绑定。" + }, + "app.settings.game-options.keybind.scancode": { "message": "扫描码 {code}" }, + "app.settings.game-options.keybind.unsupported-status": { + "message": "Minecraft 无法使用此输入,请尝试其他按键。" + }, + "app.settings.game-options.setting.advanced-opengl.label": { + "message": "高级 OpenGL" + }, + "app.settings.game-options.setting.allow-cursor-changes.label": { + "message": "允许光标变化" + }, + "app.settings.game-options.setting.allow-server-listing.description": { + "message": "允许玩家名称出现在服务器列表中。" + }, + "app.settings.game-options.setting.allow-server-listing.label": { + "message": "服务器列表" + }, + "app.settings.game-options.setting.alternate-blocks.label": { + "message": "备用方块" + }, + "app.settings.game-options.setting.ambient-occlusion.label": { + "message": "平滑光照" + }, + "app.settings.game-options.setting.ambient-volume.label": { + "message": "环境" + }, + "app.settings.game-options.setting.anaglyph-3d.label": { + "message": "3D 红蓝立体" + }, + "app.settings.game-options.setting.anisotropic-filtering.label": { + "message": "各向异性过滤" + }, + "app.settings.game-options.setting.anisotropy.label": { + "message": "各向异性" + }, + "app.settings.game-options.setting.attack-indicator.label": { + "message": "攻击指示器" + }, + "app.settings.game-options.setting.auto-jump.description": { + "message": "自动跳过一格高的障碍物。" + }, + "app.settings.game-options.setting.auto-jump.label": { + "message": "自动跳跃" + }, + "app.settings.game-options.setting.auto-suggestions.label": { + "message": "命令建议" + }, + "app.settings.game-options.setting.autosave-indicator.label": { + "message": "自动保存指示器" + }, + "app.settings.game-options.setting.biome-blend-radius.description": { + "message": "生物群系颜色过渡的距离。" + }, + "app.settings.game-options.setting.biome-blend-radius.label": { + "message": "生物群系混合" + }, + "app.settings.game-options.setting.blocks-volume.label": { + "message": "方块" + }, + "app.settings.game-options.setting.brightness.label": { "message": "亮度" }, + "app.settings.game-options.setting.cape.description": { + "message": "显示玩家的披风,包括鞘翅纹理。" + }, + "app.settings.game-options.setting.cape.label": { "message": "披风" }, + "app.settings.game-options.setting.chat-background-only.label": { + "message": "仅聊天背景" + }, + "app.settings.game-options.setting.chat-colors.label": { + "message": "聊天颜色" + }, + "app.settings.game-options.setting.chat-delay.label": { + "message": "聊天延迟" + }, + "app.settings.game-options.setting.chat-line-spacing.label": { + "message": "聊天行间距" + }, + "app.settings.game-options.setting.chat-links-prompt.description": { + "message": "打开聊天链接前询问" + }, + "app.settings.game-options.setting.chat-links-prompt.label": { + "message": "打开链接前询问" + }, + "app.settings.game-options.setting.chat-links.description": { + "message": "允许打开聊天中的网页链接。" + }, + "app.settings.game-options.setting.chat-links.label": { + "message": "网页链接" + }, + "app.settings.game-options.setting.chat-opacity.description": { + "message": "聊天文字的不透明度。" + }, + "app.settings.game-options.setting.chat-opacity.label": { + "message": "聊天不透明度" + }, + "app.settings.game-options.setting.chat-preview.label": { + "message": "聊天预览" + }, + "app.settings.game-options.setting.chat-scale.label": { + "message": "聊天缩放" + }, + "app.settings.game-options.setting.chat-visibility.label": { + "message": "聊天可见性" + }, + "app.settings.game-options.setting.chat-width.label": { + "message": "聊天宽度" + }, + "app.settings.game-options.setting.chunk-fade-time.label": { + "message": "区块淡出时间" + }, + "app.settings.game-options.setting.cloud-range.label": { + "message": "云层距离" + }, + "app.settings.game-options.setting.clouds.label": { "message": "云" }, + "app.settings.game-options.setting.ctrl-click-right-click.label": { + "message": "按住 Control 点击代替右键点击" + }, + "app.settings.game-options.setting.cutout-leaves.label": { + "message": "半透明树叶" + }, + "app.settings.game-options.setting.damage-tilt.label": { + "message": "受伤倾斜" + }, + "app.settings.game-options.setting.dark-splash.description": { + "message": "将 Mojang Studios 加载界面从红色改为黑色。" + }, + "app.settings.game-options.setting.dark-splash.label": { + "message": "单色徽标" + }, + "app.settings.game-options.setting.darkness-pulsing.label": { + "message": "黑暗脉动" + }, + "app.settings.game-options.setting.debug-gui-scale.label": { + "message": "调试界面缩放" + }, + "app.settings.game-options.setting.directional-audio.label": { + "message": "方向性音频" + }, + "app.settings.game-options.setting.discrete-mouse-scroll.description": { + "message": "将每次鼠标滚轮输入视为一个滚动步进。" + }, + "app.settings.game-options.setting.discrete-mouse-scroll.label": { + "message": "离散滚动" + }, + "app.settings.game-options.setting.entity-distance.label": { + "message": "实体距离" + }, + "app.settings.game-options.setting.entity-shadows.label": { + "message": "实体阴影" + }, + "app.settings.game-options.setting.exclusive-fullscreen.label": { + "message": "独占全屏" + }, + "app.settings.game-options.setting.extra-telemetry.label": { + "message": "可选遥测" + }, + "app.settings.game-options.setting.focused-chat-height.label": { + "message": "聚焦时聊天高度" + }, + "app.settings.game-options.setting.force-unicode-font.label": { + "message": "强制 Unicode 字体" + }, + "app.settings.game-options.setting.fov-effects.label": { + "message": "视野效果" + }, + "app.settings.game-options.setting.fov.label": { "message": "视野" }, + "app.settings.game-options.setting.fullscreen.label": { "message": "全屏" }, + "app.settings.game-options.setting.glint-speed.label": { + "message": "附魔光效速度" + }, + "app.settings.game-options.setting.glint-strength.label": { + "message": "附魔光效强度" + }, + "app.settings.game-options.setting.graphics-backend.label": { + "message": "图形后端" + }, + "app.settings.game-options.setting.graphics.description": { + "message": "控制画面质量和性能。" + }, + "app.settings.game-options.setting.graphics.label": { "message": "画面" }, + "app.settings.game-options.setting.gui-scale.description": { + "message": "游戏界面和 HUD 的大小。" + }, + "app.settings.game-options.setting.gui-scale.label": { + "message": "界面缩放" + }, + "app.settings.game-options.setting.hat.description": { + "message": "显示帽子皮肤层。" + }, + "app.settings.game-options.setting.hat.label": { "message": "帽子" }, + "app.settings.game-options.setting.held-item-tooltips.label": { + "message": "手持物品提示" + }, + "app.settings.game-options.setting.hide-lightning-flashes.label": { + "message": "隐藏闪电闪光" + }, + "app.settings.game-options.setting.hide-matched-names.label": { + "message": "隐藏匹配的名称" + }, + "app.settings.game-options.setting.hide-server-address.label": { + "message": "隐藏服务器地址" + }, + "app.settings.game-options.setting.hide-splash-texts.label": { + "message": "隐藏启动标语" + }, + "app.settings.game-options.setting.high-contrast-outline.label": { + "message": "高对比度方块轮廓" + }, + "app.settings.game-options.setting.high-contrast.description": { + "message": "增强界面元素的对比度。" + }, + "app.settings.game-options.setting.high-contrast.label": { + "message": "高对比度" + }, + "app.settings.game-options.setting.hostile-volume.label": { + "message": "敌对生物" + }, + "app.settings.game-options.setting.improved-transparency.label": { + "message": "改进透明度" + }, + "app.settings.game-options.setting.in-game-notifications.label": { + "message": "游戏内通知" + }, + "app.settings.game-options.setting.inactivity-framerate-limit.label": { + "message": "降低帧率" + }, + "app.settings.game-options.setting.invert-horizontal-mouse.label": { + "message": "反转水平鼠标" + }, + "app.settings.game-options.setting.invert-mouse.description": { + "message": "反转垂直鼠标移动。" + }, + "app.settings.game-options.setting.invert-mouse.label": { + "message": "反转鼠标" + }, + "app.settings.game-options.setting.jacket.description": { + "message": "显示夹克皮肤层。" + }, + "app.settings.game-options.setting.jacket.label": { "message": "夹克" }, + "app.settings.game-options.setting.japanese-glyph-variants.label": { + "message": "日文字符变体" + }, + "app.settings.game-options.setting.key-advancements.label": { + "message": "进度" + }, + "app.settings.game-options.setting.key-attack.label": { "message": "攻击" }, + "app.settings.game-options.setting.key-back.label": { "message": "后退" }, + "app.settings.game-options.setting.key-chat.label": { "message": "打开聊天" }, + "app.settings.game-options.setting.key-command.label": { "message": "命令" }, + "app.settings.game-options.setting.key-debug-advanced-tooltips.label": { + "message": "显示高级提示" + }, + "app.settings.game-options.setting.key-debug-chunk-borders.label": { + "message": "显示区块边界" + }, + "app.settings.game-options.setting.key-debug-clear-chat.label": { + "message": "清空聊天" + }, + "app.settings.game-options.setting.key-debug-copy-location.label": { + "message": "复制位置" + }, + "app.settings.game-options.setting.key-debug-copy-recreate-command.label": { + "message": "复制重建命令" + }, + "app.settings.game-options.setting.key-debug-crash.label": { + "message": "触发调试崩溃" + }, + "app.settings.game-options.setting.key-debug-dump-dynamic-textures.label": { + "message": "转储动态纹理" + }, + "app.settings.game-options.setting.key-debug-dump-version.label": { + "message": "转储版本" + }, + "app.settings.game-options.setting.key-debug-focus-pause.label": { + "message": "失去焦点时暂停" + }, + "app.settings.game-options.setting.key-debug-fps-charts.label": { + "message": "FPS 图表" + }, + "app.settings.game-options.setting.key-debug-hitboxes.label": { + "message": "显示碰撞箱" + }, + "app.settings.game-options.setting.key-debug-improved-transparency.label": { + "message": "改进透明度调试视图" + }, + "app.settings.game-options.setting.key-debug-lightmap-texture.label": { + "message": "光照贴图纹理" + }, + "app.settings.game-options.setting.key-debug-modifier.label": { + "message": "调试修饰键" + }, + "app.settings.game-options.setting.key-debug-network-charts.label": { + "message": "网络图表" + }, + "app.settings.game-options.setting.key-debug-options.label": { + "message": "调试选项" + }, + "app.settings.game-options.setting.key-debug-overlay.label": { + "message": "调试覆盖层" + }, + "app.settings.game-options.setting.key-debug-profiling-chart.label": { + "message": "性能分析图表" + }, + "app.settings.game-options.setting.key-debug-profiling.label": { + "message": "开始性能分析" + }, + "app.settings.game-options.setting.key-debug-reload-chunks.label": { + "message": "重新加载区块" + }, + "app.settings.game-options.setting.key-debug-reload-resource-packs.label": { + "message": "重新加载资源包" + }, + "app.settings.game-options.setting.key-debug-spectate.label": { + "message": "旁观实体" + }, + "app.settings.game-options.setting.key-debug-switch-game-mode.label": { + "message": "切换游戏模式" + }, + "app.settings.game-options.setting.key-drop.label": { "message": "丢弃物品" }, + "app.settings.game-options.setting.key-forward.label": { "message": "前进" }, + "app.settings.game-options.setting.key-friends.label": { "message": "好友" }, + "app.settings.game-options.setting.key-fullscreen.label": { + "message": "切换全屏" + }, + "app.settings.game-options.setting.key-hotbar-1.label": { + "message": "快捷栏 1" + }, + "app.settings.game-options.setting.key-hotbar-2.label": { + "message": "快捷栏 2" + }, + "app.settings.game-options.setting.key-hotbar-3.label": { + "message": "快捷栏 3" + }, + "app.settings.game-options.setting.key-hotbar-4.label": { + "message": "快捷栏 4" + }, + "app.settings.game-options.setting.key-hotbar-5.label": { + "message": "快捷栏 5" + }, + "app.settings.game-options.setting.key-hotbar-6.label": { + "message": "快捷栏 6" + }, + "app.settings.game-options.setting.key-hotbar-7.label": { + "message": "快捷栏 7" + }, + "app.settings.game-options.setting.key-hotbar-8.label": { + "message": "快捷栏 8" + }, + "app.settings.game-options.setting.key-hotbar-9.label": { + "message": "快捷栏 9" + }, + "app.settings.game-options.setting.key-inventory.label": { + "message": "物品栏" + }, + "app.settings.game-options.setting.key-jump.label": { "message": "跳跃" }, + "app.settings.game-options.setting.key-left.label": { "message": "向左平移" }, + "app.settings.game-options.setting.key-load-toolbar.label": { + "message": "加载工具栏" + }, + "app.settings.game-options.setting.key-perspective.label": { + "message": "切换视角" + }, + "app.settings.game-options.setting.key-pick-item.label": { + "message": "选取方块" + }, + "app.settings.game-options.setting.key-player-list.label": { + "message": "玩家列表" + }, + "app.settings.game-options.setting.key-quick-actions.label": { + "message": "快捷操作" + }, + "app.settings.game-options.setting.key-right.label": { + "message": "向右平移" + }, + "app.settings.game-options.setting.key-save-toolbar.label": { + "message": "保存工具栏" + }, + "app.settings.game-options.setting.key-screenshot.label": { + "message": "截图" + }, + "app.settings.game-options.setting.key-smooth-camera.label": { + "message": "切换电影视角" + }, + "app.settings.game-options.setting.key-sneak.label": { "message": "潜行" }, + "app.settings.game-options.setting.key-social-interactions.label": { + "message": "社交互动" + }, + "app.settings.game-options.setting.key-spectator-hotbar.label": { + "message": "旁观者快捷栏" + }, + "app.settings.game-options.setting.key-spectator-outlines.label": { + "message": "高亮旁观者" + }, + "app.settings.game-options.setting.key-sprint.label": { "message": "疾跑" }, + "app.settings.game-options.setting.key-swap-offhand.label": { + "message": "交换副手" + }, + "app.settings.game-options.setting.key-toggle-gui.label": { + "message": "切换 HUD" + }, + "app.settings.game-options.setting.key-toggle-spectator-shader.label": { + "message": "切换旁观者着色器" + }, + "app.settings.game-options.setting.key-use.label": { "message": "使用物品" }, + "app.settings.game-options.setting.language.label": { "message": "语言" }, + "app.settings.game-options.setting.left-pants-leg.label": { + "message": "左裤腿" + }, + "app.settings.game-options.setting.left-sleeve.label": { "message": "左袖" }, + "app.settings.game-options.setting.legacy-framerate-limit.label": { + "message": "帧率上限" + }, + "app.settings.game-options.setting.legacy-view-distance.label": { + "message": "视距" + }, + "app.settings.game-options.setting.mac-fullscreen-menu.label": { + "message": "全屏时显示 macOS 菜单" + }, + "app.settings.game-options.setting.main-hand.description": { + "message": "选择主手为左手还是右手。" + }, + "app.settings.game-options.setting.main-hand.label": { "message": "主手" }, + "app.settings.game-options.setting.master-volume.label": { + "message": "主音量" + }, + "app.settings.game-options.setting.max-framerate.label": { + "message": "最大帧率" + }, + "app.settings.game-options.setting.menu-background-blur.label": { + "message": "菜单背景模糊" + }, + "app.settings.game-options.setting.mipmap-levels.description": { + "message": "平滑远处纹理。" + }, + "app.settings.game-options.setting.mipmap-levels.label": { + "message": "Mipmap 级别" + }, + "app.settings.game-options.setting.mouse-wheel-sensitivity.label": { + "message": "鼠标滚轮灵敏度" + }, + "app.settings.game-options.setting.music-frequency.label": { + "message": "音乐频率" + }, + "app.settings.game-options.setting.music-toast.description": { + "message": "选择是否在暂停菜单和提示中显示音乐标题。" + }, + "app.settings.game-options.setting.music-toast.label": { + "message": "音乐通知" + }, + "app.settings.game-options.setting.music-volume.label": { "message": "音乐" }, + "app.settings.game-options.setting.narrator-hotkey.label": { + "message": "旁白快捷键" + }, + "app.settings.game-options.setting.narrator.description": { + "message": "选择旁白朗读的内容。" + }, + "app.settings.game-options.setting.narrator.label": { "message": "旁白" }, + "app.settings.game-options.setting.neutral-volume.label": { + "message": "友好生物" + }, + "app.settings.game-options.setting.notification-time.description": { + "message": "提示通知保持显示的时长。" + }, + "app.settings.game-options.setting.notification-time.label": { + "message": "通知时长" + }, + "app.settings.game-options.setting.operator-items-tab.label": { + "message": "管理员物品栏标签" + }, + "app.settings.game-options.setting.panorama-speed.label": { + "message": "全景图速度" + }, + "app.settings.game-options.setting.particles.label": { "message": "粒子" }, + "app.settings.game-options.setting.players-volume.label": { + "message": "玩家" + }, + "app.settings.game-options.setting.prioritize-chunk-updates.label": { + "message": "区块更新优先级" + }, + "app.settings.game-options.setting.quit-shortcuts.label": { + "message": "退出快捷键" + }, + "app.settings.game-options.setting.raw-mouse-input.label": { + "message": "原始鼠标输入" + }, + "app.settings.game-options.setting.realms-notifications.label": { + "message": "Realms 通知" + }, + "app.settings.game-options.setting.record-volume.label": { + "message": "唱片机/音符盒" + }, + "app.settings.game-options.setting.reduced-debug-info.label": { + "message": "减少调试信息" + }, + "app.settings.game-options.setting.render-distance.label": { + "message": "渲染距离" + }, + "app.settings.game-options.setting.right-pants-leg.label": { + "message": "右裤腿" + }, + "app.settings.game-options.setting.right-sleeve.label": { "message": "右袖" }, + "app.settings.game-options.setting.rotate-with-minecart.label": { + "message": "随矿车旋转" + }, + "app.settings.game-options.setting.save-chat-drafts.label": { + "message": "保存聊天草稿" + }, + "app.settings.game-options.setting.screen-effects.label": { + "message": "屏幕效果" + }, + "app.settings.game-options.setting.secure-chat-only.label": { + "message": "仅显示安全聊天" + }, + "app.settings.game-options.setting.sensitivity.label": { + "message": "鼠标灵敏度" + }, + "app.settings.game-options.setting.server-textures.label": { + "message": "服务器纹理" + }, + "app.settings.game-options.setting.share-presence.label": { + "message": "共享在线状态" + }, + "app.settings.game-options.setting.simulation-distance.description": { + "message": "实体更新以及方块和流体更新的距离。" + }, + "app.settings.game-options.setting.simulation-distance.label": { + "message": "模拟距离" + }, + "app.settings.game-options.setting.snooper.label": { "message": "数据收集" }, + "app.settings.game-options.setting.sprint-window.label": { + "message": "疾跑窗口" + }, + "app.settings.game-options.setting.subtitles.description": { + "message": "显示游戏声音的字幕。" + }, + "app.settings.game-options.setting.subtitles.label": { "message": "字幕" }, + "app.settings.game-options.setting.text-background-opacity.label": { + "message": "文字背景不透明度" + }, + "app.settings.game-options.setting.texture-filtering.label": { + "message": "纹理过滤" + }, + "app.settings.game-options.setting.toggle-attack.label": { + "message": "切换攻击" + }, + "app.settings.game-options.setting.toggle-crouch.description": { + "message": "按一次即可保持潜行。" + }, + "app.settings.game-options.setting.toggle-crouch.label": { + "message": "切换潜行" + }, + "app.settings.game-options.setting.toggle-sprint.description": { + "message": "按一次即可保持疾跑。" + }, + "app.settings.game-options.setting.toggle-sprint.label": { + "message": "切换疾跑" + }, + "app.settings.game-options.setting.toggle-use.label": { + "message": "切换使用" + }, + "app.settings.game-options.setting.touchscreen.label": { + "message": "触屏模式" + }, + "app.settings.game-options.setting.ui-volume.label": { "message": "界面" }, + "app.settings.game-options.setting.unfocused-chat-height.label": { + "message": "未聚焦时聊天高度" + }, + "app.settings.game-options.setting.use-vbo.label": { "message": "使用 VBO" }, + "app.settings.game-options.setting.view-bobbing.description": { + "message": "行走时为镜头添加摇摆效果。" + }, + "app.settings.game-options.setting.view-bobbing.label": { + "message": "视角摇摆" + }, + "app.settings.game-options.setting.vignette.label": { "message": "晕影" }, + "app.settings.game-options.setting.voice-volume.label": { + "message": "语音和语音朗读" + }, + "app.settings.game-options.setting.vsync.description": { + "message": "将帧率限制为显示器刷新率,以防止画面撕裂。" + }, + "app.settings.game-options.setting.vsync.label": { "message": "垂直同步" }, + "app.settings.game-options.setting.weather-radius.label": { + "message": "天气范围" + }, + "app.settings.game-options.setting.weather-volume.label": { + "message": "天气" + }, + "app.settings.game-options.validation.changed-since-opened": { + "message": "此设置已在其他位置更改,请检查后重试。" + }, + "app.settings.game-options.validation.invalid-value": { + "message": "请选择有效值。" + }, + "app.settings.game-options.validation.missing-value": { + "message": "请先选择一个值。" + }, + "app.settings.game-options.validation.no-compatible-instances": { + "message": "部分实例无法使用此设置" + }, + "app.settings.synced-options.game-settings.conflict-text": { + "message": "我们已加载最新设置。请检查更改后再次保存。" + }, + "app.settings.synced-options.game-settings.conflict-title": { + "message": "这些设置已在其他地方更改" + }, + "app.settings.synced-options.game-settings.custom-empty": { + "message": "Modrinth 在某个实例中找到模组添加的设置后,它们会显示在这里。" + }, + "app.settings.synced-options.game-settings.disable-all": { + "message": "取消同步全部" + }, + "app.settings.synced-options.game-settings.empty": { + "message": "没有匹配当前搜索或筛选条件的设置。" + }, + "app.settings.synced-options.game-settings.enable-all": { + "message": "同步全部" + }, + "app.settings.synced-options.game-settings.load-failed": { + "message": "无法加载游戏设置。" + }, + "app.settings.synced-options.game-settings.loading": { + "message": "正在加载设置……" + }, + "app.settings.synced-options.game-settings.not-being-synced": { + "message": "未同步" + }, + "app.settings.synced-options.game-settings.retry": { "message": "重试" }, + "app.settings.synced-options.game-settings.save": { "message": "保存设置" }, + "app.settings.synced-options.game-settings.search": { + "message": "搜索设置……" + }, + "app.settings.synced-options.game-settings.sync-description": { + "message": "同步的选项会应用到每个实例,并覆盖整合包中包含的值。" + }, + "app.settings.synced-options.game-settings.sync-setting": { + "message": "在所有实例间同步{setting}" + }, + "app.settings.synced-options.game-settings.sync-title": { + "message": "同步游戏设置" + }, + "app.settings.synced-options.game-settings.synced-across-instances": { + "message": "已在所有实例间同步" + }, + "app.settings.synced-options.game-settings.title": { "message": "游戏设置" }, + "app.settings.synced-options.game-settings.unsaved-changes": { + "message": "你有未保存的更改。" + }, + "app.settings.synced-options.game-settings.unsync-setting": { + "message": "停止在所有实例间同步{setting}" + }, + "app.settings.synced-options.game-settings.value-mixed": { + "message": "各实例不同" + }, + "app.settings.synced-options.game-settings.value-off": { "message": "关闭" }, + "app.settings.synced-options.game-settings.value-on": { "message": "开启" }, + "app.settings.synced-options.game-settings.value-unset": { + "message": "选择一个值" + }, + "app.anniversary.banner": { "message": "Starlight {ordinal} 周年快乐!" }, + "instance.settings.tabs.window.window-title": { "message": "窗口标题" }, + "instance.settings.tabs.window.window-title.description": { + "message": "自定义 Minecraft 窗口标题。留空则使用默认标题。" + }, + "instance.settings.tabs.window.window-title.enter": { + "message": "输入窗口标题..." + }, + "app.settings.defaults.window-title.enabled": { + "message": "自定义 Minecraft 窗口标题" + }, + "app.settings.defaults.window-title.enabled-description": { + "message": "允许实例自定义 Minecraft 窗口标题。" + }, + "app.settings.defaults.window-title.default": { "message": "默认窗口标题" }, + "app.settings.defaults.window-title.default-description": { + "message": "当实例未提供自己的标题时使用。" + }, + "app.settings.defaults.window-title.default-placeholder": { + "message": "输入默认窗口标题..." + }, + "app.action-bar.announcements": { "message": "公告" }, + "app.remote-announcements.center-title": { "message": "公告" }, + "app.remote-announcements.empty": { "message": "暂无公告" }, + "app.settings.tabs.logs": { "message": "日志与诊断" }, + "app.settings.logs.export.title": { "message": "导出日志" }, + "app.settings.logs.export.description": { + "message": "将启动器日志打包,可附带环境摘要、最近的实例日志与崩溃分析。" + }, + "app.settings.logs.export.button": { "message": "导出日志…" }, + "app.settings.logs.open-folder": { "message": "打开日志文件夹" }, + "app.settings.logs.export.modal.title": { "message": "导出日志" }, + "app.settings.logs.export.modal.description": { + "message": "选择要包含的详细程度。导出的日志会把访问令牌、Minecraft 令牌与 IP 地址替换为占位符。" + }, + "app.settings.logs.export.modal.range": { "message": "时间范围" }, + "app.settings.logs.export.modal.range.30-minutes": { + "message": "最近 30 分钟" + }, + "app.settings.logs.export.modal.range.2-hours": { "message": "最近 2 小时" }, + "app.settings.logs.export.modal.range.all": { "message": "全部会话" }, + "app.settings.logs.export.modal.level": { "message": "日志等级" }, + "app.settings.logs.export.modal.level.all": { "message": "全部等级" }, + "app.settings.logs.export.modal.level.debug": { "message": "DEBUG 及以上" }, + "app.settings.logs.export.modal.level.info": { "message": "INFO 及以上" }, + "app.settings.logs.export.modal.extras": { "message": "附加信息" }, + "app.settings.logs.export.modal.system-info": { "message": "系统与环境摘要" }, + "app.settings.logs.export.modal.instance-logs": { + "message": "最近的实例日志" + }, + "app.settings.logs.export.modal.crash-analysis": { + "message": "崩溃分析(检测到崩溃时)" + }, + "app.settings.logs.export.modal.cancel": { "message": "取消" }, + "app.settings.logs.export.modal.confirm": { "message": "导出" }, + "app.settings.logs.export.notification-title": { "message": "日志已导出" }, + "app.settings.logs.export.notification-text": { + "message": "日志压缩包已保存到 {path}" + }, + "app.skins.armor.title": { "message": "盔甲与纹饰" }, + "app.skins.armor.save": { "message": "保存" }, + "app.skins.armor.close": { "message": "关闭" }, + "app.skins.armor.description": { + "message": "在皮肤上试穿盔甲与纹饰。未保存前不会写入任何内容。" + }, + "app.skins.armor.unsaved": { "message": "有未保存的更改" }, + "app.skins.armor.reset-to-saved": { "message": "重置为已保存" }, + "app.skins.armor.restore-defaults": { "message": "恢复默认" }, + "app.instances.batch-edit-groups.add": { "message": "添加" }, + "app.instances.batch-edit-groups.add-to-group-title": { + "message": "添加实例到「{groupName}」" + }, + "app.instances.batch-edit-groups.added": { "message": "已添加" }, + "app.instances.batch-edit-groups.cancel": { "message": "取消" }, + "app.instances.batch-edit-groups.create": { "message": "创建分组" }, + "app.instances.batch-edit-groups.group-name": { "message": "分组名称" }, + "app.instances.batch-edit-groups.group-name-placeholder": { + "message": "输入分组名称" + }, + "app.instances.batch-edit-groups.no-instances-found": { + "message": "未找到实例" + }, + "app.instances.batch-edit-groups.save-changes": { "message": "保存" }, + "app.instances.batch-edit-groups.search-instance": { "message": "搜索实例" }, + "app.instances.group.add-to-group": { "message": "添加到分组" }, + "app.instances.group.collapse": { "message": "折叠分组" }, + "app.instances.group.delete-description": { + "message": "此分组中的实例将被取消分组。" + }, + "app.instances.group.delete-group": { "message": "删除分组" }, + "app.instances.group.edit-name": { "message": "编辑分组名称" }, + "app.instances.group.empty": { "message": "拖放实例到此处添加。" }, + "app.instances.group.expand": { "message": "展开分组" }, + "app.instances.group.move-down": { "message": "下移分组" }, + "app.instances.group.move-up": { "message": "上移分组" }, + "app.instances.group.name-empty": { "message": "分组名称不能为空。" }, + "app.instances.group.name-too-long": { + "message": "分组名称不能超过 {maxLength} 个字符。" + }, + "app.instances.group.new-instance": { "message": "新建实例" }, + "app.instances.group.pinned": { "message": "已置顶" }, + "app.instances.group.rename-group": { "message": "重命名分组" }, + "app.instances.sort-by": { "message": "排序方式" }, + "app.instances.sort.direction.asc-alphabetical": { "message": "A–Z 正序" }, + "app.instances.sort.direction.asc-date": { "message": "最早的在前" }, + "app.instances.sort.direction.asc-recency": { "message": "最早游玩在前" }, + "app.instances.sort.direction.asc-version": { "message": "旧版本在前" }, + "app.instances.sort.direction.desc-alphabetical": { "message": "Z–A 倒序" }, + "app.instances.sort.direction.desc-date": { "message": "最新的在前" }, + "app.instances.sort.direction.desc-recency": { "message": "最近游玩在前" }, + "app.instances.sort.direction.desc-version": { "message": "新版本在前" }, + "app.library.context-menu.pin-instance": { "message": "置顶实例" }, + "app.library.context-menu.remove-from-group": { "message": "移出分组" }, + "app.library.context-menu.unpin-instance": { "message": "取消置顶" }, + "app.library.group.new": { "message": "新建分组" }, + "app.library.selection.new-group": { "message": "新建分组" }, + "app.library.selection.remove-from-group": { "message": "移出分组" }, + "app.log-share.settings.title": { "message": "日志分享与 AI 分析" }, + "app.log-share.settings.description": { + "message": "将崩溃诊断分享到 LogShare,获取结构化摘要与可选的 AI 分析。优先使用 LogShare,不可用时回退到 mclo.gs。" + }, + "app.log-share.settings.share-provider": { "message": "日志分享服务" }, + "app.log-share.settings.share-provider-description": { + "message": "分享诊断链接时上传到的目标服务。" + }, + "app.log-share.settings.ai-source": { "message": "AI 分析来源" }, + "app.log-share.settings.ai-source-logshare": { "message": "LogShare AI" }, + "app.log-share.settings.ai-source-custom": { "message": "自定义 AI 服务商" }, + "app.log-share.settings.ai-source-description": { + "message": "LogShare AI 在云端分析;自定义则使用下方配置的服务商。" + }, + "app.log-share.settings.auto-upload": { + "message": "自动上传以获取结构化摘要" + }, + "app.log-share.settings.auto-upload-description": { + "message": "仅在 LogShare 模式下生效。" + }, + "app.log-share.settings.multi-file": { "message": "多文件上传" }, + "app.log-share.settings.multi-file-description": { + "message": "同时上传 latest.log、崩溃报告、hs_err 以及启动器日志。" + }, + "app.log-share.settings.no-storage": { "message": "不落盘直接分析" }, + "app.log-share.settings.no-storage-description": { + "message": "直接提交内容进行分析并跳过存储上传。会关闭自动摘要。" + }, + "app.log-share.settings.show-progress": { "message": "显示 AI 分析进度" }, + "app.log-share.settings.show-progress-description": { + "message": "展示 LogAgent 运行期间的思考、工具及上限状态。" + }, + "app.log-share.shared-logs.title": { "message": "已分享日志" }, + "app.log-share.shared-logs.description": { + "message": "你分享过的所有诊断都记录在这里。删除条目会将其从记录中移除,并向分享服务请求删除。" + }, + "app.log-share.shared-logs.empty": { "message": "暂无已分享的日志。" }, + "app.log-share.shared-logs.delete": { "message": "删除" }, + "app.log-share.shared-logs.deleting": { "message": "删除中…" }, + "app.log-share.shared-logs.deleted": { "message": "已删除共享日志。" }, + "app.log-share.shared-logs.delete-failed": { + "message": "删除已分享日志失败。" + }, + "app.log-share.shared-logs.truncated": { "message": "已截断" }, + "app.minecraft-crash.share-fallback": { + "message": "LogShare 不可用,已改用 mclo.gs 分享诊断信息。" + }, + "app.log-share.ai.action": { "message": "AI 深度分析" }, + "app.log-share.summary.title": { "message": "LogShare 分析" }, + "app.log-share.summary.loading": { "message": "正在加载结构化摘要…" }, + "app.log-share.summary.empty": { + "message": "LogShare 未返回这些日志的结构化摘要。" + }, + "app.log-share.summary.no-storage": { + "message": "启用不落盘模式时无法获取结构化摘要。" + }, + "app.log-share.summary.failed": { + "message": "无法加载 LogShare 摘要:{message}" + }, + "app.log-share.summary.problems": { "message": "问题" }, + "app.log-share.summary.information": { "message": "信息" }, + "app.minecraft-crash.logs.loading": { "message": "正在加载崩溃日志…" }, + "app.minecraft-crash.logs.empty": { "message": "未找到本次启动产生的日志。" }, + "app.minecraft-crash.logs.failed": { + "message": "无法加载崩溃日志:{message}" + }, + "app.minecraft-crash.log-file.loading": { "message": "正在加载日志文件…" }, + "app.minecraft-crash.log-file.failed": { + "message": "无法加载此日志文件:{message}" + }, + "app.log-share.ai.tab": { "message": "LogAgent 深度分析" }, + "app.log-share.ai.root-cause": { "message": "核心根因" }, + "app.log-share.ai.confidence": { "message": "诊断置信度" }, + "app.log-share.ai.steps": { "message": "推荐排障步骤" }, + "app.log-share.ai.evidence": { "message": "支撑证据链" }, + "app.log-share.ai.thinking": { "message": "思考中…" }, + "app.log-share.ai.queued": { "message": "排队中,前方约 {position} 个任务" }, + "app.log-share.ai.queued-front": { "message": "排队中,正在等待空闲槽位" }, + "app.log-share.ai.tool": { "message": "正在使用工具:{name}" }, + "app.log-share.ai.unknown-tool": { "message": "工具" }, + "app.log-share.ai.tool-result": { "message": "已收到工具结果" }, + "app.log-share.ai.limit": { "message": "已达到工具调用上限" }, + "app.log-share.ai.working": { "message": "正在使用 LogAgent 分析…" }, + "app.log-share.ai.failed": { "message": "LogAgent 分析失败:{message}" }, + "app.shortcut-settings.change-shortcut": { + "message": "更改「{action}」的快捷键" + }, + "app.shortcut-settings.enable": { "message": "启用快捷滚动" }, + "app.shortcut-settings.end-action": { "message": "滚动到页面底部" }, + "app.shortcut-settings.end-action-description": { + "message": "将当前页面移动到底部。" + }, + "app.shortcut-settings.home-action": { "message": "滚动到页面顶部" }, + "app.shortcut-settings.home-action-description": { + "message": "将当前页面移动到顶部。" + }, + "app.shortcut-settings.nav-create": { "message": "新建实例" }, + "app.shortcut-settings.nav-create-description": { + "message": "前往新建实例。" + }, + "app.shortcut-settings.nav-description": { + "message": "使用各自的快捷键跳转到对应菜单项。每个快捷键默认关闭,需逐个启用。" + }, + "app.shortcut-settings.nav-discover": { "message": "发现内容" }, + "app.shortcut-settings.nav-discover-description": { + "message": "前往浏览内容。" + }, + "app.shortcut-settings.nav-downloads": { "message": "下载" }, + "app.shortcut-settings.nav-downloads-description": { + "message": "前往下载。" + }, + "app.shortcut-settings.nav-home": { "message": "首页" }, + "app.shortcut-settings.nav-home-description": { "message": "前往首页。" }, + "app.shortcut-settings.nav-lab": { "message": "实验室" }, + "app.shortcut-settings.nav-lab-description": { "message": "前往实验室。" }, + "app.shortcut-settings.nav-library": { "message": "内容库" }, + "app.shortcut-settings.nav-library-description": { + "message": "前往内容库。" + }, + "app.shortcut-settings.nav-multiplayer": { "message": "多人游戏" }, + "app.shortcut-settings.nav-multiplayer-description": { + "message": "前往多人游戏。" + }, + "app.shortcut-settings.nav-settings": { "message": "设置" }, + "app.shortcut-settings.nav-settings-description": { "message": "前往设置。" }, + "app.shortcut-settings.nav-skins": { "message": "皮肤选择器" }, + "app.shortcut-settings.nav-skins-description": { + "message": "前往皮肤选择器。" + }, + "app.shortcut-settings.nav-title": { "message": "导航快捷键" }, + "app.shortcut-settings.nav-worlds": { "message": "世界" }, + "app.shortcut-settings.nav-worlds-description": { + "message": "前往你的世界。" + }, + "app.shortcut-settings.page-down-action": { "message": "向下滚动一屏" }, + "app.shortcut-settings.page-down-action-description": { + "message": "将当前页面向下移动一屏。" + }, + "app.shortcut-settings.page-up-action": { "message": "向上滚动一屏" }, + "app.shortcut-settings.page-up-action-description": { + "message": "将当前页面向上移动一屏。" + }, + "app.shortcut-settings.scroll-description": { + "message": "使用键盘在长页面中快速滚动。" + }, + "app.shortcut-settings.scroll-title": { "message": "快速滚动" }, + "app.settings.tabs.shortcut-settings": { "message": "键盘快捷键" }, + "app.skin-site.bugs.title": { "message": "问题与建议" }, + "app.skin-site.bugs.back": { "message": "返回主页" }, + "app.skin-site.bugs.subtitle": { "message": "反馈问题并跟踪处理进度。" }, + "app.skin-site.bugs.loading": { "message": "加载中…" }, + "app.skin-site.bugs.failed": { "message": "无法加载问题列表。" }, + "app.skin-site.bugs.empty": { "message": "没有符合筛选条件的问题。" }, + "app.skin-site.bugs.all": { "message": "全部" }, + "app.skin-site.bugs.more": { "message": "加载更多" }, + "app.skin-site.bugs.open-only": { "message": "仅显示未关闭" }, + "app.skin-site.bugs.comments": { "message": "{count} 条评论" }, + "app.skin-site.bugs.type.bug": { "message": "缺陷" }, + "app.skin-site.bugs.type.feature": { "message": "功能建议" }, + "app.skin-site.bugs.type.improvement": { "message": "改进" }, + "app.skin-site.bugs.status.pending": { "message": "待处理" }, + "app.skin-site.bugs.status.confirmed": { "message": "已确认" }, + "app.skin-site.bugs.status.needs-info": { "message": "待补充信息" }, + "app.skin-site.bugs.status.in-progress": { "message": "处理中" }, + "app.skin-site.bugs.status.verifying": { "message": "验证中" }, + "app.skin-site.bugs.status.closed": { "message": "已关闭" }, + "app.skin-site.bugs.priority.critical": { "message": "紧急" }, + "app.skin-site.bugs.priority.high": { "message": "高" }, + "app.skin-site.bugs.priority.normal": { "message": "普通" }, + "app.skin-site.bugs.priority.low": { "message": "低" }, + "app.skin-site.bugs.resolution.fixed": { "message": "已修复" }, + "app.skin-site.bugs.resolution.wont-fix": { "message": "不予修复" }, + "app.skin-site.bugs.resolution.by-design": { "message": "设计如此" }, + "app.skin-site.bugs.resolution.duplicate": { "message": "重复问题" }, + "app.skin-site.bugs.resolution.cannot-reproduce": { "message": "无法复现" }, + "app.skin-site.bugs.resolution.invalid": { "message": "无效" }, + "app.skin-site.bug-detail.back": { "message": "返回列表" }, + "app.skin-site.bug-detail.loading": { "message": "加载中…" }, + "app.skin-site.bug-detail.failed": { "message": "无法加载该问题。" }, + "app.skin-site.bug-detail.issue-no": { "message": "问题 #{id}" }, + "app.skin-site.bug-detail.by": { "message": "由 {name} 提交" }, + "app.skin-site.bug-detail.assignee": { "message": "负责人:{name}" }, + "app.skin-site.bug-detail.unassigned": { "message": "未分配" }, + "app.skin-site.bug-detail.description-empty": { "message": "未提供描述。" }, + "app.skin-site.bug-detail.resolution": { "message": "处理结果:{name}" }, + "app.skin-site.bug-detail.comments-title": { "message": "评论" }, + "app.skin-site.bug-detail.comments-empty": { + "message": "还没有评论,来抢沙发吧。" + }, + "app.skin-site.bug-detail.comments-loading": { "message": "加载评论中…" }, + "app.skin-site.bug-detail.comment-placeholder": { + "message": "写下你的评论…" + }, + "app.skin-site.bug-detail.comment-submit": { "message": "发表评论" }, + "app.skin-site.bug-detail.comment-sending": { "message": "发送中…" }, + "app.skin-site.bug-detail.comment-empty-error": { + "message": "评论内容不能为空。" + }, + "app.skin-site.bug-detail.comment-posted": { "message": "评论已发表。" }, + "app.skin-site.bug-detail.comment-deleted": { "message": "评论已删除。" }, + "app.skin-site.bug-detail.delete": { "message": "删除" }, + "app.skin-site.bug-detail.deleting": { "message": "删除中…" }, + "app.skin-site.bug-detail.system": { "message": "系统" }, + "app.skin-site.bug-create.title": { "message": "新建问题" }, + "app.skin-site.bug-create.type": { "message": "类型" }, + "app.skin-site.bug-create.title-field": { "message": "标题" }, + "app.skin-site.bug-create.title-placeholder": { "message": "简要描述问题" }, + "app.skin-site.bug-create.description": { "message": "描述" }, + "app.skin-site.bug-create.description-placeholder": { + "message": "发生了什么?如何复现?" + }, + "app.skin-site.bug-create.private": { "message": "私密问题" }, + "app.skin-site.bug-create.private-hint": { "message": "仅你和维护者可见。" }, + "app.skin-site.bug-create.images": { "message": "图片" }, + "app.skin-site.bug-create.images-hint": { + "message": "可选,最多 5 张图片。" + }, + "app.skin-site.bug-create.submit": { "message": "创建问题" }, + "app.skin-site.bug-create.submitting": { "message": "创建中…" }, + "app.skin-site.bug-create.created": { "message": "问题已创建。" }, + "app.skin-site.bug-create.cancel": { "message": "取消" }, + "app.skin-site.bug-notifications.title": { "message": "通知" }, + "app.skin-site.bug-notifications.back": { "message": "返回主页" }, + "app.skin-site.bug-notifications.subtitle": { + "message": "你提交或关注的问题动态。" + }, + "app.skin-site.bug-notifications.loading": { "message": "加载中…" }, + "app.skin-site.bug-notifications.failed": { "message": "无法加载通知。" }, + "app.skin-site.bug-notifications.empty": { "message": "暂无新通知。" }, + "app.skin-site.bug-notifications.item": { + "message": "{name} 更新了问题 #{id}" + }, + "app.skin-site.bug-notifications.mark-all": { "message": "全部标为已读" }, + "app.skin-site.bug-notifications.marked-all": { + "message": "已将全部通知标为已读。" + }, + "app.skin-site.bugs.create": { "message": "新建问题" }, + "app.skin-site.bugs.notifications": { "message": "通知" }, + "app.skin-site.home.title": { "message": "星光皮肤站" }, + "app.skin-site.home.subtitle": { "message": "星光服务器玩家的衣柜。" }, + "app.skin-site.home.address": { "message": "皮肤站地址" }, + "app.skin-site.home.copied": { "message": "地址已复制。" }, + "app.skin-site.home.copy": { "message": "复制" }, + "app.skin-site.admin.title": { "message": "管理控制台" }, + "app.skin-site.admin.back": { "message": "返回主页" }, + "app.skin-site.admin.no-access": { "message": "你没有访问权限。" }, + "app.skin-site.admin.no-access-hint": { + "message": "请使用管理员账号登录后使用本控制台。" + }, + "app.skin-site.admin.group.security": { "message": "系统安全" }, + "app.skin-site.admin.group.users": { "message": "用户管理" }, + "app.skin-site.admin.group.community": { "message": "社区管理" }, + "app.skin-site.admin.group.resources": { "message": "资源分发" }, + "app.skin-site.admin.item.servers": { "message": "服务器管理" }, + "app.skin-site.admin.item.summary": { "message": "状态概览" }, + "app.skin-site.admin.item.access-audit": { "message": "登录与认证审计" }, + "app.skin-site.admin.item.users": { "message": "用户信息" }, + "app.skin-site.admin.item.players": { "message": "玩家信息" }, + "app.skin-site.admin.item.review": { "message": "玩家审核" }, + "app.skin-site.admin.item.broadcast": { "message": "公告操作" }, + "app.skin-site.admin.item.chat": { "message": "聊天室管理" }, + "app.skin-site.admin.item.wiki": { "message": "维基管理" }, + "app.skin-site.admin.item.donations": { "message": "捐赠管理" }, + "app.skin-site.admin.item.mods": { "message": "Mod 管理" }, + "app.skin-site.admin.item.launcher": { "message": "启动器管理" }, + "app.skin-site.admin.item.downloads": { "message": "下载管理" }, + "app.skin-site.home.admin": { "message": "管理" }, + "app.skin-site.home.settings": { "message": "账号" }, + "app.skin-site.home.sign-in": { "message": "登录" }, + "app.skin-site.home.players": { "message": "角色" }, + "app.skin-site.home.my-players": { "message": "我的角色" }, + "app.skin-site.home.no-players": { "message": "尚未绑定角色。" }, + "app.skin-site.home.loading": { "message": "加载中…" }, + "app.skin-site.home.error": { "message": "加载失败。" }, + "app.skin-site.home.luck": { "message": "幸运值" }, + "app.skin-site.home.luck-unavailable": { "message": "不可用" }, + "app.skin-site.home.signed-out-title": { "message": "未登录" }, + "app.skin-site.home.signed-out-body": { + "message": "登录后可管理你的账号与皮肤。" + }, + "app.skin-site.admin.summary.title": { "message": "系统概况" }, + "app.skin-site.admin.summary.loading": { "message": "加载中…" }, + "app.skin-site.admin.summary.failed": { "message": "无法加载状态。" }, + "app.skin-site.admin.summary.uptime": { "message": "运行时长" }, + "app.skin-site.admin.summary.memory": { "message": "内存占用" }, + "app.skin-site.admin.summary.users": { "message": "用户数量" }, + "app.skin-site.admin.summary.players": { "message": "玩家数量" }, + "app.skin-site.admin.summary.realtime-hint": { + "message": "实时 CPU 与 GC 图表依赖管理端 WebSocket,目前尚未接入。" + }, + "app.skin-site.admin.broadcast.title": { "message": "公告" }, + "app.skin-site.admin.broadcast.loading": { "message": "加载中…" }, + "app.skin-site.admin.broadcast.failed": { "message": "加载失败。" }, + "app.skin-site.admin.broadcast.empty": { "message": "尚未发布过任何公告。" }, + "app.skin-site.admin.broadcast.create": { "message": "发布新公告" }, + "app.skin-site.admin.broadcast.save": { "message": "保存" }, + "app.skin-site.admin.broadcast.cancel": { "message": "取消" }, + "app.skin-site.admin.broadcast.edit": { "message": "编辑" }, + "app.skin-site.admin.broadcast.remove": { "message": "删除" }, + "app.skin-site.admin.broadcast.title-field": { "message": "标题" }, + "app.skin-site.admin.broadcast.subtitle-field": { "message": "副标题" }, + "app.skin-site.admin.broadcast.content-field": { "message": "内容" }, + "app.skin-site.admin.broadcast.expire-at": { "message": "过期时间" }, + "app.skin-site.admin.broadcast.star": { "message": "标星" }, + "app.skin-site.admin.broadcast.level": { "message": "重要程度" }, + "app.skin-site.admin.broadcast.image": { "message": "图片" }, + "app.skin-site.admin.broadcast.remove-image": { "message": "移除图片" }, + "app.skin-site.admin.broadcast.created": { "message": "公告已发布。" }, + "app.skin-site.admin.broadcast.updated": { "message": "公告已更新。" }, + "app.skin-site.admin.broadcast.deleted": { "message": "公告已删除。" }, + "app.skin-site.admin.broadcast.confirm-delete": { + "message": "确定删除「{title}」吗?此操作不可撤销。" + }, + "app.skin-site.admin.broadcast.uploader": { "message": "由 {name} 发布" }, + "app.skin-site.admin.players.title": { "message": "玩家" }, + "app.skin-site.admin.players.loading": { "message": "加载中…" }, + "app.skin-site.admin.players.failed": { "message": "无法加载玩家列表。" }, + "app.skin-site.admin.players.empty": { "message": "没有找到玩家。" }, + "app.skin-site.admin.players.search": { "message": "搜索" }, + "app.skin-site.admin.players.search-name": { "message": "名称" }, + "app.skin-site.admin.players.search-owner": { "message": "所有者" }, + "app.skin-site.admin.players.search-uuid": { "message": "UUID" }, + "app.skin-site.admin.players.total": { "message": "共 {count} 名玩家" }, + "app.skin-site.admin.players.prev": { "message": "上一页" }, + "app.skin-site.admin.players.next": { "message": "下一页" }, + "app.skin-site.admin.players.page": { "message": "第 {page} 页" }, + "app.skin-site.admin.players.name": { "message": "名称" }, + "app.skin-site.admin.players.owner": { "message": "所有者" }, + "app.skin-site.admin.players.source": { "message": "来源" }, + "app.skin-site.admin.players.legacy": { "message": "旧版适配" }, + "app.skin-site.admin.players.actions": { "message": "操作" }, + "app.skin-site.admin.players.edit": { "message": "编辑" }, + "app.skin-site.admin.players.save": { "message": "保存" }, + "app.skin-site.admin.players.cancel": { "message": "取消" }, + "app.skin-site.admin.players.remove": { "message": "删除" }, + "app.skin-site.admin.players.updated": { "message": "玩家已更新。" }, + "app.skin-site.admin.players.deleted": { "message": "玩家已删除。" }, + "app.skin-site.admin.players.confirm-delete": { + "message": "确定删除玩家「{name}」吗?此操作不可撤销。" + }, + "app.skin-site.admin.players.mojang": { "message": "正版" }, + "app.skin-site.admin.players.custom": { "message": "皮肤站" }, + "app.skin-site.admin.users.title": { "message": "用户" }, + "app.skin-site.admin.users.loading": { "message": "加载中…" }, + "app.skin-site.admin.users.failed": { "message": "无法加载用户列表。" }, + "app.skin-site.admin.users.empty": { "message": "没有找到用户。" }, + "app.skin-site.admin.users.search": { "message": "搜索" }, + "app.skin-site.admin.users.search-name": { "message": "用户名" }, + "app.skin-site.admin.users.search-email": { "message": "邮箱" }, + "app.skin-site.admin.users.search-uuid": { "message": "UUID" }, + "app.skin-site.admin.users.total": { "message": "共 {count} 名用户" }, + "app.skin-site.admin.users.prev": { "message": "上一页" }, + "app.skin-site.admin.users.next": { "message": "下一页" }, + "app.skin-site.admin.users.page": { "message": "第 {page} 页" }, + "app.skin-site.admin.users.edit": { "message": "编辑" }, + "app.skin-site.admin.users.save": { "message": "保存" }, + "app.skin-site.admin.users.cancel": { "message": "取消" }, + "app.skin-site.admin.users.remove": { "message": "删除" }, + "app.skin-site.admin.users.players": { "message": "角色" }, + "app.skin-site.admin.users.updated": { "message": "用户已更新。" }, + "app.skin-site.admin.users.deleted": { "message": "用户已删除。" }, + "app.skin-site.admin.users.confirm-delete": { + "message": "确定删除用户「{name}」吗?此操作不可撤销。" + }, + "app.skin-site.admin.users.username": { "message": "用户名" }, + "app.skin-site.admin.users.email": { "message": "邮箱" }, + "app.skin-site.admin.users.qq": { "message": "QQ" }, + "app.skin-site.admin.users.password": { "message": "新密码" }, + "app.skin-site.admin.users.password-hint": { + "message": "留空则保持原密码不变。" + }, + "app.skin-site.admin.users.banned": { "message": "封禁" }, + "app.skin-site.admin.users.permissions": { "message": "权限" }, + "app.skin-site.admin.users.permissions-hint": { + "message": "以逗号分隔,例如 WEB_ADMIN, SERVER_ADMIN。" + }, + "app.skin-site.admin.users.no-players": { "message": "没有绑定的角色。" }, + "app.skin-site.admin.users.registered": { "message": "注册时间" }, + "app.skin-site.admin.review.title": { "message": "玩家审核" }, + "app.skin-site.admin.review.loading": { "message": "加载中…" }, + "app.skin-site.admin.review.failed": { "message": "无法加载申请列表。" }, + "app.skin-site.admin.review.empty": { "message": "没有找到申请。" }, + "app.skin-site.admin.review.total": { "message": "共 {count} 份申请" }, + "app.skin-site.admin.review.filter-all": { "message": "全部" }, + "app.skin-site.admin.review.filter-pending": { "message": "待处理" }, + "app.skin-site.admin.review.filter-passed": { "message": "已通过" }, + "app.skin-site.admin.review.filter-rejected": { "message": "已拒绝" }, + "app.skin-site.admin.review.result-pending": { "message": "待处理" }, + "app.skin-site.admin.review.result-passed": { "message": "已通过" }, + "app.skin-site.admin.review.result-rejected": { "message": "已拒绝" }, + "app.skin-site.admin.review.mode-auto": { "message": "自动" }, + "app.skin-site.admin.review.mode-manual": { "message": "人工" }, + "app.skin-site.admin.review.applicant": { "message": "申请人" }, + "app.skin-site.admin.review.submitted-at": { "message": "提交时间" }, + "app.skin-site.admin.review.score": { "message": "得分" }, + "app.skin-site.admin.review.reviewer": { "message": "审核人" }, + "app.skin-site.admin.review.details": { "message": "详情" }, + "app.skin-site.admin.review.hide": { "message": "收起" }, + "app.skin-site.admin.review.answers": { "message": "作答内容" }, + "app.skin-site.admin.review.no-answers": { "message": "没有作答记录。" }, + "app.skin-site.admin.review.auto-checks": { "message": "自动检查" }, + "app.skin-site.admin.review.context": { "message": "提交环境" }, + "app.skin-site.admin.review.ip": { "message": "IP" }, + "app.skin-site.admin.review.user-agent": { "message": "浏览器标识" }, + "app.skin-site.admin.review.activity": { "message": "行为记录" }, + "app.skin-site.admin.review.duration": { "message": "时长" }, + "app.skin-site.admin.review.hidden-time": { "message": "切出时长" }, + "app.skin-site.admin.review.screen-switches": { "message": "切屏次数" }, + "app.skin-site.admin.review.history": { "message": "审核记录" }, + "app.skin-site.admin.review.accept": { "message": "通过" }, + "app.skin-site.admin.review.reject": { "message": "拒绝" }, + "app.skin-site.admin.review.reason": { "message": "理由" }, + "app.skin-site.admin.review.accept-done": { "message": "申请已通过。" }, + "app.skin-site.admin.review.reject-done": { "message": "申请已拒绝。" }, + "app.skin-site.admin.review.regen-invite": { "message": "重发邀请码" }, + "app.skin-site.admin.review.invite-regenerated": { + "message": "邀请码已重新生成。" + }, + "app.skin-site.admin.review.invite-sent": { "message": "邮件已发送。" }, + "app.skin-site.admin.review.invite-not-sent": { "message": "邮件未发送。" }, + "app.skin-site.admin.review.prev": { "message": "上一页" }, + "app.skin-site.admin.review.next": { "message": "下一页" }, + "app.skin-site.admin.review.page": { "message": "第 {page} 页" }, + "app.skin-site.admin.launcher.title": { "message": "启动器版本" }, + "app.skin-site.admin.launcher.loading": { "message": "加载中…" }, + "app.skin-site.admin.launcher.failed": { "message": "无法加载版本列表。" }, + "app.skin-site.admin.launcher.empty": { "message": "尚未上传任何版本。" }, + "app.skin-site.admin.launcher.latest-url": { "message": "最新版本地址" }, + "app.skin-site.admin.launcher.version": { "message": "版本" }, + "app.skin-site.admin.launcher.channel": { "message": "渠道" }, + "app.skin-site.admin.launcher.uploader": { "message": "上传者" }, + "app.skin-site.admin.launcher.uploaded-at": { "message": "上传时间" }, + "app.skin-site.admin.launcher.published-at": { "message": "发布时间" }, + "app.skin-site.admin.launcher.force-update": { "message": "强制更新" }, + "app.skin-site.admin.launcher.active": { "message": "当前版本" }, + "app.skin-site.admin.launcher.activate": { "message": "设为当前" }, + "app.skin-site.admin.launcher.activated": { "message": "已设为当前版本。" }, + "app.skin-site.admin.launcher.delete": { "message": "删除版本" }, + "app.skin-site.admin.launcher.confirm-delete": { + "message": "确定永久删除启动器 {version} 及服务器上的全部安装文件吗?此版本将无法下载或回滚,已安装的启动器不受影响。" + }, + "app.skin-site.admin.launcher.deleted": { + "message": "已删除该版本及服务器上的安装文件。" + }, + "app.skin-site.admin.launcher.upload": { "message": "上传版本" }, + "app.skin-site.admin.launcher.upload-hint": { + "message": "选择发布包 ZIP(最大 4 GiB)。" + }, + "app.skin-site.admin.launcher.uploading": { "message": "上传中…" }, + "app.skin-site.admin.launcher.upload-done": { "message": "版本已上传。" }, + "app.skin-site.admin.launcher.force-flag": { "message": "强制更新" }, + "app.skin-site.admin.launcher.prev": { "message": "上一页" }, + "app.skin-site.admin.launcher.next": { "message": "下一页" }, + "app.skin-site.admin.launcher.page": { "message": "第 {page} 页" }, + "app.skin-site.admin.launcher.total": { "message": "共 {count} 个版本" }, + "app.skin-site.admin.downloads.title": { "message": "资源下载" }, + "app.skin-site.admin.downloads.loading": { "message": "加载中…" }, + "app.skin-site.admin.downloads.failed": { "message": "无法加载资源列表。" }, + "app.skin-site.admin.downloads.empty": { "message": "没有下载条目。" }, + "app.skin-site.admin.downloads.categories": { "message": "分类" }, + "app.skin-site.admin.downloads.all": { "message": "全部条目" }, + "app.skin-site.admin.downloads.add-category": { "message": "添加" }, + "app.skin-site.admin.downloads.category-name": { "message": "分类名称" }, + "app.skin-site.admin.downloads.remove-category": { "message": "移除" }, + "app.skin-site.admin.downloads.total": { "message": "共 {count} 个条目" }, + "app.skin-site.admin.downloads.add-item": { "message": "新建条目" }, + "app.skin-site.admin.downloads.save": { "message": "保存" }, + "app.skin-site.admin.downloads.cancel": { "message": "取消" }, + "app.skin-site.admin.downloads.edit": { "message": "编辑" }, + "app.skin-site.admin.downloads.remove": { "message": "删除" }, + "app.skin-site.admin.downloads.filename": { "message": "文件名" }, + "app.skin-site.admin.downloads.description": { "message": "描述" }, + "app.skin-site.admin.downloads.routes": { "message": "下载线路" }, + "app.skin-site.admin.downloads.route-name": { "message": "名称" }, + "app.skin-site.admin.downloads.route-url": { "message": "URL" }, + "app.skin-site.admin.downloads.add-route": { "message": "添加线路" }, + "app.skin-site.admin.downloads.remove-route": { "message": "移除" }, + "app.skin-site.admin.downloads.statuses": { "message": "状态" }, + "app.skin-site.admin.downloads.bind-category": { "message": "所属分类" }, + "app.skin-site.admin.downloads.uploader": { "message": "由 {name} 上传" }, + "app.skin-site.admin.downloads.created": { "message": "条目已创建。" }, + "app.skin-site.admin.downloads.updated": { "message": "条目已更新。" }, + "app.skin-site.admin.downloads.deleted": { "message": "条目已删除。" }, + "app.skin-site.admin.downloads.category-added": { "message": "分类已添加。" }, + "app.skin-site.admin.downloads.category-deleted": { + "message": "分类已删除。" + }, + "app.skin-site.admin.downloads.confirm-delete-item": { + "message": "确定删除「{name}」吗?此操作不可撤销。" + }, + "app.skin-site.admin.downloads.confirm-delete-category": { + "message": "确定删除分类「{name}」吗?" + }, + "app.skin-site.admin.servers.title": { "message": "地图服务器" }, + "app.skin-site.admin.servers.loading": { "message": "加载中…" }, + "app.skin-site.admin.servers.failed": { "message": "无法加载服务器列表。" }, + "app.skin-site.admin.servers.empty": { "message": "尚未配置地图服务器。" }, + "app.skin-site.admin.servers.server-name": { "message": "服务器名称" }, + "app.skin-site.admin.servers.internal": { "message": "内部" }, + "app.skin-site.admin.servers.maps": { "message": "地图" }, + "app.skin-site.admin.servers.map-name": { "message": "地图名称" }, + "app.skin-site.admin.servers.map-url": { "message": "地图地址" }, + "app.skin-site.admin.servers.add-map": { "message": "添加地图" }, + "app.skin-site.admin.servers.remove-map": { "message": "移除" }, + "app.skin-site.admin.servers.add-server": { "message": "添加服务器" }, + "app.skin-site.admin.servers.remove-server": { "message": "删除服务器" }, + "app.skin-site.admin.servers.save": { "message": "保存更改" }, + "app.skin-site.admin.servers.saving": { "message": "保存中…" }, + "app.skin-site.admin.servers.saved": { "message": "地图服务器已保存。" }, + "app.skin-site.admin.audit.title": { "message": "登录与认证审计" }, + "app.skin-site.admin.audit.loading": { "message": "加载中…" }, + "app.skin-site.admin.audit.failed": { "message": "无法加载审计日志。" }, + "app.skin-site.admin.audit.empty": { "message": "没有审计记录。" }, + "app.skin-site.admin.audit.subject": { "message": "主体" }, + "app.skin-site.admin.audit.action": { "message": "操作" }, + "app.skin-site.admin.audit.source-ip": { "message": "来源 IP" }, + "app.skin-site.admin.audit.reported-ip": { "message": "上报玩家 IP" }, + "app.skin-site.admin.audit.count": { "message": "次数" }, + "app.skin-site.admin.audit.first-at": { "message": "首次出现" }, + "app.skin-site.admin.audit.last-at": { "message": "最近出现" }, + "app.skin-site.admin.audit.proxy": { "message": "代理" }, + "app.skin-site.admin.audit.internal": { "message": "内部" }, + "app.skin-site.admin.audit.search-subject": { "message": "主体" }, + "app.skin-site.admin.audit.search-ip": { "message": "IP" }, + "app.skin-site.admin.audit.search-action": { "message": "操作" }, + "app.skin-site.admin.audit.search": { "message": "搜索" }, + "app.skin-site.admin.audit.clear": { "message": "清空" }, + "app.skin-site.admin.audit.load-more": { "message": "加载更多" }, + "app.skin-site.admin.audit.retention": { "message": "保留天数" }, + "app.skin-site.admin.audit.record-limit": { "message": "记录上限" }, + "app.skin-site.admin.audit.save-retention": { "message": "保存" }, + "app.skin-site.admin.audit.retention-saved": { + "message": "保留天数已更新。" + }, + "app.skin-site.admin.donations.title": { "message": "捐赠管理" }, + "app.skin-site.admin.donations.loading": { "message": "加载中…" }, + "app.skin-site.admin.donations.failed": { "message": "无法加载捐赠列表。" }, + "app.skin-site.admin.donations.empty": { "message": "暂无捐赠记录。" }, + "app.skin-site.admin.donations.total-amount": { "message": "总额" }, + "app.skin-site.admin.donations.donor-count": { "message": "捐赠人数" }, + "app.skin-site.admin.donations.donor": { "message": "捐赠者" }, + "app.skin-site.admin.donations.amount": { "message": "金额" }, + "app.skin-site.admin.donations.updated-at": { "message": "更新时间" }, + "app.skin-site.admin.donations.external": { "message": "外部" }, + "app.skin-site.admin.donations.linked": { "message": "已绑定" }, + "app.skin-site.admin.donations.create": { "message": "新增捐赠" }, + "app.skin-site.admin.donations.save": { "message": "保存" }, + "app.skin-site.admin.donations.cancel": { "message": "取消" }, + "app.skin-site.admin.donations.edit": { "message": "编辑" }, + "app.skin-site.admin.donations.remove": { "message": "删除" }, + "app.skin-site.admin.donations.amount-field": { "message": "金额" }, + "app.skin-site.admin.donations.display-name": { "message": "显示名称" }, + "app.skin-site.admin.donations.user-uuid": { "message": "用户 UUID" }, + "app.skin-site.admin.donations.qq": { "message": "QQ" }, + "app.skin-site.admin.donations.append-mode": { + "message": "在原有金额上累加" + }, + "app.skin-site.admin.donations.created": { "message": "捐赠记录已创建。" }, + "app.skin-site.admin.donations.updated": { "message": "捐赠记录已更新。" }, + "app.skin-site.admin.donations.deleted": { "message": "捐赠记录已删除。" }, + "app.skin-site.admin.donations.confirm-delete": { + "message": "确定删除「{name}」的捐赠记录吗?此操作不可撤销。" + }, + "app.skin-site.admin.donations.load-more": { "message": "加载更多" }, + "app.skin-site.admin.mods.title": { "message": "Mod 管理" }, + "app.skin-site.admin.mods.tab-mods": { "message": "Mod 文件" }, + "app.skin-site.admin.mods.tab-tags": { "message": "规则标签" }, + "app.skin-site.admin.mods.tab-runtime": { "message": "运行时" }, + "app.skin-site.admin.mods.loading": { "message": "加载中…" }, + "app.skin-site.admin.mods.failed": { "message": "无法加载 Mod 列表。" }, + "app.skin-site.admin.mods.empty": { "message": "没有找到 Mod。" }, + "app.skin-site.admin.mods.total": { "message": "共 {count} 个 Mod" }, + "app.skin-site.admin.mods.search": { "message": "按名称搜索" }, + "app.skin-site.admin.mods.filter-all": { "message": "全部标签" }, + "app.skin-site.admin.mods.prev": { "message": "上一页" }, + "app.skin-site.admin.mods.next": { "message": "下一页" }, + "app.skin-site.admin.mods.page": { "message": "第 {page} 页" }, + "app.skin-site.admin.mods.name": { "message": "名称" }, + "app.skin-site.admin.mods.version": { "message": "版本" }, + "app.skin-site.admin.mods.mod-id": { "message": "Mod ID" }, + "app.skin-site.admin.mods.size": { "message": "大小" }, + "app.skin-site.admin.mods.loaders": { "message": "加载器" }, + "app.skin-site.admin.mods.domain-rules": { "message": "域名规则" }, + "app.skin-site.admin.mods.edit": { "message": "编辑" }, + "app.skin-site.admin.mods.save": { "message": "保存" }, + "app.skin-site.admin.mods.cancel": { "message": "取消" }, + "app.skin-site.admin.mods.remove": { "message": "删除" }, + "app.skin-site.admin.mods.updated": { "message": "Mod 已更新。" }, + "app.skin-site.admin.mods.deleted": { "message": "Mod 已删除。" }, + "app.skin-site.admin.mods.confirm-delete": { + "message": "确定删除 Mod「{name}」吗?此操作不可撤销。" + }, + "app.skin-site.admin.mods.rule-tags": { "message": "规则标签" }, + "app.skin-site.admin.mods.tag-name": { "message": "标签名称" }, + "app.skin-site.admin.mods.tag-rules": { "message": "规则" }, + "app.skin-site.admin.mods.tag-rules-hint": { "message": "每行一条规则。" }, + "app.skin-site.admin.mods.new-tag": { "message": "新建标签" }, + "app.skin-site.admin.mods.tag-created": { "message": "标签已创建。" }, + "app.skin-site.admin.mods.tag-updated": { "message": "标签已更新。" }, + "app.skin-site.admin.mods.tag-deleted": { "message": "标签已删除。" }, + "app.skin-site.admin.mods.confirm-delete-tag": { + "message": "确定删除标签「{name}」吗?" + }, + "app.skin-site.admin.mods.runtime": { "message": "运行时版本" }, + "app.skin-site.admin.mods.manifest-url": { "message": "清单地址" }, + "app.skin-site.admin.mods.upload-runtime": { "message": "上传运行时" }, + "app.skin-site.admin.mods.runtime-version": { "message": "版本" }, + "app.skin-site.admin.mods.uploading": { "message": "上传中…" }, + "app.skin-site.admin.mods.runtime-uploaded": { "message": "运行时已上传。" }, + "app.skin-site.admin.mods.activate": { "message": "设为当前" }, + "app.skin-site.admin.mods.activated": { "message": "运行时已启用。" }, + "app.skin-site.admin.mods.available": { "message": "可用" }, + "app.skin-site.admin.mods.unavailable": { "message": "不可用" }, + "app.skin-site.admin.mods.active": { "message": "当前版本" }, + "app.skin-site.admin.mods.uploader": { "message": "由 {name} 上传" }, + "app.skin-site.home.nav.title": { "message": "皮肤站" }, + "app.skin-site.home.nav.download": { "message": "资源下载" }, + "app.skin-site.home.nav.download-desc": { + "message": "浏览服务器分享的文件。" + }, + "app.skin-site.home.nav.review": { "message": "玩家审核" }, + "app.skin-site.home.nav.review-desc": { "message": "提交并审核玩家申请。" }, + "app.skin-site.home.nav.wiki": { "message": "服务器维基" }, + "app.skin-site.home.nav.wiki-desc": { "message": "服务器的指南与文档。" }, + "app.skin-site.home.nav.bugs": { "message": "问题追踪" }, + "app.skin-site.home.nav.bugs-desc": { "message": "反馈问题并跟踪处理进度。" }, + "app.skin-site.home.nav.map": { "message": "服务器地图" }, + "app.skin-site.home.nav.map-desc": { "message": "探索实时世界地图。" }, + "app.skin-site.home.nav.profile": { "message": "个人资料" }, + "app.skin-site.home.nav.profile-desc": { "message": "管理你的账号与皮肤。" }, + "app.skin-site.admin.wiki.title": { "message": "维基管理" }, + "app.skin-site.admin.wiki.tab-page": { "message": "页面" }, + "app.skin-site.admin.wiki.tab-audit": { "message": "审计日志" }, + "app.skin-site.admin.wiki.tab-settings": { "message": "设置" }, + "app.skin-site.admin.wiki.loading": { "message": "加载中…" }, + "app.skin-site.admin.wiki.page-path": { "message": "页面路径" }, + "app.skin-site.admin.wiki.load-page": { "message": "加载页面" }, + "app.skin-site.admin.wiki.page-not-found": { "message": "未找到该页面。" }, + "app.skin-site.admin.wiki.revision": { "message": "版本" }, + "app.skin-site.admin.wiki.author": { "message": "作者" }, + "app.skin-site.admin.wiki.updated-at": { "message": "更新时间" }, + "app.skin-site.admin.wiki.categories": { "message": "分类" }, + "app.skin-site.admin.wiki.read-policy": { "message": "阅读权限" }, + "app.skin-site.admin.wiki.edit-policy": { "message": "编辑权限" }, + "app.skin-site.admin.wiki.save-protect": { "message": "保存权限" }, + "app.skin-site.admin.wiki.protect-saved": { "message": "页面权限已更新。" }, + "app.skin-site.admin.wiki.set-home": { "message": "设为首页" }, + "app.skin-site.admin.wiki.home-set": { "message": "首页已更新。" }, + "app.skin-site.admin.wiki.set-deleted": { "message": "标记为已删除" }, + "app.skin-site.admin.wiki.set-restored": { "message": "恢复页面" }, + "app.skin-site.admin.wiki.deleted-updated": { + "message": "页面删除状态已更新。" + }, + "app.skin-site.admin.wiki.audit-empty": { "message": "没有审计记录。" }, + "app.skin-site.admin.wiki.audit-target": { "message": "目标" }, + "app.skin-site.admin.wiki.load-more": { "message": "加载更多" }, + "app.skin-site.admin.wiki.settings-hint": { "message": "以逗号分隔域名。" }, + "app.skin-site.admin.wiki.domains": { "message": "域名" }, + "app.skin-site.admin.wiki.home-page": { "message": "首页" }, + "app.skin-site.admin.wiki.default-skin": { "message": "默认皮肤" }, + "app.skin-site.admin.wiki.max-page-bytes": { "message": "页面最大字节数" }, + "app.skin-site.admin.wiki.max-attachment-bytes": { + "message": "附件最大字节数" + }, + "app.skin-site.admin.wiki.save-settings": { "message": "保存设置" }, + "app.skin-site.admin.wiki.settings-saved": { "message": "设置已保存。" }, + "app.skin-site.admin.review.tab-list": { "message": "申请列表" }, + "app.skin-site.admin.review.tab-papers": { "message": "试卷管理" }, + "app.skin-site.admin.review.papers-empty": { "message": "还没有审核试卷。" }, + "app.skin-site.admin.review.new-paper": { "message": "新建试卷" }, + "app.skin-site.admin.review.edit-paper": { "message": "编辑" }, + "app.skin-site.admin.review.paper-title": { "message": "试卷标题" }, + "app.skin-site.admin.review.paper-annotation": { "message": "描述" }, + "app.skin-site.admin.review.paper-enabled": { "message": "启用" }, + "app.skin-site.admin.review.paper-mode": { "message": "阅卷模式" }, + "app.skin-site.admin.review.paper-pass-score": { "message": "通过分数" }, + "app.skin-site.admin.review.paper-target-permissions": { + "message": "通过后获得的身份" + }, + "app.skin-site.admin.review.paper-questions": { "message": "题目" }, + "app.skin-site.admin.review.add-question": { "message": "添加题目" }, + "app.skin-site.admin.review.question-title": { "message": "题目" }, + "app.skin-site.admin.review.question-type": { "message": "题型" }, + "app.skin-site.admin.review.question-score": { "message": "分数" }, + "app.skin-site.admin.review.question-annotation": { "message": "题目注解" }, + "app.skin-site.admin.review.add-option": { "message": "添加选项" }, + "app.skin-site.admin.review.option-description": { "message": "选项文本" }, + "app.skin-site.admin.review.option-correct": { "message": "正确" }, + "app.skin-site.admin.review.remove-question": { "message": "删除" }, + "app.skin-site.admin.review.question-no": { "message": "第 {n} 题" }, + "app.skin-site.admin.review.paper-created": { "message": "试卷已创建。" }, + "app.skin-site.admin.review.paper-saved": { "message": "试卷已保存。" }, + "app.skin-site.admin.review.mail-title": { "message": "通过邮件" }, + "app.skin-site.admin.review.mail-enabled": { + "message": "审核通过后发送邮件" + }, + "app.skin-site.admin.review.mail-subject": { "message": "邮件标题" }, + "app.skin-site.admin.review.mail-message": { "message": "邮件正文" }, + "app.skin-site.admin.review.mail-extra": { "message": "邮件补充说明" }, + "app.skin-site.admin.review.mail-include-invite": { "message": "附带邀请码" }, + "app.skin-site.admin.review.prevent-duplicate": { "message": "禁止重复作答" }, + "app.skin-site.admin.review.copy-link": { "message": "复制直链" }, + "app.skin-site.admin.review.link-copied": { "message": "直链已复制。" }, + "app.skin-site.admin.review.move-up": { "message": "上移" }, + "app.skin-site.admin.review.move-down": { "message": "下移" }, + "app.skin-site.admin.review.mail-subject-required": { + "message": "开启邮件后必须填写邮件标题。" + }, + "app.skin-site.admin.review.mail-message-required": { + "message": "开启邮件后必须填写邮件正文。" + }, + "app.skin-site.admin.users.actions": { "message": "操作" }, + "app.skin-site.admin.users.audit": { "message": "审计" }, + "app.skin-site.admin.users.audit-empty": { "message": "暂无管理审计记录。" }, + "app.skin-site.admin.users.audit-more": { "message": "加载更早记录" }, + "app.skin-site.admin.users.audit-title": { "message": "用户管理审计" }, + "app.skin-site.admin.users.bot": { "message": "机器人" }, + "app.skin-site.admin.users.bot-active": { "message": "Token 有效" }, + "app.skin-site.admin.users.bot-ban": { "message": "封禁 Bot 创建" }, + "app.skin-site.admin.users.bot-creation-banned": { + "message": "禁止创建 Token" + }, + "app.skin-site.admin.users.bot-exists": { "message": "已创建 Bot" }, + "app.skin-site.admin.users.bot-inactive": { "message": "Token 已失效" }, + "app.skin-site.admin.users.bot-invalidate": { "message": "使 Token 失效" }, + "app.skin-site.admin.users.bot-not-exists": { "message": "尚未创建 Bot" }, + "app.skin-site.admin.users.bot-save-username": { + "message": "保存机器人用户名" + }, + "app.skin-site.admin.users.bot-title": { "message": "Bot 管理" }, + "app.skin-site.admin.users.bot-token-hint": { "message": "Token 标识" }, + "app.skin-site.admin.users.bot-unban": { "message": "解除 Bot 封禁" }, + "app.skin-site.admin.users.bot-username": { "message": "机器人用户名" }, + "app.skin-site.admin.users.bound-players-title": { "message": "绑定玩家" }, + "app.skin-site.admin.users.frequency": { "message": "频率限制" }, + "app.skin-site.admin.users.frequency-clear": { "message": "取消限制" }, + "app.skin-site.admin.users.frequency-current": { + "message": "当前 {percent}%" + }, + "app.skin-site.admin.users.frequency-hint": { + "message": "以下列频率对指定用户进行丢包处理,限制其进入服务器的频率。" + }, + "app.skin-site.admin.users.frequency-none": { "message": "当前未启用" }, + "app.skin-site.admin.users.frequency-range": { + "message": "仅允许设置 10% 至 100% 的整数。" + }, + "app.skin-site.admin.users.frequency-save": { "message": "保存限制" }, + "app.skin-site.admin.users.frequency-title": { "message": "频率限制" }, + "app.skin-site.admin.users.invite": { "message": "邀请用户" }, + "app.skin-site.admin.users.invite-copied": { "message": "邀请码已复制。" }, + "app.skin-site.admin.users.invite-copy": { "message": "复制" }, + "app.skin-site.admin.users.invite-email": { "message": "邮箱" }, + "app.skin-site.admin.users.invite-email-invalid": { + "message": "请输入正确格式的邮箱。" + }, + "app.skin-site.admin.users.invite-generate": { "message": "生成邀请码" }, + "app.skin-site.admin.users.invite-title": { "message": "邀请用户" }, + "app.skin-site.admin.users.legacy-adapted": { "message": "已适配旧内服" }, + "app.skin-site.admin.users.registered-at": { "message": "注册时间" }, + "app.skin-site.admin.users.status": { "message": "状态" }, + "app.skin-site.admin.users.status-banned": { "message": "已封禁" }, + "app.skin-site.admin.users.status-normal": { "message": "正常" }, + "app.skin-site.admin.mods.upload": { "message": "上传" }, + "app.skin-site.admin.mods.select-mode": { "message": "选择多个" }, + "app.skin-site.admin.mods.exit-select": { "message": "完成选择" }, + "app.skin-site.admin.mods.select-all": { "message": "全选本页" }, + "app.skin-site.admin.mods.clear-selection": { "message": "取消全选" }, + "app.skin-site.admin.mods.selected-count": { "message": "已选择 {count} 项" }, + "app.skin-site.admin.mods.delete-selected": { "message": "删除所选" }, + "app.skin-site.admin.mods.confirm-delete-multi": { + "message": "确定删除选中的 {count} 个 Mod?此操作不可撤销。" + }, + "app.skin-site.admin.mods.deleted-multi": { "message": "已删除所选 Mod。" }, + "app.skin-site.admin.mods.server-address": { "message": "服务器地址" }, + "app.skin-site.admin.mods.server-address-hint": { + "message": "按服务器地址过滤" + }, + "app.skin-site.admin.mods.apply": { "message": "应用" }, + "app.skin-site.admin.mods.clear": { "message": "清除" }, + "app.skin-site.admin.mods.upload-title": { "message": "上传 Mod" }, + "app.skin-site.admin.mods.upload-drop": { + "message": "拖拽 .jar 文件到此处,或点击选择" + }, + "app.skin-site.admin.mods.upload-sub": { + "message": "支持多文件,单个不超过 {size} MB" + }, + "app.skin-site.admin.mods.upload-tags": { "message": "附加规则标签" }, + "app.skin-site.admin.mods.upload-queue": { "message": "文件列表" }, + "app.skin-site.admin.mods.upload-pending": { "message": "等待中" }, + "app.skin-site.admin.mods.upload-checking": { "message": "检查中…" }, + "app.skin-site.admin.mods.upload-uploading": { "message": "上传中…" }, + "app.skin-site.admin.mods.upload-conflict": { "message": "名称已存在" }, + "app.skin-site.admin.mods.upload-success": { "message": "完成" }, + "app.skin-site.admin.mods.upload-error": { "message": "失败" }, + "app.skin-site.admin.mods.upload-exists": { + "message": "该文件已存在于服务器。" + }, + "app.skin-site.admin.mods.upload-name-conflict": { + "message": "已存在同名 Mod" + }, + "app.skin-site.admin.mods.upload-name-conflict-hint": { + "message": "覆盖已有 Mod,或跳过此文件。" + }, + "app.skin-site.admin.mods.upload-overwrite": { "message": "覆盖" }, + "app.skin-site.admin.mods.upload-skip": { "message": "跳过" }, + "app.skin-site.admin.mods.upload-close": { "message": "关闭" }, + "app.skin-site.admin.mods.upload-all-done": { + "message": "全部文件处理完成。" + }, + "app.skin-site.admin.mods.upload-too-large": { + "message": "文件过大:{name}" + }, + "app.skin-site.chat.avatar.label": { "message": "房间头像" }, + "app.skin-site.chat.avatar.upload": { "message": "上传头像" }, + "app.skin-site.chat.avatar.replace": { "message": "更换头像" }, + "app.skin-site.chat.avatar.remove": { "message": "移除头像" }, + "app.skin-site.chat.avatar.hint": { + "message": "支持 PNG、JPEG、WebP,单边不超过 8192 像素,文件不超过 5 MB。" + }, + "app.skin-site.chat.avatar.bad-format": { + "message": "房间头像仅支持 PNG、JPEG 和 WebP 格式。" + }, + "app.skin-site.chat.avatar.too-large": { + "message": "房间头像大小不能超过 5 MB。" + }, + "app.skin-site.chat.avatar.not-image": { "message": "房间头像必须是图片。" }, + "app.skin-site.chat.admin.title": { "message": "聊天室管理" }, + "app.skin-site.chat.admin.subtitle": { + "message": "创建公开或私有房间,并将日常管理权限交给合适的成员。" + }, + "app.skin-site.chat.admin.create-room": { "message": "创建房间" }, + "app.skin-site.chat.admin.loading": { "message": "加载中…" }, + "app.skin-site.chat.admin.failed": { "message": "无法加载房间列表。" }, + "app.skin-site.chat.admin.empty": { "message": "还没有聊天室。" }, + "app.skin-site.chat.admin.edit": { "message": "编辑" }, + "app.skin-site.chat.admin.remove": { "message": "删除" }, + "app.skin-site.chat.admin.save": { "message": "保存" }, + "app.skin-site.chat.admin.cancel": { "message": "取消" }, + "app.skin-site.chat.admin.name": { "message": "房间名称" }, + "app.skin-site.chat.admin.description": { "message": "房间简介" }, + "app.skin-site.chat.admin.visibility": { "message": "可见性" }, + "app.skin-site.chat.admin.visibility-public": { "message": "公开" }, + "app.skin-site.chat.admin.visibility-private": { "message": "私有" }, + "app.skin-site.chat.admin.kind": { "message": "房间类型" }, + "app.skin-site.chat.admin.kind-standard": { "message": "普通房间" }, + "app.skin-site.chat.admin.kind-settlement": { "message": "聚落房间" }, + "app.skin-site.chat.admin.prerequisite-mode": { "message": "前置条件判定" }, + "app.skin-site.chat.admin.prerequisite-any": { "message": "满足任一" }, + "app.skin-site.chat.admin.prerequisite-all": { "message": "满足全部" }, + "app.skin-site.chat.admin.prerequisite-permissions": { + "message": "所需权限" + }, + "app.skin-site.chat.admin.prerequisite-hint": { + "message": "以逗号分隔;留空表示无限制。" + }, + "app.skin-site.chat.admin.created": { "message": "房间已创建。" }, + "app.skin-site.chat.admin.updated": { "message": "房间资料已更新。" }, + "app.skin-site.chat.admin.deleted": { "message": "房间已删除。" }, + "app.skin-site.chat.admin.confirm-delete": { + "message": "确认永久删除房间“{name}”及其中全部消息吗?" + }, + "app.skin-site.chat.admin.manager-badge": { "message": "管理" }, + "app.skin-site.chat.admin.voice-badge": { "message": "语音" }, + "app.skin-site.chat.user-picker.label": { "message": "选择用户" }, + "app.skin-site.chat.user-picker.placeholder": { + "message": "搜索用户名、邮箱或账号 ID" + }, + "app.skin-site.chat.user-picker.by-user": { "message": "按用户信息" }, + "app.skin-site.chat.user-picker.by-player": { "message": "按玩家 ID" }, + "app.skin-site.chat.user-picker.hint": { + "message": "支持按用户名、邮箱模糊搜索,也可输入账号 ID 搜索。" + }, + "app.skin-site.chat.user-picker.player-hint": { + "message": "输入玩家名称,查找绑定该玩家 ID 的用户。" + }, + "app.skin-site.chat.user-picker.empty": { "message": "没有找到匹配的用户" }, + "app.skin-site.chat.user-picker.banned": { + "message": "该账号已被封禁,不能执行此操作。" + }, + "app.skin-site.chat.user-picker.guest": { + "message": "游客不能成为房管、聚落主或聚落成员。" + }, + "app.skin-site.chat.user-picker.already-in": { + "message": "该用户已经在当前房间中。" + }, + "app.skin-site.chat.user-picker.not-allowed": { + "message": "该用户不在当前允许选择的范围内" + }, + "app.skin-site.chat.user-picker.select": { "message": "选择此用户" }, + "app.skin-site.chat.user-picker.selected": { "message": "已选择此用户" }, + "app.skin-site.chat.user-picker.id": { "message": "ID" }, + "app.skin-site.chat.admin.managers": { "message": "房管" }, + "app.skin-site.chat.admin.manager-title": { "message": "任命房管" }, + "app.skin-site.chat.admin.manager-hint": { + "message": "房管可以管理该房间的成员、消息与文件。" + }, + "app.skin-site.chat.admin.grant": { "message": "任命" }, + "app.skin-site.chat.admin.revoke": { "message": "撤销" }, + "app.skin-site.chat.admin.manager-granted": { "message": "已任命房管。" }, + "app.skin-site.chat.admin.manager-revoked": { "message": "已撤销房管。" }, + "app.skin-site.chat.admin.owner-title": { "message": "聚落主" }, + "app.skin-site.chat.admin.owner-hint": { + "message": "为该房间任命首任聚落主。" + }, + "app.skin-site.chat.admin.owner-assigned": { "message": "已任命聚落主。" }, + "app.skin-site.chat.admin.owner-current": { "message": "当前聚落主:{name}" }, + "app.skin-site.chat.admin.owner-none": { "message": "尚未设置聚落主。" }, + "app.skin-site.chat.admin.audit": { "message": "审计" }, + "app.skin-site.chat.admin.audit-title": { "message": "房间审计" }, + "app.skin-site.chat.admin.audit-empty": { "message": "暂无审计记录。" }, + "app.skin-site.chat.admin.audit-target": { "message": "对象:{name}" }, + "app.skin-site.chat.admin.close": { "message": "关闭" }, + "app.skin-site.chat.voice-runtime-title": { "message": "实时语音库" }, + "app.skin-site.chat.voice-logs": { "message": "查看日志" }, + "app.skin-site.chat.voice-config": { "message": "配置语音库" }, + "app.skin-site.chat.voice-retry": { "message": "重新部署" }, + "app.skin-site.chat.voice-config-title": { "message": "语音库配置" }, + "app.skin-site.chat.voice-logs-title": { "message": "LiveKit 日志" }, + "app.skin-site.chat.voice-capacity-title": { "message": "语音容量" }, + "app.skin-site.chat.voice-capacity": { "message": "语音容量" }, + "app.skin-site.chat.participant-limit": { "message": "参与人数上限" }, + "app.skin-site.chat.listener-limit": { "message": "旁听人数上限" }, + "app.skin-site.chat.voice-capacity-updated": { + "message": "语音容量已更新。" + }, + "app.skin-site.chat.voice-enabled": { "message": "启用实时语音" }, + "app.skin-site.chat.voice-runtime-path": { "message": "语音库目录" }, + "app.skin-site.chat.voice-mirror": { "message": "镜像基础地址" }, + "app.skin-site.chat.voice-public-url": { "message": "公网访问地址" }, + "app.skin-site.chat.voice-bind": { "message": "监听地址" }, + "app.skin-site.chat.voice-signal-port": { "message": "信令端口" }, + "app.skin-site.chat.voice-rtc-tcp-port": { "message": "媒体 TCP 端口" }, + "app.skin-site.chat.voice-rtc-udp-port": { "message": "媒体 UDP 端口" }, + "app.skin-site.chat.voice-startup-timeout": { + "message": "启动等待时间(秒)" + }, + "app.skin-site.chat.voice-use-external-ip": { "message": "使用外部 IP" }, + "app.skin-site.chat.voice-node-ip": { "message": "节点 IP" }, + "app.skin-site.chat.voice-saved": { "message": "语音库配置已保存。" }, + "app.skin-site.chat.voice-logs-auto-refresh": { "message": "自动刷新" }, + "app.skin-site.chat.voice-logs-refresh": { "message": "刷新" }, + "app.skin-site.chat.voice-logs-empty": { "message": "暂无日志。" }, + "app.skin-site.chat.admin.voice-runtime-title": { "message": "实时语音库" }, + "app.skin-site.chat.admin.voice-logs": { "message": "查看日志" }, + "app.skin-site.chat.admin.voice-config": { "message": "配置语音库" }, + "app.skin-site.chat.admin.voice-retry": { "message": "重新部署" }, + "app.skin-site.chat.admin.voice-config-title": { "message": "语音库配置" }, + "app.skin-site.chat.admin.voice-logs-title": { "message": "LiveKit 日志" }, + "app.skin-site.chat.admin.voice-capacity-title": { "message": "语音容量" }, + "app.skin-site.chat.admin.voice-capacity": { "message": "语音容量" }, + "app.skin-site.chat.admin.participant-limit": { "message": "参与人数上限" }, + "app.skin-site.chat.admin.listener-limit": { "message": "旁听人数上限" }, + "app.skin-site.chat.admin.voice-capacity-updated": { + "message": "语音容量已更新。" + }, + "app.skin-site.chat.admin.voice-enabled": { "message": "启用实时语音" }, + "app.skin-site.chat.admin.voice-runtime-path": { "message": "语音库目录" }, + "app.skin-site.chat.admin.voice-mirror": { "message": "镜像基础地址" }, + "app.skin-site.chat.admin.voice-public-url": { "message": "公网访问地址" }, + "app.skin-site.chat.admin.voice-bind": { "message": "监听地址" }, + "app.skin-site.chat.admin.voice-signal-port": { "message": "信令端口" }, + "app.skin-site.chat.admin.voice-rtc-tcp-port": { "message": "媒体 TCP 端口" }, + "app.skin-site.chat.admin.voice-rtc-udp-port": { "message": "媒体 UDP 端口" }, + "app.skin-site.chat.admin.voice-startup-timeout": { + "message": "启动等待时间(秒)" + }, + "app.skin-site.chat.admin.voice-use-external-ip": { + "message": "使用外部 IP" + }, + "app.skin-site.chat.admin.voice-node-ip": { "message": "节点 IP" }, + "app.skin-site.chat.admin.voice-saved": { "message": "语音库配置已保存。" }, + "app.skin-site.chat.admin.voice-logs-auto-refresh": { "message": "自动刷新" }, + "app.skin-site.chat.admin.voice-logs-refresh": { "message": "刷新" }, + "app.skin-site.chat.admin.voice-logs-empty": { "message": "暂无日志。" }, + "app.skin-site.admin.wiki.tab-migration": { "message": "迁移中心" }, + "app.skin-site.admin.wiki.migration-title": { "message": "MediaWiki 迁移" }, + "app.skin-site.admin.wiki.migration-hint": { + "message": "迁移内容会先进入不可见暂存区,所有页面完成导入或排除审核后才能整批发布。" + }, + "app.skin-site.admin.wiki.auto-title": { + "message": "从 MediaWiki API 自动读取" + }, + "app.skin-site.admin.wiki.api-url": { "message": "api.php 地址" }, + "app.skin-site.admin.wiki.bot-username": { "message": "Bot 用户名(选填)" }, + "app.skin-site.admin.wiki.bot-password": { "message": "Bot 密码(选填)" }, + "app.skin-site.admin.wiki.credentials-hint": { + "message": "凭据只存在于本次后台任务的内存中,携带凭据时必须使用 HTTPS。" + }, + "app.skin-site.admin.wiki.allow-private": { + "message": "明确允许访问内网来源" + }, + "app.skin-site.admin.wiki.allow-private-hint": { + "message": "内网来源可能访问皮肤站所在网络中的服务,请只对可信地址启用。" + }, + "app.skin-site.admin.wiki.start-auto": { "message": "创建自动迁移任务" }, + "app.skin-site.admin.wiki.xml-title": { "message": "导入 MediaWiki XML" }, + "app.skin-site.admin.wiki.xml-file": { "message": "导出文件" }, + "app.skin-site.admin.wiki.start-xml": { "message": "上传并建立暂存任务" }, + "app.skin-site.admin.wiki.stale-rules": { "message": "疑似过时页面筛选规则" }, + "app.skin-site.admin.wiki.stale-days": { "message": "未更新天数" }, + "app.skin-site.admin.wiki.maintainer-window": { "message": "维护者统计天数" }, + "app.skin-site.admin.wiki.max-maintainers": { "message": "维护者人数不超过" }, + "app.skin-site.admin.wiki.stale-markers": { + "message": "过时分类、模板或文字标记" + }, + "app.skin-site.admin.wiki.stale-markers-hint": { "message": "使用逗号分隔" }, + "app.skin-site.admin.wiki.jobs": { "message": "迁移任务" }, + "app.skin-site.admin.wiki.refresh-jobs": { "message": "刷新" }, + "app.skin-site.admin.wiki.jobs-empty": { "message": "还没有迁移任务。" }, + "app.skin-site.admin.wiki.reviewed-count": { + "message": "已审核 {reviewed} / {total}" + }, + "app.skin-site.admin.wiki.imported-excluded": { + "message": "导入 {imported} · 排除 {excluded}" + }, + "app.skin-site.admin.wiki.view-job": { "message": "查看任务" }, + "app.skin-site.admin.wiki.delete-job": { "message": "删除迁移记录" }, + "app.skin-site.admin.wiki.confirm-delete-job": { + "message": "确认删除迁移任务 #{id}?此操作不可恢复。" + }, + "app.skin-site.admin.wiki.candidates": { "message": "候选页面" }, + "app.skin-site.admin.wiki.candidates-empty": { + "message": "选择任务后查看其页面。" + }, + "app.skin-site.admin.wiki.last-updated": { "message": "更新于 {date}" }, + "app.skin-site.admin.wiki.maintainer-count": { + "message": "{count} 位维护者" + }, + "app.skin-site.admin.wiki.conflict": { "message": "标题冲突" }, + "app.skin-site.admin.wiki.target-title": { "message": "目标标题" }, + "app.skin-site.admin.wiki.overwrite": { "message": "覆盖" }, + "app.skin-site.admin.wiki.import": { "message": "导入" }, + "app.skin-site.admin.wiki.exclude": { "message": "排除" }, + "app.skin-site.admin.wiki.publish": { "message": "整批发布" }, + "app.skin-site.admin.wiki.rollback": { "message": "回滚" }, + "app.skin-site.admin.wiki.confirm-rollback": { + "message": "确认回滚本批迁移?已发布的页面将被还原。" + }, + "app.skin-site.admin.wiki.state-importing": { "message": "正在读取" }, + "app.skin-site.admin.wiki.state-review": { "message": "等待审核" }, + "app.skin-site.admin.wiki.state-publishing": { "message": "正在发布" }, + "app.skin-site.admin.wiki.state-published": { "message": "已发布" }, + "app.skin-site.admin.wiki.state-failed": { "message": "失败" }, + "app.skin-site.admin.wiki.state-rolled-back": { "message": "已回滚" }, + "app.skin-site.admin.wiki.decision-pending": { "message": "待审核" }, + "app.skin-site.admin.wiki.decision-import": { "message": "导入" }, + "app.skin-site.admin.wiki.decision-exclude": { "message": "排除" }, + "app.skin-site.admin.wiki.migration-started": { + "message": "迁移任务已创建。" + }, + "app.skin-site.admin.wiki.xml-staged": { + "message": "XML 已解析并进入逐页审核阶段。" + }, + "app.skin-site.admin.wiki.published": { + "message": "已发布 {imported} 个页面,覆盖 {overwritten} 个。" + }, + "app.skin-site.admin.wiki.rolled-back": { "message": "迁移批次已安全回滚。" }, + "app.skin-site.admin.wiki.job-deleted": { "message": "迁移记录已删除。" }, + "app.skin-site.admin.wiki.select-xml": { + "message": "请先选择 MediaWiki XML 文件。" + }, + "app.skin-site.wiki.title": { "message": "StarLight 维基" }, + "app.skin-site.wiki.search-placeholder": { "message": "输入页面标题" }, + "app.skin-site.wiki.open": { "message": "打开" }, + "app.skin-site.wiki.loading": { "message": "加载中…" }, + "app.skin-site.wiki.not-found": { "message": "页面不存在。" }, + "app.skin-site.wiki.empty": { "message": "在上方输入页面标题开始阅读。" }, + "app.skin-site.wiki.updated-at": { + "message": "最后编辑于 {date},编辑者 {author}" + }, + "app.skin-site.wiki.revision": { "message": "修订 #{id}" }, + "app.skin-site.wiki.categories": { "message": "分类" }, + "app.skin-site.wiki.back": { "message": "返回" }, + "app.skin-site.home.donation.thanks": { + "message": "感谢每一位支持 StarLight 运行的朋友。" + }, + "app.skin-site.home.donation.empty": { "message": "暂无捐赠记录。" }, + "app.skin-site.home.donation.list-failed": { "message": "无法加载捐赠记录。" }, + "app.skin-site.home.donation.more": { "message": "加载更多" }, + "app.skin-site.home.preview.players": { "message": "玩家" }, + "app.skin-site.home.preview.empty": { "message": "暂无玩家" }, + "app.skin-site.home.preview.empty-hint": { + "message": "登录或在侧栏添加 Minecraft 账号,即可在这里预览皮肤。" + }, + "app.skin-site.home.preview.unavailable": { "message": "此玩家没有可预览的皮肤。" }, + "app.skin-site.home.preview.loading": { "message": "正在加载玩家…" }, + "app.skin-site.home.preview.failed": { "message": "无法加载皮肤站玩家。" } } diff --git a/apps/app-frontend/src/providers/app-update.ts b/apps/app-frontend/src/providers/app-update.ts index dc0afe6..073bc3d 100644 --- a/apps/app-frontend/src/providers/app-update.ts +++ b/apps/app-frontend/src/providers/app-update.ts @@ -10,6 +10,7 @@ export interface AppUpdate { currentVersion?: string publishedAt?: string forceUpdate?: boolean + rollback?: boolean } interface UpdatePromptState { diff --git a/apps/app-frontend/src/store/theme.test.ts b/apps/app-frontend/src/store/theme.test.ts index 6a2549d..856180b 100644 --- a/apps/app-frontend/src/store/theme.test.ts +++ b/apps/app-frontend/src/store/theme.test.ts @@ -1,7 +1,17 @@ import assert from 'node:assert/strict' +import { registerHooks } from 'node:module' import test from 'node:test' -import { applySystemAccentHue, DEFAULT_CUSTOM_ACCENT_COLOR, hexToHsl } from './theme.ts' +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + if (specifier === '@/helpers/font-family.ts') { + return nextResolve(new URL('../helpers/font-family.ts', import.meta.url).href, context) + } + return nextResolve(specifier, context) + }, +}) +const { applySystemAccentHue, DEFAULT_CUSTOM_ACCENT_COLOR, hexToHsl } = await import('./theme.ts') +hooks.deregister() test('applies the system hue with the custom accent saturation and lightness', () => { const system = hexToHsl('#0078d4') diff --git a/apps/app/Cargo.toml b/apps/app/Cargo.toml index c17cdde..2971523 100644 --- a/apps/app/Cargo.toml +++ b/apps/app/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "theseus_gui" # The actual version is set by the theseus-build workflow on tagging -version = "1.0.2-beta11" +version = "1.0.2-beta13" edition.workspace = true description = "Axolotl Launcher is a cross-platform Minecraft launcher" homepage = "https://www.ghs.red" diff --git a/apps/app/src/main.rs b/apps/app/src/main.rs index 4510a65..cb70414 100644 --- a/apps/app/src/main.rs +++ b/apps/app/src/main.rs @@ -43,6 +43,8 @@ struct UpdatePreferences { #[cfg(target_os = "macos")] mod macos; +#[cfg(feature = "updater")] +mod update_policy; #[cfg(feature = "updater")] mod updater_impl; #[cfg(not(feature = "updater"))] @@ -1024,7 +1026,8 @@ fn main() { s.restart_after_pending_update.load(Ordering::Relaxed) }) .unwrap_or(false); - if let Some((update, data)) = &*update_data.0.lock().unwrap() + if let Some((update, data)) = + &update_data.0.lock().unwrap().pending { fn set_changelog_toast(version: Option) { let toast_result: theseus::Result<()> = tauri::async_runtime::block_on(async move { diff --git a/apps/app/src/update_policy.rs b/apps/app/src/update_policy.rs new file mode 100644 index 0000000..5b0b52d --- /dev/null +++ b/apps/app/src/update_policy.rs @@ -0,0 +1,227 @@ +use semver::Version; + +pub fn requires_update(current: &Version, target: &Version) -> bool { + current != target +} + +pub fn is_rollback(current: &Version, target: &Version) -> bool { + requires_update(current, target) && !is_remote_newer(current, target) +} + +pub struct UpdateTarget { + target: Option, + check_revision: u64, + pub pending: Option, +} + +impl Default for UpdateTarget { + fn default() -> Self { + Self { + target: None, + check_revision: 0, + pending: None, + } + } +} + +impl UpdateTarget { + pub fn begin_check(&mut self) -> u64 { + self.check_revision = self.check_revision.wrapping_add(1); + self.check_revision + } + + pub fn select_checked( + &mut self, + revision: u64, + version: Option<&str>, + ) -> bool { + if revision != self.check_revision { + return false; + } + self.select(version); + true + } + + pub fn select(&mut self, version: Option<&str>) { + if self.target.as_deref() != version { + self.target = version.map(str::to_owned); + self.pending = None; + } + } + + pub fn is_selected(&self, version: &str) -> bool { + self.target.as_deref() == Some(version) + } + + pub fn enqueue(&mut self, version: &str, download: T) -> bool { + if !self.is_selected(version) { + return false; + } + self.pending = Some(download); + true + } +} + +// semver compares prerelease identifiers lexically, so "beta10" < "beta9" +// (because the character '1' sorts before '9'). Our release names use a +// "betaN" scheme where N is a decimal counter, so a strict lexical compare +// would wrongly report an older beta as the latest. Use a comparator that +// treats the trailing digits of a prerelease identifier numerically. +fn is_remote_newer(current: &Version, remote: &Version) -> bool { + use std::cmp::Ordering; + + let core = (remote.major, remote.minor, remote.patch).cmp(&( + current.major, + current.minor, + current.patch, + )); + if core != Ordering::Equal { + return core == Ordering::Greater; + } + + // Same x.y.z. A final release outranks any prerelease of that version. + match (current.pre.is_empty(), remote.pre.is_empty()) { + (true, true) => false, + (true, false) => false, + (false, true) => true, + (false, false) => { + compare_prerelease(remote.pre.as_str(), current.pre.as_str()) + == Ordering::Greater + } + } +} + +/// Split a prerelease identifier into its non-digit prefix and an optional +/// trailing decimal number (so "beta10" -> ("beta", Some(10))). +fn split_prerelease_identifier(segment: &str) -> (&str, Option) { + let digit_start = segment + .char_indices() + .find(|(_, c)| c.is_ascii_digit()) + .map(|(i, _)| i); + match digit_start { + Some(i) => (&segment[..i], segment[i..].parse::().ok()), + None => (segment, None), + } +} + +/// Compare two prerelease strings, treating a trailing run of ASCII digits +/// as a decimal number (so "beta10" > "beta9"). All other segments fall back +/// to a plain lexical comparison. +fn compare_prerelease(left: &str, right: &str) -> std::cmp::Ordering { + use std::cmp::Ordering; + + let left_segments: Vec<&str> = left.split('.').collect(); + let right_segments: Vec<&str> = right.split('.').collect(); + + for (l, r) in left_segments.iter().zip(right_segments.iter()) { + let (l_prefix, l_num) = split_prerelease_identifier(l); + let (r_prefix, r_num) = split_prerelease_identifier(r); + + match (l_num, r_num) { + (Some(ln), Some(rn)) if l_prefix == r_prefix => match ln.cmp(&rn) { + Ordering::Equal => continue, + other => return other, + }, + _ => { + let prefix_cmp = l_prefix.cmp(r_prefix); + if prefix_cmp != Ordering::Equal { + return prefix_cmp; + } + let num_cmp = l_num.cmp(&r_num); + if num_cmp != Ordering::Equal { + return num_cmp; + } + } + } + } + + left_segments.len().cmp(&right_segments.len()) +} + +#[cfg(test)] +mod tests { + use super::*; + use semver::Version; + + fn version(value: &str) -> Version { + Version::parse(value).unwrap() + } + + #[test] + fn follows_the_server_target_in_both_directions() { + for (current, target) in [ + ("1.0.2-beta12", "1.0.2-beta9"), + ("1.0.2-beta9", "1.0.2-beta12"), + ("1.2.0", "1.1.0"), + ("1.1.0", "1.2.0"), + ("1.1.0", "1.1.0-beta1"), + ] { + assert!(requires_update(&version(current), &version(target))); + } + assert!(!requires_update( + &version("1.0.2-beta12"), + &version("1.0.2-beta12") + )); + } + + #[test] + fn rollback_direction_uses_numeric_beta_suffixes() { + assert!(is_rollback( + &version("1.0.2-beta12"), + &version("1.0.2-beta9") + )); + assert!(!is_rollback( + &version("1.0.2-beta9"), + &version("1.0.2-beta12") + )); + assert!(is_rollback(&version("1.2.0"), &version("1.1.0"))); + assert!(!is_rollback(&version("1.1.0"), &version("1.2.0"))); + assert!(!is_rollback(&version("1.2.0"), &version("1.2.0"))); + } + + #[test] + fn changing_the_target_discards_an_already_downloaded_update() { + let mut state = UpdateTarget::default(); + state.select(Some("1.0.2-beta12")); + assert!(state.enqueue("1.0.2-beta12", "new installer")); + state.select(Some("1.0.2-beta9")); + assert!(state.pending.is_none()); + assert!(state.enqueue("1.0.2-beta9", "rollback installer")); + assert_eq!(state.pending, Some("rollback installer")); + } + + #[test] + fn a_stale_download_cannot_replace_the_selected_rollback() { + let mut state = UpdateTarget::default(); + state.select(Some("1.0.2-beta12")); + state.select(Some("1.0.2-beta9")); + assert!(state.enqueue("1.0.2-beta9", "rollback installer")); + assert!(!state.enqueue("1.0.2-beta12", "late installer")); + assert_eq!(state.pending, Some("rollback installer")); + } + + #[test] + fn late_checks_cannot_reauthorize_a_superseded_version() { + let mut state = UpdateTarget::default(); + let old_check = state.begin_check(); + let rollback_check = state.begin_check(); + assert!(state.select_checked(rollback_check, Some("1.0.2-beta9"))); + assert!(state.enqueue("1.0.2-beta9", "rollback installer")); + assert!(!state.select_checked(old_check, Some("1.0.2-beta12"))); + assert!(!state.enqueue("1.0.2-beta12", "late installer")); + assert_eq!(state.pending, Some("rollback installer")); + } + + #[test] + fn repeated_checks_preserve_the_matching_download_and_no_update_clears_it() + { + let mut state = UpdateTarget::default(); + state.select(Some("1.0.2-beta9")); + state.enqueue("1.0.2-beta9", "rollback installer"); + state.select(Some("1.0.2-beta9")); + assert_eq!(state.pending, Some("rollback installer")); + state.select(None); + assert!(state.pending.is_none()); + assert!(!state.enqueue("1.0.2-beta9", "late installer")); + } +} diff --git a/apps/app/src/updater_impl.rs b/apps/app/src/updater_impl.rs index 3817ee6..7159e61 100644 --- a/apps/app/src/updater_impl.rs +++ b/apps/app/src/updater_impl.rs @@ -1,4 +1,5 @@ use crate::api::Result; +use crate::update_policy::{UpdateTarget, is_rollback, requires_update}; use futures::StreamExt; use semver::Version; use serde::{Deserialize, Serialize}; @@ -27,82 +28,6 @@ const STARLIGHT_UPDATE_BASE_URL: &str = "https://skin.starlight.cool/"; const UPDATE_DOWNLOAD_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(15 * 60); -// semver compares prerelease identifiers lexically, so "beta10" < "beta9" -// (because the character '1' sorts before '9'). Our release names use a -// "betaN" scheme where N is a decimal counter, so a strict lexical compare -// would wrongly report an older beta as the latest. Use a comparator that -// treats the trailing digits of a prerelease identifier numerically. -fn is_remote_newer(current: &Version, remote: &Version) -> bool { - use std::cmp::Ordering; - - let core = (remote.major, remote.minor, remote.patch).cmp(&( - current.major, - current.minor, - current.patch, - )); - if core != Ordering::Equal { - return core == Ordering::Greater; - } - - // Same x.y.z. A final release outranks any prerelease of that version. - match (current.pre.is_empty(), remote.pre.is_empty()) { - (true, true) => false, - (true, false) => false, - (false, true) => true, - (false, false) => { - compare_prerelease(remote.pre.as_str(), current.pre.as_str()) - == Ordering::Greater - } - } -} - -/// Split a prerelease identifier into its non-digit prefix and an optional -/// trailing decimal number (so "beta10" -> ("beta", Some(10))). -fn split_prerelease_identifier(segment: &str) -> (&str, Option) { - let digit_start = segment - .char_indices() - .find(|(_, c)| c.is_ascii_digit()) - .map(|(i, _)| i); - match digit_start { - Some(i) => (&segment[..i], segment[i..].parse::().ok()), - None => (segment, None), - } -} - -/// Compare two prerelease strings, treating a trailing run of ASCII digits -/// as a decimal number (so "beta10" > "beta9"). All other segments fall back -/// to a plain lexical comparison. -fn compare_prerelease(left: &str, right: &str) -> std::cmp::Ordering { - use std::cmp::Ordering; - - let left_segments: Vec<&str> = left.split('.').collect(); - let right_segments: Vec<&str> = right.split('.').collect(); - - for (l, r) in left_segments.iter().zip(right_segments.iter()) { - let (l_prefix, l_num) = split_prerelease_identifier(l); - let (r_prefix, r_num) = split_prerelease_identifier(r); - - match (l_num, r_num) { - (Some(ln), Some(rn)) if l_prefix == r_prefix => match ln.cmp(&rn) { - Ordering::Equal => continue, - other => return other, - }, - _ => { - let prefix_cmp = l_prefix.cmp(r_prefix); - if prefix_cmp != Ordering::Equal { - return prefix_cmp; - } - let num_cmp = l_num.cmp(&r_num); - if num_cmp != Ordering::Equal { - return num_cmp; - } - } - } - } - - left_segments.len().cmp(&right_segments.len()) -} - // ── Shared types ───────────────────────────────────────────────── #[derive(Serialize)] @@ -115,11 +40,12 @@ pub struct UpdateMetadata { body: Option, published_at: Option, force_update: bool, + rollback: bool, raw_json: serde_json::Value, } #[derive(Default)] -pub struct PendingUpdateData(pub Mutex, Vec)>>); +pub struct PendingUpdateData(pub Mutex, Vec)>>); // ── Update Server API types ───────────────────────────────────── @@ -307,7 +233,7 @@ async fn check_with_endpoints( .header("X-Axolotl-Platform", platform)? .header("X-Axolotl-Version", current_version)? .version_comparator(|current, release| { - is_remote_newer(¤t, &release.version) + requires_update(¤t, &release.version) }); #[cfg(target_os = "windows")] @@ -345,7 +271,20 @@ async fn check_with_updater( webview: &Webview, channel: &str, ) -> Result> { - let Some(mut update) = check_with_endpoints(webview, channel).await? else { + let pending_data = webview.state::(); + let revision = pending_data.0.lock().unwrap().begin_check(); + let checked = check_with_endpoints(webview, channel).await?; + if !pending_data.0.lock().unwrap().select_checked( + revision, + checked.as_ref().map(|update| update.version.as_str()), + ) { + return Err(theseus::Error::from(theseus::ErrorKind::OtherError( + "A newer launcher update check superseded this response" + .to_string(), + )) + .into()); + } + let Some(mut update) = checked else { return Ok(None); }; update.timeout = Some(UPDATE_DOWNLOAD_TIMEOUT); @@ -369,6 +308,10 @@ async fn check_with_updater( .and_then(serde_json::Value::as_bool) .unwrap_or(false); let metadata = UpdateMetadata { + rollback: is_rollback( + &Version::parse(&update.current_version).map_err(Error::from)?, + &Version::parse(&update.version).map_err(Error::from)?, + ), rid: webview.resources_table().add(update.clone()), current_version: update.current_version.clone(), version: update.version.clone(), @@ -449,6 +392,12 @@ pub async fn enqueue_update_for_installation( let update = webview.resources_table().get::(rid)?; + if !pending_data.0.lock().unwrap().is_selected(&update.version) { + return Err(theseus::Error::from(theseus::ErrorKind::OtherError( + "The server-selected launcher version changed; check for updates again".to_string(), + )).into()); + } + let progress = init_loading( LoadingBarType::LauncherUpdate { version: update.version.clone(), @@ -565,11 +514,19 @@ pub async fn enqueue_update_for_installation( let download_duration = download_start.elapsed(); tracing::info!("Downloaded update in {download_duration:?}"); - pending_data + let version = update.version.clone(); + if !pending_data .0 .lock() .unwrap() - .replace((update, update_data)); + .enqueue(&version, (update, update_data)) + { + return Err(theseus::Error::from(theseus::ErrorKind::OtherError( + "The server-selected launcher version changed during download" + .to_string(), + )) + .into()); + } Ok(()) } @@ -577,7 +534,9 @@ pub async fn enqueue_update_for_installation( #[tauri::command] pub fn remove_enqueued_update(webview: Webview) { let pending_data = webview.state::().inner(); - pending_data.0.lock().unwrap().take(); + let mut pending = pending_data.0.lock().unwrap(); + pending.begin_check(); + pending.select(None); } // ── Debian / derivatives apt update ───────────────────────────── @@ -630,6 +589,7 @@ pub async fn install_apt_package(version: &str, data: &[u8]) -> Result<()> { .arg("apt") .arg("install") .arg("-y") + .arg("--allow-downgrades") .arg(&install_path) .output() }) diff --git a/apps/app/tauri.conf.json b/apps/app/tauri.conf.json index 99b6e43..f5ec734 100644 --- a/apps/app/tauri.conf.json +++ b/apps/app/tauri.conf.json @@ -21,6 +21,7 @@ "icons/AxolotlAssets.car" ], "windows": { + "allowDowngrades": true, "nsis": { "installMode": "currentUser", "installerHooks": "./nsis/hooks.nsi" diff --git a/packages/app-lib/Cargo.toml b/packages/app-lib/Cargo.toml index 663be6d..3c9bfc5 100644 --- a/packages/app-lib/Cargo.toml +++ b/packages/app-lib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "theseus" # The actual version is set by the theseus-build workflow on tagging -version = "1.0.2-beta11" +version = "1.0.2-beta13" edition.workspace = true [dependencies] diff --git a/scripts/axolotl/create-update-manifest.test.mjs b/scripts/axolotl/create-update-manifest.test.mjs index 3344859..14ade90 100644 --- a/scripts/axolotl/create-update-manifest.test.mjs +++ b/scripts/axolotl/create-update-manifest.test.mjs @@ -49,7 +49,11 @@ try { tag, outputPath, ], - { cwd: root, encoding: 'utf8' }, + { + cwd: root, + encoding: 'utf8', + env: { ...process.env, GITHUB_REPOSITORY: 'Mystic-Stars/Axolotl' }, + }, ) assert.equal(create.status, 0, create.stderr)