rin
Публичный Open-source lightweight git hosting.
i18n.go · 1269 строк · 77.6 KB
Raw
1 package i18n
2
3 type Lang string
4
5 const (
6 RU Lang = "ru"
7 EN Lang = "en"
8 )
9
10 func Normalize(code string) Lang {
11 switch code {
12 case "en", "EN":
13 return EN
14 default:
15 return RU
16 }
17 }
18
19 var translations = map[Lang]map[string]string{
20 RU: {
21 // Навигация и общее
22 "app.tagline": "Лёгкий self-hosted Git-хостинг",
23 "nav.home": "Главная",
24 "nav.repositories": "Репозитории",
25 "nav.explore": "Обзор",
26 "nav.settings": "Настройки",
27 "nav.admin": "Админка",
28 "nav.agents": "Для AI-агентов",
29 "nav.login": "Войти",
30 "nav.register": "Регистрация",
31 "nav.logout": "Выйти",
32 "nav.new_repo": "Создать",
33 "nav.command_palette": "Поиск и команды",
34 "nav.search_placeholder": "Поиск...",
35 "nav.theme": "Тема",
36 "nav.lang": "Язык",
37 "common.copy": "Копировать",
38 "common.copied": "Скопировано",
39 "common.copy_failed": "Не удалось скопировать",
40 "common.cancel": "Отмена",
41 "common.save": "Сохранить",
42 "common.delete": "Удалить",
43 "common.close": "Закрыть",
44 "common.never": "Никогда",
45 "common.newer": "Новее",
46 "common.older": "Старее",
47 "common.up": "Наверх",
48
49 // Темы (только 3)
50 "theme.light": "Светлая",
51 "theme.dark": "Тёмная",
52 "theme.system": "Авто",
53
54 // Лендинг
55 "landing.badge": "Один бинарник · SQLite · Ноль зависимостей",
56 "landing.hero.title": "Лёгкий self-hosted Git-хостинг",
57 "landing.hero.subtitle": "Один бинарник на Go со встроенным SQLite. Поднимается за минуту, потребляет минимум памяти и не перегружен лишним.",
58 "landing.hero.cta_start": "Начать",
59 "landing.features.title": "Принципы",
60 "landing.feat1.title": "Один бинарник",
61 "landing.feat1.desc": "Шаблоны, стили, шрифты, миграции и иконки вшиты через go:embed.",
62 "landing.feat2.title": "SQLite (WAL)",
63 "landing.feat2.desc": "Вся база — один файл data/polar.db без CGO. Бэкап простым копированием.",
64 "landing.feat3.title": "Быстрый отклик",
65 "landing.feat3.desc": "Мгновенный старт, серверный рендеринг и < 30 МБ памяти в простое.",
66 "landing.feat4.title": "Приватность",
67 "landing.feat4.desc": "Публичные и приватные репозитории, Argon2id и токены доступа для Git HTTP.",
68 // Авторизация
69 "auth.login.title": "Вход",
70 "auth.register.title": "Регистрация",
71 "auth.register.disabled": "Публичная регистрация отключена администратором.",
72 "auth.username": "Имя пользователя",
73 "auth.username_hint": "2–32 символа: латиница, цифры, дефис, подчёркивание",
74 "auth.username_or_email": "Логин или Email",
75 "auth.email": "Email",
76 "auth.password": "Пароль",
77 "auth.password_hint": "Минимум 8 символов",
78 "auth.submit_login": "Войти",
79 "auth.submit_register": "Создать аккаунт",
80 "auth.no_account": "Нет аккаунта?",
81 "auth.have_account": "Уже есть аккаунт?",
82 "auth.invalid_creds": "Неверный логин или пароль",
83
84 // Репозитории
85 "repo.new.title": "Новый репозиторий",
86 "repo.name": "Название",
87 "repo.name_hint": "Латинские буквы, цифры, точка, дефис, подчёркивание",
88 "repo.description": "Описание",
89 "repo.description_ph": "Краткое описание проекта (необязательно)",
90 "repo.visibility": "Доступ",
91 "repo.public": "Публичный",
92 "repo.public_desc": "Виден всем, клонирование без авторизации",
93 "repo.private": "Приватный",
94 "repo.private_desc": "Доступен только владельцу",
95 "repo.create_btn": "Создать репозиторий",
96 "repo.filter_ph": "Фильтр репозиториев...",
97 "repo.empty_list": "Репозиториев пока нет",
98 "repo.empty_list_sub": "Создайте первый репозиторий, чтобы отправить код.",
99 "repo.empty.title": "Репозиторий пуст",
100 "repo.empty.new_cmd": "Создать новый репозиторий в командной строке",
101 "repo.empty.push_cmd": "Отправить существующий репозиторий",
102 "repo.tab.code": "Код",
103 "repo.tab.commits": "Коммиты",
104 "repo.tab.branches": "Ветки и теги",
105 "repo.tab.issues": "Задачи",
106 "repo.tab.pulls": "Пул-реквесты",
107 "repo.tab.releases": "Релизы",
108 "repo.tab.activity": "Активность",
109 "repo.tab.settings": "Настройки",
110 "repo.features": "Возможности репозитория",
111 "repo.clone": "Клонировать",
112 "repo.download_zip": "Скачать ZIP",
113 "repo.branches": "Ветки",
114 "repo.tags": "Теги",
115 "repo.default_branch": "Ветка по умолчанию",
116 "repo.find_file": "Поиск файла...",
117 "repo.files": "Файлы",
118 "repo.readme": "README",
119 "repo.raw": "Raw",
120 "repo.history": "История",
121 "repo.lines": "строк",
122 "repo.lines_one": "строка",
123 "repo.lines_few": "строки",
124 "repo.lines_many": "строк",
125 "repo.binary_notice": "Бинарный файл — предпросмотр недоступен",
126 "repo.download_raw": "Скачать файл",
127 "repo.browse_at_commit": "Файлы на момент коммита",
128 "repo.files_changed": "файлов изменено",
129 "repo.files_changed_one": "файл изменён",
130 "repo.files_changed_few": "файла изменено",
131 "repo.files_changed_many": "файлов изменено",
132 "repo.no_commits": "Коммитов пока нет",
133 "repo.danger_zone": "Опасная зона",
134 "repo.delete": "Удалить репозиторий",
135 "repo.delete_desc": "Удаление необратимо: все файлы и история git будут стёрты.",
136 "repo.delete_confirm": "Введите название репозитория для подтверждения",
137 "repo.rename": "Переименовать",
138 "repo.save": "Сохранить",
139 "repo.branch.new": "Новая ветка",
140 "repo.branch.name_ph": "Имя ветки (напр. feat/ui)",
141 "repo.branch.from": "От ветки / коммита",
142 "repo.branch.create": "Создать ветку",
143 "repo.branch.default": "по умолчанию",
144 "repo.tag.new": "Новый тег / релиз",
145 "repo.tag.name_ph": "Тег (напр. v1.0.0)",
146 "repo.tag.msg_ph": "Описание тега (необязательно)",
147 "repo.tag.create": "Создать тег",
148 "repo.tags.empty": "Тегов пока нет",
149
150 // Pull Requests
151 "pulls.title": "Пул-реквесты",
152 "pulls.new": "Новый пул-реквест",
153 "pulls.empty": "Пул-реквестов пока нет",
154 "pulls.open": "Открыт",
155 "pulls.closed": "Закрыт",
156 "pulls.merged": "Слит",
157 "pulls.compare": "Сравнение веток",
158 "pulls.base": "Базовая ветка",
159 "pulls.head": "Ветка изменений",
160 "pulls.title_ph": "Заголовок пул-реквеста...",
161 "pulls.desc_ph": "Опишите предлагаемые изменения (Markdown)...",
162 "pulls.create_btn": "Создать пул-реквест",
163 "pulls.merge_btn": "Слить пул-реквест",
164 "pulls.can_merge": "Ветки можно объединить автоматически.",
165 "pulls.cannot_merge": "Невозможно объединить автоматически: обнаружены конфликты.",
166 "pulls.already_merged": "Ветка изменений уже объединена с базовой.",
167 "pulls.close_btn": "Закрыть PR",
168 "pulls.reopen_btn": "Открыть заново",
169 "pulls.comment_btn": "Прокомментировать",
170 "pulls.conversation": "Обсуждение",
171 "pulls.files_changed": "Изменения",
172 "pulls.commits": "Коммиты",
173 "pulls.able_to_merge": "Можно слить автоматически",
174 "pulls.body": "Описание",
175 "pulls.body_ph": "Опишите предлагаемые изменения (Markdown)...",
176 "pulls.branches_identical": "Ветки идентичны — сравнивать нечего",
177 "pulls.cannot_merge_warning": "Обнаружены конфликты — автоматическое слияние невозможно",
178 "pulls.closed_desc": "Ветка изменений не была объединена с базовой.",
179 "pulls.closed_message": "Пул-реквест закрыт",
180 "pulls.comment_ph": "Напишите комментарий (поддерживается Markdown)...",
181 "pulls.compare_branches": "Сравнение веток",
182 "pulls.conflicts_desc": "Разрешите конфликты локально и запушьте изменения в ветку.",
183 "pulls.conflicts_title": "Есть конфликты слияния",
184 "pulls.into": "в",
185 "pulls.merge_clean": "Конфликтов нет — изменения можно объединить.",
186 "pulls.merged_message": "Пул-реквест слит",
187 "pulls.no_changes": "Файлы не изменены",
188 "pulls.no_commits": "В этом пул-реквесте пока нет коммитов",
189 "pulls.only_write_merge": "Сливать пул-реквесты могут только пользователи с правом записи.",
190 "pulls.status.closed": "Закрыт",
191 "pulls.status.merged": "Слит",
192 "pulls.status.open": "Открыт",
193 "pulls.wants_to_merge": "хочет слить",
194
195 // Releases
196 "releases.title": "Релизы",
197 "releases.new": "Новый релиз",
198 "releases.assets_upload": "Файлы релиза",
199 "releases.assets_upload_hint": "Необязательно. До 20 файлов, каждый до 100 МБ.",
200 "releases.asset_delete": "Удалить файл",
201 "releases.asset_delete_confirm": "Удалить этот файл? Действие необратимо.",
202 "releases.empty": "Релизов пока нет",
203 "releases.tag_select": "Тег",
204 "releases.title_ph": "Название релиза",
205 "releases.desc_ph": "Описание релиза, список изменений (Markdown)...",
206 "releases.prerelease": "Пре-релиз (нестабильная сборка)",
207 "releases.publish": "Опубликовать релиз",
208 "releases.delete": "Удалить релиз",
209 "releases.edit": "Редактировать релиз",
210 "releases.edit_title": "Редактирование релиза",
211 "releases.save_btn": "Сохранить изменения",
212 "releases.current_assets": "Текущие файлы",
213 "releases.add_assets": "Добавить файлы",
214 "releases.tag_locked": "Тег нельзя изменить после публикации.",
215 "releases.assets": "Файлы",
216 "releases.source_zip": "Исходный код (zip)",
217 "releases.source_tar": "Исходный код (tar.gz)",
218 "releases.body": "Описание",
219 "releases.body_ph": "Опишите релиз, список изменений (Markdown)...",
220 "releases.count": "релизов",
221 "releases.count_one": "релиз",
222 "releases.count_few": "релиза",
223 "releases.count_many": "релизов",
224 "releases.delete_confirm": "Удалить этот релиз? Действие необратимо.",
225 "releases.is_prerelease": "Пре-релиз (нестабильная сборка)",
226 "releases.publish_btn": "Опубликовать релиз",
227 "releases.tag_desc": "Существующий тег или новый — он будет создан автоматически.",
228 "releases.tag_name": "Тег",
229 "releases.tags": "тегов",
230 "releases.tags_one": "тег",
231 "releases.tags_few": "тега",
232 "releases.tags_many": "тегов",
233 "releases.target": "Ветка",
234 "releases.target_desc": "Ветка или коммит, на который будет указывать тег.",
235
236 // Activity
237 "activity.title": "Активность",
238 "activity.pulse": "Сводка активности",
239 "activity.empty": "Активности пока нет",
240 "activity.commits": "коммитов",
241 "activity.open_prs": "открытых PR",
242 "activity.merged_prs": "слитых PR",
243 "activity.open_issues": "открытых задач",
244 "activity.releases": "релизов",
245 "activity.issues": "открыто и закрыто",
246 "activity.on_default_branch": "в ветке по умолчанию",
247 "activity.published_releases": "опубликованные релизы",
248 "activity.pull_requests": "открыто и слито",
249 "activity.recent_feed": "Лента активности",
250 "activity.badge_commit": "коммит",
251 "activity.badge_release": "релиз",
252
253 // Задачи (Issues)
254 "issue.new": "Новая задача",
255 "issue.title": "Заголовок",
256 "issue.title_ph": "Кратко опишите задачу или проблему",
257 "issue.body": "Описание",
258 "issue.body_ph": "Подробное описание (поддерживается Markdown)...",
259 "issue.create": "Создать задачу",
260 "issue.open": "Открытые",
261 "issue.closed": "Закрытые",
262 "issue.status.open": "Открыта",
263 "issue.status.closed": "Закрыта",
264 "issue.close_btn": "Закрыть задачу",
265 "issue.reopen_btn": "Переоткрыть",
266 "issue.comment_ph": "Напишите комментарий (поддерживается Markdown)...",
267 "issue.comment_btn": "Отправить",
268 "issue.empty": "Задач в этом списке нет",
269
270 // Настройки пользователя, профиль и токены
271 "settings.title": "Настройки",
272 "settings.profile": "Профиль",
273 "settings.avatar": "Аватар",
274 "settings.avatar_upload": "Выбрать изображение",
275 "settings.avatar_remove": "Удалить аватар",
276 "settings.avatar_hint": "PNG, JPG, WebP или GIF — автоматически кадрируется до 256×256",
277 "settings.full_name": "Отображаемое имя",
278 "settings.full_name_ph": "Ваше имя или ник",
279 "settings.bio": "О себе",
280 "settings.bio_ph": "Короткая подпись в профиле",
281 "settings.location": "Локация",
282 "settings.location_ph": "Город, страна",
283 "settings.website": "Сайт",
284 "settings.website_ph": "https://example.com",
285 "profile.edit": "Редактировать профиль",
286 "profile.joined": "Регистрация",
287 "profile.public_repos": "Публичные",
288 "profile.private_repos": "Приватные",
289 "profile.total_repos": "Репозитории",
290 "settings.tokens": "Токены доступа",
291 "settings.tokens.desc": "Используйте токен вместо пароля для git clone и git push по HTTP.",
292 "settings.token.name": "Название токена (например, Ноутбук)",
293 "settings.token.create": "Создать",
294 "settings.token.revoke": "Отозвать",
295 "settings.token.created_once": "Скопируйте токен сейчас — он показывается только один раз:",
296 "settings.token.col_name": "Название",
297 "settings.token.col_prefix": "Префикс",
298 "settings.token.col_created": "Создан",
299 "settings.token.col_used": "Использован",
300 "settings.token.empty": "Токенов доступа пока нет",
301 "settings.password.current": "Текущий пароль",
302 "settings.password.new": "Новый пароль",
303 "settings.password.update": "Обновить пароль",
304
305 // Админка
306 "admin.title": "Администрирование",
307 "admin.features": "Модули и доступ",
308 "admin.users": "Пользователи",
309 "admin.registration": "Публичная регистрация",
310 "admin.registration.desc": "Разрешить самостоятельную регистрацию новых аккаунтов",
311 "admin.explore": "Раздел «Обзор» (Explore)",
312 "admin.explore.desc": "Показывать каталог публичных репозиториев в сайдбаре и по адресу /explore",
313 "admin.landing": "Приветственная страница",
314 "admin.landing.desc": "Показывать лендинг на главной странице (если отключено — переход сразу к репозиториям или входу)",
315 "admin.anon_read": "Гостевой просмотр",
316 "admin.anon_read.desc": "Разрешить неавторизованным пользователям просматривать публичные репозитории и профили",
317 "admin.issues": "Трекер задач (Issues)",
318 "admin.issues.desc": "Включить вкладку «Задачи» в репозиториях",
319 "admin.enabled": "Включено",
320 "admin.disabled": "Отключено",
321 "admin.enable_btn": "Включить",
322 "admin.disable_btn": "Отключить",
323 "admin.col.user": "Пользователь",
324 "admin.col.repos": "Репозитории",
325 "admin.col.role": "Роль",
326 "admin.col.joined": "Дата",
327 "admin.role.admin": "Админ",
328 "admin.role.user": "Участник",
329
330 // Командная палитра и хоткеи
331 "palette.placeholder": "Поиск репозитория, файла или команды...",
332 "palette.group.nav": "Навигация",
333 "palette.group.themes": "Тема оформления",
334 "palette.group.repos": "Репозитории",
335 "shortcuts.title": "Горячие клавиши",
336 "shortcuts.palette": "Командная палитра",
337 "shortcuts.search": "Фокус на поиск",
338 "shortcuts.home": "На главную",
339 "shortcuts.files": "Фильтр файлов",
340 "shortcuts.sidebar": "Скрыть / показать сайдбар",
341 "shortcuts.shortcuts": "Это окно шорткатов",
342 "shortcuts.context_menu": "Открыть контекстное меню",
343 "shortcuts.theme": "Переключить тему",
344 "shortcuts.copy_url": "Копировать адрес страницы",
345 "shortcuts.close": "Закрыть меню или диалог",
346 "shortcuts.profile": "Мой профиль",
347 "shortcuts.new_repo": "Новый репозиторий",
348 "shortcuts.unavailable": "Этот шорткат здесь недоступен",
349 "shortcuts.group.general": "Общее",
350 "shortcuts.group.navigation": "Навигация",
351 "shortcuts.group.repo": "Репозиторий",
352 "nav.toggle_sidebar": "Сайдбар (Ctrl+B)",
353
354 // Контекстное меню
355 "contextmenu.title": "Контекстное меню",
356 "contextmenu.selection": "Выделение",
357 "contextmenu.copy_selection": "Копировать выделенное",
358 "contextmenu.search_selection": "Искать выделенное",
359 "contextmenu.link": "Ссылка",
360 "contextmenu.open_link": "Открыть в новой вкладке",
361 "contextmenu.copy_link": "Копировать адрес ссылки",
362 "contextmenu.copy_link_text": "Копировать текст ссылки",
363 "contextmenu.image": "Изображение",
364 "contextmenu.open_image": "Открыть изображение",
365 "contextmenu.copy_image": "Копировать адрес изображения",
366 "contextmenu.save_image": "Сохранить изображение",
367 "contextmenu.repository": "Репозиторий",
368 "contextmenu.repo_actions": "Действия",
369 "contextmenu.page": "Страница",
370 "contextmenu.back": "Назад",
371 "contextmenu.forward": "Вперёд",
372 "contextmenu.reload": "Обновить",
373 "contextmenu.copy_url": "Копировать адрес страницы",
374 "contextmenu.appearance": "Оформление",
375 "contextmenu.app": "Приложение",
376
377 // Флеш-сообщения
378 "flash.welcome": "Добро пожаловать в Polar, @%s!",
379 "flash.profile_updated": "Профиль обновлён.",
380 "flash.password_updated": "Пароль успешно изменён.",
381 "flash.token_revoked": "Токен доступа отозван.",
382 "flash.settings_updated": "Настройки сохранены.",
383 "flash.error": "Ошибка: %s",
384 "flash.comment_error": "Не удалось отправить комментарий: %s",
385 "flash.pr_created": "Пул-реквест #%d создан.",
386 "flash.pr_closed": "Пул-реквест #%d закрыт.",
387 "flash.pr_reopened": "Пул-реквест #%d открыт заново.",
388 "flash.pr_merged": "Пул-реквест #%d слит.",
389 "flash.pr_merged_state": "Нельзя изменить состояние слитого пул-реквеста.",
390 "flash.pr_merge_open_only": "Слить можно только открытый пул-реквест.",
391 "flash.pr_merge_failed": "Не удалось слить: %s",
392 "flash.release_tag_empty": "Имя тега не может быть пустым.",
393 "flash.release_tag_failed": "Не удалось создать тег: %s",
394 "flash.release_create_failed": "Не удалось создать релиз: %s",
395 "flash.release_published": "Релиз %s опубликован.",
396 "flash.release_delete_failed": "Не удалось удалить релиз: %s",
397 "flash.release_deleted": "Релиз удалён.",
398 "flash.release_updated": "Релиз %s обновлён.",
399 "flash.release_update_failed": "Не удалось обновить релиз: %s",
400 "flash.release_updated_with_assets": "Релиз %s обновлён, файлов добавлено: %d.",
401 "flash.release_updated_assets_failed": "Релиз %s обновлён, но часть файлов не удалось сохранить.",
402 "flash.release_published_with_assets": "Релиз %s опубликован, файлов прикреплено: %d.",
403 "flash.release_published_assets_failed": "Релиз %s опубликован, но часть файлов не удалось сохранить.",
404 "flash.release_asset_too_many": "Слишком много файлов: максимум %d.",
405 "flash.release_asset_too_big": "Файл слишком большой — лимит 100 МБ на файл.",
406 "flash.release_asset_deleted": "Файл удалён.",
407 "flash.release_asset_delete_failed": "Не удалось удалить файл: %s",
408 "file.new_file": "Новый файл",
409 "file.new_folder": "Новая папка",
410 "file.path": "Путь",
411 "file.path_ph": "напр. src/main.go",
412 "file.folder_ph": "напр. docs",
413 "file.branch": "Ветка",
414 "file.content": "Содержимое",
415 "file.content_ph": "Текст файла…",
416 "file.message": "Сообщение коммита",
417 "file.create_file": "Создать файл",
418 "file.create_folder": "Создать папку",
419 "file.folder_hint": "Git не хранит пустые папки — Polar добавит туда .gitkeep.",
420 "flash.file_created": "Файл создан.",
421 "flash.folder_created": "Папка создана.",
422 "flash.file_exists": "Файл с таким путём уже существует.",
423 "flash.path_invalid": "Некорректный путь.",
424 "flash.file_create_failed": "Не удалось создать файл.",
425 "flash.folder_create_failed": "Не удалось создать папку.",
426 "file.upload_file": "Загрузить файлы",
427 "file.upload_dest": "Папка назначения",
428 "file.upload_dest_ph": "напр. docs/images (необязательно)",
429 "file.upload_pick": "Выберите файлы или перетащите сюда",
430 "file.upload_hint": "До 25 файлов, до 50 МБ суммарно.",
431 "file.upload_submit": "Загрузить",
432 "file.upload_replace_hint": "Существующие файлы будут перезаписаны.",
433 "flash.upload_done": "Загружено файлов: %d.",
434 "flash.upload_none": "Файлы не выбраны.",
435 "flash.upload_failed": "Не удалось загрузить файлы.",
436 "flash.upload_too_big": "Слишком большой объём — лимит 50 МБ.",
437 "flash.upload_too_many": "Слишком много файлов: максимум %d.", "flash.repo_settings_saved": "Настройки репозитория сохранены.",
438 "flash.repo_rename_failed": "Не удалось переименовать: %s",
439 "flash.repo_renamed": "Репозиторий переименован в %s.",
440 "flash.repo_confirm_mismatch": "Введённое имя не совпадает с названием репозитория.",
441 "flash.repo_deleted": "Репозиторий %s удалён.",
442 "flash.branch_created": "Ветка %s создана.",
443 "flash.branch_create_failed": "Не удалось создать ветку: %s",
444 "flash.branch_default_delete": "Нельзя удалить ветку по умолчанию.",
445 "flash.branch_deleted": "Ветка %s удалена.",
446 "flash.branch_delete_failed": "Не удалось удалить ветку: %s",
447 "flash.tag_created": "Тег %s создан.",
448 "flash.tag_create_failed": "Не удалось создать тег: %s",
449 "flash.tag_deleted": "Тег %s удалён.",
450 "flash.tag_delete_failed": "Не удалось удалить тег: %s",
451 "flash.issue_closed": "Задача #%d закрыта.",
452 "flash.issue_reopened": "Задача #%d открыта заново.",
453
454 // Ошибочные страницы
455 "err.not_found": "Не найдено",
456 "err.forbidden": "Доступ запрещён",
457 "err.session_error": "Ошибка сессии",
458 "err.session_create": "Не удалось создать сессию.",
459 "err.settings_error": "Ошибка настроек",
460 "err.settings_save": "Не удалось сохранить настройку.",
461 "err.explore_disabled": "Раздел «Обзор» отключён на этом сервере.",
462 "err.activity_disabled": "Активность отключена для этого репозитория.",
463 "err.pulls_disabled": "Пул-реквесты отключены для этого репозитория.",
464 "err.releases_disabled": "Релизы отключены для этого репозитория.",
465 "err.release_not_found": "Релиз не найден",
466 "err.release_not_found_desc": "Не удалось найти релиз.",
467 "err.asset_not_found": "Файл не найден",
468 "err.asset_not_found_desc": "Запрошенный файл релиза не найден.",
469 "err.issues_disabled": "Задачи отключены для этого репозитория.",
470 "err.repo_not_found": "Репозиторий не найден",
471 "err.repo_not_found_desc": "Репозиторий не существует или у вас нет к нему доступа.",
472 "err.repo_private_desc": "Репозиторий не существует или является приватным.",
473 "err.access_denied": "Доступ запрещён",
474 "err.repo_write_denied": "У вас нет прав на изменение этого репозитория.",
475 "err.invalid_repo_path": "Некорректный путь репозитория",
476 "err.path_not_found": "Путь не найден",
477 "err.path_not_found_desc": "Не удалось найти путь в репозитории для ссылки %s",
478 "err.file_not_found": "Файл не найден",
479 "err.file_not_found_desc": "Запрошенный файл не найден в %s",
480 "err.commit_not_found": "Коммит не найден",
481 "err.commit_not_found_desc": "Не удалось найти коммит %s",
482 "err.pr_not_found": "Пул-реквест не найден",
483 "err.pr_not_found_desc": "Не удалось найти пул-реквест.",
484 "err.pr_state_forbidden": "Вы не можете изменить состояние этого пул-реквеста.",
485 "err.pr_merge_forbidden": "У вас нет прав на слияние пул-реквестов.",
486 "err.issue_not_found": "Задача не найдена",
487 "err.issue_not_found_desc": "Не удалось найти задачу.",
488 "err.issue_state_forbidden": "Вы не можете изменить состояние этой задачи.",
489 "err.delete_error": "Ошибка удаления",
490 "err.repo_delete_failed": "Не удалось удалить репозиторий.",
491 "err.user_not_found": "Пользователь @%s не существует.",
492 "err.archive_error": "Ошибка архива",
493 "err.archive_tar_failed": "Не удалось создать tar.gz архив для %s",
494 "err.archive_zip_failed": "Не удалось создать zip архив для %s",
495
496 // Форки
497 "fork.forked_from": "форк от",
498 "fork.forks": "Форки",
499 "fork.forks_btn": "Форки",
500 "fork.fork_btn": "Форк",
501 "fork.fork_btn_desc": "Создать форк этого репозитория",
502 "fork.your_fork": "Ваш форк",
503 "fork.your_fork_desc": "Перейти к вашему форку",
504 "forks.title": "Форки",
505 "forks.empty": "Пока никто не форкал этот репозиторий.",
506
507 // Коллабораторы
508 "collab.title": "Коллабораторы",
509 "collab.desc": "Люди с доступом к репозиторию",
510 "collab.owner": "Владелец",
511 "collab.role": "Роль",
512 "collab.role_read": "Чтение",
513 "collab.role_write": "Запись",
514 "collab.username": "Пользователь",
515 "collab.username_ph": "username",
516 "collab.add": "Добавить",
517 "collab.remove": "Убрать доступ",
518 "collab.empty": "Коллабораторов пока нет.",
519
520 // Ревью
521 "reviews.title": "Ревью",
522 "reviews.approved": "Одобрено",
523 "reviews.changes_requested": "Запрошены изменения",
524 "reviews.body_ph": "Комментарий к ревью (необязательно)",
525 "reviews.approve": "Одобрить",
526 "reviews.request_changes": "Запросить изменения",
527
528 // Device flow (RFC 8628)
529 "device.title": "Подключение устройства",
530 "device.badge": "Git",
531 "device.desc": "Введите код, который показал git или скрипт-помощник, чтобы выдать устройству доступ к вашему аккаунту.",
532 "device.check": "Проверить",
533 "device.authorize_for": "Выдать доступ по коду",
534 "device.scope_hint": "Доступ даётся на чтение и запись репозиториев, к которым у вас есть права, и действует только для этого устройства.",
535 "device.approve": "Разрешить",
536 "device.deny": "Отклонить",
537 "device.signin_to_approve": "Войдите, чтобы подтвердить доступ",
538 "device.helper_hint": "Подсказка: настройте credential helper, чтобы код запрашивался автоматически — см. README.",
539 "device.code_unknown": "Код не найден. Проверьте, что он введён верно.",
540 "device.code_used": "Этот код уже использован или истёк.",
541 "device.approved_now": "Готово! Устройство подключено — вернитесь в терминал.",
542 "device.denied_now": "Запрос отклонён. Устройство не получит доступ.",
543
544 // Flash: форки, коллабораторы, ревью, device flow
545 "flash.fork_self": "Это ваш репозиторий — форк не нужен.",
546 "flash.fork_exists": "У вас уже есть форк этого репозитория.",
547 "flash.fork_created": "Форк создан.",
548 "flash.fork_failed": "Не удалось создать форк: %s",
549 "flash.collab_added": "@%s добавлен в коллабораторы.",
550 "flash.collab_removed": "Доступ коллаборатора отозван.",
551 "flash.collab_failed": "Не удалось изменить коллаборатора: %s",
552 "flash.review_self": "Нельзя ревьюить собственный пул-реквест.",
553 "flash.review_closed": "Ревью доступно только для открытых пул-реквестов.",
554 "flash.review_failed": "Не удалось сохранить ревью: %s",
555 "flash.review_approved": "Ревью сохранено: одобрено.",
556 "flash.review_changes_requested": "Ревью сохранено: запрошены изменения.",
557 "flash.device_code_required": "Введите код устройства.",
558 "flash.device_code_invalid": "Код не найден, истёк или уже использован.",
559 "flash.device_approved": "Устройство авторизовано — можно возвращаться к git.",
560 "flash.device_denied": "Запрос отклонён.",
561
562 // Прочее
563 "issues.new": "Новая задача",
564 "pulls.head_repo": "Из репозитория",
565 "repo.about": "О репозитории",
566 "repo.clone_title": "Клонирование",
567 "repo.created": "Создан",
568 "repo.updated": "Обновлён",
569 "repo.view_file": "Открыть",
570 "err.collab_forbidden": "Управлять коллабораторами может только владелец или администратор.",
571 "err.pr_head_repo_invalid": "Выбран недопустимый репозиторий-источник.",
572
573 // Media, account deletion & administration
574 "auth.pending_approval": "Аккаунт ожидает подтверждения администратора.",
575 "auth.register.pending_notice": "После регистрации аккаунт должен подтвердить администратор.",
576 "settings.background": "Фон профиля",
577 "settings.background_upload": "Выбрать фон",
578 "settings.background_remove": "Убрать фон",
579 "settings.background_hint": "PNG, JPG, WebP или GIF. Изображение мягко растворяется по краям.",
580 "settings.delete_account": "Удаление аккаунта",
581 "settings.delete_account_desc": "Аккаунт и все его репозитории будут удалены без возможности восстановления.",
582 "settings.delete_account_confirm": "Введите имя пользователя",
583 "settings.delete_password": "Текущий пароль",
584 "settings.delete_account_button": "Удалить аккаунт навсегда",
585 "settings.delete_mismatch": "Имя пользователя не совпадает.",
586 "settings.delete_last_admin": "Нельзя удалить последнего администратора.",
587 "repo.avatar": "Аватар репозитория",
588 "repo.avatar_upload": "Выбрать изображение",
589 "repo.avatar_remove": "Удалить аватар",
590 "repo.avatar_hint": "Квадратное изображение до 2 МБ. Без аватара используется изображение владельца.",
591 "repo.background": "Фон репозитория",
592 "repo.background_upload": "Выбрать фон",
593 "repo.background_remove": "Убрать фон",
594 "repo.background_hint": "PNG, JPG, WebP или GIF до 6 МБ. Изображение мягко растворяется в цвет текущей темы.",
595 "admin.registration.public": "Публичная регистрация",
596 "admin.registration.confirm": "Регистрация с подтверждением",
597 "admin.registration.closed": "Без регистрации",
598 "admin.registration.public_desc": "Аккаунт активируется сразу.",
599 "admin.registration.confirm_desc": "Аккаунт активируется после одобрения администратором.",
600 "admin.registration.closed_desc": "Самостоятельная регистрация новых аккаунтов закрыта.",
601 "admin.registration.mode": "Новые аккаунты",
602 "admin.repos": "Репозитории",
603 "admin.col.status": "Статус",
604 "admin.col.actions": "Действия",
605 "admin.pending": "Ожидает",
606 "admin.approved": "Подтверждён",
607 "admin.approve": "Подтвердить",
608 "admin.make_admin": "Сделать админом",
609 "admin.remove_admin": "Снять админа",
610 "admin.delete_user": "Удалить",
611 "admin.delete_repo": "Удалить",
612 "admin.repo_visibility": "Доступ",
613 "admin.delete_user_title": "Удалить аккаунт",
614 "admin.delete_user_desc": "Все репозитории и данные пользователя будут удалены без возможности восстановления.",
615 "admin.delete_repo_title": "Удалить репозиторий",
616 "admin.delete_repo_desc": "Git-данные, релизы и файлы будут удалены без возможности восстановления.",
617 "admin.confirm_user": "Введите имя пользователя",
618 "admin.confirm_repo": "Введите название репозитория",
619 "flash.image_invalid": "Изображение слишком большое или имеет неподдерживаемый формат.",
620 "flash.image_save_failed": "Не удалось сохранить изображение. Попробуйте ещё раз.",
621 "flash.account_deleted": "Аккаунт и все его репозитории удалены.",
622 "flash.account_delete_failed": "Не удалось удалить аккаунт.",
623 "flash.admin_user_approved": "Аккаунт @%s подтверждён.",
624 "flash.admin_user_missing": "Пользователь не найден.",
625 "flash.admin_user_update_failed": "Не удалось обновить пользователя.",
626 "flash.admin_self_role": "Нельзя менять собственную роль через админку.",
627 "flash.admin_last_admin": "Нельзя удалить или понизить последнего администратора.",
628 "flash.admin_role_updated": "Роль @%s обновлена.",
629 "flash.admin_delete_self": "Удалить собственный аккаунт можно только в настройках профиля.",
630 "flash.admin_delete_mismatch": "Подтверждение не совпадает.",
631 "flash.admin_user_delete_failed": "Не удалось удалить пользователя.",
632 "flash.admin_user_deleted": "Пользователь @%s и его репозитории удалены.",
633 "flash.admin_repo_missing": "Репозиторий не найден.",
634 "flash.admin_repo_delete_failed": "Не удалось удалить репозиторий.",
635 "flash.admin_repo_deleted": "Репозиторий %s/%s удалён.",
636 "flash.admin_registration_invalid": "Некорректный режим регистрации."},
637 EN: {
638 // Navigation & Common
639 "app.tagline": "Lightweight self-hosted Git hosting",
640 "nav.home": "Home",
641 "nav.repositories": "Repositories",
642 "nav.explore": "Explore",
643 "nav.settings": "Settings",
644 "nav.admin": "Admin",
645 "nav.agents": "For AI agents",
646 "nav.login": "Sign in",
647 "nav.register": "Sign up",
648 "nav.logout": "Sign out",
649 "nav.new_repo": "New",
650 "nav.command_palette": "Search & commands",
651 "nav.search_placeholder": "Search...",
652 "nav.theme": "Theme",
653 "nav.lang": "Language",
654 "common.copy": "Copy",
655 "common.copied": "Copied",
656 "common.copy_failed": "Could not copy",
657 "common.cancel": "Cancel",
658 "common.save": "Save",
659 "common.delete": "Delete",
660 "common.close": "Close",
661 "common.never": "Never",
662 "common.newer": "Newer",
663 "common.older": "Older",
664 "common.up": "Up",
665
666 // Themes (only 3)
667 "theme.light": "Light",
668 "theme.dark": "Dark",
669 "theme.system": "System",
670
671 // Landing
672 "landing.badge": "Single Binary · SQLite · Zero Dependencies",
673 "landing.hero.title": "Lightweight self-hosted Git hosting",
674 "landing.hero.subtitle": "A single Go binary backed by SQLite. Deploys in a minute, uses minimal memory, and stays out of your way.",
675 "landing.hero.cta_start": "Get Started",
676 "landing.features.title": "Principles",
677 "landing.feat1.title": "Single Binary",
678 "landing.feat1.desc": "Templates, styles, fonts, migrations, and icons are compiled in via go:embed.",
679 "landing.feat2.title": "SQLite (WAL)",
680 "landing.feat2.desc": "Your entire database is a single data/polar.db file without CGO. Back up by copying.",
681 "landing.feat3.title": "Fast & Quiet",
682 "landing.feat3.desc": "Instant cold start, server-side rendering, and < 30 MB idle memory.",
683 "landing.feat4.title": "Private by Default",
684 "landing.feat4.desc": "Public and private repositories, Argon2id passwords, and Git HTTP access tokens.",
685
686 // Auth
687 "auth.login.title": "Sign in",
688 "auth.register.title": "Create account",
689 "auth.register.disabled": "Public registration is disabled by the administrator.",
690 "auth.username": "Username",
691 "auth.username_hint": "2–32 characters: letters, digits, hyphen, underscore",
692 "auth.username_or_email": "Username or Email",
693 "auth.email": "Email",
694 "auth.password": "Password",
695 "auth.password_hint": "At least 8 characters",
696 "auth.submit_login": "Sign in",
697 "auth.submit_register": "Create account",
698 "auth.no_account": "No account?",
699 "auth.have_account": "Have an account?",
700 "auth.invalid_creds": "Invalid username/email or password",
701
702 // Repositories
703 "repo.new.title": "New repository",
704 "repo.name": "Name",
705 "repo.name_hint": "Letters, digits, '.', '-', '_'",
706 "repo.description": "Description",
707 "repo.description_ph": "Short description (optional)",
708 "repo.visibility": "Visibility",
709 "repo.public": "Public",
710 "repo.public_desc": "Anyone can view and clone this repository",
711 "repo.private": "Private",
712 "repo.private_desc": "Accessible only to you",
713 "repo.create_btn": "Create repository",
714 "repo.filter_ph": "Filter repositories...",
715 "repo.empty_list": "No repositories yet",
716 "repo.empty_list_sub": "Create your first repository to push code.",
717 "repo.empty.title": "Repository is empty",
718 "repo.empty.new_cmd": "Create a new repository on the command line",
719 "repo.empty.push_cmd": "Push an existing repository",
720 "repo.tab.code": "Code",
721 "repo.tab.commits": "Commits",
722 "repo.tab.branches": "Branches & Tags",
723 "repo.tab.issues": "Issues",
724 "repo.tab.pulls": "Pull requests",
725 "repo.tab.releases": "Releases",
726 "repo.tab.activity": "Activity",
727 "repo.tab.settings": "Settings",
728 "repo.features": "Repository Features",
729 "repo.clone": "Clone",
730 "repo.download_zip": "Download ZIP",
731 "repo.branches": "Branches",
732 "repo.tags": "Tags",
733 "repo.default_branch": "Default branch",
734 "repo.find_file": "Filter files...",
735 "repo.files": "Files",
736 "repo.readme": "README",
737 "repo.raw": "Raw",
738 "repo.history": "History",
739 "repo.lines": "lines",
740 "repo.lines_one": "line",
741 "repo.lines_few": "lines",
742 "repo.lines_many": "lines",
743 "repo.binary_notice": "Binary file — inline preview unavailable",
744 "repo.download_raw": "Download file",
745 "repo.browse_at_commit": "Browse files",
746 "repo.files_changed": "files changed",
747 "repo.files_changed_one": "file changed",
748 "repo.files_changed_few": "files changed",
749 "repo.files_changed_many": "files changed",
750 "repo.no_commits": "No commits yet",
751 "repo.danger_zone": "Danger Zone",
752 "repo.delete": "Delete repository",
753 "repo.delete_desc": "Once deleted, the repository and its git history cannot be recovered.",
754 "repo.delete_confirm": "Type the repository name to confirm",
755 "repo.rename": "Rename",
756 "repo.save": "Save",
757 "repo.branch.new": "New branch",
758 "repo.branch.name_ph": "Branch name (e.g. feat/ui)",
759 "repo.branch.from": "From branch / ref",
760 "repo.branch.create": "Create branch",
761 "repo.branch.default": "default",
762 "repo.tag.new": "New tag / release",
763 "repo.tag.name_ph": "Tag (e.g. v1.0.0)",
764 "repo.tag.msg_ph": "Tag note (optional)",
765 "repo.tag.create": "Create tag",
766 "repo.tags.empty": "No tags yet",
767
768 // Pull Requests
769 "pulls.title": "Pull requests",
770 "pulls.new": "New pull request",
771 "pulls.empty": "No pull requests yet",
772 "pulls.open": "Open",
773 "pulls.closed": "Closed",
774 "pulls.merged": "Merged",
775 "pulls.compare": "Comparing changes",
776 "pulls.base": "base",
777 "pulls.head": "compare",
778 "pulls.title_ph": "Pull request title...",
779 "pulls.desc_ph": "Describe your changes (Markdown supported)...",
780 "pulls.create_btn": "Create pull request",
781 "pulls.merge_btn": "Merge pull request",
782 "pulls.can_merge": "Able to merge automatically.",
783 "pulls.cannot_merge": "Can't automatically merge: conflicts detected.",
784 "pulls.already_merged": "The head branch is already merged into base.",
785 "pulls.close_btn": "Close PR",
786 "pulls.reopen_btn": "Reopen PR",
787 "pulls.comment_btn": "Comment",
788 "pulls.conversation": "Conversation",
789 "pulls.files_changed": "Files changed",
790 "pulls.commits": "Commits",
791 "pulls.able_to_merge": "Able to merge automatically",
792 "pulls.body": "Description",
793 "pulls.body_ph": "Describe your changes (Markdown supported)...",
794 "pulls.branches_identical": "Branches are identical — nothing to compare",
795 "pulls.cannot_merge_warning": "Conflicts detected — automatic merge is not possible",
796 "pulls.closed_desc": "The head branch was not merged into base.",
797 "pulls.closed_message": "Pull request closed",
798 "pulls.comment_ph": "Write a comment (Markdown supported)...",
799 "pulls.compare_branches": "Comparing branches",
800 "pulls.conflicts_desc": "Resolve the conflicts locally and push to the head branch.",
801 "pulls.conflicts_title": "Merge conflicts detected",
802 "pulls.into": "into",
803 "pulls.merge_clean": "No conflicts — changes can be merged.",
804 "pulls.merged_message": "Pull request merged",
805 "pulls.no_changes": "No files changed",
806 "pulls.no_commits": "No commits in this pull request yet",
807 "pulls.only_write_merge": "Only users with write access can merge pull requests.",
808 "pulls.status.closed": "Closed",
809 "pulls.status.merged": "Merged",
810 "pulls.status.open": "Open",
811 "pulls.wants_to_merge": "wants to merge",
812
813 // Releases
814 "releases.title": "Releases",
815 "releases.new": "Draft a new release",
816 "releases.assets_upload": "Release files",
817 "releases.assets_upload_hint": "Optional. Up to 20 files, 100 MB each.",
818 "releases.asset_delete": "Delete file",
819 "releases.asset_delete_confirm": "Delete this file? This cannot be undone.",
820 "releases.empty": "No releases yet",
821 "releases.tag_select": "Tag",
822 "releases.title_ph": "Release title",
823 "releases.desc_ph": "Describe this release, release notes (Markdown)...",
824 "releases.prerelease": "This is a pre-release",
825 "releases.publish": "Publish release",
826 "releases.delete": "Delete release",
827 "releases.edit": "Edit release",
828 "releases.edit_title": "Edit release",
829 "releases.save_btn": "Save changes",
830 "releases.current_assets": "Current files",
831 "releases.add_assets": "Add files",
832 "releases.tag_locked": "The tag cannot be changed after publishing.",
833 "releases.assets": "Assets",
834 "releases.source_zip": "Source code (zip)",
835 "releases.source_tar": "Source code (tar.gz)",
836 "releases.body": "Description",
837 "releases.body_ph": "Describe this release, release notes (Markdown)...",
838 "releases.count": "releases",
839 "releases.count_one": "release",
840 "releases.count_few": "releases",
841 "releases.count_many": "releases",
842 "releases.delete_confirm": "Delete this release? This cannot be undone.",
843 "releases.is_prerelease": "This is a pre-release",
844 "releases.publish_btn": "Publish release",
845 "releases.tag_desc": "An existing tag or a new one — it will be created automatically.",
846 "releases.tag_name": "Tag",
847 "releases.tags": "tags",
848 "releases.tags_one": "tag",
849 "releases.tags_few": "tags",
850 "releases.tags_many": "tags",
851 "releases.target": "Branch",
852 "releases.target_desc": "Branch or commit the tag will point to.",
853
854 // Activity
855 "activity.title": "Activity",
856 "activity.pulse": "Activity overview",
857 "activity.empty": "No recent activity recorded.",
858 "activity.commits": "commits",
859 "activity.open_prs": "open PRs",
860 "activity.merged_prs": "merged PRs",
861 "activity.open_issues": "open issues",
862 "activity.releases": "releases",
863 "activity.issues": "opened and closed",
864 "activity.on_default_branch": "on the default branch",
865 "activity.published_releases": "published releases",
866 "activity.pull_requests": "opened and merged",
867 "activity.recent_feed": "Activity feed",
868 "activity.badge_commit": "commit",
869 "activity.badge_release": "release",
870
871 // Issues
872 "issue.new": "New issue",
873 "issue.title": "Title",
874 "issue.title_ph": "Brief summary of the issue",
875 "issue.body": "Description",
876 "issue.body_ph": "Detailed description (Markdown supported)...",
877 "issue.create": "Create issue",
878 "issue.open": "Open",
879 "issue.closed": "Closed",
880 "issue.status.open": "Open",
881 "issue.status.closed": "Closed",
882 "issue.close_btn": "Close issue",
883 "issue.reopen_btn": "Reopen",
884 "issue.comment_ph": "Write a comment (Markdown supported)...",
885 "issue.comment_btn": "Comment",
886 "issue.empty": "No issues in this list",
887
888 // Settings, Profile & Tokens
889 "settings.title": "Settings",
890 "settings.profile": "Profile",
891 "settings.avatar": "Avatar",
892 "settings.avatar_upload": "Choose image",
893 "settings.avatar_remove": "Remove avatar",
894 "settings.avatar_hint": "PNG, JPG, WebP, or GIF — automatically cropped to 256×256",
895 "settings.full_name": "Display name",
896 "settings.full_name_ph": "Your name",
897 "settings.bio": "Bio",
898 "settings.bio_ph": "Short profile bio",
899 "settings.location": "Location",
900 "settings.location_ph": "City, Country",
901 "settings.website": "Website",
902 "settings.website_ph": "https://example.com",
903 "profile.edit": "Edit profile",
904 "profile.joined": "Joined",
905 "profile.public_repos": "Public",
906 "profile.private_repos": "Private",
907 "profile.total_repos": "Repositories",
908 "settings.tokens": "Access Tokens",
909 "settings.tokens.desc": "Use a token instead of your password for git clone and git push over HTTP.",
910 "settings.token.name": "Token name (e.g., Laptop)",
911 "settings.token.create": "Create",
912 "settings.token.revoke": "Revoke",
913 "settings.token.created_once": "Copy this token now — it will only be shown once:",
914 "settings.token.col_name": "Name",
915 "settings.token.col_prefix": "Prefix",
916 "settings.token.col_created": "Created",
917 "settings.token.col_used": "Last used",
918 "settings.token.empty": "No access tokens yet",
919 "settings.password.current": "Current password",
920 "settings.password.new": "New password",
921 "settings.password.update": "Update password",
922
923 // Admin
924 "admin.title": "Administration",
925 "admin.features": "Features & Access",
926 "admin.users": "Users",
927 "admin.registration": "Public registration",
928 "admin.registration.desc": "Allow new users to create accounts",
929 "admin.explore": "Explore page",
930 "admin.explore.desc": "Show public repository directory in sidebar and at /explore",
931 "admin.landing": "Landing page",
932 "admin.landing.desc": "Show landing page on root URL (if disabled, redirects to repos or sign in)",
933 "admin.anon_read": "Anonymous read access",
934 "admin.anon_read.desc": "Allow unauthenticated guests to browse public repositories and profiles",
935 "admin.issues": "Issue tracker",
936 "admin.issues.desc": "Enable the Issues tab inside repositories",
937 "admin.enabled": "Enabled",
938 "admin.disabled": "Disabled",
939 "admin.enable_btn": "Enable",
940 "admin.disable_btn": "Disable",
941 "admin.col.user": "User",
942 "admin.col.repos": "Repos",
943 "admin.col.role": "Role",
944 "admin.col.joined": "Joined",
945 "admin.role.admin": "Admin",
946 "admin.role.user": "User",
947
948 // Command Palette & Shortcuts
949 "palette.placeholder": "Search repositories, files, or commands...",
950 "palette.group.nav": "Navigation",
951 "palette.group.themes": "Theme",
952 "palette.group.repos": "Repositories",
953 "shortcuts.title": "Keyboard shortcuts",
954 "shortcuts.palette": "Command palette",
955 "shortcuts.search": "Focus search",
956 "shortcuts.home": "Go home",
957 "shortcuts.files": "Filter files",
958 "shortcuts.sidebar": "Toggle sidebar",
959 "shortcuts.shortcuts": "Show this dialog",
960 "shortcuts.context_menu": "Open context menu",
961 "shortcuts.theme": "Cycle theme",
962 "shortcuts.copy_url": "Copy page URL",
963 "shortcuts.close": "Close menu or dialog",
964 "shortcuts.profile": "Your profile",
965 "shortcuts.new_repo": "New repository",
966 "shortcuts.unavailable": "This shortcut is unavailable here",
967 "shortcuts.group.general": "General",
968 "shortcuts.group.navigation": "Navigation",
969 "shortcuts.group.repo": "Repository",
970 "nav.toggle_sidebar": "Sidebar (Ctrl+B)",
971
972 // Context menu
973 "contextmenu.title": "Context menu",
974 "contextmenu.selection": "Selection",
975 "contextmenu.copy_selection": "Copy selection",
976 "contextmenu.search_selection": "Search selection",
977 "contextmenu.link": "Link",
978 "contextmenu.open_link": "Open in new tab",
979 "contextmenu.copy_link": "Copy link address",
980 "contextmenu.copy_link_text": "Copy link text",
981 "contextmenu.image": "Image",
982 "contextmenu.open_image": "Open image in new tab",
983 "contextmenu.copy_image": "Copy image address",
984 "contextmenu.save_image": "Save image",
985 "contextmenu.repository": "Repository",
986 "contextmenu.repo_actions": "Actions",
987 "contextmenu.page": "Page",
988 "contextmenu.back": "Back",
989 "contextmenu.forward": "Forward",
990 "contextmenu.reload": "Reload",
991 "contextmenu.copy_url": "Copy page URL",
992 "contextmenu.appearance": "Appearance",
993 "contextmenu.app": "Application",
994
995 // Flash messages
996 "flash.welcome": "Welcome to Polar, @%s!",
997 "flash.profile_updated": "Profile updated.",
998 "flash.password_updated": "Password changed successfully.",
999 "flash.token_revoked": "Access token revoked.",
1000 "flash.settings_updated": "Settings saved.",
1001 "flash.error": "Error: %s",
1002 "flash.comment_error": "Could not post the comment: %s",
1003 "flash.pr_created": "Pull request #%d created.",
1004 "flash.pr_closed": "Pull request #%d closed.",
1005 "flash.pr_reopened": "Pull request #%d reopened.",
1006 "flash.pr_merged": "Pull request #%d merged.",
1007 "flash.pr_merged_state": "Cannot change the state of a merged pull request.",
1008 "flash.pr_merge_open_only": "Only an open pull request can be merged.",
1009 "flash.pr_merge_failed": "Could not merge: %s",
1010 "flash.release_tag_empty": "Tag name cannot be empty.",
1011 "flash.release_tag_failed": "Could not create the tag: %s",
1012 "flash.release_create_failed": "Could not create the release: %s",
1013 "flash.release_published": "Release %s published.",
1014 "flash.release_delete_failed": "Could not delete the release: %s",
1015 "flash.release_deleted": "Release deleted.",
1016 "flash.release_updated": "Release %s updated.",
1017 "flash.release_update_failed": "Could not update the release: %s",
1018 "flash.release_updated_with_assets": "Release %s updated with %d new file(s).",
1019 "flash.release_updated_assets_failed": "Release %s updated, but some files could not be saved.",
1020 "flash.release_published_with_assets": "Release %s published with %d attached file(s).",
1021 "flash.release_published_assets_failed": "Release %s published, but some files could not be saved.",
1022 "flash.release_asset_too_many": "Too many files: %d max.",
1023 "flash.release_asset_too_big": "File is too large — 100 MB per-file limit.",
1024 "flash.release_asset_deleted": "File deleted.",
1025 "flash.release_asset_delete_failed": "Could not delete the file: %s",
1026 "file.new_file": "New file",
1027 "file.new_folder": "New folder",
1028 "file.path": "Path",
1029 "file.path_ph": "e.g. src/main.go",
1030 "file.folder_ph": "e.g. docs",
1031 "file.branch": "Branch",
1032 "file.content": "Content",
1033 "file.content_ph": "File contents…",
1034 "file.message": "Commit message",
1035 "file.create_file": "Create file",
1036 "file.create_folder": "Create folder",
1037 "file.folder_hint": "Git does not track empty folders — Polar adds a .gitkeep placeholder.",
1038 "flash.file_created": "File created.",
1039 "flash.folder_created": "Folder created.",
1040 "flash.file_exists": "A file with that path already exists.",
1041 "flash.path_invalid": "Invalid path.",
1042 "flash.file_create_failed": "Could not create the file.",
1043 "flash.folder_create_failed": "Could not create the folder.",
1044 "file.upload_file": "Upload files",
1045 "file.upload_dest": "Destination folder",
1046 "file.upload_dest_ph": "e.g. docs/images (optional)",
1047 "file.upload_pick": "Choose files or drag them here",
1048 "file.upload_hint": "Up to 25 files, 50 MB in total.",
1049 "file.upload_submit": "Upload",
1050 "file.upload_replace_hint": "Existing files will be overwritten.",
1051 "flash.upload_done": "Uploaded %d file(s).",
1052 "flash.upload_none": "No files selected.",
1053 "flash.upload_failed": "Could not upload the files.",
1054 "flash.upload_too_big": "Upload is too large — 50 MB limit.",
1055 "flash.upload_too_many": "Too many files: %d max.", "flash.repo_settings_saved": "Repository settings saved.",
1056 "flash.repo_rename_failed": "Could not rename: %s",
1057 "flash.repo_renamed": "Repository renamed to %s.",
1058 "flash.repo_confirm_mismatch": "The name you typed does not match the repository name.",
1059 "flash.repo_deleted": "Repository %s deleted.",
1060 "flash.branch_created": "Branch %s created.",
1061 "flash.branch_create_failed": "Could not create the branch: %s",
1062 "flash.branch_default_delete": "The default branch cannot be deleted.",
1063 "flash.branch_deleted": "Branch %s deleted.",
1064 "flash.branch_delete_failed": "Could not delete the branch: %s",
1065 "flash.tag_created": "Tag %s created.",
1066 "flash.tag_create_failed": "Could not create the tag: %s",
1067 "flash.tag_deleted": "Tag %s deleted.",
1068 "flash.tag_delete_failed": "Could not delete the tag: %s",
1069 "flash.issue_closed": "Issue #%d closed.",
1070 "flash.issue_reopened": "Issue #%d reopened.",
1071
1072 // Error pages
1073 "err.not_found": "Not found",
1074 "err.forbidden": "Access denied",
1075 "err.session_error": "Session error",
1076 "err.session_create": "Could not create a session.",
1077 "err.settings_error": "Settings error",
1078 "err.settings_save": "Could not save the setting.",
1079 "err.explore_disabled": "Explore is disabled on this server.",
1080 "err.activity_disabled": "Activity is disabled for this repository.",
1081 "err.pulls_disabled": "Pull requests are disabled for this repository.",
1082 "err.releases_disabled": "Releases are disabled for this repository.",
1083 "err.release_not_found": "Release not found",
1084 "err.release_not_found_desc": "Could not find the release.",
1085 "err.asset_not_found": "File not found",
1086 "err.asset_not_found_desc": "The requested release file was not found.",
1087 "err.issues_disabled": "Issues are disabled for this repository.",
1088 "err.repo_not_found": "Repository not found",
1089 "err.repo_not_found_desc": "The repository does not exist or you do not have access to it.",
1090 "err.repo_private_desc": "The repository does not exist or is private.",
1091 "err.access_denied": "Access denied",
1092 "err.repo_write_denied": "You do not have permission to modify this repository.",
1093 "err.invalid_repo_path": "Invalid repository path",
1094 "err.path_not_found": "Path not found",
1095 "err.path_not_found_desc": "Could not find the path in the repository for ref %s",
1096 "err.file_not_found": "File not found",
1097 "err.file_not_found_desc": "The requested file was not found in %s",
1098 "err.commit_not_found": "Commit not found",
1099 "err.commit_not_found_desc": "Could not find commit %s",
1100 "err.pr_not_found": "Pull request not found",
1101 "err.pr_not_found_desc": "Could not find the pull request.",
1102 "err.pr_state_forbidden": "You cannot change the state of this pull request.",
1103 "err.pr_merge_forbidden": "You do not have permission to merge pull requests.",
1104 "err.issue_not_found": "Issue not found",
1105 "err.issue_not_found_desc": "Could not find the issue.",
1106 "err.issue_state_forbidden": "You cannot change the state of this issue.",
1107 "err.delete_error": "Delete error",
1108 "err.repo_delete_failed": "Could not delete the repository.",
1109 "err.user_not_found": "User @%s does not exist.",
1110 "err.archive_error": "Archive error",
1111 "err.archive_tar_failed": "Could not create a tar.gz archive for %s",
1112 "err.archive_zip_failed": "Could not create a zip archive for %s",
1113
1114 // Forks
1115 "fork.forked_from": "forked from",
1116 "fork.forks": "Forks",
1117 "fork.forks_btn": "Forks",
1118 "fork.fork_btn": "Fork",
1119 "fork.fork_btn_desc": "Create a fork of this repository",
1120 "fork.your_fork": "Your fork",
1121 "fork.your_fork_desc": "Go to your fork",
1122 "forks.title": "Forks",
1123 "forks.empty": "Nobody has forked this repository yet.",
1124
1125 // Collaborators
1126 "collab.title": "Collaborators",
1127 "collab.desc": "People with access to this repository",
1128 "collab.owner": "Owner",
1129 "collab.role": "Role",
1130 "collab.role_read": "Read",
1131 "collab.role_write": "Write",
1132 "collab.username": "User",
1133 "collab.username_ph": "username",
1134 "collab.add": "Add",
1135 "collab.remove": "Revoke access",
1136 "collab.empty": "No collaborators yet.",
1137
1138 // Reviews
1139 "reviews.title": "Reviews",
1140 "reviews.approved": "Approved",
1141 "reviews.changes_requested": "Changes requested",
1142 "reviews.body_ph": "Review comment (optional)",
1143 "reviews.approve": "Approve",
1144 "reviews.request_changes": "Request changes",
1145
1146 // Device flow (RFC 8628)
1147 "device.title": "Device authorization",
1148 "device.badge": "Git",
1149 "device.desc": "Enter the code shown by git or the credential helper to grant this device access to your account.",
1150 "device.check": "Check",
1151 "device.authorize_for": "Grant access to code",
1152 "device.scope_hint": "Access covers repositories you can already reach and is bound to this device only.",
1153 "device.approve": "Approve",
1154 "device.deny": "Deny",
1155 "device.signin_to_approve": "Sign in to approve access",
1156 "device.helper_hint": "Tip: configure the credential helper so the code is requested automatically — see the README.",
1157 "device.code_unknown": "Code not found. Double-check the code you entered.",
1158 "device.code_used": "This code has already been used or expired.",
1159 "device.approved_now": "All set! The device is authorized — return to your terminal.",
1160 "device.denied_now": "Request denied. The device will not get access.",
1161
1162 // Flash: forks, collaborators, reviews, device flow
1163 "flash.fork_self": "This repository is yours — no fork needed.",
1164 "flash.fork_exists": "You already have a fork of this repository.",
1165 "flash.fork_created": "Fork created.",
1166 "flash.fork_failed": "Could not create fork: %s",
1167 "flash.collab_added": "@%s added as a collaborator.",
1168 "flash.collab_removed": "Collaborator access revoked.",
1169 "flash.collab_failed": "Could not update collaborator: %s",
1170 "flash.review_self": "You cannot review your own pull request.",
1171 "flash.review_closed": "Reviews are only available on open pull requests.",
1172 "flash.review_failed": "Could not save the review: %s",
1173 "flash.review_approved": "Review saved: approved.",
1174 "flash.review_changes_requested": "Review saved: changes requested.",
1175 "flash.device_code_required": "Enter the device code.",
1176 "flash.device_code_invalid": "Code not found, expired, or already used.",
1177 "flash.device_approved": "Device authorized — you can return to git.",
1178 "flash.device_denied": "Request denied.",
1179
1180 // Misc
1181 "issues.new": "New issue",
1182 "pulls.head_repo": "From repository",
1183 "repo.about": "About",
1184 "repo.clone_title": "Clone",
1185 "repo.created": "Created",
1186 "repo.updated": "Updated",
1187 "repo.view_file": "Open",
1188 "err.collab_forbidden": "Only the owner or an administrator can manage collaborators.",
1189 "err.pr_head_repo_invalid": "The selected source repository is not allowed.",
1190
1191 // Media, account deletion & administration
1192 "auth.pending_approval": "This account is waiting for administrator approval.",
1193 "auth.register.pending_notice": "An administrator must approve the account after sign-up.",
1194 "settings.background": "Profile background",
1195 "settings.background_upload": "Choose background",
1196 "settings.background_remove": "Remove background",
1197 "settings.background_hint": "PNG, JPG, WebP, or GIF. The image fades gently at the edges.",
1198 "settings.delete_account": "Delete account",
1199 "settings.delete_account_desc": "The account and all of its repositories will be permanently deleted.",
1200 "settings.delete_account_confirm": "Type your username to confirm",
1201 "settings.delete_password": "Current password",
1202 "settings.delete_account_button": "Delete account permanently",
1203 "settings.delete_mismatch": "The username does not match.",
1204 "settings.delete_last_admin": "The last administrator account cannot be deleted.",
1205 "repo.avatar": "Repository avatar",
1206 "repo.avatar_upload": "Choose image",
1207 "repo.avatar_remove": "Remove avatar",
1208 "repo.avatar_hint": "A square image up to 2 MB. The owner avatar is used when empty.",
1209 "repo.background": "Repository background",
1210 "repo.background_upload": "Choose background",
1211 "repo.background_remove": "Remove background",
1212 "repo.background_hint": "PNG, JPG, WebP, or GIF up to 6 MB. The image fades into the current theme.",
1213 "admin.registration.public": "Public Registration",
1214 "admin.registration.confirm": "Confirm-only Registration",
1215 "admin.registration.closed": "No Registration",
1216 "admin.registration.public_desc": "Accounts become active immediately.",
1217 "admin.registration.confirm_desc": "Accounts become active after administrator approval.",
1218 "admin.registration.closed_desc": "New accounts cannot be created by visitors.",
1219 "admin.registration.mode": "New accounts",
1220 "admin.repos": "Repositories",
1221 "admin.col.status": "Status",
1222 "admin.col.actions": "Actions",
1223 "admin.pending": "Pending",
1224 "admin.approved": "Approved",
1225 "admin.approve": "Approve",
1226 "admin.make_admin": "Make admin",
1227 "admin.remove_admin": "Remove admin",
1228 "admin.delete_user": "Delete",
1229 "admin.delete_repo": "Delete",
1230 "admin.repo_visibility": "Access",
1231 "admin.delete_user_title": "Delete account",
1232 "admin.delete_user_desc": "All repositories and user data will be permanently deleted.",
1233 "admin.delete_repo_title": "Delete repository",
1234 "admin.delete_repo_desc": "Git data, releases, and uploaded files will be permanently deleted.",
1235 "admin.confirm_user": "Type the username",
1236 "admin.confirm_repo": "Type the repository name",
1237 "flash.image_invalid": "The image is too large or uses an unsupported format.",
1238 "flash.image_save_failed": "The image could not be saved. Please try again.",
1239 "flash.account_deleted": "The account and all of its repositories were deleted.",
1240 "flash.account_delete_failed": "Could not delete the account.",
1241 "flash.admin_user_approved": "Account @%s approved.",
1242 "flash.admin_user_missing": "User not found.",
1243 "flash.admin_user_update_failed": "Could not update the user.",
1244 "flash.admin_self_role": "You cannot change your own role from the admin panel.",
1245 "flash.admin_last_admin": "The last administrator cannot be removed or demoted.",
1246 "flash.admin_role_updated": "The role for @%s was updated.",
1247 "flash.admin_delete_self": "Delete your own account from profile settings.",
1248 "flash.admin_delete_mismatch": "The confirmation does not match.",
1249 "flash.admin_user_delete_failed": "Could not delete the user.",
1250 "flash.admin_user_deleted": "User @%s and their repositories were deleted.",
1251 "flash.admin_repo_missing": "Repository not found.",
1252 "flash.admin_repo_delete_failed": "Could not delete the repository.",
1253 "flash.admin_repo_deleted": "Repository %s/%s deleted.",
1254 "flash.admin_registration_invalid": "Invalid registration mode."},
1255 }
1256
1257 func T(lang Lang, key string) string {
1258 dict, ok := translations[Normalize(string(lang))]
1259 if !ok {
1260 dict = translations[RU]
1261 }
1262 if val, ok := dict[key]; ok {
1263 return val
1264 }
1265 if val, ok := translations[RU][key]; ok {
1266 return val
1267 }
1268 return key
1269 }
1270