Files
tiny-forge/web/src/lib/i18n/ru.json
T
alexei.dolgolyov 05440a5f92
Build / build (push) Successful in 10m50s
feat(stats): resource metrics dashboard + sites logs/stats
Background collector samples CPU/memory/network/block I/O for every
instance and site on a configurable interval (default 15s, range
5-300s), persists samples to SQLite with a configurable retention
window (default 2h, range 0-24h), and skips ticks gracefully when
the Docker daemon is unreachable. Settings are reloadable without
a restart — each tick re-reads them.

New API endpoints:
- GET /api/system/stats (host snapshot: info + df)
- GET /api/system/stats/history
- GET /api/system/stats/top?by=cpu|memory
- GET /api/projects/{id}/stages/{s}/instances/{iid}/stats/history
- GET /api/sites/{id}/stats[/history]
- GET /api/sites/{id}/logs (SSE + JSON, reuses instance log streamer)

Frontend:
- ECharts added with tree-shaken imports (~180KB gzip) for
  future-proof time-series/gantt/graph visualizations
- CollapsibleSection wraps all dashboard sections (system health,
  daemons, system resources, static sites, projects) with
  localStorage-persisted open state
- SystemResourcesCard shows capacity tiles, workload utilization
  chart with 30m/2h/6h/24h window picker, disk breakdown with
  reclaimable callouts, and top 5 consumers
- ContainerStats and ContainerLogs take a source discriminated union
  so sites reuse the same components as instances; sites detail page
  embeds both for Deno backend debugging
- Settings › Maintenance exposes collection interval + retention
- Docker-unavailable state returns 503 and renders an amber banner
  instead of a generic 500

Full i18n coverage (en + ru) for all new strings.
2026-04-24 15:02:43 +03:00

1170 lines
65 KiB
JSON
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.
{
"app": {
"name": "Tinyforge",
"version": "v0.1"
},
"health": {
"connected": "подключён",
"disconnected": "отключён",
"rawError": "Технические детали",
"retryNow": "Проверить сейчас"
},
"nav": {
"dashboard": "Панель",
"projects": "Проекты",
"deploy": "Деплой",
"proxies": "Прокси",
"events": "События",
"settings": "Настройки",
"logout": "Выйти",
"dns": "DNS-записи",
"sites": "Сайты",
"stacks": "Стеки"
},
"dashboard": {
"title": "Панель управления",
"quickDeploy": "Быстрый деплой",
"totalProjects": "Всего проектов",
"runningInstances": "Запущенных экземпляров",
"failedInstances": "Сбойных экземпляров",
"projects": "Проекты",
"retry": "Повторить",
"noProjects": "Проектов пока нет.",
"addFirst": "Добавьте первый проект",
"loadFailed": "Не удалось загрузить панель",
"staleContainers": "Устаревшие контейнеры",
"unusedImagesWarning": "Неиспользуемые Docker-образы занимают дисковое пространство",
"unusedImages": "неиспользуемых образов",
"staticSites": "Статические сайты",
"totalSites": "Всего сайтов",
"deployedSites": "развёрнуто",
"failedSites": "с ошибкой",
"noSites": "Статических сайтов пока нет.",
"addFirstSite": "Разверните первый сайт",
"viewAllSites": "Все сайты",
"systemHealth": "Состояние системы",
"daemons": "Демоны",
"systemResources": "Системные ресурсы",
"systemResourcesSubtitle": "CPU, память, диск и топ потребителей"
},
"resources": {
"cpuCores": "Ядра CPU",
"memory": "Память",
"running": "Запущено",
"dockerDisk": "Диск Docker",
"workloadUtilization": "Использование нагрузкой",
"windowMinutes": "{n} минут",
"windowHours": "{n} часов",
"noSamples": "Пока нет данных — сбор идёт каждые {interval}с.",
"diskImages": "Образы",
"diskContainers": "Контейнеры",
"diskVolumes": "Тома",
"diskBuildCache": "Кэш сборки",
"reclaimable": "{size} можно освободить",
"topConsumers": "Топ потребителей",
"byCpu": "по CPU",
"byMemory": "по памяти",
"noRunning": "Нет запущенных контейнеров.",
"instance": "экземпляр",
"site": "сайт",
"showHistory": "Показать историю",
"hideHistory": "Скрыть историю",
"cpuSeries": "CPU %",
"memorySeries": "Память %",
"loading": "Загрузка…",
"sectionTitle": "Ресурсы",
"showLogs": "Показать логи",
"hideLogs": "Скрыть логи",
"dockerUnavailable": "Docker недоступен. Проверьте, что демон запущен."
},
"statsSettings": {
"intervalLabel": "Интервал сбора статистики (с)",
"intervalHelp": "Как часто собираются замеры ресурсов. 0 отключает сбор. Диапазон: 5–300с.",
"retentionLabel": "Хранение статистики (часы)",
"retentionHelp": "Как долго хранятся замеры ресурсов. 0 отключает сбор. Диапазон: 0–24ч."
},
"projects": {
"title": "Проекты",
"addProject": "Добавить проект",
"cancel": "Отмена",
"newProject": "Новый проект",
"name": "Название",
"image": "Образ",
"port": "Порт",
"registry": "Реестр",
"created": "Создан",
"view": "Открыть",
"noProjects": "Проекты ещё не настроены.",
"getStarted": "Нажмите «Добавить проект» для начала.",
"createProject": "Создать проект",
"creating": "Создание...",
"healthcheck": "Путь проверки здоровья",
"nameRequired": "Название и образ обязательны.",
"loadFailed": "Не удалось загрузить проекты",
"createFailed": "Не удалось создать проект",
"browseImages": "Обзор образов",
"selectImage": "Выберите образ",
"noImages": "Образы не найдены",
"loadingImages": "Загрузка образов...",
"imageLoadFailed": "Не удалось загрузить образы",
"alreadyAdded": "Уже добавлен",
"portHelpText": "Автоопределение из EXPOSE, если пусто",
"healthcheckHelpText": "Автоопределение из образа, если пусто",
"searchPlaceholder": "Поиск по имени, образу или реестру...",
"noMatchingProjects": "Проекты не найдены."
},
"projectDetail": {
"webhookTitle": "Webhook проекта",
"webhookDesc": "Отправьте POST с image-ссылкой на этот URL из CI — и Tinyforge запустит деплой. Стейдж выбирается по tag_pattern.",
"deleteProject": "Удалить проект",
"envVars": "Переменные окружения",
"volumes": "Тома",
"stages": "Стадии",
"noStages": "Для этого проекта не настроены стадии.",
"pattern": "Шаблон",
"autoDeploy": "авто-деплой",
"requiresConfirm": "нужно подтверждение",
"instances": "экземпляров",
"deployNewVersion": "Развернуть новую версию",
"selectTag": "Выберите тег для деплоя",
"loadingTags": "Загрузка тегов...",
"chooseTag": "Выберите тег...",
"enterTag": "Введите тег образа (напр., dev-abc123)",
"registryTag": "Реестр",
"localTag": "Локальный",
"alsoLocal": "Также доступен локально",
"searchTags": "Поиск тегов...",
"deployTag": "Тег",
"deploy": "Развернуть",
"deploying": "Развёртывание...",
"recentDeploys": "Последние деплои",
"noDeployHistory": "Нет истории деплоев для этого проекта.",
"tag": "Тег",
"status": "Статус",
"started": "Начат",
"finished": "Завершён",
"error": "Ошибка",
"noInstancesRunning": "Нет запущенных экземпляров",
"deleteConfirmTitle": "Удалить проект",
"deleteConfirmMessage": "Это безвозвратно удалит проект '{name}' и все его стадии, экземпляры и историю деплоев.",
"loadFailed": "Не удалось загрузить проект",
"deleteFailed": "Не удалось удалить проект",
"deployFailed": "Деплой не удался",
"nameLabel": "Название *",
"imageLabel": "Образ *",
"portLabel": "Порт",
"healthcheckLabel": "Путь проверки",
"saving": "Сохранение...",
"addStage": "Добавить стадию",
"tagPattern": "Шаблон тега",
"tagPatternHelp": "Glob-шаблон (напр., dev-*, v*)",
"maxInstances": "Макс. экземпляров",
"autoDeployLabel": "Авто-деплой",
"enableProxy": "Включить прокси",
"accessListId": "ID списка доступа NPM",
"accessListIdHelp": "Переопределить глобальный список доступа для этого проекта. Очистите, чтобы наследовать из настроек NPM.",
"localImages": "Локальные Docker-образы",
"imageTag": "Тег",
"imageId": "ID образа",
"imageSize": "Размер",
"imageCreated": "Создан",
"cpuLimit": "Лимит CPU (ядра)",
"cpuLimitHelp": "напр., 0.5, 1, 2. Оставьте 0 для без ограничений",
"memoryLimit": "Лимит памяти (МБ)",
"memoryLimitHelp": "напр., 256, 512, 1024. Оставьте 0 для без ограничений",
"npmProxy": "NPM прокси",
"creating": "Создание...",
"createStage": "Создать стадию",
"noProxy": "Без прокси",
"deleteStage": "Удалить стадию",
"deleteStageConfirm": "Удалить стадию \"{name}\"?",
"stageCreated": "Стадия \"{name}\" создана",
"stageUpdated": "Стадия обновлена",
"stageUpdateFailed": "Не удалось обновить стадию",
"stageDeleted": "Стадия \"{name}\" удалена",
"projectUpdated": "Проект обновлён",
"updateFailed": "Не удалось обновить проект",
"stageCreateFailed": "Не удалось создать стадию",
"stageDeleteFailed": "Не удалось удалить стадию"
},
"envEditor": {
"title": "Переменные окружения",
"description": "Управление переопределениями переменных окружения на уровне стадий. Значения стадий переопределяют значения проекта.",
"stage": "Стадия",
"projectDefaults": "Значения проекта по умолчанию",
"noProjectEnv": "Переменные окружения на уровне проекта ещё не определены.",
"stageOverrides": "Переопределения стадии",
"key": "Ключ",
"value": "Значение",
"secret": "Секрет",
"source": "Источник",
"actions": "Действия",
"overridden": "переопределено",
"inherited": "наследуется",
"overridesProject": "переопределяет проект",
"stageOnly": "только стадия",
"edit": "Изменить",
"change": "Изменить",
"delete": "Удалить",
"save": "Сохранить",
"add": "Добавить",
"adding": "Добавление...",
"noStages": "Стадии не настроены. Сначала добавьте стадии к проекту.",
"loadFailed": "Не удалось загрузить проект",
"envAdded": "Переменная окружения добавлена",
"envUpdated": "Переменная окружения обновлена",
"envDeleted": "Переменная окружения удалена",
"addFailed": "Не удалось добавить переменную",
"updateFailed": "Не удалось обновить переменную",
"deleteFailed": "Не удалось удалить переменную",
"loadEnvFailed": "Не удалось загрузить переменные",
"leaveEmptyToKeep": "Оставьте пустым, чтобы сохранить текущее",
"deleteTitle": "Удалить переменную окружения",
"deleteMessage": "Вы уверены, что хотите удалить эту переменную окружения? Это действие нельзя отменить."
},
"volumeEditor": {
"title": "Тома",
"description": "Настройка монтирования томов для контейнеров. Выберите область видимости для управления общим доступом между развёртываниями.",
"sourceHost": "Источник (хост)",
"targetContainer": "Цель (контейнер)",
"scope": "Область",
"nameColumn": "Имя",
"namePlaceholder": "напр. shared-db",
"requiresName": "требуется имя",
"noHostPath": "нет пути на хосте",
"tmpfs": "tmpfs (в памяти)",
"actions": "Действия",
"edit": "Изменить",
"delete": "Удалить",
"save": "Сохранить",
"add": "Добавить",
"adding": "Добавление...",
"scopeGuide": "Области видимости томов",
"noVolumes": "Тома ещё не настроены. Добавьте один выше.",
"volumeAdded": "Том добавлен",
"volumeUpdated": "Том обновлён",
"volumeDeleted": "Том удалён",
"loadFailed": "Не удалось загрузить тома",
"addFailed": "Не удалось добавить том",
"updateFailed": "Не удалось обновить том",
"deleteFailed": "Не удалось удалить том"
},
"volumeBrowser": {
"title": "Обзор тома",
"loadFailed": "Не удалось загрузить каталог",
"empty": "Этот каталог пуст.",
"name": "Имя",
"size": "Размер",
"modified": "Изменён",
"downloadAll": "Скачать том как ZIP",
"downloadFolder": "Скачать папку как ZIP",
"upload": "Загрузить файлы",
"uploaded": "Загружено",
"files": "файл(ов)",
"uploadFailed": "Не удалось загрузить файлы",
"browse": "Обзор",
"download": "Скачать"
},
"quickDeploy": {
"title": "Быстрый деплой",
"description": "Разверните образ контейнера без настройки. Вставьте URL образа, проверьте параметры и разверните.",
"step1": "1. Введите URL образа",
"imageUrl": "URL образа",
"imageUrlHelp": "Полный URL образа с тегом (напр., git.example.com/user/app:dev-abc123)",
"inspect": "Проверить",
"inspecting": "Проверка...",
"step2": "2. Проверка конфигурации",
"reviewDesc": "Эти параметры были обнаружены из образа. Измените при необходимости перед деплоем.",
"projectName": "Имя проекта",
"port": "Порт",
"portHelp": "Порт контейнера (1-65535)",
"healthCheckPath": "Путь проверки здоровья",
"healthCheckHelp": "Необязательный HTTP-путь для проверки работоспособности",
"stage": "Стадия",
"development": "Разработка",
"release": "Релиз",
"production": "Продакшн",
"stageHelp": "Стадия развёртывания для этого образа",
"subdomainOverride": "Переопределение поддомена",
"subdomainHelp": "Оставьте пустым для использования шаблона по умолчанию",
"envVars": "Переменные окружения",
"envVarsHelp": "По одной на строку, формат KEY=VALUE",
"step3": "3. Развёртывание",
"deployDesc": "Будет создан новый проект и контейнер будет развёрнут немедленно.",
"deployBtn": "Развернуть",
"inspectedSuccess": "Образ успешно проверен",
"deployedSuccess": "{name} успешно развёрнут!",
"inspectFailed": "Не удалось проверить образ",
"deployFailed": "Развёртывание не удалось",
"browseImages": "Обзор",
"selectImage": "Выберите образ из реестра",
"noImages": "Образы не найдены",
"loadingImages": "Загрузка...",
"imageLoadFailed": "Не удалось загрузить образы",
"autoDeployLabel": "Развернуть сразу",
"lowercaseHint": "Строчные буквы и дефисы",
"imageAlreadyExists": "Образ уже развёрнут",
"conflictDescription": "Проект с этим образом уже существует. Откройте существующий проект для развёртывания новой версии или создайте отдельный проект.",
"openProject": "Открыть проект \u2192",
"createNewAnyway": "Создать новый проект"
},
"settings": {
"title": "Настройки",
"general": "Общие",
"integrations": "Интеграции",
"dns": "DNS",
"maintenance": "Обслуживание",
"registries": "Реестры",
"credentials": "Учётные данные",
"authentication": "Аутентификация",
"backup": "Резервные копии",
"appearance": "Внешний вид",
"groupMain": "Обзор",
"groupProxy": "Маршрутизация",
"groupSystem": "Система",
"groupSecurity": "Безопасность",
"staleThreshold": "Порог устаревания (дни)",
"staleThresholdHelp": "Контейнеры, неактивные дольше этого срока, будут помечены как устаревшие.",
"dockerCleanup": "Очистка Docker-образов",
"dockerCleanupHelp": "Удаление неиспользуемых Docker-образов ваших проектов. Удаляются только образы, не используемые активными экземплярами.",
"pruneThreshold": "Порог предупреждения (МБ)",
"pruneThresholdHelp": "Показывать предупреждение на дашборде, когда неиспользуемые образы превышают этот размер. 0 = отключено.",
"pruneImages": "Очистить неиспользуемые образы",
"pruning": "Очистка...",
"pruneResult": "Удалено {count} образов, освобождено {mb} МБ",
"pruneConfirmMessage": "Будут удалены неиспользуемые Docker-образы ваших проектов. Образы активных экземпляров не затрагиваются.",
"pruneFailed": "Не удалось очистить образы",
"proxyProvider": "Провайдер прокси",
"proxyProviderHelp": "Выберите способ управления обратным прокси для развёрнутых контейнеров.",
"proxyNone": "Нет",
"proxyNoneDesc": "Без прокси — контейнеры доступны напрямую по порту",
"proxyNpm": "Nginx Proxy Manager",
"proxyNpmDesc": "Маршруты через NPM API (настройте учётные данные ниже)",
"npm": "Nginx Proxy Manager",
"traefik": "Traefik",
"traefikLabelsTitle": "Справка по Docker-меткам",
"traefikLabelsDesc": "Эти метки автоматически добавляются к развёрнутым контейнерам. Показаны для справки.",
"proxyTraefik": "Traefik",
"proxyTraefikDesc": "Автообнаружение через Docker-метки — без API-вызовов",
"proxyNoneWarning": "Переключение на «Нет» не удаляет существующие прокси-маршруты. Возможно, потребуется очистить их вручную.",
"traefikEntrypoint": "Точка входа",
"traefikEntrypointHelp": "Имя точки входа Traefik для HTTPS-маршрутов",
"traefikCertResolver": "Резолвер сертификатов",
"traefikCertResolverHelp": "Имя резолвера TLS-сертификатов (напр., letsencrypt)",
"traefikNetwork": "Docker-сеть",
"traefikNetworkHelp": "Сеть, которую слушает Traefik (оставьте пустым для глобальной сети)",
"traefikApiUrl": "URL API Traefik",
"traefikApiUrlHelp": "Необязательно — для проверки состояния (напр., http://traefik:8080)"
},
"settingsGeneral": {
"title": "Общие настройки",
"globalConfig": "Глобальная конфигурация",
"globalConfigDesc": "Базовая инфраструктура: домен, сеть и интервал опроса, используемые Tinyforge для оркестрации контейнеров.",
"configureNpm": "Выбран Nginx Proxy Manager.",
"configureTraefik": "Выбран Traefik.",
"configureLink": "Настроить провайдера",
"domain": "Домен",
"domainHelp": "Базовый домен для маршрутизации (напр., example.com → stage-dev-app.example.com)",
"serverIp": "IP сервера (Docker Host)",
"serverIpHelp": "IP машины с Docker. Используется для удалённого NPM.",
"publicIp": "Публичный IP (для DNS)",
"publicIpHelp": "IP для DNS A-записей — обычно адрес прокси/балансировщика. Если пусто, используется IP сервера.",
"dockerNetwork": "Docker-сеть",
"dockerNetworkHelp": "Docker-сеть, общая для контейнеров и прокси. Должна совпадать с сетью NPM/Traefik.",
"subdomainPattern": "Шаблон поддомена",
"subdomainPatternHelp": "Шаблон для автоматически генерируемых поддоменов",
"subdomainVarsTitle": "Доступные переменные",
"varProject": "Имя проекта",
"varStage": "Имя стадии",
"varTag": "Тег образа",
"varPort": "Порт контейнера",
"pollingInterval": "Интервал опроса (секунды)",
"pollingIntervalHelp": "Как часто проверять реестры на новые теги (60-86400)",
"notificationUrl": "URL уведомлений",
"notificationUrlHelp": "URL вебхука для уведомлений о деплоях",
"saveSettings": "Сохранить настройки",
"saving": "Сохранение...",
"saved": "Настройки успешно сохранены",
"saveFailed": "Не удалось сохранить настройки",
"loadFailed": "Не удалось загрузить настройки",
"webhookUrl": "URL вебхука",
"webhookDesc": "Этот секретный URL получает уведомления о push-событиях из вашего CI-пайплайна.",
"noWebhookUrl": "URL вебхука не настроен",
"copy": "Копировать",
"copied": "URL вебхука скопирован в буфер обмена",
"regenerateUrl": "Перегенерировать URL",
"regenerating": "Перегенерация...",
"regenerated": "URL вебхука перегенерирован",
"regenerateFailed": "Не удалось перегенерировать URL вебхука",
"regenerateWarning": "Внимание: перегенерация сделает текущий URL недействительным. Обновите ваши CI-пайплайны.",
"sslCertificate": "SSL-сертификат",
"sslCertificateHelp": "Wildcard-сертификат из NPM для автоматического SSL на прокси-хостах",
"selectCertificate": "Выбрать сертификат",
"noCertificate": "Нет (без SSL)",
"clearCertificate": "Очистить",
"loadingCertificates": "Загрузка сертификатов...",
"noCertificatesFound": "Wildcard-сертификаты в NPM не найдены",
"dnsConfig": "Настройки DNS",
"wildcardDns": "Wildcard DNS настроен",
"wildcardDnsHelp": "Когда включено, все поддомены разрешаются на ваш сервер через wildcard DNS правило. Отключите для управления DNS-записями для каждого сервиса.",
"dnsProvider": "DNS-провайдер",
"dnsProviderHelp": "Выберите DNS-провайдера для автоматического управления записями",
"cloudflareApiToken": "API-токен Cloudflare",
"cloudflareApiTokenHelp": "API-токен с правами редактирования DNS для вашей зоны",
"cloudflareApiTokenPlaceholder": "Введите API-токен Cloudflare",
"cloudflareApiTokenConfigured": "API-токен настроен",
"cloudflareZone": "Зона Cloudflare",
"cloudflareZoneHelp": "Выберите DNS-зону для управления записями",
"selectZone": "Выбрать зону",
"noZone": "Зона не выбрана",
"loadingZones": "Загрузка зон...",
"noZonesFound": "Зоны для этого токена не найдены",
"testConnection": "Проверить соединение",
"testingConnection": "Проверка...",
"connectionSuccess": "Соединение успешно",
"connectionFailed": "Ошибка соединения",
"baseVolumePath": "Базовый путь томов",
"baseVolumePathHelp": "Добавляется к относительным путям источников (напр., /data + my-app/uploads = /data/my-app/uploads)"
},
"settingsRegistries": {
"title": "Реестры контейнеров",
"description": "Управление реестрами контейнеров для обнаружения образов.",
"addRegistry": "Добавить реестр",
"editRegistry": "Редактировать реестр",
"addNewRegistry": "Добавить новый реестр",
"name": "Название",
"nameHelp": "Понятное название для этого реестра",
"url": "URL",
"urlHelp": "Базовый URL реестра",
"type": "Тип",
"typeHelp": "Тип реестра для совместимости API",
"token": "Токен",
"tokenHelpNew": "API-токен для аутентификации",
"tokenHelpEdit": "Оставьте пустым, чтобы сохранить текущий токен",
"owner": "Владелец",
"ownerHelp": "Владельцы пакетов через запятую (напр., alexei,my-org)",
"save": "Сохранить",
"saving": "Сохранение...",
"update": "Обновить",
"test": "Тест",
"testing": "Тестирование...",
"edit": "Изменить",
"delete": "Удалить",
"noRegistries": "Реестры ещё не настроены.",
"addFirst": "Добавьте первый реестр",
"registryUpdated": "Реестр обновлён",
"registryAdded": "Реестр добавлен",
"registryDeleted": "Реестр «{name}» удалён",
"testSuccess": "Подключение к «{name}» успешно",
"saveFailed": "Не удалось сохранить реестр",
"deleteFailed": "Не удалось удалить реестр",
"testFailed": "Тест подключения не удался",
"loadFailed": "Не удалось загрузить реестры",
"deleteConfirm": "Удалить реестр «{name}»? Это действие необратимо.",
"healthChecking": "Проверка...",
"healthConnected": "Подключено",
"healthUnreachable": "Недоступно"
},
"settingsNpm": {
"testConnection": "Проверить соединение",
"testing": "Проверка...",
"testSuccess": "Подключение к NPM успешно",
"testFailed": "Не удалось подключиться к NPM",
"saveFailedConnection": "Невозможно сохранить — проверка соединения не пройдена",
"remoteMode": "Удалённый NPM",
"remoteModeHelp": "Включите, если NPM работает на другой машине. Перенаправление на IP сервера с опубликованными портами.",
"remoteModeWarning": "Требуется IP сервера в общих настройках. Порты автоматически привязываются к случайным портам хоста.",
"accessList": "Список доступа по умолчанию",
"accessListHelp": "Список доступа NPM для HTTP-аутентификации на прокси-хостах. Можно переопределить для каждого проекта.",
"noAccessList": "Глобальные настройки",
"selectAccessList": "Выберите список доступа",
"noAccessLists": "Списки доступа в NPM не найдены",
"accessListLoadFailed": "Не удалось загрузить списки доступа"
},
"settingsCredentials": {
"title": "Учётные данные",
"description": "Управление учётными данными для Nginx Proxy Manager и токенами реестров. Все значения зашифрованы.",
"npm": "Nginx Proxy Manager",
"npmDesc": "Учётные данные для управления прокси-хостами через NPM API",
"configured": "Настроено",
"npmUrl": "URL NPM",
"npmUrlHelp": "URL API Nginx Proxy Manager",
"email": "Email",
"emailHelp": "Email администратора NPM",
"password": "Пароль",
"passwordHelpNew": "Пароль администратора NPM (будет зашифрован)",
"passwordHelpEdit": "Введите новый пароль для замены текущего",
"changeCredentials": "Изменить учётные данные",
"save": "Сохранить",
"saving": "Сохранение...",
"saved": "Учётные данные NPM сохранены",
"saveFailed": "Не удалось сохранить учётные данные NPM",
"loadFailed": "Не удалось загрузить учётные данные",
"registryTokens": "Токены реестров",
"registryTokensDesc": "Токены аутентификации реестров управляются для каждого реестра в разделе",
"registriesLink": "Реестры",
"registryTokensSuffix": ". Каждый реестр хранит свой токен в зашифрованном виде.",
"notSet": "Не задано"
},
"settingsBackup": {
"title": "Управление резервными копиями",
"description": "Управление резервными копиями базы данных и настройка автоматического резервного копирования.",
"autoBackup": "Автоматическое резервное копирование",
"autoBackupHelp": "Автоматически создавать резервные копии с заданным интервалом.",
"interval": "Интервал копирования",
"intervalHelp": "Как часто создавать автоматические резервные копии.",
"intervalHours": "{hours} часов",
"retention": "Количество хранимых копий",
"retentionHelp": "Максимальное количество хранимых резервных копий. Старые удаляются первыми.",
"backupNow": "Создать копию",
"creatingBackup": "Создание...",
"backupCreated": "Резервная копия создана",
"backupFailed": "Не удалось создать резервную копию",
"backupList": "Резервные копии",
"noBackups": "Резервных копий пока нет. Создайте вручную или включите автоматическое копирование.",
"columnFilename": "Файл",
"columnSize": "Размер",
"columnType": "Тип",
"columnDate": "Создано",
"columnActions": "Действия",
"download": "Скачать",
"delete": "Удалить",
"restore": "Восстановить",
"deleteConfirm": "Вы уверены, что хотите удалить эту резервную копию?",
"deleted": "Резервная копия удалена",
"deleteFailed": "Не удалось удалить резервную копию",
"restoreConfirm": "Вы уверены, что хотите восстановить из этой копии? Текущая база данных будет заменена и сервер будет перезапущен. Все текущие данные будут потеряны.",
"restoreWarning": "Это действие необратимо!",
"restored": "База данных восстановлена. Сервер перезапускается...",
"restoreFailed": "Не удалось восстановить резервную копию",
"typeManual": "Ручная",
"typeAuto": "Авто",
"save": "Сохранить",
"saving": "Сохранение...",
"saved": "Настройки копирования сохранены",
"saveFailed": "Не удалось сохранить настройки копирования"
},
"settingsAuth": {
"title": "Настройки аутентификации",
"description": "Настройка режима аутентификации и управление пользователями.",
"authMode": "Режим аутентификации",
"local": "Локальный (логин/пароль)",
"oidc": "OIDC (SSO)",
"oidcConfig": "Конфигурация OIDC-провайдера",
"issuerUrl": "URL издателя",
"clientId": "ID клиента",
"clientSecret": "Секрет клиента",
"redirectUrl": "URL перенаправления",
"saveSettings": "Сохранить настройки",
"saving": "Сохранение...",
"saved": "Настройки сохранены",
"saveFailed": "Не удалось сохранить",
"loadFailed": "Не удалось загрузить настройки",
"localUsers": "Локальные пользователи",
"username": "Имя пользователя",
"email": "Email",
"role": "Роль",
"created": "Создан",
"noUsers": "Пользователи не найдены.",
"addUser": "Добавить пользователя",
"viewer": "Наблюдатель",
"admin": "Администратор",
"userCreated": "Пользователь создан",
"userDeleted": "Пользователь удалён",
"createFailed": "Не удалось создать пользователя",
"deleteFailed": "Не удалось удалить пользователя",
"deleteConfirm": "Вы уверены, что хотите удалить этого пользователя?",
"usernameRequired": "Имя пользователя и пароль обязательны",
"networkError": "Ошибка сети",
"password": "Пароль"
},
"login": {
"title": "Tinyforge",
"subtitle": "Войдите в свой аккаунт",
"username": "Имя пользователя",
"password": "Пароль",
"signIn": "Войти",
"signingIn": "Вход...",
"or": "или",
"ssoButton": "Войти через SSO (OIDC)",
"loginFailed": "Ошибка входа",
"networkError": "Ошибка сети"
},
"proxies": {
"title": "Менеджер прокси",
"create": "Создать прокси",
"standalone": "Автономные прокси",
"managed": "Управляемые прокси",
"noProxies": "Прокси не найдены",
"noProxiesDesc": "Создайте автономный прокси или разверните проект с включённым прокси.",
"filter": {
"search": "Поиск по домену или назначению...",
"health": "Здоровье",
"type": "Тип",
"all": "Все",
"clear": "Сбросить фильтры"
},
"health": {
"healthy": "Здоров",
"unhealthy": "Нездоров",
"unknown": "Неизвестно"
},
"lastChecked": "Последняя проверка"
},
"sites": {
"webhookTitle": "Webhook сайта",
"webhookDesc": "Укажите этот URL в push-вебхуке Git-провайдера. Tinyforge пересинхронизирует сайт при подходящей ref-ссылке (ветка для push, шаблон тега для tag). Пустое тело запускает синхронизацию безусловно.",
"title": "Статические сайты",
"addSite": "Новый сайт",
"newSite": "Новый статический сайт",
"createSite": "Создать сайт",
"noSites": "Нет статических сайтов",
"noSitesDesc": "Разверните статический контент из папки Git-репозитория.",
"searchPlaceholder": "Поиск по имени, домену или репозиторию...",
"noMatching": "Нет сайтов, соответствующих поиску.",
"name": "Имя",
"domain": "Домен",
"mode": "Режим",
"status": "Статус",
"lastSync": "Последняя синхр.",
"deploy": "Развернуть",
"stop": "Остановить",
"start": "Запустить",
"openSite": "Открыть сайт",
"confirmDelete": "Удалить сайт",
"confirmDeleteMsg": "Это удалит сайт и его контейнер",
"confirmDeleteSecret": "Удалить секрет",
"confirmDeleteSecretMsg": "Вы уверены, что хотите удалить секрет",
"siteInfo": "Информация о сайте",
"folder": "Папка",
"syncTrigger": "Триггер синхр.",
"commitSha": "Коммит SHA",
"secrets": "Секреты",
"addSecret": "Добавить секрет",
"noSecrets": "Секреты не настроены. Добавьте их, если сайту нужны серверные API-ключи.",
"secretKey": "Ключ",
"secretValue": "Значение",
"encryptSecret": "Шифровать значение",
"saveSecret": "Добавить секрет",
"step1Title": "1. Репозиторий",
"step2Title": "2. Выбор ветки",
"step3Title": "3. Выбор папки",
"step4Title": "4. Настройки",
"step5Title": "5. Проверка и создание",
"fullRepoUrl": "URL репозитория",
"fullRepoUrlHelp": "Вставьте полный URL для автозаполнения полей ниже (напр., https://git.example.com/owner/repo)",
"serverUrl": "URL сервера",
"repoUrl": "URL Git-сервера",
"repoUrlHelp": "Вставьте полный URL репозитория или базовый URL сервера (Gitea, Forgejo, Gogs)",
"repoOwner": "Владелец",
"repoName": "Репозиторий",
"accessToken": "Токен доступа",
"accessTokenPlaceholder": "Необязательно — для приватных репозиториев",
"accessTokenHelp": "Персональный токен с правами на чтение репозитория. Оставьте пустым для публичных.",
"noToken": "Нет (публичный репо)",
"testConnection": "Проверить соединение",
"connectionSuccess": "Репозиторий доступен",
"loadingBranches": "Загрузка веток...",
"selectBranch": "Выберите ветку",
"chooseBranch": "Выберите ветку...",
"branch": "Ветка",
"loadingTree": "Загрузка дерева репозитория...",
"selectFolder": "Выберите папку с файлами сайта",
"selectedFolder": "Выбранная папка",
"siteName": "Имя сайта",
"domainHelp": "Публичный домен сайта. Прокси будет настроен автоматически.",
"modeStaticDesc": "HTML, CSS, JS, изображения через Nginx",
"modeDenoDesc": "Статические файлы + серверный API из папки api/",
"triggerManual": "Вручную",
"triggerPush": "При пуше",
"triggerTag": "По тегу",
"tagPattern": "Паттерн тега",
"tagPatternHelp": "Glob-паттерн для тегов (напр., v*, pages-*)",
"renderMarkdown": "Рендерить Markdown-файлы в HTML",
"provider": "Git-провайдер",
"detectedProvider": "Автоопределён",
"browseRepos": "Обзор репозиториев",
"selectRepo": "Выберите репозиторий",
"storage": "Хранилище данных",
"enableStorage": "Включить хранилище данных",
"storageHelp": "Подключает Docker-том в /app/data, чтобы Deno-бэкенд мог читать и записывать файлы, сохраняющиеся между деплоями.",
"storageLimitMB": "Лимит хранилища (МБ)",
"storageLimitHelp": "Максимальный размер хранилища в мегабайтах. 0 = без ограничений.",
"storageVolume": "Том",
"dataPath": "Путь к данным",
"storageMountPath": "Путь монтирования",
"storageLimit": "Лимит",
"storageUsed": "Использовано",
"storageOfLimit": "от лимита использовано",
"unlimited": "Без ограничений"
},
"common": {
"cancel": "Отмена",
"confirm": "Подтвердить",
"delete": "Удалить",
"edit": "Изменить",
"change": "Изменить",
"save": "Сохранить",
"retry": "Повторить",
"loading": "Загрузка...",
"noData": "Нет данных",
"project": "Проект",
"back": "Назад",
"actions": "Действия",
"stop": "Остановить",
"start": "Запустить",
"restart": "Перезапустить",
"remove": "Удалить",
"instance": "экземпляр",
"instances": "экземпляров",
"next": "Далее",
"yes": "Да",
"no": "Нет",
"saving": "Сохранение..."
},
"instance": {
"stopConfirm": "Контейнер будет остановлен. Экземпляр можно будет запустить снова позже.",
"restartConfirm": "Контейнер будет перезапущен с кратковременным простоем.",
"removeConfirm": "Контейнер и его прокси-конфигурация будут безвозвратно удалены.",
"actionFailed": "Действие не удалось"
},
"empty": {
"noProjects": "Проектов пока нет",
"noProjectsDesc": "Начните с создания первого проекта или используйте быстрый деплой.",
"createProject": "Создать проект",
"noInstances": "Нет экземпляров",
"noInstancesDesc": "Разверните новую версию, чтобы увидеть экземпляры здесь.",
"noDeploys": "Нет истории деплоев",
"noDeploysDesc": "История деплоев появится здесь после первого развёртывания.",
"noRegistries": "Нет реестров",
"noRegistriesDesc": "Добавьте реестр контейнеров для обнаружения образов.",
"noVolumes": "Нет томов",
"noVolumesDesc": "Настройте монтирование томов для постоянных данных.",
"noUsers": "Нет пользователей",
"noUsersDesc": "Добавьте локальных пользователей для управления доступом."
},
"validation": {
"required": "Поле {field} обязательно",
"invalidUrl": "Неверный формат URL",
"invalidDomain": "Неверный формат домена",
"invalidIp": "Неверный формат IP",
"invalidEmail": "Неверный формат email",
"invalidPort": "Порт должен быть от 1 до 65535",
"invalidPollingInterval": "Интервал опроса должен быть от 60 до 86400 секунд",
"invalidProjectName": "Допускаются только строчные буквы, цифры и дефисы",
"requiredWhenUpdating": "Поле {field} обязательно при обновлении учётных данных",
"requiredForNew": "Поле {field} обязательно для новых реестров"
},
"confirm": {
"stopInstance": "Остановить экземпляр",
"startInstance": "Запустить экземпляр",
"restartInstance": "Перезапустить экземпляр",
"removeInstance": "Удалить экземпляр",
"stopAction": "Остановить",
"restartAction": "Перезапустить",
"removeAction": "Удалить"
},
"theme": {
"light": "Светлая",
"dark": "Тёмная",
"system": "Системная"
},
"entityPicker": {
"search": "Поиск...",
"noResults": "Ничего не найдено"
},
"stale": {
"title": "Устаревшие контейнеры",
"noStale": "Нет устаревших контейнеров",
"noStaleDesc": "Все контейнеры исправны и работают.",
"cleanup": "Очистить",
"cleanupAll": "Очистить все",
"confirmCleanup": "Это остановит и удалит контейнер. Продолжить?",
"confirmBulkCleanup": "Это остановит и удалит все устаревшие контейнеры. Продолжить?",
"daysStale": "дней устарел",
"lastAlive": "Последний раз жив",
"count": "Устаревшие",
"cleanedUp": "Контейнер очищен",
"bulkCleanedUp": "{count} контейнеров очищено",
"cleanupFailed": "Не удалось очистить",
"loadFailed": "Не удалось загрузить устаревшие контейнеры"
},
"proxies": {
"title": "Прокси",
"create": "Создать прокси",
"noProxies": "Прокси ещё не настроены.",
"noProxiesDesc": "Создайте автономный прокси или разверните проект, чтобы увидеть прокси здесь.",
"standalone": "Автономные прокси",
"managed": "Управляемые",
"lastChecked": "Последняя проверка",
"health": {
"healthy": "Работает",
"unhealthy": "Недоступен",
"unknown": "Неизвестно"
},
"filter": {
"search": "Поиск прокси...",
"health": "Здоровье",
"type": "Тип",
"all": "Все",
"clear": "Сбросить фильтры"
},
"form": {
"title": "Создать прокси",
"editTitle": "Редактировать прокси",
"destination": "URL / IP назначения",
"port": "Порт",
"domain": "Домен",
"domainHelp": "Публичный домен для этого прокси.",
"validate": "Проверить",
"validating": "Проверка...",
"create": "Создать прокси",
"save": "Сохранить изменения",
"cancel": "Отмена",
"delete": "Удалить",
"deleteConfirm": "Удалить этот прокси? Это действие необратимо."
},
"validation": {
"title": "Проверка назначения",
"syntax": "Синтаксис URL",
"dns": "DNS разрешение",
"tcp": "TCP подключение",
"http": "HTTP ответ",
"checking": "Проверка...",
"skipped": "Пропущено"
}
},
"proxies": {
"title": "Прокси-маршруты",
"description": "Активные прокси-маршруты от контейнеров и статических сайтов.",
"domain": "Домен",
"project": "Проект / Сайт",
"stage": "Этап / Режим",
"tag": "Тег",
"port": "Порт",
"status": "Статус",
"source": "Источник",
"sourceContainer": "Контейнер",
"sourceStatic": "Статический сайт",
"sourceDeno": "Deno-сайт",
"filterAll": "Все",
"filterContainers": "Контейнеры",
"filterSites": "Сайты",
"noRoutes": "Нет прокси-маршрутов",
"noRoutesDesc": "Прокси-маршруты создаются автоматически при развёртывании контейнера с прокси или публикации статического сайта.",
"searchPlaceholder": "Поиск по домену, проекту или тегу...",
"noMatch": "Нет маршрутов, соответствующих поиску.",
"loadFailed": "Не удалось загрузить прокси-маршруты",
"route": "маршрут",
"routes": "маршрутов"
},
"logs": {
"title": "Логи контейнера",
"lines": "строк",
"follow": "Следить",
"following": "Слежение...",
"loading": "Загрузка логов...",
"noLogs": "Нет вывода логов"
},
"events": {
"title": "Журнал событий",
"noEvents": "Событий не найдено",
"noEventsDesc": "События будут отображаться здесь по мере их возникновения.",
"loadMore": "Загрузить ещё",
"newEvents": "новых событий",
"totalCount": "всего {count}",
"clearAll": "Очистить всё",
"clearAllTitle": "Очистить журнал событий",
"clearAllMessage": "Все записи журнала событий будут удалены безвозвратно.",
"cleared": "Удалено {count} событий",
"clearFailed": "Не удалось очистить события",
"filter": {
"severity": "Уровень",
"source": "Источник",
"dateRange": "Период",
"search": "Поиск событий...",
"lastHour": "Последний час",
"last24h": "Последние 24 часа",
"last7d": "Последние 7 дней",
"allTime": "За всё время",
"clear": "Сбросить фильтры"
},
"severity": {
"info": "Инфо",
"warn": "Предупреждение",
"error": "Ошибка"
},
"source": {
"deploy": "Развёртывание",
"static_site": "Статический сайт",
"stale_scanner": "Сканер устаревших",
"stale_cleanup": "Очистка устаревших",
"admin": "Администратор"
},
"metadata": "Подробности"
},
"stats": {
"cpu": "ЦП",
"mem": "ОЗУ",
"unavailable": "Статистика недоступна"
},
"systemHealth": {
"title": "Состояние системы",
"containers": "Контейнеры",
"proxies": "Прокси",
"recentErrors": "Недавние ошибки"
},
"daemons": {
"title": "Демоны",
"refresh": "Обновить",
"refreshing": "Обновление",
"docker": "Docker Engine",
"npm": "Nginx Proxy Manager",
"traefik": "Traefik",
"proxy": "Прокси",
"online": "Онлайн",
"offline": "Оффлайн",
"notConfigured": "Не настроено",
"containers": "Контейнеры",
"running": "Запущено",
"paused": "Пауза",
"stopped": "Остановлено",
"version": "Версия",
"apiVersion": "Версия API",
"platform": "Платформа",
"kernel": "Ядро",
"cpu": "CPU",
"memory": "Память",
"storage": "Хранилище",
"images": "Образы",
"latency": "Задержка",
"rootDir": "Корневой каталог",
"provider": "Провайдер",
"endpoint": "Адрес",
"proxyHosts": "Прокси-хосты",
"managed": "наши",
"external": "внешние",
"accessLists": "Списки доступа",
"certificates": "Сертификаты",
"dockerHint": "Проверьте, что Docker-демон запущен и сокет доступен.",
"proxyHint": "Проверьте URL прокси, учётные данные и доступность сервиса.",
"noProxyDesc": "Провайдер прокси не настроен. Tinyforge поддерживает Nginx Proxy Manager или Traefik.",
"configureProxy": "Настроить в параметрах"
},
"dns": {
"title": "DNS-записи",
"description": "Просмотр и управление DNS-записями, созданными Tinyforge.",
"wildcardActive": "Режим Wildcard DNS активен",
"wildcardActiveDesc": "DNS-записи управляются внешне через wildcard DNS. Отключите wildcard DNS в настройках для индивидуального управления записями.",
"refresh": "Обновить",
"syncNow": "Синхронизировать",
"syncing": "Синхронизация...",
"syncComplete": "Синхронизация завершена: {created} создано, {deleted} удалено, {synced} уже синхронизировано",
"syncFailed": "Ошибка синхронизации DNS",
"searchPlaceholder": "Поиск по FQDN...",
"allConsumers": "Все потребители",
"managed": "Управляемые (инстансы)",
"standalone": "Автономные прокси",
"orphaned": "Осиротевшие",
"allStatuses": "Все статусы",
"statusSynced": "Синхронизировано",
"statusMissing": "Отсутствует",
"statusOrphaned": "Осиротевшее",
"columnFqdn": "FQDN",
"columnType": "Тип",
"columnValue": "Значение",
"columnConsumer": "Потребитель",
"columnStatus": "Статус",
"columnActions": "Действия",
"noConsumer": "Нет потребителя",
"noRecords": "DNS-записи не найдены. Записи появятся здесь после развёртывания сервисов.",
"noMatchingRecords": "Нет записей, соответствующих текущим фильтрам.",
"deleteRecord": "Удалить запись",
"recordDeleted": "DNS-запись {fqdn} удалена",
"deleteFailed": "Не удалось удалить DNS-запись",
"loadFailed": "Не удалось загрузить DNS-записи",
"totalRecords": "Всего: {count}",
"syncedCount": "Синхронизировано: {count}",
"missingCount": "Отсутствует: {count}",
"orphanedCount": "Осиротевших: {count}"
},
"language": {
"en": "Английский",
"ru": "Русский"
},
"stacks": {
"eyebrow": "КУЗНИЦА",
"title": "Стеки",
"lede": "Compose-чертежи, выкованные как <em>атомарные единицы</em>. Запускайте сервисы, меняйте ревизии и откатывайтесь без нервов.",
"newStack": "Новый стек",
"refresh": "Обновить",
"total": "Всего",
"running": "Работают",
"deploying": "Куются",
"failed": "Сбой",
"stopped": "Холодные",
"empty": {
"title": "Наковальня остыла.",
"desc": "Загрузите docker-compose.yml, чтобы выковать первый стек."
},
"card": {
"noDescription": "Без описания",
"updated": "Обновлён",
"start": "Запустить",
"stop": "Остановить",
"delete": "Удалить",
"open": "Открыть"
},
"new": {
"eyebrow": "НОВЫЙ ЧЕРТЁЖ",
"title": "Выковать новый стек.",
"lede": "Загрузите или вставьте <code>docker-compose.yml</code>. Все сервисы чертежа разворачиваются как одна атомарная единица.",
"back": "Стеки",
"name": "Имя",
"namePlaceholder": "мой-стек",
"nameHint": "Строчные буквы, через дефис. Используется как имя compose-проекта.",
"description": "Описание",
"descriptionPlaceholder": "Что делает этот стек?",
"composeYaml": "Compose YAML",
"required": "обязательно",
"optional": "необязательно",
"loadSample": "Загрузить пример",
"uploadFile": "Загрузить файл",
"dropHere": "Перетащите сюда docker-compose.yml",
"dropSub": "или нажмите для выбора · или используйте <strong>Загрузить пример</strong> выше",
"lines": "{n} строк",
"bytes": "{n} байт",
"clear": "Очистить",
"deployImmediate": "Развернуть сразу",
"deployHint": "Куй железо, пока горячо. Без галочки стек сохраняется холодным.",
"cancel": "Отмена",
"forging": "Куём…",
"forgeAndDeploy": "Выковать и развернуть",
"saveBlueprint": "Сохранить чертёж",
"errorRequired": "Имя и compose YAML обязательны.",
"errorCreate": "Не удалось создать стек"
},
"detail": {
"manifest": "МАНИФЕСТ",
"loading": "Загрузка чертежа…",
"composeProject": "COMPOSE-ПРОЕКТ",
"noDescription": "Без описания",
"refresh": "Обновить",
"start": "Запустить",
"stop": "Остановить",
"delete": "Удалить",
"fault": "СБОЙ",
"err": "ОШБ",
"stats": {
"services": "Сервисы",
"servicesSub": "в чертеже",
"running": "Работают",
"runningSub": "активных контейнеров",
"revisions": "Ревизии",
"revisionsSub": "в истории",
"current": "Текущая",
"currentSub": "развёрнута"
},
"services": {
"title": "Сервисы",
"count": "{n} в работе",
"empty": "— нет запущенных контейнеров —"
},
"tabs": {
"blueprint": "Чертёж",
"revisions": "Ревизии",
"logs": "Логи"
},
"yaml": {
"currentRevision": "Текущая ревизия",
"edit": "Править и развернуть",
"cancel": "Отмена",
"forging": "Куём…",
"deployNew": "Развернуть новую ревизию"
},
"revisions": {
"current": "ТЕКУЩАЯ",
"by": "автор",
"rollback": "← Откатиться к этой ревизии",
"rollbackTitle": "Откатить ревизию?",
"rollbackMessage": "Создать новую ревизию из rev {n} и развернуть стек заново.",
"rollbackConfirm": "Откатить"
},
"logs": {
"service": "Сервис:",
"allServices": "Все сервисы",
"fetching": "Загрузка…",
"fetch": "Получить логи",
"empty": "— логи не загружены. нажмите получить. —"
},
"delete": {
"title": "Удалить стек?",
"messageBase": "Будет выполнен 'docker compose down' и удалён \"{name}\".",
"messageVolumes": " Именованные тома также будут удалены.",
"confirm": "Удалить"
},
"errors": {
"load": "Не удалось загрузить стек",
"stop": "Остановка не удалась",
"start": "Запуск не удался",
"update": "Обновление не удалось",
"rollback": "Откат не удался",
"delete": "Удаление не удалось",
"fetchLogs": "Не удалось загрузить логи"
}
}
},
"timezone": {
"eyebrow": "The Forge // Хронограф",
"title": "Часовой пояс отображения",
"subtitle": "Все даты в Tinyforge — лог событий, деплои, бэкапы, сайты — показываются в этом поясе.",
"modeLabel": "Режим определения",
"modeAuto": "Автоопределение",
"modeManual": "Вручную",
"autoDetect": "Автоопределение из браузера",
"autoBadge": "Авто",
"activeZone": "Активный пояс",
"changeZone": "Сменить часовой пояс",
"clickToChange": "Нажмите, чтобы выбрать пояс →",
"pickerTitle": "Выбор часового пояса",
"pickerPlaceholder": "Поиск — город, регион, смещение UTC…",
"groupAuto": "Определение",
"groupPopular": "Популярные",
"groupAll": "Все пояса",
"previewFull": "Полная метка времени",
"previewDate": "Только дата",
"previewHint": "Метки времени в логе событий будут выглядеть именно так."
},
"settingsDns": {
"title": "Настройка DNS",
"description": "Выберите, использовать ли wildcard-запись или отдельные поддомены, управляемые DNS-провайдером."
},
"settingsIntegrations": {
"title": "Интеграции",
"outgoing": "Исходящие уведомления",
"outgoingDesc": "Куда Tinyforge отправляет события деплоев и алертов. Укажите webhook-URL (Apprise, Discord, Slack, свой обработчик).",
"incoming": "Входящие вебхуки",
"incomingMovedDesc": "Входящие вебхуки теперь привязаны к конкретному проекту или сайту. Откройте страницу проекта или статического сайта, чтобы увидеть и перегенерировать URL."
},
"webhookPanel": {
"copy": "Копировать",
"copied": "Webhook-URL скопирован в буфер обмена",
"copyFailed": "Не удалось скопировать",
"noUrl": "Webhook-URL не настроен",
"loadFailed": "Не удалось загрузить webhook-URL",
"regenerate": "Перегенерировать URL",
"regenerated": "Webhook-URL перегенерирован",
"regenerateFailed": "Не удалось перегенерировать webhook-URL",
"regenerateWarning": "Перегенерация инвалидирует текущий URL. Обновите CI-пайплайны и Git-вебхуки, использующие его.",
"confirmRegenerate": "Заменить текущий URL?",
"confirmYes": "Перегенерировать",
"confirmNo": "Отмена"
},
"settingsMaintenance": {
"title": "Обслуживание",
"thresholds": "Пороги",
"thresholdsDesc": "Настройте, когда Tinyforge помечает контейнеры как устаревшие и предупреждает о неиспользуемых образах.",
"dangerZone": "Опасная зона"
}
}