Files
galaxy-game/ui/frontend/src/lib/i18n/locales/ru.ts
T
Ilia Denisov 7c8b5aeb23 ui/phase-16: cargo routes inspector + map pick foundation
Add per-planet cargo routes (COL/CAP/MAT/EMP) to the inspector with
a renderer-driven destination picker (faded out-of-reach planets,
cursor-line anchor, hover-highlight) and per-route arrows on the
map. The pick-mode primitives are exposed via `MapPickService` so
ship-group dispatch in Phase 19/20 can reuse the same surface.

Pass A — generic map foundation:
- hit-test now sizes the click zone to `pointRadiusPx + slopPx` so
  the visible disc is always part of the target.
- `RendererHandle` gains `onPointerMove`, `onHoverChange`,
  `setPickMode`, `getPickState`, `getPrimitiveAlpha`,
  `setExtraPrimitives`, `getPrimitives`. The click dispatcher is
  centralised: pick-mode swallows clicks atomically so the standard
  selection consumers do not race against teardown.
- `MapPickService` (`lib/map-pick.svelte.ts`) wraps the renderer
  contract in a promise-shaped `pick(...)`. The in-game shell
  layout owns the service so sidebar and bottom-sheet inspectors
  see the same instance.
- Debug-surface registry exposes `getMapPrimitives`,
  `getMapPickState`, `getMapCamera` to e2e specs without spawning a
  separate debug page after navigation.

Pass B — cargo-route feature:
- `CargoLoadType`, `setCargoRoute`, `removeCargoRoute` typed
  variants with `(source, loadType)` collapse rule on the order
  draft; round-trip through the FBS encoder/decoder.
- `GameReport` decodes `routes` and the local player's drive tech
  for the inline reach formula (40 × drive). `applyOrderOverlay`
  upserts/drops route entries for valid/submitting/applied
  commands.
- `lib/inspectors/planet/cargo-routes.svelte` renders the
  four-slot section. `Add` / `Edit` call `MapPickService.pick`,
  `Remove` emits `removeCargoRoute`.
- `map/cargo-routes.ts` builds shaft + arrowhead primitives per
  cargo type; the map view pushes them through
  `setExtraPrimitives` so the renderer never re-inits Pixi on
  route mutations (Pixi 8 doesn't support that on a reused
  canvas).

Docs:
- `docs/cargo-routes-ux.md` covers engine semantics + UI map.
- `docs/renderer.md` documents pick mode and the debug surface.
- `docs/calc-bridge.md` records the Phase 16 reach waiver.
- `PLAN.md` rewrites Phase 16 to reflect the foundation + feature
  split and the decisions baked in (map-driven picker, inline
  reach, optimistic overlay via `setExtraPrimitives`).

Tests:
- `tests/map-pick-mode.test.ts` — pure overlay-spec helper.
- `tests/map-cargo-routes.test.ts` — `buildCargoRouteLines`.
- `tests/inspector-planet-cargo-routes.test.ts` — slot rendering,
  picker invocation, collapse, cancel, remove.
- Extensions to `order-draft`, `submit`, `order-load`,
  `order-overlay`, `state-binding`, `inspector-planet`,
  `inspector-overlay`, `game-shell-sidebar`, `game-shell-header`.
- `tests/e2e/cargo-routes.spec.ts` — Playwright happy path: add
  COL, add CAP, remove COL, asserting both the inspector and the
  arrow count via `__galaxyDebug.getMapPrimitives()`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 20:01:34 +02:00

199 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Russian translation dictionary. The keys are identical to the
// English dictionary in `en.ts`; the values are the human Russian
// text. Adding a new key requires updating every locale file in
// this folder so the `t()` helper does not fall back to English.
import type en from "./en";
const ru: Record<keyof typeof en, string> = {
"common.language": "язык",
"common.loading": "загрузка…",
"common.browser_not_supported_title": "браузер не поддерживается",
"common.browser_not_supported_body":
"Galaxy требует поддержки Ed25519 в WebCrypto. См. список поддерживаемых браузеров.",
"login.title": "вход в Galaxy",
"login.email_label": "электронная почта",
"login.email_required": "адрес не должен быть пустым",
"login.send_code": "отправить код",
"login.sending": "отправляем…",
"login.code_label": "код",
"login.code_required": "код не должен быть пустым",
"login.code_sent_to": "код отправлен на {email}",
"login.verify": "подтвердить",
"login.verifying": "проверяем…",
"login.send_new_code": "отправить новый код",
"login.change_email": "изменить адрес",
"login.challenge_expired":
"запрос устарел, запросите новый код",
"login.code_expired_or_used":
"код устарел или уже использован, запросите новый",
"login.device_key_not_ready":
"ключ устройства ещё не готов, перезагрузите страницу",
"lobby.title": "вы вошли в систему",
"lobby.device_session_id_label": "идентификатор сессии устройства",
"lobby.greeting": "здравствуйте, {name}!",
"lobby.account_loading": "загрузка профиля…",
"lobby.logout": "выйти",
"lobby.section.my_games": "мои игры",
"lobby.section.invitations": "ожидающие приглашения",
"lobby.section.applications": "мои заявки",
"lobby.section.public_games": "публичные игры",
"lobby.section.create": "создать игру",
"lobby.create_button": "создать новую игру",
"lobby.my_games.empty": "пока нет игр",
"lobby.invitations.empty": "приглашений нет",
"lobby.applications.empty": "заявок нет",
"lobby.public_games.empty": "публичных игр нет",
"lobby.invitation.accept": "принять",
"lobby.invitation.decline": "отклонить",
"lobby.application.submit": "подать заявку",
"lobby.application.submit_for": "подать заявку в {name}",
"lobby.application.race_name_label": "название расы",
"lobby.application.race_name_required": "название расы не должно быть пустым",
"lobby.application.cancel": "отмена",
"lobby.application.submitted": "заявка отправлена, ожидает одобрения",
"lobby.application.status.pending": "ожидает",
"lobby.application.status.approved": "одобрена",
"lobby.application.status.rejected": "отклонена",
"lobby.application.status.unknown": "{status}",
"lobby.list_loading": "загрузка…",
"lobby.create.title": "создание новой игры",
"lobby.create.game_name_label": "название игры",
"lobby.create.description_label": "описание",
"lobby.create.turn_schedule_label": "расписание ходов",
"lobby.create.turn_schedule_hint": "cron из пяти полей, например 0 0 * * *",
"lobby.create.enrollment_ends_at_label": "окончание набора",
"lobby.create.advanced": "дополнительно",
"lobby.create.min_players_label": "мин. игроков",
"lobby.create.max_players_label": "макс. игроков",
"lobby.create.start_gap_hours_label": "интервал старта (часы)",
"lobby.create.start_gap_players_label": "интервал старта (игроки)",
"lobby.create.target_engine_version_label": "версия движка",
"lobby.create.submit": "создать",
"lobby.create.submitting": "создаём…",
"lobby.create.cancel": "отмена",
"lobby.create.game_name_required": "название игры не должно быть пустым",
"lobby.create.turn_schedule_required": "расписание ходов не должно быть пустым",
"lobby.create.enrollment_ends_at_required": "время окончания набора обязательно",
"lobby.error.invalid_request": "запрос некорректен",
"lobby.error.subject_not_found": "объект не найден",
"lobby.error.forbidden": "операция запрещена",
"lobby.error.conflict": "запрос конфликтует с текущим состоянием",
"lobby.error.internal_error": "внутренняя ошибка сервера",
"lobby.error.unknown": "{message}",
"game.shell.unknown": "?",
"game.shell.headline": "{race} @ {game}, ход {turn}",
"game.shell.connection.online": "онлайн",
"game.shell.connection.reconnecting": "переподключение…",
"game.shell.connection.offline": "офлайн",
"game.shell.menu.toggle_sidebar": "открыть боковую панель",
"game.shell.menu.close_sidebar": "закрыть боковую панель",
"game.shell.menu.open_views": "открыть меню видов",
"game.shell.menu.close_views": "закрыть меню видов",
"game.shell.menu.account": "аккаунт",
"game.shell.menu.settings": "настройки",
"game.shell.menu.sessions": "сессии",
"game.shell.menu.theme": "тема",
"game.shell.menu.language": "язык",
"game.shell.menu.logout": "выйти",
"game.shell.coming_soon": "скоро будет",
"game.view.map": "карта",
"game.view.table": "таблица",
"game.view.table.planets": "планеты",
"game.view.table.ship_classes": "классы кораблей",
"game.view.table.ship_groups": "группы кораблей",
"game.view.table.fleets": "флоты",
"game.view.table.sciences": "науки",
"game.view.table.races": "расы",
"game.view.report": "отчёт хода",
"game.view.battle": "журнал боёв",
"game.view.mail": "дипломатическая почта",
"game.view.designer.ship_class": "конструктор класса кораблей",
"game.view.designer.science": "редактор наук",
"game.sidebar.tab.calculator": "калькулятор",
"game.sidebar.tab.inspector": "инспектор",
"game.sidebar.tab.order": "приказ",
"game.sidebar.empty.calculator": "скоро будет",
"game.sidebar.empty.inspector": "выберите объект на карте",
"game.sidebar.empty.order": "приказ пуст",
"game.sidebar.order.command_delete": "удалить",
"game.sidebar.order.sync.idle": "нет изменений",
"game.sidebar.order.sync.in_flight": "синхронизация…",
"game.sidebar.order.sync.synced": "сохранено на сервере",
"game.sidebar.order.sync.error": "ошибка синхронизации: {message}",
"game.sidebar.order.sync.retry": "повторить",
"game.sidebar.order.status.draft": "черновик",
"game.sidebar.order.status.valid": "готова",
"game.sidebar.order.status.invalid": "ошибка",
"game.sidebar.order.status.submitting": "отправка",
"game.sidebar.order.status.applied": "принята",
"game.sidebar.order.status.rejected": "отклонена",
"game.sidebar.order.label.placeholder": "{label}",
"game.sidebar.order.label.planet_rename": "переименовать планету {planet} → {name}",
"game.sidebar.order.label.planet_production": "сменить производство планеты {planet} → {target}",
"game.bottom_tabs.map": "карта",
"game.bottom_tabs.calc": "калк",
"game.bottom_tabs.order": "приказ",
"game.bottom_tabs.more": "ещё",
"game.inspector.planet.kind.local": "ваша планета",
"game.inspector.planet.kind.other": "планета другой расы",
"game.inspector.planet.kind.uninhabited": "необитаемая планета",
"game.inspector.planet.kind.unidentified": "неопознанная планета",
"game.inspector.planet.field.name": "название",
"game.inspector.planet.field.owner": "владелец",
"game.inspector.planet.field.coordinates": "координаты",
"game.inspector.planet.field.size": "размер",
"game.inspector.planet.field.population": "население",
"game.inspector.planet.field.colonists": "колонисты",
"game.inspector.planet.field.industry": "промышленность",
"game.inspector.planet.field.industry_stockpile": "запасы промышленности ($)",
"game.inspector.planet.field.materials_stockpile": "запасы сырья (M)",
"game.inspector.planet.field.natural_resources": "природные ресурсы",
"game.inspector.planet.field.production": "текущее производство",
"game.inspector.planet.field.free_industry": "свободные мощности",
"game.inspector.planet.production_none": "не задано",
"game.inspector.planet.unidentified_no_data": "нет данных — известно только местоположение",
"game.inspector.sheet_close": "закрыть",
"game.inspector.planet.action.rename": "переименовать",
"game.inspector.planet.rename.title": "переименование планеты",
"game.inspector.planet.rename.confirm": "сохранить",
"game.inspector.planet.rename.cancel": "отмена",
"game.inspector.planet.rename.invalid.empty": "имя не может быть пустым",
"game.inspector.planet.rename.invalid.too_long": "имя слишком длинное (максимум 30 символов)",
"game.inspector.planet.rename.invalid.starts_with_special": "имя не может начинаться со спецсимвола",
"game.inspector.planet.rename.invalid.ends_with_special": "имя не может заканчиваться спецсимволом",
"game.inspector.planet.rename.invalid.consecutive_specials": "слишком много спецсимволов подряд",
"game.inspector.planet.rename.invalid.whitespace": "имя не может содержать пробелы",
"game.inspector.planet.rename.invalid.disallowed_character": "имя содержит недопустимые символы",
"game.inspector.planet.production.title": "производство",
"game.inspector.planet.production.option.industry": "промышленность",
"game.inspector.planet.production.option.materials": "сырьё",
"game.inspector.planet.production.option.research": "исследование",
"game.inspector.planet.production.option.ship": "корабль",
"game.inspector.planet.production.research.drive": "двигатель",
"game.inspector.planet.production.research.weapons": "оружие",
"game.inspector.planet.production.research.shields": "щиты",
"game.inspector.planet.production.research.cargo": "трюм",
"game.inspector.planet.production.ship.no_classes": "классы кораблей ещё не спроектированы",
"game.inspector.planet.cargo.title": "грузовые маршруты",
"game.inspector.planet.cargo.slot.col": "колонисты",
"game.inspector.planet.cargo.slot.cap": "промышленность",
"game.inspector.planet.cargo.slot.mat": "сырьё",
"game.inspector.planet.cargo.slot.emp": "пустые корабли",
"game.inspector.planet.cargo.empty": "(маршрута нет)",
"game.inspector.planet.cargo.add": "добавить",
"game.inspector.planet.cargo.edit": "изменить",
"game.inspector.planet.cargo.remove": "удалить",
"game.inspector.planet.cargo.pick.prompt": "выбери цель на карте (Esc — отмена)",
"game.inspector.planet.cargo.pick.cancel": "отменить выбор",
"game.inspector.planet.cargo.pick.no_destinations": "нет планет в зоне полёта {reach} ед.",
"game.sidebar.order.label.cargo_route_set": "маршрут {loadType} с планеты {source} → планета {destination}",
"game.sidebar.order.label.cargo_route_remove": "удалить маршрут {loadType} с планеты {source}",
};
export default ru;