// Русская локаль — источник правды ключей; en.ts/uk.ts типизируются как typeof ru.
// Namespaces по областям UI (см. план i18n): common, nav, stack, tree, list,
// options, projects, settings, taskui.
export default {
common: {
any: '— любой —',
anyStatus: '— любой статус —',
noProject: '— без проекта —',
none: '— нет —',
choose: '— выберите —',
notSet: '— не указано —',
error: 'Ошибка запроса',
save: 'Сохранить',
cancel: 'Отмена',
edit: 'Редактировать',
preview: 'Предпросмотр',
confirmTitle: 'Подтверждение',
delete: 'Удалить',
open: 'Открыть',
expand: 'Развернуть',
collapse: 'Свернуть',
deleteConfirmTask: 'Удалить задачу «{title}»? Действие необратимо.',
deleteConfirmProject: 'Удалить проект «{name}»? Задачи останутся, но без проекта.',
archive: 'В архив',
archiveTitle: 'Отправить в архив',
saved: 'Сохранено',
created: 'Создано',
create: 'Создать',
taskDeleted: 'Задача удалена',
projectDeleted: 'Проект удалён',
taskApproved: 'Задача утверждена',
taskTaken: 'Задача взята в работу',
taskFinished: 'Задача завершена',
},
nav: {
sections: 'Разделы',
subtitle: 'GNexus Tasks — личные задачи',
signIn: 'Войти',
account: 'Аккаунт',
signOut: 'Выйти',
task: 'Задача',
home: 'Главная',
stack: 'Стек входящих',
list: 'Список задач',
garden: 'Сад',
stats: 'Статистика',
projects: 'Проекты',
archive: 'Архив',
options: 'Выдача задачи',
settings: 'Настройки',
},
garden: {
title: 'Сад',
level: 'Уровень {n}',
xpTotal: '{n} XP',
plants: 'растений: {n}',
levelProgress: 'До уровня: {xp} / {span} XP',
aboutOpen: 'Как это работает',
aboutTitle: 'Как устроен сад',
levelsTitle: 'Дерево уровней',
levelsHint:
'Пороги XP и награды каждого уровня: новые виды растений (цена семени) и расширения карты. Уровень растёт из опыта за задачи — ничего не сгорает.',
levelCurrent: 'текущий',
achDone: 'Все ступени пройдены (высшая — {r})',
achStep: 'Ступень: римская — номер, дробь — прогресс к следующей',
rewardCreateTask: 'создание задачи',
rewardCreateProject: 'создание проекта',
about: [
'Каждая закрытая задача оставляет на грядке растение — сад только растёт и никогда не уменьшается.',
'За закрытие начисляется XP: база 10 + бонус за приоритет задачи (до 15) + бонус за объём работы по оценке времени (до 15) + 10 за «ментально сложную» — честная награда за силу воли. Крупные и срочные дела ценнее.',
'Накопленный XP повышает уровень — от «Ростка» до «Легенды сада». Уровень не падает: XP не сгорает и не отнимается, даже если задачу удалить.',
'Иногда задача приносит редкое растение — шанс тем выше, чем «весомее» задача. Эпические растения достаются только крупным закрытиям.',
'Общий принцип: опыт открывает, монеты покупают. Опыт (уровень) открывает новые виды растений и землю; монеты тратятся на рост растений, декорации и расширение карты. Монеты приходят за закрытые задачи (половина XP) и за новые уровни.',
'Достижения отмечают вехи: закрытые задачи, уровни, разные проекты, часы работы, строгие дедлайны, «ментально сложные» задачи. У каждой ступени I, II, III — прогресс виден всегда.',
'Задача, закрытая из режима «3 вариантов», отмечается меткой «выбрал и сделал». Закрытие «не хочется делать» празднуется золотом — сила воли того стоила. Ничего не сгорает, серий и наказаний нет — только приятные награды.',
],
lastReward: 'Последняя награда за: {title} — {date}',
emptyTitle: 'Сад пока пуст',
emptyText: 'Закройте первую задачу — на грядке появится растение.',
levels: [
'Росток',
'Сеянцев',
'Садовник',
'Огородник',
'Дендролог',
'Лесничий',
'Садовый мастер',
'Хранитель сада',
'Королевский садовник',
'Магистр садоводства',
'Ландшафтный архитектор',
'Хранитель легенд',
'Легенда сада',
],
achievements: 'Достижения',
coins: 'монет: {n}',
coinsHint: 'Валюта сада: тратится на рост растений и декорации',
shop: 'Маркет',
shopTitle: 'Маркет сада',
buy: 'Купить',
notEnoughCoins: 'Не хватает {n} монет',
lockedUntil: 'Откроется на уровне {n}',
expansion: 'Расширение сада',
expansionHint: 'Больше земли — {n} клеток к периметру карты',
expansionCurrent: 'Текущая карта: {cols}×{rows}',
expansionMax: 'Вся земля открыта',
inventory: 'Инвентарь',
inventoryHint: 'Перетащите декорацию или семя на карту; декорацию можно вернуть обратно',
inventoryEmpty: 'Пока пусто: купленные декорации ждут здесь — перетащите их на карту',
zoomIn: 'Приблизить',
zoomOut: 'Отдалить',
zoomReset: 'Сбросить вид',
fullscreen: 'Во весь экран',
fullscreenExit: 'Выйти из полного экрана',
boughtHint: 'Куплено: {name} — перетащите её из инвентаря под картой на сад',
decorations: 'Декорации',
decorationsHint: 'Украсьте сад — декорации не дают бонусов, только настроение',
unique: 'уникальная',
rareOnly: 'только редкие растения',
seeds: 'Семена растений',
seedsHint: 'Открытые уровнем виды можно купить: семя попадает в инвентарь — перетащите его на свободную клетку. Редкие/эпик рождаются только из задач.',
seedBought: 'Семя куплено — перетащите его из инвентаря на грядку',
speciesHint:
'Опыт открывает новые виды и землю, монеты покупают семена, рост и украшения. Вид фиксируется за растением в момент рождения.',
upgrade: 'Вырастить — {n} монет',
maxStage: 'Полностью выросло',
stage: { sprout: 'Росток', bush: 'Куст', bloom: 'Цветение' },
speciesNames: {
'ph-flower': 'Цветок',
'ph-leaf': 'Зелень',
'ph-tree-evergreen': 'Ель',
'ph-flower-lotus': 'Лотос',
'ph-cactus': 'Кактус',
'ph-tree': 'Дуб',
'ph-drop': 'Роса',
'ph-sun': 'Подсолнух',
'ph-tree-structure': 'Бонсай',
'ph-butterfly': 'Бабочий куст',
'ph-campfire': 'Рябина',
'ph-sparkle': 'Звездоцвет',
'ph-fire': 'Огнецвет',
},
decorNames: {
fence: 'Изгородь',
bush: 'Куст',
flowerbed: 'Клумба',
lantern: 'Фонарь',
bench: 'Лавочка',
birdbath: 'Поилка для птиц',
flag: 'Флюгер',
birdhouse: 'Скворечник',
gem: 'Садовый самоцвет',
pond: 'Пруд',
greenhouse: 'Теплица',
gazebo: 'Беседка',
},
ach: {
firstDone: 'Первый росток',
done10: 'Десяток',
level5: 'Высоты',
sprinter: 'Спринтер',
explorer: 'Разносторонний',
marathon: 'Марафонец',
deadlineBoss: 'Дедлайн-босс',
chooser: 'Выбрал и сделал',
willpower: 'Преодоление',
recurring: 'Ритм жизни',
projectDone: 'Проект под ключ',
},
},
gamify: {
praise: [
'Отлично сделано!',
'Готово — полдела!',
'Ещё один шаг впереди.',
'Красота!',
'Так держать!',
'Минус одна задача, плюс настроение.',
],
rarePlant: 'На грядке редкое растение!',
epicPlant: 'Легендарное растение в саду!',
chosen: 'выбрал и сделал',
willpower: 'сила воли',
willpowerText: 'Сила воли! Это того стоило.',
coins: 'монет',
createdReward: 'Создано — капля опыта уже ваша',
daily: 'Ежедневная награда за визит',
},
stats: {
title: 'Статистика',
modeDay: 'День',
modeWeek: 'Неделя',
modeMonth: 'Месяц',
today: 'Сегодня, {date}',
prevPeriod: 'Предыдущий период',
nextPeriod: 'Следующий период',
ofDays: 'из {n} дн.',
totalVs: 'За период закрыто: {n} · в предыдущий раз: {m}',
chartTitle: 'Закрытые задачи',
legendNow: 'Сейчас',
legendPrev: 'Предыдущий период',
heatmapHalf: 'Активность за полгода',
heatmapYear: 'Активность за год',
heatTasks: 'Задачи',
heatXp: 'XP',
heatLess: 'меньше',
heatMore: 'больше',
heatHalf: 'Полгода',
heatYear: 'Год',
emptyTitle: 'Пока нет данных',
emptyText: 'Закройте пару задач — и здесь появится динамика со сравнением.',
metric: {
closed: 'Закрыто задач',
xp: 'XP получено',
created: 'Создано задач',
hours: 'Часы работы',
activeDays: 'Дни с результатом',
},
},
home: {
title: 'Главное',
stackCount: 'в стеке: {n}',
activeCount: 'активных: {n}',
inProgress: 'В работе',
overdue: 'Просрочено',
deadlines: 'Дедлайны на неделю',
next: 'Следующие',
overview: 'Обзор',
projects: 'Активные проекты',
totalTasks: 'Всего задач',
doneMonth: 'Выполнено за месяц',
doneAll: 'Выполнено всего',
clearTitle: 'Всё спокойно',
clearText: 'Нет активных задач — самое время закрыть что-то из стека.',
},
stack: {
title: 'Стек входящих',
count: 'Задач в стеке: {n}',
quickPlaceholder: 'Закинуть задачу — только текст, остальное потом…',
quickAdd: 'Закинуть',
newTask: 'Новая задача',
added: 'Задача закинута в стек',
detailTitle: 'Детализация задачи',
emptyTitle: 'Стек пуст',
emptyText: 'Закиньте первую задачу — детализация подберётся автоматически.',
inStack: 'в стеке',
uploading: 'загрузка…',
proposal: 'Предложение ИИ:',
proposalPending: 'Детализация подбирается…',
proposalNewProject: '+ проект «{name}»',
approveProposal: 'Да, всё верно',
detail: 'Детализировать',
redetail: 'Переспросить ИИ',
deleteTask: 'Удалить задачу',
deleteAttachment: 'Удалить вложение',
promptProject: 'Название нового проекта:',
promptTag: 'Название нового тега:',
newProject: 'Новый проект',
newTag: 'Новый тег',
approve: 'Утвердить',
form: {
title: 'Заголовок',
description: 'Описание (Markdown, Ctrl+V — картинка)',
preview: 'Предпросмотр Markdown',
project: 'Проект',
tagsPlaceholder: 'Добавить тег…',
tags: 'Теги',
priority: 'Приоритет',
estimate: 'Оценка времени',
budget: 'Бюджет (в валюте настроек)',
cost: 'Оценка затрат (в валюте настроек)',
estimateLegend: 'Оценка',
extra: 'Дополнительно',
},
deadline: {
legend: 'Дедлайн',
date: 'Строгий — дата',
period: 'Нестрогий — период',
},
recur: {
legend: 'Тип задачи',
oneTime: 'Разовая',
recurring: 'Регулярная (повторяется)',
kind: 'Правило повторения',
interval: 'Интервал, дней',
weekdays: 'Дни недели',
monthlyDay: 'День месяца (1–31, без дня — последний)',
},
},
tree: {
addSubtask: 'Добавить подзадачу',
promptSubtask: 'Подзадача:',
},
task: {
notFoundTitle: 'Задача не найдена',
notFoundText: 'Возможно, задача удалена или ссылка устарела.',
proposalNewTitle: 'Новый заголовок',
proposalNewDescription: 'Описание с шагами',
proposalTitle: 'Предложение ИИ',
proposalHint: 'Проверьте детали и утвердите — задача попадёт в список.',
proposalMyself: 'Я сам',
description: 'Описание',
editTitle: 'Изменить название',
editDescription: 'Редактировать описание',
deadlineConflict: 'Дедлайн: либо дата, либо период — не оба',
descriptionEmpty: 'Описание пусто — детализируйте задачу.',
attachments: 'Вложения',
fields: 'Параметры',
dates: 'Даты',
field: {
project: 'Проект',
taskType: 'Тип задачи',
priority: 'Приоритет',
estimate: 'Оценка времени',
actual: 'Фактически',
money: 'Деньги',
deadline: 'Дедлайн',
recurrence: 'Повторение',
created: 'Создана',
approved: 'Утверждена',
done: 'Завершена',
},
subtasks: 'Подзадачи',
noSubtasks: 'Подзадач нет',
statusTitle: 'Статус',
changeStatus: 'Изменить статус',
takeWork: 'Взять в работу',
mentallyHard: {
set: 'Не хочется делать',
unset: 'Снять «ментально сложная»',
badge: 'ментально сложная',
},
subtaskCreated: 'Подзадача создана — попала в стек на детализацию',
createdRaw: 'Задача попала в стек — детализируйте её там',
actions: 'Действия',
addTag: 'Добавить тег…',
},
projectPage: {
notFoundTitle: 'Проект не найден',
notFoundText: 'Возможно, проект удалён или ссылка устарела.',
note: 'Заметка',
editNote: 'Редактировать заметку',
noteEmpty: 'Заметки пока нет — добавьте её через «Редактировать».',
progress: 'Задачи проекта: {done}/{total}',
newTask: 'Новая задача',
taskCreated: 'Задача создана — попала в стек на детализацию',
promptTask: 'Новая задача проекта:',
emptyTitle: 'Задач нет',
emptyText: 'Создайте первую задачу проекта или ослабьте фильтры.',
tree: 'Дерево проекта',
stats: 'Статистика',
total: 'Всего задач',
doneN: 'Завершено',
inProgress: 'В работе',
toDo: 'К выполнению',
overdue: 'Просрочено',
taskCount: '{n} задач',
},
list: {
title: 'Список задач',
count: 'Найдено: {n}',
emptyTitle: 'Ничего не найдено',
emptyText: 'Попробуйте ослабить фильтры или закиньте новую задачу в стек.',
filterStatus: 'Статус',
filterProject: 'Проект',
filterTag: 'Тег',
filterPriority: 'Приоритет',
},
options: {
title: 'Выдача задачи',
done: 'Готово',
notNow: 'Не сейчас — другие варианты',
availableHours: 'Доступное время, часов',
suggest: 'Предложить',
choose: 'Делаем сейчас',
emptyTitle: 'Вариантов нет',
emptyText:
'Свободных задач под это время не нашлось — закиньте что-нибудь в стек или уменьшите время.',
},
projects: {
title: 'Проекты',
count: 'Проектов: {n}',
new: 'Новый проект',
emptyTitle: 'Проектов нет',
emptyText:
'Создайте проект — задачи можно будет группировать и добавлять заметки с ресурсами.',
prompt: 'Название нового проекта:',
promptLabel: 'Название проекта',
taskCounts: 'Задач закрыто {done}/{total}',
archived: 'Проект отправлен в архив',
archiveConfirm:
'Отправить проект «{name}» и его задачи ({n}) в архив? Всё можно будет восстановить из архива.',
edit: 'Редактировать',
delete: 'Удалить проект',
form: {
name: 'Название',
relevance: 'Актуальность',
priority: 'Приоритет',
note: 'Заметка (Markdown: ссылки, контекст)',
preview: 'Предпросмотр',
},
},
pagination: {
prev: 'Назад',
next: 'Вперёд',
pageOf: 'Страница {n} из {m}',
aria: 'Постраничная навигация',
},
archive: {
title: 'Архив',
count: 'Проектов: {n}',
emptyTitle: 'Архив пуст',
emptyText: 'Сюда попадают проекты, отправленные в архив, — вместе со всеми задачами и историей.',
restore: 'Восстановить',
restored: '«{name}» восстановлен из архива',
deleteForever: 'Удалить навсегда',
deleteConfirm:
'Удалить «{name}» навсегда? Проект и все его задачи будут потеряны безвозвратно.',
banner: 'Проект в архиве — история доступна только для просмотра. Восстановите его, чтобы продолжить работу.',
},
settings: {
title: 'Настройки',
currencyTitle: 'Валюта бюджетов',
currencyHint:
'Единица выбирается один раз и применяется во всех суммах: бюджет задачи, оценка затрат.',
currencyUnit: 'Единица измерения',
saved: 'Сохранено — применяется во всех видах.',
languageTitle: 'Язык интерфейса',
languageHint:
'Выбранный язык применяется сразу. «Как в аккаунте» — язык берётся из gnexus auth.',
languageUnit: 'Язык',
languageAuto: 'Как в аккаунте (SSO)',
langRu: 'Русский',
langEn: 'English',
langUk: 'Українська',
mcpHint: 'ИИ-агенты (например, Claude) могут работать с вашими задачами через MCP.',
mcpOpen: 'Как подключить',
},
mcp: {
title: 'MCP для ИИ-агентов',
whatTitle: 'Что это такое',
whatText:
'В приложение встроен MCP-сервер (Model Context Protocol): ИИ-агенты подключаются к нему и работают с вашими задачами от вашего имени — создают, ищут, обновляют и закрывают их. Закрытие задачи агентом даёт те же награды, что и в приложении: XP, монеты, растение в саду; у регулярной задачи следующий экземпляр создаётся автоматически.',
toolsTitle: 'Инструменты',
toolsHint:
'Сервер сам объясняет агенту порядок работы: начинать с проектов, привязывать задачи к проекту, не придумывать идентификаторы и следовать подсказкам в ошибках.',
toolListProjects: 'список проектов: заметки, статус, число открытых задач',
toolGetProject: 'контекст проекта: заметка и открытые задачи',
toolCreateTask: 'создать задачу (достаточно заголовка, желательно с проектом)',
toolUpdateTask: 'обновить поля задачи; закрытие — status="done"',
toolCompleteTask: 'завершить задачу (можно указать фактическое время)',
toolListTasks: 'поиск и фильтры: проект, тег, статус, подстрока',
toolGetTask: 'полные данные задачи, включая вложения',
toolListTags: 'справочник тегов',
connectTitle: 'Как подключить агента',
connectText:
'Транспорт — Streamable HTTP. Адрес совпадает с адресом этого приложения. Для подключения понадобится токен доступа.',
connectUrlLabel: 'Адрес сервера',
connectTokenLabel: 'Токен доступа',
connectTokenText:
'Авторизация — bearer-токен: значение настройки MCP_TOKEN в конфиге backend (переменная окружения, в .env; в репозиторий не попадает). Один токен для всех агентов — храните его как пароль: любой, у кого он есть, может управлять задачами.',
connectClaudeLabel: 'Claude Code — одна команда',
connectJsonLabel: 'Универсальный JSON (Claude Desktop и другие клиенты)',
copy: 'Скопировать',
copied: 'Адрес скопирован',
copyFailed: 'Не удалось скопировать',
projectTitle: 'Контекст проекта',
projectText:
'Агент видит ваши проекты с заметками и их открытые задачи. Сервер инструктирует агента начинать работу с проектов (list_projects → get_project), привязывать создаваемые задачи к проекту и перечитывать get_project, возвращаясь к разговору после перерыва, — так задачи не теряются вне контекста своего проекта.',
},
md: {
bold: 'Жирный',
boldText: 'жирный текст',
italic: 'Курсив',
italicText: 'курсивный текст',
heading: 'Заголовок',
list: 'Список',
checklist: 'Чек-лист',
link: 'Ссылка',
linkText: 'текст ссылки',
code: 'Код',
},
duration: {
hours: 'Часы',
minutes: 'Минуты',
h: 'ч',
min: 'мин',
},
taskui: {
priority: {
very_low: 'Очень низкий',
low: 'Низкий',
medium: 'Средний',
high: 'Высокий',
urgent: 'Срочно',
},
status: {
to_do: 'К выполнению',
in_progress: 'В работе',
done: 'Завершено',
cancelled: 'Отменено',
deferred: 'Отложено',
},
relevance: {
active: 'Активен',
paused: 'Приостановлен',
},
time: {
hm: '{h} ч {m} м',
h: '{h} ч',
m: '{m} м',
},
money: {
budget: 'бюджет {amount}',
estimate: 'оценка {amount}',
},
currency: {
UAH: '₴ Гривна (UAH)',
USD: '$ Доллар (USD)',
EUR: '€ Евро (EUR)',
GBP: '£ Фунт (GBP)',
PLN: 'zł Злотый (PLN)',
},
deadline: {
day: 'в течение дня',
week: 'в течение недели',
month: 'в течение месяца',
year: 'в течение года',
until: 'до {date}',
},
recur: {
kind: {
interval: 'Каждые N дней',
weekdays: 'Дни недели',
monthly: 'День месяца',
},
daily: 'ежедневно',
weekly: 'еженедельно',
everyN: 'каждые {n} дн.',
byWeekdays: 'по дням недели',
monthlyDay: 'ежемесячно {day}-го',
recurring: 'регулярная',
},
},
}