This commit is contained in:
Mikan
2026-06-19 11:28:04 +03:00
commit 53c89829a8
80 changed files with 12482 additions and 0 deletions

168
frontend/src/i18n/en.ts Normal file
View File

@@ -0,0 +1,168 @@
export const en = {
app: {
title: "AI RPG",
subtitle: "Flexible AI-powered role-playing game",
},
nav: {
home: "Home",
dashboard: "My worlds",
admin: "Admin",
logout: "Logout",
login: "Login",
register: "Register",
language: "Language",
},
auth: {
login_title: "Login",
register_title: "Register",
email: "Email",
username: "Username",
password: "Password",
login_btn: "Login",
register_btn: "Register",
no_account: "No account? Register",
have_account: "Have an account? Login",
admin_setup_title: "Admin setup",
admin_setup_desc: "Enter the token printed to the backend console to create the first admin user.",
admin_setup_token: "Setup token",
setup_btn: "Create admin",
},
worlds: {
title: "Your worlds",
new: "Create new world",
empty: "You don't have any worlds yet.",
preset_choice: "Pick a preset or start from scratch",
use_preset: "From preset",
from_scratch: "From scratch",
name: "World name",
language: "World language",
create: "Create",
cancel: "Cancel",
start: "Start game",
continue: "Continue",
edit: "Edit",
delete: "Delete",
builder_title: "World builder",
builder_desc: "Describe your world — the AI will help you build it out.",
setting_brief: "Setting",
setting_brief_ph: "Dark fantasy in a late-medieval style...",
character_brief: "Character",
character_brief_ph: "Young adventurer seeking fame...",
rules_brief: "World rules",
rules_brief_ph: "Mana-based magic system, d20 turn-based combat...",
notes: "Additional notes",
notes_ph: "I want a complex faction reputation system...",
start_builder: "Start dialogue with AI",
builder_history: "Dialogue history",
builder_message_ph: "Your reply or edits...",
send: "Send",
accept: "Accept world and create",
accepting: "Creating world...",
status_draft: "Draft",
status_ready: "Ready",
status_active: "Active",
status_archived: "Archived",
},
session: {
title: "Session",
back: "Back to worlds",
glossary: "Glossary",
character: "Character",
edit_world: "Edit world",
history: "History",
action_placeholder: "What do you do?",
send: "Act",
sending: "Thinking...",
options: "Options",
custom_action: "Or your own action",
status_planning: "Planning...",
status_orchestrator_turn: "GM turn...",
status_writing_scene: "Writing scene...",
world_time: "World time",
triggers_panel: "Deferred events",
no_messages: "Start with your first action!",
new_session: "New session",
error_iter: "Iteration failed",
},
admin: {
title: "Admin panel",
settings: "LLM settings",
base_url: "OpenAI-compatible endpoint",
api_key: "API key",
model: "Model",
temperature: "Temperature (orchestrator)",
step_temperature: "Temperature (step writer)",
summary_temperature: "Temperature (summarizer)",
max_tokens: "Max tokens",
request_timeout: "Timeout (sec)",
streaming: "Streaming",
context_settings: "Context manager",
recent_messages: "Guaranteed recent messages",
compress_threshold: "Compression threshold",
summary_messages: "Messages per summary",
max_tokens_total: "Context token budget",
trigger_settings: "Deferred triggers",
triggers_enabled: "Enabled",
triggers_check_interval: "Check interval (sec)",
embedding_settings: "Embeddings (RAG)",
embedding_provider: "Provider",
embedding_provider_hash: "Hash (offline fallback, no semantics)",
embedding_provider_openai: "OpenAI-compatible /embeddings",
embedding_base_url: "Endpoint (empty = same as LLM)",
embedding_api_key: "API key (empty = same as LLM)",
embedding_model: "Embedding model",
embedding_dim: "Dimension (0 = auto-probe)",
embedding_timeout: "Timeout (sec)",
embedding_test: "Test embeddings",
embedding_testing: "Testing...",
embedding_test_ok: "OK: {{provider}} | dim={{dim}} | norm={{norm}}",
embedding_test_fail: "Error: {{error}}",
save: "Save",
saved: "Saved!",
llm_logs: "LLM logs",
users: "Users",
back: "Back",
},
glossary: {
title: "World glossary",
npc: "NPCs",
location: "Locations",
item: "Items",
lore: "Lore",
event: "Events",
rule: "Rules",
empty: "Nothing yet. The AI will fill the glossary as you play.",
},
character: {
title: "Character sheet",
name: "Name",
race: "Race",
class: "Class",
level: "Level",
stats: "Stats",
inventory: "Inventory",
effects: "Effects",
gold: "Gold",
location: "Location",
empty: "No character data.",
},
common: {
save: "Save",
cancel: "Cancel",
delete: "Delete",
edit: "Edit",
confirm: "Confirm",
yes: "Yes",
no: "No",
loading: "Loading...",
error: "Error",
success: "Done",
not_found: "Not found",
forbidden: "Forbidden",
},
errors: {
network: "Network error. Check your connection.",
unauthorized: "Unauthorized.",
unknown: "Unknown error.",
},
};

View File

@@ -0,0 +1,24 @@
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { ru } from "./ru";
import { en } from "./en";
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
ru: { translation: ru },
en: { translation: en },
},
fallbackLng: "ru",
supportedLngs: ["ru", "en"],
interpolation: { escapeValue: false },
detection: {
order: ["localStorage", "navigator"],
caches: ["localStorage"],
},
});
export default i18n;

168
frontend/src/i18n/ru.ts Normal file
View File

@@ -0,0 +1,168 @@
export const ru = {
app: {
title: "AI RPG",
subtitle: "Гибкая ролевая игра с ИИ",
},
nav: {
home: "Главная",
dashboard: "Мои миры",
admin: "Админка",
logout: "Выйти",
login: "Войти",
register: "Регистрация",
language: "Язык",
},
auth: {
login_title: "Вход",
register_title: "Регистрация",
email: "Email",
username: "Имя пользователя",
password: "Пароль",
login_btn: "Войти",
register_btn: "Зарегистрироваться",
no_account: "Нет аккаунта? Зарегистрируйтесь",
have_account: "Уже есть аккаунт? Войдите",
admin_setup_title: "Создание администратора",
admin_setup_desc: "Введите токен из консоли backend, чтобы создать первого администратора.",
admin_setup_token: "Токен инициализации",
setup_btn: "Создать администратора",
},
worlds: {
title: "Ваши миры",
new: "Создать новый мир",
empty: "У вас пока нет ни одного мира.",
preset_choice: "Выберите пресет или начните с нуля",
use_preset: "Из пресета",
from_scratch: "С нуля",
name: "Название мира",
language: "Язык мира",
create: "Создать",
cancel: "Отмена",
start: "Начать игру",
continue: "Продолжить",
edit: "Редактировать",
delete: "Удалить",
builder_title: "Конструктор мира",
builder_desc: "Опишите свой мир — ИИ поможет его достроить.",
setting_brief: "Сеттинг",
setting_brief_ph: "Тёмное фэнтези в духе позднего средневековья...",
character_brief: "Персонаж",
character_brief_ph: "Молодой авантюрист, ищущий славы...",
rules_brief: "Правила мира",
rules_brief_ph: "Система магии с маной, пошаговый бой d20...",
notes: "Дополнительные заметки",
notes_ph: "Хочу сложную систему репутации с фракциями...",
start_builder: "Начать диалог с ИИ",
builder_history: "История диалога",
builder_message_ph: "Ваш ответ или правки...",
send: "Отправить",
accept: "Принять мир и создать",
accepting: "Создаём мир...",
status_draft: "Черновик",
status_ready: "Готов",
status_active: "Активен",
status_archived: "В архиве",
},
session: {
title: "Сессия",
back: "Назад к мирам",
glossary: "Глоссарий",
character: "Персонаж",
edit_world: "Редактировать мир",
history: "История",
action_placeholder: "Что вы делаете?",
send: "Действие",
sending: "Думаю...",
options: "Варианты",
custom_action: "Или своё действие",
status_planning: "Планирование...",
status_orchestrator_turn: "Ход GM...",
status_writing_scene: "Пишем сцену...",
world_time: "Время мира",
triggers_panel: "Отложенные события",
no_messages: "Начните с первого действия!",
new_session: "Новая сессия",
error_iter: "Ошибка при выполнении итерации",
},
admin: {
title: "Панель администратора",
settings: "Настройки LLM",
base_url: "OpenAI-совместимый endpoint",
api_key: "API ключ",
model: "Модель",
temperature: "Temperature (orchestrator)",
step_temperature: "Temperature (step writer)",
summary_temperature: "Temperature (summarizer)",
max_tokens: "Max tokens",
request_timeout: "Таймаут (сек)",
streaming: "Стриминг",
context_settings: "Контекстный менеджер",
recent_messages: "Гарантированных сообщений",
compress_threshold: "Порог сжатия",
summary_messages: "Сообщений на сводку",
max_tokens_total: "Бюджет токенов контекста",
trigger_settings: "Отложенные триггеры",
triggers_enabled: "Включены",
triggers_check_interval: "Интервал проверки (сек)",
embedding_settings: "Эмбеддинги (RAG)",
embedding_provider: "Провайдер",
embedding_provider_hash: "Hash (офлайн-фолбэк, без семантики)",
embedding_provider_openai: "OpenAI-compatible /embeddings",
embedding_base_url: "Endpoint (пусто = как у LLM)",
embedding_api_key: "API ключ (пусто = как у LLM)",
embedding_model: "Модель эмбеддингов",
embedding_dim: "Размерность (0 = авто-проба)",
embedding_timeout: "Таймаут (сек)",
embedding_test: "Проверить эмбеддинги",
embedding_testing: "Проверяю...",
embedding_test_ok: "OK: {{provider}} | dim={{dim}} | norm={{norm}}",
embedding_test_fail: "Ошибка: {{error}}",
save: "Сохранить",
saved: "Сохранено!",
llm_logs: "Логи LLM",
users: "Пользователи",
back: "Назад",
},
glossary: {
title: "Глоссарий мира",
npc: "NPC",
location: "Локации",
item: "Предметы",
lore: "Лор",
event: "События",
rule: "Правила",
empty: "Пока пусто. ИИ заполнит глоссарий по ходу игры.",
},
character: {
title: "Лист персонажа",
name: "Имя",
race: "Раса",
class: "Класс",
level: "Уровень",
stats: "Характеристики",
inventory: "Инвентарь",
effects: "Эффекты",
gold: "Золото",
location: "Локация",
empty: "Нет данных о персонаже.",
},
common: {
save: "Сохранить",
cancel: "Отмена",
delete: "Удалить",
edit: "Редактировать",
confirm: "Подтвердить",
yes: "Да",
no: "Нет",
loading: "Загрузка...",
error: "Ошибка",
success: "Готово",
not_found: "Не найдено",
forbidden: "Доступ запрещён",
},
errors: {
network: "Сетевая ошибка. Проверьте подключение.",
unauthorized: "Не авторизован.",
unknown: "Неизвестная ошибка.",
},
};