feat(web-panel): multi-locale i18n with selector + browser autodetect

- Add 6 locales (en-US source + ru-RU, de-DE, fr-FR, es-ES, zh-CN)
  matching the patcher's WPF UI; full .po catalogs incl. plural forms.
- Language selector in the left settings drawer; persist choice and
  auto-detect from navigator language on first load.
- Load .po directly via @lingui/vite-plugin (drop the compile step);
  gitignore generated catalog .js as build artifacts.
This commit is contained in:
kitbyte
2026-06-15 00:26:41 +03:00
parent 8c6d87671c
commit 4ce47dc6d2
14 changed files with 1831 additions and 21 deletions
+4
View File
@@ -0,0 +1,4 @@
# The web panel is the bundled frontend shipped inside the C# patcher.
# Mark it as vendored so GitHub Linguist keeps it out of the repository's
# language statistics — the project is a C# app, not a TypeScript one.
web-panel/** linguist-vendored
+4
View File
@@ -22,3 +22,7 @@ dist-ssr
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
# Compiled lingui catalogs — generated from .po by `lingui compile`; the app
# loads .po directly via @lingui/vite-plugin, so these are build artifacts.
src/locales/**/*.js
+2 -2
View File
@@ -2,8 +2,8 @@ import { defineConfig } from '@lingui/cli';
import { formatter } from '@lingui/format-po'; import { formatter } from '@lingui/format-po';
export default defineConfig({ export default defineConfig({
sourceLocale: 'en', sourceLocale: 'en-US',
locales: ['en'], locales: ['en-US', 'ru-RU', 'de-DE', 'fr-FR', 'es-ES', 'zh-CN'],
catalogs: [ catalogs: [
{ {
path: '<rootDir>/src/locales/{locale}/messages', path: '<rootDir>/src/locales/{locale}/messages',
+1 -1
View File
@@ -6,7 +6,7 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"dev:host": "vite --host 0.0.0.0", "dev:host": "vite --host 0.0.0.0",
"build": "pnpm run i18n:compile && tsc --noEmit && vite build && pnpm run build:bridge", "build": "tsc --noEmit && vite build && pnpm run build:bridge",
"build:bridge": "node ./bridge/build.mjs", "build:bridge": "node ./bridge/build.mjs",
"lint": "eslint src protocol bridge/src --max-warnings=0", "lint": "eslint src protocol bridge/src --max-warnings=0",
"typecheck:web": "tsc --noEmit", "typecheck:web": "tsc --noEmit",
+59 -15
View File
@@ -1,26 +1,70 @@
import { i18n } from '@lingui/core'; import { i18n, type Messages } from '@lingui/core';
export const DEFAULT_LOCALE = 'en'; export const DEFAULT_LOCALE = 'en-US';
type CatalogModule = { export const SUPPORTED_LOCALES = [
default?: { messages: Record<string, string> }; { code: 'en-US', label: 'English' },
messages?: Record<string, string>; { code: 'ru-RU', label: 'Русский' },
}; { code: 'de-DE', label: 'Deutsch' },
{ code: 'fr-FR', label: 'Français' },
{ code: 'es-ES', label: 'Español' },
{ code: 'zh-CN', label: '简体中文' },
] as const;
const catalogs = import.meta.glob<CatalogModule>('../locales/*/messages.js'); export type LocaleCode = (typeof SUPPORTED_LOCALES)[number]['code'];
export async function activateLocale(locale: string): Promise<void> { const LOCALE_STORAGE_KEY = 'wand:locale';
const loadCatalog = catalogs[`../locales/${locale}/messages.js`];
type CatalogModule = { messages: Messages };
const catalogs = import.meta.glob<CatalogModule>('../locales/*/messages.po');
export async function activateLocale(locale: LocaleCode): Promise<void> {
const loadCatalog = catalogs[`../locales/${locale}/messages.po`];
if (!loadCatalog) { if (!loadCatalog) {
throw new Error(`Locale catalog not found: ${locale}`); throw new Error(`Locale catalog not found: ${locale}`);
} }
const catalog = await loadCatalog(); const { messages } = await loadCatalog();
const messages = catalog.messages ?? catalog.default?.messages;
if (!messages) {
throw new Error(`Locale catalog is invalid: ${locale}`);
}
i18n.load(locale, messages); i18n.load(locale, messages);
i18n.activate(locale); i18n.activate(locale);
persistLocale(locale);
}
export function detectInitialLocale(): LocaleCode {
return readStoredLocale() ?? matchBrowserLocale() ?? DEFAULT_LOCALE;
}
function readStoredLocale(): LocaleCode | null {
try {
const stored = localStorage.getItem(LOCALE_STORAGE_KEY);
return isSupportedLocale(stored) ? stored : null;
} catch {
return null;
}
}
function matchBrowserLocale(): LocaleCode | null {
const candidates = typeof navigator === 'undefined' ? [] : (navigator.languages ?? [navigator.language]);
for (const candidate of candidates) {
const base = candidate.split('-')[0];
const match = SUPPORTED_LOCALES.find(({ code }) => code === candidate || code.split('-')[0] === base);
if (match) {
return match.code;
}
}
return null;
}
function persistLocale(locale: LocaleCode): void {
try {
localStorage.setItem(LOCALE_STORAGE_KEY, locale);
} catch {
// Ignore storage failures (private mode, blocked cookies, etc.).
}
}
function isSupportedLocale(value: string | null): value is LocaleCode {
return value !== null && SUPPORTED_LOCALES.some(({ code }) => code === value);
} }
+2 -2
View File
@@ -6,7 +6,7 @@ import { I18nProvider } from '@lingui/react';
import { applySavedAccentColor } from '@/appearance/appearance-storage'; import { applySavedAccentColor } from '@/appearance/appearance-storage';
import { App } from './app'; import { App } from './app';
import { activateLocale, DEFAULT_LOCALE } from './i18n'; import { activateLocale, detectInitialLocale } from './i18n';
import '../index.css'; import '../index.css';
const root = document.getElementById('root') ?? document.getElementById('app'); const root = document.getElementById('root') ?? document.getElementById('app');
@@ -17,7 +17,7 @@ if (!root) {
applySavedAccentColor(); applySavedAccentColor();
activateLocale(DEFAULT_LOCALE).then(() => { activateLocale(detectInitialLocale()).then(() => {
createRoot(root).render( createRoot(root).render(
<StrictMode> <StrictMode>
<I18nProvider i18n={i18n}> <I18nProvider i18n={i18n}>
+30
View File
@@ -6,6 +6,7 @@ import { useLingui } from '@lingui/react';
import { Icon } from '@/shared/ui/Icon'; import { Icon } from '@/shared/ui/Icon';
import { cn } from '@/shared/lib/ui'; import { cn } from '@/shared/lib/ui';
import { activateLocale, type LocaleCode, SUPPORTED_LOCALES } from '@/app/i18n';
import { DEFAULT_ACCENT_COLOR, loadAccentColor, setAccentColor } from '@/appearance/appearance-storage'; import { DEFAULT_ACCENT_COLOR, loadAccentColor, setAccentColor } from '@/appearance/appearance-storage';
import type { LibraryGame } from '@/library/model/games'; import type { LibraryGame } from '@/library/model/games';
import { EConnectionStatus } from '@/remote-session/remote-session.reducer'; import { EConnectionStatus } from '@/remote-session/remote-session.reducer';
@@ -71,6 +72,9 @@ export const SettingsDrawer = ({
<SectionHeader title={_(msg`Session`)} /> <SectionHeader title={_(msg`Session`)} />
<SessionPanel currentGame={currentGame} currentTrainer={currentTrainer} /> <SessionPanel currentGame={currentGame} currentTrainer={currentTrainer} />
<SectionHeader title={_(msg`Language`)} />
<LanguagePicker />
<SectionHeader title={_(msg`Accent Color`)} /> <SectionHeader title={_(msg`Accent Color`)} />
<AccentPicker /> <AccentPicker />
</div> </div>
@@ -160,6 +164,32 @@ const SessionPanel = ({ currentGame, currentTrainer }: { currentGame: LibraryGam
); );
}; };
const LanguagePicker = () => {
const { i18n } = useLingui();
const handleSelect = (locale: LocaleCode) => {
void activateLocale(locale);
};
return (
<div className="grid grid-cols-2 gap-1.5">
{SUPPORTED_LOCALES.map(({ code, label }) => {
const active = i18n.locale === code;
return (
<button
key={code}
type="button"
className={cn('remote-glass-control flex items-center justify-center rounded-[9px] border px-2 py-2 text-[12px] font-medium', active ? 'border-(--deck-accent) text-(--deck-fg)' : 'text-(--deck-fg-3)')}
onClick={() => handleSelect(code)}
>
{label}
</button>
);
})}
</div>
);
};
const AccentPicker = () => { const AccentPicker = () => {
const { _ } = useLingui(); const { _ } = useLingui();
const [current, setCurrent] = useState(loadAccentColor); const [current, setCurrent] = useState(loadAccentColor);
+345
View File
@@ -0,0 +1,345 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2026-06-15 00:17+0300\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: de-DE\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Plural-Forms: \n"
#. placeholder {0}: games.length
#: src/library/ui/LibraryDrawer.tsx
msgid "{0, plural, one {# game detected} other {# games detected}}"
msgstr "{0, plural, one {# Spiel erkannt} other {# Spiele erkannt}}"
#. placeholder {0}: trainer.totalVisibleCheats
#: src/app/app.tsx
msgid "{0} matches"
msgstr "{0} Treffer"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods"
msgstr "{cheatCount} Mods"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods · {enabledCount}/{toggleCount} on"
msgstr "{cheatCount} Mods · {enabledCount}/{toggleCount} an"
#: src/app/ui/SettingsDrawer.tsx
msgid "Accent Color"
msgstr "Akzentfarbe"
#: src/app/ui/SettingsDrawer.tsx
msgid "Active Session"
msgstr "Aktive Sitzung"
#: src/trainer/ui/QuickActions.tsx
msgid "Add"
msgstr "Hinzufügen"
#: src/trainer/ui/QuickActions.tsx
msgid "Add Preset"
msgstr "Preset hinzufügen"
#: src/library/ui/LibraryDrawer.tsx
msgid "All Games"
msgstr "Alle Spiele"
#: src/app/ui/SettingsDrawer.tsx
msgid "Amber"
msgstr "Bernstein"
#: src/trainer/controls/ActionButton.tsx
msgid "Apply"
msgstr "Anwenden"
#: src/app/ui/SettingsDrawer.tsx
msgid "Bridge"
msgstr "Bridge"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Bridge offline"
msgstr "Bridge offline"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Browse library"
msgstr "Bibliothek öffnen"
#: src/trainer/ui/QuickActions.tsx
msgid "Cancel"
msgstr "Abbrechen"
#: src/trainer/ui/category-labels.ts
msgid "Challenge"
msgstr "Herausforderung"
#: src/trainer/ui/category-labels.ts
msgid "Character"
msgstr "Charakter"
#: src/trainer/ui/category-labels.ts
msgid "Cheats"
msgstr "Cheats"
#: src/shared/ui/SearchInput.tsx
msgid "Clear search"
msgstr "Suche leeren"
#: src/shared/ui/Drawer.tsx
msgid "Close drawer"
msgstr "Leiste schließen"
#: src/library/ui/LibraryDrawer.tsx
msgid "Close library"
msgstr "Bibliothek schließen"
#: src/trainer/ui/QuickActions.tsx
msgid "Close preset modal"
msgstr "Preset-Fenster schließen"
#: src/app/ui/SettingsDrawer.tsx
msgid "Close settings"
msgstr "Einstellungen schließen"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cobalt"
msgstr "Kobalt"
#: src/trainer/ui/category-labels.ts
msgid "Crafting"
msgstr "Handwerk"
#: src/app/ui/SettingsDrawer.tsx
msgid "Crimson"
msgstr "Karminrot"
#: src/app/ui/SettingsDrawer.tsx
msgid "Custom"
msgstr "Eigene"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cyan"
msgstr "Cyan"
#. placeholder {0}: preset.name
#: src/trainer/ui/QuickActions.tsx
msgid "Delete preset {0}"
msgstr "Preset {0} löschen"
#. placeholder {0}: trainer.totalCheats
#: src/app/app.tsx
msgid "END · {0} MODS"
msgstr "ENDE · {0} MODS"
#: src/trainer/ui/category-labels.ts
msgid "Enemies"
msgstr "Gegner"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Favorite game"
msgstr "Spiel favorisieren"
#: src/library/ui/LibraryDrawer.tsx
msgid "Favorites"
msgstr "Favoriten"
#: src/trainer/ui/category-labels.ts
msgid "Game"
msgstr "Spiel"
#: src/app/ui/SettingsDrawer.tsx
msgid "GO"
msgstr "START"
#: src/app/ui/TopBar.tsx
msgid "Idle · no game"
msgstr "Inaktiv · kein Spiel"
#: src/trainer/ui/category-labels.ts
msgid "Inventory"
msgstr "Inventar"
#: src/trainer/ui/category-labels.ts
msgid "Items"
msgstr "Gegenstände"
#: src/app/ui/SettingsDrawer.tsx
msgid "Language"
msgstr "Sprache"
#: src/app/ui/FloatingDock.tsx
#: src/library/ui/LibraryDrawer.tsx
msgid "Library"
msgstr "Bibliothek"
#: src/app/ui/SettingsDrawer.tsx
msgid "Lime"
msgstr "Limette"
#: src/app/ui/StatusPill.tsx
msgid "LINKING"
msgstr "VERBINDET"
#: src/app/ui/StatusPill.tsx
msgid "LIVE"
msgstr "LIVE"
#: src/app/ui/SettingsDrawer.tsx
msgid "Magenta"
msgstr "Magenta"
#: src/trainer/ui/QuickActions.tsx
msgid "Name"
msgstr "Name"
#: src/trainer/ui/QuickActions.tsx
msgid "New preset"
msgstr "Neues Preset"
#: src/app/ui/SettingsDrawer.tsx
msgid "No active game session."
msgstr "Keine aktive Spielsitzung."
#: src/app/ui/SessionPlaceholder.tsx
msgid "No game is running yet. Open the library and launch one to start tweaking."
msgstr "Es läuft noch kein Spiel. Öffnen Sie die Bibliothek und starten Sie eines, um loszulegen."
#: src/library/ui/LibraryDrawer.tsx
msgid "No games match \"{query}\""
msgstr "Keine Spiele für „{query}“"
#. placeholder {0}: trainer.query
#: src/app/app.tsx
msgid "No mods match \"{0}\""
msgstr "Keine Mods für „{0}“"
#: src/trainer/controls/SelectionControl.tsx
msgid "No options"
msgstr "Keine Optionen"
#: src/app/ui/FloatingDock.tsx
msgid "No session"
msgstr "Keine Sitzung"
#: src/library/ui/LibraryDrawer.tsx
msgid "Now Playing"
msgstr "Wird gespielt"
#: src/app/ui/StatusPill.tsx
msgid "OFFLINE"
msgstr "OFFLINE"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings"
msgstr "Einstellungen öffnen"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings to point Wand at your trainer bridge over WebSocket."
msgstr "Öffnen Sie die Einstellungen, um Wand über WebSocket mit Ihrer Trainer-Bridge zu verbinden."
#: src/trainer/ui/QuickActions.tsx
msgid "Panic Off"
msgstr "Alles aus"
#: src/trainer/ui/category-labels.ts
msgid "Physics"
msgstr "Physik"
#: src/trainer/ui/category-labels.ts
msgid "Pinned"
msgstr "Angeheftet"
#: src/library/ui/LibraryDrawer.tsx
msgid "Play"
msgstr "Spielen"
#: src/trainer/ui/category-labels.ts
msgid "Player"
msgstr "Spieler"
#: src/trainer/ui/QuickActions.tsx
msgid "Preset name"
msgstr "Preset-Name"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Remove favorite"
msgstr "Favorit entfernen"
#: src/trainer/ui/category-labels.ts
msgid "Resources"
msgstr "Ressourcen"
#: src/trainer/ui/QuickActions.tsx
msgid "Save"
msgstr "Speichern"
#: src/library/ui/LibraryDrawer.tsx
msgid "Search games"
msgstr "Spiele suchen"
#: src/app/app.tsx
msgid "Search mods"
msgstr "Mods suchen"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Select a game"
msgstr "Spiel auswählen"
#: src/app/ui/SettingsDrawer.tsx
msgid "Session"
msgstr "Sitzung"
#: src/app/ui/FloatingDock.tsx
#: src/app/ui/SettingsDrawer.tsx
#: src/app/ui/TopBar.tsx
msgid "Settings"
msgstr "Einstellungen"
#: src/trainer/ui/category-labels.ts
msgid "Stats"
msgstr "Werte"
#: src/app/ui/SettingsDrawer.tsx
msgid "STOP"
msgstr "STOPP"
#: src/library/ui/LibraryDrawer.tsx
msgid "Stop playing"
msgstr "Beenden"
#: src/trainer/ui/category-labels.ts
msgid "Teleport"
msgstr "Teleport"
#: src/trainer/ui/TrainerHeader.tsx
msgid "Trainer Active"
msgstr "Trainer aktiv"
#: src/trainer/ui/category-labels.ts
msgid "Vehicles"
msgstr "Fahrzeuge"
#: src/app/ui/SettingsDrawer.tsx
msgid "Violet"
msgstr "Violett"
#. placeholder {0}: WEB_CONTRACT.defaultRemotePort
#: src/app/ui/SettingsDrawer.tsx
msgid "wand remote · port {0}"
msgstr "wand remote · Port {0}"
#: src/trainer/ui/category-labels.ts
msgid "Weapons"
msgstr "Waffen"
#: src/trainer/ui/category-labels.ts
msgid "World"
msgstr "Welt"
@@ -170,6 +170,10 @@ msgstr "Inventory"
msgid "Items" msgid "Items"
msgstr "Items" msgstr "Items"
#: src/app/ui/SettingsDrawer.tsx
msgid "Language"
msgstr "Language"
#: src/app/ui/FloatingDock.tsx #: src/app/ui/FloatingDock.tsx
#: src/library/ui/LibraryDrawer.tsx #: src/library/ui/LibraryDrawer.tsx
msgid "Library" msgid "Library"
-1
View File
@@ -1 +0,0 @@
/*eslint-disable*/module.exports={messages:JSON.parse("{\"0eyak2\":[\"Close preset modal\"],\"15SPG8\":[\"Stop playing\"],\"1uJlG9\":[\"Accent Color\"],\"29Hx9U\":[\"Stats\"],\"2MiXF-\":[\"No mods match \\\"\",[\"0\"],\"\\\"\"],\"4R8qoo\":[\"No games match \\\"\",[\"query\"],\"\\\"\"],\"5B_EbJ\":[\"OFFLINE\"],\"5Tsr0S\":[\"GO\"],\"5_DJAT\":[\"Delete preset \",[\"0\"]],\"6YtxFj\":[\"Name\"],\"7kV7X8\":[\"Idle · no game\"],\"8Tg_JR\":[\"Custom\"],\"8v0yqM\":[\"Weapons\"],\"9EqSGz\":[\"Lime\"],\"BzfzPK\":[\"Items\"],\"C_i4ng\":[\"Select a game\"],\"Cie1-b\":[\"Teleport\"],\"CqO9qC\":[\"Session\"],\"D1jeqs\":[\"No session\"],\"DB8zMK\":[\"Apply\"],\"DD0Fnh\":[\"LINKING\"],\"DlBKuz\":[\"Browse library\"],\"F37c1s\":[\"Open Settings\"],\"Hz-sxK\":[\"No options\"],\"J24FyN\":[\"Bridge\"],\"Jv26w1\":[\"Close drawer\"],\"LCXVTv\":[\"Cobalt\"],\"LZRTnY\":[\"Game\"],\"NWm6Qw\":[\"All Games\"],\"OkA8xh\":[\"Crafting\"],\"OzDccM\":[\"Bridge offline\"],\"QBOwbf\":[\"Close settings\"],\"T91vKp\":[\"Play\"],\"TvwYwN\":[\"Enemies\"],\"Tz0i8g\":[\"Settings\"],\"U3lTk6\":[\"Add Preset\"],\"Ul-m9L\":[\"Search games\"],\"V3MCts\":[\"Preset name\"],\"V8yTm6\":[\"Clear search\"],\"X9kySA\":[\"Favorites\"],\"Y9Da-w\":[\"Trainer Active\"],\"ZrsGjm\":[\"Inventory\"],\"aPk9_7\":[\"Panic Off\"],\"dEgA5A\":[\"Cancel\"],\"dMVx8s\":[\"New preset\"],\"e73uuf\":[\"Crimson\"],\"eedtPL\":[\"Violet\"],\"exYcTF\":[\"Library\"],\"fFwMZv\":[\"Cyan\"],\"fg3Xvh\":[\"Character\"],\"fpMs2Z\":[\"LIVE\"],\"garODz\":[\"Remove favorite\"],\"i5IWIg\":[\"Physics\"],\"iZWlw6\":[\"Challenge\"],\"isSRI0\":[\"Active Session\"],\"kJs53F\":[[\"0\"],\" matches\"],\"kNiQp6\":[\"Pinned\"],\"llTC8Z\":[\"END · \",[\"0\"],\" MODS\"],\"m16xKo\":[\"Add\"],\"nPRduv\":[\"Close library\"],\"nsI6F9\":[[\"cheatCount\"],\" mods · \",[\"enabledCount\"],\"/\",[\"toggleCount\"],\" on\"],\"pBpfre\":[\"Cheats\"],\"pipqSe\":[\"Now Playing\"],\"q1-iDP\":[\"Open Settings to point Wand at your trainer bridge over WebSocket.\"],\"q1I2y_\":[[\"0\",\"plural\",{\"one\":[\"#\",\" game detected\"],\"other\":[\"#\",\" games detected\"]}]],\"qSNzRg\":[\"wand remote · port \",[\"0\"]],\"qVkch9\":[\"No active game session.\"],\"qanr4_\":[\"Search mods\"],\"s-MGs7\":[\"Resources\"],\"s8OcrP\":[\"Vehicles\"],\"tfDRzk\":[\"Save\"],\"u4hZgR\":[\"Favorite game\"],\"uprOiC\":[\"Amber\"],\"v-jdqd\":[\"World\"],\"vRayGs\":[\"Player\"],\"vmwjgT\":[\"No game is running yet. Open the library and launch one to start tweaking.\"],\"vz5zAR\":[\"Magenta\"],\"wOM6pH\":[\"STOP\"],\"xVi7fK\":[[\"cheatCount\"],\" mods\"]}")};
+345
View File
@@ -0,0 +1,345 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2026-06-15 00:17+0300\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: es-ES\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Plural-Forms: \n"
#. placeholder {0}: games.length
#: src/library/ui/LibraryDrawer.tsx
msgid "{0, plural, one {# game detected} other {# games detected}}"
msgstr "{0, plural, one {# juego detectado} other {# juegos detectados}}"
#. placeholder {0}: trainer.totalVisibleCheats
#: src/app/app.tsx
msgid "{0} matches"
msgstr "{0} coincidencias"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods"
msgstr "{cheatCount} mods"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods · {enabledCount}/{toggleCount} on"
msgstr "{cheatCount} mods · {enabledCount}/{toggleCount} activos"
#: src/app/ui/SettingsDrawer.tsx
msgid "Accent Color"
msgstr "Color de acento"
#: src/app/ui/SettingsDrawer.tsx
msgid "Active Session"
msgstr "Sesión activa"
#: src/trainer/ui/QuickActions.tsx
msgid "Add"
msgstr "Añadir"
#: src/trainer/ui/QuickActions.tsx
msgid "Add Preset"
msgstr "Añadir preajuste"
#: src/library/ui/LibraryDrawer.tsx
msgid "All Games"
msgstr "Todos los juegos"
#: src/app/ui/SettingsDrawer.tsx
msgid "Amber"
msgstr "Ámbar"
#: src/trainer/controls/ActionButton.tsx
msgid "Apply"
msgstr "Aplicar"
#: src/app/ui/SettingsDrawer.tsx
msgid "Bridge"
msgstr "Puente"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Bridge offline"
msgstr "Puente desconectado"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Browse library"
msgstr "Explorar biblioteca"
#: src/trainer/ui/QuickActions.tsx
msgid "Cancel"
msgstr "Cancelar"
#: src/trainer/ui/category-labels.ts
msgid "Challenge"
msgstr "Desafío"
#: src/trainer/ui/category-labels.ts
msgid "Character"
msgstr "Personaje"
#: src/trainer/ui/category-labels.ts
msgid "Cheats"
msgstr "Trucos"
#: src/shared/ui/SearchInput.tsx
msgid "Clear search"
msgstr "Borrar búsqueda"
#: src/shared/ui/Drawer.tsx
msgid "Close drawer"
msgstr "Cerrar panel"
#: src/library/ui/LibraryDrawer.tsx
msgid "Close library"
msgstr "Cerrar biblioteca"
#: src/trainer/ui/QuickActions.tsx
msgid "Close preset modal"
msgstr "Cerrar ventana de preajuste"
#: src/app/ui/SettingsDrawer.tsx
msgid "Close settings"
msgstr "Cerrar ajustes"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cobalt"
msgstr "Cobalto"
#: src/trainer/ui/category-labels.ts
msgid "Crafting"
msgstr "Fabricación"
#: src/app/ui/SettingsDrawer.tsx
msgid "Crimson"
msgstr "Carmesí"
#: src/app/ui/SettingsDrawer.tsx
msgid "Custom"
msgstr "Personalizado"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cyan"
msgstr "Cian"
#. placeholder {0}: preset.name
#: src/trainer/ui/QuickActions.tsx
msgid "Delete preset {0}"
msgstr "Eliminar preajuste {0}"
#. placeholder {0}: trainer.totalCheats
#: src/app/app.tsx
msgid "END · {0} MODS"
msgstr "FIN · {0} MODS"
#: src/trainer/ui/category-labels.ts
msgid "Enemies"
msgstr "Enemigos"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Favorite game"
msgstr "Marcar favorito"
#: src/library/ui/LibraryDrawer.tsx
msgid "Favorites"
msgstr "Favoritos"
#: src/trainer/ui/category-labels.ts
msgid "Game"
msgstr "Juego"
#: src/app/ui/SettingsDrawer.tsx
msgid "GO"
msgstr "IR"
#: src/app/ui/TopBar.tsx
msgid "Idle · no game"
msgstr "Inactivo · sin juego"
#: src/trainer/ui/category-labels.ts
msgid "Inventory"
msgstr "Inventario"
#: src/trainer/ui/category-labels.ts
msgid "Items"
msgstr "Objetos"
#: src/app/ui/SettingsDrawer.tsx
msgid "Language"
msgstr "Idioma"
#: src/app/ui/FloatingDock.tsx
#: src/library/ui/LibraryDrawer.tsx
msgid "Library"
msgstr "Biblioteca"
#: src/app/ui/SettingsDrawer.tsx
msgid "Lime"
msgstr "Lima"
#: src/app/ui/StatusPill.tsx
msgid "LINKING"
msgstr "CONECTANDO"
#: src/app/ui/StatusPill.tsx
msgid "LIVE"
msgstr "EN VIVO"
#: src/app/ui/SettingsDrawer.tsx
msgid "Magenta"
msgstr "Magenta"
#: src/trainer/ui/QuickActions.tsx
msgid "Name"
msgstr "Nombre"
#: src/trainer/ui/QuickActions.tsx
msgid "New preset"
msgstr "Nuevo preajuste"
#: src/app/ui/SettingsDrawer.tsx
msgid "No active game session."
msgstr "No hay sesión de juego activa."
#: src/app/ui/SessionPlaceholder.tsx
msgid "No game is running yet. Open the library and launch one to start tweaking."
msgstr "Aún no hay ningún juego en marcha. Abre la biblioteca e inicia uno para empezar a ajustar."
#: src/library/ui/LibraryDrawer.tsx
msgid "No games match \"{query}\""
msgstr "Ningún juego coincide con «{query}»"
#. placeholder {0}: trainer.query
#: src/app/app.tsx
msgid "No mods match \"{0}\""
msgstr "Ningún mod coincide con «{0}»"
#: src/trainer/controls/SelectionControl.tsx
msgid "No options"
msgstr "Sin opciones"
#: src/app/ui/FloatingDock.tsx
msgid "No session"
msgstr "Sin sesión"
#: src/library/ui/LibraryDrawer.tsx
msgid "Now Playing"
msgstr "Jugando ahora"
#: src/app/ui/StatusPill.tsx
msgid "OFFLINE"
msgstr "SIN CONEXIÓN"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings"
msgstr "Abrir ajustes"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings to point Wand at your trainer bridge over WebSocket."
msgstr "Abre los ajustes para conectar Wand con tu puente de trainer por WebSocket."
#: src/trainer/ui/QuickActions.tsx
msgid "Panic Off"
msgstr "Apagar todo"
#: src/trainer/ui/category-labels.ts
msgid "Physics"
msgstr "Física"
#: src/trainer/ui/category-labels.ts
msgid "Pinned"
msgstr "Fijados"
#: src/library/ui/LibraryDrawer.tsx
msgid "Play"
msgstr "Jugar"
#: src/trainer/ui/category-labels.ts
msgid "Player"
msgstr "Jugador"
#: src/trainer/ui/QuickActions.tsx
msgid "Preset name"
msgstr "Nombre del preajuste"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Remove favorite"
msgstr "Quitar favorito"
#: src/trainer/ui/category-labels.ts
msgid "Resources"
msgstr "Recursos"
#: src/trainer/ui/QuickActions.tsx
msgid "Save"
msgstr "Guardar"
#: src/library/ui/LibraryDrawer.tsx
msgid "Search games"
msgstr "Buscar juegos"
#: src/app/app.tsx
msgid "Search mods"
msgstr "Buscar mods"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Select a game"
msgstr "Elige un juego"
#: src/app/ui/SettingsDrawer.tsx
msgid "Session"
msgstr "Sesión"
#: src/app/ui/FloatingDock.tsx
#: src/app/ui/SettingsDrawer.tsx
#: src/app/ui/TopBar.tsx
msgid "Settings"
msgstr "Ajustes"
#: src/trainer/ui/category-labels.ts
msgid "Stats"
msgstr "Estadísticas"
#: src/app/ui/SettingsDrawer.tsx
msgid "STOP"
msgstr "PARAR"
#: src/library/ui/LibraryDrawer.tsx
msgid "Stop playing"
msgstr "Detener"
#: src/trainer/ui/category-labels.ts
msgid "Teleport"
msgstr "Teletransporte"
#: src/trainer/ui/TrainerHeader.tsx
msgid "Trainer Active"
msgstr "Trainer activo"
#: src/trainer/ui/category-labels.ts
msgid "Vehicles"
msgstr "Vehículos"
#: src/app/ui/SettingsDrawer.tsx
msgid "Violet"
msgstr "Violeta"
#. placeholder {0}: WEB_CONTRACT.defaultRemotePort
#: src/app/ui/SettingsDrawer.tsx
msgid "wand remote · port {0}"
msgstr "wand remote · puerto {0}"
#: src/trainer/ui/category-labels.ts
msgid "Weapons"
msgstr "Armas"
#: src/trainer/ui/category-labels.ts
msgid "World"
msgstr "Mundo"
+345
View File
@@ -0,0 +1,345 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2026-06-15 00:17+0300\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: fr-FR\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Plural-Forms: \n"
#. placeholder {0}: games.length
#: src/library/ui/LibraryDrawer.tsx
msgid "{0, plural, one {# game detected} other {# games detected}}"
msgstr "{0, plural, one {# jeu détecté} other {# jeux détectés}}"
#. placeholder {0}: trainer.totalVisibleCheats
#: src/app/app.tsx
msgid "{0} matches"
msgstr "{0} résultats"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods"
msgstr "{cheatCount} mods"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods · {enabledCount}/{toggleCount} on"
msgstr "{cheatCount} mods · {enabledCount}/{toggleCount} actifs"
#: src/app/ui/SettingsDrawer.tsx
msgid "Accent Color"
msgstr "Couleur d'accent"
#: src/app/ui/SettingsDrawer.tsx
msgid "Active Session"
msgstr "Session active"
#: src/trainer/ui/QuickActions.tsx
msgid "Add"
msgstr "Ajouter"
#: src/trainer/ui/QuickActions.tsx
msgid "Add Preset"
msgstr "Ajouter un préréglage"
#: src/library/ui/LibraryDrawer.tsx
msgid "All Games"
msgstr "Tous les jeux"
#: src/app/ui/SettingsDrawer.tsx
msgid "Amber"
msgstr "Ambre"
#: src/trainer/controls/ActionButton.tsx
msgid "Apply"
msgstr "Appliquer"
#: src/app/ui/SettingsDrawer.tsx
msgid "Bridge"
msgstr "Pont"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Bridge offline"
msgstr "Pont hors ligne"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Browse library"
msgstr "Parcourir la bibliothèque"
#: src/trainer/ui/QuickActions.tsx
msgid "Cancel"
msgstr "Annuler"
#: src/trainer/ui/category-labels.ts
msgid "Challenge"
msgstr "Défi"
#: src/trainer/ui/category-labels.ts
msgid "Character"
msgstr "Personnage"
#: src/trainer/ui/category-labels.ts
msgid "Cheats"
msgstr "Triches"
#: src/shared/ui/SearchInput.tsx
msgid "Clear search"
msgstr "Effacer la recherche"
#: src/shared/ui/Drawer.tsx
msgid "Close drawer"
msgstr "Fermer le panneau"
#: src/library/ui/LibraryDrawer.tsx
msgid "Close library"
msgstr "Fermer la bibliothèque"
#: src/trainer/ui/QuickActions.tsx
msgid "Close preset modal"
msgstr "Fermer la fenêtre de préréglage"
#: src/app/ui/SettingsDrawer.tsx
msgid "Close settings"
msgstr "Fermer les paramètres"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cobalt"
msgstr "Cobalt"
#: src/trainer/ui/category-labels.ts
msgid "Crafting"
msgstr "Artisanat"
#: src/app/ui/SettingsDrawer.tsx
msgid "Crimson"
msgstr "Cramoisi"
#: src/app/ui/SettingsDrawer.tsx
msgid "Custom"
msgstr "Personnalisé"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cyan"
msgstr "Cyan"
#. placeholder {0}: preset.name
#: src/trainer/ui/QuickActions.tsx
msgid "Delete preset {0}"
msgstr "Supprimer le préréglage {0}"
#. placeholder {0}: trainer.totalCheats
#: src/app/app.tsx
msgid "END · {0} MODS"
msgstr "FIN · {0} MODS"
#: src/trainer/ui/category-labels.ts
msgid "Enemies"
msgstr "Ennemis"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Favorite game"
msgstr "Mettre en favori"
#: src/library/ui/LibraryDrawer.tsx
msgid "Favorites"
msgstr "Favoris"
#: src/trainer/ui/category-labels.ts
msgid "Game"
msgstr "Jeu"
#: src/app/ui/SettingsDrawer.tsx
msgid "GO"
msgstr "GO"
#: src/app/ui/TopBar.tsx
msgid "Idle · no game"
msgstr "Inactif · aucun jeu"
#: src/trainer/ui/category-labels.ts
msgid "Inventory"
msgstr "Inventaire"
#: src/trainer/ui/category-labels.ts
msgid "Items"
msgstr "Objets"
#: src/app/ui/SettingsDrawer.tsx
msgid "Language"
msgstr "Langue"
#: src/app/ui/FloatingDock.tsx
#: src/library/ui/LibraryDrawer.tsx
msgid "Library"
msgstr "Bibliothèque"
#: src/app/ui/SettingsDrawer.tsx
msgid "Lime"
msgstr "Citron vert"
#: src/app/ui/StatusPill.tsx
msgid "LINKING"
msgstr "CONNEXION"
#: src/app/ui/StatusPill.tsx
msgid "LIVE"
msgstr "EN DIRECT"
#: src/app/ui/SettingsDrawer.tsx
msgid "Magenta"
msgstr "Magenta"
#: src/trainer/ui/QuickActions.tsx
msgid "Name"
msgstr "Nom"
#: src/trainer/ui/QuickActions.tsx
msgid "New preset"
msgstr "Nouveau préréglage"
#: src/app/ui/SettingsDrawer.tsx
msgid "No active game session."
msgstr "Aucune session de jeu active."
#: src/app/ui/SessionPlaceholder.tsx
msgid "No game is running yet. Open the library and launch one to start tweaking."
msgstr "Aucun jeu n'est lancé. Ouvrez la bibliothèque et lancez-en un pour commencer."
#: src/library/ui/LibraryDrawer.tsx
msgid "No games match \"{query}\""
msgstr "Aucun jeu pour « {query} »"
#. placeholder {0}: trainer.query
#: src/app/app.tsx
msgid "No mods match \"{0}\""
msgstr "Aucun mod pour « {0} »"
#: src/trainer/controls/SelectionControl.tsx
msgid "No options"
msgstr "Aucune option"
#: src/app/ui/FloatingDock.tsx
msgid "No session"
msgstr "Aucune session"
#: src/library/ui/LibraryDrawer.tsx
msgid "Now Playing"
msgstr "En cours"
#: src/app/ui/StatusPill.tsx
msgid "OFFLINE"
msgstr "HORS LIGNE"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings"
msgstr "Ouvrir les paramètres"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings to point Wand at your trainer bridge over WebSocket."
msgstr "Ouvrez les paramètres pour connecter Wand à votre pont de trainer via WebSocket."
#: src/trainer/ui/QuickActions.tsx
msgid "Panic Off"
msgstr "Tout désactiver"
#: src/trainer/ui/category-labels.ts
msgid "Physics"
msgstr "Physique"
#: src/trainer/ui/category-labels.ts
msgid "Pinned"
msgstr "Épinglés"
#: src/library/ui/LibraryDrawer.tsx
msgid "Play"
msgstr "Jouer"
#: src/trainer/ui/category-labels.ts
msgid "Player"
msgstr "Joueur"
#: src/trainer/ui/QuickActions.tsx
msgid "Preset name"
msgstr "Nom du préréglage"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Remove favorite"
msgstr "Retirer des favoris"
#: src/trainer/ui/category-labels.ts
msgid "Resources"
msgstr "Ressources"
#: src/trainer/ui/QuickActions.tsx
msgid "Save"
msgstr "Enregistrer"
#: src/library/ui/LibraryDrawer.tsx
msgid "Search games"
msgstr "Rechercher des jeux"
#: src/app/app.tsx
msgid "Search mods"
msgstr "Rechercher des mods"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Select a game"
msgstr "Choisir un jeu"
#: src/app/ui/SettingsDrawer.tsx
msgid "Session"
msgstr "Session"
#: src/app/ui/FloatingDock.tsx
#: src/app/ui/SettingsDrawer.tsx
#: src/app/ui/TopBar.tsx
msgid "Settings"
msgstr "Paramètres"
#: src/trainer/ui/category-labels.ts
msgid "Stats"
msgstr "Stats"
#: src/app/ui/SettingsDrawer.tsx
msgid "STOP"
msgstr "STOP"
#: src/library/ui/LibraryDrawer.tsx
msgid "Stop playing"
msgstr "Arrêter"
#: src/trainer/ui/category-labels.ts
msgid "Teleport"
msgstr "Téléportation"
#: src/trainer/ui/TrainerHeader.tsx
msgid "Trainer Active"
msgstr "Trainer actif"
#: src/trainer/ui/category-labels.ts
msgid "Vehicles"
msgstr "Véhicules"
#: src/app/ui/SettingsDrawer.tsx
msgid "Violet"
msgstr "Violet"
#. placeholder {0}: WEB_CONTRACT.defaultRemotePort
#: src/app/ui/SettingsDrawer.tsx
msgid "wand remote · port {0}"
msgstr "wand remote · port {0}"
#: src/trainer/ui/category-labels.ts
msgid "Weapons"
msgstr "Armes"
#: src/trainer/ui/category-labels.ts
msgid "World"
msgstr "Monde"
+345
View File
@@ -0,0 +1,345 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2026-06-15 00:17+0300\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: ru-RU\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Plural-Forms: \n"
#. placeholder {0}: games.length
#: src/library/ui/LibraryDrawer.tsx
msgid "{0, plural, one {# game detected} other {# games detected}}"
msgstr "{0, plural, one {# игра найдена} few {# игры найдено} many {# игр найдено} other {# игр найдено}}"
#. placeholder {0}: trainer.totalVisibleCheats
#: src/app/app.tsx
msgid "{0} matches"
msgstr "{0} совпадений"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods"
msgstr "{cheatCount} модов"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods · {enabledCount}/{toggleCount} on"
msgstr "{cheatCount} модов · {enabledCount}/{toggleCount} вкл"
#: src/app/ui/SettingsDrawer.tsx
msgid "Accent Color"
msgstr "Акцентный цвет"
#: src/app/ui/SettingsDrawer.tsx
msgid "Active Session"
msgstr "Активная сессия"
#: src/trainer/ui/QuickActions.tsx
msgid "Add"
msgstr "Добавить"
#: src/trainer/ui/QuickActions.tsx
msgid "Add Preset"
msgstr "Добавить пресет"
#: src/library/ui/LibraryDrawer.tsx
msgid "All Games"
msgstr "Все игры"
#: src/app/ui/SettingsDrawer.tsx
msgid "Amber"
msgstr "Янтарный"
#: src/trainer/controls/ActionButton.tsx
msgid "Apply"
msgstr "Применить"
#: src/app/ui/SettingsDrawer.tsx
msgid "Bridge"
msgstr "Мост"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Bridge offline"
msgstr "Мост не в сети"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Browse library"
msgstr "Открыть библиотеку"
#: src/trainer/ui/QuickActions.tsx
msgid "Cancel"
msgstr "Отмена"
#: src/trainer/ui/category-labels.ts
msgid "Challenge"
msgstr "Испытание"
#: src/trainer/ui/category-labels.ts
msgid "Character"
msgstr "Персонаж"
#: src/trainer/ui/category-labels.ts
msgid "Cheats"
msgstr "Читы"
#: src/shared/ui/SearchInput.tsx
msgid "Clear search"
msgstr "Очистить поиск"
#: src/shared/ui/Drawer.tsx
msgid "Close drawer"
msgstr "Закрыть панель"
#: src/library/ui/LibraryDrawer.tsx
msgid "Close library"
msgstr "Закрыть библиотеку"
#: src/trainer/ui/QuickActions.tsx
msgid "Close preset modal"
msgstr "Закрыть окно пресета"
#: src/app/ui/SettingsDrawer.tsx
msgid "Close settings"
msgstr "Закрыть настройки"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cobalt"
msgstr "Кобальт"
#: src/trainer/ui/category-labels.ts
msgid "Crafting"
msgstr "Крафт"
#: src/app/ui/SettingsDrawer.tsx
msgid "Crimson"
msgstr "Багровый"
#: src/app/ui/SettingsDrawer.tsx
msgid "Custom"
msgstr "Свой"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cyan"
msgstr "Циан"
#. placeholder {0}: preset.name
#: src/trainer/ui/QuickActions.tsx
msgid "Delete preset {0}"
msgstr "Удалить пресет {0}"
#. placeholder {0}: trainer.totalCheats
#: src/app/app.tsx
msgid "END · {0} MODS"
msgstr "КОНЕЦ · {0} МОДОВ"
#: src/trainer/ui/category-labels.ts
msgid "Enemies"
msgstr "Враги"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Favorite game"
msgstr "В избранное"
#: src/library/ui/LibraryDrawer.tsx
msgid "Favorites"
msgstr "Избранное"
#: src/trainer/ui/category-labels.ts
msgid "Game"
msgstr "Игра"
#: src/app/ui/SettingsDrawer.tsx
msgid "GO"
msgstr "ПУСК"
#: src/app/ui/TopBar.tsx
msgid "Idle · no game"
msgstr "Простой · нет игры"
#: src/trainer/ui/category-labels.ts
msgid "Inventory"
msgstr "Инвентарь"
#: src/trainer/ui/category-labels.ts
msgid "Items"
msgstr "Предметы"
#: src/app/ui/SettingsDrawer.tsx
msgid "Language"
msgstr "Язык"
#: src/app/ui/FloatingDock.tsx
#: src/library/ui/LibraryDrawer.tsx
msgid "Library"
msgstr "Библиотека"
#: src/app/ui/SettingsDrawer.tsx
msgid "Lime"
msgstr "Лайм"
#: src/app/ui/StatusPill.tsx
msgid "LINKING"
msgstr "ПОДКЛЮЧЕНИЕ"
#: src/app/ui/StatusPill.tsx
msgid "LIVE"
msgstr "В СЕТИ"
#: src/app/ui/SettingsDrawer.tsx
msgid "Magenta"
msgstr "Пурпурный"
#: src/trainer/ui/QuickActions.tsx
msgid "Name"
msgstr "Название"
#: src/trainer/ui/QuickActions.tsx
msgid "New preset"
msgstr "Новый пресет"
#: src/app/ui/SettingsDrawer.tsx
msgid "No active game session."
msgstr "Нет активной игровой сессии."
#: src/app/ui/SessionPlaceholder.tsx
msgid "No game is running yet. Open the library and launch one to start tweaking."
msgstr "Игра ещё не запущена. Откройте библиотеку и запустите игру, чтобы начать настройку."
#: src/library/ui/LibraryDrawer.tsx
msgid "No games match \"{query}\""
msgstr "Нет игр по запросу «{query}»"
#. placeholder {0}: trainer.query
#: src/app/app.tsx
msgid "No mods match \"{0}\""
msgstr "Нет модов по запросу «{0}»"
#: src/trainer/controls/SelectionControl.tsx
msgid "No options"
msgstr "Нет вариантов"
#: src/app/ui/FloatingDock.tsx
msgid "No session"
msgstr "Нет сессии"
#: src/library/ui/LibraryDrawer.tsx
msgid "Now Playing"
msgstr "Сейчас в игре"
#: src/app/ui/StatusPill.tsx
msgid "OFFLINE"
msgstr "НЕ В СЕТИ"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings"
msgstr "Открыть настройки"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings to point Wand at your trainer bridge over WebSocket."
msgstr "Откройте настройки, чтобы указать Wand адрес моста трейнера по WebSocket."
#: src/trainer/ui/QuickActions.tsx
msgid "Panic Off"
msgstr "Выключить всё"
#: src/trainer/ui/category-labels.ts
msgid "Physics"
msgstr "Физика"
#: src/trainer/ui/category-labels.ts
msgid "Pinned"
msgstr "Закреплённые"
#: src/library/ui/LibraryDrawer.tsx
msgid "Play"
msgstr "Играть"
#: src/trainer/ui/category-labels.ts
msgid "Player"
msgstr "Игрок"
#: src/trainer/ui/QuickActions.tsx
msgid "Preset name"
msgstr "Название пресета"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Remove favorite"
msgstr "Убрать из избранного"
#: src/trainer/ui/category-labels.ts
msgid "Resources"
msgstr "Ресурсы"
#: src/trainer/ui/QuickActions.tsx
msgid "Save"
msgstr "Сохранить"
#: src/library/ui/LibraryDrawer.tsx
msgid "Search games"
msgstr "Поиск игр"
#: src/app/app.tsx
msgid "Search mods"
msgstr "Поиск модов"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Select a game"
msgstr "Выберите игру"
#: src/app/ui/SettingsDrawer.tsx
msgid "Session"
msgstr "Сессия"
#: src/app/ui/FloatingDock.tsx
#: src/app/ui/SettingsDrawer.tsx
#: src/app/ui/TopBar.tsx
msgid "Settings"
msgstr "Настройки"
#: src/trainer/ui/category-labels.ts
msgid "Stats"
msgstr "Статы"
#: src/app/ui/SettingsDrawer.tsx
msgid "STOP"
msgstr "СТОП"
#: src/library/ui/LibraryDrawer.tsx
msgid "Stop playing"
msgstr "Остановить"
#: src/trainer/ui/category-labels.ts
msgid "Teleport"
msgstr "Телепорт"
#: src/trainer/ui/TrainerHeader.tsx
msgid "Trainer Active"
msgstr "Трейнер активен"
#: src/trainer/ui/category-labels.ts
msgid "Vehicles"
msgstr "Транспорт"
#: src/app/ui/SettingsDrawer.tsx
msgid "Violet"
msgstr "Фиолетовый"
#. placeholder {0}: WEB_CONTRACT.defaultRemotePort
#: src/app/ui/SettingsDrawer.tsx
msgid "wand remote · port {0}"
msgstr "wand remote · порт {0}"
#: src/trainer/ui/category-labels.ts
msgid "Weapons"
msgstr "Оружие"
#: src/trainer/ui/category-labels.ts
msgid "World"
msgstr "Мир"
+345
View File
@@ -0,0 +1,345 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2026-06-15 00:17+0300\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: zh-CN\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Plural-Forms: \n"
#. placeholder {0}: games.length
#: src/library/ui/LibraryDrawer.tsx
msgid "{0, plural, one {# game detected} other {# games detected}}"
msgstr "{0, plural, other {检测到 # 个游戏}}"
#. placeholder {0}: trainer.totalVisibleCheats
#: src/app/app.tsx
msgid "{0} matches"
msgstr "{0} 个匹配"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods"
msgstr "{cheatCount} 个模组"
#: src/trainer/ui/CategorySection.tsx
msgid "{cheatCount} mods · {enabledCount}/{toggleCount} on"
msgstr "{cheatCount} 个模组 · {enabledCount}/{toggleCount} 已开"
#: src/app/ui/SettingsDrawer.tsx
msgid "Accent Color"
msgstr "强调色"
#: src/app/ui/SettingsDrawer.tsx
msgid "Active Session"
msgstr "当前会话"
#: src/trainer/ui/QuickActions.tsx
msgid "Add"
msgstr "添加"
#: src/trainer/ui/QuickActions.tsx
msgid "Add Preset"
msgstr "添加预设"
#: src/library/ui/LibraryDrawer.tsx
msgid "All Games"
msgstr "所有游戏"
#: src/app/ui/SettingsDrawer.tsx
msgid "Amber"
msgstr "琥珀"
#: src/trainer/controls/ActionButton.tsx
msgid "Apply"
msgstr "应用"
#: src/app/ui/SettingsDrawer.tsx
msgid "Bridge"
msgstr "桥接"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Bridge offline"
msgstr "桥接已离线"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Browse library"
msgstr "浏览游戏库"
#: src/trainer/ui/QuickActions.tsx
msgid "Cancel"
msgstr "取消"
#: src/trainer/ui/category-labels.ts
msgid "Challenge"
msgstr "挑战"
#: src/trainer/ui/category-labels.ts
msgid "Character"
msgstr "角色"
#: src/trainer/ui/category-labels.ts
msgid "Cheats"
msgstr "作弊"
#: src/shared/ui/SearchInput.tsx
msgid "Clear search"
msgstr "清除搜索"
#: src/shared/ui/Drawer.tsx
msgid "Close drawer"
msgstr "关闭抽屉"
#: src/library/ui/LibraryDrawer.tsx
msgid "Close library"
msgstr "关闭游戏库"
#: src/trainer/ui/QuickActions.tsx
msgid "Close preset modal"
msgstr "关闭预设窗口"
#: src/app/ui/SettingsDrawer.tsx
msgid "Close settings"
msgstr "关闭设置"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cobalt"
msgstr "钴蓝"
#: src/trainer/ui/category-labels.ts
msgid "Crafting"
msgstr "制作"
#: src/app/ui/SettingsDrawer.tsx
msgid "Crimson"
msgstr "深红"
#: src/app/ui/SettingsDrawer.tsx
msgid "Custom"
msgstr "自定义"
#: src/app/ui/SettingsDrawer.tsx
msgid "Cyan"
msgstr "青色"
#. placeholder {0}: preset.name
#: src/trainer/ui/QuickActions.tsx
msgid "Delete preset {0}"
msgstr "删除预设 {0}"
#. placeholder {0}: trainer.totalCheats
#: src/app/app.tsx
msgid "END · {0} MODS"
msgstr "结束 · {0} 个模组"
#: src/trainer/ui/category-labels.ts
msgid "Enemies"
msgstr "敌人"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Favorite game"
msgstr "收藏游戏"
#: src/library/ui/LibraryDrawer.tsx
msgid "Favorites"
msgstr "收藏"
#: src/trainer/ui/category-labels.ts
msgid "Game"
msgstr "游戏"
#: src/app/ui/SettingsDrawer.tsx
msgid "GO"
msgstr "连接"
#: src/app/ui/TopBar.tsx
msgid "Idle · no game"
msgstr "空闲 · 无游戏"
#: src/trainer/ui/category-labels.ts
msgid "Inventory"
msgstr "物品栏"
#: src/trainer/ui/category-labels.ts
msgid "Items"
msgstr "物品"
#: src/app/ui/SettingsDrawer.tsx
msgid "Language"
msgstr "语言"
#: src/app/ui/FloatingDock.tsx
#: src/library/ui/LibraryDrawer.tsx
msgid "Library"
msgstr "游戏库"
#: src/app/ui/SettingsDrawer.tsx
msgid "Lime"
msgstr "青柠"
#: src/app/ui/StatusPill.tsx
msgid "LINKING"
msgstr "连接中"
#: src/app/ui/StatusPill.tsx
msgid "LIVE"
msgstr "在线"
#: src/app/ui/SettingsDrawer.tsx
msgid "Magenta"
msgstr "品红"
#: src/trainer/ui/QuickActions.tsx
msgid "Name"
msgstr "名称"
#: src/trainer/ui/QuickActions.tsx
msgid "New preset"
msgstr "新预设"
#: src/app/ui/SettingsDrawer.tsx
msgid "No active game session."
msgstr "没有活动的游戏会话。"
#: src/app/ui/SessionPlaceholder.tsx
msgid "No game is running yet. Open the library and launch one to start tweaking."
msgstr "尚未运行游戏。打开游戏库并启动一个即可开始调整。"
#: src/library/ui/LibraryDrawer.tsx
msgid "No games match \"{query}\""
msgstr "没有匹配「{query}」的游戏"
#. placeholder {0}: trainer.query
#: src/app/app.tsx
msgid "No mods match \"{0}\""
msgstr "没有匹配「{0}」的模组"
#: src/trainer/controls/SelectionControl.tsx
msgid "No options"
msgstr "无选项"
#: src/app/ui/FloatingDock.tsx
msgid "No session"
msgstr "无会话"
#: src/library/ui/LibraryDrawer.tsx
msgid "Now Playing"
msgstr "正在游玩"
#: src/app/ui/StatusPill.tsx
msgid "OFFLINE"
msgstr "离线"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings"
msgstr "打开设置"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Open Settings to point Wand at your trainer bridge over WebSocket."
msgstr "打开设置,通过 WebSocket 将 Wand 指向你的训练器桥接。"
#: src/trainer/ui/QuickActions.tsx
msgid "Panic Off"
msgstr "全部关闭"
#: src/trainer/ui/category-labels.ts
msgid "Physics"
msgstr "物理"
#: src/trainer/ui/category-labels.ts
msgid "Pinned"
msgstr "已固定"
#: src/library/ui/LibraryDrawer.tsx
msgid "Play"
msgstr "开始游戏"
#: src/trainer/ui/category-labels.ts
msgid "Player"
msgstr "玩家"
#: src/trainer/ui/QuickActions.tsx
msgid "Preset name"
msgstr "预设名称"
#: src/library/ui/LibraryDrawer.tsx
#: src/trainer/ui/TrainerHeader.tsx
msgid "Remove favorite"
msgstr "取消收藏"
#: src/trainer/ui/category-labels.ts
msgid "Resources"
msgstr "资源"
#: src/trainer/ui/QuickActions.tsx
msgid "Save"
msgstr "保存"
#: src/library/ui/LibraryDrawer.tsx
msgid "Search games"
msgstr "搜索游戏"
#: src/app/app.tsx
msgid "Search mods"
msgstr "搜索模组"
#: src/app/ui/SessionPlaceholder.tsx
msgid "Select a game"
msgstr "选择游戏"
#: src/app/ui/SettingsDrawer.tsx
msgid "Session"
msgstr "会话"
#: src/app/ui/FloatingDock.tsx
#: src/app/ui/SettingsDrawer.tsx
#: src/app/ui/TopBar.tsx
msgid "Settings"
msgstr "设置"
#: src/trainer/ui/category-labels.ts
msgid "Stats"
msgstr "属性"
#: src/app/ui/SettingsDrawer.tsx
msgid "STOP"
msgstr "停止"
#: src/library/ui/LibraryDrawer.tsx
msgid "Stop playing"
msgstr "停止游戏"
#: src/trainer/ui/category-labels.ts
msgid "Teleport"
msgstr "传送"
#: src/trainer/ui/TrainerHeader.tsx
msgid "Trainer Active"
msgstr "训练器已激活"
#: src/trainer/ui/category-labels.ts
msgid "Vehicles"
msgstr "载具"
#: src/app/ui/SettingsDrawer.tsx
msgid "Violet"
msgstr "紫色"
#. placeholder {0}: WEB_CONTRACT.defaultRemotePort
#: src/app/ui/SettingsDrawer.tsx
msgid "wand remote · port {0}"
msgstr "wand remote · 端口 {0}"
#: src/trainer/ui/category-labels.ts
msgid "Weapons"
msgstr "武器"
#: src/trainer/ui/category-labels.ts
msgid "World"
msgstr "世界"