From 0b3e79331b782d7e06b3eaf2e799ac2c1f625dfd Mon Sep 17 00:00:00 2001 From: Alexander <48564353+Merrcurys@users.noreply.github.com> Date: Thu, 24 Sep 2026 07:49:11 +0300 Subject: [PATCH] feat(i18n): add Russian locale --- .github/scripts/i18n-autofill.mjs | 3 +- ...ssistant.writeConfirmationProposal.spec.ts | 2 +- .../src/i18n/__tests__/backendErrors.spec.ts | 2 + .../__tests__/docsNamespaceParity.spec.ts | 2 + .../i18n/__tests__/featureMessages.spec.ts | 5 +- apps/desktop/src/i18n/index.ts | 6 +- apps/desktop/src/i18n/locales/docs/ru.ts | 69 + .../src/i18n/locales/meilisearchManagement.ts | 118 + apps/desktop/src/i18n/locales/ru.ts | 11640 ++++++++++++++++ apps/desktop/src/lib/app/localeOptions.ts | 1 + .../app-tests/sidebarMutationRuntime.test.ts | 2 +- src-tauri/src/lib.rs | 10 + 12 files changed, 11853 insertions(+), 7 deletions(-) create mode 100644 apps/desktop/src/i18n/locales/docs/ru.ts create mode 100644 apps/desktop/src/i18n/locales/ru.ts diff --git a/.github/scripts/i18n-autofill.mjs b/.github/scripts/i18n-autofill.mjs index 9bb67d313c..e8bb51bd23 100644 --- a/.github/scripts/i18n-autofill.mjs +++ b/.github/scripts/i18n-autofill.mjs @@ -6,7 +6,7 @@ import { dirname, join, resolve } from "node:path"; const LOCALES_DIR = "apps/desktop/src/i18n/locales"; const SOURCE_LOCALE = "zh-CN"; -const TARGET_LOCALES = ["en", "es", "it", "ja", "ko", "pt-BR", "zh-TW"]; +const TARGET_LOCALES = ["en", "es", "it", "ja", "ko", "pt-BR", "ru", "zh-TW"]; // `git show :` needs forward slashes even on Windows, where // `path.join()` yields backslashes. Allow an override (CI keeps the default). const refPath = (path) => path.replaceAll("\\", "/"); @@ -17,6 +17,7 @@ const TARGET_LABELS = { ja: "Japanese", ko: "Korean", "pt-BR": "Brazilian Portuguese", + ru: "Russian", "zh-TW": "Traditional Chinese used in Taiwan", }; diff --git a/apps/desktop/src/components/editor/__tests__/AiAssistant.writeConfirmationProposal.spec.ts b/apps/desktop/src/components/editor/__tests__/AiAssistant.writeConfirmationProposal.spec.ts index 1d5255a4a3..47ef76ee4c 100644 --- a/apps/desktop/src/components/editor/__tests__/AiAssistant.writeConfirmationProposal.spec.ts +++ b/apps/desktop/src/components/editor/__tests__/AiAssistant.writeConfirmationProposal.spec.ts @@ -2,7 +2,7 @@ import { readFileSync } from "node:fs"; import { describe, expect, it } from "vitest"; const source = readFileSync(new URL("../AiAssistant.vue", import.meta.url), "utf8"); -const localePaths = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"]; +const localePaths = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]; describe("AI assistant write confirmation replacement", () => { it("renders a localized confirmation from the backend's semantic event", () => { diff --git a/apps/desktop/src/i18n/__tests__/backendErrors.spec.ts b/apps/desktop/src/i18n/__tests__/backendErrors.spec.ts index 732c1f11d4..c8850529a0 100644 --- a/apps/desktop/src/i18n/__tests__/backendErrors.spec.ts +++ b/apps/desktop/src/i18n/__tests__/backendErrors.spec.ts @@ -10,6 +10,7 @@ import it from "@/i18n/locales/it"; import ja from "@/i18n/locales/ja"; import ko from "@/i18n/locales/ko"; import ptBR from "@/i18n/locales/pt-BR"; +import ru from "@/i18n/locales/ru"; import tr from "@/i18n/locales/tr"; import zhCN from "@/i18n/locales/zh-CN"; import zhTW from "@/i18n/locales/zh-TW"; @@ -23,6 +24,7 @@ const LOCALES = { ja, ko, "pt-BR": ptBR, + ru, tr, "zh-CN": zhCN, "zh-TW": zhTW, diff --git a/apps/desktop/src/i18n/__tests__/docsNamespaceParity.spec.ts b/apps/desktop/src/i18n/__tests__/docsNamespaceParity.spec.ts index 0c582e5455..2c0f6c0512 100644 --- a/apps/desktop/src/i18n/__tests__/docsNamespaceParity.spec.ts +++ b/apps/desktop/src/i18n/__tests__/docsNamespaceParity.spec.ts @@ -6,6 +6,7 @@ import it_ from "../locales/docs/it"; import ja from "../locales/docs/ja"; import ko from "../locales/docs/ko"; import ptBR from "../locales/docs/pt-BR"; +import ru from "../locales/docs/ru"; import tr from "../locales/docs/tr"; import zhCN from "../locales/docs/zh-CN"; import zhTW from "../locales/docs/zh-TW"; @@ -24,6 +25,7 @@ const locales: Array<[string, Record]> = [ ["ja", ja], ["ko", ko], ["pt-BR", ptBR], + ["ru", ru], ["tr", tr], ["zh-CN", zhCN], ["zh-TW", zhTW], diff --git a/apps/desktop/src/i18n/__tests__/featureMessages.spec.ts b/apps/desktop/src/i18n/__tests__/featureMessages.spec.ts index a7122b3fbf..8dd9e7ac49 100644 --- a/apps/desktop/src/i18n/__tests__/featureMessages.spec.ts +++ b/apps/desktop/src/i18n/__tests__/featureMessages.spec.ts @@ -7,6 +7,7 @@ import itLocale from "../locales/it"; import ja from "../locales/ja"; import ko from "../locales/ko"; import ptBR from "../locales/pt-BR"; +import ru from "../locales/ru"; import tr from "../locales/tr"; import zhCN from "../locales/zh-CN"; import zhTW from "../locales/zh-TW"; @@ -19,9 +20,9 @@ import zhTW from "../locales/zh-TW"; vi.mock("../locales/fallback", () => ({ withEnglishFallback: (messages: Record) => messages })); type Messages = Record; -type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "tr" | "zh-CN" | "zh-TW"; +type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW"; -const declared: Record = { az, en, es, it: itLocale, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW }; +const declared: Record = { az, en, es, it: itLocale, ja, ko, "pt-BR": ptBR, ru, tr, "zh-CN": zhCN, "zh-TW": zhTW }; const ALL_LOCALES = Object.keys(declared) as Locale[]; const EXCEPT_AZ_TR = ALL_LOCALES.filter((locale) => locale !== "az" && locale !== "tr"); diff --git a/apps/desktop/src/i18n/index.ts b/apps/desktop/src/i18n/index.ts index 177f7edf85..f59ebea8de 100644 --- a/apps/desktop/src/i18n/index.ts +++ b/apps/desktop/src/i18n/index.ts @@ -3,14 +3,14 @@ import en from "./locales/en"; import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/backend/safeStorage"; import { isTauriRuntime } from "@/lib/backend/tauriRuntime"; -export type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "tr" | "zh-CN" | "zh-TW"; +export type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW"; type LocaleMessages = Record; type I18nGlobal = { locale: { value: Locale }; setLocaleMessage: (locale: Locale, messages: LocaleMessages) => void; }; -const supportedLocales: Locale[] = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"]; +const supportedLocales: Locale[] = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]; const defaultLocale: Locale = "en"; const loadedLocales = new Set([defaultLocale]); const localeLoaders: Record, () => Promise<{ default: LocaleMessages }>> = { @@ -20,6 +20,7 @@ const localeLoaders: Record, () => Promise<{ default: Loca ja: () => import("./locales/ja"), ko: () => import("./locales/ko"), "pt-BR": () => import("./locales/pt-BR"), + ru: () => import("./locales/ru"), tr: () => import("./locales/tr"), "zh-CN": () => import("./locales/zh-CN"), "zh-TW": () => import("./locales/zh-TW"), @@ -48,6 +49,7 @@ export function localeFromLanguageTag(value: string | null | undefined): Locale if (normalized === "ja" || normalized.startsWith("ja-")) return "ja"; if (normalized === "ko" || normalized.startsWith("ko-")) return "ko"; if (normalized === "pt" || normalized.startsWith("pt-")) return "pt-BR"; + if (normalized === "ru" || normalized.startsWith("ru-")) return "ru"; if (normalized === "tr" || normalized.startsWith("tr-")) return "tr"; return null; } diff --git a/apps/desktop/src/i18n/locales/docs/ru.ts b/apps/desktop/src/i18n/locales/docs/ru.ts new file mode 100644 index 0000000000..d13d215c24 --- /dev/null +++ b/apps/desktop/src/i18n/locales/docs/ru.ts @@ -0,0 +1,69 @@ +export default { + title: "Документация", + groupBySchema: "Схемы", + groupByTableGroup: "Группы таблиц", + noGroup: "(без группы)", + noSchema: "(без схемы)", + search: "Поиск таблиц, столбцов, групп…", + columns: "Столбцы", + indexes: "Индексы", + references: "Ссылки", + referencedBy: "Ссылаются на", + localNote: "ЛОКАЛЬНО", + shadowedComment: "Комментарий базы данных: {comment}", + addNote: "Добавить заметку", + editNote: "Редактировать заметку", + newGroup: "Новая группа…", + groupName: "Название группы", + groupColour: "Цвет", + deleteGroup: "Удалить группу", + enumValues: "Значения", + usedBy: "Используется в", + openDiagram: "Открыть схему", + saving: "Сохранение…", + saved: "Сохранено", + saveFailed: "Не удалось сохранить заметки: {error}", + overview: "Обзор", + groupBy: "Группировать по", + searchLabel: "Поиск", + groups: "Группы", + relationships: "Связи", + columnHeader: "Столбец", + typeHeader: "Тип", + settingsHeader: "Настройки", + noteHeader: "Заметка", + nameHeader: "Имя", + definitionHeader: "Определение", + noOutgoingRelationships: "Эта таблица не ссылается на другие таблицы.", + noIncomingRelationships: "Ни одна таблица не ссылается на эту.", + diagram: "Диаграмма", + language: "Язык", + theme: "Тема", + themeLight: "Светлая", + themeDark: "Тёмная", + exportHtml: "Экспорт в HTML…", + exporting: "Экспорт…", + exportFailed: "Не удалось выполнить экспорт: {error}", + warnings: { + tableSkipped: { + title: "Не удалось задокументировать таблицу", + detail: "{table} пропущена: {reason}. Её нет в этой документации.", + }, + noForeignKeyMetadata: { + title: "Связи недоступны", + detail: "{engine} не сообщает метаданные внешних ключей, поэтому связи не удалось построить. Для этого движка диаграмма полная.", + }, + commentsUnsupported: { + title: "Комментарии базы данных недоступны", + detail: "{engine} не поддерживает комментарии к таблицам и столбцам, поэтому все описания здесь взяты из собственных заметок проекта.", + }, + orphanedNotes: { + title: "Часть заметок больше ни с чем не связана", + detail: "Заметок, ссылающихся на несуществующую таблицу или столбец: {count}. Ничего не удалено — измените привязку или удалите их в файле заметок.", + }, + dbmlOmitted: { + title: "Невозможно представить в DBML", + detail: "{item} в {table} задокументирован здесь, но пропущен в экспортированном DBML: {reason}.", + }, + }, +}; diff --git a/apps/desktop/src/i18n/locales/meilisearchManagement.ts b/apps/desktop/src/i18n/locales/meilisearchManagement.ts index cb4ad38d66..326756d01b 100644 --- a/apps/desktop/src/i18n/locales/meilisearchManagement.ts +++ b/apps/desktop/src/i18n/locales/meilisearchManagement.ts @@ -457,6 +457,123 @@ export const meilisearchManagementMessages = { deleteTaskHistory: "Geçmişi sil", readOnlyDisabled: "Salt okunur bağlantılarda işlemler devre dışıdır.", }, + ru: { + systemManagement: "Управление системой", + overview: "Обзор", + overviewDescription: "Состояние, ёмкость, индексы, ключи и активность задач в реальном времени.", + apiKeys: "API-ключи", + keysDescription: "Создание и управление ограниченными по области действия API-ключами Meilisearch.", + tasks: "Задачи", + tasksDescription: "Просмотр асинхронных операций, отмена активных задач и очистка завершённой истории.", + health: "Состояние", + version: "Версия", + indexCount: "Индексы", + totalDocuments: "Всего документов", + indexingCount: "Индексация", + keyCount: "Ключи", + storage: "Хранилище", + usedDatabaseSize: "Занято базой данных", + lastUpdate: "Последнее обновление", + taskStatusDistribution: "Распределение статусов задач", + topIndexes: "Индексы с наибольшим числом документов", + status: "Статус", + idle: "Простой", + sectionStatus: { available: "Доступно", forbidden: "Доступ запрещён", unsupported: "Не поддерживается этим сервером", error: "Недоступно" }, + refresh: "Обновить", + rowActions: "Действия", + previous: "Назад", + next: "Вперёд", + name: "Название", + key: "Ключ", + description: "Описание", + actions: "Действия", + indexes: "Индексы", + expiresAt: "Срок действия", + never: "Никогда", + createKey: "Создать ключ", + editKey: "Изменить ключ", + deleteKey: "Удалить ключ", + keyDetails: "Сведения о ключе", + keyCreated: "API-ключ создан", + keyUpdated: "API-ключ обновлён", + keyDeleted: "API-ключ удалён", + noKeys: "API-ключи не найдены", + deleteKeyConfirm: "Удалить API-ключ {uid}? Это действие нельзя отменить.", + deleteKeyTypePrompt: "Введите полный UID ключа, чтобы подтвердить удаление.", + deleteKeyTypePlaceholder: "Введите UID ключа", + immutableKeyFields: "Действия, индексы, срок действия, UID и секрет неизменяемы. Чтобы изменить их, создайте ключ заново.", + secretShownOnce: "Скопируйте секрет сейчас. DBX никогда не сохраняет значения API-ключей.", + actionsIndexesRequired: "Требуется указать хотя бы одно действие и один индекс.", + uidPlaceholder: "Оставьте пустым, чтобы сгенерировать случайный UID", + uidHelp: "Необязательно. Если оставить пустым, Meilisearch сгенерирует случайный UID.", + namePlaceholder: "Укажите название ключа", + nameHelp: "Необязательное название для идентификации этого ключа.", + descriptionPlaceholder: "Добавьте необязательное описание", + descriptionHelp: "Необязательная заметка о том, где и для чего используется ключ.", + indexesPlaceholder: "Выберите разрешённые индексы", + indexesHelp: "Выберите один или несколько доступных индексов. Значение * предоставляет доступ ко всем индексам.", + actionsPlaceholder: "Выберите разрешённые действия", + actionsHelp: "Выберите операции API, которые этот ключ разрешено выполнять.", + expiresAtPlaceholder: "Выберите или введите дату и время", + expiresAtHelp: "Необязательно. Оставьте пустым, чтобы срок действия не истекал, либо введите корректные дату и время.", + openDateTimePicker: "Открыть выбор даты и времени", + invalidExpiresAt: "Введите корректные дату и время окончания срока действия.", + copyKeyValue: "Копировать API-ключ", + paginationSummary: "{start}–{end} из {total}", + readOnlyDisabled: "Это подключение доступно только для чтения; управляющие операции отключены.", + filters: "Фильтры", + applyFilters: "Применить фильтры", + resetFilters: "Сбросить фильтры", + uidFilter: "Фильтр по UID", + searchUid: "Поиск по UID", + allIndexes: "Все индексы", + allStatuses: "Все статусы", + indexListUnavailable: "Не удалось загрузить список доступных индексов", + reverseOrder: "Обратный порядок", + columnSettings: "Настроить столбцы", + index: "Индекс", + type: "Тип", + details: "Подробности", + receivedDocuments: "Получено документов", + indexedDocuments: "Проиндексировано документов", + enqueuedAt: "В очереди", + startedAt: "Начато", + finishedAt: "Завершено", + duration: "Длительность", + afterEnqueuedAt: "В очереди после", + beforeEnqueuedAt: "В очереди до", + afterStartedAt: "Начато после", + beforeStartedAt: "Начато до", + afterFinishedAt: "Завершено после", + beforeFinishedAt: "Завершено до", + indexTasks: "Задачи · {index}", + noTasks: "Задачи не найдены", + taskCount: "Подходящих задач: {count}", + taskDetails: "Сведения о задаче", + cancelTask: "Отменить задачу", + cancelTasks: "Отменить задачи", + deleteTaskHistory: "Удалить историю задач", + cancelFilteredTasks: "Отменить отобранные активные задачи", + deleteFilteredHistory: "Удалить отобранную завершённую историю", + explicitFilterRequired: "Перед массовой операцией задайте хотя бы один явный фильтр.", + noAllowedTaskStatuses: "В применённом фильтре нет статусов задач, разрешённых для этой операции.", + countingMatchingTasks: "Подсчёт подходящих задач...", + cancelTasksConfirm: "Отменить активные задачи, соответствующие этому фильтру (сейчас найдено: {count})?", + deleteTasksConfirm: "Удалить завершённую историю задач, соответствующую этому фильтру (сейчас найдено: {count})?", + waitingForTask: "Ожидание задачи управления #{uid}", + taskOperationCompleted: "Операция с задачей завершена", + taskOperationFinished: "Операция с задачей завершена со статусом {status}", + taskPollingTimeout: "Задача #{uid} не завершилась за 60 секунд. Обновите страницу вручную, чтобы проверить её состояние.", + taskOutsideIndex: "Эта задача не относится к текущему индексу.", + createIndex: "Создать индекс", + createIndexUid: "UID индекса", + createIndexPrimaryKey: "Первичный ключ", + indexCreated: "Индекс создан", + createIndexUidRequired: "Укажите UID индекса.", + createIndexUidPlaceholder: "Введите UID индекса", + createIndexPrimaryKeyPlaceholder: "Необязательный первичный ключ", + createIndexPrimaryKeyHelp: "Оставьте пустым, чтобы задать первичный ключ при добавлении первого документа.", + }, } as const; export const meilisearchManagementAz = meilisearchManagementMessages.az; @@ -469,3 +586,4 @@ export const meilisearchManagementEs = meilisearchManagementMessages.es; export const meilisearchManagementIt = meilisearchManagementMessages.it; export const meilisearchManagementPtBR = meilisearchManagementMessages["pt-BR"]; export const meilisearchManagementTr = meilisearchManagementMessages.tr; +export const meilisearchManagementRu = meilisearchManagementMessages.ru; diff --git a/apps/desktop/src/i18n/locales/ru.ts b/apps/desktop/src/i18n/locales/ru.ts new file mode 100644 index 0000000000..e33f3a3884 --- /dev/null +++ b/apps/desktop/src/i18n/locales/ru.ts @@ -0,0 +1,11640 @@ +import { withEnglishFallback } from "./fallback"; +import docs from "./docs/ru"; +import { meilisearchManagementRu } from "./meilisearchManagement"; + +// Russian locale. Entries omitted here fall back to English at runtime. +export default withEnglishFallback({ + docs, + cellTransform: { + title: "Предпросмотр преобразования", + description: "Преобразуйте текущее значение для просмотра или копирования. Исходное значение и черновик редактора не изменяются.", + format: "Преобразование", + unit: "Единица времени", + timezone: "Часовой пояс", + pattern: "Формат даты", + fromBase: "Исходная система счисления", + toBase: "Целевая система счисления", + convert: "Преобразовать", + result: "Результат", + copy: "Копировать результат", + radixHint: "Только целые числа. Вводите цифры без префикса 0x, 0o или 0b; допускается необязательный знак.", + urlHint: "Кодирование компонента URL (UTF-8). При декодировании + сохраняется как знак плюс.", + kinds: { + timestamp: "Timestamp → дата/время", + json: "Форматировать JSON", + jsonCompact: "Сжать JSON", + xml: "Форматировать XML", + base64Encode: "Текст → Base64 (UTF-8)", + base64Decode: "Base64 → текст (UTF-8)", + urlEncode: "Кодировать компонент URL", + urlDecode: "Декодировать компонент URL", + radix: "Преобразование систем счисления", + }, + units: { + auto: "Авто (10/13 цифр)", + seconds: "Секунды", + milliseconds: "Миллисекунды", + }, + errors: { + nullSource: "NULL не содержит текста для преобразования.", + incomplete: "Полное значение не загружено. Дождитесь загрузки или откройте сведения о ячейке заново.", + unsafeNumber: "Это числовое значение невозможно безопасно представить. Получите его как текст, чтобы сохранить точность.", + tooLarge: "Превышен лимит преобразования: {maxInput} входных символов, {maxOutput} выходных символов или {maxRadixDigits} символов целого числа.", + invalid: "Не удалось преобразовать. Проверьте формат ввода и параметры преобразования.", + invalidTimestamp: "Введите целочисленный timestamp в пределах поддерживаемого диапазона дат.", + ambiguousUnit: "Не удалось определить единицу времени. Укажите секунды или миллисекунды явно.", + invalidInteger: "Введите целое число с цифрами, допустимыми для выбранной исходной системы счисления, без префикса основания.", + invalidBase64: "Введите стандартный Base64 с дополнением, содержащий корректный текст UTF-8.", + }, + }, + redisGrouping: { + preparingLegacy: "Подготовка предыдущего представления; пользовательские группы остаются доступными…", + fuzzyTreeUnavailable: "Этот нечёткий поиск превышает лимит ресурсов существующего дерева. Выберите список для просмотра загруженных совпадений или уточните поиск, чтобы использовать дерево.", + useList: "Использовать список", + settings: "Правила группировки", + toggle: "Пользовательские группы", + list: "Список", + tree: "Дерево", + help: "Правила действуют на всё соединение, побеждает первое совпадение. Одна чувствительная к регистру маска Redis на строку (*, ?, [a-z], экранирование обратным слешем). Включения объединяются по OR; исключения имеют приоритет. Пустые включения соответствуют всему. Счётчики охватывают только загруженные ключи. Группы не являются границами удаления.", + enabled: "Включить правило", + name: "Название группы", + up: "Вверх", + down: "Вниз", + remove: "Удалить", + includes: "Шаблоны включения", + excludes: "Шаблоны исключения", + add: "Добавить правило", + example: "Добавить пример Redisson", + invalid: "Введите уникальные ID правил, название и хотя бы один шаблон для каждого правила (не более 64 правил, 64 шаблонов на список, 1024 байт на шаблон).", + cancel: "Отмена", + save: "Сохранить", + unmatched: "Без совпадений", + preparing: "Обновление загруженных групп…", + loadedOnly: "Группы показывают только загруженные совпадения; разворачивание не сканирует Redis.", + count: "({count} загружено)", + emptyKey: "(пустой ключ)", + selectLoaded: "Выбрать загруженные совпадения", + }, + customType: { + kinds: { + base: "Базовый", + composite: "Составной", + domain: "Домен", + enum: "Перечисление", + range: "Диапазон", + multirange: "Мультидиапазон", + }, + tabs: { + members: "Элементы", + properties: "Свойства", + ddl: "DDL", + }, + members: { + empty: "У этого типа нет элементов.", + name: "Имя", + type: "Тип", + nullable: "Допускает NULL", + default: "По умолчанию", + comment: "Комментарий", + }, + properties: { + empty: "Атрибуты недоступны.", + baseType: "Базовый тип", + notNull: "Не NULL", + default: "По умолчанию", + collation: "Сортировка", + domainConstraint: "Ограничение", + rangeSubtype: "Подтип диапазона", + rangeMultirange: "Тип мультидиапазона", + }, + ddl: { + empty: "DDL для этого типа недоступен.", + incomplete: "Созданный DDL неполон и не был скопирован. Откройте сведения о типе, чтобы просмотреть предупреждения.", + }, + }, + app: { + name: "DBX", + }, + pluginPlatform: { + openResultView: "Открыть с помощью {label}", + centerTitle: "Центр плагинов", + centerDescription: "Открывайте дополнительные возможности DBX в едином магазине, а затем управляйте установленными плагинами и репозиториями отдельно.", + marketplace: "Магазин", + installed: "Установленные", + settings: "Настройки", + searchMarketplace: "Поиск плагинов, издателей или тегов", + allRepositories: "Все репозитории", + marketplaceGuideTitle: "Плагины поддерживаются сообществом разработчиков", + marketplaceGuideDescription: "По вопросам о плагинах или для запроса функций создайте issue в собственном репозитории плагина (ссылка на исходный репозиторий есть на карточке плагина); основной репозиторий DBX принимает только вопросы о самом приложении.", + loadingMarketplace: "Загрузка магазина плагинов", + noMarketplacePlugins: "Нет плагинов для отображения", + noMarketplacePluginsDescription: "Настройте репозиторий в разделе «Настройки» или измените текущий поиск и фильтры.", + verified: "Проверено", + noDescription: "Описание не указано.", + permissionsCount: "{count} разрешений", + unsupportedTarget: "Недоступно для {target}", + installedVersion: "Установлено v{version}", + installedVersionUpdatable: "Установлено v{installed} · Обновить до v{latest}", + licenseUnknown: "Лицензия не указана", + sourceRepository: "Исходный репозиторий", + pluginHomepage: "Домашняя страница", + marketplaceStatus: { + install: "Установить", + installed: "Установлено", + update: "Обновить", + unsupported: "Не поддерживается", + }, + updateSuccess: "{name} обновлён до {version}", + installedUpdatesAvailableTitle: "Доступны обновления плагинов ({count})", + installedUpdatesAvailableDescription: "Обновления проверяют подписи и контрольные суммы, а предыдущая версия сохраняется для отката в один клик.", + updateAll: "Обновить все", + updatingProgress: "Обновление ({current}/{total})", + updateToVersion: "Обновить до v{version}", + checkingForUpdates: "Проверка обновлений плагинов…", + allPluginsUpToDate: "Все установленные плагины обновлены.", + updateCheckUnavailable: "Не удалось проверить обновления плагинов", + updateCheckUnavailableDescription: "Не удалось загрузить каталог плагинов, поэтому статус обновлений может быть устаревшим.", + updateCheckPartialFailure: "Некоторые репозитории плагинов не удалось проверить; статус обновлений может быть неполным.", + noRepositoriesEnabled: "Репозитории плагинов не включены", + notInRepositories: "Нет в репозиториях", + notInRepositoriesHint: "Установлено вне настроенных репозиториев (локальный .dbxp или репозиторий отключён); статус обновления неизвестен.", + updateSourceChangeTitle: "Подтвердить смену источника обновления плагина?", + updateSourceChangeBody: "Обновление-кандидат получено из другого репозитория, издателя или с другим ключом подписи, чем у записанной установки. Обновление заменит плагин и запишет новый источник.", + updateSourceChangeConfirm: "Всё равно обновить (записать новый источник)", + provenanceCurrentInstall: "Текущая установка", + provenanceCandidate: "Обновление-кандидат", + provenanceRepository: "Репозиторий", + provenancePublisher: "Издатель", + provenanceSigningKey: "Ключ подписи", + batchSourceChangeSkipped: "У этих плагинов изменился источник обновления, и требуется подтверждение для каждого: {names}", + updateSourceChangeRequired: "Источник обновления изменился. Сначала подтвердите изменение в Центре плагинов.", + updateDowngradeRejected: "Откат к более старой версии плагина не допускается.", + updateBlockedByConnections: "Закройте эти соединения перед обновлением или откатом плагина: {labels}", + updateBlockedByOperations: "Дождитесь завершения активных операций этого плагина перед обновлением или откатом.", + updateInProgress: "Этот плагин обновляется. Повторите попытку после завершения обновления.", + pinPlugin: "Закрепить плагин", + unpinPlugin: "Открепить плагин", + noInstalledPlugins: "Нет установленных плагинов", + browseMarketplace: "Открыть магазин", + localInstallTitle: "Установить пакет плагина", + localInstallDescription: "Установите подписанный .dbxp, полученный вне магазина, из локального файла или URL. DBX автоматически проверяет целостность пакета и подписи.", + repositoriesTitle: "Репозитории плагинов", + repositoriesDescription: "Официальный источник подписан и управляется DBX. Пользовательские репозитории используют один ключ доверия уровня репозитория, настроенный ниже.", + repositoryFieldsRequired: "Требуются ID репозитория, название и URL каталога", + repositorySaved: "Репозиторий плагинов '{name}' сохранён", + removeRepositoryConfirm: "Удалить репозиторий плагинов '{name}'? Установленные плагины останутся установленными.", + repositoryRemoved: "Репозиторий плагинов '{name}' удалён", + repositoryKind: { + official: "Официальный", + custom: "Пользовательский", + enterprise: "Корпоративный", + }, + repositoryNotConfigured: "URL каталога не настроен в этой сборке", + enabled: "Включено", + disabled: "Отключено", + enable: "Включить", + disable: "Отключить", + repositoryIdPlaceholder: "ID репозитория", + repositoryNamePlaceholder: "Название репозитория", + repositoryCatalogUrlPlaceholder: "https://plugins.example.com/catalog/index.json", + addRepository: "Добавить репозиторий", + signedPackagesVerifiedAutomatically: "Подписи проверяются автоматически", + developerOptionsTitle: "Параметры сторонних разработчиков", + developerOptionsDescription: "Используйте только для пользовательских репозиториев или локальной разработки плагинов.", + pluginDevelopmentDocsTitle: "Документация по разработке плагинов", + pluginDevelopmentDocsDescription: "Узнайте, как разрабатывать, упаковывать и публиковать плагины DBX в магазине.", + pluginDevelopmentDocsOpen: "Просмотреть документацию", + developerOptionsWarning: "Неподписанные плагины могут выполнять нативный код с вашими правами пользователя. Включайте это только для пакетов, которые вы собрали сами и которым доверяете.", + connectionManagedInDialog: "Создавайте и редактируйте соединения в едином диалоге создания соединения. Эта страница управляет только плагинами и показывает их возможности.", + allowUnsignedDevelopmentPackage: "Разрешить неподписанные пакеты для разработки", + allowUnsignedDevelopmentPackageDescription: "Применяется только к установке .dbxp вручную и никогда не ослабляет проверку официального магазина.", + installPackage: "Установить .dbxp", + installFromUrl: "Установить из URL", + installUrlPlaceholder: "https://example.com/plugin.dbxp", + deepLinkInstallConfirm: "Установить этот плагин по ссылке ниже?", + deepLinkInvalid: "Недопустимая ссылка установки плагина: {message}", + invalidPackageUrl: "Введите корректный URL пакета плагина http:// или https://", + downloadProgress: "Загрузка {downloaded} из {total}", + downloadProgressUnknown: "Загрузка {downloaded}", + dropToInstall: "Перетащите, чтобы установить пакет плагина", + dropInstallHint: "Также можно перетащить файл .dbxp на эту страницу", + packageFileType: "Пакет плагина DBX", + repositoryTrustTitle: "Доверие к пользовательскому репозиторию", + repositoryTrustDescription: "Оператор пользовательского репозитория подписывает все одобренные пакеты ключом репозитория. Получите этот открытый ключ по отдельному доверенному каналу.", + repositoryKeyAdded: "Ключ подписи репозитория '{keyId}' добавлен", + removeRepositoryKeyConfirm: "Удалить ключ подписи репозитория '{keyId}'? Установленные плагины останутся установленными.", + repositoryKeyRemoved: "Ключ подписи репозитория '{keyId}' удалён", + repositoryKeyIdPlaceholder: "ID ключа репозитория", + repositoryPublicKeyPlaceholder: "Открытый ключ репозитория Ed25519 в Base64 (32 байта)", + trustRepository: "Доверять репозиторию", + noInstalledPluginsDescription: "Установите подписанный .dbxp или явно включите неподписанные пакеты для локальной разработки.", + compatible: "Совместимо", + blocked: "Заблокировано", + rollback: "Откатить", + uninstall: "Удалить", + rollbackConfirm: "Откатить этот плагин к предыдущей установленной версии?", + rollbackSuccess: "Выполнен откат к {version}", + uninstallConfirm: "Удалить {name}?", + uninstallSuccess: "{name} удалён", + installSuccess: "{name} {version} установлен", + batchManage: "Пакетно", + batchDone: "Готово", + batchSelected: "Выбрано: {count}", + batchSelectAllUpdatable: "Выбрать все обновляемые", + batchInstallUpdate: "Установить / обновить", + batchUninstall: "Удалить выбранные", + batchUninstallConfirm: "Удалить {count} плагин(ов)?\n{names}", + batchSummary: "Готово: успешно — {success}", + batchSummaryWithFailures: "Готово: успешно — {success}, с ошибкой — {failed} ({names})", + batchDuplicateSources: "Выбрано несколько источников для: {names}. Оставьте только один источник для каждого плагина, прежде чем продолжить.", + batchRefreshFailed: "Пакетная операция завершена, но не удалось обновить список плагинов: {error}", + selectConnectionProvider: "Сначала выберите поставщика соединений", + connectionProvider: "Поставщик соединений", + newConnection: "Создать", + workbenches: "Рабочие среды", + filesystemProviders: "Поставщики файловых систем", + open: "Открыть", + browse: "Обзор", + parentDirectory: "Родительский каталог", + filesystemUri: "URI файловой системы", + refresh: "Обновить", + reloadRequired: "Страницу плагина необходимо перезагрузить.", + reloadHintPrefix: "Нажмите ", + reloadHintSuffix: " или нажмите кнопку обновления ниже, чтобы перезагрузить.", + loadingFiles: "Загрузка файлов", + emptyDirectory: "Этот каталог пуст.", + loadMore: "Загрузить ещё", + fileManagerHint: "Дважды щёлкните каталог, чтобы открыть его, или файл, чтобы просмотреть до 256 КБ.", + loadingPreview: "Загрузка предпросмотра", + previewTruncated: "Предпросмотр обрезан на 256 КБ", + previewSelectedFileHint: "Дважды щёлкните выбранный файл, чтобы загрузить его предпросмотр.", + entryCannotPreview: "Этот элемент нельзя просмотреть.", + providerNoReadCapability: "Поставщик не заявляет возможность чтения.", + filesystemUnavailable: "Файловая система плагина '{pluginId}/{providerId}' недоступна", + loadingFilesystem: "Загрузка файловой системы плагина", + filesystemUnavailableFallback: "Файловая система плагина недоступна", + workbenchUnavailable: "Рабочая среда плагина '{pluginId}/{contributionId}' недоступна", + loadingWorkbench: "Загрузка рабочей среды плагина", + workbenchUnavailableFallback: "Рабочая среда плагина недоступна", + pluginIncompatible: "Плагин несовместим", + loadingTitle: "Загрузка {title}", + }, + auth: { + rateLimited: "Повторите попытку через {seconds} с", + setupTitle: "Настройте пароль доступа", + setupDescription: "Задайте пароль для защиты вашего экземпляра", + loginDescription: "Инструмент управления базами данных", + newPassword: "Введите новый пароль", + confirmPassword: "Подтвердите пароль", + enterPassword: "Введите пароль доступа", + passwordMismatch: "Пароли не совпадают", + setPassword: "Задать пароль", + login: "Войти", + processing: "Обработка...", + loginFailed: "Неверный пароль", + connectFailed: "Не удалось подключиться", + changePassword: "Сменить пароль", + oldPassword: "Текущий пароль", + oldPasswordWrong: "Текущий пароль неверен", + passwordChanged: "Пароль успешно изменён", + changePasswordFailed: "Не удалось сменить пароль", + changePasswordDescription: "Введите текущий пароль и выберите новый", + }, + toolbar: { + commitOutcomeUnknown: "Результат фиксации неизвестен, а сессия больше не существует. Проверьте данные перед повторным выполнением этого SQL.", + moreActions: "Дополнительные действия", + newConnection: "Новое подключение", + newQuery: "Новый запрос", + execute: "Выполнить", + executeShortcut: "Выполнить выделение/запрос ({shortcut})", + stopQuery: "Остановить запрос", + explainPlan: "План выполнения", + stopExplain: "Остановить план", + autotrace: "Автотрассировка (выполняет запрос)", + explainAnalyze: "EXPLAIN ANALYZE (выполняет запрос)", + actualPlan: "Фактический план выполнения (SET STATISTICS XML)", + formatSql: "Форматировать SQL", + formatSqlFailed: "Не удалось отформатировать SQL", + formatAutoDetectFailed: "Не удаётся распознать или отформатировать выделенный фрагмент", + compressSql: "Сжать SQL", + keywordCaseLower: "Ключевые слова SQL в нижнем регистре", + keywordCaseUpper: "Ключевые слова SQL в верхнем регистре", + sqlSemanticDiagnosticsToggleOn: "Семантическая диагностика SQL: вкл. (нажмите, чтобы отключить)", + sqlSemanticDiagnosticsToggleOff: "Семантическая диагностика SQL: выкл. (нажмите, чтобы включить)", + insertValueHintsToggleOn: "Подсказки столбцов INSERT: вкл. (нажмите, чтобы отключить)", + insertValueHintsToggleOff: "Подсказки столбцов INSERT: выкл. (нажмите, чтобы включить)", + autoCommit: "Автофиксация", + manualTransaction: "Ручная транзакция", + autoCommitAgent: "Автофиксация (зависит от бэкенда агента)", + manualTransactionAgent: "Ручная транзакция (зависит от бэкенда агента)", + commit: "Зафиксировать", + rollback: "Откатить", + txnAutoRolledBack: "Транзакция автоматически откатана после 5 минут бездействия", + autoCommitTxnRolledBack: "Явная транзакция, оставленная открытой этой вкладкой, была автоматически откатана; включите «Сохранять явные транзакции с автофиксацией», чтобы сохранять её между выполнениями", + autoCommitSessionTxnRolledBack: "Это соединение работает с отключённой автофиксацией (SET autocommit = 0), поэтому его неявная транзакция была откатана после выполнения; DBX сообщает об этом один раз на соединение", + previewSql: "Предпросмотр SQL", + previewQuery: "Предпросмотр запроса", + hidePreviewSql: "Скрыть предпросмотр SQL", + saveSql: "Сохранить в библиотеку SQL", + saveSqlFile: "Сохранить в исходный файл", + openSql: "Открыть файл SQL", + exPasteSqlInCondition: "ExPaste: вставить как условие IN", + theme: "Тема", + themeLight: "Светлая", + themeDark: "Тёмная", + themeSystem: "Как в системе", + sqlSaved: "SQL сохранён", + sqlOpenFailed: "Не удалось открыть файл: {message}", + sqlSaveFailed: "Не удалось сохранить файл: {message}", + driverManager: "Диспетчер драйверов", + pluginCenter: "Центр плагинов", + updatableDriverCount: "Количество обновляемых драйверов", + mcpUpdateAvailable: "Доступно обновление сервера MCP", + alwaysOnTop: "Поверх других окон", + alwaysOnTopOff: "Не оставлять поверх других окон", + blockDangerousRedisCommands: "Блокировать опасные команды", + multiDbExecute: "Выполнение на нескольких БД", + }, + multiDbExecute: { + manualTransaction: "Ручная транзакция", + manualWarning: "У каждой цели своя транзакция. Commit и rollback применяются к одной цели за раз; фиксации между базами данных не атомарны. DDL и явные команды транзакций могут фиксироваться независимо. Отмена ожидает завершения активного оператора перед откатом.", + pendingCommit: "Ожидает фиксации", + rolledBack: "Откатано", + commit: "Зафиксировать", + rollback: "Откатить", + manualUnsupported: "Эта цель не поддерживает ручные транзакции.", + manualCommitUnavailable: "Commit недоступен; откатите эту транзакцию.", + discardTitle: "Откатить ожидающие изменения?", + discardWarning: "Выполняющиеся операторы завершатся перед откатом. Уже зафиксированные цели нельзя отменить.", + rollbackAndClose: "Откатить и закрыть", + cleanupFailed: "Некоторые транзакции не удалось откатить.", + title: "Выполнение на нескольких базах данных", + progress: "Ход выполнения ({completed}/{total})", + sqlPreview: "Предпросмотр SQL", + databaseType: "Тип базы данных", + searchTargets: "Поиск соединений, баз данных, схем...", + selectedCount: "Выбрано: {count}", + selectedTargets: "Выбранные цели", + selectGroup: "Группа целей выполнения", + noGroupSelected: "Выберите группу целей", + manageGroups: "Управление группами", + manageGroupsDescription: "Группы целей — это переиспользуемые цели выполнения SQL, они не изменяют группы соединений.", + noGroups: "Нет групп целей", + loadGroup: "Загрузить группу", + available: "Доступно", + typeMismatch: "Несовпадение типов", + targets: "цели", + saveAsGroup: "Сохранить как группу", + saveChanges: "Сохранить изменения", + saveAsNewGroup: "Сохранить как новую группу", + renameGroup: "Переименовать группу", + deleteGroup: "Удалить группу", + deleteGroupConfirm: "Удалить группу целей «{name}»? Соединения и базы данных не пострадают.", + groupName: "Название группы", + groupNameRequired: "Введите название группы.", + groupNameExists: "Группа с таким названием уже существует.", + groupSaved: "Группа целей сохранена", + groupSaveFailed: "Не удалось сохранить группу целей: {message}", + groupLoadFailed: "Не удалось загрузить группу целей: {message}", + groupModified: "Выбор целей изменён", + unsavedChangesConfirm: "В текущем выборе целей есть несохранённые изменения. Сохранить их перед продолжением?", + cancelOperation: "Отменить операцию", + discardChanges: "Отменить изменения", + internalCatalog: "внутренний", + defaultDatabase: "база данных по умолчанию", + noDatabase: "область соединения", + clearTargets: "Очистить", + noTargets: "Нет доступных целей для выполнения.", + removeTarget: "Удалить цель", + validTarget: "Цель корректна", + needsRecheck: "Ожидание проверки цели", + needsRecheckCount: "{count} цель(ей) требуют проверки", + invalidTargetCount: "{count} некорректных цель(ей)", + invalidTarget: "Некорректная цель", + connectionOnlyTarget: "Цель уровня соединения", + targetMissingConnection: "Соединение больше не существует", + targetTypeMismatch: "Тип базы данных соединения больше не совпадает", + targetCatalogMissing: "Каталог больше не существует", + targetDatabaseMissing: "База данных больше не существует или недоступна", + targetSchemaMissing: "Схема больше не существует или недоступна", + targetPermissionDenied: "Отказано в доступе при проверке цели", + targetValidationFailed: "Проверка цели не удалась", + retryValidation: "Повторить проверку", + serialContinueOnError: "Последовательное выполнение; продолжать после ошибок", + parallelContinueOnError: "Параллельное выполнение; продолжать после ошибок", + serial: "Последовательно", + parallel: "Параллельно", + switchToParallel: "Переключить на параллельное", + switchToSerial: "Переключить на последовательное", + elapsed: "Затрачено: {duration}", + pending: "Ожидание", + awaitingConfirmation: "Ожидание подтверждения", + running: "Выполняется", + success: "Успешно", + failed: "Ошибка", + skipped: "Пропущено", + cancelled: "Отменено", + notExecuted: "Не выполнено", + execute: "Выполнить", + cancelBatch: "Отменить пакет", + dangerTitle: "Подтвердите выполнение на цели", + dangerConfirm: "Выполнить на этой цели", + resultTabPrefix: "Мульти-БД", + mergeResults: "Объединённый просмотр результатов", + mergeResultsBack: "Назад к ходу выполнения", + mergedSourceColumn: "Источник", + mergedSources: "{count} источников данных · {rows} строк", + mergedSourceRowCap: "До {count} строк на источник данных", + mergedWriteSummary: "{targets} целей · затронуто {rows} строк", + mergedSourceCapReached: "{count} источник(ов) данных достигли лимита на источник ({limit} строк); строк может быть больше", + mergedSummaryLabel: "SUM", + mergedSummaryCellHint: "Сумма {count} числовых значений", + backgroundBatchDone: "{count} источник(ов) данных завершены; объединённый просмотр готов", + statusColumn: "Статус", + affectedRowsColumn: "Затронуто строк", + durationColumn: "Затрачено", + errorColumn: "Ошибка", + rerunTarget: "Повторить здесь", + dangerTargets: "Источники данных ({count})", + dangerConfirmCodePrompt: "Введите этот код для подтверждения", + dangerConfirmCodeCopy: "Копировать код", + dangerConfirmCodeOnce: "Запрашивается один раз на пакет; вставьте его, если скопировали.", + dangerConfirmCodePlaceholder: "Проверочный код", + txnColumn: "Транзакция", + txnOpen: "Не зафиксирована", + txnCommitted: "Зафиксирована", + txnRolledBack: "Откатана", + txnOpenHint: "{count} цель(ей) ещё не зафиксированы", + commitAllTargets: "Зафиксировать все ({count})", + rollbackAllTargets: "Откатить все ({count})", + txnActionFailed: "Не удалось выполнить действие с транзакцией: {message}", + elapsedColumn: "Затрачено: {duration}", + executedAtColumn: "Выполнено в", + executedAtChip: "Выполнено в: {time}", + mergedRowLimit: "Показаны первые {count} строк; итоги охватывают все {rows} строк", + mergedTruncated: "Объединённый результат обрезан (лимит {count} строк)", + mergedEmpty: "Этот пакет не создал строк для объединения.", + mergedSheetName: "Объединённый результат", + exportCurrentPage: "Экспортировать текущую страницу", + exportAllRows: "Экспортировать все (Excel)", + exportedRows: "Экспортировано {rows} строк", + exportedRowsCapped: "Экспортировано {rows} строк; {count} источник(ов) данных достигли лимита в {limit} строк", + }, + externalSqlFile: { + modifiedTitle: "Файл изменён вне DBX", + modifiedDescription: "{path} был изменён другой программой. Выберите, какую версию сохранить.", + deletedTitle: "Файл больше не существует", + deletedDescription: "{path} был удалён или перемещён вне DBX. Содержимое редактора по-прежнему доступно.", + unsavedWarning: "В этом редакторе также есть несохранённые изменения. Загрузка внешней версии отменит их.", + deletedUnsavedWarning: "В этом редакторе есть несохранённые изменения. Закрытие вкладки отменит их.", + keepEditor: "Сохранить содержимое редактора", + loadLatest: "Загрузить последнюю", + cancelSave: "Отменить сохранение", + loadExternal: "Загрузить внешнюю версию", + overwriteSave: "Перезаписать файл", + keepEditing: "Продолжить редактирование", + saveAs: "Сохранить как...", + recreate: "Воссоздать файл", + closeTab: "Закрыть вкладку", + loadFailed: "Не удалось загрузить последнее содержимое файла: {message}", + checkFailed: "Не удалось проверить внешний файл SQL: {message}", + changedAgain: "Файл снова изменился во время сохранения. Повторите попытку.", + }, + updates: { + preparationWindowOperation: "Дождитесь завершения текущей операции с окном перед обновлением.", + preparationBusy: "Обновление уже готовится.", + preparationCancelled: "Подготовка обновления отменена.", + preparationTimeout: "Одно из окон не сохранилось за 5 секунд. Повторите попытку.", + preparationWindowsChanged: "Набор открытых окон изменился. Повторите обновление.", + preparationTasks: "Завершите активные задачи и транзакции перед обновлением.", + preparationDrafts: "Сохраните или отмените несохранённые изменения перед обновлением.", + preparationConfig: "Завершите редактирование текущей конфигурации перед обновлением.", + preparationNotReady: "Подготовка обновления не готова. Повторите попытку.", + downloadedReady: "Новая версия v{version} загружена. Перезапустите для обновления.", + restartAndUpdate: "Перезапустить и обновить", + preparing: "Подготовка обновления…", + retryDownload: "Повторить загрузку", + title: "Обновления", + centerTitle: "Центр обновлений", + centerAvailable: "Доступно: {count}", + check: "Проверить обновления", + checking: "Проверка обновлений…", + updateReadyTooltip: "Обновление готово — нажмите, чтобы установить", + restartRequiredTooltip: "Обновление установлено — перезапустите для завершения", + availableTitle: "Доступно обновление", + availableMessage: "Доступен DBX {latest}. Вы используете {current}.", + upToDate: "DBX обновлён ({version}).", + failed: "Не удалось проверить обновления: {error}", + rateLimited: "Проверка обновлений на GitHub временно ограничена по частоте. Вы по-прежнему можете открыть страницу релиза и проверить вручную.", + openRelease: "Открыть релиз", + ignoreVersion: "Игнорировать эту версию", + versionIgnored: "Версия {version} игнорируется. Мы напомним вам при выходе следующей версии.", + ignoreVersionFailed: "Не удалось сохранить игнорируемую версию: {error}", + downloadInBackground: "Загрузить в фоне", + cancelDownload: "Отменить загрузку", + downloadStarted: "Загрузка DBX {version} в фоне.", + activeTasksBlockUpdate: "Ещё выполняется задач: {count}. Дождитесь их завершения перед обновлением DBX.", + portableAutomaticUpdate: "DBX загрузит подписанный portable ZIP, заменит только DBX.exe после выхода и автоматически перезапустится. portable.dbx и данные будут сохранены.", + windows7ManualUpdate: "Для Windows 7 требуется отдельный автономный установщик WebView2 109. Откройте страницу релиза и скачайте пакет для Windows 7, чтобы обновиться.", + downloading: "Загрузка {progress}%", + downloadFailed: "Не удалось загрузить обновление: {error}", + cacheWriteFailed: "Не удалось сохранить загруженное обновление: {error}. Проверьте, не блокирует ли DBX антивирус и доступна ли для записи папка кэша обновлений, затем повторите попытку.", + downloadCanceled: "Загрузка обновления отменена.", + readyToInstall: "DBX {version} готов к установке.", + installNow: "Установить сейчас", + installedReadyToRestart: "DBX обновлён. Перезапустите для завершения.", + networkOrMirrorFailed: "Время ожидания соединения истекло или зеркала загрузки сейчас недоступны. Проверьте подключение или нажмите «Открыть релиз», чтобы скачать вручную.", + source: "Источник обновлений", + sourceOfficial: "Официальный источник", + sourceCnb: "CNB", + installing: "Установка обновления...", + portableHelperFailed: "Не удалось запустить помощник портативного обновления: {error}", + installFailed: "Не удалось установить обновление: {error}", + restart: "Выйти и перезапустить", + updateAction: "Обновить", + updateNow: "Обновить сейчас", + updateInBackground: "Выполнить в фоне", + updating: "Обновление…", + notInstalled: "Не установлено", + componentsAutoUpdated: "Автоматически обновлено: {components}.", + componentListSeparator: ", ", + componentsAutoUpdateFailed: "Не удалось обновить компонентов: {count}. Повторите попытку вручную позже.", + updateAll: "Обновить все", + componentsAutoUpdateSkipped: "Часть обновлений драйверов отложена, так как их используют активные подключения.", + restartFailed: "Не удалось перезапустить приложение: {error}", + exitAndUpdate: "Выйти и обновить", + dockerUsersRun: "Пользователям Docker следует выполнить", + toUpdate: "для обновления", + }, + pluginDock: { + close: "Закрыть терминал", + hide: "Скрыть панель", + collapse: "Свернуть панель", + expand: "Развернуть панель", + maximize: "Развернуть панель на весь экран", + restore: "Восстановить панель", + newTerminal: "Новый терминал", + newLocalTerminal: "Локальный терминал", + connectionTerminal: "Подключение", + filter: "Фильтр…", + noMatch: "Совпадений нет", + }, + sidebar: { + connections: "ПОДКЛЮЧЕНИЯ", + noConnections: "Подключений пока нет", + importExport: "Импорт / экспорт", + import: "Импортировать подключения", + importDbx: "Импорт конфигурации DBX", + importNavicat: "Импорт Navicat NCX", + importDbeaver: "Импорт DBeaver", + importDatagrip: "Импорт DataGrip", + export: "Экспортировать подключения", + collapseAll: "Свернуть всё", + collapse: "Свернуть боковую панель", + expand: "Развернуть боковую панель", + showMore: "Показать ещё {count}...", + filterByType: "Фильтр по типу", + showActiveConnectionsOnly: "Показывать только активные подключения", + activeConnectionsStatus: "Активные подключения: {count}", + disconnectAllActiveConnections: "Отключить все активные подключения", + sortConnections: "Сортировка подключений", + sortConnectionsManual: "Ручной порядок", + sortConnectionsAscending: "Имя: А–Я", + sortConnectionsDescending: "Имя: Я–А", + searchConnectionSkipped: "Поиск пропустил это подключение: {message}", + searchScopeConnection: "Подключение", + searchScopeDatabase: "База данных", + searchScopeSchema: "Схема", + searchScopeTable: "Таблица", + searchScopeView: "Представление", + searchTablesInCurrentScope: "Поиск таблиц в этой базе данных...", + clearTableSearch: "Очистить поиск таблиц", + localTableSearch: "Локальный поиск", + localTableSearchTooltip: "Поиск по локальному индексу таблиц без удалённых запросов. Отключите для удалённого поиска. Используйте обновление для построения или обновления индекса.", + refreshLocalTableSearchIndex: "Обновить локальный индекс таблиц", + globalLocalSearch: "Локальный поиск", + globalLocalSearchTooltip: "Поиск только среди загруженных объектов боковой панели без удалённых запросов.", + regexSearch: "Поиск по регулярному выражению", + regexSearchTooltip: "Сопоставлять имена, комментарии и псевдонимы в боковой панели с помощью регулярных выражений JavaScript.", + clearFilter: "Очистить фильтр", + locateActiveTab: "Найти в боковой панели", + }, + savedSql: { + saveToLibrary: "Сохранить в библиотеку SQL", + saveToFile: "Сохранить локально", + save: "Сохранить", + saved: "SQL сохранён", + saveFailed: "Не удалось сохранить SQL: {message}", + fileName: "Имя файла", + folder: "Папка", + rootFolder: "Библиотека SQL", + newQuery: "Новый запрос", + newFolder: "Новая папка SQL", + newSubfolder: "Новая вложенная папка", + newFolderDefault: "Новая папка", + renameFolder: "Переименовать папку", + deleteFolder: "Удалить папку", + deleteFolderConfirm: "Удалить «{name}» и SQL-файлы внутри неё?", + open: "Открыть SQL", + copyFile: "Копировать SQL", + pasteFile: "Вставить SQL", + copied: "Скопировано файлов SQL: {count}", + pasted: "Вставлено файлов SQL: {count}", + nothingToPaste: "Нет SQL-файлов для вставки", + pasteFailed: "Не удалось вставить SQL: {message}", + renameFile: "Переименовать SQL", + renameFailed: "Не удалось переименовать SQL: {message}", + nameConflict: "SQL с именем «{name}» уже существует в этом месте", + deleteFile: "Удалить SQL", + deleteFileConfirm: "Удалить «{name}»?", + createFolderOption: "Создать папку «{name}»", + folderPlaceholder: "Выберите папку", + searchPlaceholder: "Поиск папок...", + createFolderFailed: "Не удалось создать папку: {message}", + }, + sqlLibrary: { + title: "Библиотека SQL", + storageHelp: "Содержимое библиотеки SQL хранится в данных приложения DBX, а не в виде отдельных .sql-файлов на диске.\nЧтобы использовать файлы в файловой системе, экспортируйте библиотеку SQL.", + unassociated: "Без связи", + deletedConnection: "Подключение удалено", + openInCurrentDatabase: "Открыть в текущей базе данных", + empty: "Сохранённых запросов пока нет", + emptyFolder: "Пустая папка", + unfiled: "Без папки", + exportFile: "Экспорт SQL", + exportFolder: "Экспорт папки", + exportLibrary: "Экспорт библиотеки SQL", + importDirectory: "Импорт локальной папки", + importIntoFolder: "Импорт в папку", + openStorageDirectory: "Открыть каталог хранения SQL", + chooseSyncDirectory: "Задать локальный каталог синхронизации", + disableSyncDirectory: "Отключить локальный каталог синхронизации", + syncDirectorySaved: "Локальный каталог синхронизации SQL сохранён", + syncDirectoryDisabled: "Локальная синхронизация SQL отключена", + syncDirectoryFailed: "Не удалось задать каталог синхронизации: {message}", + openDirectoryFailed: "Не удалось открыть каталог: {message}", + noSyncDirectory: "Сначала задайте локальный каталог синхронизации", + exported: "Экспортировано", + exportFailed: "Ошибка экспорта: {message}", + importFailed: "Ошибка импорта: {message}", + importNone: "В выбранной папке не найдено .sql-файлов", + imported: "Импортировано файлов SQL: {count}", + desktopOnly: "Эта функция доступна только в настольной версии", + noConnection: "Нет доступного подключения для импорта", + batchDelete: "Массовое удаление", + batchDeleteConfirm: "Вы уверены, что хотите удалить выбранные элементы ({count})? Это действие нельзя отменить.", + batchDeleteSuccess: "Успешно удалено элементов: {count}", + moveToFolder: "Переместить в папку...", + moveSelectedToFolder: "Переместить SQL ({count}) в папку...", + moveSuccess: "Перемещено файлов SQL: {count}", + moveFailed: "Не удалось переместить SQL: {message}", + clearSelection: "Снять выделение", + sortByDate: "Сортировать по дате изменения", + sortByFolder: "Сортировать по структуре папок", + collapseAll: "Свернуть все", + }, + connection: { + title: "Новое подключение", + name: "Имя", + namePlaceholder: "Имя подключения; создаётся автоматически, если пусто", + note: "Заметки", + noteShow: "Показать", + noteShowInSidebar: "Показывать заметку в списке подключений", + notePlaceholder: "Не храните пароли в заметках в открытом виде", + type: "Тип", + host: "Хост", + addHost: "Добавить хост", + filePath: "Путь к файлу", + h2FileMode: "Файл", + h2TcpMode: "TCP", + h2FilePathRequired: "Путь к файлу H2 не может быть пустым", + createDuckDbFile: "Создать файл DuckDB", + createSqliteFile: "Создать базу данных SQLite", + memoryDatabasePathHint: "Используйте :memory:, чтобы создать базу данных SQLite или DuckDB в памяти.", + sqliteCipherKey: "Ключ шифрования SQLite", + sqliteCipherKeyPlaceholder: "Оставьте пустым для незашифрованного SQLite", + sqliteExtensions: "Расширения SQLite", + sqliteExtensionsPlaceholder: "/path/to/regexp.dylib\n/path/to/text.dylib|sqlite3_text_init", + sqliteExtensionsHint: "По одному .dylib/.so/.dll в строке. Используйте «путь|точка входа», если требуется точка входа. Загружается при подключении, после чего load_extension отключается.", + initScript: "Скрипт инициализации", + initScriptPlaceholder: "INSTALL quack;\nLOAD quack;\nATTACH 'quack:host' AS remote (TOKEN '...');", + initScriptHint: "SQL-инструкции, выполняемые при каждом открытии подключения (INSTALL/LOAD, SET, CREATE SECRET, ATTACH ...). Присоединённые здесь базы данных отображаются в боковой панели.", + sqliteExtensionBrowse: "Выбрать расширение SQLite", + user: "Пользователь", + password: "Пароль", + dynamodbEndpoint: "Конечная точка", + dynamodbRegion: "Регион", + dynamodbAccessKeyId: "ID ключа доступа", + dynamodbSecretAccessKey: "Секретный ключ доступа", + dynamodbSessionToken: "Токен сеанса", + dynamodbSessionTokenPlaceholder: "Необязательно", + dynamodbCredentialsRequired: "Для DynamoDB требуются ID ключа доступа и секретный ключ доступа", + savePassword: "Сохранить пароль", + savePasswordHint: "Пароль сохранён, поэтому вводить его снова не потребуется.", + savePasswordSessionHint: "Пароль хранится только в этой сессии и очищается при выходе из приложения.", + disconnectAndForgetPassword: "Отключиться и забыть пароль", + passwordForgotten: "Пароль забыт. При повторном подключении его потребуется ввести снова.", + promptPasswordTitle: "Введите пароль", + promptPasswordMessage: "Введите пароль для подключения «{connection}». Если пароль пустой, подключитесь напрямую.", + promptPasswordPlaceholder: "Пароль", + promptPasswordSubmit: "Подключиться", + promptPasswordCancel: "Отмена", + promptRememberPassword: "Запомнить пароль", + rememberPasswordSaveFailed: "Подключение выполнено, но DBX не смог запомнить пароль: {message}", + mysqlMissingPasswordHint: "Пароль базы данных не был отправлен. Введите пароль и повторите попытку.", + database: "База данных", + databasePlaceholder: "Необязательно", + databasePlaceholderRequired: "Обязательно, укажите существующую базу данных", + databasePlaceholderWithDefault: "Необязательно, по умолчанию {database}", + kingbaseDatabaseRequired: "KingbaseES требует существующую базу данных перед подключением или загрузкой списка баз данных.", + xuguDatabaseRequired: "XuguDB требует существующую базу данных перед подключением.", + defaultDatabase: "БД по умолчанию", + authDatabase: "БД аутентификации", + authDatabasePlaceholder: "Необязательно, часто admin", + authMechanism: "Механизм аутентификации", + authMechanismDefault: "По умолчанию", + oidcBrowserAuthHint: "Аутентификация открывается в системном браузере. Пароль базы данных не требуется.", + driverMode: "Драйвер", + mongoDriverAuto: "Авто", + mongoDriverLegacy: "Устаревший", + serviceName: "Служба/SID", + serviceNameOnly: "Имя службы", + oracleTnsAlias: "Сетевой псевдоним", + oracleTnsAliasPlaceholder: "Псевдоним из tnsnames.ora", + oracleTnsAdminPlaceholder: "Каталог, содержащий tnsnames.ora", + oracleTnsAdminBrowse: "Выбрать tnsnames.ora", + oracleTnsPathHint: "Этот путь читает бэкенд DBX / агент Oracle. В настольной версии пути локальные; в Web и Docker — на сервере.", + oracleTnsAliasRequired: "Режим Oracle TNS требует сетевой псевдоним.", + oracleTnsAdminRequired: "Режим Oracle TNS требует каталог TNS_ADMIN, содержащий tnsnames.ora.", + oracleTnsTransportUnsupported: "Подключения Oracle TNS не могут использовать слои туннеля SSH, прокси или HTTP. Удалите транспортный слой или используйте режим Service Name/SID.", + igniteVersion: "Версия Ignite", + elasticsearchDirectMode: "Прямой", + elasticsearchKibanaProxyMode: "Прокси Kibana", + elasticsearchKibanaHost: "Хост Kibana", + elasticsearchKibanaBasePath: "Базовый путь", + elasticsearchConnectivityCheckPath: "Путь проверки подключения", + elasticsearchConnectivityCheckPathPlaceholder: "/ or /my-index/_search", + elasticsearchConnectivityCheckDisabled: "Отключить проверку подключения", + elasticsearchConnectivityCheckDisabledHint: "Если включено, подключение и проверка пропускают пробный запрос и считают сервер доступным. Используйте, когда у учётной записи нет прав на корневой путь и любой путь проверки либо когда права различаются между кластерами.", + elasticsearchIndexGroupingPattern: "Regex группировки индексов", + elasticsearchIndexGroupingPatternPlaceholder: "по умолчанию выключено; введите regex для включения", + elasticsearchIndexGroupingPatternHint: "По умолчанию выключено (схемы именования различаются). Введите регулярное выражение для включения: совпавшие rolling- или time-series-индексы объединяются в один запрашиваемый шаблон с подстановочным знаком, скрывая детализацию по дням.", + version: "Версия", + victoriametricsApiPath: "Путь API", + victoriametricsApiPathHint: "Используйте /prometheus для одноузловых развёртываний или /select/tenantID/prometheus для кластеров.", + victoriametricsLookback: "Глубина просмотра метаданных", + victoriametricsLookbackHint: "Используется для обнаружения метрик и столбцов меток, например 1h или 7d. Предпросмотр метрик использует 1h и остаётся редактируемым.", + victoriametricsInvalidApiPath: "Путь API VictoriaMetrics должен быть пустым или начинаться с /.", + victoriametricsInvalidLookback: "Недопустимая глубина просмотра VictoriaMetrics. Используйте значение, например 15m, 1h или 7d.", + driverInstallHintPrefix: "Установите требуемый драйвер из ", + driverInstallHintSuffix: " на верхней панели инструментов перед подключением.", + driverName: "Имя драйвера", + driverNamePlaceholder: "Название производителя или окружения", + urlParams: "Параметры URL", + sessionVariablesHint: + "DBX повышает значение сеансовой переменной group_concat_max_len до 1048576, чтобы результаты GROUP_CONCAT не обрезались незаметно. Чтобы следовать конфигурации сервера, используйте sessionVariables=group_concat_max_len={'@'}{'@'}global.group_concat_max_len (синтаксис MySQL Connector/J; разделяйте несколько переменных запятыми).", + localInfilePathHint: "Для LOAD DATA LOCAL INFILE явно добавьте каждый файл в белый список с помощью localInfilePath=/absolute/path/file.csv. Повторите параметр для дополнительных файлов.", + d1AccountId: "ID учётной записи", + d1DatabaseId: "ID базы данных", + d1ApiToken: "Токен API", + d1TokenHint: "Токену требуется разрешение D1 Read; для записи, DDL и импорта также требуется D1 Write.", + d1FieldsRequired: "Требуются Cloudflare Account ID, D1 Database ID и API Token.", + spannerStructuredMode: "ID ресурсов", + spannerResourcePathMode: "Путь ресурса", + spannerProject: "ID проекта", + spannerInstance: "ID экземпляра", + spannerDatabase: "ID базы данных", + spannerResourcePathHint: "projects/my-project/instances/my-instance/databases/my-database", + spannerHostHint: "Оставьте хост пустым для Google Cloud. Для локального эмулятора задайте хост localhost с портом 9010; для loopback-хостов plaintext gRPC включается автоматически.", + spannerCredentialsHint: "Аутентификация использует Application Default Credentials. Чтобы использовать файл ключа сервисной учётной записи, добавьте credentials=/path/key.json в параметры URL.", + spannerFieldsRequired: "Требуются проект, экземпляр и база данных Cloud Spanner.", + hiveAuthMode: "Аутентификация", + hiveAuthNone: "Нет", + hivePrincipal: "Принципал", + hiveKerberosPrincipalRequired: "Требуется Kerberos principal", + hiveKrb5ConfBrowse: "Выбрать krb5.conf", + hiveJaasConfigBrowse: "Выбрать конфигурацию JAAS", + hiveTicketCache: "Кэш билетов", + hiveTicketCacheFallback: "Задайте useSubjectCredsOnly=false", + hiveJvmOptions: "Параметры JVM", + hiveJvmOptionsPlaceholder: "-Dsun.security.krb5.debug=true", + gbaseServer: "GBASEDBTSERVER", + gbaseServerHint: "Должно совпадать с DBSERVERNAME или DBSERVERALIASES сервера.", + gbaseServerMismatch: "Не удалось подключиться к GBase 8s, поскольку GBASEDBTSERVER не совпадает с DBSERVERNAME или DBSERVERALIASES сервера. Укажите в GBASEDBTSERVER фактическое имя сервера.", + informixServer: "INFORMIXSERVER", + sslEnable: "Включить зашифрованное подключение", + caCertPath: "Сертификат CA", + caCertPathPlaceholder: "Необязательно, например ~/.yandex/RootCA.crt", + caCertPathBrowse: "Выбрать сертификат", + cassandraTruststore: "Хранилище сертификатов", + cassandraTruststorePlaceholder: "/path/to/client.truststore", + cassandraTruststorePassword: "Пароль truststore", + cassandraTruststoreBrowse: "Выбрать Cassandra truststore", + cassandraTruststoreHint: "Truststore JKS или PKCS#12, используемый для проверки сертификатов сервера Cassandra.", + cassandraTruststorePasswordRequiresPath: "Выберите Cassandra truststore перед вводом его пароля.", + cassandraKeystore: "Клиентский keystore", + cassandraKeystorePlaceholder: "/path/to/client.keystore", + cassandraKeystorePassword: "Пароль keystore", + cassandraKeystoreBrowse: "Выбрать клиентский keystore Cassandra", + cassandraKeystoreHint: "Необязательный keystore JKS или PKCS#12 для аутентификации по клиентскому сертификату.", + cassandraKeystorePasswordRequiresPath: "Выберите клиентский keystore Cassandra перед вводом его пароля.", + damengSslFilesPath: "Каталог сертификатов", + damengSslFilesPathPlaceholder: "/path/to/dmcert", + damengSslFilesPathBrowse: "Выбрать каталог сертификатов", + damengSslKeystorePassword: "Пароль keystore", + damengSslHint: "DM8 JDBC читает SSL-сертификаты из этого каталога и передаёт оба поля через параметры URL.", + damengSslProtocol: "Протокол SSL", + damengSslProtocolPlaceholder: "Необязательно, например TLSv1.2", + damengSslVerificationHint: "Проверка сертификата управляется настройкой ENABLE_ENCRYPT сервера DM8. Режим 5 проверяет сертификат сервера; режим 4 шифрует без проверки сертификата.", + damengJvmOptions: "Системные свойства JVM", + damengJvmOptionsPlaceholder: "-Djava.net.preferIPv4Stack=true", + damengJvmOptionsHint: "По одному -Dkey или -Dkey=value в строке. Значения с пробелами не требуют кавычек оболочки.", + damengJvmOptionsInvalid: "Строка {line} должна быть системным свойством -Dkey или -Dkey=value без кавычек оболочки.", + damengBuiltinDriver: "Встроенный DM8", + damengCustomDriver: "DM6 / Пользовательский JAR", + damengDriverModeHint: "Используйте встроенный драйвер для DM8. Для DM6 или другой совместимой версии выберите её официальный JDBC JAR.", + damengCustomDriverHint: "Выберите Dameng JDBC JAR из лицензированного источника. Пользовательский драйвер изолирован внутри агента Dameng и не требует универсального плагина JDBC.", + damengCustomDriverRequired: "Выберите JAR-файл драйвера Dameng JDBC.", + redisTlsInsecure: "Пропускать проверку сертификата", + redisTlsInsecureHint: "Эквивалентно redis-cli --tls --insecure, для самоподписанных сертификатов или частных CA.", + mysqlTlsMode: "Режим TLS", + mysqlTlsModePreferred: "Предпочтительный", + mysqlTlsModeDisabled: "Отключено", + mysqlTlsModeRequired: "Обязательный", + mysqlTlsModeVerifyCa: "Проверять CA", + mysqlTlsModeVerifyIdentity: "Проверять удостоверение", + mysqlCleartextPasswordAuth: "Аутентификация с паролем в открытом виде", + mysqlCleartextPasswordAuthHint: "Включайте только если сервер MySQL требует плагин аутентификации с паролем в открытом виде.", + mysqlCaCertHint: "Требуется для «Проверять CA» и «Проверять удостоверение», когда сертификат сервера использует частный CA.", + mysqlClientCert: "Аутентификация клиента", + mysqlClientCertPlaceholder: "/path/to/client.crt", + mysqlClientKeyPlaceholder: "/path/to/client.key", + mysqlClientCertHint: "Клиентский сертификат и закрытый ключ должны предоставляться вместе, когда MySQL требует mTLS.", + mysqlTlsConnectionFailureHint: "Если сервер MySQL не требует TLS, измените подключение, установите для режима TLS значение «Отключено» и повторите попытку.", + mysqlUnsupportedCertVersionHint: "Строгая проверка не поддерживает эту версию сертификата сервера. Замените его на сертификат X.509 v3 или используйте режим «Обязательный» только в доверенной сети.", + mysqlClientCertBrowse: "Выбрать клиентский сертификат", + mysqlClientKeyBrowse: "Выбрать закрытый ключ клиента", + postgresSslMode: "Режим TLS", + postgresSslModeDisable: "Отключить", + postgresSslModePrefer: "Предпочитать", + postgresSslModeRequire: "Требовать", + postgresSslModeVerifyCa: "Проверять CA", + postgresSslModeVerifyFull: "Проверять полностью", + postgresLegacyTls: "Совместимость со старым TLS", + postgresLegacyTlsHint: "Поддерживает серверы, ограниченные статическим обменом ключами RSA в TLS 1.2. Это менее безопасно, чем режим по умолчанию; включайте только если конфигурацию TLS сервера нельзя обновить.", + postgresServerCert: "CA сервера", + postgresRootCertPlaceholder: "/path/to/ca.crt", + postgresRootCertHint: "Используйте это для verify-ca или verify-full, когда сертификат сервера подписан частным CA.", + postgresRootCertBrowse: "Выбрать сертификат CA", + postgresClientCert: "Аутентификация клиента", + postgresClientCertPlaceholder: "/path/to/client.crt", + postgresClientKeyPlaceholder: "/path/to/client.key", + postgresClientCertHint: "Клиентский сертификат и закрытый ключ должны предоставляться вместе, когда PostgreSQL требует mTLS.", + postgresClientCertBrowse: "Выбрать клиентский сертификат", + postgresClientKeyBrowse: "Выбрать закрытый ключ клиента", + connectionUrlOptional: "URL (необязательно)", + connectionUrlPlaceholder: "postgresql://user:pass{'@'}host:5432/db?sslmode=require", + parseConnectionUrl: "Разобрать URL подключения", + parseConnectionUrlApplied: "URL подключения применён", + parseConnectionUrlFailed: "Не удалось разобрать URL подключения: {message}", + mode: "Режим подключения", + modeForm: "Форма", + redisStandaloneMode: "Автономный", + redisSentinelMode: "Sentinel", + redisClusterMode: "Кластер", + oceanbaseMySQLMode: "Режим MySQL", + oceanbaseOracleMode: "Режим Oracle", + redisFirstSentinel: "Первый Sentinel", + redisFirstClusterNode: "Первый начальный узел", + redisSentinelNodes: "Узлы Sentinel", + redisClusterNodes: "Начальные узлы кластера", + redisSentinelMaster: "Имя master", + redisSentinelUser: "Пользователь Sentinel", + redisSentinelPassword: "Пароль Sentinel", + redisSentinelTls: "TLS Sentinel", + redisSentinelTlsHint: "Использовать TLS при подключении к узлам Sentinel", + redisKeySeparator: "Разделитель пространства имён ключей", + redisKeyTemplates: "Шаблоны поиска ключей", + redisKeyTemplatesPlaceholder: "Example:\nuser:{'{'}$userId{'}'}\nv3:adui:{'{'}$positionID{'}'}", + redisKeyTemplatesHint: "По одному шаблону в строке. Если заданы, они заменяют глобальные шаблоны ключей Redis для этого подключения.", + etcdEndpoints: "Конечные точки", + etcdEndpointsHint: "По одной конечной точке в строке. Оставьте пустым, чтобы использовать хост и порт выше.", + etcdV2ApiHint: "API v2 доступен только в etcd 2.x или etcd 3.0–3.5, запущенном с --enable-v2. История ключей, аренды, компактификация и дефрагментация недоступны.", + etcdGrpcMaxInbound: "Лимит приёма gRPC (МиБ)", + etcdGrpcMaxInboundHint: "Максимальный размер одного ответа etcd. По умолчанию 32 МиБ, максимум 256 МиБ.", + etcdCaCertPlaceholder: "/path/to/ca.crt", + etcdCaCertBrowse: "Выбрать сертификат CA", + etcdClientAuth: "Аутентификация клиента", + etcdClientCertPlaceholder: "/path/to/client.crt", + etcdClientKeyPlaceholder: "/path/to/client.key", + etcdClientCertHint: "Клиентский сертификат и закрытый ключ должны предоставляться вместе, когда etcd требует mTLS.", + clientCertHint: "Клиентский сертификат и закрытый ключ должны предоставляться вместе, когда требуется взаимный TLS (mTLS).", + etcdClientCertBrowse: "Выбрать клиентский сертификат", + etcdClientKeyBrowse: "Выбрать закрытый ключ клиента", + etcdClientCertPairRequired: "Клиентский сертификат и закрытый ключ должны предоставляться вместе.", + consulAddress: "Адрес Consul API", + consulAddressInvalid: "Введите абсолютный адрес Consul API HTTP или HTTPS без учётных данных, параметров запроса и фрагмента.", + consulToken: "Токен ACL", + consulTokenPlaceholder: "Необязательный токен Consul ACL", + consulDatacenter: "Центр обработки данных", + consulNamespace: "Пространство имён", + consulPartition: "Административный раздел", + consulAgentTargetNode: "Целевой узел агента", + consulAgentTargetAddress: "Прямой адрес агента", + consulAgentTargetHint: "Требуется для операций записи агента. DNS/балансируемые и конечные точки транспортного уровня остаются доступными только для чтения.", + consulMeshFeatures: "Сервисная сетка", + consulMeshVisible: "Показывать расширенную рабочую область service mesh", + consulMeshVisibleHint: "Включайте только для управления Connect, intentions или peering. Когда отключено, рабочая область остаётся скрытой.", + consulOperatorWrites: "Операторские записи", + consulOperatorVisible: "Показывать экспериментальную рабочую область Operator", + consulOperatorSnapshotRestore: "Включить восстановление из снимка", + consulOperatorAutopilot: "Включить обновления Autopilot", + consulOperatorRaft: "Включить изменения Raft", + consulOperatorKeyring: "Включить изменения Keyring", + consulOperatorLicense: "Включить обновления лицензии", + consulAgentTargetIncomplete: "Целевой узел агента и прямой адрес должны задаваться вместе.", + consulAgentTargetAddressMismatch: "Прямой адрес агента должен совпадать с хостом конечной точки Consul.", + consulConsistency: "Согласованность чтения", + consulConsistencyDefault: "По умолчанию", + consulConsistencyStale: "Устаревшая", + consulConsistencyConsistent: "Согласованная", + consulTlsSkipVerify: "Пропускать проверку сертификата", + consulTlsSkipVerifyHint: "Используйте только для доверенных самоподписанных конечных точек Consul.", + zookeeperConnectString: "Строка подключения", + zookeeperConnectStringHint: "Записи host:port через запятую или с новой строки с необязательным общим /chroot. Оставьте пустым, чтобы использовать хост и порт выше.", + zookeeperClusterInputHint: "Для ансамбля ZooKeeper введите все узлы либо в URL (например zookeeper://zk-1:2181,zk-2:2181/app), либо в поле «Строка подключения» ниже.", + zookeeperAuthMethod: "Аутентификация", + zookeeperAuthDigest: "Digest (по умолчанию)", + zookeeperAuthSaslDigest: "SASL DIGEST-MD5", + zookeeperCreateModePersistent: "Постоянный", + zookeeperCreateModeEphemeral: "Временный", + zookeeperCreateModePersistentSequential: "Постоянный последовательный", + zookeeperCreateModeEphemeralSequential: "Временный последовательный", + nacosConsoleUrl: "Адрес управления Nacos", + nacosConsoleUrlHint: "Используйте адрес, соответствующий выбранному профилю Nacos. Принимаются полные URL браузера и API.", + nacosConsoleUrlRequired: "Требуется адрес управления Nacos", + nacosConsoleUrlAutoAdjusted: "URL консоли Nacos скорректирован с {from} на {to}.", + nacosWebConsoleUrl: "URL веб-консоли Nacos", + nacosWebConsoleUrlHint: "Необязательно. Открывает консоль Nacos в браузере. Nacos 3 требует отдельный адрес веб-консоли; браузеру нужен прямой доступ, туннели DBX и аутентификация API не используются.", + nacosWebConsoleUrlInvalid: "URL веб-консоли Nacos должен быть допустимым URL HTTP или HTTPS без встроенных учётных данных.", + nacosRNacosOpenApiAutoAdjusted: "Переключено на OpenAPI r-nacos: {from} → {to} (Context Path: /nacos).", + nacosImplementation: "Реализация службы", + nacosVersion: "Версия Nacos", + nacosVersionAuto: "Автоопределение", + nacosPrimaryAddressRNacos: "Адрес API, совместимого с Nacos", + nacosPrimaryAddressV2: "Адрес службы (общий для API и консоли)", + nacosPrimaryAddressV3: "Адрес Server / Admin API", + nacosPrimaryAddressAuto: "Адрес управления Nacos", + nacosPrimaryAddressHint: "Для Nacos 3 используйте адрес Server / Admin API (обычно http://host:8848/nacos), а не консоль на порту 8080; пользовательские префиксы прокси сохраняются.", + nacosRequestsUse: "Запросы будут использовать {address}/…", + nacosNamespace: "Пространство имён", + nacosContextPath: "Путь контекста", + nacosContextPathPlaceholder: "Оставьте пустым или /nacos", + nacosContextPathRestoreAuto: "Восстановить автоматически", + nacosConfigurationHistory: "История конфигураций", + nacosConfigurationHistoryEnable: "Включить историю конфигураций", + nacosConfigurationHistoryHint: + "История конфигураций r-nacos доступна только через его независимую консоль (обычно порт 10848). Консоль имеет отдельный сеанс входа от OpenAPI, совместимого с Nacos: OpenAPI может не требовать аутентификации, пока консоль всё ещё требует. Используйте ту же учётную запись r-nacos, если только вам намеренно не нужна другая.", + nacosRNacosConsoleUrl: "URL консоли r-nacos", + nacosRNacosConsoleUrlPlaceholder: "http://127.0.0.1:10848", + nacosRNacosConsoleUrlHint: "Необязательно. Используйте независимый URL консоли (обычно порт 10848), а не URL OpenAPI; он включает историю конфигураций и чтение типов и описаний конфигураций r-nacos.", + nacosRNacosOpenApiRequired: "Основной адрес r-nacos должен использовать API, совместимый с Nacos, а не URL независимой консоли.", + nacosRNacosConsoleUrlRequired: "Для истории конфигураций r-nacos требуется URL консоли.", + nacosConsoleAuthSeparateRequired: "Основная аутентификация — «Нет»; настройте отдельные учётные данные консоли.", + nacosAuth: "Аутентификация", + nacosAuthNone: "Нет", + nacosAuthUserPassword: "Пользователь / Пароль", + nacosConsoleAuthentication: "Аутентификация консоли", + nacosConsoleAuthInherit: "Использовать основные учётные данные", + nacosConsoleAuthSeparate: "Отдельные учётные данные", + nacosConsoleAuthPrimaryNone: "Основная аутентификация — «Нет»; используйте отдельные учётные данные консоли.", + nacosConsoleUser: "Пользователь консоли", + nacosConsolePassword: "Пароль консоли", + nacosConsoleUsernameRequired: "Требуется имя пользователя консоли r-nacos", + nacosUsernameRequired: "Требуется имя пользователя Nacos", + nacosTls: "TLS", + nacosTlsSkipVerify: "Пропускать проверку сертификата", + nacosPageSize: "Размер страницы", + nacosMetrics: "Метрики Prometheus", + nacosMetricsAuto: "Автоопределение", + nacosMetricsDisabled: "Отключено", + nacosMetricsCustom: "Пользовательский URL", + nacosMetricsAutoHint: "Проверяются по порядку: {addresses}", + nacosMetricsUrl: "URL метрик", + nacosMetricsUrlInvalid: "Введите абсолютный URL метрик Prometheus HTTP или HTTPS без учётных данных и фрагмента.", + kafkaKerberosPrincipal: "Принципал", + kafkaKerberosKeytab: "Файл keytab", + kafkaKerberosServiceName: "Имя службы", + kafkaKerberosKrb5Conf: "krb5.conf", + kafkaKerberosPrincipalRequired: "Требуется Kafka Kerberos principal", + kafkaKerberosKeytabRequired: "Требуется путь к Kafka Kerberos keytab", + kafkaKerberosKeytabBrowse: "Выбрать keytab", + kafkaKerberosKrb5ConfBrowse: "Выбрать krb5.conf", + kafkaKerberosKeytabPlaceholder: "Путь на машине DBX Agent, например /etc/security/keytabs/user.keytab", + kafkaKerberosKrb5ConfPlaceholder: "Необязательный путь на машине DBX Agent, например /etc/krb5.conf", + kafkaKerberosPathHint: "Пути keytab и krb5.conf читаются DBX Agent и должны существовать на машине, где запущен DBX Agent; файлы не загружаются из этого браузера.", + kafkaKerberosAuthHint: "Использует вход GSSAPI + keytab. Если сервер требует зашифрованный транспорт, задайте для Security значение SASL_SSL; иначе можно использовать Auto или SASL_PLAINTEXT.", + mqSystem: "Система", + mqSystemPulsar: "Apache Pulsar", + mqSystemKafka: "Apache Kafka", + mqSystemRocketMq: "Apache RocketMQ", + rocketmqNamesrvAddr: "Адрес NameServer", + rocketmqNamesrvAddrPlaceholder: "127.0.0.1:9876", + rocketmqNamesrvAddrRequired: "Требуется адрес NameServer RocketMQ", + rocketmqNamesrvAddrInvalid: "Адрес NameServer RocketMQ недействителен", + rocketmqClusterName: "Имя кластера", + rocketmqClusterNamePlaceholder: "Необязательно, например DefaultCluster", + rocketmqAccessKey: "Ключ доступа", + rocketmqSecretKey: "Секретный ключ", + rocketmqAclAuth: "ACL", + mqBootstrapServers: "Bootstrap-серверы", + mqBootstrapServersPlaceholder: "127.0.0.1:9092", + mqBootstrapServersRequired: "Требуются bootstrap-серверы Kafka", + mqBootstrapServersInvalid: "Bootstrap-серверы Kafka недействительны", + mqKafkaConnectionSource: "Источник подключения", + mqKafkaConnectionSourceBootstrap: "Bootstrap-серверы", + mqKafkaConnectionSourceZooKeeper: "ZooKeeper (Kafka 1.x)", + mqKafkaZooKeeperServers: "Серверы ZooKeeper", + mqKafkaZooKeeperServersPlaceholder: "zk1:2181,zk2:2181/kafka", + mqSystemRabbitMq: "RabbitMQ", + mqRabbitmqAddresses: "Адреса", + mqRabbitmqAddressesPlaceholder: "127.0.0.1:5672", + mqRabbitmqAddressesRequired: "Укажите адреса RabbitMQ", + mqRabbitmqAddressesInvalid: "Введите адреса RabbitMQ в формате host:port (например, 127.0.0.1:5672), без amqp://", + mqVirtualHost: "Виртуальный хост", + mqVirtualHostPlaceholder: "/", + mqRabbitmqAdminUrl: "URL управления", + mqRabbitmqAdminUrlPlaceholder: "http://192.168.1.1:15672", + mqRabbitmqAdminUrlHint: "Оставьте пустым только для стандартного порта AMQP; для нестандартных портов AMQP требуется отдельно настроенный URL Management API. Поддерживаются пути обратного прокси, например https://proxy/rmq", + mqRabbitmqUsernamePlaceholder: "По умолчанию guest", + mqRabbitmqPasswordPlaceholder: "По умолчанию guest", + mqSecurity: "Безопасность", + mqSecurityAuto: "Авто", + mqAdminUrl: "URL администратора", + mqAdminUrlRequired: "Укажите URL администратора MQ", + mqAdminUrlInvalid: "Недопустимый URL администратора MQ", + mqAuth: "Аутентификация", + mqAuthNone: "Нет", + mqAuthToken: "Токен", + mqAuthBasic: "Basic", + mqAuthKerberos: "Kerberos", + mqAuthApiKey: "API-ключ", + mqAuthOauth2: "OAuth2", + mqToken: "Токен", + mqSaslMechanism: "Механизм SASL", + mqApiKeyHeader: "Заголовок", + mqApiKeyValue: "Значение", + mqOauthIssuerUrl: "URL издателя", + mqOauthClientId: "Client ID", + mqOauthClientSecret: "Client Secret", + mqOauthAudience: "Аудитория", + mqOauthScope: "Область доступа", + mqOauthIssuerRequired: "Для аутентификации OAuth2 требуется URL издателя", + mqOauthClientIdRequired: "Для аутентификации OAuth2 требуется client ID", + mqOauthClientSecretRequired: "Для аутентификации OAuth2 требуется client secret", + mqTls: "TLS", + mqTlsSkipVerify: "Пропускать проверку сертификата", + mqPinnedVersion: "Фиксированная версия", + mqTokenSigning: "Подпись токенов брокера", + mqTokenSigningNone: "Не настроено", + mqTokenSigningKey: "Ключ подписи", + mqTokenSigningKeyRequired: "Укажите ключ подписи токенов брокера", + mqTokenSigningKeyPlaceholderHs256: "Broker SECRET", + mqTokenSigningKeyPlaceholderRs256: "-----BEGIN PRIVATE KEY-----", + mqTokenSigningHint: "Выбирайте в зависимости от jwt.broker.token.mode на брокере: SECRET использует HS256, PRIVATE — RS256. Ключ хранится вместе с секретами подключения.", + mqttBrokerAddress: "Адрес брокера", + mqttBrokerAddressPlaceholder: "127.0.0.1", + mqttBrokerPort: "Порт", + mqttClientId: "Client ID", + mqttClientIdPlaceholder: "Генерируется автоматически", + mqttUsername: "Имя пользователя", + mqttUsernamePlaceholder: "Необязательно", + mqttPassword: "Пароль", + mqttAuthCertificate: "Клиентский сертификат", + mqttCaCertPath: "Путь к сертификату CA", + mqttClientCertPath: "Путь к клиентскому сертификату", + mqttClientKeyPath: "Путь к закрытому ключу клиента", + mqttPasswordPlaceholder: "Необязательно", + mqttTls: "TLS", + mqttTlsSkipVerify: "Пропускать проверку сертификата", + mqttKeepAlive: "Keep Alive (секунды)", + mqttProtocolVersion: "Версия протокола", + mqttTransport: "Транспорт", + mqttTransportTcp: "TCP", + mqttTransportWebSocket: "WebSocket", + mqttWsPath: "Путь WebSocket", + mqttWsPathPlaceholder: "/mqtt", + mqttConnectTimeout: "Тайм-аут подключения (секунды)", + mqttMaxPacketSize: "Макс. размер пакета (байты)", + mqttConsoleTitle: "Консоль MQTT", + mqttTopics: "Топики", + mqttMessages: "Сообщения", + mqttPublish: "Опубликовать сообщение", + mqttSubscribe: "Подписаться", + mqttNoLocal: "Без локальных", + mqttUnsubscribe: "Отписаться", + mqttNoMessages: "Нет сообщений", + mqttNoTopics: "Нет подписанных топиков", + mqttQuickSubscribe: "Быстрая подписка", + mqttTopicPlaceholder: "Имя топика", + mqttConnected: "Подключено", + mqttDisconnected: "Отключено", + mqttRefresh: "Обновить", + mqttPublishDialogTitle: "Опубликовать сообщение MQTT", + mqttClearMessages: "Очистить сообщения", + mqttPauseMessages: "Пауза", + mqttResumeMessages: "Продолжить", + mqttHidePublishPanel: "Скрыть панель публикации", + mqttShowPublishPanel: "Показать панель публикации", + mqttNoTopicsHint: "Нет подписок. Используйте поле ниже, чтобы подписаться на топик.", + mqttSubscribePlaceholder: "Введите фильтр топика...", + mqttMessagesForTopic: "Сообщения: {topic}", + mqttAllMessages: "Сообщения (все топики)", + mqttSent: "Отправленные", + mqttReceived: "Полученные", + mqttRetained: "Сохранённые", + mqttTopic: "Топик", + mqttTopicExample: "например, sensors/temperature", + mqttRetainMessage: "Сохранить сообщение (retain)", + mqttPayloadEncoding: "Кодировка полезной нагрузки", + mqttPayload: "Полезная нагрузка", + mqttResizePayload: "Перетащите, чтобы изменить размер поля ввода сообщения", + mqttPayloadPlaceholderPlaintext: "Введите содержимое сообщения...", + mqttPayloadPlaceholderJson: "Введите JSON, например {example}", + mqttPayloadPlaceholderBase64: "Введите данные в кодировке Base64", + mqttPayloadPlaceholderHex: "Введите шестнадцатеричные данные, например 48 65 6C 6C 6F", + mqttPayloadPlaceholderStructured: "Введите значение JSON; оно будет закодировано как {encoding}", + mqttPublishShortcut: "Ctrl+Enter — опубликовать", + mqttPublishTopicRequired: "Укажите топик", + mqttPublishTopicWildcard: "Топики публикации не могут содержать подстановочные знаки # или +. Замените фильтр подписки на конкретный топик.", + mqttPublishSuccess: "Сообщение опубликовано", + mqttPublishing: "Публикация...", + mqttQosAtMostOnce: "Не более одного раза", + mqttQosAtLeastOnce: "Не менее одного раза", + mqttQosExactlyOnce: "Ровно один раз", + mqttSubscriptionConfig: "Настройка подписки", + mqttNewSubscription: "Новая подписка", + mqttEditSubscription: "Изменить подписку", + mqttSearchSubscriptionsPlaceholder: "Поиск фильтров подписки...", + mqttSearchPayloadPlaceholder: "Поиск по полезной нагрузке сообщений...", + mqttNoMatchingMessages: "Нет загруженных сообщений, соответствующих этому фильтру полезной нагрузки", + mqttNoSavedSubscriptions: "Нет сохранённых подписок. Нажмите «Новая подписка», чтобы добавить.", + mqttTopicFilter: "Фильтр топика", + mqttTopicFilterPlaceholder: "например, device/+/status", + mqttTopicFilterHint: "Поддерживаются одноуровневый знак + и многоуровневый знак #.", + mqttNoLocalMqtt5Only: "Только MQTT 5.0", + mqttEnableSubscription: "Включить подписку", + mqttEnableSubscriptionHint: "Подписаться сразу после сохранения и восстанавливать при переподключении.", + mqttSaving: "Сохранение...", + mqttSubscriptionTopicFilterInvalid: "Недопустимый фильтр топика: + должен занимать один уровень, а # — быть последним уровнем.", + mqttSubscriptionTopicFilterDuplicate: "Такой фильтр топика уже существует.", + mqttSubscriptionNoLocalProtocolError: "No Local не поддерживается в MQTT 3.x. Переключитесь на MQTT 5.0.", + mqttDeleteSubscriptionConfirm: "Удалить настройку подписки «{topic}»?", + mqttSubscriptionStatusActive: "Подписан", + mqttSubscriptionStatusPending: "Ожидание", + mqttSubscriptionStatusDisabled: "Отключено", + mqttSubscriptionDisable: "Отключить подписку", + mqttSubscriptionEnable: "Включить подписку", + mqttSubscriptionEdit: "Изменить настройку", + mqttSubscriptionDelete: "Удалить настройку", + mqttSubscriptionOperationFailed: "Не удалось выполнить операцию с подпиской: {error}. Настройка сохранена.", + searchDatabasePlaceholder: "Поиск типов баз данных", + searchResults: "Результаты поиска", + databaseCategories: "Категории", + databaseCategorySql: "Реляционные", + databaseCategoryAnalytics: "Аналитические", + databaseCategoryDomestic: "Китайские БД", + databaseCategoryLightweight: "Лёгкие", + databaseCategoryDocument: "Документные/Кэш/Поиск", + databaseCategoryGraphAi: "Графовые/Векторные", + databaseCategoryTimeseries: "Временные ряды", + databaseCategoryMq: "Очереди сообщений", + databaseCategoryRegistryConfig: "Реестр/Конфигурация", + databaseCategoryPlugins: "Плагины", + pluginProviderUnavailable: "Провайдер подключения этого плагина недоступен. Переустановите или включите плагин и повторите попытку.", + pluginRequiredField: "Укажите {field}", + pluginSshKeyPickerPlaceholder: "Выбрать локальный SSH-ключ…", + pluginFieldSelectFile: "Выбрать файл…", + pluginFieldUploadFile: "Загрузить файл…", + pluginFieldSelectDirectory: "Выбрать папку…", + pluginSshKeyPickerEmpty: "Локальные SSH-ключи не найдены", + pluginSshKeyEncrypted: "зашифрован", + jdbcConnection: "Подключение JDBC", + iconView: "Вид значками", + listView: "Вид списком", + selectedDatabase: "Выбрано", + noDatabaseMatches: "Нет подходящих баз данных", + next: "Далее", + back: "Назад", + basicTab: "Подключение", + tlsTab: "TLS/SSL", + test: "Проверить", + testing: "Проверка...", + copyTestResult: "Копировать результат проверки", + sqlServerLegacyCompatibilityMode: "Режим совместимости с устаревшими версиями", + sqlServerLegacyCompatibilityModeEnable: "Включить", + sqlServerLegacyCompatibilityModeHint: "Для экземпляров SQL Server, ограниченных TLS 1.0, шифрованием только при входе или без шифрования.\nНекоторые функции могут быть ограничены; используйте только в доверенных сетях.", + sqlServerLegacyCompatibilityComponent: "Компонент совместимости SQL Server с устаревшими версиями", + gaussdbConnectionMode: "Режим подключения", + gaussdbConnectionModeNative: "Совместимый с PostgreSQL (встроенный драйвер)", + gaussdbConnectionModeMJdbc: "Режим M (JDBC-драйвер производителя)", + gaussdbConnectionModeNativeHint: "Использует встроенный в DBX протокол, совместимый с PostgreSQL, для режимов совместимости GaussDB A/PG/Oracle.", + gaussdbConnectionModeMJdbcHint: "Использует jdbc:gaussdb с com.huawei.gaussdb.jdbc.Driver для режима GaussDB M.", + gaussdbMJdbcDriver: "JDBC-драйвер GaussDB", + gaussdbMJdbcDriverPlaceholder: "Выберите gaussdbjdbc.jar, соответствующий версии сервера", + gaussdbMJdbcDriverHint: "Драйвер выпускается для каждой версии сервера GaussDB. Получите gaussdbjdbc.jar из соответствующего пакета драйверов GaussDB.", + gaussdbMJdbcDriverRequired: "Для режима GaussDB M требуется JDBC-драйвер производителя. Выберите gaussdbjdbc.jar, соответствующий версии сервера.", + gaussdbMJdbcPluginInstalling: "Установка среды выполнения JDBC...", + gaussdbIdentifierQuoteStyle: "Совместимость идентификаторов", + gaussdbIdentifierQuoteAuto: "Авто (драйвер/по умолчанию)", + gaussdbIdentifierQuoteDouble: 'Oracle/PostgreSQL (двойные кавычки ")', + gaussdbIdentifierQuoteBacktick: "MySQL/M (обратные кавычки `)", + gaussdbIdentifierQuoteHint: "Авто использует метаданные JDBC-драйвера или значение GaussDB по умолчанию. Выбирайте режим вручную только если генерируемый SQL использует неверные кавычки идентификаторов.", + gaussdbTargetServerType: "Тип целевого сервера", + gaussdbTargetServerTypeMaster: "Master (основной)", + gaussdbTargetServerTypeSlave: "Slave (резервный)", + gaussdbTargetServerTypeAny: "Любой (без предпочтений)", + gaussdbTargetServerTypeHint: "Управляет тем, к какому узлу кластера GaussDB подключается JDBC-драйвер. Master пробует основной, slave — резервный, any подключается к доступному. Применяется только в режиме M (JDBC).", + gaussdbCountQueryDop: "Параллелизм COUNT(*)", + gaussdbCountQueryDopHint: "Задаёт query_dop (степень параллелизма) для запросов COUNT(*) на больших таблицах. Большие значения используют больше ресурсов. Установите 1 (по умолчанию), чтобы отключить подсказку оптимизатору.", + saveAndConnect: "Сохранить и подключиться", + save: "Сохранить", + editTitle: "Изменить подключение", + testSuccess: "Подключение выполнено", + databaseInfo: { + title: "Сведения о базе данных", + open: "Открыть сведения о базе данных {database}", + copy: "Копировать сведения о базе данных", + sourceConfigured: "Текущая конфигурация", + sourceTested: "Проверено", + configuredDescription: "Сначала показывает сведения, известные из формы. Успешная проверка добавляет версию сервера и метаданные драйвера.", + testedDescription: "Эти сведения получены из подключения, использованного при последней успешной проверке.", + productName: "СУБД", + productVersion: "Версия сервера", + currentDatabase: "Текущая база данных", + serverComment: "Комментарий сервера", + serverCharset: "Кодировка сервера", + serverCollation: "Сортировка сервера", + unquotedIdentifierCase: "Идентификаторы без кавычек", + quotedIdentifierCase: "Идентификаторы в кавычках", + driverName: "Драйвер", + driverVersion: "Версия драйвера", + jdbcVersion: "Версия JDBC", + identifierCase: { + lower: "Нижний регистр", + upper: "Верхний регистр", + mixed: "Смешанный регистр", + }, + }, + connecting: "Подключение к {name}...", + connectSuccess: "Подключено к {name}", + connectFailed: "Не удалось подключиться: {message}", + objectCacheRefreshFailed: "Не удалось обновить кэш объектов: {message}", + driverNotInstalled: "Драйвер {driver} не установлен. Установите его в менеджере драйверов.", + phoenixDriverNotInstalled: "JDBC-драйвер Apache Phoenix не установлен. Установите его в менеджере драйверов и повторите попытку.", + jreNotInstalled: "Среда выполнения JRE {jre} не установлена. Установите её в менеджере драйверов.", + systemJavaNotFound: "Системная среда выполнения Java не найдена в JAVA_HOME или PATH. Установите Java или выберите собственный исполняемый файл Java.", + customJavaPathEmpty: "Путь к собственной среде выполнения Java пуст. Выберите исполняемый файл Java.", + agentJavaTooOld: "Для этого драйвера требуется Java 21. Используйте управляемую DBX JRE 21 или выберите исполняемый файл Java 21 в менеджере драйверов.", + agentDriverUpdateConnectionHint: "Для этого подключения доступно обновление встроенного драйвера. Сбой подключения может быть связан с устаревшим локальным драйвером. Обновите соответствующий драйвер в менеджере драйверов и повторите попытку.", + jdbcPluginNotInstalled: "Плагин JDBC не установлен. Установите дополнительный плагин JDBC, чтобы использовать это подключение.", + connectFailedTitle: "Не удалось подключиться", + fullErrorMessage: "Полный текст ошибки", + copyError: "Копировать ошибку", + optionalSuffix: " (необязательно)", + customColorPlaceholder: "#ff0000 или rgba(…)", + tursoHostPlaceholder: "your-database.turso.io или libsql://your-database.turso.io", + tursoHostHint: "Поддерживаются протоколы libsql:// и https://. Можно также ввести только имя хоста (HTTPS используется автоматически).", + tursoTokenHint: "Создайте токен командой:", + tursoUrlParamsPlaceholder: "authToken=xxx (необязательно; поле Auth Token выше имеет приоритет)", + driverInstall: { + installingTitle: "Установка драйвера", + failedTitle: "Не удалось установить драйвер", + fullError: "Полная ошибка", + statusFailed: "Установка не удалась", + statusWaiting: "Ожидание установки", + statusPreparing: "Подготовка установки драйвера...", + statusExtractingJre: "Распаковка JRE...", + stepJre: "Загрузка JRE", + stepDriver: "Загрузка драйвера", + stepDefault: "Установка драйвера", + installingButton: "Установка...", + }, + lastError: "Ошибка подключения", + errorIndicatorHint: "Ошибка подключения. Нажмите, чтобы посмотреть подробности", + clearError: "Очистить ошибку подключения", + saveFailed: "Не удалось сохранить подключение: {message}", + savedSettingsFailed: "Подключение сохранено, но не удалось сохранить настройку отображения: {message}. Повторите сохранение настройки.", + deleted: "Подключение удалено", + deletedSelected: "Удалено подключений: {count}", + copied: "Скопировано", + disconnected: "Отключено", + disconnectedSelected: "Отключено подключений: {count}", + disconnectSelectedPartial: "Отключено подключений: {succeeded}; не удалось: {failed}", + databaseConnectionClosed: "Закрыто подключение к базе данных: {name}", + duplicated: "Подключение дублировано", + duplicatedSelected: "Дублировано подключений: {count}", + groupDeleted: "Группа удалена", + groupsDeleted: "Удалено групп: {count}", + loadFailed: "Не удалось загрузить сохранённые подключения: {message}", + sshTunnel: "Туннель / Прокси", + sshTunnelTest: "Проверить SSH-туннель", + sshTunnelTesting: "Проверка SSH-туннеля...", + sshTunnelTestSuccess: "Подключение через SSH-туннель выполнено", + advancedTab: "Дополнительно", + sshEnable: "Использовать туннель / прокси", + sshHost: "Хост SSH", + sshHostPlaceholder: "ssh.example.com или псевдоним из ~/.ssh/config", + sshUser: "Пользователь SSH", + sshAuthMethod: "Способ входа", + sshAuthMethodPassword: "Пароль", + sshAuthMethodKey: "Закрытый ключ", + sshAuthMethodKeyPassword: "Закрытый ключ + пароль", + sshAuthMethodNone: "Нет", + sshAuthMethodNoneHint: "Учётные данные не отправляются. Используйте для бастионов или прокси, принимающих подключения без аутентификации.", + sshAuthMethodAgentLegacy: "SSH Agent (устаревший)", + sshPassword: "Пароль SSH", + sshPasswordPlaceholder: "Оставьте пустым, чтобы использовать ключ", + sshKeyPath: "Путь к ключу", + sshKeyPassphrase: "Парольная фраза ключа", + sshKeyPassphrasePlaceholder: "Оставьте пустым, если ключ не зашифрован", + sshKeyPathBrowse: "Обзор", + sshExposeLan: "Открыть туннель для локальной сети", + sshAllowExecChannelProxy: "Включить резервный вариант SSH exec-channel (nc)", + sshConnectTimeout: "Тайм-аут SSH (секунды)", + sshHops: "Слои туннеля / прокси", + sshHopAdd: "Добавить слой SSH", + sshHopDuplicate: "Дублировать", + sshHopDelete: "Удалить", + sshHopMoveUp: "Переместить вверх", + sshHopMoveDown: "Переместить вниз", + sshHopName: "Имя слоя", + sshHopNamePlaceholder: "Бастион, промежуточный хост, продакшен-шлюз", + sshHopDefaultName: "Слой {index}", + sshHopInvalidHost: "{hop}: укажите хост SSH", + sshHopInvalidUser: "{hop}: укажите пользователя SSH", + sshHopInvalidPort: "{hop}: порт SSH должен быть от 1 до 65535", + sshHopInvalidAuth: "{hop}: требуются пароль, путь к ключу или ssh-agent", + sshUseAgent: "Использовать ssh-agent", + sshAgentSockPath: "Путь к сокету агента", + sshAgentSockPathPlaceholder: "например, ~/.ssh/agent.sock", + sshHostKeyVerifyTitle: "Подтвердите неизвестный ключ хоста SSH", + sshHostKeyVerifyMessage: "Не удалось установить подлинность хоста «{host}:{port}». Чтобы защититься от атак «человек посередине», проверьте отпечаток ключа хоста у администратора сервера, прежде чем продолжать.", + sshHostKeyVerifyKeyType: "Тип ключа", + sshHostKeyVerifyFingerprint: "Отпечаток", + sshHostKeyVerifyRemember: "Доверять этому хосту (запомнить этот ключ для будущих подключений)", + sshHostKeyVerifyAccept: "Принять и подключиться", + sshHostKeyVerifyReject: "Отмена", + sshHostKeyChangedTitle: "Отпечаток хоста изменился", + sshHostKeyChangedMessage: "Сохранённый отпечаток для {host} не совпадает с текущим сервером.", + sshHostKeyChangedCurrent: "Отпечаток {keyType} — SHA256:", + sshHostKeyChangedSaved: "Сохранённый отпечаток", + sshHostKeyChangedWarning: "Продолжайте, только если уверены, что этот хост действительно изменился.", + sshHostKeyChangedClose: "Закрыть", + sshHostKeyChangedContinue: "Продолжить", + sshHostKeyChangedUpdate: "Обновить и продолжить", + sshInteractiveTitle: "Требуется проверка SSH", + sshInteractiveMessage: "SSH-сервер {host}:{port} требует дополнительной проверки.", + sshInteractiveDefaultPrompt: "Введите запрошенный ответ для проверки.", + sshInteractivePlaceholder: "Введите код подтверждения", + sshInteractiveSubmit: "Проверить", + sshInteractiveCancel: "Отмена", + sshPluginInputTitle: "Требуется ввод", + sshPluginInputMessage: "{source} требует ввода, прежде чем продолжить.", + sshPluginInputMessageNoSource: "Плагину требуется ввод, прежде чем продолжить.", + sshPluginInputSubmit: "Отправить", + sshHostKeyNoticeChanged: "Ключ хоста {host}:{port} изменился — это может указывать на атаку «человек посередине». Удалите старую запись и подключитесь заново, только если ожидаете это изменение.", + sshHostKeyNoticeRejected: "Вы отклонили ключ хоста {host}:{port}; подключение прервано, учётные данные не отправлены.", + sshHostKeyNoticeLearnFailed: "Не удалось сохранить ключ хоста {host}:{port} — хост считается доверенным только для этого сеанса, и при следующем подключении потребуется повторная проверка.", + sshHostKeyNoticeGeneric: "Не удалось проверить ключ хоста SSH для {host}:{port}.", + sqliteTransportSshOnly: "Удалённый SQLite поддерживает только переходы SSH. Слои прокси и HTTP-туннеля использовать нельзя.", + sqliteRemotePathPlaceholder: "/var/lib/app/data.db", + sqliteRemotePathHint: "Введите абсолютный путь на последнем переходе SSH.", + sqliteSshCipherUnsupportedHint: "Зашифрованные базы данных SQLite (SQLCipher) пока не поддерживаются через SSH.", + sqliteWorkerPlacement: "Воркер SQLite", + sqliteWorkerPlacementSession: "Сеанс", + sqliteWorkerPlacementPersist: "Постоянно", + sqliteWorkerPlacementPreplaced: "Размещён заранее", + sqliteWorkerPlacementSessionHint: "DBX загружает воркер по SSH на хост с файлами, а затем удаляет удалённый файл при отключении. Подходит для временного использования.", + sqliteWorkerPlacementPersistHint: "DBX загружает воркер по SSH на хост с файлами и оставляет его там после отключения. Он не удаляется автоматически.", + sqliteWorkerPlacementPreplacedHint: "Загрузите воркер на хост с файлами самостоятельно, затем укажите абсолютный путь к файлу. DBX не будет загружать или удалять его автоматически, но проверит, что файл соответствует этой версии Desktop.", + sqliteWorkerPlacementDefault: "По умолчанию", + sqliteWorkerPersistPathPlaceholder: "~/.cache/dbx/sqlite-worker/", + sqliteWorkerPreplacedPathPlaceholder: "/opt/dbx/dbx-sqlite-worker", + sshWorkerUploadConsentTitle: "Загрузить воркер SQLite", + sshWorkerUploadConsentMessage: "DBX необходимо скопировать недолговечный воркер SQLite на {host}:{port}. Это привилегированное действие. Проверьте путь назначения и дайджест, прежде чем разрешить загрузку.", + sshWorkerUploadConsentPath: "Путь назначения", + sshWorkerUploadConsentDigest: "Дайджест воркера", + sshWorkerUploadConsentRemember: "Запомнить этот хост с файлами и дайджест", + sshWorkerUploadConsentAccept: "Загрузить", + sshWorkerUploadConsentReject: "Отмена", + sshHopInvalidTimeout: "{hop}: тайм-аут SSH должен быть от 1 до 300 секунд", + connectTimeout: "Тайм-аут подключения (секунды)", + queryTimeout: "Тайм-аут запроса (секунды)", + useGlobalQueryTimeout: "Глобальный", + globalConnectTimeoutHint: "Диапазон: от 1 до 300 секунд", + globalQueryTimeoutHint: "Диапазон: от 0 до 3600 секунд. Установите 0, чтобы отключить тайм-аут.", + useConnectionQueryTimeout: "Подключение", + idleTimeout: "Тайм-аут простоя (секунды)", + keepaliveInterval: "Интервал keepalive (секунды)", + readOnly: "Только чтение", + readOnlyHint: "Блокировать все операции записи (INSERT, UPDATE, DELETE и т. д.)", + doltShowSystemTables: "Показывать системные таблицы Dolt", + doltShowSystemTablesHint: "Показывать встроенные таблицы контроля версий Dolt в списках таблиц для этого подключения.", + showSystemSchemas: "Показывать системные схемы", + showSystemSchemasHint: "Показывать встроенные схемы и схемы метаданных на боковой панели и в выборе схем для этого подключения.", + docsNotesPath: "Файл заметок", + docsNotesPathPlaceholder: "docs/dbx-docs.json", + docsNotesPathHint: "Где хранятся заметки документации. Оставьте пустым, чтобы хранить их в каталоге данных приложения, или укажите файл в вашем репозитории, чтобы просматривать документацию схемы в pull request.", + readOnlyBadge: "Только чтение", + proxy: "Прокси", + proxyEnable: "Подключаться к базе данных через прокси", + proxyType: "Тип прокси", + proxyHost: "Хост прокси", + proxyUsername: "Пользователь прокси", + proxyUsernamePlaceholder: "Необязательно", + proxyPassword: "Пароль прокси", + proxyPasswordPlaceholder: "Необязательно", + proxyTestTarget: "Цель проверки", + proxyTestTargetPlaceholder: "host:port — пусто = проверка конечной точки, заполните для полной проверки туннеля", + tunnelProfile: "Профиль туннеля", + tunnelProfileCustom: "Собственный (только для этого подключения)", + tunnelProfileManaged: "Управляется общим профилем туннеля. Измените его в разделе «Настройки > Туннели» — изменения применятся ко всем использующим его подключениям при следующем подключении.", + tunnelProfileMissing: "Указанный профиль туннеля больше не существует. Выберите другой профиль или переключитесь на собственный.", + tunnelProfileMissingName: "Отсутствует профиль туннеля", + tunnelProfileManage: "Управление", + httpTunnel: "HTTP-туннель", + httpTunnelAdd: "Добавить HTTP-туннель", + httpTunnelUrl: "URL скрипта туннеля", + httpTunnelToken: "Токен туннеля", + httpTunnelTokenPlaceholder: "Токен, настроенный в dbx_tunnel.php", + httpTunnelConnectTimeout: "Тайм-аут туннеля (секунды)", + httpTunnelDefaultName: "HTTP-туннель {index}", + httpTunnelInvalidOrder: "{hop}: HTTP-туннель должен быть первым слоем туннеля / прокси", + httpTunnelInvalidUrl: "{hop}: укажите URL скрипта туннеля", + httpTunnelInvalidTimeout: "{hop}: тайм-аут HTTP-туннеля должен быть от 1 до 300 секунд", + dremioArrowFlightSqlMode: "Arrow Flight SQL", + dremioLegacyJdbcMode: "Устаревший JDBC", + phoenixDirectMode: "Прямое", + phoenixRuntimeOption: "Apache Phoenix JDBC ({mode})", + phoenixQueryServerMode: "Сервер запросов", + phoenixDirectModeHint: "Подключается напрямую к HBase. Среда выполнения по умолчанию рассчитана на Phoenix 5.2.1 с HBase 2.5; для других версий кластера выберите совместимый клиент Phoenix и при необходимости добавьте hbase-site.xml.", + phoenixQueryServerModeHint: "Подключается по HTTP через отдельно развёрнутый Phoenix Query Server (PQS) с использованием тонкого клиента Phoenix.", + phoenixDriverManagerHintPrefix: "Установите или удалите среду выполнения по умолчанию в ", + phoenixDriverManagerHintSuffix: ". Вручную выбранные пути к совместимым драйверам имеют приоритет.", + phoenixDocs: "Открыть документацию Phoenix", + jdbcUrl: "JDBC URL", + jdbcUrlPlaceholder: "jdbc:postgresql://localhost:5432/database", + jdbcDriverClass: "Класс драйвера (необязательно)", + jdbcDriverClassPlaceholder: "Большинство драйверов регистрируются автоматически; при необходимости используйте com.vendor.jdbc.Driver", + jdbcDriverPaths: "JAR-файлы драйверов", + jdbcDriverSelectPlaceholder: "Выбрать импортированный драйвер", + jdbcManualClasspath: "Ручной classpath", + jdbcManualClasspathCount: "Путей: {count}", + jdbcDriverPathsPlaceholder: "/path/to/driver.jar\n/path/to/another-driver.jar", + jdbcDriverBrowse: "Выбрать JAR-файл драйвера JDBC", + jdbcDocs: "Открыть документацию JDBC", + jdbcPluginHint: "Сначала установите плагин DBX JDBC. Для драйверов с внешними зависимостями установите их из Maven в менеджере драйверов или импортируйте драйвер и все зависимые JAR-файлы вместе.", + jdbcMissingRuntimeDependencyHint: "В этом JDBC-драйвере отсутствуют зависимости среды выполнения. Установите его из Maven в менеджере драйверов или импортируйте драйвер и все зависимые JAR-файлы вместе.", + jdbcxExtensions: "Расширения JDBCX", + jdbcxHighPrivilegeExtensions: "Разрешить расширения с высокими привилегиями", + jdbcxHighPrivilegeExtensionsWarning: "Отключено по умолчанию. Включение разрешает расширениям Shell, Script, Web, MCP и другим выполнять локальные команды или обращаться к сети.", + dmCompatHint: "Требуется установленный в системе драйвер DM8 ODBC.", + dmDownload: "Скачать с сайта Dameng", + mongoLegacyHint: "Используйте Legacy для старых серверов MongoDB, особенно версий ниже 4.2. Если аутентификация не удаётся и пользователь создан в admin, установите Auth DB в admin.", + mongoTlsAllowInvalidCertificates: "Отключить проверку TLS-сертификата", + mongoTlsAllowInvalidCertificatesHint: "Соответствует tlsAllowInvalidCertificates=true и отключает всю проверку сертификатов, а не только проверку имени хоста. Это повышает риск MITM. Часто требуется для AWS DocumentDB через SSH-туннель.", + mongoRetryWrites: "Повторять записи", + mongoRetryWritesHint: "Соответствует retryWrites. Отключите для AWS DocumentDB, который не поддерживает повторяемые записи.", + compatible: "Совместимые", + mainstream: "Популярные", + color: "Цвет", + colorNone: "Без цвета", + colorGreen: "Зелёный", + colorYellow: "Жёлтый", + colorOrange: "Оранжевый", + colorRed: "Красный", + colorBlue: "Синий", + colorPurple: "Фиолетовый", + colorCustom: "Свой цвет", + cancelConnecting: "Отменить подключение", + connectCancelled: "Подключение отменено", + sshTotpCancelled: "Ввод одноразового кода отменён", + }, + editor: { + duckdbDraining: "Предыдущий запрос DuckDB ещё завершается. Повторите попытку чуть позже.", + statementExecutionRunning: "{count} инструкция выполняется | Выполняется инструкций: {count}", + statementExecutionSucceeded: "{count} инструкция выполнена | Выполнено инструкций: {count}", + statementExecutionFailed: "{count} инструкция завершилась с ошибкой | Завершилось с ошибкой инструкций: {count}", + pressToExecute: "Нажмите {mod}+Enter для выполнения", + pressToSaveSql: "Нажмите {mod}+S для сохранения SQL", + queryTimeoutError: "Время запроса истекло ({seconds} с). Проверьте работоспособность подключения к базе данных.", + changeConnectionTimeout: "Изменить тайм-аут подключения", + changeQueryTimeout: "Изменить тайм-аут запроса", + locateError: "Перейти к ошибке (строка {line}, столбец {column})", + errorPositionUnavailable: "Позиция ошибки больше не соответствует содержимому редактора, поэтому перейти к ней нельзя.", + connectionMayBeLost: "Возможно, подключение было потеряно. Обновите данные и повторите попытку.", + showResultsPane: "Показать результаты", + hideResultsPane: "Скрыть результаты", + noDatabase: "База данных не выбрана", + connectionOnlyTarget: "Цель уровня подключения", + unsavedChangesTitle: "Несохранённые изменения", + unsavedChangesMessage: "В «{title}» есть несохранённые изменения, которые будут потеряны при закрытии. Сохранить перед закрытием?", + unsavedChangesBatchCloseMessage: "В некоторых закрываемых вкладках есть несохранённые изменения, которые будут потеряны. Сохранить перед продолжением?", + unsavedChangesBatchCloseMultipleMessage: "В {count} закрываемых вкладках SQL есть несохранённые изменения. Сейчас DBX показывает «{title}». Сохранить перед продолжением?", + unsavedChangesAppCloseMessage: "В «{title}» есть несохранённые изменения SQL, которые будут потеряны при выходе из DBX. Сохранить перед выходом?", + unsavedChangesAppCloseMultipleMessage: "В {count} вкладках SQL есть несохранённые изменения. Сейчас DBX показывает «{title}». Сохранить перед выходом?", + unsavedChangesViewList: "Показать вкладки ({count})", + unsavedChangesListTitle: "Несохранённые вкладки ({count})", + discardChanges: "Отменить", + discardAllChanges: "Отменить все", + saveAllChanges: "Сохранить все", + selectConnection: "Выбрать подключение", + searchConnection: "Поиск подключений...", + selectCatalog: "Выбрать каталог", + searchCatalog: "Поиск каталогов...", + selectDatabase: "Выбрать базу данных", + selectDatabaseRequired: "Сначала выберите базу данных", + searchDatabase: "Поиск баз данных...", + selectSchema: "Выбрать схему", + searchSchema: "Поиск схем...", + setDefaultDatabase: "Сделать по умолчанию", + defaultDatabase: "По умолчанию", + defaultSchema: "По умолчанию", + clearDatabase: "Очистить базу данных", + exPasteNoValues: "В буфере обмена нет значений для условия IN", + exPasteNotList: "Преобразуемый многозначный список не обнаружен", + exPasteTooLarge: "Содержимое буфера обмена слишком велико. Максимальная поддерживаемая длина — {limit} символов.", + exPasteTooManyValues: "Слишком много значений. Максимальное поддерживаемое количество — {limit}.", + exPasteClipboardReadFailed: "Не удалось прочитать буфер обмена: {message}", + exPastePasted: "Вставлено значений условия IN: {count}", + completion: { + nullValue: "Значение NULL", + isNull: "Проверить на NULL", + isNotNull: "Проверить, что не NULL", + stringLiteral: "Строковый литерал", + numericLiteral: "Числовой литерал", + booleanValue: "Логическое значение", + starExpansionColumns: "{count} столбцов", + insertSelectedColumns: "Вставить выбранные столбцы ({count})", + insertSelectedColumnsDetail: "Отметьте столбцы флажками и вставьте их вместе", + selectAllColumns: "Выбрать все столбцы", + selectAllColumnsDetail: "Отметить все поля сразу", + deselectAllColumns: "Снять выделение со всех", + selectColumnsBeforeInsert: "Сначала выберите хотя бы один столбец", + tableAlias: "Псевдоним таблицы", + functionDescriptions: { + COUNT: "Возвращает количество строк", + SUM: "Возвращает сумму числового столбца", + AVG: "Возвращает среднее по числовому столбцу", + MIN: "Возвращает минимальное значение", + MAX: "Возвращает максимальное значение", + GROUP_CONCAT: "Объединяет значения группы в строку", + STRING_AGG: "Объединяет строки группы", + CONCAT: "Объединяет несколько строк", + CONCAT_WS: "Объединяет строки с разделителем", + SUBSTRING: "Извлекает подстроку", + REPLACE: "Заменяет фрагмент строки", + TRIM: "Удаляет начальные и конечные пробелы", + UPPER: "Преобразует в верхний регистр", + LOWER: "Преобразует в нижний регистр", + LENGTH: "Возвращает длину строки", + REGEXP_REPLACE: "Заменяет с помощью регулярного выражения", + DATE_FORMAT: "Форматирует дату по заданному формату", + DATEDIFF: "Вычисляет разницу между двумя датами", + DATE_ADD: "Прибавляет интервал к дате", + DATE_SUB: "Вычитает интервал из даты", + EXTRACT: "Извлекает часть даты", + NOW: "Возвращает текущие дату и время", + CURRENT_DATE: "Возвращает текущую дату", + CURRENT_TIME: "Возвращает текущее время", + CURRENT_TIMESTAMP: "Возвращает текущие дату и время", + CURDATE: "Возвращает текущую дату", + CURTIME: "Возвращает текущее время", + LOCALTIME: "Возвращает текущее местное время", + LOCALTIMESTAMP: "Возвращает текущие местные дату и время", + UTC_DATE: "Возвращает текущую дату UTC", + UTC_TIME: "Возвращает текущее время UTC", + UTC_TIMESTAMP: "Возвращает текущие дату и время UTC", + SYSDATE: "Возвращает текущие дату и время", + DATE: "Извлекает часть с датой", + TIME: "Извлекает часть со временем", + TIMESTAMPDIFF: "Возвращает разницу между двумя датами и временем", + YEAR: "Извлекает год", + MONTH: "Извлекает месяц", + DAY: "Извлекает день", + HOUR: "Извлекает часы", + MINUTE: "Извлекает минуты", + SECOND: "Извлекает секунды", + DAYOFWEEK: "Возвращает индекс дня недели", + DAYOFYEAR: "Возвращает день года", + LAST_DAY: "Возвращает последний день месяца", + STR_TO_DATE: "Преобразует строку в дату", + IF: "Возвращает значение в зависимости от условия", + LEFT: "Возвращает крайние левые символы", + RIGHT: "Возвращает крайние правые символы", + SUBSTRING_INDEX: "Возвращает подстроку до разделителя с указанным номером", + CHAR_LENGTH: "Возвращает длину в символах", + INSTR: "Возвращает позицию подстроки", + LOCATE: "Возвращает позицию подстроки", + LPAD: "Дополняет строку слева до нужной длины", + RPAD: "Дополняет строку справа до нужной длины", + FIND_IN_SET: "Возвращает индекс в списке с разделителями-запятыми", + RAND: "Возвращает случайное число с плавающей точкой", + MD5: "Возвращает хеш MD5", + SHA1: "Возвращает хеш SHA1", + SHA2: "Возвращает хеш SHA2", + ROUND: "Округляет до указанного числа знаков после запятой", + FLOOR: "Округляет вниз", + CEIL: "Округляет вверх", + ABS: "Возвращает абсолютное значение", + MOD: "Возвращает остаток от деления", + COALESCE: "Возвращает первый аргумент, не равный NULL", + IFNULL: "Возвращает значение замены, если NULL", + NULLIF: "Возвращает NULL, если аргументы равны", + CAST: "Преобразует выражение к целевому типу", + JSON_EXTRACT: "Извлекает значение из JSON", + JSON_VALUE: "Извлекает скалярное значение из JSON", + JSON_OBJECT: "Создаёт объект JSON", + JSON_ARRAY: "Создаёт массив JSON", + }, + }, + previewChanges: "Предпросмотр изменений", + previewChangesComment: "Предпросмотр изменений (пробный запуск) для оператора {operation}", + previewChangesFailed: "Не удалось выполнить предпросмотр изменений.", + previewChangesNoStatement: "Выделите оператор UPDATE / INSERT / DELETE или установите на него курсор, чтобы увидеть предпросмотр изменений.", + contextMenu: { + executeSelection: "Выполнить выделенное", + executeCurrent: "Выполнить SQL", + export: "Экспорт", + exportQueryResultTo: "Экспортировать текущий результат запроса в {format}", + copySelection: "Копировать выделенное", + copySelectionAsRichText: "Копировать как форматированный текст", + screenshotSelection: "Снимок выделенного кода", + commentSelection: "Закомментировать выделенное", + blockCommentSelection: "Блочный комментарий выделенного", + formatSelectionSql: "Форматировать выделенный SQL", + compressSelectionSql: "Сжать выделенный SQL", + cutSelection: "Вырезать выделенное", + pasteFromClipboard: "Вставить", + pasteClipboardReadFailed: "Не удалось прочитать буфер обмена: {message}", + sendToAi: "Отправить в AI", + uppercaseSelection: "Преобразовать в верхний регистр", + lowercaseSelection: "Преобразовать в нижний регистр", + convertNamingStyle: "Переключить стиль именования", + delimitedList: "Преобразовать в список с разделителями", + addNextSelectionOccurrence: "Добавить следующее вхождение", + selectAllSelectionOccurrences: "Выбрать все вхождения", + expandSelectStar: "Раскрыть * в столбцы", + expandSelectStarUnavailable: "Не удалось загрузить столбцы этой таблицы", + findReplace: "Найти/Заменить", + deleteEmptyLines: "Удалить пустые строки", + selectAll: "Выбрать всё", + }, + delimitedList: { + title: "Преобразовать в список с разделителями", + columnDelimiter: "Разделитель столбцов", + resultDelimiter: "Разделитель результата", + quoteChar: "Символ кавычки", + wrapColumn: "Перенос по столбцу", + prefixText: "Текст префикса", + suffixText: "Текст суффикса", + preview: "Предпросмотр", + emptyPreview: "Нечего показывать", + confirm: "Подтвердить", + selectFirst: "Выберите текст списка", + }, + structurePeek: { + title: "Структура: {name}", + hint: "Дважды щёлкните ячейку, чтобы вставить её значение в редактор", + doubleClickInsert: "Дважды щёлкните для вставки", + drag: "Перетащите, чтобы переместить", + empty: "Нет столбцов", + }, + gotoLine: { + placeholder: "Номер строки", + total: "{total} строк", + outOfRange: "Введите номер строки от 1 до {total}", + empty: "Введите номер строки", + }, + search: { + find: "Найти", + replace: "Заменить", + replaceAll: "Заменить всё", + caseSensitive: "Учитывать регистр", + regex: "Регулярное выражение", + collapseReplace: "Свернуть замену", + expandReplace: "Развернуть замену", + prevMatch: "Предыдущее (Shift+Enter)", + nextMatch: "Следующее (Enter)", + selectAll: "Выбрать все совпадения", + selectAllLimit: "Выбрать все совпадения (до {limit})", + selectionTruncated: "Найдено совпадений: {total}; выбраны первые {limit}.", + selectionLimitSummary: "Выбрано {limit}/{total}", + close: "Закрыть (Esc)", + noResults: "Нет результатов", + inSelection: "В выделенном", + }, + noExecutableStatementAtCursor: "В позиции курсора нет исполняемого оператора.", + executionPicker: { + title: "Цель выполнения", + currentStatement: "Текущий SQL", + allStatements: "Весь SQL", + currentCommand: "Текущая команда", + allCommands: "Все команды", + }, + }, + tabs: { + sql: "SQL", + emptyGroup: "Нет открытых вкладок", + table: "Таблица", + tableData: "Данные таблицы", + redis: "Redis", + etcd: "etcd", + etcdDashboard: "Панель etcd", + etcdAccessControl: "Управление доступом etcd", + nacosAccessControl: "Управление доступом Nacos", + zookeeper: "ZooKeeper", + consul: "Consul", + mongo: "Mongo", + gridfs: "GridFS", + vector: "Вектор", + databases: "Базы данных", + objects: "Объекты", + users: "Пользователи и привилегии", + executionSummary: "Сводка", + messages: "Сообщения", + tooltipTitle: "Заголовок:", + tooltipFilePath: "Путь к файлу:", + tooltipFileStatus: "Состояние файла:", + externalFileMissing: "Удалён или перемещён вне DBX", + tooltipConnection: "Подключение:", + tooltipGroup: "Группа:", + tooltipDatabase: "База данных:", + tooltipTable: "Таблица:", + tooltipTableComment: "Комментарий к таблице:", + tooltipCollection: "Коллекция:", + tooltipSchema: "Схема:", + resultN: "Результат {n}", + runN: "Запуск {n}", + resultRuns: "Запуски результатов", + resultSets: "Наборы результатов", + allResults: "Все результаты ({count})", + searchResults: "Поиск по номеру, имени или SQL", + noMatchingResults: "Нет подходящих результатов", + removeRun: "Удалить запуск {n}", + renameResultRun: "Переименовать вкладку результата", + resultRunName: "Имя вкладки результата", + pinResultRun: "Закрепить вкладку результата", + unpinResultRun: "Открепить вкладку результата", + unpinAllResultRuns: "Открепить все вкладки результатов", + closeOtherResultRuns: "Закрыть другие вкладки результатов", + closeResultRunsToLeft: "Закрыть вкладки результатов слева", + closeResultRunsToRight: "Закрыть вкладки результатов справа", + closeResult: "Закрыть результат", + autoKeepResults: "Автосохранение результатов запросов", + autoKeepResultsEnabled: "Автосохранение результатов включено", + autoKeepResultsDisabled: "Автосохранение результатов отключено", + autoRefresh: "Автообновление результатов", + autoRefreshShort: "Авто", + autoRefreshEvery: "Обновлять каждые {seconds} с", + startAutoRefresh: "Включить автообновление", + stopAutoRefresh: "Остановить автообновление", + missingResultRun: "Этот результат больше недоступен", + exportResultArchive: "Сохранить результаты", + importResultArchive: "Импорт архива результатов", + importedResultArchive: "Импортированные результаты", + resultArchiveExported: "Результаты экспортированы", + resultArchiveImported: "Результаты импортированы", + resultArchiveUnavailable: "Нет сохранённых результатов для экспорта", + resultArchiveImportInvalid: "Не удалось открыть этот архив результатов", + resultArchiveExportFailed: "Не удалось экспортировать результаты: {message}", + resultArchiveImportFailed: "Не удалось импортировать результаты: {message}", + scrollLeft: "Прокрутить вкладки влево", + scrollRight: "Прокрутить вкладки вправо", + openTabs: "Открытые вкладки", + openInNewWindow: "Открыть в новом окне", + returnToMainWindow: "Вернуться в главное окно", + dragBackToMain: "Перетащите этот маркер в главное окно", + detachedCloseTitle: "Закрыть отдельное окно", + detachedCloseMessage: "В этой вкладке SQL есть несохранённые изменения. Сохранить их перед закрытием и удалением отдельной вкладки?", + detachedTabUnavailable: "Отдельная вкладка больше недоступна.", + openInNewWindowFailed: "Не удалось открыть отдельное окно.", + minimizeWindow: "Свернуть", + maximizeWindow: "Развернуть", + closeWindow: "Закрыть", + searchOpenTabs: "Поиск по открытым вкладкам...", + collapseTabBar: "Свернуть панель вкладок", + expandTabBar: "Развернуть панель вкладок", + switcherTitle: "Переключение вкладок", + switcherHint: "удерживайте, чтобы перемещаться, отпустите для переключения", + noMatchingTabs: "Нет подходящих вкладок", + fixedTabs: "Закреплённые вкладки", + openDataTabs: "Открытые таблицы", + editGroupTitle: "Изменить группу: {name}", + groupName: "Имя группы", + groupColor: "Цвет группы", + groupColorAuto: "Использовать цвет по умолчанию", + groupColorCustom: "Выбрать свой цвет", + resetGroup: "Сбросить", + settingsSaveFailed: "Не удалось сохранить настройки вкладок: {message}", + }, + databaseBrowser: { + search: "Поиск баз данных...", + empty: "Базы данных не найдены", + loadFailed: "Не удалось загрузить базы данных: {message}", + defaultCharset: "Кодировка", + defaultCollation: "Сортировка", + }, + gridfsBrowser: { + bucketCount: "контейнеров", + fileCount: "файлов", + name: "Имя", + totalSize: "Размер", + chunkSize: "Размер блока", + uploadDate: "Дата загрузки", + contentType: "Тип содержимого", + metadata: "Метаданные", + selectBucket: "Выберите контейнер GridFS для просмотра или открытия.", + selectFile: "Выберите файл GridFS для просмотра или управления.", + emptyBuckets: "Контейнеры GridFS не найдены. Создайте контейнер, чтобы начать хранить файлы.", + emptyFiles: "В этом контейнере пока нет файлов. Загрузите файл, чтобы начать.", + createBucket: "Новый контейнер", + openBucket: "Открыть контейнер", + deleteBucket: "Удалить контейнер", + createTitle: "Создание контейнера GridFS", + deleteTitle: "Удаление контейнера GridFS", + deleteMessage: "Удалить выбранный контейнер GridFS и все файлы в нём?", + bucketName: "Имя контейнера", + bucketNamePlaceholder: "example_bucket", + bucketCreated: "Контейнер {bucket} создан.", + bucketDeleted: "Контейнер {bucket} удалён.", + uploadFile: "Загрузить файл", + downloadFile: "Скачать файл", + downloadSelected: "Скачать выбранное", + deleteFile: "Удалить файл", + selectedCount: "Выбрано: {count}", + deleteFileTitle: "Удаление файла GridFS", + deleteFileMessage: "Удалить выбранный файл из этого контейнера GridFS?", + fileUploaded: "Файл {fileName} загружен.", + fileDeleted: "Файл {fileName} удалён.", + }, + executionSummary: { + empty: "Нет сводки", + executing: "Выполняется...", + finished: "Выполнение завершено", + statement: "Оператор", + sql: "SQL", + status: "Состояние", + type: "Тип", + rows: "Строки", + affected: "Затронуто", + time: "Время", + success: "Успешно", + error: "Ошибка", + returnedTable: "Возвращена таблица результатов из {count} столбцов", + noTable: "Таблица результатов не возвращена", + noSql: "SQL недоступен", + lineColumn: "строка {line}, столбец {column}", + navigationHint: "Щёлкните строку, чтобы увидеть её SQL; дважды щёлкните, чтобы перейти к ней в редакторе.", + recoveryPrompt: "Оператор #{statement} завершился ошибкой; операторов не выполнено: {count}.", + stop: "Остановить", + retry: "Повторить", + skipAndContinue: "Пропустить и продолжить", + skipAll: "Пропускать все ошибки", + skipAllHint: "Продолжить и автоматически пропускать последующие ошибки в этом пакете", + statuses: { + pending: "Ожидает", + running: "Выполняется", + success: "Успешно", + error: "Ошибка", + skipped: "Не выполнено", + cancelled: "Отменено", + }, + }, + queryMessages: { + empty: "Нет сообщений", + code: "Код: {code}", + }, + chart: { + title: "Диаграмма", + type: "Тип", + line: "Линейная", + bar: "Столбчатая", + pie: "Круговая", + noNumericData: "Нет числовых данных для построения диаграммы", + }, + grid: { + rows: "Строк: {count}", + totalRows: "Всего строк: {count}", + loadedRows: "Загружено строк: {count}", + totalRowCount: "(всего {count})", + totalRowCountWithAction: "({button}всего {count})", + totalRowCountAtLeast: "(не менее {count} всего)", + totalRowCountEstimated: "(~{count})", + totalRowCountLoading: "(подсчёт...)", + loadingMore: "Загрузка дополнительных данных...", + pageJumpLoading: "Переход на страницу {page}", + pageJumpProgress: "Запросов выполнено {current}/{total}", + esDeepPageJumpConfirmTitle: "Подтвердите глубокий переход по страницам Elasticsearch", + esDeepPageJumpConfirmMessage: + "Elasticsearch search_after не может перейти сразу на нужную страницу. DBX должен последовательно получить пропущенные курсоры, а переход назад начинается со страницы 1. Переход на страницу {page} потребует примерно {requests} запросов. Это может занять много времени и увеличить нагрузку на кластер. Продолжить?", + esDeepPageJumpContinue: "Продолжить", + allLoaded: "загружено всё", + calculateTotalRows: "Подсчитать общее число строк", + calculateTotalRowsInline: "(подсчитать общее число строк)", + calculateTotalRowsFailed: "Не удалось подсчитать: {message}", + rowsAffected: "Затронуто строк: {count}", + agentExecuteTime: "Выполнение: {ms} мс", + serverExecuteTime: "Выполнение в БД: {us} мкс", + serverExecuteTimeUnavailable: "Выполнение в БД: недоступно", + serverExecuteTimeHint: + "OceanBase SQL Audit EXECUTE_TIME измеряет выполнение плана на сервере. Курсор JDBC показывает образец завершённого оператора; независимые запросы страниц показывают сумму только тогда, когда каждая страница попала в выборку. Эти данные пересекаются со временем выполнения и ожидания. Недоступно, пока курсор остаётся открытым или пока данные аудита нельзя прочитать или сопоставить.", + agentExecuteTimeHint: "Время агента от настройки схемы до выполнения JDBC. Не включает выборку строк; это не время выполнения на сервере БД.", + clientRequestWait: "Ожидание: {ms} мс", + clientRequestWaitHint: "Время настольного приложения от отправки запроса до получения полного ответа. Включает выборку, необязательный поиск в аудите сервера и передачу данных; не включает подготовку SQL и отрисовку таблицы. Суммируется по загруженным страницам.", + resultViewUpdate: "Обновление таблицы: {ms} мс", + resultViewUpdateHint: "Время от обнаружения результата таблицей до завершения обновления DOM или отправки отрисовки Canvas. Не включает композитинг GPU и вывод на экран.", + querySuccess: "Запрос выполнен успешно", + noRows: "Нет данных", + noRowsDescription: "В этом наборе результатов нет записей.", + noSearchResults: "Нет совпадений", + noSearchResultsDescription: "Попробуйте другое ключевое слово.", + noFilteredRows: "Нет строк, подходящих под фильтр", + noFilteredRowsDescription: "Измените текст поиска или фильтр по состоянию строк.", + copy: "Копировать", + copyExtractorSmart: "Умное копирование", + copyExtractorRaw: "Текст ячейки", + copyExtractorWithHeaders: "{format} с заголовками", + copyExtractorOneRow: "Одна строка", + copyExtractorJsonArray: "Массив JSON", + copyExtractorSqlInList: "Список SQL IN", + copyExtractorSqlInserts: "SQL INSERT", + copyExtractorSqlInsertsWithPrimaryKeys: "SQL INSERT (с первичными ключами)", + copyExtractorSqlInsertsWithoutPrimaryKeys: "SQL INSERT (без первичных ключей)", + copyExtractorSqlUpdates: "SQL UPDATE", + copyExtractorSqlSelect: "SQL SELECT", + copyExtractorWhereClause: "Условие WHERE", + copyExtractorPipeSeparated: "С разделителем-вертикальной чертой", + copyExtractorPretty: "Удобная таблица", + copyExtractorConfigure: "Настроить извлечение данных…", + copyExtractorDefaultFormat: "Поведение копирования по умолчанию", + copyExtractorFormat: "Извлечение", + copyExtractorColumnSeparator: "Разделитель столбцов", + copyExtractorRowSeparator: "Разделитель строк", + copyExtractorNullText: "Текст для NULL", + copyExtractorQuote: "Символ кавычки", + copyExtractorQuotePolicy: "Заключение в кавычки", + copyExtractorQuoteMinimal: "При необходимости", + copyExtractorQuoteAlways: "Всегда", + copyExtractorQuoteNever: "Никогда", + copyExtractorIncludeHeader: "Включить заголовок столбцов", + copyExtractorIncludeRowHeader: "Включить номера строк", + copyExtractorSkipComputed: "Пропускать вычисляемые столбцы", + copyExtractorSkipGenerated: "Пропускать генерируемые столбцы", + copyExtractorExcludePrimaryKeys: "Исключить первичные ключи", + copyExtractorIncludeDatabaseName: "Включить имя базы данных", + copyExtractorInsertMode: "Операторы INSERT", + copyExtractorInsertMerged: "Объединять строки", + copyExtractorInsertRowByRow: "По одному оператору на строку", + copyExtractorPrettyJson: "Форматировать JSON", + copyExtractorCamelCaseJsonFields: "Преобразовать поля snake_case в camelCase", + copyExtractorPreview: "Предпросмотр (текущее выделение)", + copyExtractorEmptySelection: "Выберите данные, чтобы увидеть результат извлечения.", + copyExtractorUnsupportedSelection: "Это извлечение требует одинакового набора столбцов в каждой строке.", + copyExtractorPreviewTruncated: "Показаны первые 100 строк из {count} выбранных.", + copyExtractorWarningOmittedColumns: "В скопированном результате пропущены столбцы: {columns}.", + copyExtractorWarningDuplicateJsonColumns: "Повторяющиеся имена столбцов JSON переименованы во избежание потери данных.", + copyExtractorValidation: { + "column-separator-empty": "Разделитель столбцов не может быть пустым.", + "row-separator-empty": "Разделитель строк не может быть пустым.", + "separator-too-long": "Разделители могут содержать не более 8 символов.", + "null-text-too-long": "Текст для NULL может содержать не более 64 символов.", + "separators-overlap": "Разделители столбцов и строк не должны совпадать.", + "invalid-quote": "Кавычка должна состоять ровно из одного символа.", + "quote-conflicts": "Кавычка не должна входить в разделитель столбцов или строк.", + }, + mongoJsonPreview: "Предпросмотр JSON", + mongoJsonPreviewEmpty: "Выберите документ MongoDB для предпросмотра.", + copyJson: "Копировать JSON", + copyDdl: "Копировать DDL", + hoverSearchPlaceholder: "Поиск столбцов…", + hoverSearchNoResult: "Нет подходящих столбцов", + copyCell: "Копировать ячейку", + copyRow: "Копировать всю строку (объект JSON)", + copyColumnJson: "Копировать столбец (JSON)", + copyColumnNames: "Копировать имена столбцов", + copyColumnNamesSelected: "Копировать имена выбранных столбцов ({count})", + copyColumnNamesTitle: "Копировать имена столбцов ({count})", + copyColumnNamesSeparator: "Разделитель столбцов", + copyColumnNamesQuote: "Заключать имена столбцов в кавычки", + copyColumnNamesShowComment: "Показывать по комментарию", + copyColumnNamesPreview: "Предпросмотр", + copyAll: "Копировать всё (TSV)", + selectionSum: "СУММА: {value}", + selectionAverage: "СРЕДНЕЕ: {value}", + selectionCells: "Ячеек: {count}", + clearSelection: "Снять выделение", + export: "Экспорт", + exportCsv: "Экспорт CSV", + exportXlsx: "Экспорт XLSX", + exportXlsxWithSql: "Экспорт XLSX с SQL", + exportCurrentPageCsv: "Экспорт текущей страницы в CSV", + exportCurrentPageXlsx: "Экспорт текущей страницы в XLSX", + exportCurrentPageXlsxWithSql: "Экспорт текущей страницы в XLSX с SQL", + exportCurrentPageJson: "Экспорт текущей страницы в JSON", + exportCurrentPageMarkdown: "Экспорт текущей страницы в Markdown", + exportCurrentPageHtml: "Экспорт текущей страницы в HTML", + exportCurrentPageSql: "Экспорт текущей страницы в SQL INSERT", + exportCurrentPageTxt: "Экспорт текущей страницы в TXT", + exportCurrentResultCsv: "Экспорт всех данных текущего набора результатов в CSV", + exportCurrentResultXlsx: "Экспорт всех данных текущего набора результатов в XLSX", + exportCurrentResultXlsxWithSql: "Экспорт всех данных текущего набора результатов в XLSX с SQL", + exportCurrentResultJson: "Экспорт всех данных текущего набора результатов в JSON", + exportCurrentResultMarkdown: "Экспорт всех данных текущего набора результатов в Markdown", + exportCurrentResultHtml: "Экспорт всех данных текущего набора результатов в HTML", + exportCurrentResultSql: "Экспорт всех данных текущего набора результатов в SQL INSERT", + exportCurrentResultTxt: "Экспорт всех данных текущего набора результатов в TXT", + exportAllResultsXlsx: "Экспорт всех наборов результатов этого запуска в XLSX", + exportAllResultsXlsxWithSql: "Экспорт всех наборов результатов этого запуска в XLSX с SQL", + exportJson: "Экспорт JSON", + exportMarkdown: "Экспорт Markdown", + exportHtml: "Экспорт HTML", + exportSql: "Экспорт SQL INSERT", + sqlInsertModeTitle: "Режим экспорта SQL INSERT", + sqlInsertModePrompt: "Выберите, как строки записываются в файл SQL INSERT:", + sqlInsertModeBatch: "Пакетное добавление", + sqlInsertModeBatchDescription: "Объединять несколько строк в один оператор INSERT — файлы меньше, выполнение быстрее.", + sqlInsertModeSingle: "Одна строка на оператор", + sqlInsertModeSingleDescription: "Записывать один полный оператор INSERT на строку — проще выполнять и отлаживать по отдельности.", + exportTxt: "Экспорт TXT", + exportSelectedRowsCsv: "Экспорт выбранных строк в CSV", + exportSelectedRowsXlsx: "Экспорт выбранных строк в XLSX", + exportSelectedRowsXlsxWithSql: "Экспорт выбранных строк в XLSX с SQL", + exportSelectedRowsJson: "Экспорт выбранных строк в JSON", + exportSelectedRowsMarkdown: "Экспорт выбранных строк в Markdown", + exportSelectedRowsHtml: "Экспорт выбранных строк в HTML", + exportSelectedRowsSql: "Экспорт выбранных строк в SQL INSERT", + exportSelectedRowsTxt: "Экспорт выбранных строк в TXT", + exported: "Экспортировано", + exportFailed: "Не удалось экспортировать: {message}", + xlsxHeaderTitle: "Формат заголовков", + xlsxExportTitle: "Параметры экспорта", + xlsxHeaderPrompt: "Выберите формат заголовков для экспортируемого файла Excel:", + xlsxHeaderOriginal: "Использовать имена столбцов как заголовки", + xlsxHeaderComment: "Использовать комментарии столбцов как заголовки", + xlsxHeaderNameAndComment: "Использовать имена и комментарии столбцов как заголовки", + xlsxFilterPrompt: "Выберите, включать ли фильтры в экспортируемый файл Excel:", + xlsxIncludeAutoFilter: "Включить фильтры", + copied: "Скопировано", + copyFailed: "Не удалось скопировать: {message}", + previewSqlEmpty: "Нет ожидающих изменений SQL для предпросмотра", + renderMode: "Режим отрисовки", + domRenderMode: "DOM", + canvasRenderMode: "Canvas", + renderModeHint: "Переключение между отрисовкой Canvas и резервной таблицей DOM.", + tableFontFamily: "Шрифт таблицы", + tableFontSize: "Размер шрифта таблицы", + filter: "Фильтр", + conditionHistoryEmpty: "История пока пуста", + conditionHistoryNoMatches: "Нет подходящей истории", + filterBuilder: "Фильтры", + filterBuilderTitle: "Фильтры", + filterBuilderHint: "Стройте условия нажатием мыши и объединяйте их с полем WHERE.", + filterView: "Вид фильтра", + filterQuickView: "Быстрый вид", + filterConditionView: "Вид условий", + filterTextView: "Текстовый вид", + resizeFilterPanel: "Изменить размер панели фильтра", + filterConditionPanel: "Условия фильтра", + filterManualWhere: "Ручной WHERE", + filterSqlPreview: "Предпросмотр условия SQL", + filterSqlPreviewEmpty: "Пока нет допустимого условия фильтра", + filterSqlPreviewReady: "Условие готово; примените для обновления результатов", + copyFilterSql: "Копировать условие SQL", + filterSqlCopied: "Условие SQL скопировано", + filterBuilderSummary: "{count} правил", + filterBuilderAddRule: "Добавить правило", + filterBuilderApplyOnly: "Фильтровать только по этому правилу", + filterBuilderCompleteRuleFirst: "Сначала заполните это правило фильтра", + filterBuilderEnableRule: "Включить правило", + filterBuilderDisableRule: "Отключить правило", + filterBuilderReorderRule: "Перетащите или используйте стрелки для изменения порядка условия", + filterBuilderColumn: "Столбец", + filterBuilderSearchColumns: "Поиск столбцов...", + filterBuilderNoMatchingColumns: "Нет подходящих столбцов", + filterBuilderValue: "Значение", + filterBuilderTextValue: "", + filterBuilderValueTypeAuto: "Авто", + filterBuilderValueTypeString: "Строка", + filterBuilderValueTypeNumber: "Число", + filterBuilderValueTypeBoolean: "Логический", + filterBuilderValueTypeObjectId: "ObjectId", + filterBuilderValueTypeDate: "Дата", + filterBuilderValueTypeInt32: "Int32", + filterBuilderValueTypeInt64: "Int64", + filterBuilderValueTypeDecimal128: "Decimal128", + filterBuilderValueTypeJson: "JSON", + filterBuilderValueShortcutHint: "Shift+Enter добавляет правило", + filterBuilderValues: "Значения (через запятую или с новой строки)", + filterBuilderRangeStart: "Начальное значение", + filterBuilderRangeEnd: "Конечное значение", + filterBuilderNoValue: "Значение не требуется", + filterBuilderEmpty: "Добавьте правило, чтобы начать фильтрацию строк.", + resetFilterBuilder: "Сбросить правила", + filterBuilderEquals: "Равно", + filterBuilderNotEquals: "Не равно", + filterBuilderContains: "Содержит", + filterBuilderNotContains: "Не содержит", + filterBuilderBeginsWith: "Начинается с", + filterBuilderEndsWith: "Заканчивается на", + filterBuilderGreaterThan: "Больше", + filterBuilderGreaterThanOrEqual: "Больше или равно", + filterBuilderLessThan: "Меньше", + filterBuilderLessThanOrEqual: "Меньше или равно", + filterBuilderIn: "В списке", + filterBuilderNotIn: "Не в списке", + filterBuilderBetween: "В диапазоне", + filterBuilderNotBetween: "Вне диапазона", + filterBuilderIsNull: "Равно NULL", + filterBuilderIsNotNull: "Не равно NULL", + filterBuilderIsBlank: "Пустое (NULL или пустая строка)", + filterBuilderIsNotBlank: "Не пустое (не NULL и не пустая строка)", + columnActions: "Действия со столбцом", + localFilter: "Локальный фильтр значений", + localFilterFor: "Локальные значения для «{column}»", + databaseValueFilter: "Фильтр значений базы данных", + databaseValueFilterFor: "Значения базы данных для «{column}»", + columnFormatter: "Форматирование столбца", + columnFormatterActive: "Форматированный вывод включён", + columnFormatterFor: "Форматирование для «{column}»", + columnFormatterHint: "Форматируется только отображение; исходные значения не меняются.", + formatterType: "Тип", + formatterDatetime: "Unix-временная метка", + formatterJsonPath: "Путь JSON", + formatterMask: "Маскировать текст", + formatterForeignKeyDisplay: "Метка внешнего ключа", + formatterForeignKeyTarget: "Ссылочный ключ", + formatterForeignKeyManualHint: "У этого столбца нет внешнего ключа из одного столбца. Выберите ссылочную таблицу и соответствующий столбец вручную.", + formatterForeignKeySchema: "Схема", + formatterForeignKeySchemaPlaceholder: "Выберите схему", + formatterForeignKeySearchSchema: "Поиск схем...", + formatterForeignKeyNoSchemas: "Схемы недоступны", + formatterForeignKeyTable: "Ссылочная таблица", + formatterForeignKeyTablePlaceholder: "Выберите ссылочную таблицу", + formatterForeignKeySearchTable: "Поиск ссылочных таблиц...", + formatterForeignKeyNoTables: "Ссылочные таблицы недоступны", + formatterForeignKeyReferenceColumn: "Соответствующий столбец", + formatterForeignKeyReferenceColumnPlaceholder: "Выберите столбец, соответствующий этому значению", + formatterForeignKeyReferenceMetadataUnavailable: "Не удалось проверить уникальность соответствующего столбца: {error}", + formatterForeignKeyReferenceInvalid: "Этот столбец отсутствует или его уникальность не гарантируется уникальным ключом и текущим фильтром равенства. Выберите другой столбец.", + formatterForeignKeyReferenceUnavailable: "У целевой таблицы нет пригодного уникального ключа. Для составного уникального ключа зафиксируйте другой столбец фильтром равенства.", + formatterForeignKeyDisplayColumn: "Отображаемый столбец", + formatterForeignKeyDisplayColumnPlaceholder: "Выберите отображаемый столбец", + formatterForeignKeyFilter: "Ограничить ссылочные строки", + formatterForeignKeyFilterColumnPlaceholder: "Выберите столбец фильтра", + formatterForeignKeyHint: "Загружает метки для совпадающих ключей на текущей странице. Редактирование, фильтрация, сортировка, копирование и экспорт по-прежнему используют исходные значения.", + formatterCustomTemplate: "Пользовательский шаблон", + formatterTimestampUnit: "Единица временной метки", + formatterUnitAuto: "Авто", + formatterUnitSeconds: "Секунды", + formatterUnitMilliseconds: "Миллисекунды", + formatterDatetimePattern: "Шаблон даты и времени", + formatterDatetimePatternPlaceholder: "Выберите или введите шаблон даты и времени", + formatterDatetimePatternEmpty: "Формат ISO8601 по умолчанию", + formatterDatetimeTimezone: "Часовой пояс", + formatterDatetimeTimezonePlaceholder: "Выберите часовой пояс", + formatterJsonPathInput: "Путь JSON", + formatterMaskPrefix: "Видимый префикс", + formatterMaskSuffix: "Видимый суффикс", + formatterSavedCustom: "Сохранённые шаблоны", + formatterNewCustom: "Новый шаблон", + formatterDeleteCustom: "Удалить шаблон", + formatterDeleteCustomMessage: "Удалить «{name}»? Форматирование будет снято со всех столбцов, использующих этот шаблон.", + formatterCustomName: "Название шаблона", + formatterCustomNamePlaceholder: "Например: Метка пользователя", + formatterCustomTemplateInput: "Шаблон", + formatterCustomTemplateHint: "Доступные переменные: ${value}, ${upper}, ${lower}, ${length}. Задайте имя, чтобы сохранить шаблон в список.", + formatterPreview: "Предпросмотр", + saveFormatter: "Сохранить", + clearFormatter: "Очистить", + searchValues: "Поиск значений...", + loadingValues: "Загрузка значений...", + serverValuesLimited: "Показаны первые {count} значений", + filterTypedValue: "Использовать «{value}»", + value: "Значение", + count: "Количество", + applyFilter: "Применить фильтр", + clearLocalFilters: "Очистить локальные фильтры значений", + clearLocalFiltersShort: "Очистить локальные", + localFiltersActive: "{count} локальных фильтров значений", + localFilterMoreValues: " ещё +{count}", + columnVisibility: "Столбцы", + autoFitColumnWidths: "Подогнать столбцы по содержимому", + autoFitColumnWidthsHint: "Подбирает ширину каждого видимого столбца по его содержимому. После этого границу столбца всё ещё можно перетаскивать.", + columnVisibilityHint: "Хотя бы один столбец останется видимым.", + columnReorderHint: "Перетащите, чтобы изменить порядок столбцов.", + columnReorderSearchHint: "Очистите поиск, чтобы изменить порядок столбцов.", + searchColumns: "Поиск столбцов...", + dragColumnToReorder: "Перетащите заголовок столбца для изменения порядка", + invertColumnVisibility: "Инвертировать", + resetColumnOrder: "Сбросить порядок", + showAllColumns: "Показать все", + viewOptions: "Параметры вида", + resultRunDisplayMode: "Вкладки результатов", + resultRunDisplayList: "Список", + resultRunDisplayTabs: "Мозаика", + hideNullColumns: "Скрыть NULL", + hideNullColumnsHint: "Скрывает или показывает столбцы, все значения которых NULL в текущем результате.", + searchMode: "Режим поиска", + searchModeHint: "Выберите, будет ли Ctrl+F фильтровать совпадающие строки или оставит все строки видимыми и подсветит совпадения.", + searchModeFilter: "Фильтр", + searchModeHighlight: "Подсветка", + colorizeDataTypes: "Цвета типов данных", + numericColumnAlign: "Выравнивание числовых столбцов", + numericColumnAlignLeft: "По левому краю", + numericColumnAlignRight: "По правому краю", + booleanDisplayMode: "Отображение логических значений", + booleanDisplayCheckbox: "Флажок", + booleanDisplayDropdown: "Раскрывающийся список", + moreValues: "ещё {count} значений, продолжайте вводить для уточнения", + filterByValue: "Фильтровать по этому значению", + filterExcludeValue: "Исключить это значение", + filterLike: "Содержит значение", + filterNotLike: "Не содержит", + filterLessThan: "Меньше значения", + filterGreaterThan: "Больше значения", + filterIsNull: "Показать значения NULL", + filterIsNotNull: "Показать значения, отличные от NULL", + clearFilter: "Очистить фильтр", + sort: "Сортировка", + sortAscending: "Сортировать по возрастанию", + sortDescending: "Сортировать по убыванию", + sortCurrentPageAscending: "Сортировать текущую страницу по возрастанию", + sortCurrentPageDescending: "Сортировать текущую страницу по убыванию", + sortDatabaseAscending: "Сортировать базу данных по возрастанию", + sortDatabaseDescending: "Сортировать базу данных по убыванию", + clearSort: "Очистить сортировку", + freezeToColumn: "Закрепить до этого столбца", + freezeSelectedColumns: "Закрепить выбранные столбцы ({count})", + freezeCurrentColumn: "Закрепить текущий столбец", + unfreezeCurrentColumn: "Открепить текущий столбец", + unfreezeColumns: "Открепить столбцы ({count})", + hideColumn: "Скрыть этот столбец", + hideSelectedColumns: "Скрыть выбранные столбцы ({count})", + showAllColumnsMenu: "Показать все столбцы", + pasted: "Вставлено!", + batchAppendPasteNotEditable: "Этот результат нельзя редактировать.", + batchAppendPasteInvalidTarget: "Перед вставкой выберите номер пустой новой строки.", + batchAppendPasteTargetNotEmpty: "Выбранная новая строка уже содержит данные.", + batchAppendPasteEmpty: "В буфере обмена нет строк для добавления.", + batchAppendPasteReadonlyColumn: "Вставленные данные содержат столбец, который нельзя редактировать.", + replaceText: "Заменить на", + replaceCurrentCell: "Заменить весь подходящий текст в текущей ячейке", + replaceScope: "Область замены", + replaceLoadedResults: "Загруженные результаты", + replaceCurrentColumn: "Текущий столбец", + replaceSelectedCells: "Выбранные ячейки", + replaceChooseColumn: "Выберите столбец", + replaceMatchedCells: "{count} подходящих ячеек", + replaceStagedCells: "Заменено ячеек: {count}; ожидает сохранения", + search: "Поиск...", + searchTruncatedValuesHint: "Некоторые длинные текстовые значения и JSON обрезаются для отображения; поиск охватывает только загруженный текст ячеек и может пропускать совпадения.", + searchOrWhere: "Поиск или введите условие WHERE...", + applyWhere: "Применить WHERE", + filterRows: "Фильтровать строки", + filterAllRows: "Все строки", + filterChangedRows: "Изменённые", + page: "Страница {page}", + jumpToPage: "Перейти к странице", + rowsPerPage: "Строк на странице", + customRowsPerPage: "Своё число строк", + applyPageSize: "Применить", + currentAndDefaultPageSize: "Текущее: {current} · По умолчанию: {default}", + applyForThisQuery: "Только сейчас", + applyAndSetDefault: "Сделать значением по умолчанию", + save: "Сохранить", + discard: "Отменить", + dismiss: "Закрыть", + addRow: "Добавить строку", + insertMultipleRows: "Вставить несколько строк…", + insertRowsTitle: "Вставка нескольких строк", + insertRowsDescription: "Создаёт указанное число несохранённых черновых строк. Пустые строки игнорируются при сохранении; после сохранения порядок отображения соответствует текущему запросу.", + insertRowCountLabel: "Количество строк", + insertRowCountInvalid: "Введите целое число больше 0.", + insertRowsMaxHint: "Не более {max} строк.", + insertRowsConfirm: "Вставить", + insertAboveSelected: "Вставить выше выбранной строки", + insertBelowSelected: "Вставить ниже выбранной строки", + insertRowPositionLabel: "Позиция", + insertPositionAbove: "Выше выбранной строки", + insertPositionBelow: "Ниже выбранной строки", + insertPositionEnd: "В конце данных", + quickEntryDraftPlaceholder: "Новая", + cloneRow: "Клонировать как новую строку", + deleteRow: "Удалить строку", + deleteRows: "Удалить {count} строк", + cloneRows: "Клонировать {count} как новые строки", + restoreRows: "Восстановить {count} строк", + copyRows: "Копировать {count} строк (массив JSON)", + copyColumnsJson: "Копировать {count} столбцов (JSON)", + selectedRows: "Выбрано строк: {count}", + restoreRow: "Восстановить строку", + statusClean: "Без изменений", + statusNew: "Новые элементы", + statusEdited: "Изменённые элементы", + statusDeleted: "Удалённые элементы", + pendingChanges: "Ожидает: {count}", + selectedCells: "Выбрано: {count}", + bulkEditSelection: "Массовое редактирование выделения", + bulkEditTitle: "Массовое редактирование выделения", + bulkEditDescription: "Установить для {count} выбранных ячеек это значение.", + bulkEditValuePlaceholder: "Значение или NULL", + applyBulkEdit: "Применить", + bulkEditSelectionScope: "Только выбранные ячейки", + bulkEditSelectionScopeDescription: "Подготовить изменения для {count} выбранных ячеек.", + bulkEditConditionalScope: "Все строки, соответствующие условию", + bulkEditConditionalScopeDescription: "Обновить {column} для каждой строки базы данных, соответствующей заданному условию.", + bulkEditConditionalConditionSource: "Условие соответствия", + bulkEditConditionalUseCurrentFilter: "Использовать текущий фильтр таблицы", + bulkEditConditionalUseCurrentFilterDescription: "Сохранить условие базы данных, применённое сейчас к этой таблице.", + bulkEditConditionalBuildFilter: "Задать условия соответствия", + bulkEditConditionalBuildFilterDescription: "Выберите столбцы, операторы и значения без написания SQL.", + bulkEditConditionalAdvancedWhere: "Дополнительно: SQL WHERE", + bulkEditConditionalAdvancedWhereDescription: "Написать собственное условие SQL.", + conditionalBulkEditPreviewCount: "Предпросмотр затрагиваемых строк", + conditionalBulkEditPreviewingCount: "Предпросмотр…", + conditionalBulkEditPreviewCountResult: "Примерно затронуто строк: {count}", + conditionalBulkEditPreviewCountStale: "Условия изменились. Выполните предпросмотр снова.", + conditionalBulkEditPreviewCountFailed: "Не удалось выполнить предпросмотр затрагиваемых строк: {message}", + bulkEditConditionalWhere: "Условие WHERE (обязательно)", + bulkEditConditionalWherePlaceholder: "Например: tenant_id = 1 AND status = 'pending'", + bulkEditConditionalWhereDescription: "Введите условие WHERE или только его часть. Активный фильтр таблицы подставляется, если он есть.", + conditionalBulkEditUnavailable: "Условное массовое редактирование больше недоступно для этого выделения или фильтра.", + conditionalBulkEditConditionRequired: "Задайте хотя бы одно условие соответствия перед обновлением всех подходящих строк.", + conditionalBulkEditPrepareFailed: "Не удалось подготовить условное обновление: {message}", + conditionalBulkEditConfirmTitle: "Подтвердите условное массовое обновление", + conditionalBulkEditConfirmMessage: "Это немедленно выполняется для каждой строки, соответствующей условию на момент выполнения. Незагруженные строки тоже включаются, и DBX не может создать для них надёжный откат.", + conditionalBulkEditConfirm: "Выполнить обновление", + conditionalBulkEditAppliedCount: "Обновлено подходящих строк: {count}", + conditionalBulkEditApplied: "Подходящие строки обновлены", + conditionalBulkEditPendingChanges: "Сохраните или отмените текущие ожидающие изменения перед обновлением всех строк, соответствующих условию.", + generateValue: "Сгенерировать значение", + generateEmptyString: "Пустая строка", + generateNull: "NULL", + generateCurrentDatetime: "Текущие дата и время", + generateCurrentDate: "Текущая дата", + generateUuidV4: "UUID v4", + generateUuidV7: "UUID v7", + generateIncrementId: "Инкрементный ID", + generateSnowflakeId: "Snowflake ID", + generateSequenceDescription: "Сгенерировать последовательные значения для {count} выбранных ячеек. Введите начальное значение.", + generateStartInvalid: "Начальное значение должно быть целым числом", + generatedValuesApplied: "Сгенерировано значений: {count}", + cellDetails: "Сведения о ячейке", + cellDetailLayoutBottom: "Переместить вниз", + cellDetailLayoutRight: "Переместить вправо", + collapseCellDetailMetadata: "Свернуть метаданные ячейки", + expandCellDetailMetadata: "Развернуть метаданные ячейки", + openCellDetailsDialog: "Открыть сведения о ячейке", + rowDetails: "Сведения о строке", + rowDetailsFor: "Сведения о строке {row}", + openRowDetailsDialog: "Открыть сведения о строке", + openColumnDetailsDialog: "Открыть сведения о столбце", + columnDetailsFor: "Сведения о столбце {column}", + columnsCount: "{count} столбцов", + rowCount: "Строки", + rowsCount: "{count} строк", + fieldIndex: "№", + cellValue: "Значение", + valueEditor: "Редактор значений", + hexViewer: "Просмотр HEX", + hexViewerByteCount: "{count} байт", + hexViewerOffset: "Смещение", + hexViewerHex: "HEX", + hexViewerAscii: "ASCII", + hexViewerEmpty: "Нет двоичных байтов для отображения.", + imagePreview: "Предпросмотр изображения", + imageLoadFailed: "Не удалось загрузить изображение", + geometryPreview: "Предпросмотр геометрии", + layerPreview: "Предпросмотр слоя", + layerPreviewSkipped: "Пропущено объектов: {count}", + layerPreviewNoSupportedCrs: "Не удалось выполнить предпросмотр: система координат отсутствует или не поддерживается", + layerPreviewNoGeometryData: "Не удалось выполнить предпросмотр: нет допустимых данных геометрии", + layerPreviewLabel: "Подпись", + layerPreviewExport: "Экспортировать изображение", + layerPreviewMaximize: "Развернуть", + layerPreviewRestore: "Восстановить", + layerPreviewLoading: "Загрузка карты...", + layerPreviewCustomCrs: "Свой EPSG…", + layerPreviewCustomCrsPlaceholder: "Код EPSG", + layerPreviewUnsupportedCrs: "Неподдерживаемая система координат: EPSG:{srid}", + layerPreviewCrsManual: "Система координат: вручную", + layerPreviewCrsDetected: "Система координат: определена", + layerPreviewCrsAssumed: "Система координат: предполагается WGS 84", + layerPreviewCustomBasemap: "Своя базовая карта", + layerPreviewCustomBasemapAction: "Своя базовая карта…", + layerPreviewCustomBasemapTitle: "Своя базовая карта", + layerPreviewCustomBasemapName: "Название", + layerPreviewCustomBasemapNamePlaceholder: "например, улицы Gaode", + layerPreviewCustomBasemapHint: "Введите URL XYZ-тайлов с {z}, {x} и {y}. Дополнительный URL оверлея полезен для подписей, например аннотаций Tianditu.", + layerPreviewCustomBasemapUrl: "URL тайлов", + layerPreviewCustomBasemapOverlayUrl: "URL оверлея", + layerPreviewCustomBasemapAttribution: "Атрибуция", + layerPreviewCustomBasemapMaxZoom: "Макс. масштаб", + layerPreviewCustomBasemapOptional: "Необязательно", + layerPreviewCustomBasemapApply: "Применить", + layerPreviewCustomBasemapInvalid: "Введите название и допустимый HTTP(S) URL XYZ-тайлов, содержащий {z}, {x} и {y}.", + insertRowsNotSupported: "Текущая цель сохранения не поддерживает добавление строк.", + zoomIn: "Увеличить", + zoomOut: "Уменьшить", + fitImage: "По размеру окна", + openImage: "Открыть изображение", + columnName: "Столбец", + columnType: "Тип", + columnComment: "Комментарий", + rowNumber: "Строка", + valueLength: "Длина", + nullValue: "NULL", + emptyStringValue: "Пустая строка", + noComment: "Без комментария", + formattedJson: "Форматированный JSON", + formatted: "Форматированный", + formattedValue: "Форматированное значение", + detailSearchPlaceholder: "Поиск поля или значения…", + detailSearchNoMatch: "Нет совпадений", + rawValue: "Исходное значение", + largeValuePreviewHint: "Показаны первые {count} символов. Копирование по-прежнему использует полное значение.", + largeValueRowUnavailable: "Не удалось найти строку в базе данных. Операция отменена без использования значения из предпросмотра.", + largeValueColumnUnavailable: "Не удалось найти исходный столбец для этого большого значения.", + largeValueLoadFailed: "Не удалось загрузить полное значение большого поля.", + largeValueNeedsStableKey: "У этой таблицы нет пригодного первичного ключа, поэтому полное значение большого поля нельзя безопасно загрузить. Операция отменена.", + largeValueLoadFailedWithMessage: "Не удалось загрузить полное значение большого поля: {message}", + largeValueLocalSortUnavailable: "Этот столбец содержит предпросмотры больших значений, поэтому его нельзя сортировать локально по содержимому предпросмотра. Используйте сортировку средствами базы данных.", + copyValue: "Копировать значение", + importBinaryValue: "Импортировать из файла", + binaryImportApplied: "Импортировано байт: {count}. Сохраните изменения, чтобы записать их в базу данных.", + binaryImportFailed: "Не удалось импортировать файл: {message}", + binaryImportTooLarge: "Файл слишком большой ({size}, предел {limit}). Импорт больших файлов в одну ячейку не поддерживается.", + downloadBinaryValue: "Скачать значение", + downloadSaved: "Сохранено в {path}", + downloadStarted: "Скачивание начато: {fileName}", + binaryDownload: { + binary: "Двоичные данные", + utf8: "Декодированный текст (UTF-8)", + gbk: "Декодированный текст (GBK)", + }, + binaryTextPreview: "Просмотреть как текст", + binaryTextPreviewTitle: "Предпросмотр двоичных данных как текста", + binaryTextPreviewDescription: "Строго декодирует hex-байты 0x с выбранной кодировкой. Предпросмотр только для чтения; исходное значение не изменяется.", + binaryTextPreviewEncoding: "Кодировка", + binaryTextPreviewEncodings: { + utf8: "UTF-8", + gbk: "GBK", + }, + binaryTextPreviewByteCount: "{count} байт", + binaryTextPreviewResult: "Декодированный текст", + binaryTextPreviewCopy: "Копировать результат", + binaryTextPreviewOriginalHint: "Исходное значение остаётся в виде hex 0x; этот предпросмотр не изменяет ячейку или базу данных.", + binaryTextPreviewErrors: { + notBinary: "Это значение не является полным двоичным значением, поэтому его нельзя декодировать.", + incomplete: "Полное значение ещё не загружено; декодирование неполного предпросмотра ввело бы в заблуждение.", + undecodable: "Строгое декодирование не удалось: это похоже на настоящие двоичные данные (изображение, архив или некорректная последовательность байтов), а не текст.", + }, + copyRowTsv: "Копировать строку (TSV)", + copyColumnValues: "Копировать столбец (JSON)", + copyColumnTsv: "Копировать столбец (TSV)", + editValue: "Редактировать значение", + formatJson: "Форматировать JSON", + compactJson: "Сжать JSON", + compareJson: "Сравнить", + valueDiffTitle: "Различия JSON в {column}", + valueDiffFormat: "Формат сравнения", + valueDiffRaw: "Исходный", + valueDiffOriginal: "Оригинал", + valueDiffCurrent: "Текущее", + copyOriginalValue: "Копировать исходное значение", + copyCurrentValue: "Копировать текущее значение", + cellValueCopied: "Значение ячейки скопировано", + valueDiffInvalidJson: "Недопустимый JSON; показано исходное значение: {message}", + valueDiffTooLarge: "Значение превышает {limit} символов; показано исходное значение.", + formattedJsonEditWarning: "Вы редактируете форматированный JSON. При сохранении он будет записан как JSON, поэтому исходное форматирование может измениться.", + setNull: "Установить NULL", + restoreOriginalValue: "Восстановить оригинал", + copyColumnName: "Копировать имя столбца", + columnDragChipMany: "{names} ({count} столбцов)", + copyAlterColumnSql: "Копировать как SQL ALTER", + alterSqlCopied: "SQL ALTER скопирован в буфер обмена", + alterSqlCopiedWithWarnings: "SQL ALTER скопирован в буфер обмена (предупреждений: {count})", + noAlterSqlAvailable: "Для этого столбца нет доступного SQL ALTER", + copyAlterSqlFailed: "Ошибка копирования: {message}", + copySqlCondition: "Копировать условие SQL", + copyQuerySql: "Копировать SQL", + copyExecutableSql: "Копировать SQL (без комментариев)", + transpose: "Транспонировать строку", + transposeMultiRowToggle: "Несколько строк", + transposeSingleRow: "Текущая строка", + transposeMultiRow: "Несколько строк", + transposeMultiRowHint: "Если включено, режим транспонирования показывает несколько строк. Если выключено — только текущую строку.", + rowsPerPageShort: " строк", + columnDetails: "Сведения о столбце", + tableInfo: "Информация о таблице", + tableInfoOverview: "Обзор", + tableInfoEstimatedRows: "Примерное число строк", + tableInfoTotalSize: "Общий размер", + tableInfoDataLength: "Длина данных", + tableInfoEngine: "Движок", + tableInfoCreatedAt: "Создано", + tableInfoUpdatedAt: "Обновлено", + tableInfoCollation: "Сравнение", + tableInfoRowFormat: "Формат строки", + tableInfoAvgRowLength: "Средняя длина строки", + tableInfoMaxDataLength: "Максимальная длина данных", + tableInfoCheckTime: "Время проверки", + tableInfoIndexLength: "Длина индекса", + tableInfoAutoIncrement: "Автоинкремент", + tableInfoDataFree: "Свободные данные", + pinTableInfo: "Закрепить панель информации о таблице", + unpinTableInfo: "Открепить панель информации о таблице", + tableInfoColumns: "Столбцы", + tableInfoIndexes: "Индексы", + columnPrimaryIndex: "Индекс первичного ключа", + columnUniqueIndex: "Уникальный индекс", + columnRegularIndex: "Обычный индекс", + tableInfoForeignKeys: "Внешние ключи", + foreignKeyNavigate: "Перейти к {table}", + openUrl: "Открыть URL в браузере", + tableInfoConstraints: "Ограничения", + tableInfoConstraintDisabled: "Отключено", + tableInfoConstraintNotValidated: "Не проверено", + tableInfoTriggers: "Триггеры", + tableInfoNullable: "Допускает NULL", + tableInfoEmpty: "Нет метаданных", + tableInfoSearch: "Поиск...", + tableOwner: "Владелец", + tableOwnerUnavailable: "Недоступно", + tableInfoNoResults: "Нет результатов", + goToColumn: "Перейти к столбцу", + columnWidth: "Ширина столбца", + columnWidthCompact: "Компактная", + columnWidthStandard: "Стандартная", + columnWidthComfortable: "Комфортная", + searchColumn: "Поиск столбца или комментария...", + noColumnsFound: "Столбцы не найдены", + queryError: "Ошибка запроса", + saveErrorTitle: "Не удалось сохранить изменения", + dataUnavailable: "Данные таблицы нужно перезагрузить.", + viewSnapshotSelectionNotRestored: "Предыдущий вид восстановлен, но его выделение было слишком большим, чтобы его сохранить.", + cachedResultUnavailable: "Кэшированный результат отсутствует или несовместим.", + reexecuteQuery: "Выполнить запрос снова", + dataUnavailableHintPrefix: "Нажмите ", + dataUnavailableHintSuffix: " или нажмите «Обновить» ниже, чтобы перезагрузить.", + refresh: "Обновить", + undoChange: "Отменить изменение", + redoChange: "Повторить изменение", + commit: "Зафиксировать", + rollback: "Откатить", + transactionSaveHint: "Зафиксировать {count} ожидающих изменений в транзакции.", + nonTransactionalSaveHint: "Сохранить {count} ожидающих изменений по одному. Если одно не удастся, ранее успешно применённые изменения не будут откатаны.", + keylessEditWarning: "Нет первичного ключа", + keylessEditWarningHint: "У этой таблицы нет первичного ключа. Обновления и удаления используют все исходные значения строки в условии WHERE; одинаковые строки могут быть затронуты вместе.", + queryEditReadOnly: "Результат только для чтения", + queryEditUnsupported: { + "not-select": "Напрямую можно редактировать только результаты запросов SELECT.", + cte: "Запросы с WITH/CTE пока нельзя редактировать. Используйте простой SELECT по одной таблице.", + "set-operation": "Результаты UNION, INTERSECT или EXCEPT нельзя безопасно сопоставить с исходными строками.", + aggregation: "Результаты DISTINCT, GROUP BY, HAVING и агрегатных функций нельзя редактировать напрямую.", + "external-source": "Внешние файлы и результаты табличных функций нельзя записать напрямую. Импортируйте их в таблицу базы данных перед редактированием.", + "complex-source": "DBX не смог определить ровно одну безопасную целевую таблицу для записи этого результата.", + "computed-columns": "Вычисляемые выражения и результаты функций нельзя записать обратно. Выбирайте исходные имена столбцов.", + "no-table": "Редактируемая исходная таблица не обнаружена.", + "no-primary-key": "У целевой таблицы нет первичного ключа, поэтому строки нельзя безопасно обновлять или удалять.", + "primary-key-not-returned": "В результате отсутствует исходный столбец первичного ключа. Включите его под исходным именем столбца.", + "aliased-columns": "Столбцы результата используют псевдонимы или выражения. Выбирайте редактируемые столбцы под их исходными именами.", + "metadata-unavailable": "DBX не удалось загрузить метаданные таблицы, поэтому редактирование результата отключено.", + }, + sortUnsupported: "Этот SQL не поддерживает сортировку всего результата. Повторите с одним запросом SELECT.", + truncatedHint: "Результаты были усечены после загрузки {count} строк. Используйте пагинацию в нижней части для просмотра загруженных данных; экспорт полного результата повторно выполнит запрос к базе данных.", + victoriaMetricsTruncatedHint: "Результаты превысили лимит загрузки, поэтому загружены только первые {count} строк. «Строк на страницу» пагинирует только загруженные данные; сократите диапазон времени или добавьте фильтры, чтобы получить полный результат.", + cut: "Вырезать", + }, + exportProgress: { + streamingUnsupported: "Потоковый экспорт не поддерживается для этого запроса. Упростите его или используйте поддерживаемый драйвер.", + agentSessionMissing: "Для потокового экспорта требуется сессия набора результатов, но этот драйвер не вернул session_id.", + title: "Экспорт данных таблицы", + fetching: "Получение данных из базы данных...", + writing: "Запись в файл...", + done: "Экспорт завершён!", + error: "Экспорт не удался", + cancelled: "Экспорт отменён.", + rowsCount: "{exported} / {total} строк", + rowsExported: "Экспортировано строк: {count}", + rowsShort: "строк", + cancel: "Отмена", + minimize: "Свернуть в фон", + openFolder: "Открыть папку с файлом", + openFolderFailed: "Не удалось открыть папку: {message}", + close: "Закрыть", + tooltip: "Фоновые задачи", + failedTooltip: "Сбой фоновой задачи: {count} | Сбоев фоновых задач: {count}", + popoverTitle: "Фоновые задачи", + noTasks: "Нет фоновых задач", + clearFinished: "Очистить завершённые", + showMore: "Показать ещё {count}", + showLess: "Показать меньше", + delete: "Убрать", + databaseExportTitle: "Экспорт базы данных: {name}", + databaseBackupTitle: "Резервное копирование базы данных: {name}", + sqlFileTitle: "Файл SQL: {name}", + dataTransferTitle: "Передача данных: {name}", + multiDbExecutionTitle: "Выполнение в нескольких базах данных: {name}", + schemaDiffTitle: "Сравнение схем: {name}", + dataCompareTitle: "Сравнение данных: {name}", + compareRunning: "Выполняется", + compareDone: "Готово", + compareError: "Ошибка", + compareCancelled: "Отменено", + comparePhase: { + loadingTableLists: "Загрузка списков таблиц", + loadingSourceDetails: "Загрузка сведений об источнике", + loadingTargetDetails: "Загрузка сведений о цели", + loadingExtraObjects: "Загрузка дополнительных объектов", + comparing: "Сравнение", + generating: "Формирование результата", + complete: "Завершено", + }, + schemaDiffSummary: "Различающихся объектов: {count}", + dataCompareSummary: "Таблиц: {tables}: {same} совпадают, {different} различаются, {failed} с ошибкой · +{added} / -{removed} / ~{modified}", + multiDbTargets: "Цели {completed}/{total}, успешно {success}, с ошибкой {failed}", + openTask: "Открыть задачу", + objectsCount: "{current} / {total} объектов", + tablesCount: "{current} / {total} таблиц", + statementsCount: "успешно {done}, с ошибкой {failed}", + elapsed: "Затрачено: {duration}", + showFailureDetails: "Детали ошибок ({count})", + hideFailureDetails: "Скрыть детали ошибок", + failureDetailTruncated: "Детали ошибок были усечены", + failureDetailsOmitted: "Не показано дополнительных деталей ошибок: {count}", + copyFailureDetail: "Копировать детали ошибок", + failureDetailCopied: "Детали ошибок скопированы", + failureDetailCopyFailed: "Не удалось скопировать детали ошибок: {message}", + }, + welcome: { + title: "Рабочая область базы данных", + subtitle: "Выберите подключение слева, чтобы просмотреть схему, или сразу откройте вкладку запроса.", + connections: "Подключения", + connected: "Подключено", + databaseTypes: "Типы баз данных", + quickConnections: "Быстрый старт", + quickConnectionsHint: "Нажмите на подключение, чтобы открыть вкладку запроса.", + shortcuts: "Горячие клавиши", + shortcutsHint: "Начните следующее действие отсюда.", + sqlHistory: "История запросов", + sqlHistoryEmpty: "Записей в библиотеке SQL пока нет", + sqlHistoryOpenCount: "Открыто {count} раз", + unknownConnection: "Неизвестное подключение", + tip: "Также можно разворачивать подключения слева и щёлкать правой кнопкой по базам данных или таблицам для дополнительных действий.", + tipSidebar: "Нажмите на таблицу слева, чтобы просмотреть данные", + tipExecute: "чтобы выполнить запрос", + fileOpened: "Открыто {name}", + fileOpenFailed: "Не удалось открыть {name}: {message}", + mcpTitle: "Интеграция с ИИ-агентом", + mcpDescription: "Помимо встроенного ИИ-ассистента, вы можете использовать Claude Code, Cursor и другие агенты программирования для запросов к базам данных через MCP.", + mcpLearnMore: "Подробнее", + }, + backendErrors: { + jdbc: { + connectionFailed: "Не удалось подключиться к базе данных до начала операции (этап: {stage}).", + connectionInterrupted: "Соединение с базой данных было прервано во время выполнения операции (этап: {stage}).", + operationTimedOut: "Время ожидания операции с базой данных истекло (этап: {stage}).", + operationCanceled: "Операция с базой данных была отменена (этап: {stage}).", + busyRetryLater: "Агент базы данных занят; повторите попытку позже (этап: {stage}).", + runtimeReplaced: "Среда выполнения агента базы данных была заменена (этап: {stage}).", + sqlFailed: "База данных вернула ошибку SQL (этап: {stage}).", + protocolFailed: "Сбой протокола агента базы данных.", + contractInvalid: "Агент базы данных вернул некорректный контракт ошибки.", + legacyFailure: "Агент базы данных вернул неклассифицированную ошибку.", + }, + transaction: { + sessionExpired: "Ручная транзакция истекла после {timeoutSecs} секунд бездействия и была отменена. Новая транзакция будет запущена автоматически.", + }, + legacy: "Бэкенд вернул ошибку.", + unknown: "Произошла непредвиденная ошибка бэкенда.", + }, + common: { + fileNotFound: "Файл не существует: {path}", + language: "Язык", + loading: "Загрузка...", + stopping: "Остановка...", + close: "Закрыть", + cancel: "Отмена", + confirm: "Подтвердить", + save: "Сохранить", + clear: "Очистить", + copy: "Копировать", + import: "Импорт", + remove: "Удалить", + retry: "Повторить", + refresh: "Обновить", + more: "Ещё", + decrease: "Уменьшить", + increase: "Увеличить", + showPassword: "Показать пароль", + hidePassword: "Скрыть пароль", + done: "Готово", + connection: "Подключение", + database: "База данных", + table: "Таблица", + view: "Представление", + schema: "Схема", + materializedView: "Материализованное представление", + procedure: "Процедура", + function: "Функция", + sequence: "Последовательность", + package: "Пакет", + packageBody: "Тело пакета", + noResults: "Нет результатов", + edit: "Редактировать", + delete: "Удалить", + disabled: "Отключено", + back: "Назад", + action: "Действие", + actions: "Действия", + }, + dateTimePicker: { + open: "Открыть выбор даты и времени", + inputLabel: "Дата и время", + inputPlaceholder: "ГГГГ-ММ-ДД ЧЧ:мм:сс", + previousMonth: "Предыдущий месяц", + nextMonth: "Следующий месяц", + calendarLabel: "Календарь", + timeLabel: "Время", + hour: "Час", + minute: "Минута", + second: "Секунда", + cancel: "Отмена", + apply: "Применить", + invalidDateTime: "Введите корректные дату и время", + outOfRange: "Дата и время вне допустимого диапазона", + }, + quickOpen: { + placeholder: "Поиск подключений, баз данных, таблиц, файлов SQL и других объектов...", + emptyPlaceholder: "Начните вводить текст для поиска", + noResults: "Ничего не найдено", + results: "результатов", + navigate: "Навигация", + select: "Выбрать", + close: "Закрыть", + sqlFile: "Файл SQL", + sqlLibraryFile: "Библиотека SQL", + pluginWorkbench: "Плагин", + searchingContent: "Поиск по содержимому файлов…", + globalSearchHint: "Глобальный поиск по содержимому", + modeObjects: "Поиск объектов и файлов", + modeContent: "Поиск по содержимому файлов", + contentPlaceholder: "Поиск внутри содержимого файлов…", + searchSettings: "Настройки поиска", + searchRoots: "Каталоги поиска", + addDirectory: "Добавить каталог", + noRootsConfigured: "Каталоги поиска не настроены", + removePath: "Удалить", + searchExtensions: "Расширения файлов", + extensionsPlaceholder: "например, sql, txt, md", + apply: "Применить", + }, + explain: { + estimatedTime: "Оценочное время", + title: "План выполнения", + standardTable: "Таблица", + tree: "Дерево", + summary: "Сводка", + running: "Чтение плана выполнения...", + empty: "Нет плана выполнения", + nodeCount: "{count} узлов", + node: "Узел", + relation: "Таблица", + index: "Индекс", + cost: "Стоимость", + rows: "Строки", + details: "Детали", + canvas: "Диаграмма", + costShare: "Доля стоимости", + estRows: "Оценка строк", + actualRows: "Фактические строки", + zoomIn: "Увеличить", + zoomOut: "Уменьшить", + zoomFit: "По размеру", + legendHeat: "Интенсивность = % от общей стоимости", + legendEdge: "Ширина связи = строки", + inspectorEmpty: "Выберите узел", + catResult: "Результат", + catSort: "Сортировка", + catJoin: "Соединение", + catTscan: "Сканирование таблицы", + catIscan: "Сканирование индекса", + catLookup: "Поиск строки", + catMat: "Материализация", + catAgg: "Агрегация", + catXchg: "Параллелизм", + catMod: "Изменение", + catOther: "Прочее", + unsupported: "План выполнения пока не поддерживается для этой базы данных", + emptySql: "Нет SQL для анализа плана", + unsafe: "Эта первая версия анализирует только операторы SELECT / WITH / TABLE / VALUES", + }, + profile: { + title: "Профиль", + emptyShards: "Нет данных профиля шардов", + emptyProfile: 'Этот ответ не содержит раздела `profile`. Добавьте `"profile": true` в тело поиска и повторите запрос.', + collapseAll: "Свернуть всё", + expandAll: "Развернуть всё", + selfTime: "Собственное", + totalTime: "Всего", + breakdown: "Этапы", + criticalPath: "Критический путь", + criticalPathTag: "Критический", + shard: "Шард", + searches: "поисков", + collapsedProtection: "Большой профиль: глубокие узлы изначально свёрнуты ({nodes} узлов)", + legendSelfTime: "Собственное время не учитывает дочерние элементы; полоса показывает долю от общего времени запроса шарда.", + }, + lineage: { + title: "Происхождение поля", + open: "Просмотреть происхождение поля", + loading: "Чтение метаданных {done}/{total}", + empty: "Связанное происхождение не найдено", + noFiltered: "Нет результатов, соответствующих текущим фильтрам", + targetField: "Текущее поле", + searchPlaceholder: "Поиск таблиц, полей, представлений или фрагментов SQL...", + showing: "Показано {shown}/{total} результатов", + all: "Все", + certain: "Точная", + likely: "Вероятная", + possible: "Возможная", + queryHistory: "История запросов", + openTable: "Открыть таблицу", + copy: "Копировать имя", + copied: "Скопировано", + kind: { + foreignKey: "Внешний ключ", + viewReference: "Представление", + historyReference: "История SQL", + sameName: "Одинаковое имя", + }, + description: { + foreignKeyIncoming: "{target} указывает на текущее поле через внешний ключ. Это подтверждённая зависимость.", + foreignKeyOutgoing: "Текущее поле ссылается на {target} через внешний ключ. Это подтверждённая зависимость.", + viewLikely: "Определение представления упоминает и целевую таблицу, и поле, что обычно указывает на зависимость запроса.", + viewPossible: "Определение представления упоминает поле с таким же именем, но не целевую таблицу, поэтому требуется подтверждение.", + historyLikely: "Исторический оператор SQL упоминает и целевую таблицу, и поле. Используйте это как контекст для анализа влияния.", + historyPossible: "Исторический оператор SQL упоминает поле с таким же именем. Возможно, оно связано, но нужен контекст.", + sameName: "В другой таблице есть поле с таким же именем. Возможно, они имеют общий бизнес-смысл, но это не подтверждённая зависимость в базе данных.", + }, + cancel: "Отмена", + refresh: "Проанализировать снова", + }, + tableVGroup: { + moveToGroup: "Переместить в группу", + moveToNewGroup: "Новая группа и перемещение", + removeFromGroup: "Убрать из группы", + newGroupDefault: "Новая группа", + newSubgroup: "Новая подгруппа", + deleteGroup: "Удалить группу", + disableGroups: "Скрыть группы", + enableGroups: "Показать группы", + deleteGroupConfirmTitle: "Удалить группу", + deleteGroupConfirmMessage: 'Удалить группу "{name}"? Её элементы вернутся в список объектов; база данных не будет затронута.', + groupDeleted: "Группа удалена", + }, + connectionGroup: { + createGroup: "Новая группа", + group: "Группа", + groupNamePlaceholder: "Название группы", + selectConnection: "Выбрать подключение", + deselectConnection: "Снять выбор с подключения", + selectAllConnections: "Выбрать все подключения", + deselectAllConnections: "Снять выбор со всех подключений", + selectedConnections: "Выбрано: {count}", + exitMultiSelect: "Выйти из режима выбора", + renameGroup: "Переименовать группу", + closeConnections: "Закрыть подключения в группе ({count})", + deleteGroup: "Удалить группу", + deleteSelectedGroups: "Удалить выбранные группы ({count})", + moveToGroup: "Переместить в группу", + moveToNewGroup: "Переместить в новую группу", + ungrouped: "Без группы", + ungroupedLabel: "По умолчанию", + newGroup: "Новая группа...", + newGroupDefault: "Новая группа", + deleteGroupConfirmTitle: "Удалить группу", + deleteGroupConfirmMessage: 'Удалить группу "{name}" и все её подгруппы? Ниже выберите, удалять ли также подключения внутри.', + deleteSelectedGroupsConfirmMessage: "Удалить выбранные группы ({count}) и все их подгруппы? Ниже выберите, удалять ли также подключения внутри.", + deleteConnectionsWithGroup: "Также удалить все подключения внутри выбранных групп и их подгрупп", + selectGroup: "Выбрать группу", + deselectGroup: "Снять выбор с группы", + }, + databaseSearch: { + title: "Поиск по базе данных", + open: "Поиск по базе данных", + keyword: "Ключевое слово", + keywordPlaceholder: "Введите ID пользователя, email, номер заказа...", + limitPerTable: "На таблицу", + search: "Поиск", + searching: "Поиск", + stop: "Остановить", + hint: "Сканирует обычные таблицы в текущей базе данных или схеме. Двоичные столбцы пропускаются, а объём каждой таблицы ограничивается, чтобы не загружать слишком много данных сразу.", + loadingTables: "Чтение списка таблиц...", + progress: "Просканировано таблиц: {done}/{total}", + resultCount: "Совпадений: {count}", + continueNextBatch: "Просканировать следующие {count}", + scanAllRemaining: "Просканировать оставшиеся {count}", + results: "Результаты", + openResult: "Открыть", + waiting: "Ожидание совпадений...", + noResults: "Пока нет совпадений", + errors: "Сбой при обработке некоторых таблиц", + }, + configExport: { + passphraseTitle: "Зашифровать и экспортировать", + passphraseImportTitle: "Расшифровать файл", + passphraseExportHint: "Чтобы включить пароли подключений в экспорт, задайте парольную фразу для шифрования. Та же фраза потребуется при импорте.", + passphraseImportHint: "Этот файл зашифрован. Введите парольную фразу для расшифровки, затем выберите, какие подключения импортировать.", + passphrase: "Парольная фраза", + passphraseConfirm: "Подтвердите парольную фразу", + passphrasePlaceholder: "Введите парольную фразу", + passphraseConfirmPlaceholder: "Повторно введите парольную фразу", + passphraseRequired: "Требуется парольная фраза", + passphraseMismatch: "Парольные фразы не совпадают", + passphraseTooShort: "Парольная фраза должна содержать не менее 4 символов", + exportEncrypted: "Экспортировать зашифрованным", + exportUnencrypted: "Экспортировать без шифрования", + unencryptedWarningTitle: "Экспортировать без шифрования?", + unencryptedWarningDescription: + "Незашифрованный файл конфигурации может содержать пароли к базам данных, учётные данные SSH-туннеля и другую конфиденциальную информацию. Любой, у кого есть доступ к файлу, сможет прочитать эти данные. Используйте это только для временного переноса в доверенной среде.", + confirmUnencryptedExport: "Экспортировать без шифрования", + decryptImport: "Расшифровать", + wrongPassphrase: "Неверная парольная фраза или повреждённый файл", + cryptoUnavailable: "Импорт зашифрованной конфигурации недоступен в этом контексте браузера. Используйте HTTPS, localhost или DBX Desktop.", + exportFailed: "Не удалось экспортировать подключения", + exportSuccess: "Подключения успешно экспортированы", + importSuccess: "Импортировано подключений: {count}", + importNavicatSuccess: "Импортировано подключений Navicat: {count}. Перед проверкой заполните пароль для подключений, где он остался пустым.", + importDatagripSuccess: "Импортировано подключений DataGrip: {count}, заполнено паролей из связки ключей macOS: {filled}.", + importDatagripSelectFiles: "Выберите dataSources.xml (обязательно) и, при необходимости, dataSources.local.xml / db-forest-config.xml", + importDatagripDialogTitle: "Выберите файлы конфигурации DataGrip", + importDbeaverSuccess: "Импортировано подключений DBeaver: {count}. Перед проверкой заполните пароль для подключений, где он остался пустым.", + importNone: "Нет новых подключений для импорта", + importLayoutConfirm: "Импортированный файл содержит группы подключений. Применить их?", + importLayoutTitle: "Импорт групп", + importLayoutApply: "Применить", + selectExportTitle: "Выберите подключения для экспорта", + selectImportTitle: "Выберите подключения для импорта", + selectAll: "Выбрать все", + deselectAll: "Снять выбор со всех", + selectedCount: "{selected} / {total}", + next: "Далее", + importSelected: "Импортировать ({count})", + noConnections: "Нет доступных подключений", + }, + ai: { + placeholder: "Опишите запрос естественным языком...", + settings: "Настройки ИИ", + noConfig: "ИИ не настроен. Настройте провайдера ИИ в разделе «Настройки > ИИ».", + provider: "Провайдер", + providerCustom: "Свой", + builtinProviders: "Встроенная поддержка", + partnerProviders: "Премиум-спонсоры", + jalapenoSponsored: "$1 бесплатного кредита", + jalapenoDescription: "🎉 ИИ корпоративного уровня, которому доверяют ведущие команды, теперь доступен и вам! Попробуйте передовые модели со скидкой 50% и получайте больше бонусных кредитов при пополнении!", + hualongDescription: + "🐉 Официальный ретранслятор моделей для активных ИИ-разработчиков! 100% подлинные модели серий Codex и Claude с проверяемой токен-биллинговой детализацией, корпоративными контрактами и выставлением счетов.\n🎉Зарегистрируйтесь с промокодом DBX&HUALONG и получите $1 бесплатного кредита!", + visitPartner: "Посетить сайт партнёра", + getApiKey: "Получить ключ API", + providerStatusActive: "Активен", + providerStatusConfigured: "Настроен", + switchProvider: "Сменить провайдера", + model: "Модель", + defaultModel: "Модель по умолчанию", + browseModels: "Обзор моделей", + refreshModels: "Обновить модели", + loadingModels: "Загрузка моделей...", + modelLoadFailed: "Не удалось загрузить модели", + retry: "Повторить", + searchModels: "Поиск моделей", + noModels: "Модели не загружены", + noModelMatch: "Нет подходящих моделей", + selectModel: "Выберите модель", + noModel: "Модель не настроена", + manualModel: "Введите ID модели вручную", + manualModelPlaceholder: "ID модели", + effort: "Усилия", + providerDefault: "По умолчанию у провайдера", + loadingEffort: "Загрузка уровней усилий...", + effortLoadFailed: "Не удалось загрузить уровни усилий", + effortEnabled: "Включено", + effortDisabled: "Отключено", + customEffortPlaceholder: "Введите значение усилия", + effortUnsupported: "Эта модель не поддерживает настройку усилий", + configNameEmpty: "Название конфигурации не может быть пустым", + configNameExists: "Конфигурация с именем '{name}' уже существует", + deepLinkInvalid: "Не удалось открыть ссылку конфигурации ИИ: {message}", + deepLinkClipboardTitle: "Импорт ключа API", + deepLinkClipboardPrompt: "Прочитать ключ API из буфера обмена?", + deepLinkClipboardEmpty: "В буфере обмена нет ключа API. Введите его вручную.", + deepLinkClipboardInvalid: "В буфере обмена нет корректного однострочного ключа API. Введите его вручную.", + deepLinkClipboardReadFailed: "Не удалось прочитать буфер обмена: {message}", + configList: "Список конфигураций ИИ", + addConfig: "Добавить конфигурацию", + noAiConfigs: "Нет конфигураций ИИ", + setDefault: "Сделать по умолчанию", + editConfig: "Изменить конфигурацию", + configName: "Название конфигурации", + configNamePlaceholder: "Введите название конфигурации", + modelList: "Список моделей", + modelId: "ID модели", + modelDisplayName: "Отображаемое имя", + add: "Добавить", + fetching: "Получение...", + fetchModelList: "Получить модели из API", + default: "По умолчанию", + deleteConfigTitle: "Удалить конфигурацию", + deleteConfigConfirm: "Удалить эту конфигурацию?", + modelListHint: "Нажмите «Обновить», чтобы загрузить модели от провайдера.", + modelListUnsupported: "Этот провайдер не поддерживает получение списка моделей.", + modelListEndpointRequired: "Введите endpoint перед загрузкой моделей.", + modelListApiKeyRequired: "Введите ключ API перед загрузкой моделей.", + run: "Запустить", + readingSchema: "Чтение схемы", + noConnection: "Для этой вкладки нет доступного подключения", + noSql: "Нет SQL для обработки", + sqlPreview: "Предпросмотр SQL", + copySql: "Копировать SQL", + copyCode: "Копировать код", + executeSql: "Выполнить SQL", + tempRunSql: "Выполнить без изменения редактора", + copyAll: "Копировать всё", + copyMessage: "Копировать сообщение", + copied: "Скопировано", + copyTestResult: "Копировать результат проверки", + testErrorAuth: "Не удалось пройти аутентификацию или получить доступ. Проверьте ключ API, права на проект и доступность API.", + testErrorModelNotFound: "Модель недоступна. Проверьте её ID и доступ к вашему аккаунту.", + testErrorRateLimit: "Превышен лимит запросов или квота. Повторите позже или проверьте квоту аккаунта.", + testErrorTimeout: "Время ожидания запроса истекло. Проверьте сеть, прокси и endpoint.", + testErrorTokenLimit: "Видимый текст не был сгенерирован, так как лимит выходных токенов исчерпан.", + testErrorSafety: "Gemini заблокировал промпт или ответ в соответствии со своей политикой безопасности.", + testErrorEmptyResponse: "Сервис или прокси закрыл поток, не вернув видимый текст.", + testErrorNetwork: "Не удалось установить сетевое соединение. Проверьте endpoint и прокси.", + testErrorUnknown: "Проверка завершилась сбоем по неклассифицированной причине.", + replace: "Заменить в редакторе", + append: "Добавить в редактор", + apply: "Применить в редакторе", + clear: "Очистить чат", + maximize: "Развернуть", + restore: "Восстановить", + welcome: "Расскажите, что вы хотите запросить, и я напишу SQL", + requestFailed: "Сбой запроса к ИИ", + requestCancelled: "Запрос отменён", + backgroundRunCompleted: "Ответ ИИ получен в фоновом режиме", + backgroundRunNeedsConfirmation: "Для продолжения ИИ требуется ваше подтверждение", + recoveredDraftBanner: "Запрос, поставленный в очередь до перезапуска, был восстановлен", + recoveredDraftHint: "Измените и отправьте заново или удалите его.", + discardDraft: "Удалить черновик", + runStatusRunning: "Выполняется", + runStatusWaitingToStart: "Ожидание запуска", + runStatusAwaitingConfirmation: "Ожидание подтверждения", + runStatusPendingDraft: "Ожидание ввода", + runStatusCompleted: "Завершено", + runStatusFailed: "Сбой", + runStatusInterrupted: "Прервано", + runStatusCancelled: "Отменено", + runUnread: "Новые обновления в этом диалоге", + closeWithRunsTitle: "Задачи ИИ всё ещё выполняются", + closeWithRunsDescription: "Выход из DBX прервёт выполняющиеся или находящиеся в очереди задачи ИИ ({count}). Вы можете закрыть этот диалог и дать им завершиться.", + closeWithRunsQuit: "Выйти и прервать", + queueSend: "Поставить в очередь на отправку", + queueSendHint: "В этом диалоге всё ещё выполняется задача; сообщение будет отправлено по её завершении", + inputQueued: "Сообщение поставлено в очередь на отправку после текущей задачи", + queuedInputWaiting: "Ожидание — {text}", + queuedInputPending: "В очереди на отправку — {text}", + sendQueuedInput: "Отправить сообщение из очереди", + queuedInputEdit: "Изменить сообщение из очереди", + queuedInputRemove: "Удалить сообщение из очереди", + rowQueuedInput: "Ввод в очереди", + retryRound: "Повторить этот раунд", + deleteConversation: "Удалить диалог", + deleteActiveConversationTitle: "В диалоге есть активная задача", + deleteActiveConversationDescription: "В этом диалоге всё ещё выполняется или ожидает задача. Отменить задачу и удалить диалог или оставить его?", + cancelTaskAndDelete: "Отменить задачу и удалить диалог", + keepConversation: "Оставить диалог", + awayUpdatesDivider: "Обновления, пока вас не было", + jumpToLatest: "Перейти к последнему", + openPanel: "Открыть панель", + runRowPhaseTool: "Выполняется {tool}", + runRowPhaseThinking: "Анализ…", + toolbarAwaitingConfirmation: "Задачи ИИ, ожидающие вашего подтверждения: {count}", + newChat: "Новый чат", + thinking: "Обдумывание...", + reasoningProcess: "Процесс размышления", + chars: "символов", + stopGenerating: "Остановить генерацию", + scrollToBottom: "Вернуться вниз", + csvAttachmentSelect: "Прикрепить CSV", + csvAttachmentInvalidType: "Выберите файл CSV.", + csvAttachmentEmpty: "Файл CSV пуст.", + csvAttachmentReadFailed: "Не удалось прочитать файл CSV.", + csvAttachmentTruncated: "CSV был усечён перед отправкой ИИ.", + attachmentSelect: "Прикрепить изображение или текстовый файл", + attachmentSelectHint: "Прикрепляйте изображения или текстовые файлы. До 4 изображений (всего 12 МБ) и 8 текстовых файлов (всего 32 000 символов).", + attachmentDropHint: "Перетащите файлы, чтобы добавить вложения", + attachmentInvalidType: "Выберите изображение PNG, JPEG, GIF или WebP.", + attachmentReadFailed: "Не удалось прочитать вложение.", + attachmentImageTooLarge: "Изображения должны быть не больше 5 МБ.", + attachmentImageLimit: "Можно прикрепить до 4 изображений одновременно.", + attachmentImageTotalLimit: "Общий размер прикреплённых изображений не должен превышать 12 МБ.", + attachmentTextLimit: "Можно прикрепить до 8 текстовых файлов одновременно.", + attachmentTextTotalLimit: "Общий размер прикреплённого текста не должен превышать 32 000 символов.", + attachmentFileTooLarge: "Перетащенные файлы должны быть не больше 5 МБ.", + attachmentTruncatedStatus: "Обрезано", + attachmentEncoding: "Кодировка текста", + attachmentEncodingReadFailed: "Не удалось декодировать вложение с указанной кодировкой.", + attachmentUnsupportedProvider: "Это подключение провайдера не поддерживает отправку изображений. Удалите изображение или выберите провайдера с поддержкой изображений.", + attachmentUnsupportedFormat: "Выбранный провайдер не поддерживает этот формат изображения. Удалите его или используйте PNG, JPEG или WebP.", + attachmentPreview: "Предпросмотр вложения", + attachmentUnavailableAfterReload: "Содержимое недоступно после перезагрузки; повторно оно не будет отправлено", + attachmentUnsupportedDocument: "Этот тип файлов пока не поддерживается. Прикрепите изображения или текстовые файлы.", + tableMentionEmpty: "Подходящих таблиц или SQL-файлов нет", + tableMentionPlaceholderHint: "Введите {'@'}, чтобы упомянуть таблицы или SQL-файлы для контекста", + tableMentionTypes: { + table: "Таблица", + view: "Представление", + systemTable: "Системная таблица", + temporaryTable: "Временная таблица", + }, + modes: { + ask: "Вопрос", + agent: "Агент", + }, + modeHints: { + ask: "Генерировать SQL и пояснения без автоматического выполнения", + agent: "Использовать инструменты для запроса данных и ответа по реальным результатам", + }, + fixWithAi: "Исправить с помощью ИИ", + truncated: "Контекст обрезан", + contextSummary: "{database} · таблиц: {tables}", + autoSqlBlocked: "SQL, сгенерированный ИИ, выглядит слишком рискованным для автоматического выполнения. Проверьте его вручную перед запуском.", + redisConsoleUnreachable: "Команда ИИ не смогла подключиться к консоли Redis этого диалога. Откройте консоль Redis привязанного подключения и повторите попытку.", + writeSqlConfirmationRequired: "Этот SQL изменяет данные или схему. Внимательно проверьте его перед выполнением.", + writeSqlConfirmationQuestion: "Выполнить этот SQL один раз?", + writeSqlConfirmYes: "Подтвердить выполнение", + writeSqlConfirmNo: "Отмена", + writeSqlConfirmationReplyYes: "Выполните указанный выше SQL ровно один раз. Больше не запрашивайте подтверждение.", + writeSqlConfirmationReplyNo: "Не выполняйте указанный выше SQL. Продолжите диалог.", + productionWriteBlocked: "ИИ не может выполнять изменения данных или схемы в рабочей базе данных. Проверьте этот SQL и выполните его вручную в DBX.", + proposalConfirmReplyYes: "Выполните действие, предложенное выше; больше не запрашивайте подтверждение.", + proposalConfirmReplyNo: "Не выполняйте упомянутое выше действие; продолжите текущий диалог.", + proposalConfirmYes: "Да, продолжить", + proposalConfirmNo: "Нет, спасибо", + proposalConfirmTitle: "Требуется подтверждение действия", + agentSteps: { + generated: "SQL сгенерирован", + noSql: "SQL не найден", + safe: "Проверка безопасности пройдена", + needsConfirm: "Требуется подтверждение", + blocked: "Заблокировано", + autoExecute: "Готово к запуску", + notRequested: "Запуск не запрошен", + skipped: "Не запущено", + callingTool: "Вызов инструмента...", + executing: "Выполнение…", + toolDone: "Инструмент завершён", + toolError: "Ошибка инструмента", + executeSafe: "Проверка безопасности пройдена · Выполнено", + executeBlocked: "Заблокировано проверкой безопасности", + contextCompacted: "Контекст сжат", + skillsLoaded: "Навыки загружены", + }, + agentStepTitles: { + riskCheck: "Проверка риска: {action} · {category} · {environment} · {reasons}", + blocked: "Выполнение заблокировано политикой рисков. Проверьте SQL вручную.", + requiresConfirmation: "Этот SQL требует подтверждения перед выполнением.", + askMode: "Режим «Вопрос» не выполняет SQL автоматически.", + unsupportedAction: "Текущее действие ИИ не выполняет SQL автоматически.", + noSql: "Ответ не содержит исполняемого блока кода SQL.", + notRequested: "Пользователь не просил запускать SQL.", + skipped: "Этот шаг не был выполнен.", + }, + status: { + waitingModel: "Ожидание ответа модели · {elapsed} с", + waitingModelLive: "Ожидание ответа модели", + generating: "Генерация ответа · {elapsed} с", + generatingLive: "Генерация ответа", + runningTool: "Шаг {turn} · Выполняется {tool} · {elapsed} с", + runningToolAction: "· Выполняется", + runningToolElapsed: "· {elapsed} с", + turnBadge: "Шаг {turn}", + idle: "Ожидание этого шага · Последняя активность {idle} с назад", + idleLive: "Ожидание этого шага", + idleWithTool: "Ожидание этого шага · Последняя активность {idle} с назад · Выполняется {tool}", + longRunningHint: "Это занимает больше времени, чем ожидалось. Можно продолжить ожидание или остановить.", + cancelling: "Отмена…", + toolLabels: { + executeQuery: "Выполнить запрос", + executeSql: "Выполнить SQL", + listTables: "Список таблиц", + getColumns: "Получить столбцы", + getCurrentTime: "Получить текущее время", + explainQuery: "Пояснить план запроса", + getSampleData: "Получить образец данных", + listCollections: "Список коллекций", + browseCollection: "Просмотр коллекции", + }, + }, + proxy: "Прокси", + proxyEnable: "Отправлять запросы ИИ через прокси", + proxyUrl: "URL прокси", + sslVerification: "SSL-сертификат", + skipTlsVerify: "Пропускать проверку SSL-сертификата", + skipTlsVerifyHint: "Пропускайте только для доверенных узлов с самоподписанными сертификатами. Отключение проверки делает трафик уязвимым для перехвата.", + customHeaders: "Пользовательские заголовки", + customHeadersAdd: "Добавить заголовок", + customHeadersHint: "Дополнительные заголовки отправляются при обнаружении моделей, проверке подключения, в чате и запросах агента. Значения заголовков могут быть конфиденциальными.", + customHeadersNamePlaceholder: "X-Tenant-ID", + customHeadersValuePlaceholder: "tenant-a", + customHeadersInvalidName: "Недопустимое имя заголовка: {name}", + customHeadersInvalidValue: "Недопустимое значение заголовка для: {name}", + customHeadersDuplicate: "Дублирующееся имя заголовка: {name}", + customHeadersReserved: "Этот заголовок управляется DBX: {name}", + enableThinking: "Размышление", + enableThinkingOn: "Включено", + enableThinkingOff: "Отключено", + enableThinkingHint: "Эта опция действует только для API /chat/completions и поддерживаемых моделей. При отключении расход токенов может значительно снизиться, но качество результатов может немного упасть.", + anthropicMessagesHint: "API, совместимые с Anthropic Messages, обычно используют /v1/messages.", + openAiCompatibleEndpointHint: "Большинство API, совместимых с OpenAI, требуют префикс пути /v1.", + contextWindow: "Контекстное окно", + contextWindowAuto: "Авто (определение по имени модели)", + contextWindowHint: "Токены. Оставьте пустым для автоопределения. Задайте вручную для локальных/пользовательских моделей.", + maxOutputTokens: "Макс. выходных токенов", + maxOutputTokensAuto: "Авто (для каждого действия)", + maxOutputTokensHint: "Необязательный лимит для конфигурации, отправляемый провайдеру. Диапазон: {min}–{max}. Запросы с размышлением всё равно используют минимум 8192 токена.", + maxRetries: "Макс. число повторов", + maxRetriesHint: "Повторять при ограничениях частоты, тайм-аутах и временных сетевых ошибках. 0 = никогда, максимум 10.", + maxRetriesGlobal: "Макс. число повторов", + maxRetriesGlobalDescription: "Число автоматических повторов при временных ошибках API (ограничения частоты, тайм-ауты, сбои сети). Применяется ко всем AI-провайдерам через API. На CLI-провайдеров не влияет.", + maxRetriesRange: "{min}–{max}, по умолчанию {default}", + maxRetriesSaved: "Макс. число повторов сохранено", + codexCliPath: "Путь к Codex CLI", + codexCliPathHint: "Оставьте пустым, чтобы использовать codex из PATH. Войдите отдельно командой codex login.", + codexCliPathEnvError: "Путь к Codex CLI должен содержать только путь к исполняемому файлу. Добавьте переменные окружения ниже.", + codexCliEnv: "Переменные окружения", + codexCliEnvAdd: "Добавить переменную", + codexCliEnvHint: "Необязательные переменные, передаваемые Codex CLI, например HTTPS_PROXY, NO_PROXY, SSL_CERT_FILE или CODEX_CA_CERTIFICATE.", + codexCliEnvKeyPlaceholder: "HTTPS_PROXY", + codexCliEnvValuePlaceholder: "http://proxy:9800", + codexCliEnvInvalidName: "Недопустимое имя переменной окружения: {name}", + codexCliEnvReservedName: "Переменная {name} управляется DBX для сервера MCP и не может быть задана здесь.", + cliMcpRequiredTitle: "Требуется DBX MCP Server", + cliMcpRequiredDescription: "{provider} использует DBX MCP Server для доступа к схеме базы данных и инструментам запросов. Установите его перед использованием этого провайдера в ИИ-ассистенте.", + cliPath: "Путь к {provider}", + cliPathHint: "Оставьте пустым, чтобы использовать {command} из PATH. Войдите отдельно командой {loginCommand}.", + cliPathEnvError: "Путь к {provider} должен содержать только путь к исполняемому файлу. Добавьте переменные окружения ниже.", + cliEnv: "Переменные окружения", + cliEnvAdd: "Добавить переменную", + cliEnvHint: "Необязательные переменные, передаваемые {provider}, например HTTPS_PROXY, NO_PROXY или SSL_CERT_FILE.", + cliEnvKeyPlaceholder: "HTTPS_PROXY", + cliEnvValuePlaceholder: "http://proxy:9800", + cliEnvInvalidName: "Недопустимое имя переменной окружения: {name}", + cliEnvReservedName: "Переменная {name} управляется DBX для сервера MCP и не может быть задана здесь.", + codexMcpRequiredTitle: "Требуется DBX MCP Server", + codexMcpRequiredDescription: "Codex CLI использует DBX MCP Server для доступа к схеме базы данных и инструментам запросов. Установите его перед использованием Codex в ИИ-ассистенте.", + reasoningLevel: "Уровень рассуждений", + reasoningLevelDefault: "По умолчанию", + reasoningLevelMinimal: "Минимальный", + reasoningLevelLow: "Низкий", + reasoningLevelMedium: "Средний", + reasoningLevelHigh: "Высокий", + reasoningLevelXhigh: "Очень высокий", + reasoningLevelMax: "Максимальный", + reasoningLevelHint: "Управляет параметром model_reasoning_effort в Codex CLI. «По умолчанию» использует вашу конфигурацию Codex.", + claudeCodeEffortHint: "Доступные уровни сообщаются выбранной моделью через локальный Claude Code CLI.", + claudeCodeEffortUnavailable: "Выбранная модель не сообщает о настраиваемых уровнях усилий. Claude Code будет использовать значение по умолчанию.", + cliErrors: { + code: "Код ошибки: {code}", + details: "Диагностические сведения:", + reportHint: "При сообщении об этой проблеме укажите код ошибки и диагностические сведения ниже.", + claudeCodeNotInstalled: "Claude Code CLI не найден. Установите Claude Code или укажите путь к исполняемому файлу в «Настройки > ИИ».", + claudeCodeCliPathInvalid: "Путь к Claude Code CLI недействителен. Выберите только исполняемый файл Claude, а переменные окружения настройте отдельно.", + claudeCodeEnvInvalid: "Недопустимое имя переменной окружения Claude Code CLI. Используйте имена вида HTTPS_PROXY.", + claudeCodeEnvReserved: "Переменная окружения MCP, управляемая DBX, была переопределена. Удалите переменные DBX_MCP_* из конфигурации провайдера.", + claudeCodeNotAuthenticated: "Claude Code CLI не авторизован. Выполните `claude auth login` в терминале и повторите попытку.", + claudeCodeMcpConfigInvalid: "Claude Code не смог прочитать или разобрать конфигурацию DBX MCP. Проверьте версию Claude Code CLI и путь к исполняемому файлу.", + dbxMcpMissing: "Совместимая установка DBX MCP Server не найдена. Проверьте «Настройки > MCP», затем переустановите или обновите его.", + claudeCodeMcpStartupFailed: "Claude Code загрузил конфигурацию MCP, но не смог запустить DBX MCP Server. Проверьте «Настройки > MCP» и диагностику ниже.", + claudeCodeCommandLineTooLong: "Windows отклонил команду Claude Code из-за слишком большой длины. Обновите DBX и повторите попытку с использованием созданного файла конфигурации MCP.", + claudeCodeRunFailed: "Claude Code CLI неожиданно завершился. Используйте код ошибки и диагностику ниже, чтобы определить сбойный исполняемый файл или вывод CLI.", + piAgentNotInstalled: "Pi Coding Agent не найден. Установите Pi или укажите путь к исполняемому файлу в «Настройки > ИИ».", + piAgentCliPathInvalid: "Путь к Pi Coding Agent недействителен. Выберите только исполняемый файл Pi, а переменные окружения настройте отдельно.", + piAgentEnvInvalid: "Недопустимое имя переменной окружения Pi Coding Agent. Используйте имена вида HTTPS_PROXY.", + piAgentEnvReserved: "Переменная окружения Pi или MCP, управляемая DBX, была переопределена. Удалите переменные DBX_PI_* и DBX_MCP_* из конфигурации провайдера.", + piAgentNotAuthenticated: "В Pi Coding Agent нет авторизованного провайдера моделей. Настройте провайдера или войдите в него через Pi и повторите попытку.", + piAgentMcpStartupFailed: "Pi не смог запустить привязанный мост DBX MCP. Проверьте «Настройки > MCP» и диагностику ниже.", + piAgentTimeout: "Pi Coding Agent не ответил до истечения тайм-аута операции.", + piAgentProtocolError: "Pi Coding Agent вернул недопустимый ответ RPC. Проверьте версию Pi и диагностику ниже.", + piAgentModelInvalid: "Идентификатор выбранной модели Pi недействителен. Обновите список моделей и выберите запись провайдер/модель.", + piAgentRunFailed: "Pi Coding Agent неожиданно завершился. Используйте код ошибки и диагностику ниже, чтобы определить сбойный исполняемый файл или вывод CLI.", + openCodeNotInstalled: "OpenCode CLI не найден. Установите OpenCode или укажите путь к исполняемому файлу в «Настройки > ИИ».", + openCodeCliPathInvalid: "Путь к OpenCode CLI недействителен. Выберите только исполняемый файл OpenCode, а переменные окружения настройте отдельно.", + openCodeEnvInvalid: "Недопустимое имя переменной окружения OpenCode CLI. Используйте имена вида HTTPS_PROXY.", + openCodeEnvReserved: "Переменная окружения OpenCode или управляемая DBX была переопределена. Удалите управляющие переменные OPENCODE и переменные DBX_MCP_* из конфигурации провайдера.", + openCodeNotAuthenticated: "В OpenCode нет авторизованного провайдера моделей. Выполните `opencode auth login` или настройте провайдера в OpenCode, затем повторите попытку.", + openCodeMcpStartupFailed: "OpenCode не смог запустить привязанный сервер DBX MCP. Проверьте «Настройки > MCP» и диагностику ниже.", + openCodeTimeout: "OpenCode CLI не ответил до истечения тайм-аута операции.", + openCodeProtocolError: "OpenCode CLI вернул недопустимый поток событий JSON. Проверьте версию OpenCode и диагностику ниже.", + openCodeRunFailed: "OpenCode CLI неожиданно завершился. Используйте код ошибки и диагностику ниже, чтобы определить сбойный исполняемый файл или вывод CLI.", + cursorNotInstalled: "Cursor CLI не найден. Установите Cursor CLI или укажите путь к исполняемому файлу в «Настройки > ИИ».", + cursorCliPathInvalid: "Путь к Cursor CLI недействителен. Выберите только исполняемый файл агента, а переменные окружения настройте отдельно.", + grokCliNotInstalled: "Grok CLI не найден. Установите Grok CLI или укажите путь к исполняемому файлу в «Настройки > ИИ».", + grokCliPathInvalid: "Путь к Grok CLI недействителен. Выберите только исполняемый файл grok, а переменные окружения настройте отдельно.", + grokCliEnvInvalid: "Недопустимое имя переменной окружения Grok CLI. Используйте имена вида HTTPS_PROXY.", + grokCliEnvReserved: "Переменная окружения MCP, управляемая DBX, была переопределена. Удалите переменные DBX_MCP_* из конфигурации провайдера.", + grokCliNotAuthenticated: "Grok CLI не авторизован. Выполните `grok login` в терминале и повторите попытку.", + grokCliMcpStartupFailed: "Grok загрузил конфигурацию MCP, но не смог запустить DBX MCP Server. Проверьте «Настройки > MCP» и диагностику ниже.", + grokCliCommandLineTooLong: "Windows отклонил команду Grok CLI из-за слишком большой длины. Обновите DBX и повторите попытку с использованием созданного файла запроса.", + grokCliRunFailed: "Grok CLI неожиданно завершился. Используйте код ошибки и диагностику ниже, чтобы определить сбойный исполняемый файл или вывод CLI.", + codeBuddyNotInstalled: "CodeBuddy Code CLI не найден. Установите CodeBuddy Code или укажите путь к исполняемому файлу в «Настройки > ИИ».", + codeBuddyCliPathInvalid: "Путь к CodeBuddy Code CLI недействителен. Выберите только исполняемый файл codebuddy, а переменные окружения настройте отдельно.", + codeBuddyEnvInvalid: "Недопустимое имя переменной окружения CodeBuddy. Используйте имена вида HTTPS_PROXY.", + codeBuddyEnvReserved: "Переменная окружения MCP, управляемая DBX, была переопределена. Удалите переменные DBX_MCP_* из конфигурации провайдера.", + codeBuddyNotAuthenticated: "CodeBuddy Code не авторизован. Откройте `codebuddy` в терминале, войдите и повторите попытку.", + codeBuddyTimeout: "CodeBuddy Code CLI не ответил до истечения тайм-аута операции.", + codeBuddyMcpConfigInvalid: "CodeBuddy Code не смог прочитать временную конфигурацию DBX MCP. Проверьте диагностику ниже.", + codeBuddyMcpStartupFailed: "CodeBuddy Code загрузил конфигурацию MCP, но не смог запустить DBX MCP Server. Проверьте «Настройки > MCP» и диагностику ниже.", + codeBuddyProtocolError: "CodeBuddy Code вернул недопустимый управляющий ответ или поток событий JSON. Проверьте версию CodeBuddy Code и диагностику ниже.", + codeBuddyRunFailed: "CodeBuddy Code CLI неожиданно завершился. Используйте код ошибки и диагностику ниже, чтобы определить сбойный исполняемый файл или вывод CLI.", + qoderNotInstalled: "Qoder CLI не найден. Установите Qoder CLI или укажите путь к исполняемому файлу в «Настройки > ИИ».", + qoderCliPathInvalid: "Путь к Qoder CLI недействителен. Выберите только исполняемый файл qodercli, а переменные окружения настройте отдельно.", + qoderEnvInvalid: "Недопустимое имя переменной окружения Qoder CLI. Используйте имена вида HTTPS_PROXY или QODER_PERSONAL_ACCESS_TOKEN.", + qoderEnvReserved: "Переменная окружения MCP, управляемая DBX, была переопределена. Удалите переменные DBX_MCP_* из конфигурации провайдера.", + qoderNotAuthenticated: "Qoder CLI не авторизован. Выполните `qodercli login` в терминале или настройте QODER_PERSONAL_ACCESS_TOKEN, затем повторите попытку.", + qoderTimeout: "Qoder CLI не ответил до истечения тайм-аута операции.", + qoderMcpConfigInvalid: "Qoder CLI не смог прочитать временную конфигурацию DBX MCP. Проверьте версию Qoder CLI и диагностику ниже.", + qoderMcpStartupFailed: "Qoder CLI загрузил конфигурацию MCP, но не смог запустить DBX MCP Server. Проверьте «Настройки > MCP» и диагностику ниже.", + qoderProtocolError: "Qoder CLI вернул недопустимый поток событий JSON. Проверьте версию Qoder CLI и диагностику ниже.", + qoderRunFailed: "Qoder CLI неожиданно завершился. Используйте код ошибки и диагностику ниже, чтобы определить сбойный исполняемый файл или вывод CLI.", + cursorEnvInvalid: "Недопустимое имя переменной окружения Cursor CLI. Используйте имена вида HTTPS_PROXY.", + cursorEnvReserved: "Переменная окружения Cursor или управляемая DBX была переопределена. Удалите переменные CURSOR_CONFIG_DIR, CURSOR_DATA_DIR и DBX_MCP_* из конфигурации провайдера.", + cursorNotAuthenticated: "Cursor CLI не авторизован. Выполните `agent login` в терминале и повторите попытку.", + cursorMcpStartupFailed: "Cursor не смог запустить привязанный сервер DBX MCP. Проверьте «Настройки > MCP» и диагностику ниже.", + cursorTimeout: "Cursor CLI не ответил до истечения тайм-аута операции.", + cursorProtocolError: "Cursor CLI вернул недопустимый поток событий JSON. Проверьте версию Cursor CLI и диагностику ниже.", + cursorRunFailed: "Cursor CLI неожиданно завершился. Используйте код ошибки и диагностику ниже, чтобы определить сбойный исполняемый файл или вывод CLI.", + }, + actions: { + auto: "Авто", + general: "Общее", + generate: "Сгенерировать SQL", + explain: "Пояснить SQL", + optimize: "Оптимизировать SQL", + fix: "Исправить ошибку", + convert: "Преобразовать диалект", + sampleData: "Образец данных", + query: "Запросить данные", + exploreSchema: "Изучить схему", + executeAndExplain: "Запустить и пояснить", + generateNoExec: "Сгенерировать (без запуска)", + }, + routing: { + recognizing: "Определение намерения…", + chip: "Авто · {action}", + switchTo: "Переключить на {action}", + }, + placeholders: { + general: "Спросите что угодно...", + generate: "Опишите, что нужно запросить, например заказы на пользователя за последние 7 дней", + explain: "Необязательно: добавьте, что хотите понять", + optimize: "Необязательно: добавьте цель, например сократить полные сканирования таблиц", + fix: "Вставьте ошибку или опишите ожидаемый результат", + convert: "например, преобразовать в PostgreSQL / MySQL / SQL Server", + sampleData: "Опишите образец данных или тестовые выражения для генерации", + query: "Опишите, что запросить или посчитать, например суммы заказов по регионам за этот месяц", + exploreSchema: "Опишите таблицу или структуру для изучения, например столбцы и индексы таблицы orders", + executeAndExplain: "Необязательно: добавьте, на чём сосредоточиться в пояснении", + }, + editMessage: "Изменить сообщение", + editResend: "Отправить снова", + editCancel: "Отмена", + cannotDeleteActiveConfig: "Нельзя удалить текущую активную конфигурацию. Сначала переключитесь на другую.", + globalInstructions: "Глобальные пользовательские инструкции", + globalInstructionsDescription: "Автоматически применяются ко всем диалогам с ИИ.", + globalInstructionsCharCount: "{count}/{max} символов", + globalInstructionsSaved: "Глобальные инструкции сохранены", + globalInstructionsSave: "Сохранить", + globalInstructionsTooLong: "Глобальные инструкции слишком длинные (макс. {max} символов)", + customInstructionsLoadFailed: "Не удалось загрузить пользовательские инструкции ИИ. Повторите попытку.", + maxAgentTurns: "Лимит шагов агента", + maxAgentTurnsDescription: "Максимальное число шагов с вызовом инструментов за один запуск API-агента до паузы с запросом продолжения. CLI-провайдеры используют собственные лимиты запуска.", + maxAgentTurnsRange: "{min}–{max}, по умолчанию {default}", + maxAgentTurnsSaved: "Лимит шагов агента сохранён", + pluginHttpModelOnly: "Для анализа плагина выберите HTTP-модель или Ollama в меню моделей.", + pluginWelcome: "Спросите об этом снимке данных и продолжите диалог здесь", + pluginFollowUp: "Задайте уточняющий вопрос об этом снимке…", + defaultAiMode: "Режим ИИ по умолчанию", + defaultAiModeDescription: "Режим, используемый при начале нового диалога с ИИ. Переключение режима в текущем диалоге не изменяет эту настройку.", + defaultAutoRouting: "Автоопределение намерения по умолчанию", + defaultAutoRoutingDescription: "Начинать новые диалоги с ИИ с действия «Авто»: ассистент определяет ваше намерение при отправке и направляет его в конкретное действие. Не изменяет текущий диалог.", + restoreLastConversation: "Восстанавливать последний диалог с ИИ", + restoreLastConversationDescription: "Если включено, при открытии ИИ-ассистента загружается последний обновлённый диалог вместо пустого.", + promptTemplates: "Шаблоны запросов для сценариев", + promptTemplatesDescription: "Выберите один или несколько шаблонов в ИИ-ассистенте, чтобы добавить соглашения для конкретного сценария.", + promptTemplateNew: "Новый шаблон", + promptTemplateEdit: "Изменить шаблон", + promptTemplateName: "Имя шаблона", + promptTemplateNamePlaceholder: "например, правила для рабочей БД", + promptTemplateContent: "Содержимое шаблона", + promptTemplateContentPlaceholder: "Опишите соглашение или инструкцию...", + promptTemplateNameEmpty: "Имя шаблона не может быть пустым", + promptTemplateNameExists: "Шаблон с именем '{name}' уже существует", + promptTemplateContentRequired: "Содержимое шаблона не может быть пустым", + promptTemplateDeleteTitle: "Удалить шаблон", + promptTemplateDeleteConfirm: "Удалить шаблон '{name}'? Это действие необратимо.", + promptTemplateTooLong: "Содержимое шаблона слишком длинное (макс. {max} символов)", + promptTemplateNameTooLong: "Имя шаблона слишком длинное (макс. {max} символов)", + promptTemplateSaved: "Шаблон сохранён", + promptTemplateDeleted: "Шаблон удалён", + promptTemplateNoTemplates: "Шаблонов пока нет. Создайте один, чтобы начать.", + promptTemplateManage: "Управление шаблонами", + promptTemplateSavedHint: "Изменения сохраняются автоматически.", + templateSelectorNone: "Не выбрано", + templateSelectorButton: "Шаблоны", + templateSelectorLabel: "Шаблоны: {label}", + templateSelectorDeselectAll: "Снять выделение", + templateSelectorLoading: "Загрузка...", + skillsEntry: "Навыки", + skillsLoading: "Загрузка навыков…", + skillsEmpty: "Навыки пока не найдены", + skillsRefresh: "Обновить", + skillsLoadError: "Не удалось загрузить навыки", + skillsRetry: "Повторить", + skillsOpenSettings: "Открыть настройки", + skillsSendBlocked: "Запрос не отправлен", + skillsGroupDefault: "Каталог по умолчанию", + skillsGroupCustom: "Пользовательский каталог", + skillsReasonNotFound: "Папка навыка или SKILL.md больше не существует", + skillsReasonRootUnavailable: "Его исходный каталог недоступен (отключён, перемещён или удалён)", + skillsReasonOversized: "SKILL.md превышает ограничение размера в 1 МиБ", + skillsReasonNotUtf8: "SKILL.md больше не является корректным UTF-8", + skillsReasonInvalidFrontmatter: "В frontmatter файла SKILL.md отсутствует name/description или он имеет неверный формат", + skillsReasonUnreadable: "Не удалось прочитать SKILL.md", + skillsTotalTrimmed: "Некоторые выбранные навыки превышают общий лимит содержимого ({max} символов) и были пропущены при этой отправке.", + templateSelectorEmpty: "Шаблонов нет. Нажмите «Управление», чтобы добавить.", + templateSelectorTooLong: "Выбранные шаблоны превышают общий лимит содержимого ({max} символов). Снимите выделение с некоторых, чтобы продолжить.", + templateSetDefault: "Сделать по умолчанию", + templateDefaultsTitle: "По умолчанию для типов баз данных", + templateDefaultsEmpty: "Пока не является шаблоном по умолчанию ни для одного типа базы данных. Шаблоны по умолчанию применяются автоматически при открытии панели ИИ для подходящего подключения.", + templateDefaultBadgeTitle: "Шаблон по умолчанию для {type}", + exportMarkdown: "Экспортировать как Markdown", + analysis: "Анализ ИИ", + chartDownloadPng: "Скачать PNG", + chartDownloadFailed: "Не удалось скачать изображение диаграммы", + chartData: "Данные диаграммы", + htmlPreviewLabel: "Предпросмотр HTML, созданного ИИ", + htmlExpandPreview: "Открыть увеличенный предпросмотр", + htmlExpandPreviewHint: "Этот предпросмотр работает полностью в песочнице — скрипты и доступ к сети заблокированы.", + htmlSaveSafe: "Сохранить безопасный HTML", + htmlSaveFailed: "Не удалось сохранить файл HTML", + htmlCopySource: "Копировать исходный код", + htmlCopyRiskBody: "Этот HTML создан ИИ. Открытие его вне DBX может привести к выполнению скриптов и доступу к сети.", + htmlCopyRiskAccept: "Всё равно скопировать", + htmlCopyRiskRemember: "Больше не спрашивать в этом сеансе", + htmlCopyRiskToast: "Скопировано. Этот HTML, созданный ИИ, может выполнять скрипты или обращаться к сети при открытии вне DBX.", + exportConversation: "Экспортировать диалог", + conversationExportMarkdown: "Экспортировать как Markdown", + conversationExportHtml: "Экспортировать как HTML", + conversationRoleUser: "Пользователь", + conversationRoleAssistant: "ИИ", + conversationFailedMarker: "Не удалось сгенерировать этот ответ", + conversationExportEmpty: "Пока нет сообщений для экспорта", + renameConversation: "Переименовать диалог", + conversationRenameFailed: "Не удалось переименовать диалог", + clearDatabaseSelection: "Очистить выбор", + searchDatabases: "Поиск баз данных…", + noDatabasesFound: "Базы данных не найдены", + }, + contextMenu: { + openConnection: "Открыть подключение", + closeConnection: "Закрыть подключение", + closeSelectedConnections: "Закрыть выбранные подключения ({count})", + closeDatabaseConnection: "Закрыть подключение к базе данных", + deleteConnection: "Удалить подключение", + deleteSelectedConnections: "Удалить выбранные подключения ({count})", + confirmDeleteTitle: "Удалить подключение", + confirmDeleteMessage: 'Вы уверены, что хотите удалить "{name}"? Это действие необратимо.', + confirmDeleteSelectedMessage: "Вы уверены, что хотите удалить выбранные подключения ({count})? Это действие необратимо.", + editConnection: "Изменить подключение", + revealDatabaseFile: "Показать в проводнике", + selectVisibleDatabases: "Выбрать видимые базы данных", + configureVisibleObjects: "Фильтр видимых объектов", + userAdmin: "Пользователи и права", + openUserAdmin: "Открыть «Пользователи и права»", + processList: "Список процессов", + sqlServerTrace: "Трассировка активности", + serverDashboard: "Панель сервера", + damengUsers: "Пользователи Dameng", + openDamengUsers: "Открыть управление пользователями Dameng", + damengRoles: "Роли Dameng", + openDamengRoles: "Открыть управление ролями Dameng", + damengJobAdmin: "Задания агента Dameng", + openDamengJobAdmin: "Открыть задания агента Dameng", + duplicateConnection: "Дублировать подключение", + duplicateSelectedConnections: "Дублировать выбранные подключения ({count})", + newQuery: "Новый запрос", + addToAi: "Добавить в ИИ", + addToAiMultiple: "Добавить в ИИ (таблиц: {count})", + instanceInfo: "Сведения об экземпляре", + newSql: "Новый SQL", + generateSql: "Сгенерировать SQL", + newInsert: "Новый Insert", + newUpdate: "Новый Update", + sqlHistory: "История запросов", + noSqlHistory: "Связанного SQL нет", + openObjectBrowser: "Обзор объектов", + openDatabaseBrowser: "Обзор баз данных", + viewData: "Просмотр данных", + openInNewDataTab: "Открыть в новой вкладке", + peekStructure: "Просмотр структуры", + editStructure: "Изменить структуру", + editColumn: "Изменить столбец", + editIndex: "Изменить индекс", + refreshChildren: "Обновить", + collapseAll: "Свернуть все", + expandAll: "Развернуть все", + tableNameFilters: "Фильтры...", + tableNameFiltersDescription: "Показывать только имена объектов из списка включения, затем скрывать имена из списка исключения. По одному шаблону SQL LIKE в строке.", + tableNameFilterInclude: "Шаблоны имён объектов для включения", + tableNameFilterExclude: "Шаблоны имён объектов для исключения", + tableNameFilterIncludePlaceholder: "Пример:\nads_%\nuser_%", + tableNameFilterExcludePlaceholder: "Пример:\n%_bak\ntmp_%", + tableNameFilterLikeHint: "Используйте синтаксис SQL LIKE: % соответствует любым символам, _ — одному символу. Сопоставление не учитывает регистр.", + pin: "Закрепить", + reorderPinned: "Изменить порядок закреплённого элемента", + unpin: "Открепить", + pinTab: "Закрепить вкладку", + unpinTab: "Открепить вкладку", + refreshTab: "Обновить данные", + renameTab: "Переименовать вкладку", + duplicateTab: "Дублировать вкладку", + splitRight: "Разделить справа", + splitDown: "Разделить снизу", + changeOrientation: "Изменить направление разделения", + unsplit: "Отменить разделение", + compactTabTitle: "Сократить заголовки вкладок", + fullTabTitle: "Показывать полные заголовки вкладок", + closeTab: "Закрыть вкладку", + editTabGroup: "Изменить группу вкладок", + resetTabGroup: "Сбросить группу вкладок", + closeTabGroup: "Закрыть группу вкладок", + closeFixedTab: "Закрыть закреплённую вкладку", + closeLeftTabs: "Закрыть вкладки слева", + closeRightTabs: "Закрыть вкладки справа", + closeOtherTabs: "Закрыть другие вкладки", + closeOtherRegularTabs: "Закрыть другие обычные вкладки", + closeOtherFixedTabs: "Закрыть другие закреплённые вкладки", + closeAllTabs: "Закрыть все вкладки", + closeAllRegularTabs: "Закрыть все обычные вкладки", + closeAllFixedTabs: "Закрыть все закреплённые вкладки", + copyName: "Копировать имя", + name: "Имя", + fullPath: "Полный путь", + copyFinalProxyPort: "Копировать итоговый порт прокси", + finalProxyPortCopied: "Итоговый порт прокси {port} скопирован", + copyConnectionInfo: "Копировать сведения о подключении", + copyConnectionUrl: "URL подключения", + copyConnectionUrlWithPassword: "URL подключения (с паролем)", + copyJdbcUrl: "JDBC URL", + copyJdbcUrlWithCredentials: "JDBC URL (с учётными данными)", + copyHostPort: "Хост:порт", + copyDsn: "DSN (key=value)", + copyDsnWithPassword: "DSN (с паролем)", + copyPsqlCommand: "Команда psql", + copyPasswordConfirmTitle: "Копировать с паролем", + copyPasswordConfirmMessage: "Скопированный текст будет содержать сохранённый пароль в виде обычного текста. Продолжить?", + copyPasswordConfirmAction: "Копировать", + setDefaultDatabase: "Сделать базой данных по умолчанию", + clearDefaultDatabase: "Сбросить базу данных по умолчанию", + setDefaultSchema: "Сделать схемой по умолчанию", + clearDefaultSchema: "Сбросить схему по умолчанию", + exportDatabase: "Экспортировать базу данных", + exportAllDatabases: "Экспортировать все базы данных", + exportDatabaseSuccess: "Экспортировано таблиц: {count}, до {limit} строк каждая", + exportDatabaseFailed: "Не удалось экспортировать базу данных: {message}", + backupSqliteDatabase: "Резервное копирование базы данных SQLite", + restoreSqliteDatabase: "Восстановление базы данных SQLite", + backupSqliteDatabaseInProgress: "Резервное копирование базы данных SQLite...", + backupSqliteDatabaseSuccess: "Резервная копия базы данных SQLite создана", + backupSqliteDatabaseFailed: "Не удалось создать резервную копию базы данных SQLite: {message}", + restoreSqliteDatabaseInProgress: "Восстановление базы данных SQLite...", + restoreSqliteDatabaseSuccess: "База данных SQLite восстановлена", + restoreSqliteDatabaseFailed: "Не удалось восстановить базу данных SQLite: {message}", + importData: "Импортировать данные", + exportData: "Экспортировать данные", + exportDataMultiple: "Экспортировать данные (таблиц: {count})", + exportDataSelectDirectory: "Выберите папку экспорта", + exportDataMultipleSuccess: "Экспортировано таблиц: {count}", + exportStructure: "Экспортировать структуру", + exportStructurePreviewTitle: "Структура — {name}", + exportStructurePreviewTitleMultiple: "Структура — объектов: {count}", + exportStructureLoading: "Загрузка структуры...", + copyStructure: "Копировать структуру", + copyStructureAs: "Копировать структуру как", + copyStructureAsTsv: "TSV (для Excel)", + copyStructureAsMarkdown: "Таблица Markdown", + structureDocTable: "Таблица", + structureDocColumn: "Столбец", + structureDocType: "Тип", + structureDocPrimaryKey: "Первичный ключ", + structureDocNullable: "Допускает NULL", + structureDocDefault: "По умолчанию", + structureDocComment: "Комментарий", + structureDocYes: "Да", + structureDocNo: "Нет", + structureDocCopied: "Структура скопирована", + structureDocCopyFallbackHint: "Автоматическое копирование заблокировано. Нажмите «Копировать» ещё раз или выделите содержимое ниже.", + saveStructure: "Сохранить SQL", + exportStructureCopied: "Структура скопирована", + createTable: "Создать таблицу", + createView: "Создать представление", + createProcedure: "Создать процедуру", + createFunction: "Создать функцию", + createTrigger: "Создать триггер", + dropTable: "Удалить таблицу", + emptyTable: "Очистить таблицу", + truncateTable: "Усечь таблицу", + vacuumTable: "Выполнить VACUUM", + vacuumTableTitle: "Выполнить VACUUM", + vacuumTableMessage: 'Выполнить VACUUM для "{name}"?', + vacuumTableAnalyze: "ANALYZE", + vacuumTableAnalyzeHint: "Обновляет статистику оптимизатора. Это может изменить последующие планы запросов и создаёт дополнительную нагрузку на CPU и дисковый ввод-вывод.", + vacuumTableFull: "FULL", + vacuumTableFullHint: "Высокий риск: перезаписывает всю таблицу и берёт исключительную блокировку. Чтение и запись могут быть заблокированы, может потребоваться дополнительное место на диске.", + vacuumTableDefaultRisk: "Плановая операция: возможна дополнительная нагрузка на дисковый ввод-вывод, длительность зависит от размера таблицы.", + vacuumTableAnalyzeRisk: "Статистика оптимизатора будет обновлена, что может изменить последующие планы запросов.", + vacuumTableFullRisk: "Высокий риск: перезаписывает всю таблицу и берёт исключительную блокировку, что может заблокировать чтение и запись и потребовать дополнительного места на диске.", + vacuumTableFullConfirm: "Выполнить VACUUM FULL", + vacuumTableRunning: "VACUUM выполняется...", + vacuumTableRunningHint: "VACUUM выполняется. Большие таблицы могут обрабатываться долго; не закрывайте эту операцию.", + vacuumTableSuccess: "VACUUM завершён для «{name}»", + mysqlAutoIncrement: "Задать AUTO_INCREMENT", + mysqlAutoIncrementTitle: "Задать MySQL AUTO_INCREMENT", + mysqlAutoIncrementMessage: "Задать запрошенное следующее значение AUTO_INCREMENT для «{name}»?", + mysqlAutoIncrementNonemptyHint: "Для непустой таблицы MySQL не переиспользует занятые ID. Фактическое следующее значение остаётся не меньше MAX(id) + 1.", + mysqlAutoIncrementValue: "Запрошенное следующее значение", + duplicateStructure: "Клонировать как новую таблицу", + renameObject: "Переименовать", + renameObjectTitle: "Переименовать объект", + renameObjectNamePlaceholder: "Новое имя", + renameObjectSuccess: "«{oldName}» переименован в «{newName}»", + renameDatabase: "Переименовать базу данных", + renameDatabaseTitle: "Переименовать базу данных", + renameDatabaseNotOwner: "Только владелец базы данных может переименовать «{name}».", + renameDatabasePreparedTransactions: "В базе данных «{name}» есть незавершённые подготовленные транзакции ({count}). Сначала выполните COMMIT или ROLLBACK.", + confirmDropTableTitle: "Удалить таблицу", + confirmDropTableMessage: "Вы уверены, что хотите удалить «{name}»? Таблица и все её данные будут безвозвратно удалены.", + dropTableCascade: "Использовать CASCADE", + dropTableCascadeHint: "Также удалить зависимые объекты, например представления. Если выключено, используется поведение PostgreSQL по умолчанию — RESTRICT.", + truncateTableCascade: "Использовать CASCADE", + truncateTableCascadeHint: "Также очистить таблицы, ссылающиеся на эту через внешние ключи. Если выключено, используется поведение PostgreSQL по умолчанию — RESTRICT.", + confirmEmptyTableTitle: "Очистить таблицу", + confirmEmptyTableMessage: "Вы уверены, что хотите удалить все данные из «{name}»?", + confirmTruncateTableTitle: "Очистить таблицу (TRUNCATE)", + confirmTruncateTableMessage: "Вы уверены, что хотите выполнить TRUNCATE «{name}»? Все строки будут удалены.", + mysqlAutoIncrementSuccess: "Запрошен AUTO_INCREMENT {value} для таблицы «{name}»", + dropTableSuccess: "Таблица «{name}» удалена", + editView: "Редактировать представление", + viewSource: "Просмотреть исходный код", + viewDependencies: "Просмотреть зависимости", + viewObject: "Просмотреть", + changeOpenMode: "Изменить режим открытия", + viewDetails: "Просмотреть сведения", + viewDdl: "Просмотреть DDL", + viewDdlLoading: "Загрузка DDL...", + ddlCopied: "DDL скопирован", + excludeDdlStorage: "Исключить атрибуты хранения", + excludeDdlStorageHint: "Применяется к отображению, копированию и экспорту структуры DDL Oracle и OceanBase Oracle. Отключите, чтобы сохранить параметры сжатия, реплик и хранения. Секции и ограничения сохраняются.", + refreshDdlOnOpen: "Обновлять при каждом открытии", + refreshDdlOnOpenHint: "Если включено, DDL перезагружается из базы данных при каждом открытии; если выключено, предпочтение отдаётся кэшированным данным", + dropObject: "Удалить объект", + dropEventSuccess: "Событие «{name}» удалено", + editObject: "Редактировать объект", + createEvent: "Создать событие", + eventEditorTitle: "Событие MySQL", + eventDefinition: "Определение", + eventSchedule: "Расписание", + eventComment: "Комментарий", + eventSqlPreview: "Предпросмотр SQL", + eventName: "Имя", + eventBodyPlaceholder: "Тело события, например CALL procedure();", + eventExecuteAt: "Выполнить в", + eventIntervalValue: "Значение интервала", + eventIntervalUnit: "Единица интервала", + eventStarts: "Начало", + eventEnds: "Окончание", + eventCompletion: "Завершение", + eventStatus: "Статус", + eventCommentPlaceholder: "Необязательный комментарий", + eventLoading: "Загрузка...", + eventCancel: "Отмена", + eventSave: "Сохранить", + dropView: "Удалить представление", + dropColumn: "Удалить столбец", + dropIndex: "Удалить индекс", + dropAllIndexes: "Удалить все индексы", + createMongoIndex: "Создать индекс", + createMongoIndexTitle: "Создать индекс: «{collection}»", + createMongoIndexFields: "Поля индекса", + createMongoIndexFieldRequired: "Выберите или введите поле для каждой строки индекса.", + mongoIndexAscending: "По возрастанию (1)", + mongoIndexDescending: "По убыванию (-1)", + createMongoIndexNamePlaceholder: "Создаётся автоматически", + createMongoIndexNameHint: "Оставьте пустым, чтобы MongoDB сгенерировала имя из полей и типов.", + createMongoIndexSparse: "Разреженный", + createMongoIndexTtlInvalid: "Время устаревания должно быть целым числом секунд.", + createMongoIndexFilterInvalid: 'Частичный фильтр должен быть объектом, например { "status": "active" }.', + createMongoIndexBucketSizeInvalid: "Размер bucket должен быть целым числом.", + manageMongoIndexes: "Управление индексами", + manageMongoIndexesTitle: "Индексы: «{collection}»", + mongoIndexKeys: "Ключи", + mongoIndexEmpty: "В этой коллекции пока нет индексов.", + mongoIndexSelectHint: "Выберите индекс, чтобы просмотреть его свойства.", + mongoIndexReadOnlyHint: "MongoDB не может изменить существующий индекс. Удалите его и создайте новый, чтобы изменить свойства.", + editMongoIndex: "Редактировать индекс", + saveMongoIndex: "Сохранить", + mongoIndexRebuildHint: "При сохранении индекс пересоздаётся: старый индекс удаляется и создаётся новый.", + mongoEditIndexSuccess: "Индекс «{oldName}» пересоздан как «{newName}» в «{collection}»", + mongoEditIndexNotFound: "Индекс «{name}» больше не существует на сервере. Список мог устареть — обновите его и повторите попытку.", + mongoEditIndexStale: "Индекс «{name}» был изменён другой сессией после открытия диалога. Обновите список и повторите попытку.", + mongoEditIndexIncompleteSameName: "Индекс «{name}» не имеет полной спецификации на сервере, поэтому его нельзя деструктивно пересоздать с тем же именем.", + mongoEditIndexDropFailed: "Не удалось удалить индекс «{name}»; замена не создана: {error}", + mongoEditIndexDropFailedAfterCreate: "Индекс «{newName}» создан, но исходный индекс «{oldName}» удалить не удалось: {error}", + mongoEditIndexCreateFailedRolledBack: "Не удалось создать замену для индекса «{name}», поэтому исходный индекс восстановлен: {error}", + mongoEditIndexCreateAndRollbackFailed: "Не удалось создать замену для индекса «{name}» ({createError}), и восстановить исходный индекс тоже не удалось ({rollbackError}).", + mongoIndexExtraOptionsPreserved: "Параметры, сообщённые сервером (collation, wildcardProjection, weights, …), сохраняются при пересоздании.", + dropForeignKey: "Удалить внешний ключ", + dropTrigger: "Удалить триггер", + batchDrop: "Удалить выбранные ({count})", + batchEmpty: "Очистить выбранные ({count})", + batchTruncate: "Очистить выбранные (TRUNCATE) ({count})", + batchMysqlAutoIncrement: "Задать AUTO_INCREMENT ({count})", + batchDropIndexes: "Удалить индексы ({count})", + executeProcedure: "Выполнить процедуру", + compileObject: "Скомпилировать", + compileObjectSuccess: "«{name}» успешно скомпилирован", + compileObjectFailedTitle: "Ошибка компиляции представления", + compileObjectFailedMessage: "Ошибка компиляции представления «{name}»:\n{message}", + confirmExecuteProcedureTitle: "Выполнить процедуру", + confirmExecuteProcedureMessage: "Выполнить процедуру «{name}»? Сначала можно заполнить или изменить значения параметров.", + loadingProcedureParameters: "Загрузка параметров...", + procedureParametersUnavailable: "Не удалось загрузить метаданные параметров. Вы всё равно можете отредактировать SQL ниже и выполнить его.", + noProcedureParameters: "Параметры не найдены. Текущий SQL будет выполнен как показано.", + inputParameters: "{count} входных параметров", + outputParameters: "{count} выходных параметров", + parameterName: "Имя", + parameterType: "Тип", + parameterMode: "Режим", + parameterValue: "Значение", + parameterNull: "NULL", + parameterDefault: "DEFAULT", + parameterDefaultHint: "Если отмечено DEFAULT, DBX пропускает этот аргумент, и база данных использует значение процедуры по умолчанию.", + parameterValuePlaceholder: "Введите значение", + outputOnly: "Только выходной", + sqlPreview: "Предпросмотр SQL", + resetSqlPreview: "Сбросить SQL", + openInSqlEditor: "Открыть в редакторе", + dropProcedure: "Удалить процедуру", + dropFunction: "Удалить функцию", + manageExtension: "Управление расширениями...", + dropExtension: "Удалить расширение", + confirmDropViewTitle: "Удалить представление", + confirmDropViewMessage: "Вы уверены, что хотите удалить представление «{name}»?", + confirmDropObjectTitle: "Удалить объект", + confirmDropObjectMessage: "Вы уверены, что хотите удалить «{name}»?", + confirmDropColumnTitle: "Удалить столбец", + confirmDropIndexTitle: "Удалить индекс", + confirmDropMongoIndexMessage: "Вы уверены, что хотите удалить индекс «{name}» из коллекции «{collection}»?", + confirmDropMongoAllIndexesMessage: "Вы уверены, что хотите удалить все удаляемые индексы из коллекции «{name}»?", + confirmDropMongoAllIndexesDetails: 'MongoDB сохраняет индекс "_id_". Также могут остаться индексы, необходимые для ключа шардирования; в результате будут перечислены только фактически удалённые индексы.', + confirmDropForeignKeyTitle: "Удалить внешний ключ", + confirmDropTriggerTitle: "Удалить триггер", + confirmDropTableChildObjectMessage: "Вы уверены, что хотите удалить «{name}» из «{table}»?", + confirmDropBatchIndexesMessage: "Вы уверены, что хотите удалить {count} выбранных индексов из «{table}»? Это действие необратимо.", + confirmBatchDropTitle: "Удалить выбранные объекты", + confirmBatchDropMessage: "Вы уверены, что хотите удалить {count} выбранных объектов? Это действие необратимо.", + confirmBatchEmptyTitle: "Очистить выбранные таблицы", + confirmBatchEmptyMessage: "Вы уверены, что хотите удалить все данные из {count} выбранных таблиц?", + confirmBatchTruncateTitle: "Очистить выбранные таблицы (TRUNCATE)", + confirmBatchTruncateMessage: "Вы уверены, что хотите выполнить TRUNCATE для {count} выбранных таблиц? Все строки будут удалены.", + batchMysqlAutoIncrementTitle: "Задать MySQL AUTO_INCREMENT ({count} таблиц)", + batchMysqlAutoIncrementMessage: "Задать запрошенное следующее значение AUTO_INCREMENT для {count} выбранных таблиц?", + batchMysqlAutoIncrementSuccess: "Запрошен AUTO_INCREMENT {value} для {count} таблиц", + batchMysqlAutoIncrementPartialFail: "AUTO_INCREMENT задан для {success} таблиц, для {failed} не удалось", + confirmDropProcedureTitle: "Удалить процедуру", + confirmDropProcedureMessage: "Вы уверены, что хотите удалить процедуру «{name}»?", + confirmDropFunctionTitle: "Удалить функцию", + confirmDropFunctionMessage: "Вы уверены, что хотите удалить функцию «{name}»?", + confirmDropEventTitle: "Удалить событие", + confirmDropEventMessage: "Вы уверены, что хотите удалить событие «{name}»?", + dropViewSuccess: "Представление «{name}» удалено", + dropProcedureSuccess: "Процедура «{name}» удалена", + dropFunctionSuccess: "Функция «{name}» удалена", + dropTableChildObjectSuccess: "«{name}» удалён", + dropAllIndexesSuccess: "Удалено индексов из «{name}»: {count}", + dropIndexesPartialFailure: "Удалено индексов: {success}; не удалось: {failed}.", + createMongoIndexSuccess: "Индекс «{name}» создан в «{collection}»", + mongoIndexRefreshFailed: "Не удалось обновить список индексов после операции: {message}", + batchDropSuccess: "Удалено объектов: {count}", + batchEmptySuccess: "Очищено таблиц: {count}", + batchEmptyPartialFail: "Очищено таблиц: {success}, не удалось: {failed}", + batchEmptySubmitted: "Отправлено задач очистки для {count} таблиц", + batchEmptySubmittedPartial: "Отправлено задач очистки: {success}, не удалось: {failed}", + batchTruncateSuccess: "Выполнен TRUNCATE для {count} таблиц", + emptyTableSuccess: "Все данные удалены из «{name}»", + emptyTableSubmitted: "Задача очистки для «{name}» отправлена", + truncateTableSuccess: "Выполнен TRUNCATE для таблицы «{name}»", + duplicateStructureSuccess: "Таблица клонирована как «{name}»", + tableOperationFailed: "Операция не выполнена: {message}", + tableOperationTimedOut: "Операция с «{name}» выполняется дольше ожидаемого и не была отменена — возможно, она всё ещё выполняется в базе данных. Проверьте результат позже или нажмите «Отмена», чтобы остановить её. ({message})", + tableOperationCancelled: "Операция с «{name}» отменена", + tableOperationCancelUnconfirmed: "Запрос на отмену для «{name}» не подтверждён базой данных — операция могла уже завершиться или всё ещё выполняться. Проверьте результат. ({message})", + tableOperationCancelPending: "Запрос на отмену для «{name}» пока не подтверждён — возможно, операция всё ещё выполняется в базе данных. Попробуйте нажать «Отмена» ещё раз или проверьте позже.", + dangerOperationAlreadyRunning: "Другая опасная операция всё ещё выполняется. Дождитесь её завершения или отмените её, прежде чем начинать новую.", + objectDropRefreshFailed: "Объекты удалены, но не удалось обновить боковую панель: {message}", + duplicateNameTitle: "Клонировать как новую таблицу", + duplicateNamePlaceholder: "Имя новой таблицы", + copyTable: "Копировать таблицу", + pasteTable: "Вставить таблицу", + pasteOptionStructureAndData: "Структура и данные", + pasteOptionStructureOnly: "Только структура", + pasteOptionDataOnly: "Только данные", + pasteTableSuccess: "Таблица вставлена как «{name}»", + pasteTableConfirmTitle: "Вставить таблицу", + pasteTableConfirmMessage: "Вставить таблицу из буфера обмена", + batchPasteTitle: "Вставить таблицы", + batchPasteSuccess: "Успешно вставлено таблиц: {count}", + batchPastePartialFail: "Вставлено таблиц: {success}, не удалось: {failed}", + pasteTableRefreshFailed: "Таблицы вставлены, но не удалось обновить список объектов: {message}", + pasteTableCancelledAfterPartial: "Вставка отменена. Таблицы, созданные до отмены, были обновлены; содержимое буфера обмена сохранено.", + noTableToPaste: "Нет таблиц для вставки", + pasteTableClipboardUpdated: "Таблица скопирована в буфер обмена", + createDatabase: "Создать базу данных", + createDuckDbFile: "Создать файл базы данных", + attachSqliteDatabase: "Присоединить базу данных SQLite", + dropDatabase: "Удалить базу данных", + confirmDropDatabaseTitle: "Удалить базу данных", + confirmDropDatabaseMessage: "Вы уверены, что хотите удалить базу данных «{name}»? База данных и все её данные будут безвозвратно удалены.", + createDatabaseSuccess: "База данных «{name}» создана", + mysqlCreateDatabasePermissionHint: "Текущая учётная запись MySQL не может создать эту базу данных. Учётная запись с именем root не обязательно обладает правами администратора. Используйте учётную запись администратора с GRANT OPTION, чтобы выдать право CREATE, и повторите попытку.", + createDatabasePartial: "База данных «{name}» создана, но некоторые права выдать не удалось", + createDatabaseFailed: "Не удалось создать базу данных «{name}»", + createDatabaseUsers: "Предоставить доступ пользователям", + createDatabaseUsersHint: "Выбранные пользователи получат полный собственный доступ после создания базы данных.", + createDatabaseUsersSelected: "Выбрано: {count}", + createDatabaseUsersLoading: "Загрузка пользователей...", + createDatabaseUsersLoadFailed: "Не удалось загрузить пользователей: {message}", + previewCreateDatabaseSql: "Предпросмотр SQL", + createDatabaseSqlPreview: "Предпросмотр SQL создания базы данных", + applyCreateDatabaseSql: "Создать и выдать права", + closeCreateDatabaseResult: "Закрыть", + createDatabaseStep: "Создать базу данных «{database}»", + createDatabaseGrantStep: "Предоставить пользователю {user} доступ к базе данных «{database}»", + createDatabaseGrantObjectsStep: "Предоставить пользователю {user} доступ к схеме и объектам в «{database}»", + createDatabaseStepSkipped: "Пропущено, так как необходимый предыдущий шаг завершился ошибкой.", + editDatabaseProperties: "Редактировать свойства базы данных", + editDatabasePropertiesTitle: "Редактировать свойства базы данных: «{name}»", + editDatabasePropertiesSaving: "Сохранение...", + editDatabasePropertiesSuccess: "Свойства базы данных «{name}» обновлены", + editDatabaseComment: "Комментарий к базе данных", + editDatabaseCommentPlaceholder: "Введите комментарий к базе данных...", + createDuckDbFileSuccess: "Файл базы данных DuckDB «{name}» создан и присоединён", + createDuckDbFileDesktopOnly: "Создание файлов баз данных DuckDB доступно только в настольном приложении", + attachSqliteDatabaseSuccess: "База данных SQLite «{name}» присоединена", + attachSqliteDatabaseDesktopOnly: "Присоединение файлов баз данных SQLite доступно только в настольном приложении", + dropDatabaseSuccess: "База данных «{name}» удалена", + dropCollection: "Удалить коллекцию", + elasticsearchViewMapping: "Просмотреть mapping", + elasticsearchViewSettings: "Просмотреть настройки индекса", + elasticsearchViewStats: "Просмотреть статистику индекса", + elasticsearchClearIndex: "Очистить данные индекса", + elasticsearchClearIndexMessage: "Это удалит все документы в индексе {index}. Mapping, настройки и псевдонимы сохранятся. Продолжить?", + elasticsearchClearIndexPatternMessage: "{index} — это сгруппированный шаблон, а не один индекс. Это удалит все документы во всех соответствующих индексах. Mapping, настройки и псевдонимы сохранятся. Продолжить?", + elasticsearchClearIndexTypeToConfirm: "Введите {index} для подтверждения", + elasticsearchClearIndexDetails: "Документы удаляются с помощью _delete_by_query; сам индекс не удаляется.", + elasticsearchClearIndexConfirm: "Очистить данные", + elasticsearchClearIndexDone: "Индекс {index} очищен: удалено документов: {deleted}", + elasticsearchClearIndexPartial: "Индекс {index} очищен частично: удалено документов: {deleted} из {total}. Проверьте конфликты или сбои шардов и запустите снова.", + cloneCollection: "Клонировать коллекцию", + cloneCollectionTitle: "Клонировать как новую коллекцию", + cloneCollectionNamePlaceholder: "Имя новой коллекции", + cloneCollectionSuccess: "Коллекция «{name}» клонирована с {documents} документами и {indexes} индексами", + confirmDropCollectionTitle: "Удалить коллекцию", + confirmDropCollectionMessage: "Вы уверены, что хотите удалить коллекцию «{name}»? Коллекция и все её документы будут безвозвратно удалены.", + dropCollectionSuccess: "Коллекция «{name}» удалена", + createDatabaseNamePlaceholder: "Имя базы данных", + createDatabaseCharset: "Набор символов", + createDatabaseCharsetPlaceholder: "например utf8mb4", + createDatabaseCharsetSearchPlaceholder: "Найдите или введите набор символов", + createDatabaseCharsetEmpty: "Наборы символов не найдены", + createDatabaseCharsetLoading: "Загрузка наборов символов...", + createDatabaseCharsetCustomOption: "Использовать «{value}»", + createDatabaseCollation: "Сопоставление", + createDatabaseCollationPlaceholder: "например utf8mb4_unicode_ci", + createDatabaseCollationSearchPlaceholder: "Найдите или введите сопоставление", + createDatabaseCollationEmpty: "Сопоставления не найдены", + createDatabaseCollationLoading: "Загрузка сопоставлений...", + createDatabaseCollationCustomOption: "Использовать «{value}»", + createSchema: "Создать схему", + dropSchema: "Удалить схему", + confirmDropSchemaTitle: "Удалить схему", + confirmDropSchemaMessage: "Вы уверены, что хотите удалить схему «{name}»? Схема и все её объекты будут безвозвратно удалены.", + createSchemaSuccess: "Схема «{name}» создана", + dropSchemaSuccess: "Схема «{name}» удалена", + dropDamengSchemaRequiresDifferentDba: "Dameng не может безопасно удалить эту схему из текущего подключения. Подключитесь как другой пользователь DBA и повторите попытку.", + createSchemaNamePlaceholder: "Имя схемы", + editSchemaComment: "Редактировать комментарий", + editSchemaCommentTitle: "Редактировать комментарий: «{name}»", + schemaCommentPlaceholder: "Введите комментарий к схеме...", + schemaCommentSaving: "Сохранение...", + editSchemaCommentSuccess: "Комментарий к схеме «{name}» обновлён", + }, + visibleDatabases: { + title: "Видимые базы данных", + detailLabel: "Видимые базы данных", + detailActionLabel: "Настроить видимые базы данных для «{connection}»", + description: "Выберите, какие базы данных отображаются в «{connection}».", + searchPlaceholder: "Поиск баз данных...", + selectedCount: "Выбрано: {selected}/{total}", + patternsPlaceholder: "Шаблоны, например %n1%, через запятую", + patternsHint: "Базы данных, соответствующие этим шаблонам, отображаются всегда (% — любые символы, _ — один символ)", + patternsMatchCount: "Совпадений: {count}", + selectAll: "Выбрать все", + selectFiltered: "Выбрать результаты поиска", + clear: "Очистить", + showAll: "Показать все", + showSystemDatabases: "Показывать системные базы данных", + save: "Сохранить", + emptySelection: "Выберите хотя бы одну базу данных или используйте «Показать все», чтобы сбросить фильтр.", + loadFailed: "Не удалось загрузить базы данных: {message}", + }, + visibleSchemas: { + title: "Фильтр схем", + detailLabel: "Видимые схемы", + detailActionLabel: "Настроить видимые схемы для «{connection}»", + description: "Выберите, какие схемы отображаются в «{connection}».", + searchPlaceholder: "Поиск схем...", + selectedCount: "Выбрано: {selected}/{total}", + selectAll: "Выбрать все", + selectFiltered: "Выбрать результаты поиска", + clear: "Очистить", + showAll: "Показать все", + showSystemSchemas: "Показывать системные схемы", + save: "Сохранить", + emptySelection: "Выберите хотя бы одну схему или используйте «Показать все», чтобы сбросить фильтр.", + loadFailed: "Не удалось загрузить схемы: {message}", + }, + databaseLinks: { + remoteTenant: "Удалённый тенант", + remoteProtocol: "Протокол удалённой базы данных", + remoteCluster: "Удалённый кластер (необязательно)", + oceanbaseRecreateHint: "Для ссылок OceanBase обновление на месте недоступно. Создайте и проверьте замену, прежде чем явно удалять старую ссылку. Существующие ссылки никогда не удаляются автоматически.", + oceanbasePublic: "Публичная", + oceanbaseSharedReadOnly: "Эта публичная ссылка создана другим пользователем. Вы можете проверить и использовать её, но удалить может только её создатель.", + shadowed: "В этой сессии приоритет имеет частная ссылка с тем же именем. Проверьте публичную ссылку от пользователя, у которого нет этой частной ссылки.", + search: "Поиск ссылок на базы данных", + name: "Имя ссылки", + owner: "Владелец", + username: "Удалённый пользователь", + host: "Строка подключения", + password: "Удалённый пароль", + public: "Публичная ссылка (требуется CREATE PUBLIC DATABASE LINK)", + create: "Создать ссылку", + alter: "Обновить учётные данные", + test: "Проверить ссылку", + testSuccess: "Запрос к ссылке на базу данных выполнен успешно.", + empty: "Нет доступных ссылок на базы данных.", + saved: "Ссылка на базу данных обновлена.", + alterHint: "Обновите сохранённый удалённый пароль для {name}. Чтобы изменить пользователя или строку подключения, создайте новую ссылку.", + dropConfirm: "Удалить ссылку на базу данных {owner} / {name}? Удалённые данные при этом не удаляются.", + manage: "Управление ссылками на базы данных", + }, + tree: { + savedSql: "Библиотека SQL", + queries: "Запросы", + userAdmin: "Пользователи и права", + damengUsers: "Пользователи", + damengRoles: "Роли", + damengJobAdmin: "Задания агента", + xuguTablespaces: "Пространства хранения", + xuguDatafiles: "Файлы", + xuguStorage: { + name: "Имя", + nodeId: "ID узла", + spaceId: "ID табличного пространства", + spaceType: "Тип табличного пространства", + datafileCount: "Файлы данных", + totalChunks: "Всего блоков", + freeChunks: "Свободные блоки", + usedChunks: "Использованные блоки", + usage: "Использование", + mediaError: "Ошибка носителя", + path: "Путь", + fileNo: "Номер файла", + currentSize: "Текущий размер", + maxSize: "Максимальный размер", + stepSize: "Шаг роста", + reserved: "Зарезервировано", + unlimited: "Неограничено", + yes: "Да", + no: "Нет", + }, + linkedServers: "Связанные серверы", + defaultDatabase: "БД по умолчанию", + elasticsearchAlias: "Псевдоним", + columns: "Столбцы", + attributes: "Атрибуты", + methods: "Методы", + indexes: "Индексы", + foreignKeys: "Внешние ключи", + triggers: "Триггеры", + events: "События", + constraints: "Ограничения", + tables: "Таблицы", + doltSystemTables: "Системные таблицы Dolt", + tableNameFilterActive: "отфильтровано", + views: "Представления", + materializedViews: "Материализованные представления", + procedures: "Процедуры", + functions: "Функции", + sequences: "Последовательности", + schedulerJobs: "Запланированные задания", + databaseLinks: "Ссылки на базы данных", + synonyms: "Синонимы", + packages: "Пакеты", + types: "Типы", + gridfs: "GridFS", + buckets: "Корзины", + partitions: "Секции", + subpartitions: "Подсекции", + childTables: "Дочерние таблицы", + loadMore: "Загрузить ещё...", + objectBrowser: "Открыть в обозревателе объектов ({count})", + extensions: "Расширения", + }, + extension: { + manageTitle: "Управление расширениями", + installTitle: "Установить расширение", + detailsTitle: "Сведения о расширении", + viewDetails: "Просмотреть сведения", + name: "Имя расширения", + namePlaceholder: "например pg_stat_statements", + install: "Установить", + drop: "Удалить", + available: "Доступные", + installed: "Установленные", + noAvailable: "Все доступные расширения уже установлены.", + noInstalled: "Расширения не установлены.", + }, + processList: { + batchCancel: "Отменить выбранные запросы ({count})", + batchNeedsSession: "Текущая сессия неизвестна. Обновите и повторите попытку.", + selectAll: "Выбрать подходящие загруженные сессии в текущем фильтре", + selectSession: "Выбрать сессию {id}", + batchTitle: "Отмена выбранных запросов", + batchConfirm: "Отменить выполняющиеся запросы в этих сессиях ({count})? Сессии останутся подключёнными.", + batchRunning: "Отмена запросов…", + batchSummary: "Запросы на отмену: успешно {succeeded}, с ошибкой {failed}.", + title: "Список процессов", + sessionCount: "Сессий: {count}", + filter: "Фильтр сессий", + autoRefresh: "Автообновление", + seconds: "с", + colId: "ID", + colUser: "Пользователь", + colHost: "Хост", + colDb: "БД", + colCommand: "Команда", + colTime: "Время", + colState: "Состояние", + colInfo: "Информация", + colPid: "PID", + colClient: "Клиент", + colApp: "Приложение", + colWait: "Ожидание", + colQuery: "Запрос", + colActions: "Действия", + self: "вы", + kill: "Отменить запрос", + cannotKillSelf: "Нельзя отменить запрос в собственной сессии", + empty: "Нет активных сессий.", + killTitle: "Отмена выполняющегося запроса", + killConfirm: "Отменить выполняющийся запрос в сессии {id} ({user})? Сессия останется подключённой.", + killSuccess: "Выполняющийся запрос в сессии {id} отменён", + killFailed: "Не удалось отменить запрос: {message}", + terminate: "Завершить сессию", + cannotTerminateSelf: "Нельзя завершить собственную сессию", + terminateTitle: "Завершение сессии", + terminateConfirm: "Завершить сессию {id} ({user})? Соединение закрывается немедленно, а незафиксированная транзакция откатывается.", + terminateSuccess: "Сессия {id} завершена", + terminateFailed: "Не удалось завершить сессию: {message}", + batchTerminate: "Завершить выбранные сессии ({count})", + batchTerminateTitle: "Завершение выбранных сессий", + batchTerminateConfirm: "Завершить эти сессии ({count})? Соединения закрываются немедленно, а незафиксированные транзакции откатываются.", + batchTerminateRunning: "Завершение сессий…", + batchTerminateSummary: "Запросы на завершение: успешно {succeeded}, с ошибкой {failed}.", + previewTitle: "Инструкция", + copy: "Копировать", + copied: "Скопировано", + }, + sqlServerTrace: { + title: "Трассировка активности SQL Server", + start: "Запустить", + pause: "Приостановить опрос", + resume: "Возобновить", + stop: "Остановить", + clear: "Очистить события", + export: "Экспортировать отфильтрованные события в CSV", + database: "База данных", + selectDatabase: "Выберите базу данных", + maxEvents: "Лимит событий", + duration: "Длительность (мин)", + statements: "Инструкции", + statementsHint: "Захватывать инструкции внутри хранимых процедур. Это событие может существенно увеличить нагрузку.", + highCost: "Высокая нагрузка", + elapsed: "{seconds} с", + eventCount: "Показано событий: {visible} / {total}", + cleanedStaleSessions: "Очищено устаревших сессий трассировки DBX: {count}.", + permissionHint: "Требуются разрешение ALTER ANY EVENT SESSION и права на просмотр состояния сервера", + filterSql: "Фильтр по процедуре или тексту SQL", + filterLogin: "Логин", + filterClient: "Клиент или хост", + filterSession: "ID сессии", + noEvents: "Запустите трассировку, затем выполните SQL или хранимую процедуру в другой сессии.", + noMatches: "Нет событий, соответствующих текущим фильтрам.", + statuses: { + idle: "Готово", + starting: "Запуск", + running: "Выполняется", + paused: "Опрос приостановлен", + stopping: "Остановка", + stopped: "Остановлено", + error: "Ошибка", + }, + eventTypes: { + rpc_completed: "RPC завершён", + sql_batch_completed: "Пакет завершён", + sp_statement_completed: "Инструкция процедуры", + }, + columns: { + time: "Время", + event: "Событие", + database: "База данных", + sql: "Процедура / SQL и параметры", + duration: "Длительность, мс", + cpu: "CPU, мс", + reads: "Чтения", + writes: "Записи", + rows: "Строки", + session: "Сессия", + login: "Логин", + host: "Хост", + client: "Клиент", + result: "Результат", + }, + autoStopped: { + duration: "Трассировка активности остановлена после достижения лимита длительности.", + events: "Трассировка активности остановлена после достижения лимита событий.", + }, + capabilityErrors: { + "unsupported-version": "SQL Server {version} не поддерживает эту трассировку Extended Events. Требуется SQL Server 2008 или новее.", + "unsupported-engine": "В этом выпуске SQL Server используются Extended Events уровня базы данных, которые не поддерживаются в первом релизе.", + "alter-permission": "У текущего логина нет разрешения ALTER ANY EVENT SESSION.", + "view-permission": "У текущего логина нет разрешения на состояние сервера, необходимого для чтения событий трассировки.", + "missing-capability": "В этом экземпляре SQL Server отсутствуют необходимые возможности Extended Events: {capabilities}.", + }, + }, + serverDashboard: { + title: "Панель сервера", + autoRefresh: "Автообновление", + off: "Выкл.", + qps: "Запросов / сек", + connections: "Соединения", + running: "Активные потоки", + trafficIn: "Входящий трафик", + trafficOut: "Исходящий трафик", + slowQueries: "Медленные запросы", + uptime: "Время работы", + innodbHit: "Попадания InnoDB", + in: "Входящий", + out: "Исходящий", + sessions: "Сессии", + qpsChart: "Запросов в секунду", + sessionsChart: "Сессий в секунду", + trafficChart: "Сетевой трафик /с", + commandChart: "Команд в секунду", + rawStatus: "Переменные статуса", + filterStatus: "Фильтр переменных статуса", + tps: "Транзакций / сек", + activeQueries: "Активные запросы", + cacheHit: "Попадания в кэш", + deadlocks: "Дедлоки", + tempFiles: "Временные файлы", + walRate: "Скорость WAL", + commit: "Зафиксировать", + rollback: "Откатить", + total: "Всего", + active: "Активные", + idle: "Простаивающие", + fetched: "Извлечено", + returned: "Возвращено", + read: "Чтение", + hits: "Попадания", + serverSessionsChart: "Сессии сервера", + transactionsChart: "Транзакций в секунду", + tuplesInChart: "Кортежи на входе", + tuplesOutChart: "Кортежи на выходе", + blockIoChart: "Блочный ввод-вывод", + }, + xuguServerDashboard: { + title: "Панель сервера Xugu", + off: "Выкл.", + unsupported: "Эта страница поддерживает только подключения XuguDB.", + loadFailed: "Не удалось прочитать статус работы Xugu.", + partialData: "Некоторые представления мониторинга не удалось прочитать. Возможно, текущей учётной записи не хватает прав на системные представления; доступные данные всё равно показаны.", + readOnlyHint: "Мониторинг только для чтения; состояние базы данных не изменяется", + version: "Версия базы данных", + onlineNodes: "Узлы онлайн", + sessions: "Сессии", + activeCount: "{count} активных", + transactions: "Активные транзакции", + lockWaits: "Ожидания блокировок (уровень таблицы)", + lockOwners: "Удерживаемые блокировки", + nodes: "Состояние узлов", + node: "Узел", + type: "Тип", + state: "Состояние", + cpuLoad: "Загрузка CPU (справочно)", + diskRead: "Чтение с диска", + diskWrite: "Запись на диск", + memoryAndCache: "Кэш и память", + memoryHint: "Из представлений системной памяти", + bufferPool: "Пул буферов данных", + sga: "SGA", + swap: "Swap", + usedPercent: "{percent}% использовано", + dirtyPages: "Грязные {value}", + runtimeAndWrite: "Работа и записи", + cumulativeHint: "Накопительные счётчики; они не сбрасываются при обновлении", + walPending: "WAL ожидает контрольной точки", + transactionSpan: "Диапазон ID транзакций (сигнал риска)", + freeStores: "Свободные хранилища", + datafiles: "Файлы данных", + sessionsAndTransactions: "Сессии и транзакции", + activeSessionHint: "Активные сессии включают этот запрос мониторинга", + idleSessions: "Простаивающие сессии", + executingSessions: "Выполняющиеся сессии", + otherSessions: "Другие состояния", + oldestStatement: "Начало самого старого активного выражения", + oldestTransaction: "Начало самой старой активной транзакции", + locksAndCapacity: "Блокировки и ёмкость", + tablespaces: "Табличные пространства", + mediaErrors: "Ошибки носителя", + lockModes: "Удерживаемые режимы блокировок", + dataTempFree: "DATA/TEMP свободно {value}", + rowLockLimit: "Ожидания блокировок охватывают только блокировки уровня таблицы; блокировку строк ищите через долгие транзакции.", + bootTime: "Время запуска", + rack: "Стойка {rack}", + stores: "{count} хранилищ", + emptyNodes: "Данные об узлах не возвращены, либо у учётной записи нет доступа к SYS_CLUSTERS.", + nodeState: { + joining: "Присоединяется", + running: "Работает", + error: "Ошибка", + offline: "Офлайн", + unknown: "Неизвестно", + }, + nodeType: { + master: "Master", + standby: "Standby", + storage: "Storage", + query: "Query", + worker: "Worker", + change: "Change", + unknown: "Неизвестно", + }, + }, + solrAdmin: { + title: "Администрирование Solr", + refresh: "Обновить", + selectCore: "Выберите core", + noCore: "Core не выбран. Выберите core для просмотра страниц администрирования уровня core.", + emptyBody: "Пустое тело ответа.", + optional: "необязательно", + sections: { + server: "Сервер", + core: "Core", + }, + views: { + dashboard: "Панель", + logging: "Логирование", + javaProps: "Свойства Java", + threads: "Дамп потоков", + coreAdmin: "Администрирование core", + metrics: "Метрики", + overview: "Обзор", + analysis: "Анализ", + documents: "Документы", + paramsets: "Наборы параметров", + files: "Файлы", + ping: "Ping", + plugins: "Плагины / Статистика", + query: "Запрос", + replication: "Репликация", + schema: "Схема", + segments: "Информация о сегментах", + }, + dashboard: { + instance: "Экземпляр", + start: "Запуск", + uptime: "Время работы", + versions: "Версии", + jvmTitle: "JVM", + runtime: "Среда выполнения", + args: "Аргументы", + system: "Система", + physMem: "Физическая память", + swap: "Пространство подкачки", + fd: "Количество файловых дескрипторов", + jvmMemory: "Память JVM", + outdatedWarning: "Этому выпуску Solr больше года. Рассмотрите обновление.", + mode: "Режим", + solr_home: "Solr Home", + core_root: "Core Root", + processors: "Процессоры", + }, + logging: { + name: "Логгер", + level: "Уровень", + set: "Установить", + }, + core: { + name: "Core", + docs: "Документы", + size: "Размер", + segments: "Сегм.", + uptime: "Время работы", + ops: "Действия", + }, + schema: { + fields: "поля", + dynamicFields: "динамические поля", + fieldTypes: "типы полей", + name: "Имя", + type: "Тип", + flags: "Флаги", + }, + analysis: { + field: "Имя поля", + indexValue: "Значение индекса", + queryValue: "Значение запроса (необязательно)", + indexPlaceholder: "Текст, индексируемый в поле", + queryPlaceholder: "Текст запроса, анализируемый во время запроса", + run: "Анализировать", + index: "Цепочка индексации", + query: "Цепочка запроса", + empty: "Этапы анализа не возвращены. Проверьте имя поля.", + }, + segments: { + name: "Сегмент", + deleted: "Удалено", + age: "Возраст", + source: "Источник", + }, + actions: { + create: "Создать Core", + reload: "Перезагрузить", + unload: "Выгрузить", + rename: "Переименовать", + swap: "Поменять", + confirm: 'Выполнить {action} для core "{core}"?', + success: '{action} для "{core}" выполнено', + failed: "Действие администрирования core не удалось: {message}", + newName: "Новое имя core", + swapWith: "Поменять с core", + }, + queryForm: { + defaultParser: "парсер по умолчанию", + paramsets: "набор(ы) параметров", + jsonHint: "непустое значение переключает на POST JSON DSL", + execute: "Выполнить запрос", + openInConsole: "Открыть в консоли", + rowsReturned: "строк", + tableView: "Таблица", + rawJson: "Необработанный JSON", + }, + overview: { + statistics: "Статистика", + instance: "Экземпляр", + replication: "Репликация", + healthcheck: "Проверка работоспособности", + lastModified: "Последнее изменение", + numDocs: "Число документов", + maxDoc: "Макс. документ", + deletedDocs: "Удалённые документы", + version: "Версия", + segmentCount: "Количество сегментов", + current: "Текущий", + cwd: "CWD", + instanceDir: "Экземпляр", + data: "Данные", + index: "Индекс", + impl: "Реализация", + colVersion: "Версия", + colGen: "Поколение", + colSize: "Размер", + leaderSearching: "Лидер (поиск)", + leaderReplicable: "Лидер (репликация)", + noReplication: "Нет данных о репликации лидера для этого core.", + noHealthcheck: "Обработчик запроса Ping не настроен с файлом проверки работоспособности.", + justNow: "только что", + minutesAgo: "около {n} минут назад", + hoursAgo: "около {n} часов назад", + daysAgo: "около {n} дней назад", + }, + replication: { + refresh: "Обновить статус", + disable: "Отключить репликацию", + enable: "Включить репликацию", + index: "Индекс", + settingsLeader: "Настройки (лидер)", + settingsFollower: "Настройки (последователь)", + noDetails: "Нет данных о репликации для этого core.", + }, + }, + userAdmin: { + title: "Пользователи и привилегии", + unsupported: "Поддерживаются подключения, совместимые с MySQL и PostgreSQL. SQL Server, Oracle и другие модели разрешений могут быть добавлены позже.", + newUser: "Новый пользователь", + anonymous: "Анонимный", + roleName: "Имя роли", + allowLogin: "Разрешить вход", + searchUser: "Поиск пользователя или хоста", + loadingUsers: "Загрузка пользователей...", + loadingGrants: "Загрузка привилегий...", + emptyUsers: "Пользователи не найдены, либо текущая учётная запись не может прочитать список пользователей.", + pluginUnknown: "Плагин аутентификации неизвестен", + grants: "Привилегии", + noGrants: "Привилегии не найдены", + privilegeEditor: "Редактор привилегий", + privilegeHint: "Выберите привилегии, базу данных и таблицу, затем просмотрите SQL перед применением. * означает глобально или все таблицы.", + privilegeAppendHint: "Выберите базы данных и укажите область таблиц, затем настройте привилегии для каждой базы данных. Привилегии добавляются и никогда не отзывают существующие.", + globalScope: "Глобально (*.*)", + database: "База данных", + schema: "Схема", + table: "Таблица", + scope: "Область привилегии", + scopeDatabase: "База данных", + scopeSchema: "Схема", + scopeTable: "Таблица", + scopeRole: "Членство в роли", + memberRole: "Роль-участник", + privileges: "Привилегии", + grantOption: "Разрешить дальнейшую выдачу (WITH GRANT OPTION)", + grantOptionHint: "Применяется только к операторам GRANT; REVOKE его игнорирует.", + adminOption: "Разрешить управление членством (WITH ADMIN OPTION)", + grant: "Выдать", + revoke: "Отозвать", + username: "Имя пользователя", + host: "Хост", + addHost: "Добавить хост", + changeHost: "Изменить хост", + newHost: "Новый хост", + changePassword: "Изменить пароль", + newPassword: "Новый пароль", + lock: "Заблокировать", + unlock: "Разблокировать", + disableLogin: "Отключить вход", + enableLogin: "Включить вход", + dropUser: "Удалить пользователя", + previewSql: "Просмотр SQL", + sqlPreview: "Предпросмотр SQL", + applySql: "Применить SQL", + applySuccess: "Привилегии пользователя обновлены", + applyPartial: "Пользователь создан, но некоторые привилегии не выданы", + applyFailedSummary: "Операция не удалась", + applyFailed: "Выполнение не удалось: {message}", + applyFailedUnknown: "Выполнение не удалось", + standardUser: "Обычный пользователь", + standardUserHint: "Выдать только базы данных и привилегии, выбранные ниже.", + adminUser: "Административный пользователь", + adminUserHint: "Создать учётную запись с высокими привилегиями уровня экземпляра.", + adminUserWarning: "Эта учётная запись может управлять базами данных и другими пользователями. Внимательно проверьте полный SQL перед применением.", + databaseAccess: "Доступ к базам данных", + databaseAccessHint: "Выберите базы данных и настройте отдельный уровень прав для каждой.", + tableScope: "Область таблиц", + allTables: "Все таблицы", + specificTables: "Определённые таблицы", + chooseTables: "Выбрать таблицы", + selectedTableCount: "Выбрано таблиц: {count}", + searchTable: "Поиск таблиц", + loadingTables: "Загрузка таблиц...", + emptyTables: "Таблицы не найдены", + loadTablesFailed: "Не удалось загрузить таблицы: {message}", + tableSelectionRequired: "Выберите хотя бы одну таблицу.", + selectAllTables: "Выбрать все", + clearAllTables: "Очистить", + retry: "Повторить", + selectedDatabaseCount: "Баз данных: {count}", + searchDatabase: "Поиск баз данных", + loadingDatabases: "Загрузка баз данных...", + emptyDatabases: "Базы данных не найдены", + loadDatabasesFailed: "Не удалось загрузить базы данных: {message}", + prepareAuthorizationFailed: "Не удалось подготовить авторизацию базы данных: {message}", + presetReadWrite: "Чтение/запись", + presetReadOnly: "Только чтение", + presetDdl: "Только DDL", + presetDml: "Только DML", + presetCustom: "Настраиваемый", + customPrivilegeRequired: "Выберите хотя бы одну привилегию.", + postgresDdlHint: "PostgreSQL выдаёт CREATE на базу данных/схему. Для изменения или удаления объектов всё равно требуется владение.", + resultSuccess: "Все шаги успешно выполнены", + resultPartial: "Выполнено частично", + resultFailed: "Выполнение не удалось", + closeResult: "Закрыть", + stepCreateUser: "Создать пользователя или роль", + stepGrantAdmin: "Выдать административные привилегии {user}", + stepGrantDatabase: 'Выдать {user} доступ к базе данных "{database}"', + stepGrantTable: 'Выдать {user} доступ к таблице "{database}.{table}"', + stepRevokeDatabase: 'Отозвать у {user} доступ к базе данных "{database}"', + stepRevokeTable: 'Отозвать у {user} доступ к таблице "{database}.{table}"', + stepGrantObjects: 'Выдать {user} привилегии на схему и объекты в "{database}"', + stepGrantCurrentObjects: 'Выдать текущие {scope} в схеме "{schema}" пользователю {user} в "{database}"', + stepGrantFutureObjects: 'Выдать будущие {scope}, созданные текущей ролью, пользователю {user} в "{database}"', + stepGrantFutureObjectsForOwner: 'Выдать будущие {scope}, созданные {owner}, пользователю {user} в "{database}"', + scopeSchemas: "схемы", + scopeTables: "таблицы", + scopeSequences: "последовательности", + scopeFunctions: "функции", + stepSkipped: "Пропущено из-за сбоя необходимого предыдущего шага.", + }, + damengJobAdmin: { + title: "Задания агента Dameng", + unsupported: "Эта страница поддерживает только подключения Dameng.", + initEnvironment: "Инициализировать среду заданий", + environmentReady: "Среда заданий готова", + newJob: "Новое задание", + searchJob: "Поиск заданий", + loadFailed: "Загрузка не удалась", + environmentMissingTitle: "Среда заданий не инициализирована", + environmentMissingHint: "В этой базе данных ещё нет среды заданий SYSJOB.", + environmentMissingDescription: "Задания агента Dameng требуют системных таблиц и представлений в схеме SYSJOB. Сначала инициализируйте среду заданий; обычно требуются права администратора.", + emptyJobs: "Задания не найдены, либо текущая учётная запись не может прочитать список заданий.", + emptyDetails: "Нет строк с деталями", + selectJob: "Выберите задание", + enabled: "Включено", + disabled: "Отключено", + running: "Выполняется", + enable: "Включить", + disable: "Отключить", + runAsync: "Запустить сейчас", + stopRunning: "Остановить текущий запуск", + stopRunningDisabled: "Остановить можно только выполняющиеся задания", + clearHistories: "Очистить историю", + dropJob: "Удалить", + steps: "Шаги", + schedules: "Расписания", + histories: "История", + noDescription: "Без описания", + jobName: "Имя задания", + description: "Описание", + stepName: "Имя шага", + scheduleName: "Имя расписания", + sqlCommand: "SQL-скрипт", + scheduleMode: "Тип расписания", + daily: "Ежедневно", + once: "Однократно", + startDate: "Дата начала", + startTime: "Время начала", + endTime: "Время окончания", + minuteInterval: "Интервал в минутах", + previewSql: "Просмотр SQL", + sqlPreview: "Предпросмотр SQL", + applySql: "Применить SQL", + applySuccess: "Операция с заданием применена", + applyFailed: "Выполнение не удалось: {message}", + }, + xuguSchedulerJob: { + enable: "Включить", + disable: "Отключить", + run: "Запустить сейчас", + drop: "Удалить задание", + confirmDrop: 'Удалить запланированное задание "{name}"? Это действие необратимо.', + actionSuccess: '{action} выполнено для "{name}".', + }, + damengUserAdmin: { + title: "Пользователи Dameng", + unsupported: "Эта страница поддерживает только подключения к базе данных Dameng.", + newUser: "Новый пользователь", + searchUser: "Поиск пользователей", + loadFailed: "Загрузка не удалась", + emptyUsers: "Пользователей нет, либо текущая учётная запись не может прочитать список пользователей.", + selectUser: "Выберите пользователя", + username: "Имя пользователя", + usernamePlaceholder: "например, APP_USER", + password: "Пароль", + passwordPolicyHint: "Пароль должен соответствовать политике паролей DM8 (по умолчанию: не менее 9 символов; желательно сочетание заглавных, строчных букв и цифр)", + tablespace: "Табличное пространство по умолчанию", + tablespacePlaceholder: "Введите имя табличного пространства", + locked: "Заблокировать учётную запись после создания", + changePassword: "Изменить пароль", + newPassword: "Новый пароль", + confirmPassword: "Подтвердите пароль", + open: "Открыть", + systemUser: "Системный пользователь", + systemUserAdmin: "Административный пользователь", + systemUserAuditor: "Пользователь аудита", + systemUserSecurity: "Пользователь безопасности", + systemUserSystem: "Системный пользователь", + cannotChangePassword: "Пароль этого пользователя нельзя изменить через текущее подключение (это может сделать только SYSDBA или сам пользователь)", + inheritedFrom: "Унаследовано от {via}", + userType: "Тип пользователя", + userTypeHint: "Admin автоматически выдаёт DBA, audit выдаёт DB_AUDIT_ADMIN, security выдаёт DB_POLICY_ADMIN", + groupOther: "Другие пользователи", + systemUserProtected: "Системных пользователей нельзя изменять или удалять", + builtinRole: "Встроенная роль", + builtinRoleProtected: "Встроенные роли нельзя отозвать", + defaultTablespace: "Табличное пространство по умолчанию", + created: "Создан", + lock: "Заблокировать", + unlock: "Разблокировать", + dropUser: "Удалить пользователя", + roles: "Роли", + systemPrivileges: "Системные привилегии", + grantedRoles: "Выданные роли", + grantedPrivileges: "Выданные привилегии", + grantRole: "Выдать роль", + revokeRole: "Отозвать роль", + roleToGrant: "Роль для выдачи", + selectRole: "Выберите роль", + grantRoleHint: "Выдать роль пользователю {user}.", + noRolesToGrant: "Нет ролей, доступных для выдачи", + noGrantedRoles: "У этого пользователя нет выданных ролей", + grantPrivilege: "Выдать привилегию", + revokePrivilege: "Отозвать привилегию", + privilegeToGrant: "Привилегия для выдачи", + selectPrivilege: "Выберите привилегию", + grantPrivilegeHint: "Выдать системную привилегию пользователю {user}.", + noPrivilegesToGrant: "Нет привилегий, доступных для выдачи", + noGrantedPrivileges: "У этого пользователя нет выданных системных привилегий", + previewSql: "Просмотр SQL", + sqlPreview: "Предпросмотр SQL", + applySql: "Применить SQL", + applySuccess: "Операция с пользователем применена", + applyFailed: "Выполнение не удалось: {message}", + enableDdlAnyPrivHint: + "Подсказка: DM8 по умолчанию отключает выдачу привилегий DDL ANY (ENABLE_DDL_ANY_PRIV=0). Чтобы выдать привилегии типа ANY, выполните от имени SYSDBA: sp_set_para_value(1,'ENABLE_DDL_ANY_PRIV',1). Для привилегий, не относящихся к ANY, убедитесь, что текущая учётная запись обладает ADMIN OPTION для этой привилегии.", + anyPrivilegeDisabled: "Привилегии типа ANY отключены в DM8 (ENABLE_DDL_ANY_PRIV=0) и не могут быть выданы или отозваны", + }, + damengRoleAdmin: { + title: "Роли Dameng", + unsupported: "Эта страница поддерживает только подключения к базе данных Dameng.", + newRole: "Новая роль", + searchRole: "Поиск ролей", + loadFailed: "Загрузка не удалась", + emptyRoles: "Ролей нет, либо текущая учётная запись не может прочитать список ролей.", + selectRole: "Выберите роль", + roleName: "Имя роли", + roleNamePlaceholder: "например, APP_ROLE", + members: "Участники", + systemPrivileges: "Системные привилегии", + grantedToUsers: "Пользователи с этой ролью", + grantedPrivileges: "Выданные привилегии", + noMembers: "Ни одному пользователю не выдана эта роль", + grantToUser: "Выдать пользователю", + userToGrant: "Пользователь для выдачи", + selectUser: "Выберите пользователя", + grantUserHint: "Выдать роль {role} пользователю.", + noUsersToGrant: "Нет пользователей, доступных для выдачи", + revokeFromUser: "Отозвать", + systemUser: "Системный пользователь", + systemUserProtected: "Нельзя отозвать у системных пользователей", + builtinRole: "Встроенная роль", + builtinRoleProtected: "Предопределённые роли нельзя удалять или изменять", + grantPrivilege: "Выдать привилегию", + revokePrivilege: "Отозвать привилегию", + privilegeToGrant: "Привилегия для выдачи", + selectPrivilege: "Выберите привилегию", + grantPrivilegeHint: "Выдать системную привилегию роли {role}.", + noPrivilegesToGrant: "Нет привилегий, доступных для выдачи", + noGrantedPrivileges: "У этой роли нет выданных системных привилегий", + dropRole: "Удалить роль", + previewSql: "Просмотр SQL", + sqlPreview: "Предпросмотр SQL", + applySql: "Применить SQL", + applySuccess: "Операция с ролью применена", + applyFailed: "Выполнение не удалось: {message}", + enableDdlAnyPrivHint: + "Подсказка: DM8 по умолчанию отключает выдачу привилегий DDL ANY (ENABLE_DDL_ANY_PRIV=0). Чтобы выдать привилегии типа ANY, выполните от имени SYSDBA: sp_set_para_value(1,'ENABLE_DDL_ANY_PRIV',1). Для привилегий, не относящихся к ANY, убедитесь, что текущая учётная запись обладает ADMIN OPTION для этой привилегии.", + anyPrivilegeDisabled: "Привилегии типа ANY отключены в DM8 (ENABLE_DDL_ANY_PRIV=0) и не могут быть выданы или отозваны", + }, + objects: { + all: "Все", + tables: "Таблицы", + collections: "Коллекции", + views: "Представления", + procedures: "Процедуры", + functions: "Функции", + sequences: "Последовательности", + packages: "Пакеты", + table: "Таблица", + collection: "Коллекция", + partitions: "Разделов: {count}", + view: "Представление", + timeseries: "Временные ряды", + procedure: "Процедура", + function: "Функция", + trigger: "Триггер", + triggerTiming: "Момент", + triggerEvent: "Событие", + triggerLevel: "Уровень", + triggerStatus: "Состояние", + triggerCondition: "Условие", + triggerLanguage: "Язык", + enabled: "Включено", + disabled: "Отключено", + validity: "Валидность", + valid: "Валидный", + invalid: "Невалидный", + validStatus: "VALID", + invalidStatus: "INVALID", + sequence: "Последовательность", + package: "Пакет", + packageBody: "Тело пакета", + typeDefinition: "Тип", + typeBody: "Тело типа", + name: "Имя", + type: "Тип", + rows: "Строки", + series: "Ряды", + size: "Размер", + statisticsHint: "Оценка по статистике базы данных; COUNT(*) не выполняется.", + createdAt: "Создано", + updatedAt: "Обновлено", + source: "Исходный код", + saveSource: "Сохранить", + cancelEdit: "Отмена", + sourceSaved: "Исходный код сохранён", + sourceSaveFailed: "Не удалось сохранить исходный код: {message}", + refreshDiscardConfirm: "Обновление отменит несохранённые изменения исходного кода. Продолжить?", + postgresViewColumnChangeHint: + "PostgreSQL не позволяет с помощью CREATE OR REPLACE VIEW удалять, переупорядочивать, переименовывать столбцы существующего представления или изменять их типы. Сохраняйте количество, порядок, имена и типы существующих столбцов неизменными; новые столбцы можно только добавлять в конец. Для переименования столбца используйте ALTER VIEW ... RENAME COLUMN. Чтобы удалить столбец, проверьте зависимости и пересоздайте представление вручную.", + sourceReadOnly: "Этот исходный код доступен только для чтения и не может быть изменён.", + schemaColumn: "Схема", + comment: "Комментарий", + loadingSchemas: "Загрузка схем...", + schema: "Схема", + search: "Поиск таблиц, представлений, функций, последовательностей или процедур...", + searchCollections: "Поиск коллекций...", + loading: "Загрузка объектов...", + empty: "Объекты не найдены", + selectedTables: "Выбрано таблиц: {count}", + exportSelected: "Экспорт выбранного", + dropSelected: "Удалить выбранное", + truncateSelected: "Очистить выбранное", + clearSelection: "Снять выделение", + confirmBatchDropTitle: "Удаление выбранных таблиц", + confirmBatchDropMessage: "Удалить выбранные таблицы ({count})? Это действие необратимо.", + confirmBatchTruncateTitle: "Очистка выбранных таблиц", + confirmBatchTruncateMessage: "Очистить выбранные таблицы ({count})? Все строки будут удалены.", + batchDropSuccess: "Удалено таблиц: {count}", + batchTruncateSuccess: "Очищено таблиц: {count}", + copyTableSelected: "Копировать", + pasteTableSelected: "Вставить", + toggleCheckbox: "Переключить множественный выбор", + viewList: "Список", + viewGrid: "Сетка", + sortAsc: "По возрастанию", + sortDesc: "По убыванию", + sortBy: "Сортировать по", + }, + structureEditor: { + title: "Редактирование структуры таблицы", + createTitle: "Создание таблицы", + editTabTitle: "Редактирование: {tableName}", + tableName: "Имя таблицы", + refresh: "Обновить структуру", + density: "Плотность", + densityCompact: "Компактная", + densityStandard: "Стандартная", + densityComfortable: "Просторная", + columns: "Столбцы", + indexes: "Индексы", + foreignKeys: "Внешние ключи", + constraints: "Ограничения", + constraintDisabled: "Отключено", + constraintNotValidated: "Не проверено", + triggers: "Триггеры", + partitions: "Разделы", + partitionsEmpty: "Эта таблица не секционирована", + partitionsEmptyChildren: "У этой секционированной таблицы пока нет разделов", + partitionsParent: "Родительская таблица", + partitionsOwnBound: "Граница раздела", + partitionsDefault: "Раздел по умолчанию", + partitionsRowEstimate: "Примерное число строк: {count}", + partitionsSize: "Размер: {size}", + partitionChildCount: "{count} подраздел | {count} подразделов", + partitionExpand: "Развернуть", + partitionCollapse: "Свернуть", + partitionSubPartitionBadge: "Подраздел", + partitionMemberBadge: "Раздел", + partitionKindRange: "Диапазон", + partitionKindList: "Список", + partitionKindHash: "Хеш", + partitionBoundDefault: "По умолчанию", + partitionEnable: "Включить секционирование", + partitionKind: "Стратегия секционирования", + partitionKeyColumns: "Столбцы ключа секционирования", + partitionKeyNoColumns: "Сначала добавьте столбцы или используйте выражение.", + partitionKeyExpression: "Выражение ключа секционирования (переопределяет столбцы)", + partitionInitialPartitions: "Начальные разделы", + partitionInitialPartitionsEmpty: "Начальных разделов нет; их можно добавить после создания таблицы.", + partitionAdd: "Добавить раздел", + partitionAttach: "Присоединить раздел", + partitionDetach: "Отсоединить", + partitionDrop: "Удалить", + partitionDetachSelf: "Отсоединить этот раздел", + partitionDetachConcurrently: "Отсоединить параллельно", + partitionDetachWarning: "При отсоединении данные раздела остаются в собственной таблице; он перестаёт быть частью родительской.", + partitionDropWarning: "Удаление раздела безвозвратно удаляет таблицу раздела и все её данные.", + partitionPendingOperations: "Ожидающие операции с разделами (применяются при сохранении)", + partitionRemoveOperation: "Убрать", + partitionName: "Имя раздела", + partitionNamePlaceholder: "например, sales_2025", + partitionBoundKind: "Тип границы", + partitionBoundFrom: "От", + partitionBoundTo: "До", + partitionBoundValues: "Значения", + partitionBoundModulus: "Модуль", + partitionBoundRemainder: "Остаток", + partitionRangeBoundInvalid: "Для RANGE нужны кортежи FROM и TO с одинаковым числом значений.", + partitionListBoundInvalid: "Для LIST нужно хотя бы одно значение.", + partitionHashBoundInvalid: "Для HASH требуется Modulus > 0 и 0 <= Remainder < Modulus.", + partitionSqlPreview: "SQL для выполнения", + partitionNameRequired: "Введите имя раздела.", + ddl: "DDL", + addColumn: "Добавить столбец", + copyColumns: "Копировать поля из другой таблицы", + copyColumn: "Копировать столбец", + copyColumnsTitle: "Копирование столбцов из другой таблицы", + copyColumnsSourceTable: "Исходная таблица", + copyColumnsSearchSourceTables: "Поиск исходных таблиц", + copyColumnsSelectFields: "Выберите поля", + copyColumnsSearchFields: "Поиск полей или типов", + copyColumnsSelectAll: "Выбрать все", + copyColumnsClearSelection: "Снять выделение", + copyColumnsNoSourceTables: "В этой схеме нет других доступных таблиц.", + copyColumnsNoMatchingSourceTables: "Нет исходных таблиц, соответствующих поиску.", + copyColumnsPreviousSourceTablePage: "Предыдущая страница исходных таблиц", + copyColumnsNextSourceTablePage: "Следующая страница исходных таблиц", + copyColumnsNoFields: "В выбранной таблице нет полей.", + copyColumnsNoMatchingFields: "Нет полей, соответствующих поиску.", + copyColumnsAlreadyExists: "Уже существует", + copyColumnsCancel: "Отмена", + copyColumnsApply: "Копировать поля ({count})", + columnTemplates: "Вставить предустановленные поля", + configureColumnTemplates: "Настроить предустановленные поля", + presetFieldsTemplate: "Набор предустановленных полей", + searchColumns: "Поиск по столбцу/комментарию", + nextColumnMatch: "Перейти к следующему совпадению столбца", + searchIndexes: "Поиск индекса", + nextIndexMatch: "Перейти к следующему совпадению индекса", + addIndex: "Добавить индекс", + addForeignKey: "Добавить внешний ключ", + addTrigger: "Добавить триггер", + columnName: "Столбец", + dataType: "Тип", + typePlaceholder: "Выберите или введите...", + noMatchingType: "Нет подходящего типа", + mysqlDataTypeHelp: { + tinyint: "Целое число размером 1 байт. Диапазон со знаком: от -128 до 127; без знака: от 0 до 255.", + smallint: "Целое число размером 2 байта. Диапазон со знаком: от -32 768 до 32 767; без знака: от 0 до 65 535.", + mediumint: "Целое число размером 3 байта. Диапазон со знаком: от -8 388 608 до 8 388 607; без знака: от 0 до 16 777 215.", + int: "Целое число размером 4 байта. Диапазон со знаком: от -2 147 483 648 до 2 147 483 647; без знака: от 0 до 4 294 967 295.", + bigint: "Целое число размером 8 байт. Диапазон со знаком: от -2^63 до 2^63-1; без знака: от 0 до 2^64-1.", + decimal: "Точное число с фиксированной запятой. MySQL поддерживает точность до 65 цифр и масштаб до 30 цифр; ограничения версий MariaDB могут отличаться. Используйте его для денежных сумм и других точных значений.", + float: "Приблизительное число одинарной точности. Используйте DECIMAL, когда требуются точные десятичные значения.", + double: "Приблизительное число двойной точности. Используйте DECIMAL, когда требуются точные десятичные значения.", + real: "По умолчанию псевдоним DOUBLE; режим SQL REAL_AS_FLOAT делает его псевдонимом FLOAT.", + bit: "Битовое поле от 1 до 64 бит. Ширина по умолчанию — 1 бит.", + boolean: "Псевдоним TINYINT(1): 0 означает false, а ненулевые значения — true.", + serial: "Удобный псевдоним для BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.", + date: "Календарная дата. Поддерживаемый диапазон: с 1000-01-01 по 9999-12-31.", + datetime: "Дата и время без преобразования часового пояса. Поддерживаемый диапазон: с 1000-01-01 00:00:00 по 9999-12-31 23:59:59; точность долей секунды — от 0 до 6 (по умолчанию 0).", + timestamp: "Дата и время, преобразуемые между часовым поясом сеанса и UTC. Поддерживаемый диапазон: с 1970-01-01 00:00:01 UTC по 2038-01-19 03:14:07 UTC; точность долей секунды — от 0 до 6 (по умолчанию 0).", + time: "Время суток или прошедшее время. Поддерживаемый диапазон: от -838:59:59 до 838:59:59; точность долей секунды — от 0 до 6 (по умолчанию 0).", + year: "Значение года. Четырёхзначные значения — от 1901 до 2155, плюс 0000.", + char: "Символьная строка фиксированной длины до 255 символов. Сохранённые значения дополняются справа пробелами.", + varchar: "Символьная строка переменной длины. Её практический максимум ограничен размером строки и кодировкой.", + tinytext: "Текст переменной длины до 255 байт. Кодировка, размер строки и ограничение max_allowed_packet могут снижать практический предел.", + text: "Текст переменной длины до 65 535 байт. Кодировка, размер строки и ограничение max_allowed_packet могут снижать практический предел.", + mediumtext: "Текст переменной длины до 16 777 215 байт. Кодировка, размер строки и ограничение max_allowed_packet могут снижать практический предел.", + longtext: "Текст переменной длины до 4 294 967 295 байт (около 4 ГиБ). Кодировка, размер строки и ограничение max_allowed_packet могут снижать практический предел.", + binary: "Двоичная строка фиксированной длины до 255 байт. Сохранённые значения дополняются 0x00.", + varbinary: "Двоичная строка переменной длины. Её практический максимум ограничен размером строки.", + tinyblob: "Двоичный большой объект до 255 байт. Ограничения размера строки и max_allowed_packet могут снижать практический предел.", + blob: "Двоичный большой объект до 65 535 байт. Ограничения размера строки и max_allowed_packet могут снижать практический предел.", + mediumblob: "Двоичный большой объект до 16 777 215 байт. Ограничения размера строки и max_allowed_packet могут снижать практический предел.", + longblob: "Двоичный большой объект до 4 294 967 295 байт (около 4 ГиБ). Ограничения размера строки и max_allowed_packet могут снижать практический предел.", + enum: "Одно значение, выбранное из до 65 535 объявленных литералов. Изменение порядка литералов может изменить смысл сохранённых значений.", + set: "Ноль или более значений, выбранных из до 64 объявленных элементов.", + json: "Проверенный документ JSON. Способ хранения и поддержка возможностей JSON зависят от продукта и версии подключённого сервера; размер документа также ограничен max_allowed_packet.", + jsonMysql: "Собственный двоичный тип документа JSON в MySQL с функциями JSON и проверкой. Размер документа ограничен max_allowed_packet.", + jsonMariaDb: "MariaDB JSON — это псевдоним LONGTEXT с ограничением JSON_VALID и сопоставлением utf8mb4_bin; размер документа ограничен max_allowed_packet.", + nationalCharacter: "Псевдоним символьной строки национального набора. В MySQL используется предопределённый национальный набор символов (utf8mb3, устарел); для новых схем явно выбирайте utf8mb4.", + geometry: "Пространственное значение любого поддерживаемого геометрического типа. Пространственный индекс InnoDB в MySQL требует столбца NOT NULL с атрибутом SRID.", + point: "Пространственная точка с одной парой координат. Пространственный индекс InnoDB в MySQL требует столбца NOT NULL с атрибутом SRID.", + linestring: "Пространственная кривая, состоящая из одной или нескольких соединённых точек. Пространственный индекс InnoDB в MySQL требует столбца NOT NULL с атрибутом SRID.", + polygon: "Пространственная поверхность, ограниченная одним или несколькими кольцами. Пространственный индекс InnoDB в MySQL требует столбца NOT NULL с атрибутом SRID.", + multipoint: "Коллекция пространственных точек. Пространственный индекс InnoDB в MySQL требует столбца NOT NULL с атрибутом SRID.", + multilinestring: "Коллекция пространственных кривых. Пространственный индекс InnoDB в MySQL требует столбца NOT NULL с атрибутом SRID.", + multipolygon: "Коллекция пространственных многоугольников. Пространственный индекс InnoDB в MySQL требует столбца NOT NULL с атрибутом SRID.", + geometrycollection: "Коллекция, которая может содержать пространственные геометрические типы разных видов. Пространственный индекс InnoDB в MySQL требует столбца NOT NULL с атрибутом SRID.", + inet4: "Тип IPv4-адреса MariaDB (доступен с MariaDB 10.10); хранит IPv4-адрес в четырёх байтах.", + inet6: "Совместимый с MariaDB тип адреса для IPv6 и отображённых значений IPv4.", + uuid: "Тип 128-битного универсально уникального идентификатора, предоставляемый совместимыми серверами.", + vector: "Векторный тип данных для задач поиска сходства или машинного обучения; доступность и размерность зависят от версии сервера.", + xmltype: "Тип данных XML, предоставляемый совместимыми серверами.", + integerDisplayWidth: "Ширина отображения целых чисел в MySQL (например, INT(11)) устарела и не ограничивает хранимый диапазон. Не добавляйте её в новые схемы MySQL 8.", + zerofill: "ZEROFILL устарел в MySQL 8. Он также неявно делает столбец UNSIGNED; вместо этого используйте явное форматирование в приложении.", + unsignedNumeric: "UNSIGNED для DECIMAL, FLOAT или DOUBLE устарел в MySQL 8. Используйте ограничение CHECK, когда требуется неотрицательная область значений.", + floatPrecision: "Для FLOAT(p) значения p от 25 до 53 выбирают точность DOUBLE, а не FLOAT. Если это и требуется, указывайте DOUBLE явно.", + floatingPointDisplay: "FLOAT(M,D) и DOUBLE(M,D) устарели в MySQL 8. Используйте FLOAT/DOUBLE без параметров отображения или DECIMAL(M,D) для точных значений.", + }, + postgresDataTypeHelp: { + smallint: "Целое число со знаком размером 2 байта, от -32 768 до 32 767.", + integer: "Целое число со знаком размером 4 байта, от -2 147 483 648 до 2 147 483 647.", + bigint: "Целое число со знаком размером 8 байт, от -2^63 до 2^63-1.", + serial: "Удобный синтаксис, создающий целочисленный столбец, последовательность, NOT NULL и значение по умолчанию nextval. Сам по себе он не уникален, а значения последовательности могут иметь пропуски; для новых схем предпочитайте IDENTITY.", + numeric: "Точное десятичное число с задаваемыми пользователем точностью и масштабом. Используйте его для денежных сумм и других значений, которые не должны использовать двоичное округление с плавающей запятой.", + real: "Число с плавающей запятой одинарной точности размером 4 байта. FLOAT(p) с p от 1 до 24 выбирает этот тип.", + double: "Число с плавающей запятой двойной точности размером 8 байт. FLOAT без точности — его псевдоним; FLOAT(p) с p от 25 до 53 выбирает его.", + money: "Денежная сумма в формате локали. Её вывод и разбор зависят от lc_monetary; NUMERIC обычно надёжнее для переносимых финансовых данных.", + boolean: "Логическое значение true, false или null. BOOL — псевдоним BOOLEAN.", + char: "Символьная строка фиксированной длины, дополняемая пробелами. CHARACTER — псевдоним; избегайте его, когда конечные пробелы значимы.", + varchar: "Символьная строка переменной длины с необязательным ограничением на число символов. CHARACTER VARYING — псевдоним.", + text: "Символьная строка переменной длины без объявленного ограничения; ведёт себя при хранении так же, как VARCHAR без ограничения.", + bytea: "Двоичная строка переменной длины. Большие значения могут храниться отдельно с помощью TOAST.", + date: "Календарная дата без времени суток и часового пояса.", + time: "Время суток без часового пояса, с необязательной точностью долей секунды.", + timetz: "Время суток плюс смещение UTC. Имеет ограниченную полезность и обычно не рекомендуется; используйте timestamptz для момента времени.", + timestamp: "Дата и время без преобразования часового пояса. Используйте для локальных значений настенных часов, для которых часовой пояс не является частью данных.", + timestamptz: "Момент времени, внутренне хранимый в UTC и отображаемый в часовом поясе сеанса. Он не сохраняет исходный именованный часовой пояс.", + interval: "Длительность, выраженная в месяцах, днях и микросекундах. Календарные единицы не являются длительностями фиксированной длины.", + uuid: "128-битный универсально уникальный идентификатор.", + json: "Текст JSON, сохраняемый в исходном представлении ввода. Разбор проверяется, но обработка обычно медленнее, чем у JSONB.", + jsonb: "Разложенное двоичное представление JSON, оптимизированное для обработки и индексирования. Не сохраняет незначащие пробелы, порядок ключей и повторяющиеся ключи.", + xml: "Значение XML с необязательной проверкой документа или содержимого в зависимости от используемого параметра XML.", + bit: "Битовая строка фиксированной или переменной длины. BIT VARYING и VARBIT — псевдонимы переменной длины.", + tsvector: "Нормализованные лексемы, используемые как индексируемая часть документа в полнотекстовом поиске PostgreSQL; обычно индексируются с помощью GIN или GiST.", + tsquery: "Булев запрос полнотекстового поиска, вычисляемый по tsvector.", + cidr: "Сеть IPv4 или IPv6 с битами узла, приравненными к нулю.", + inet: "Адрес узла IPv4 или IPv6, при необходимости с сетевой маской; в отличие от CIDR, биты узла могут быть ненулевыми.", + macaddr: "MAC-адрес. MACADDR хранит 6-байтовые адреса, а MACADDR8 — 8-байтовые.", + geometry: "Встроенный двумерный геометрический тип. Геометрия PostgreSQL планарная и не имеет SRID; используйте PostGIS для географических координат, проекций или сложных пространственных операций.", + range: "Единый непрерывный диапазон с включающими/исключающими границами. Значения диапазона требуют совместимого подтипа; используйте типы multirange для нескольких непересекающихся диапазонов.", + oid: "Идентификатор объекта без знака. Это системный идентификатор, а не долговечный первичный ключ приложения; для данных приложения используйте обычное целое число или UUID.", + array: "Массив PostgreSQL любого типа элементов, включая многомерные массивы. Размерность массива не проверяется объявленным типом, и массивы часто менее гибки, чем нормализованные дочерние строки.", + multirange: "Набор непересекающихся диапазонов соответствующего подтипа диапазона. PostgreSQL нормализует смежные или пересекающиеся элементы согласно правилам подтипа.", + jsonpath: "Выражение пути SQL/JSON, используемое функциями запросов и предикатов JSONB.", + pgLsn: "Позиция журнала упреждающей записи, используемая в качестве координат репликации и восстановления; это не порядковый номер приложения.", + pgSnapshot: "Снимок видимости транзакций. Его текстовое представление предназначено для операций со снимками базы данных, а не для обычных данных приложения.", + }, + sqliteDataTypeHelp: { + integer: "SQLite использует динамическую типизацию и сродство INTEGER; обычный столбец не навязывает класс хранения INTEGER. Значения по возможности хранятся как целые числа со знаком; INTEGER PRIMARY KEY (точное написание) — специальный псевдоним rowid.", + real: "Сродство REAL хранит значения с плавающей запятой IEEE 754. Подходит для приблизительных измерений, но не для точных денежных или десятичных вычислений.", + text: "Сродство TEXT хранит текст в кодировке базы данных. VARCHAR(n) и CHAR(n) в SQLite не навязывают n; добавьте ограничение CHECK, когда ограничение длины важно.", + blob: "Сродство BLOB хранит байты точно в том виде, в каком они предоставлены, без преобразования типов.", + numeric: + "Сродство NUMERIC пытается сначала преобразовать корректный числовой текст в INTEGER, затем в REAL; это не отдельный класс хранения SQLite. Объявления DATE, DATETIME и TIME также имеют сродство NUMERIC; последовательно храните TEXT в формате ISO-8601, REAL в юлианских днях или INTEGER в Unix-времени.", + }, + length: "Длина", + lengthUnit: "Единица длины", + unitPlaceholder: "Единица", + geometryTypePlaceholder: "Выберите или введите геометрический тип", + sridPlaceholder: "например, 4326", + geometrySridHint: "Укажите геометрический тип и SRID, чтобы включить пространственное индексирование и корректные пространственные запросы.", + geometryEmptyTypeHint: "Пустой геометрический тип равен GEOMETRY (любой подтип); dbx формирует geometry(GEOMETRY, SRID).", + enumValues: "Значения перечисления", + enumValueCount: "Значений: {count}", + addEnumValue: "Добавить значение", + removeEnumValue: "Удалить значение перечисления", + enumValuePlaceholder: "Значение (пустое допустимо)", + nullable: "Допускает NULL", + notNull: "Не NULL", + primaryKey: "Первичный ключ", + defaultValue: "По умолчанию", + defaultValuePresets: "Предустановленные значения по умолчанию", + comment: "Комментарий", + characterSet: "Кодировка", + charsetPlaceholder: "Кодировка", + collation: "Сопоставление", + collationPlaceholder: "Сопоставление", + editComment: "Изменить комментарий", + commentPlaceholder: "Введите комментарий к столбцу...", + tableCommentPlaceholder: "Введите комментарий к таблице...", + mysqlTableEngine: "Движок хранения", + mysqlTableEnginePlaceholder: "Выберите движок хранения", + mysqlTableEngineSearchPlaceholder: "Поиск движков хранения", + mysqlTableEngineEmpty: "Нет доступных движков хранения", + mysqlTableEngineLoadFailed: "Не удалось загрузить движки хранения: {message}", + owner: "Владелец", + ownerPlaceholder: "Введите имя роли...", + ownerSearchPlaceholder: "Найдите или введите имя роли...", + ownerRolesEmpty: "Роли не найдены; введите имя роли вручную", + ownerLoadFailed: "Не удалось загрузить владельца таблицы: {message}", + ownerRolesLoadFailed: "Не удалось загрузить роли; вы всё ещё можете ввести её вручную: {message}", + tableCommentUnsupported: "Эта база данных не поддерживает комментарии к таблицам", + actions: "Действия", + indexName: "Индекс", + indexColumns: "Столбцы", + indexColumnsPlaceholder: "Выберите столбцы...", + unique: "Уникальный", + indexType: "Тип", + includedColumns: "Включённые", + includedColumnsPlaceholder: "Выберите столбцы...", + filter: "Фильтр", + concurrent: "Параллельно", + concurrentTooltip: "Создать индекс параллельно, чтобы не блокировать запись. Обычно это занимает больше времени и не может выполняться внутри блока транзакции.", + concurrentExistingIndexTooltip: "Доступно только для новых индексов. Перестроение существующего индекса параллельно (DROP INDEX CONCURRENTLY + CREATE INDEX CONCURRENTLY) пока не поддерживается.", + concurrentPartitionedTooltip: "Недоступно для секционированных родительских таблиц. PostgreSQL отклоняет параллельное создание индексов для секционированных родителей; создавайте индексы дочерних таблиц параллельно и присоединяйте их.", + invalidIndexBlocksSave: 'Сохранение заблокировано: уже существует индекс со статусом INVALID (оставшийся от отменённого параллельного создания) с тем же именем: {indexNames}. Сначала удалите его (например, DROP INDEX "schema"."name"), затем повторите попытку.', + concurrentUnavailableTooltip: "Недоступно, пока нельзя проверить статус секционирования таблицы. Параллельное создание предлагается только для несекционированных таблиц.", + concurrentUnavailableBlocksSave: + "Параллельное создание индекса больше недоступно (не удалось проверить статус секционирования таблицы). Выбранный параметр «Параллельно» сброшен, и это изменение заблокировано до повторной проверки таблицы. Обновите, чтобы повторить попытку, или удалите индекс, чтобы продолжить с другими изменениями.", + invalidIndexRetryHint: "Это может быть вызвано индексом со статусом INVALID с тем же именем, оставшимся от ранее отменённого параллельного создания. Сначала удалите этот индекс, затем повторите попытку.", + foreignKeyName: "Внешний ключ", + referencedSchema: "Ссылочная схема", + referencedTable: "Ссылочная таблица", + referencedColumn: "Ссылочный столбец", + onDelete: "При удалении", + onUpdate: "При обновлении", + defaultAction: "По умолчанию", + triggerName: "Триггер", + triggerStatement: "Оператор триггера", + primary: "Первичный", + drop: "Удалить", + restore: "Восстановить", + remove: "Убрать", + moveColumnUp: "Переместить столбец вверх", + copySelectedColumns: "Копировать выбранные поля ({count})", + dropSelectedColumns: "Удалить выбранные поля ({count})", + moveColumnDown: "Переместить столбец вниз", + dragColumn: "Перетащите, чтобы изменить порядок столбца", + localColumnOrderNotice: "Порядок столбцов сохраняется локально и не изменяет структуру таблицы базы данных.", + yes: "Да", + no: "Нет", + emptyReadonly: "Нет записей", + sqlPreview: "Предпросмотр SQL", + collapseSqlPreview: "Свернуть предпросмотр SQL", + expandSqlPreview: "Развернуть предпросмотр SQL", + noChanges: "Нет изменений", + apply: "Применить изменения", + ready: "Готово", + saved: "Структура таблицы обновлена", + copySql: "Копировать SQL", + sqliteRebuildNotice: "Перестроение таблицы SQLite преобразует значения через CAST, поэтому такие значения, как 0.0, могут потерять точность.", + ddlEditNotice: "Изменённый DDL выполняется как скрипт точно в том виде, в каком он написан, — он не сравнивается с текущей структурой. Для существующей таблицы перепишите его как операторы ALTER (или DROP + CREATE).", + ddlEditConflictsWithStructure: "И скрипт DDL, и вкладки структуры были изменены. Перед сохранением примените или отмените одно из них.", + resetDdl: "Восстановить DDL базы данных", + extendedProperties: "Расширенные", + autoIncrement: "Автоувеличение", + mysqlAutoIncrementNextValue: "Следующее значение автоувеличения", + editMysqlAutoIncrementValue: "Изменить следующее значение автоувеличения (текущее: {value})", + onUpdateCurrentTimestamp: "Автообновление времени", + identity: "Идентичность", + identityGeneration: "Генерация", + identitySeed: "Начальное значение", + identityIncrement: "Шаг", + sqlServerIdentityTypeHint: "Identity в SQL Server поддерживает только tinyint, smallint, int, bigint и decimal/numeric с масштабом 0", + }, + diagram: { + title: "Диаграмма связей", + open: "Открыть диаграмму", + selectConnection: "Выберите подключение", + selectDatabase: "Выберите базу данных", + selectSchema: "Выберите схему", + allSchemas: "Вся база данных (все схемы)", + entireDatabase: "Вся база данных", + selectedSchemasCount: "Выбрано схем: {count}", + selectAllSchemas: "Выбрать все схемы", + deselectAllSchemas: "Снять выделение", + onlyThisSchema: "Только", + searchSchemas: "Поиск схем...", + searchTables: "Поиск таблиц, столбцов, ключей...", + refresh: "Обновить диаграмму", + refreshConfirm: "При обновлении перезагружаются метаданные таблиц и сбрасываются расположение на холсте и история отмен. Сохранённые смоделированные связи сохраняются. Продолжить?", + loading: "Чтение связей...", + loadingProgress: "Чтение связей... {loaded}/{total}", + partialError: "Пропущены метаданные для {count} таблиц, которые не удалось загрузить", + selectTarget: "Выберите подключение и базу данных", + empty: "Нет таблиц для отображения", + noMatches: "Нет подходящих таблиц", + tablesCount: "Таблиц: {count}", + relationshipsCount: "Связей: {count}", + tableMode: "Вид таблиц", + engineeringMode: "Инженерная ER", + modelRelationships: "Моделировать связи", + layers: "Слои", + autoMatch: "Автосопоставление", + autoLayout: "Авторасположение", + matchRelationshipsCount: "Совпадений: {count}", + copyJoinSql: "Копировать SQL", + customRelationshipsCount: "Смоделировано: {count}", + relationshipName: "Имя", + relationshipNamePlaceholder: "Необязательно", + sourceTable: "Исходная таблица", + sourceColumn: "Исходный столбец", + targetTable: "Целевая таблица", + targetColumn: "Целевой столбец", + cardinality: "Кардинальность", + cardinalityOneToMany: "Источник 1 · Цель N", + cardinalityManyToOne: "Источник N · Цель 1", + cardinalityOneToOne: "Источник 1 · Цель 1", + cardinalityManyToMany: "Источник N · Цель N", + cardinalityDirected: "Источник {source} · Цель {target}", + matchPickCardinality: "Подтвердите совпадение после выбора кардинальности (1:1 / 1:N / N:1 / N:N).", + manualAddRelationship: "Добавить вручную", + confirmMatch: "Подтвердить", + ignoreMatch: "Игнорировать", + addRelationship: "Добавить связь", + removeRelationship: "Удалить связь", + relationshipIncomplete: "Выберите и исходный, и целевой столбцы", + relationshipSelfInvalid: "Связь не может ссылаться на тот же столбец", + relationshipExists: "Эта связь уже существует", + relationshipAdded: "Связь добавлена", + noJoinSql: "Нет SQL связи для копирования", + allTables: "Все таблицы", + relatedTables: "Связанные таблицы", + moreColumns: "+ {count} столбцов", + exportSvg: "Экспорт SVG", + exportPng: "Экспорт PNG", + exportJson: "Экспорт JSON", + exportDbml: "Экспорт DBML", + exportMermaid: "Экспорт Mermaid", + export: "Экспорт", + exportedSvg: "SVG экспортирован", + exportedFormat: "{format} экспортирован", + exportSvgFailed: "Не удалось экспортировать SVG: {message}", + exportFailed: "Не удалось экспортировать {format}: {message}", + zoomIn: "Увеличить", + zoomOut: "Уменьшить", + fitView: "По размеру окна", + resetZoom: "Сбросить масштаб", + undo: "Отменить", + redo: "Повторить", + resetLayout: "Сбросить расположение", + fullscreen: "Полный экран", + exitFullscreen: "Выйти из полноэкранного режима", + addLayer: "Добавить слой", + noLayersYet: "Слоёв пока нет. Нажмите +, чтобы создать слой.", + layoutFree: "Свободное", + layoutAuto: "Авто", + layerLock: "Заблокировать слой (пропускать авторасположение внутри)", + layerUnlock: "Разблокировать слой (разрешить авторасположение внутри)", + layerLocked: "Заблокирован", + layerUnlocked: "Разблокирован", + hideLayer: "Скрыть слой", + showLayer: "Показать слой", + deleteLayer: "Удалить слой", + layerHiddenCannotFocus: "Слой скрыт — покажите его, чтобы перейти к нему на холсте", + createTable: "Новая таблица", + createTableNotSupported: "Создание таблиц не поддерживается для этой базы данных", + create: "Создать", + syncToDatabase: "Синхронизировать с базой данных", + structureSyncNotSupported: "Синхронизация структуры таблиц не поддерживается для этой базы данных", + syncDraftCount: "Изменений для синхронизации: {count} (create / alter / drop)", + executeSync: "Выполнить", + syncing: "Синхронизация…", + buildingSql: "Построение SQL…", + noSqlYet: "SQL пока нет", + copySql: "Копировать SQL", + tableName: "Имя таблицы", + tableNameRequired: "Требуется имя таблицы", + tableNameExists: "Таблица с таким именем уже существует", + assignLayer: "Слой", + noLayer: "Без слоя", + withDefaultIdPk: "Включить первичный ключ id по умолчанию", + inspectorTable: "Таблица", + inspectorRelationship: "Связь", + fieldComment: "Комментарий", + fields: "Поля", + tabFields: "Поля", + tabIndexes: "Индексы", + addIndex: "Добавить индекс", + indexName: "Имя индекса", + indexUnique: "UNIQUE", + indexColumns: "Столбцы", + noIndexesYet: "Индексов пока нет", + indexesNotSupported: "Создание индексов не поддерживается для этой базы данных из редактора диаграмм", + addColumnNotSupported: "Добавление столбцов не поддерживается для этой базы данных", + dropColumnNotSupported: "Удаление столбцов не поддерживается для этой базы данных", + dropTableNotSupported: "Удаление таблиц не поддерживается для этой базы данных из редактора диаграмм", + addField: "Добавить поле", + deleteField: "Удалить поле", + undoDropField: "Отменить удаление поля", + noFieldsYet: "Полей пока нет — добавьте поле для синхронизации", + deleteDraftTable: "Удалить черновик таблицы", + deleteLiveTable: "Удалить таблицу", + deleteLiveTableHint: "Помечает таблицу для DROP TABLE при следующей синхронизации. При необходимости отмените через историю.", + deleteLiveTableConfirm: "Пометить эту таблицу для DROP TABLE при синхронизации с базой данных?", + liveTableReadOnly: "Живая таблица — редактируйте структуру в редакторе таблиц", + liveTableAddColumnsHint: "Добавляйте столбцы (ALTER ADD) или помечайте существующие для удаления (ALTER DROP), затем синхронизируйте. Редактирование типов существующих столбцов остаётся в редакторе структуры таблицы.", + liveTableIndexesReadOnly: "Редактируйте индексы для живых таблиц в редакторе структуры таблицы", + pendingColumnsBadge: "Ожидающие изменения", + pendingDropColumnBadge: "Удалить", + pendingDropTableBadge: "Удалить таблицу", + source: "Источник", + target: "Цель", + emptyDesignHint: "Пока нет таблиц. Создайте слой и таблицы, отредактируйте поля в инспекторе, затем синхронизируйте с базой данных.", + removeFromLayer: "Убрать из слоя", + addTables: "Добавить таблицы", + tabSelectExisting: "Выбрать существующие", + tabCreateTable: "Новая таблица", + multiSelect: "Множественный выбор", + closeMultiSelect: "Закрыть", + selectAll: "Выбрать все", + clearSelection: "Очистить", + tablesInOtherLayers: "Таблицы в других слоях", + filterTables: "Фильтр таблиц...", + noMatchingTables: "Нет подходящих таблиц", + addSelectedCount: "Добавить выбранные ({count})", + layerNameTooLong: "Имя слоя должно быть меньше 50 символов", + layerNameInvalid: "Имя слоя может содержать буквы, цифры, китайские символы, пробелы, подчёркивания, дефисы и точки", + layerNameExists: "Имя слоя уже существует", + total: "всего", + confirmed: "подтверждено", + pending: "в ожидании", + conflicts: "конфликты", + conflict: "Конфликт", + ignored: "проигнорировано", + confirmAll: "Подтвердить все", + ignoreAll: "Игнорировать все", + clearAll: "Очистить все", + confidenceHigh: "Высокая", + confidenceMedium: "Средняя", + confidenceLow: "Низкая", + noInferred: "Нет выведенных связей", + editRelationship: "Изменить", + saveRelationship: "Сохранить", + deleteRelationship: "Удалить", + confirmDeleteRelationship: "Удалить эту связь?", + confirmDeleteRelationshipAction: "Удалить", + confirmRelationship: "Подтвердить", + ignoreRelationship: "Игнорировать", + relationshipKindFk: "Внешний ключ", + relationshipKindCustom: "Пользовательская", + relationshipKindInferred: "Выведенная", + relationshipReadOnlyFk: "Эта связь основана на внешнем ключе базы данных и не может быть изменена здесь.", + relationshipUpdated: "Связь обновлена", + }, + etcd: { + adminPermissionRequired: "Для этого представления etcd требуется роль root.", + targetKeyWriteDenied: "У целевого подключения нет прав на запись этого ключа.", + selectedKeysWriteDenied: "У целевого подключения нет прав на запись выбранных ключей; изменения не внесены.", + prefixPlaceholder: "Поиск пути ключа, например /app/ или service", + newKey: "Новый ключ", + loadingKeys: "Загрузка ключей...", + empty: "Ключи не найдены", + loadMore: "Загрузить ещё", + selectKey: "Выберите ключ, чтобы просмотреть его значение", + loadingValue: "Загрузка значения...", + notFound: "Ключ не найден", + edit: "Изменить", + editKey: "Изменить ключ", + delete: "Удалить", + deleteTitle: "Удалить ключ etcd", + keyPlaceholder: "/path/to/key", + keyRequired: "Ключ обязателен", + ttl: "TTL (секунды)", + ttlPlaceholder: "Введите положительное число секунд", + ttlInvalid: "TTL должно быть положительным целым числом", + ttlUnavailable: "Обновите агент etcd и переподключитесь, чтобы настроить TTL.", + expiryMode: "Политика истечения", + expiryPermanent: "Постоянный", + expiryPermanentHint: "Не привязывать аренду; ключ не будет истекать автоматически", + expiryTtl: "Время жизни (TTL)", + expiryTtlHint: "Создать временную аренду, которая истекает через заданный интервал", + expiryLease: "Привязать аренду", + expiryLeaseHint: "Привязать ключ к существующему ID аренды", + leaseId: "ID аренды", + leasePlaceholder: "Введите существующий ID аренды", + leaseInvalid: "ID аренды должен быть допустимым положительным 64-битным целым числом", + valueContent: "Содержимое значения", + keyAlreadyExists: "Ключ с таким именем уже существует. Выберите другое имя или закройте этот диалог и измените существующий ключ.", + conflict: "Этот ключ изменился после загрузки. Обновите его и повторите попытку.", + saved: "Ключ сохранён", + deleted: "Ключ удалён", + base64Readonly: "Редактируйте значения Base64 в режиме Base64.", + rename: "Переименовать", + clone: "Клонировать", + copyKey: "Копировать ключ", + export: "Экспорт", + exportAll: "Экспортировать все", + exportSelection: "Экспортировать выбранное", + batchExport: "Пакетный экспорт", + exportAllJson: "Экспортировать все (JSON, пригодно для импорта)", + exportAllCsv: "Экспортировать все (CSV)", + exportAllMarkdown: "Экспортировать все (Markdown)", + exportSelectionJson: "Экспортировать выбранное (JSON)", + exportSelectionCsv: "Экспортировать выбранное (CSV)", + exportSelectionMarkdown: "Экспортировать выбранное (Markdown)", + import: "Импорт", + sync: "Синхронизация", + history: "История", + restore: "Восстановить эту версию", + compare: "Сравнить", + format: "Формат значения", + savePreview: "Проверить изменения значения", + globalSearch: "Глобальный поиск", + searchPrefix: "Ограничить префиксом (необязательно)", + searchAll: "Ключ и значение", + searchPlaceholder: "Поиск по содержимому ключа или значения", + searchProgress: "Просканировано ключей: {scanned}, совпадений: {matched}", + exportResults: "Экспортировать результаты", + clearSearchResults: "Очистить результаты", + exported: "Экспортировано ключей: {count}", + selectAllLoaded: "Выбрать все", + deselectAll: "Очистить", + batchDelete: "Пакетное удаление", + batchDeleteTitle: "Удалить выбранные ключи etcd", + batchDeleteConfirm: "Удалить выбранные ключи ({count})? Это действие нельзя отменить.", + batchDeleteSuccess: "Удалено ключей: {count}", + batchDeletePartial: "Удалено ключей до остановки пакета: {count}. Ошибка: {error}", + importPreview: "Предпросмотр импорта", + syncPreview: "Предпросмотр синхронизации", + targetConnection: "Выберите целевое подключение etcd", + targetReadOnly: "Целевое подключение доступно только для чтения; операции импорта и синхронизации невозможны.", + mirrorDelete: "Удалять лишние ключи в целевом хранилище (зеркалирование)", + mirrorDeleteWarning: "Режим зеркалирования удаляет целевые ключи, отсутствующие в источнике. Проверьте каждую операцию удаления перед применением.", + preparingPreview: "Подготовка предпросмотра изменений с фиксированной ревизией...", + operation: "Операция", + reason: "Причина", + selectedOperations: "Выбрано операций: {count}", + applyOperations: "Применить операции", + transferApplied: "Применено операций: {count}", + operationApplied: "Успешно применено", + transferPartiallyApplied: "Применено операций до остановки пакета: {count}. Ошибка: {error}. Предпросмотр обновлён; повторите только оставшиеся выбранные операции.", + transferPartialRefreshFailed: "Применено операций до остановки пакета: {count}. Ошибка: {error}. Обновление предпросмотра также не удалось: {previewError}. Закройте и снова откройте предпросмотр перед повторной попыткой.", + targetChangedDuringTransfer: "Целевое подключение изменилось во время выполнения пакета", + watch: "Наблюдение", + lease: "Аренда", + key: "Ключ", + keyOrPrefix: "Ключ или префикс", + selectExistingLease: "Выберите существующую аренду", + enterLeaseId: "Или введите ID аренды вручную", + leasePickerHint: "Выберите аренду из этого сеанса или введите ID аренды вручную.", + noLeasePickerHint: "В этом сеансе нет доступных аренд. Введите ID вручную и сохраните.", + registryWarning: "Этот ключ находится в /registry/ — пространстве имён, часто используемом компонентами control-plane. Перед сохранением проверьте владельца и влияние.", + access: { + users: "Пользователи", + roles: "Роли", + title: "Управление доступом", + description: "Управление встроенными пользователями, ролями и правами на ключи etcd", + readOnly: "Подключение только для чтения", + refresh: "Обновить", + userCount: "Пользователи ({count})", + roleCount: "Роли ({count})", + createUser: "Создать пользователя", + createRole: "Создать роль", + noUsers: "Пользователи etcd ещё не созданы", + noRoles: "Роли etcd ещё не созданы", + selectUser: "Выберите пользователя слева, чтобы просмотреть роли и действия с учётными данными", + selectRole: "Выберите роль слева, чтобы просмотреть и настроить права", + loadingUser: "Загрузка данных пользователя...", + loadingRole: "Загрузка данных роли...", + userRolesSummary: "Назначено ролей: {count}. Пароли никогда не читаются, не отображаются и не сохраняются клиентом.", + changePassword: "Изменить пароль", + deleteUser: "Удалить пользователя", + roleAssignments: "Назначенные роли", + roleAssignmentHint: "Роли определяют диапазоны ключей, которые пользователь может читать и записывать.", + revokeAssociation: "Отозвать связь", + noAssignedRoles: "У этого пользователя нет назначенных ролей.", + assignRole: "Назначить роль", + assignRoleHint: "Выберите роль, которая ещё не назначена этому пользователю.", + selectRoleOption: "Выберите роль", + noAssignableRoles: "Нет ролей, доступных для назначения", + grantRole: "Назначить роль", + rolePermissionHint: "Права могут охватывать все ключи, префикс или точный ключ. Префиксы хранятся как полуоткрытые диапазоны etcd.", + grantPermission: "Предоставить право", + deleteRole: "Удалить роль", + resource: "Ресурс", + permission: "Право", + allKeys: "Все ключи", + exactKey: "Точный ключ", + allKeyspace: "Всё пространство ключей", + edit: "Изменить", + revoke: "Отозвать", + noPermissions: "У этой роли нет прав.", + createEtcdUser: "Создать пользователя etcd", + username: "Имя пользователя", + password: "Пароль", + initialRoles: "Начальные роли", + optional: "Необязательно", + initialRolesHint: "Выбранные роли будут назначены сразу после создания.", + selectedCount: "Выбрано: {count}", + noRolesForNewUser: "Ролей пока нет. Можно сначала создать пользователя, а роли назначить из его данных.", + createAndAssignRoles: "Создать и назначить роли ({count})", + createUserAction: "Создать пользователя", + createEtcdRole: "Создать роль etcd", + roleName: "Имя роли", + initialPermission: "Начальное право", + initialPermissionHint: "Если указано, это право предоставляется при создании роли.", + keyOrPrefixPlaceholder: "Ключ или префикс", + allKeysHint: "Это предоставляет доступ ко всем ключам.", + createAndGrantPermission: "Создать и предоставить право", + read: "Чтение", + write: "Запись", + readWrite: "Чтение и запись", + passwordHint: "Новый пароль отправляется только с этим запросом и очищается из интерфейса после отправки.", + newPassword: "Новый пароль", + continue: "Продолжить", + editPermission: "Изменить право роли", + permissionUpdateHint: "В etcd Auth нет атомарного обновления. При сохранении старое право отзывается, затем предоставляется новое. Если предоставление не удаётся, DBX пытается восстановить старое право.", + saveChanges: "Сохранить изменения", + dangerousTitle: "Подтвердите опасную операцию", + dangerousHint: "Эта операция напрямую изменяет данные etcd Auth. Введите текст подтверждения ниже, чтобы продолжить.", + confirmationPlaceholder: "Введите текст подтверждения", + confirmExecute: "Подтвердить и выполнить", + cancel: "Отмена", + preflightRequired: "Для этого изменения прав требуется новое подтверждение. Нажмите «Сохранить изменения» и подтвердите снова.", + preflightExpired: "Срок действия подтверждения истёк. Нажмите «Сохранить изменения» и подтвердите снова.", + preflightMismatch: "Содержимое подтверждения или ожидающее право изменилось. Подтвердите снова перед повторной попыткой.", + confirmationMismatch: "Тексты подтверждения не совпадают. Повторите попытку.", + createdUser: "Создан пользователь {user}", + createdUserWithRoles: "Создан пользователь {user} и назначено ролей: {count}", + createdUserRolesFailed: "Пользователь создан, но назначить начальные роли не удалось: {error}", + createdRole: "Создана роль {role}", + createdRoleWithPermission: "Создана роль {role} и предоставлено её начальное право", + createdRolePermissionFailed: "Роль создана, но предоставить её начальное право не удалось: {error}", + deletedUser: "Удалён пользователь {user}", + deletedRole: "Удалена роль {role}", + passwordUpdated: "Обновлён пароль для {user}", + roleGranted: "Роль {role} назначена пользователю {user}", + roleRevoked: "У пользователя {user} отозвана роль {role}", + permissionGranted: "Право роли предоставлено", + permissionUpdated: "Право роли обновлено", + permissionRevoked: "Право роли отозвано", + }, + admin: { + maintenance: "Обслуживание", + watch: "Наблюдение", + lease: "Аренда", + refresh: "Обновить", + maintenanceTitle: "Обслуживание истории и диска", + maintenanceDescription: "Сначала очистите неиспользуемую историю, затем решите, восстанавливать ли дисковое пространство бэкенда. Эти операции не заменяют друг друга.", + currentRevision: "Текущая ревизия {revision}", + reachableMembers: "Доступные участники {reachable} / {total}", + compactTitle: "Сжать историю", + compactDescription: "Удаляет историю MVCC до указанной ревизии. Текущие значения ключей сохраняются, но исторические чтения и наблюдения, начатые раньше, восстановить нельзя.", + compactDiskHint: "Это не освобождает дисковое пространство. Запустите дефрагментацию после сжатия, чтобы уменьшить размер файла бэкенда.", + compactRevision: "Начало хранения истории (ревизия)", + compactPlaceholder: "Например {revision}", + compactRequired: "Введите ревизию, с которой сохранять историю.", + compactDone: "Сжатие истории завершено", + compactInputHint: "Удаляет историю до этой ревизии. Перед продолжением убедитесь, что эти исторические версии больше не нужны.", + compactAction: "Сжать историю", + defragTitle: "Восстановить дисковое пространство", + defragDescription: "Дефрагментация перезаписывает бэкенд каждого участника, возвращая освобождаемое дисковое пространство операционной системе. Follower обрабатываются последовательно перед текущим лидером.", + defragWarning: "Каждый участник ненадолго недоступен во время дефрагментации. Участники обрабатываются по одному, текущий лидер — последним; сначала убедитесь, что кластер исправен.", + defragReachableMembers: "Обработать доступных участников: {count}", + leaderLast: "Лидер последним: {endpoint}", + defragAction: "Восстановить дисковое пространство на участниках: {count}", + defragDone: "Дефрагментация завершена", + newWatch: "Новое наблюдение", + editWatch: "Изменить наблюдение", + watchSearch: "Фильтр наблюдений", + watchKeyPlaceholder: "Например /apps/payment/config", + watchScope: "Область наблюдения", + prefix: "Префикс", + exact: "Точный ключ", + watchKeyHint: "Получать события создания, изменения и удаления для этого ключа.", + watchPrefixHint: "Получать события для всех ключей, начинающихся с этого префикса.", + watchSessionHint: "Наблюдения работают только в этом сеансе подключения и останавливаются при закрытии подключения или уходе со страницы etcd. В одном подключении может работать до четырёх наблюдений.", + watchCount: "Создано: {count}", + runningWatchCount: "Работает: {count}", + watchList: "Созданные наблюдения", + itemCount: "Элементов: {count}", + scope: "Область", + status: "Статус", + actions: "Действия", + createWatch: "Создать и запустить наблюдение", + saveWatch: "Сохранить конфигурацию", + running: "Работает", + stopped: "Остановлено", + error: "Ошибка", + editWatchTitle: "Изменить наблюдение", + stopWatch: "Остановить наблюдение", + startWatch: "Запустить наблюдение", + deleteWatch: "Удалить наблюдение", + noMatchingWatches: "Нет подходящих наблюдений", + noWatches: "Наблюдений пока нет.", + eventStream: "Поток событий", + eventCount: "Событий: {count}", + filter: "Фильтр", + event: "Событие", + create: "Создание", + update: "Изменение значения", + delete: "Удаление", + noFilteredEvents: "Нет событий, соответствующих текущему фильтру", + waitingEvents: "Ожидание изменений ключей...", + watchNotRunning: "Это наблюдение не запущено.", + selectWatch: "Выберите наблюдение слева, чтобы просмотреть его поток событий", + leaseDescription: "Когда аренда истекает, все привязанные ключи автоматически удаляются.", + grantLease: "Предоставить аренду", + renew: "Продлить", + revoke: "Отозвать", + previousPage: "Назад", + nextPage: "Вперёд", + leasePageSize: "До {count} элементов на странице", + grantedTtl: "Предоставлено на {ttl} с", + noKnownLeases: "В этом сеансе нет известных аренд", + loadingLease: "Загрузка данных аренды...", + keepalive: "Автоматически продлевать каждые TTL / 3, пока эта страница открыта", + attachedKeys: "Привязанные ключи", + noAttachedKeys: "Нет привязанных ключей", + attachedKeysTruncated: "Результаты по привязанным ключам усечены до 256 записей.", + selectLease: "Выберите аренду, чтобы просмотреть её данные", + leasePartial: "Текущий клиент или сервер etcd не может перечислить аренды. Показаны только аренды, созданные или использованные в этом сеансе; данные и TTL по-прежнему берутся с сервера.", + grantNewLease: "Предоставить новую аренду", + ttl: "TTL (секунды)", + ttlPlaceholder: "Например 60", + ttlHint: "Срок аренды должен быть положительным целым числом.", + customLeaseId: "Свой ID аренды", + customLeasePlaceholder: "Оставьте пустым или введите 0, чтобы etcd назначил его автоматически", + customLeaseHint: "Используйте десятичное целое число. etcd отклоняет уже существующий ID.", + confirmationHint: "Эту операцию обслуживания кластера нельзя автоматически отменить. Перед продолжением оцените последствия.", + confirmationCredentialHint: "Введите текст подтверждения ниже. Подтверждение действительно только для этой операции.", + confirmationPlaceholder: "Введите текст подтверждения", + confirmationPrompt: "Эта операция может повлиять на кластер etcd. Введите текст подтверждения:\n{confirmationText}", + confirmExecute: "Подтвердить и выполнить", + cancel: "Отмена", + noReachableMembers: "Нет доступных участников для дефрагментации.", + defragStopped: "Дефрагментация остановлена: успешно — {succeeded}, ошибок — {failed}, не выполнено — {notExecuted}", + defragCompleted: "Дефрагментация завершена: успешно {succeeded}/{total}", + leaseRenewed: "Аренда {id} продлена", + leaseGrantCancelled: "Ожидание остановлено. etcd может всё ещё обрабатывать запрос; обновите, чтобы проверить, создана ли аренда.", + leaseCreated: "Создана аренда {id}", + }, + dashboard: { + title: "Панель etcd", + description: "Наблюдение на основе доступных клиенту эндпоинтов; это не авторитетная проверка работоспособности кворума.", + autoRefreshOff: "Автообновление выключено", + refresh: "Обновить", + retry: "Проверить снова", + loadFailed: "Не удалось загрузить панель etcd", + agentUpgradeTitle: "Панель недоступна с текущим агентом etcd", + agentUpgradeDescription: "Это подключение всё ещё использует старый агент, который не может читать состояние кластера. Просмотр и редактирование ключей по-прежнему доступны.", + agentUpgradeSteps: "Обновите агент etcd в диспетчере драйверов, затем отключите и снова подключите это подключение etcd. По завершении нажмите «Проверить снова».", + observedHealth: "Наблюдаемое состояние", + reachableMembers: "Доступные участники", + keyCount: "Количество ключей", + backendSize: "Размер бэкенда", + fragmentation: "Оценка фрагментации", + cluster: "кластер", + revision: "ревизия", + leader: "лидер", + noAlarms: "Активных тревог не обнаружено", + prometheusMetrics: "Метрики среды выполнения Prometheus", + prometheusDescription: "Стабильные метрики, собираемые из etcd /metrics. Скорости рассчитываются по двум соседним замерам.", + collectedAt: "Собрано в", + requests: "Скорость запросов gRPC", + requestFailureRate: "Доля неудачных запросов", + proposals: "Предложения Raft", + proposalLag: "Задержка между фиксацией и применением", + pending: "в ожидании", + diskLatency: "Задержка записи на диск", + walFsync: "Средний fsync WAL", + backendCommit: "Средняя фиксация бэкенда", + networkTraffic: "Сетевой трафик клиента", + peerTraffic: "Трафик между узлами", + processResources: "Ресурсы процесса", + runtime: "Среда выполнения Go", + goroutines: "горутины", + leaderChanges: "Всего смен лидера", + failedProposals: "Всего неудачных предложений", + failedProposalRate: "Доля отказов", + rateNeedsRefresh: "Обновите ещё раз для расчёта текущих скоростей", + storageQuota: "Использование квоты бэкенда", + uptime: "Время работы процесса", + consensusReliability: "Консенсус и надёжность", + leadership: "Лидерство", + knownPeers: "известных узлов", + proposalState: "Состояние предложений", + raftFailures: "Сбои Raft", + revisionState: "Ревизия MVCC", + compactRevision: "Ревизия сжатия", + requestLoad: "Нагрузка запросов", + grpcMethod: "Метод gRPC", + total: "Всего", + rate: "Скорость", + failures: "Отказы", + lag: "Задержка", + slowApply: "Медленное применение", + putBytes: "Байты Put", + avgLatency: "Средняя задержка", + storageDisk: "Хранилище и диск", + databaseState: "Состояние базы данных", + inUse: "используется", + openReadTransactions: "Открытые транзакции чтения", + backgroundTasks: "Фоновые задачи", + watchState: "Состояние наблюдений", + watchers: "Наблюдатели", + watchStreams: "Потоки наблюдений", + events: "Скорость событий", + slowPending: "Медленные / в ожидании", + leaseState: "Жизненный цикл аренд", + granted: "Скорость предоставления", + renewed: "Скорость продления", + revokedExpired: "Отозвано / истекло", + averageTtl: "Средний TTL", + runtimeResources: "Ресурсы среды выполнения", + memory: "Память", + processNetworkGc: "Сеть процесса и GC", + metricsUnavailable: "Метрики Prometheus недоступны", + metricsUnavailableHint: "Состояние кластера по-прежнему доступно. DBX запрашивает /metrics напрямую с текущего эндпоинта etcd; проверьте, что полученный URL доступен из приложения DBX.", + endpointMember: "Эндпоинт / участник", + role: "Роль", + version: "Версия", + raftTermApplied: "Терм Raft / применено", + dbSizeInUse: "Размер БД / используется", + latency: "Задержка", + status: "Статус", + learner: "учащийся", + follower: "follower", + reachable: "доступен", + unreachable: "недоступен", + loading: "Загрузка наблюдения за кластером…", + health: { + unknown: "неизвестно", + critical: "критично", + warning: "предупреждение", + healthy: "здоров", + }, + }, + }, + consul: { + ui: { + unknown: "Неизвестно", + peeringPending: "В ожидании", + peeringEstablishing: "Установка", + peeringActive: "Активно", + peeringFailing: "Сбой", + peeringDeleting: "Удаление", + peeringTerminated: "Завершено", + refresh: "Обновить", + cancel: "Отмена", + create: "Создать", + update: "Обновить", + save: "Сохранить", + delete: "Удалить", + edit: "Изменить", + apply: "Применить", + close: "Закрыть", + hide: "Скрыть", + reveal: "Показать", + copy: "Копировать", + copied: "Скопировано", + copyFailed: "Не удалось скопировать", + copyOnce: "Копировать один раз", + pause: "Пауза", + watchAction: "Наблюдение", + watchPrefix: "Наблюдать за префиксом", + watchModePrefix: "Префикс", + watchModeKey: "Точный ключ", + sessionProtected: "Защищено сеансом", + sessionProtectedHint: "Редактирование и удаление отключены для защиты этой распределённой блокировки.", + atomicTransaction: "Атомарная транзакция", + nonAtomicBatches: "Не атомарно в {count} пакетах", + batchOperation: "Пакет {batch} · OpIndex {op}", + operationTotals: "Успешно {succeeded} · Конфликтов {conflicted} · Пропущено {skipped} · Ошибок {failed}", + deleteOperationTotals: "Успешно {succeeded} · Конфликтов {conflicted} · Ошибок {failed}", + clientSideMigration: "DBX читает из источника и записывает в цель. Это не встроенная репликация Consul между дата-центрами.", + bundleFileType: "Пакет KV Consul DBX", + sourceKeyMissingModifyIndex: "У исходного ключа нет ModifyIndex", + transactionRejected: "Consul отклонил транзакцию", + overview: "Обзор кластера", + capabilities: "Возможности", + probeLoading: "Загрузка", + probeReady: "Готово", + probeForbidden: "Запрещено", + probeUnsupported: "Не поддерживается", + probeError: "Ошибка", + autopilotHealth: "Состояние Autopilot", + datacenter: "Дата-центр", + agentNode: "Узел агента", + agentAddress: "Адрес агента", + version: "Версия", + mode: "Режим", + server: "Сервер", + client: "Клиент", + leader: "Лидер", + raftPeers: "Узлы Raft", + membersAlive: "Активных участников", + members: "Участники", + node: "Узел", + address: "Адрес", + status: "Статус", + alive: "активен", + leaving: "покидает", + failed: "сбой", + previousPage: "Предыдущая страница", + nextPage: "Следующая страница", + pageStatus: "{page} / {pages} · всего {total}", + searchAllServices: "Поиск по всем сервисам", + searchAllNodes: "Поиск по всем узлам", + searchLocalServices: "Поиск локальных сервисов агента", + query: "Запрос", + searchHealthChecks: "Поиск по имени проверки, ID, узлу, сервису, выводу или заметкам", + allCheckTypes: "Все типы проверок", + clearFilters: "Очистить фильтры", + healthResultCount: "{filtered} из {total} проверок", + services: "Сервисы", + nodes: "Узлы", + service: "Сервис", + catalogServices: "Сервисы каталога", + catalogNodes: "Узлы каталога", + noVisibleServices: "Нет видимых сервисов", + noVisibleNodes: "Нет видимых узлов", + noMatchingServices: "Нет подходящих сервисов", + noMatchingNodes: "Нет подходящих узлов", + agentTarget: "Целевой Agent: {target}", + agentTargetVerifying: "Проверка целевого Agent", + unknownWritesDisabled: "неизвестно — запись отключена", + targetAgent: "целевой Agent", + agentWriteReady: "Доступно для записи", + agentReadOnly: "Только чтение", + agentWriteDisabledHint: "Подходящий целевой Agent не настроен, поэтому обслуживание и снятие регистрации отключены. Обнаруженный Agent: {target}.", + agentWriteBlocked: { + connectionUnavailable: "Конфигурация подключения недоступна. Переподключитесь перед записью.", + readOnly: "Это подключение доступно только для чтения. Снятие регистрации службы отключено.", + transport: "Запись через Agent недоступна через Transport Layers. Подключитесь напрямую к целевому Agent.", + targetRequired: "Измените подключение и настройте узел и адрес целевого Agent. Узел должен соответствовать текущему Agent, а адрес — конечной точке подключения.", + identityUnavailable: "Не удалось прочитать идентификатор Agent. Запись отключена. Проверьте подключение и права на чтение Agent, затем обновите.", + nodeMismatch: "Настроенный целевой узел не соответствует текущему Agent. Проверьте параметры подключения.", + directAddressRequired: "Для записи через Agent требуется прямой IP-адрес или конечная точка localhost. DNS-адреса и адреса с балансировкой нагрузки не поддерживаются.", + addressMismatch: "Адрес целевого Agent не соответствует конечной точке подключения. Проверьте параметры подключения.", + invalidAddress: "Адрес подключения Consul недействителен. Проверьте параметры подключения.", + }, + register: "Зарегистрировать", + registrationHint: "Регистрации HTTP Agent относятся к среде выполнения целевого Agent и не изменяют его постоянные файлы конфигурации.", + name: "Имя", + id: "ID", + port: "Порт", + tags: "Теги (через запятую)", + registerOn: "Зарегистрировать на {node}", + catalogInstances: "Экземпляры каталога", + nodeServices: "Службы узла", + serviceId: "ID службы", + localAgentServices: "Локальные службы Agent", + enableMaintenance: "Включить обслуживание", + disableMaintenance: "Отключить обслуживание", + deregister: "Снять регистрацию", + deregisterService: "Снять регистрацию локальной службы {id} с {node}?", + deregistering: "Снятие регистрации", + deregisterServiceHint: "Это удаляет регистрацию службы и связанные проверки. Каталог синхронизируется после этого. Процесс службы продолжает работать и может зарегистрироваться снова.", + deregisterServiceSucceeded: "Служба {id} снята с регистрации на {node}. Синхронизация каталога может занять некоторое время; служба может появиться снова, если приложение зарегистрирует её повторно.", + deregisterRefreshFailed: "Служба снята с регистрации, но обновление не удалось. Обновите вручную", + maintenanceReason: "Запрос пользователя DBX", + serviceDetails: "Подробности {service}", + kind: "Вид", + serviceKind: "ServiceKind", + standard: "стандартный", + metadata: "Метаданные", + nodeMeta: "Метаданные узла", + serviceMeta: "Метаданные службы", + nodeId: "ID узла", + serviceWeights: "Проходит / Предупреждение", + taggedAddresses: "TaggedAddresses", + enableTagOverride: "EnableTagOverride", + agent: "Agent", + watch: "Наблюдение", + writeOperation: "Операция записи", + localServiceDetails: "Подробности локальной службы", + agentIdentityRequestTimedOut: "Истекло время ожидания загрузки идентификатора Agent.", + localServicesRequestTimedOut: "Истекло время ожидания загрузки локальных служб Agent.", + localChecksRequestTimedOut: "Истекло время ожидания загрузки локальных проверок Agent.", + healthChecks: "Проверки работоспособности", + state: "Состояние", + nodeName: "Имя узла", + allStates: "Все состояния", + passing: "Проходит", + warning: "Предупреждение", + critical: "Критично", + watchPaused: "Наблюдение приостановлено", + watchingIndex: "Наблюдение за индексом {index}", + pauseWatch: "Приостановить наблюдение", + startWatch: "Запустить наблюдение", + checkRegistrationHint: "Проверки Agent — это регистрации среды выполнения на {node}, они не сохраняются в файлах конфигурации Agent.", + type: "Тип", + ttl: "TTL", + http: "HTTP", + tcp: "TCP", + grpc: "gRPC", + docker: "Docker", + script: "Скрипт", + arguments: "Аргументы", + containerId: "ID контейнера", + endpoint: "Конечная точка", + interval: "Интервал", + timeout: "Таймаут", + commandArguments: "Аргументы команды", + clusterHealth: "Работоспособность кластера", + nodeHealth: "Работоспособность узла: {node}", + serviceHealth: "Работоспособность службы: {service}", + noMatchingHealthChecks: "Нет подходящих проверок работоспособности", + serviceInstances: "Экземпляры служб", + localAgentChecks: "Локальные проверки Agent", + maintenance: "обслуживание", + ttlPass: "TTL проходит", + ttlWarn: "TTL предупреждение", + ttlFail: "TTL сбой", + deregisterCheck: "Снять регистрацию проверки {id} с {node}?", + checkDetails: "Подробности {check}", + checkId: "ID проверки", + notes: "Заметки", + output: "Вывод", + definition: "Определение", + indexes: "CreateIndex / ModifyIndex", + sessionsAndLocks: "Сеансы и блокировки", + sessions: "Сеансы", + sessionDescription: "Сеанс — это контракт наподобие аренды, используемый блокировками Consul KV. Сеансы с TTL требуют продления; сеансы без TTL существуют до явного уничтожения или аннулирования их проверками.", + createSession: "Создать сеанс", + searchSessions: "Поиск по имени, ID, узлу или проверке сеанса", + sessionResultCount: "Показано {filtered} из {total} сеансов", + noMatchingSessions: "Нет подходящих сеансов", + allSessionTypes: "Все типы сеансов", + ttlSessions: "Сеансы с TTL", + persistentSessions: "Сеансы без TTL", + allBehaviors: "Все варианты поведения", + aclFilteredSessions: "Список сеансов отфильтрован политиками ACL", + sessionRequestTimedOut: "Истекло время ожидания загрузки сеансов. Проверьте подключение к Consul и повторите попытку.", + complete: "Завершить", + lock: "Блокировка", + lockManagement: "Управление блокировками KV", + lockIndex: "LockIndex {index}", + lockDelay: "Задержка блокировки", + lockDelayHint: "0s–60s; задерживает повторное получение после аннулирования.", + nodeOptional: "Узел (необязательно)", + behavior: "Поведение", + behaviorRelease: "release", + behaviorDelete: "delete", + behaviorHint: "release сохраняет удерживаемые ключи; delete удаляет их по истечении срока сеанса.", + releaseLocks: "Освободить блокировки", + deleteKeys: "Удалить ключи", + deleteBehaviorWarning: "Behavior=delete удаляет все ключи, удерживаемые этим сеансом, при его аннулировании. Продолжить?", + checks: "Проверки", + nodeChecks: "Проверки узла", + serviceChecks: "Проверки служб", + nodeCheckShort: "Узел", + serviceCheckShort: "Служба", + serviceChecksPlaceholder: "service:api:health{'@'}namespace-a", + serviceChecksHint: "ID проверок через запятую; используйте ID{'@'}namespace для проверки с заданной областью.", + lockHint: "Просмотрите ключ, выберите сеанс, затем получите или освободите рекомендательную блокировку.", + key: "Ключ", + inspectKey: "Просмотреть ключ", + keyExists: "Ключ существует", + keyNotFound: "Ключ не существует", + keyUnlocked: "Ключ в настоящее время не удерживается", + keyHeldBy: "Удерживается сеансом {session}", + sessionValue: "Сеанс {id}", + modifyIndexValue: "ModifyIndex {index}", + createIndex: "CreateIndex", + modifyIndexLabel: "ModifyIndex", + selectSession: "Выберите сеанс", + sessionId: "ID сеанса", + expectedModifyIndex: "Ожидаемый ModifyIndex (0 для нового ключа)", + value: "Значение", + releaseMatchingSession: "Освободить", + acquire: "Получить", + unnamedSession: "Сеанс без имени", + heldKeys: "Удерживаемые ключи", + heldKeysIncomplete: "Результаты неполные или отфильтрованы по ACL", + stop: "Остановить", + renewNow: "Продлить сейчас", + autoRenew: "Автопродление", + autoRenewPageHint: "Автопродление выполняется только пока это подключение и страница активны.", + noRenewRequired: "Продление не требуется", + noTtl: "Без TTL", + ttlOptional: "TTL (необязательно)", + ttlRangeHint: "Оставьте пустым для постоянного сеанса или используйте 10s–24h.", + invalidSessionTtl: "TTL должен быть пустым или допустимой длительностью от 10s до 24h.", + invalidLockDelay: "Задержка блокировки должна быть допустимой длительностью от 0s до 60s.", + destroy: "Уничтожить", + noHeldKeys: "Нет удерживаемых ключей", + noVisibleSessions: "Нет видимых сеансов", + destroySession: "Уничтожить сеанс {id}? Блокировки, использующие этот сеанс, могут быть освобождены или удалены согласно его поведению.", + destroySessionImpact: "Уничтожить сеанс {id}? Поведение: {behavior}. Удерживаемые ключи ({count}): {keys}", + sessionImpactIncomplete: "Влияние сеанса неполное или отфильтровано по ACL. Уничтожение заблокировано.", + sessionDetails: "TTL {ttl} · {behavior} · проверки {checks}", + tokens: "Токены", + policies: "Политики", + roles: "Роли", + authMethods: "Методы аутентификации", + bindingRules: "Правила привязки", + templatedPolicies: "Шаблонные политики", + capability: "Возможность: {status}", + capabilitySupported: "Поддерживается", + capabilityUnsupported: "Не поддерживается", + capabilityDisabled: "Отключено", + capabilityForbidden: "Нет прав", + capabilityUnknown: "Неизвестно", + loading: "Загрузка...", + viewOrEdit: "Просмотр или изменение", + cloneToken: "Клонировать токен", + deleteAndInspectReferences: "Удалить и проверить ссылки", + noResources: "Нет ресурсов", + editResource: "Изменить {kind}", + createResource: "Создать {kind}", + knownImpact: "Известное влияние: {tokens} токенов, {roles} ролей, {bindingRules} правил привязки", + incomplete: "(неполно)", + reviewAclChanges: "Проверить изменения ACL", + deleteResource: "Удалить {label}", + tokenReferences: "Ссылки на токены: {tokens} · Ссылки на роли: {roles} · Ссылки на правила привязки: {bindingRules}", + impactBlocked: "Влияние неполное или отфильтровано по ACL. Удаление заблокировано.", + cloneTokenDescription: "Описание клонированного токена", + scope: "Область Consul", + adminPartition: "Административный раздел", + namespace: "Пространство имён", + default: "по умолчанию", + applyScope: "Применить область", + enterpriseCapability: "Возможность Enterprise: {status}. Действия жизненного цикла недоступны.", + namespaces: "Пространства имён", + lifecycleImpact: "Влияние на ресурсы области", + inspectImpactAndDelete: "Проверить влияние и удалить", + impactAclFiltered: "Consul сообщает о результатах, отфильтрованных по ACL; удаление заблокировано.", + impactUnavailable: "Не удалось перечислить: {resources}", + impactResource: { + services: "Службы", + nodes: "Узлы", + kvKeys: "Ключи KV", + healthChecks: "Проверки работоспособности", + sessions: "Сеансы", + configEntries: "Записи конфигурации", + intentions: "Намерения", + peerings: "Пиринги", + namespaces: "Пространства имён", + aclTokens: "Токены ACL", + aclPolicies: "Политики ACL", + aclRoles: "Роли ACL", + aclAuthMethods: "Методы аутентификации ACL", + aclBindingRules: "Правила привязки ACL", + }, + configEntries: "Записи конфигурации", + intentions: "Намерения", + discoveryChain: "Цепочка обнаружения", + peering: "Пиринг", + exportedServices: "Экспортированные службы", + configEntryKind: "Вид записи конфигурации", + loadKind: "Загрузить вид", + newJson: "Новый JSON", + modifyIndex: "ModifyIndex {index}", + rawJson: "Необработанный JSON", + newIntention: "Новое намерение", + sourceService: "Исходная служба", + destinationService: "Целевая служба", + check: "Проверка", + matchSource: "Совпадение источника", + matchDestination: "Совпадение назначения", + allowed: "Разрешено", + denied: "Запрещено", + matchedIntentions: "Совпало намерений: {count}", + details: "Подробности", + serviceName: "Имя службы", + compile: "Скомпилировать", + defaultProtocol: "протокол по умолчанию", + configuredDatacenter: "настроенный дата-центр", + start: "Начать", + next: "Далее: {nodes}", + terminalTarget: "Терминал / цель", + upstreamTargets: "Восходящие цели ({count})", + peerName: "Имя пира", + peeringToken: "Токен пиринга для установления", + generateToken: "Создать токен", + establish: "Установить", + editExportedServices: "Изменить запись exported-services", + serviceMeshConfigEntry: "Запись конфигурации Service Mesh", + applyWithCas: "Применить с CAS", + reviewMeshChanges: "Проверить изменения Service Mesh", + deleteConfig: "Удалить {kind}/{name}?", + deleteIntention: "Удалить намерение {id}?", + deleteIntentionExact: "Удалить намерение {source} -> {destination}?", + deletePeering: "Удалить пиринг {name}?", + permissions: "Разрешений: {count}", + actionRule: "правило действия", + tools: "Инструменты Consul", + preparedQueries: "Подготовленные запросы", + events: "События", + coordinates: "Сетевые координаты", + queryName: "Имя запроса", + targetService: "Целевая служба", + targetServiceValue: "Целевая служба: {service}", + cancelEdit: "Отменить изменение", + execute: "Выполнить", + explain: "Объяснить", + eventName: "Имя события", + payload: "Полезная нагрузка", + fire: "Отправить", + deletePreparedQuery: "Удалить подготовленный запрос {id}?", + nodesDatacenter: "Узлов: {count} · {datacenter}", + coordinateError: "{segment} · ошибка {error}", + preparedQueriesDescription: + "Многоразовые запросы обнаружения служб, хранящиеся в Consul. Execute разрешает совпадающие работоспособные экземпляры служб; Explain показывает действующий запрос. Простой редактор изменяет только имя и целевую службу, сохраняя расширенные поля, уже сохранённые Consul.", + eventsDescription: "Лёгкие сообщения доставки по возможности, распространяемые через gossip Consul. События — это временная диагностика или уведомления, а не надёжная очередь сообщений.", + coordinatesDescription: "Сетевые координаты только для чтения, оцениваемые Consul для сравнения сетевой близости. Они не являются географическими местоположениями.", + noPreparedQueries: "Нет подготовленных запросов", + noEvents: "Нет недавних событий", + noCoordinates: "Нет сетевых координат", + queryExecutionResult: "Результат выполнения · экземпляров: {count} · {datacenter}", + noQueryNodes: "Ни один экземпляр службы не соответствует этому запросу", + queryExplanation: "Действующий запрос", + eventNodeFilter: "Регулярное выражение узла (необязательно)", + eventServiceFilter: "Регулярное выражение службы (необязательно)", + eventTagFilter: "Регулярное выражение тега (необязательно)", + eventPayloadBytes: "Полезная нагрузка {count} / 100 байт", + segment: "Сегмент", + error: "Ошибка", + adjustment: "Корректировка", + height: "Высота", + operatorReadOnly: "Оператор (только чтение)", + snapshot: "Снимок", + snapshotRestore: "Восстановление из снимка", + targetDatacenter: "Целевой дата-центр", + restoreSnapshot: "Восстановить из снимка", + restoreSnapshotConfirmation: "ВОССТАНОВИТЬ СНИМОК {datacenter}", + autopilotUpdate: "Обновление Autopilot", + cleanupDeadServers: "Очистить мёртвые серверы", + updateAutopilot: "Обновить Autopilot", + updateAutopilotConfirmation: "ОБНОВИТЬ AUTOPILOT", + raftOperations: "Операции Raft", + serverId: "ID сервера", + peerAddress: "Адрес пира (только удаление)", + reenterIdAddress: "Повторно введите ID или адрес", + transferLeader: "Передать лидерство", + removePeer: "Удалить пира", + gossipKeyring: "Связка ключей gossip", + operation: "Операция", + install: "Установить", + use: "Использовать", + remove: "Удалить", + gossipKey: "Ключ gossip", + changeKeyring: "Изменить связку ключей", + changeKeyringConfirmation: "ИЗМЕНИТЬ СВЯЗКУ КЛЮЧЕЙ", + licenseUpdate: "Обновление лицензии", + license: "Лицензия", + updateLicense: "Обновить лицензию", + updateLicenseConfirmation: "ОБНОВИТЬ ЛИЦЕНЗИЮ", + }, + tools: { + search: "Поиск", + searchTitle: "Поиск в Consul KV", + searchQuery: "Текст для поиска", + prefixOptional: "Префикс (необязательно)", + searchAll: "Ключи и значения", + searchKeys: "Только ключи", + searchValues: "Только значения", + caseSensitive: "С учётом регистра", + scanned: "Просканировано ключей: {count}", + searchLimited: "Результаты ограничены для защиты подключения.", + noSearchResults: "Нет подходящих ключей", + searchSummary: "{matched} совпадений из {scanned} просканированных ключей", + exportSearchResults: "Экспортировать результаты", + searchResultsFileType: "Результаты поиска Consul KV", + searchResultsExported: "Экспортировано результатов поиска: {count}", + exportPrefix: "Экспортировать префикс", + prefix: "Префикс", + emptyPrefixAll: "Оставьте пустым для всех доступных ключей", + exportLimitHint: "Экспорт включает текущую область и сохраняет метаданные ключей, необходимые для безопасного импорта.", + exported: "Экспортировано ключей: {count}", + import: "Импорт", + importTitle: "Импортировать набор Consul KV", + invalidBundle: "Этот файл не является допустимым набором DBX Consul KV", + importApplied: "Импортировано ключей: {count}", + migrate: "Перенести", + migrateTitle: "Перенести Consul KV", + sourcePrefix: "Исходный префикс", + targetConnection: "Целевое подключение", + selectTarget: "Выберите целевое подключение", + targetReadOnly: "Целевое подключение доступно только для чтения.", + conflictPolicy: "Политика конфликтов", + policyAbort: "Прервать при конфликте", + policySkip: "Пропускать конфликты", + policyCas: "Использовать CAS", + bundleSummary: "Ключей: {count} · Дата-центр {dc} · Пространство имён {ns} · Раздел {partition}", + creates: "Создать {count}", + updates: "Обновить {count}", + unchanged: "Без изменений {count}", + skipped: "Пропущено {count}", + conflicts: "Конфликтов {count}", + loadPreview: "Загрузить предпросмотр", + loadingPreview: "Загрузка предпросмотра...", + apply: "Применить", + preview: "Предпросмотр", + deletePrefix: "Удалить префикс", + deletePrefixTitle: "Удалить префикс Consul KV", + deletePrefixPlaceholder: "Префикс для удаления", + deletePrefixWarning: "Эта операция удаляет все видимые ключи под префиксом. Просмотрите предпросмотр перед подтверждением.", + candidates: "Кандидатов {count}", + lockedCount: "Заблокировано {count}", + filtered: "отфильтровано", + complete: "завершено", + confirmDeletePrefix: "Удалить подтверждённые ключи", + prefixDeleted: "Удалено ключей: {count}", + operation: { + create: "Создать", + update: "Обновить", + unchanged: "Без изменений", + skipped: "Пропущено", + conflict: "Конфликт", + locked: "Заблокировано", + succeeded: "Успешно", + conflicted: "Конфликт", + failed: "Ошибка", + }, + }, + prefixPlaceholder: "Префикс ключа, напр. app/ или services/", + newKey: "Новый ключ", + loadingKeys: "Загрузка ключей...", + empty: "Ключи не найдены", + loadMore: "Загрузить ещё", + selectKey: "Выберите ключ, чтобы просмотреть его значение", + loadingValue: "Загрузка значения...", + notFound: "Ключ не найден", + edit: "Изменить", + editKey: "Изменить ключ", + delete: "Удалить", + deleteTitle: "Удалить ключ Consul KV", + keyLabel: "Ключ", + keyPlaceholder: "path/to/key", + keyRequired: "Ключ обязателен", + rootReadonly: "Корневой префикс нельзя изменять. Введите путь ключа.", + saved: "Ключ сохранён", + deleted: "Ключ удалён", + base64Readonly: "Изменяйте бинарные значения в режиме Base64.", + rename: "Переименовать", + clone: "Клонировать", + copyKey: "Копировать ключ", + export: "Экспорт", + value: "Значение", + valueContent: "Значение", + format: "Формат", + metadata: "Метаданные KV", + prettyJson: "Форматированный", + invalidJson: "Недействительный JSON", + summarySize: "Размер", + conflict: "Этот ключ изменился после загрузки. Обновите его и повторите попытку.", + keyAlreadyExists: "Ключ с таким именем уже существует. Выберите другое имя или измените существующий ключ.", + aclFiltered: "Некоторые ключи Consul KV скрыты политиками ACL.", + locked: "Этот ключ удерживается сеансом Consul и не может быть изменён или удалён.", + valueTooLarge: "Значения Consul KV не могут превышать 512 KiB.", + watchKey: "Наблюдение", + stopWatching: "Остановить", + workspace: { + overview: "Обзор", + kv: "KV", + services: "Службы", + health: "Работоспособность", + sessions: "Сеансы", + scope: "Область", + mesh: "Service Mesh", + tools: "Инструменты", + operator: "Оператор", + refresh: "Обновить возможности", + loading: "Загрузка возможностей Consul...", + agentIdentity: "Идентификатор Agent", + capabilities: "Возможности", + version: "Версия", + edition: "Редакция", + datacenter: "Дата-центр", + node: "Узел Agent", + mode: "Режим Agent", + agent: "Agent API", + acl: "ACL", + namespaces: "Пространства имён", + partitions: "Административные разделы", + enterprise: "Enterprise", + community: "Community", + serverMode: "Сервер", + clientMode: "Клиент", + capability: { + supported: "Поддерживается", + unsupported: "Не поддерживается", + forbidden: "Нет прав", + unknown: "Неизвестно", + }, + }, + }, + zookeeper: { + prefixPlaceholder: "Префикс пути, напр. /app/", + newKey: "Новый znode", + loadingKeys: "Загрузка znode...", + empty: "znode не найдены", + loadMore: "Загрузить ещё", + selectKey: "Выберите znode, чтобы просмотреть его значение", + loadingValue: "Загрузка значения...", + notFound: "znode не найден", + edit: "Изменить", + editKey: "Изменить znode", + delete: "Удалить", + deleteTitle: "Удалить znode ZooKeeper", + keyPlaceholder: "/path/to/znode", + keyRequired: "Путь znode обязателен", + rootReadonly: "Корневой znode нельзя изменять. Введите путь дочернего znode.", + saved: "znode сохранён", + deleted: "znode удалён", + base64Readonly: "Значения Base64 доступны только для чтения в этой версии.", + utf8PreviewLossy: "Недопустимые байты UTF-8 отображаются как символы замены (�). Исходное значение Base64 не изменяется.", + utf8PreviewUnavailable: "Значение Base64 недействительно, поэтому показано исходное значение.", + createMode: "Режим создания", + createModePersistent: "Постоянный", + createModeEphemeral: "Временный", + createModePersistentSequential: "Постоянный последовательный", + createModeEphemeralSequential: "Временный последовательный", + add: "Добавить", + value: "Значение", + metadata: "Информация об узле", + prettyJson: "Форматированный", + invalidJson: "Недействительный JSON", + summaryRevision: "ред", + summaryVersion: "вер", + summaryLease: "аренда", + summarySize: "размер", + }, + redis: { + monitorStop: "Остановить прослушивание", + monitorListening: "MONITOR прослушивает · последние 1 000 записей · длинные записи усечены", + setDatabaseAlias: "Задать псевдоним базы данных", + databaseAliasTitle: "Псевдоним для db{db}", + databaseAliasPlaceholder: "напр. orders, cache, development", + databaseAliasHint: "Псевдоним предназначен только для отображения и поиска. Команды Redis продолжают использовать числовой индекс базы данных.", + clearDatabaseAlias: "Очистить псевдоним", + databaseAliasSaved: "Псевдоним для db{db} установлен на {alias}", + databaseAliasCleared: "Псевдоним для db{db} очищен", + selectKey: "Выберите ключ, чтобы просмотреть его значение", + noKeys: "Ключи не найдены", + noKeysInScanHint: "Ключи не найдены в текущем диапазоне сканирования", + pattern: "шаблон (напр. user:*)", + fuzzyPattern: "ключ содержит...", + keyTemplateSuggestions: "Шаблоны ключей", + keySearchHistory: "История поиска", + keySearchHistoryForget: "Удалить из истории", + keySearchHistoryEmpty: "Истории пока нет", + fuzzyMatch: "Нечёткий", + fuzzyMatchTitle: "Нечёткое совпадение: поиск ключей по вхождению обычного текста", + valueSearchPlaceholder: "значение содержит...", + allSearchPlaceholder: "ключ или значение содержит...", + searchByKey: "Ключ", + searchByValue: "Значение", + searchByAll: "Все", + searchFields: "Поиск по полям и значениям", + searchMembers: "Поиск элементов множества", + searchItems: "Поиск элементов", + keys: "{count} ключей", + loadedKeys: "Загружено {loaded} / {total} ключей", + loadingKeys: "Загрузка ключей...", + searchingValues: "Поиск по значениям...", + searchingAll: "Поиск по ключам и значениям...", + loadMoreKeys: "Загрузить ещё ключи", + fetchAllKeys: "Загрузить все", + stopFetchAll: "Остановить", + fetchAllProgress: "Загружено {loaded} из {total} ключей", + fetchAllProgressUnknown: "Загружено {loaded} ключей", + items: "{count} элементов", + fields: "{count} полей", + members: "{count} элементов", + loadedItems: "Загружено {loaded} из {total} элементов", + loadedFields: "Загружено {loaded} из {total} полей", + loadedMembers: "Загружено {loaded} из {total} элементов", + entries: "{count} записей", + streamData: "Данные потока", + consumerGroups: "Группы потребителей", + group: "Группа", + consumers: "Потребители", + pending: "Ожидающие", + lastDeliveredId: "Последний доставленный ID", + lastDelivered: "Последняя доставка", + entriesRead: "Прочитано записей", + lag: "Отставание", + noConsumerGroups: "Нет групп потребителей", + streamGroupsLoadFailed: "Не удалось загрузить группы потребителей", + backToGroups: "Назад к группам", + streamConsumers: "Потребители", + streamConsumersLoadFailed: "Не удалось загрузить потребителей", + noStreamConsumers: "Нет потребителей", + openConsumerDetails: "Открыть сведения о потребителе", + consumer: "Потребитель", + idle: "Простой", + inactive: "Неактивен", + pendingEntries: "Ожидающие записи", + pendingEntriesLoadFailed: "Не удалось загрузить ожидающие записи", + noPendingEntries: "Нет ожидающих записей", + entryId: "ID записи", + deliveries: "Доставки", + loadMoreEntries: "Загрузить ещё записи", + loadMorePending: "Загрузить ещё ожидающие записи", + noExpiry: "без срока действия", + noExpiryOnly: "Только без срока действия", + noExpiryOnlyTitle: "Показывать только ключи без TTL в загруженных результатах", + noExpiryKeysEmpty: "В загруженных результатах нет ключей без срока действия", + ttlCountdownTitle: "Локальный отсчёт от TTL на момент загрузки", + expired: "истёк", + expiry: "Срок действия", + expiryNone: "Без срока действия", + expiryTtl: "TTL (секунды)", + expiryAt: "Время истечения (локальное)", + expiryTtlInvalid: "Введите положительное целое число TTL в секундах", + expiryDateRequired: "Выберите корректное время истечения", + expiryDatePast: "Время истечения должно быть в будущем", + keyExpiredBeforeDisplay: "Ключ истёк до того, как его можно было отобразить.", + autoRefresh: "Обратный отсчёт автообновления", + ttlDay: "{count}д", + ttlHour: "{count}ч", + ttlMinute: "{count}м", + ttlSecond: "{count}с", + columnType: "Тип", + columnKey: "Ключ", + columnValue: "Значение", + columnSize: "Размер", + columnTTL: "TTL", + binaryStringReadonlyHint: "Двоичные строковые значения отображаются как экранированный текст в режиме только для чтения; редактирование необработанных байтов не поддерживается.", + largeStringPreviewHint: "Это значение большое. Загружено только первые {loaded} из {total}, и предпросмотр доступен только для чтения.", + largeStringPreviewHintUnknown: "Это значение большое. Загружено только первые {loaded}, и предпросмотр доступен только для чтения.", + largeStringPreviewActionUnavailable: "Предпросмотр больших значений нельзя скопировать, декодировать или использовать для генерации INSERT-инструкций", + selectedKeys: "Выбранные ключи", + selectAllLoaded: "Выбрать все", + selectAllLoadedTitle: "Выбрать все ключи (Ctrl/Cmd+A)", + deselectAll: "Снять", + selectLoadedGroupKeys: "Выбрать {count} загруженных ключей в этой папке", + loadedMatchingKeys: "{count} загруженных совпадающих ключей", + loadedGroupKeysPartial: "Пока загружено {count} ключей — в этой папке может быть больше", + fuzzyTreeLimit: "{count} нечётких совпадений показаны плоским списком, чтобы браузер оставался отзывчивым. Уточните поиск, чтобы увидеть иерархию.", + deleteGroup: "Удалить группу", + deleteKey: "Удалить ключ", + deleteGroupDetails: "{target}\n{count} ключей", + deleteLoadedSearchKeysDetails: "{target}\n{count} загруженных совпадающих ключей", + batchExpiry: "Задать срок действия", + batchExpiryTitle: "Пакетное истечение", + batchExpirySelected: "Выбрано {count} ключей", + batchExpiryApply: "Применить", + batchExpirySuccess: "Срок действия применён к {count} ключам", + batchExpiryPartial: "{success} применено, {failed} не применено", + flushDb: "Очистить текущую БД", + flushDbMessage: "Это удалит все ключи в текущей базе данных Redis, и отменить это будет невозможно. Продолжить?", + flushDbDetails: "Цель: Redis db{db}\nОбласть: все ключи в текущей БД", + flushDbConfirm: "Очистить БД", + flushDbSuccess: "Redis db{db} очищена", + keyDetail: "Сведения о ключе", + commandLine: "Командная строка", + selectKeyForDetail: "Выберите ключ для просмотра сведений", + commandWelcome: "Добро пожаловать в консоль команд Redis", + commandPlaceholder: "Команда Redis, например GET user:1", + commandPrefix: "CMD", + commandHint: "Введите команду Redis, например SMEMBERS feature:flags", + executeCommand: "Выполнить команду", + commandEmpty: "Введите команду Redis", + commandEmptyResult: "Выполните команду Redis, чтобы увидеть результат", + commandBlocked: "Эта команда Redis заблокирована в целях безопасности", + createKey: "Создать ключ", + createKeyName: "Ключ", + createKeyNamePlaceholder: "user:1", + createKeyType: "Тип", + createKeyTypeHelp: { + string: "Единое бинарно-безопасное значение размером до 512 МБ. Лучше всего подходит для кэшированных значений, счётчиков, флагов и простых сериализованных данных.", + hash: "Плоская карта поле-значение. Эффективна для отдельных полей, но полное чтение большого хэша — O(N).", + list: "Упорядоченная последовательность. Операции с началом и концом эффективны; произвольный доступ в середине линеен по длине списка.", + set: "Неупорядоченный набор уникальных элементов. Операции с одним элементом — O(1), а перечисление или объединение больших наборов линейно.", + zset: "Уникальные элементы, упорядоченные по вещественным оценкам. Записи — O(log N); элементы с одинаковыми оценками упорядочены лексикографически.", + stream: "Журнал событий только для добавления. Группам потребителей нужны XACK и обработка ожидающих записей; обрезайте поток для контроля хранения и памяти.", + json: "JSON-документ с адресацией по пути. Требует поддержки RedisJSON/Redis Stack JSON.* и обычно создаёт больше накладных расходов, чем String или Hash.", + }, + createValue: "Значение", + createMember: "Элемент", + createField: "Поле", + createFieldPlaceholder: "name", + createScore: "Оценка", + createKeyTtl: "TTL (секунды)", + createKeyTtlPlaceholder: "положительное целое число секунд", + createKeyAddEntry: "Добавить запись", + createKeyEntryId: "ID записи", + createKeyRawMode: "Необработанный ввод", + createKeyEntries: "Записи", + createKeyPartialWrite: "Часть записей была записана. Исправьте ошибку и создайте снова, чтобы записать оставшиеся записи.", + createValuePlaceholder: "значение", + createKeySubmit: "Создать", + createKeyNameRequired: "Введите имя ключа", + renameKey: "Переименовать ключ", + renameKeyName: "Имя ключа", + renameKeyNameRequired: "Введите имя ключа", + renameKeySuccess: "«{oldName}» переименован в «{newName}»", + createFieldRequired: "Введите поле хэша", + createScoreInvalid: "Введите корректную оценку", + jsonModuleNotAvailable: "Модуль ReJSON не загружен на этом сервере Redis", + field: "Поле", + fieldRequired: "Введите имя поля", + valueRequired: "Введите значение", + memberRequired: "Введите элемент", + updateAppliedRefreshFailed: "Изменение сохранено, но значение не удалось обновить: {message}", + zsetAclCompatibilityWarning: "Изменение сохранено в режиме совместимости ACL; параллельные изменения оценок не удалось проверить.", + ttlInvalid: "Введите корректный TTL в секундах (-1 — без срока действия)", + member: "Элемент", + valuePlaceholder: "значение", + memberPlaceholder: "элемент", + fieldPlaceholder: "поле", + scorePlaceholder: "оценка", + pushAction: "Вставить", + addAction: "Добавить", + setAction: "Задать", + memberDetail: "Сведения об элементе", + viewMember: "Показать полное значение", + copyMember: "Копировать элемент", + copyField: "Копировать поле", + copyFieldValue: "Копировать поле + значение", + copyOptions: "Параметры копирования", + copyKeyName: "Копировать имя ключа", + copyKeyPath: "Копировать путь ключа", + deleteGroupKeys: "Удалить загруженные ключи", + copied: "Скопировано", + copyInsertStatement: "Копировать INSERT-инструкцию", + copyInsertStatementBinary: "Невозможно сгенерировать INSERT-инструкцию для двоичных данных", + editMember: "Изменить", + jsonView: "Просмотр JSON", + jsonViewRaw: "Необработанный", + jsonViewDecoded: "Декодированный", + rawContent: "Необработанное содержимое", + wordWrap: "Перенос по словам", + codecNone: "Нет", + codecRowLabel: "Декодировать", + viewRowLabel: "Просмотр", + codecBase64: "Base64", + unicodeJsonView: "Unicode JSON", + codecMismatch: "Не удалось декодировать выбранным кодеком; показано исходное содержимое", + decompressedView: "Распаковано", + decompressedLoading: "Распаковка…", + decompressedFailed: "Не удалось распаковать выбранным форматом", + decompressedRetryAsDeflate: "Повторить как DEFLATE", + decompressedLimitExceeded: "Распакованный результат превышает лимит 50 MiB", + gzipBadgeTitle: "Сжато Gzip — нажмите, чтобы посмотреть распакованное содержимое", + formatJson: "Форматировать", + compressJson: "Сжать", + jsonFormatError: "Недопустимый формат JSON", + clearHistory: "Очистить историю команд", + historyCleared: "История команд Redis очищена", + blockedCommand: "Команда {command} заблокирована в целях безопасности. Отключите значок щита на панели инструментов, чтобы разрешить.", + pubsub: "Pub/Sub", + pubsubConnected: "Подключено", + pubsubConnecting: "Подключение...", + pubsubDisconnected: "Отключено", + pubsubConnect: "Подключить", + pubsubDisconnect: "Отключить", + pubsubChannels: "Каналы", + pubsubChannelPlaceholder: "Имя канала", + pubsubSubscribe: "Подписаться", + pubsubPatterns: "Шаблоны", + pubsubPatternPlaceholder: "Шаблон (например news:*)", + pubsubPsubscribe: "PSubscribe", + pubsubMessages: "Сообщения", + pubsubClear: "Очистить", + pubsubEmpty: "Сообщений пока нет. Подпишитесь на канал, чтобы получать сообщения.", + pubsubPublish: "Опубликовать", + pubsubPublishChannel: "Канал", + pubsubPublishMessage: "Сообщение", + pubsubSend: "Отправить", + pubsubPublishFailed: "Не удалось опубликовать: {error}", + pubsubWsConnectFailed: "Не удалось подключиться по WebSocket: {error}", + slowlog: "Медленный журнал", + slowlogCount: "Количество", + slowlogQuery: "Запрос", + slowlogNode: "Узел", + slowlogSelectNode: "Выберите узел", + slowlogNodeRequired: "Сначала выберите узел", + slowlogEmpty: "Нажмите «Запрос», чтобы получить записи медленного журнала", + slowlogFetchFailed: "Не удалось получить медленный журнал: {error}", + slowlogColumnId: "ID", + slowlogColumnTimestamp: "Временная метка", + slowlogColumnDuration: "Длительность (мкс)", + slowlogColumnCommand: "Команда", + slowlogColumnClientAddr: "Клиент", + slowlogColumnClientName: "Имя клиента", + slowlogTotal: "{count} записей", + slowlogDetailTitle: "Запись медленного журнала #{id}", + dashboard: { + totalMemory: "Всего памяти", + usedMemory: "Использовано памяти", + operations: "Операции", + hitRatio: "Коэффициент попаданий", + keyCount: "Количество ключей", + clients: "Клиенты", + searchIndicators: "Поиск индикаторов...", + node: "Узел", + off: "Выкл", + refresh: "Обновить", + noMatchingIndicators: "Нет подходящих индикаторов", + noDataAvailable: "Данные недоступны", + sections: { + server: "Сервер", + clients: "Клиенты", + memory: "Память", + persistence: "Персистентность", + stats: "Статистика", + replication: "Репликация", + cpu: "CPU", + modules: "Модули", + commandstats: "Статистика команд", + errorstats: "Статистика ошибок", + latencystats: "Статистика задержек", + cluster: "Кластер", + keyspace: "Пространство ключей", + }, + }, + }, + mongoDump: { + selectAll: "Выбрать все коллекции", + menuDump: "Дамп базы данных...", + menuRestore: "Восстановить базу данных...", + dumpTitle: "Дамп базы данных MongoDB", + restoreTitle: "Восстановление базы данных MongoDB", + format: "Формат", + archive: "Архив MongoDB", + directory: "Каталог дампа MongoDB", + gzip: "Gzip", + source: "Источник резервной копии", + readSource: "Прочитать резервную копию", + sourceDatabase: "Исходная база данных", + targetDatabase: "Целевая база данных", + destination: "Назначение", + chooseDestination: "Выбрать назначение", + collection: "Коллекция", + kind: "Тип", + documents: "Документы", + indexes: "Индексы", + dropExisting: "Удалять выбранные целевые коллекции перед восстановлением", + restoreOptions: "Восстанавливать параметры коллекций", + restoreIndexes: "Восстанавливать индексы", + stopOnError: "Останавливаться при ошибках записи", + objcheck: "Проверять документы BSON перед вставкой (objcheck)", + readBytes: "Прочитано: {size} GiB после распаковки", + batchSize: "Размер пакета", + selected: "Выбрано коллекций: {count}", + empty: "Нет коллекций", + preparing: "Чтение резервной копии...", + loading: "Загрузка коллекций...", + dump: "Начать дамп", + restore: "Начать восстановление", + review: "Проверка", + back: "Назад", + close: "Закрыть", + cancel: "Отменить задачу", + confirmDump: "Создать дамп {count} коллекций из {database}.", + confirmRestore: "Восстановить {count} коллекций в {database}.", + confirmDrop: "Выбранные целевые коллекции будут удалены и созданы заново.", + confirmAppend: "Документы будут добавлены к существующим коллекциям.", + readonly: "Это подключение доступно только для чтения.", + done: "Завершено", + cancelled: "Отменено", + failed: "Ошибка", + progress: "Коллекции: {done} / {total}", + read: "Прочитано документов", + written: "Восстановлено документов", + rejected: "Документов с ошибками", + createdIndexes: "Восстановлено индексов", + uploadBytes: "Загружено: {done} / {total} GiB", + validationBytes: "Проверено: {size} GiB после распаковки, документов: {count}", + phase: { + preparing: "Подготовка", + uploading: "Загрузка выбранных файлов", + validating: "Проверка резервной копии", + data: "Данные коллекций", + indexes: "Восстановление индексов", + views: "Восстановление представлений", + archive: "Запись резервной копии", + done: "Завершено", + }, + }, + mongo: { + documents: "Документов: {count}", + addField: "Добавить поле", + deleteField: "Удалить поле", + field: "Поле", + value: "Значение", + fieldPlaceholder: "Имя поля", + emptyCollection: "Пустая коллекция", + selectDocument: "Выберите документ", + readonlyId: "_id доступен только для чтения", + invalidJsonValue: "Эта ячейка не является допустимым значением JSON", + invalidJson: "Недопустимый JSON", + documentMustBeObject: "JSON документа должен быть объектом", + unsupportedJsonNumber: "JSON содержит число вне диапазона int64 MongoDB", + duplicateJsonKey: "Дублирующийся ключ JSON: {field}", + duplicateField: "Дублирующееся имя поля: {field}", + indexExpireAfterSeconds: "Истекает через (секунды)", + indexExpireAfterSecondsPlaceholder: "Никогда", + indexExpireAfterSecondsHint: "Только для односоставных индексов. MongoDB удаляет документы, когда проиндексированная дата старше этого возраста.", + indexPartialFilter: "Частичный фильтр", + indexLegacyOptions: "Параметры совместимости", + indexLegacyOptionsHint: "Полезно только на старых серверах: background игнорируется с MongoDB 4.2, а размер корзины перестал применяться после удаления индексов geoHaystack в 4.4.", + indexBackground: "Фоновый", + indexBucketSize: "Размер корзины", + indexSparse: "Разреженный", + indexHidden: "Скрытый", + indexNoExpiry: "Никогда", + indexOtherOptions: "Другие параметры", + indexPropertiesUnavailable: "Драйвер MongoDB Legacy не может сообщить sparse, срок действия, background или размер корзины. Подключитесь с помощью нативного драйвера, чтобы увидеть их.", + edit: "Изменить", + editModeFields: "Поля", + editModeJson: "JSON", + jsonReplaceHint: "Сохранение JSON заменяет весь документ. Изменение _id создаёт новый документ и удаляет старый.", + jsonIdRequired: "При изменении идентичности документа требуется корректный _id.", + documentView: "Просмотр документа", + tableView: "Табличный просмотр", + filterPlaceholder: "Фильтр...", + sortPlaceholder: "Сортировка...", + import: { + title: "Импорт данных", + target: "Целевая коллекция", + readonly: "Это подключение доступно только для чтения. Разблокируйте запись перед импортом.", + chooseFile: "Выбрать файл", + fileFilter: "Данные MongoDB", + noFile: "Файл не выбран", + back: "Назад", + format: "Формат", + encoding: "Кодировка", + delimiter: "Разделитель", + typeMode: "Режим типов", + typeString: "Все строки", + typeAuto: "Автоопределение", + typeExtendedJson: "Extended JSON", + columnType: "Тип для {name}", + inferredType: { + string: "Строка", + boolean: "Логический", + integer: "Целое", + decimal: "Десятичное", + date: "Дата", + objectId: "ObjectId", + object: "Объект", + array: "Массив", + mixed: "Смешанный", + }, + hasHeader: "Первая строка — заголовок", + trim: "Обрезать пробелы в значениях", + emptyAsNull: "Пустые ячейки как null", + recognizeObjectIdHex: "Считать 24-символьный hex значением ObjectId", + skipErrorRows: "Пропускать строки с ошибками", + previewing: "Обновление предпросмотра…", + estimatedRows: "Оценка: {count} документов", + continue: "Продолжить", + confirmAppend: "Документы будут добавлены. Существующие документы не усекаются и не обновляются через upsert.", + batchSize: "Размер пакета", + duplicateIdPolicy: "Дублирующиеся значения _id останавливают импорт. Уже зафиксированные пакеты не откатываются.", + start: "Импортировать", + success: "Импортировано документов: {count}", + stillRunning: "Импорт всё ещё выполняется. Используйте «Отмена», чтобы остановить новые пакеты.", + legacyInsertUnsupported: "Драйвер MongoDB Legacy не может вставлять документы массово. Обновите или переустановите драйвер MongoDB Legacy.", + legacyCursorInvalid: "Курсор экспорта MongoDB Legacy больше недоступен. Повторите экспорт.", + legacyExportUnsupported: "Драйвер MongoDB Legacy не может сохранять типы BSON при экспорте. Обновите или переустановите драйвер MongoDB Legacy.", + legacyExportStalled: "Драйвер MongoDB Legacy дважды вернул одну и ту же страницу экспорта. Обновите или переустановите драйвер MongoDB Legacy и повторите экспорт.", + legacyExportMissingId: "Драйвер MongoDB Legacy вернул документ без _id, поэтому постраничный экспорт невозможен.", + rowsRead: "Прочитано строк", + rowsInserted: "Вставлено строк", + rowsFailed: "Строк с ошибками", + batchesCommitted: "Зафиксировано пакетов", + phase: { + preparing: "Подготовка", + parsing: "Разбор", + writing: "Запись", + done: "Готово", + }, + }, + insert: { + partialFailure: "Драйвер MongoDB Legacy отклонил {failed} из {total} документов: {message}", + }, + }, + meilisearch: { + ...meilisearchManagementRu, + documents: "Документы", + settings: "Настройки", + search: "Поиск", + keywordPlaceholder: "Поиск документов...", + filter: "Фильтр", + filterPlaceholder: 'status = "published"', + sort: "Сортировка", + sortPlaceholder: "field:asc", + sortHint: "Разделяйте несколько выражений сортировки запятыми (,)", + sortNoAttributes: "Для этого индекса не настроены атрибуты, доступные для сортировки", + sortAsc: "По возрастанию", + sortDesc: "По убыванию", + limit: "Лимит", + offset: "Смещение", + resultSummary: "Около {count} результатов · {time} мс", + viewJson: "JSON", + viewTable: "Таблица", + viewGrid: "Сетка", + empty: "Документы не найдены", + editDocument: "Изменить документ", + deleteDocument: "Удалить документ", + deleteDocumentMessage: "Удалить этот документ? Это действие нельзя отменить.", + documentDeleted: "Документ удалён", + documentSaved: "Документ сохранён", + settingsSaved: "Настройки сохранены", + invalidJson: "Недопустимый JSON", + settingsJson: "JSON настроек", + dangerZone: "Опасная зона", + clearDocuments: "Очистить все документы", + clearDocumentsConfirmMessage: "Это удалит все документы из индекса. Это действие нельзя отменить.", + documentsCleared: "Все документы очищены", + deleteIndex: "Удалить индекс", + deleteIndexConfirmMessage: "Это навсегда удалит индекс и все его документы.", + indexDeleted: "Индекс удалён", + isIndexing: "Индексация", + uid: "UID", + updatedAt: "Обновлено", + primaryKey: "Первичный ключ", + documentCountLabel: "Документы", + databaseSize: "Размер базы данных", + documentSize: "Размер документа", + avgDocumentSize: "Средний размер документа", + instanceDatabaseSize: "Размер базы данных экземпляра", + copyDocument: "Копировать JSON", + copied: "Скопировано", + autoRefresh: "Автообновление", + hybrid: "Гибридный поиск", + hybridEmbedder: "Эмбеддер", + hybridSemanticRatio: "Семантическая доля", + hybridNoEmbedders: "В настройках индекса не настроены эмбеддеры; укажите один вручную.", + showRankingScore: "Оценка ранжирования", + rankingScoreThreshold: "Порог оценки", + results: "Результаты", + exportResults: "Экспорт результатов", + exportFiltered: "Экспортировать отфильтрованные результаты", + exportAll: "Экспортировать все документы", + exportLimitReached: "Доступно только {count} из {total} результатов; ограничение Meilisearch не позволяет выполнить полный экспорт.", + importResults: "Импортировать JSON", + importSuccess: "Импортировано документов: {count}", + importFailed: "Не удалось выполнить импорт: {message}", + importInvalidJson: "JSON должен содержать объект или массив объектов", + exportSearchUnsupported: "Полный экспорт недоступен для текстового, гибридного поиска или поиска с порогом оценки, поскольку Meilisearch ограничивает постраничный поиск. Снимите эти параметры, чтобы экспортировать все отфильтрованные документы.", + }, + dynamodb: { + tableMetadataUnavailable: "Метаданные таблицы DynamoDB не загружены. Обновите и повторите попытку.", + keyRequired: "Элементам DynamoDB требуется атрибут ключа {key}", + baseTable: "Базовая таблица", + filter: "фильтр", + sortKey: "ключ сортировки", + items: "{count} элементов", + index: "Индекс DynamoDB", + keySummary: "Ключ раздела: {partitionKey}; ключ сортировки: {sortKey}", + none: "нет", + sortKeyOnly: "Запрос DynamoDB может сортировать только по ключу сортировки текущего индекса: {key}", + pageCursorUnavailable: "Курсор страницы DynamoDB недоступен. Перезагрузите с первой страницы.", + repeatedCursor: "DynamoDB вернул повторяющийся курсор страницы. Экспорт остановлен.", + partialProjectionReadOnly: "Этот индекс {projection} не содержит элемент целиком. Редактирование отключено, чтобы непроецируемые атрибуты не были перезаписаны.", + exportLimitReached: "Экспорт DynamoDB остановлен на {count} элементах для ограничения памяти и использования чтения. Задайте лимит строк экспорта, чтобы выбрать другую границу.", + documentDetails: "Таблица DynamoDB: {table}\nКлюч элемента: {id}", + }, + vector: { + collectionFallback: "коллекция", + productCollection: "коллекция {product}", + browse: "Обзор", + search: "Поиск", + upsert: "Upsert", + delete: "Удалить", + reset: "Сбросить", + refresh: "Обновить", + run: "Запустить", + apply: "Применить", + requestEditor: "Редактор векторных запросов", + operationSuccess: "Операция завершена. Предпросмотр коллекции обновлён.", + vectorLabel: "Вектор", + vectorDimensionRequired: "Размерность коллекции пока недоступна. Введите вектор, соответствующий размерности коллекции.", + }, + hbase: { + prefix: "Префикс", + exact: "Точное совпадение", + rowKeyPrefix: "Префикс row key", + rowKey: "Ключ строки", + rows: "строк", + schema: "Схема", + writeRow: "Записать строку", + loadedRows: "Загружено строк: {count}", + resultTruncated: "Доступны дополнительные строки", + tableSchema: "Схема: {table}", + rowSaved: "Строка HBase сохранена", + cellsObjectRequired: "cells должен быть объектом JSON", + cellRequired: "Требуется хотя бы одна ячейка", + noColumnFamilies: "В этой таблице HBase нет семейств столбцов", + invalidJsonValue: "Недопустимое значение для {label}; используйте текст, примитив или base64:...", + createTable: "Создать таблицу", + create: "Создать", + tableCreated: "Таблица HBase {table} создана", + tableDeleted: "Таблица HBase {table} удалена", + createTableIn: "Создать таблицу в {namespace}", + tableName: "Имя таблицы", + columnFamiliesPlaceholder: "Семейства столбцов через запятую", + deleteTable: "Удалить таблицу", + deleteTableConfirm: "Удалить таблицу HBase {table}? Все строки будут удалены безвозвратно.", + }, + history: { + pendingRollback: "Откат SQL ожидает выполнения. Зафиксируйте изменения, чтобы применить его, или отмените их.", + discardRollback: "Отменить изменения отката", + manualRollbackHint: "Откат SQL ожидает фиксации. DDL всё равно может зафиксироваться неявно.", + transactionEnded: "Транзакция завершена или была откатана. Успешный откат не зафиксирован.", + rollbackBeforeClose: "Отменить незафиксированные изменения отката и закрыть историю?", + title: "История", + search: "Поиск по истории...", + conversationSearch: "Поиск по диалогам...", + empty: "История пока пуста", + emptyConversationSearch: "Нет диалогов, соответствующих запросу", + emptyFilteredRecent: "Нет совпадений среди последних 200 записей истории выполнения", + failed: "Ошибка", + success: "Успешно", + restore: "Восстановить в редакторе", + copy: "Копировать SQL", + delete: "Удалить", + clear: "Очистить историю", + viewDetails: "Просмотреть детали", + analyzeWithAi: "Анализировать с помощью AI", + aiAnalyzeNoConnection: "Невозможно проанализировать эту запись истории: её подключение больше не существует.", + aiAnalysisTab: "Анализ истории", + rollback: "Откатить", + rollbackSql: "SQL отката", + rollbackAvailable: "Доступно", + rollbackUnavailable: "Нет SQL отката", + rollbackConfirm: "Выполнить SQL отката, сформированный для этой записи истории?", + rollbackSuccess: "Откат выполнен", + rollbackFailed: "Откат не выполнен: {message}", + confirmDelete: "Удалить эту запись истории?", + confirmClear: "Очистить всю историю?", + emptyFiltered: "Нет записей истории, соответствующих текущим фильтрам", + loadMore: "Загрузить ещё", + scope: { + title: "Подключение и база данных", + search: "Поиск подключений или баз данных...", + reset: "Сбросить", + allConnections: "Все подключения", + current: "Текущее", + connections: "Подключения", + databases: "Базы данных", + connectionCount: "Подключений: {count}", + databaseCount: "Баз данных: {count}", + unknownConnection: "Неизвестное подключение", + noOptions: "Нет подходящих вариантов", + }, + filters: { + all: "Все", + query: "Запросы", + data_change: "Изменения данных", + schema_change: "Изменения схемы", + failed: "С ошибкой", + }, + dateRange: { + title: "Диапазон времени", + label: "Время выполнения:", + start: "Начальная дата", + end: "Конечная дата", + apply: "Применить", + clear: "Очистить", + invalid: "Начальная дата не может быть позже конечной", + unboundedStart: "Начало", + unboundedEnd: "Конец", + }, + kinds: { + query: "Запрос", + data_change: "Изменение данных", + schema_change: "Изменение схемы", + import: "Импорт", + transfer: "Перенос", + redis_command: "Команда Redis", + }, + kindShort: { + query: "SQL", + data_change: "Данные", + schema_change: "DDL", + import: "Импорт", + transfer: "Перенос", + redis_command: "Redis", + }, + detail: { + kind: "Тип", + operation: "Операция", + connection: "Подключение", + database: "База данных", + target: "Цель", + time: "Время", + duration: "Длительность", + affectedRows: "Затронуто строк", + rollback: "Откат", + status: "Статус", + error: "Ошибка", + }, + }, + dangerDialog: { + title: "Опасная операция", + message: "Этот оператор SQL может необратимо изменить или удалить данные. Вы уверены, что хотите его выполнить?", + redisCommandMessage: "Эта команда Redis может изменить данные и не может быть отменена автоматически. Продолжить?", + suppressFuturePrompts: "Больше не спрашивать об опасном SQL", + wrapLines: "Переключить перенос строк", + copyFullText: "Копировать весь текст", + previewTruncated: "Предпросмотр обрезан: пропущено символов — {characters}, строк — {lines}. При копировании текст будет полным.", + deleteMessage: "Эта операция удаления может быть необратимой. Продолжить?", + deleteConfirm: "Подтвердить удаление", + deleteRowMessage: "Эта строка будет помечена на удаление и удалена из базы данных после сохранения. Продолжить?", + deleteRowsMessage: "Эти строки ({count}) будут помечены на удаление и удалены из базы данных после сохранения. Продолжить?", + deleteRowDetails: "Таблица: {table}", + deleteRowDetailsNoTable: "Текущая строка результата", + redisKeyDetails: "Ключ Redis: {key}", + redisHashFieldDetails: "Хеш Redis: {key}\nПоле: {field}", + redisListItemDetails: "Список Redis: {key}\nИндекс: {index}", + redisSetMemberDetails: "Множество Redis: {key}\nЭлемент: {member}", + mongoDocumentDetails: "Коллекция MongoDB: {collection}\nДокумент _id: {id}", + mongoFieldDetails: "Поле: {field}", + mongoArrayItemDetails: "Индекс элемента массива: {index}", + cancel: "Отмена", + cancelRunning: "Отменить запрос", + confirm: "Выполнить", + }, + production: { + title: "Продуктивная среда", + connection: "Продуктивное подключение", + enable: "Включить защиту продуктивной среды", + disabledDescription: "Включите это, чтобы защитить все базы данных или выбранные базы данных.", + namespaceDisabledDescription: "Включите это, чтобы защитить все пространства имён или выбранные пространства имён.", + scope: "Область защиты", + allDatabases: "Все базы данных", + selectedDatabases: "Выбранные базы данных", + allNamespaces: "Все пространства имён", + selectedNamespaces: "Выбранные пространства имён", + singleDatabaseScopeHint: "Этот тип базы данных поддерживает защиту продуктивной среды только на уровне подключения.", + databases: "Продуктивные базы данных", + namespaces: "Продуктивные пространства имён", + connectionDescription: "Все базы данных этого подключения используют защиту продуктивной среды.", + namespaceConnectionDescription: "Все пространства имён этого подключения используют защиту продуктивной среды.", + databaseDescription: "Выберите базы данных, которым нужна защита продуктивной среды. Первый вариант включает все базы данных.", + namespaceDescription: "Выберите пространства имён, которым нужна защита продуктивной среды. Первый вариант включает все пространства имён.", + selectDatabases: "Выбрать продуктивные базы данных", + selectNamespaces: "Выбрать продуктивные пространства имён", + noDatabasesSelected: "Базы данных не выбраны", + databasesConfiguredCount: "Выбрано: {count}", + databasesSelectedCount: "Выбрано: {selected}/{total}", + databasePickerTitle: "Выбор продуктивных баз данных", + databasePickerDescription: 'Выберите базы данных в "{connection}", которым нужна защита продуктивной среды.', + databaseSearchPlaceholder: "Поиск баз данных...", + databaseSelectionRequired: "Выберите хотя бы одну базу данных.", + databaseLoadFailed: "Не удалось загрузить базы данных: {message}", + noDatabasesAvailable: "Нет баз данных для выбора.", + namespacePickerTitle: "Выбор продуктивных пространств имён", + namespacePickerDescription: 'Выберите пространства имён в "{connection}", которым нужна защита продуктивной среды.', + namespaceSearchPlaceholder: "Поиск пространств имён...", + namespaceSelectionRequired: "Выберите хотя бы одно пространство имён.", + namespaceLoadFailed: "Не удалось загрузить пространства имён: {message}", + noNamespacesAvailable: "Нет пространств имён для выбора.", + retry: "Повторить", + confirmTitle: "Подтвердите запись в продуктивную среду", + confirmMessage: "Эта операция изменяет продуктивную базу данных и требует явного подтверждения.", + confirmDetails: "Подключение: {connection}\nБаза данных: {database}\nИсточник: {source}", + confirmAction: "Выполнить в продуктивной среде", + sourceSqlEditor: "Редактор SQL", + sourceMultiDbSql: "Выполнение SQL в нескольких базах данных", + sourceDataGrid: "Редактор данных", + sourceStructure: "Редактор структуры", + sourceSqlFile: "Выполнение файла SQL", + sourceObjectBrowser: "Обозреватель объектов", + sourceSchemaDiff: "Сравнение схем", + sourceDataCompare: "Сравнение данных", + sourceExtension: "Менеджер расширений", + sourceSidebar: "Дерево объектов", + sourceMq: "Очередь сообщений", + sourceObjectSource: "Редактор исходного кода объекта", + sourceDataGenerate: "Генератор данных", + sourceQueryHistory: "Откат из истории запросов", + sourceAdmin: "Администрирование базы данных", + aiReviewRequired: "SQL для продуктивной среды добавлен в редактор. Проверьте его и запустите вручную для подтверждения.", + }, + readOnlyUnlock: { + confirmTitle: "Разблокировать запись", + confirmMessage: "Это подключение доступно только для чтения. Запись остаётся заблокированной, пока вы не разблокируете её на короткое время. Сохранённая настройка «только чтение» не будет отключена.", + confirmDetails: "Подключение: {connection}\nИсточник: {source}\nЗапись будет разрешена на выбранный период, затем режим «только чтение» возобновится автоматически.", + confirmAction: "Разблокировать запись", + durationLabel: "Разрешить запись на", + durationOneMinute: "1 минуту", + durationFiveMinutes: "5 минут", + remaining: "Осталось {time}", + unlockedBadge: "Запись разблокирована", + lockNow: "Заблокировать запись сейчас", + unlockAction: "Разблокировать запись…", + sourceImport: "Импорт таблицы", + sourceMongoImport: "Импорт MongoDB", + sourceTransfer: "Перенос данных", + sourceSqlFile: "Выполнение файла SQL", + sourceStatus: "Управление режимом «только чтение»", + sourceDataEditor: "Редактор данных", + }, + sqlParameters: { + title: "Параметры SQL", + description: "Заполните значения для заполнителей шаблона SQL. DBX подставит их перед выполнением SQL.", + name: "Параметр", + syntax: "Синтаксис", + type: "Тип", + value: "Значение", + valuePlaceholder: "Введите значение", + collectionValuePlaceholder: "Введите массив JSON или значения через запятую", + preview: "Предпросмотр SQL", + execute: "Выполнить", + clearValues: "Очистить значения", + useRawForAll: "Использовать Raw SQL для всех", + ignore: "Игнорировать", + kind: { + string: "Строка", + number: "Число", + boolean: "Логическое", + null: "NULL", + raw: "Необработанный SQL", + }, + }, + transfer: { + title: "Перенос данных", + content: "Содержимое переноса", + contentStructureAndData: "Структура и данные", + contentStructureOnly: "Только структура", + contentDataOnly: "Только данные", + contentStructureOnlyHint: "Создавать только таблицы и структуры объектов, без данных", + contentDataOnlyHint: "Копировать только данные в существующие целевые таблицы", + objects: "Объекты", + searchObjects: "Поиск имён объектов...", + noObjects: "Нет объектов", + bulkSelectObjects: "Массовый ввод", + bulkSelectTitle: "Массовый выбор объектов", + bulkSelectHint: "Вставьте имена объектов (по одному в строке или через запятую, точку с запятой либо табуляцию), чтобы автоматически выбрать совпадающие элементы: регистр и кавычки игнорируются, поддерживаются префиксы schema.table.", + bulkSelectPlaceholder: "например, orders, users, public.payments", + bulkSelectConfirm: "Выбрать совпадения", + bulkSelectMatched: "Выбрано совпадающих объектов: {count}", + bulkSelectUnmatched: "Не найдено совпадений для имён: {count}: {names}", + noMatchingObjects: "Нет совпадений", + objectTypeTable: "Таблицы", + objectTypeView: "Представления", + objectTypeMaterializedView: "Материализованные представления", + objectTypeProcedure: "Процедуры", + objectTypeFunction: "Функции", + objectTypeTrigger: "Триггеры", + objectTypeSequence: "Последовательности", + objectTypeEvent: "События", + objectDataOnlyDisabled: "Объекты, не являющиеся таблицами, не переносятся в режиме «только данные»", + objectCrossFamilyDisabled: "Межбазовый перенос поддерживает только последовательности (обычный DDL; тела запросов представлений не могут быть преобразованы)", + crossFamilyViewHint: "Межбазовый перенос представлений: выберите также таблицы, от которых зависит представление, или убедитесь, что они уже существуют в целевой базе данных", + objectUnsupportedDisabled: "Эта база данных не поддерживает перенос объектов этого типа", + skippedExistingObjects: "Пропущено существующих объектов: {count}", + targetTableHandling: "Обработка целевых таблиц", + source: "Источник", + target: "Цель", + sourceConnection: "Исходное подключение", + sourceCatalog: "Исходный каталог", + targetCatalog: "Целевой каталог", + selectCatalog: "Выбрать каталог...", + searchCatalog: "Поиск каталога...", + sourceDatabase: "Исходная база данных", + sourceSchema: "Исходная схема", + swap: "Поменять источник и цель", + targetConnection: "Целевое подключение", + targetDatabase: "Целевая база данных", + targetSchema: "Целевая схема", + tables: "Таблицы", + selectAll: "Выбрать все", + deselectAll: "Снять выделение", + createTable: "Создать таблицу, если не существует", + transferMode: "Режим переноса", + modeAppend: "Добавить (INSERT)", + modeOverwrite: "Перезаписать (TRUNCATE + INSERT)", + modeUpsert: "Upsert (INSERT или UPDATE по PK)", + targetTableNameCase: "Регистр имён целевых таблиц", + quoteTargetColumnNames: "Заключать имена целевых столбцов в кавычки", + tableNameCasePreserve: "Сохранять", + tableNameCaseLower: "Нижний регистр", + tableNameCaseUpper: "Верхний регистр", + batchSize: "Размер пакета", + modeRebuild: "Перестроить структуру и данные (RENAME + CREATE + INSERT)", + modeKeepExisting: "Оставить существующие таблицы", + modeRebuildStructure: "Перестроить структуру (RENAME + CREATE)", + rebuildSummary: "Перестроить таблиц: {count}. Существующие целевые таблицы сначала переименовываются в резервные копии, затем пересоздаются по структуре источника и заполняются; резервные копии удаляются после успешного завершения всех шагов.", + rebuildDanger: "Перестроение заменяет выбранные целевые таблицы, их существующие строки и метаданные, относящиеся только к цели. Проверьте фактические цели, имена резервных копий и SQL. После удаления резервные копии нельзя использовать для восстановления.", + rebuildDataOnlyDisabled: "Перестроение недоступно для переноса только данных. Выберите «структура и данные» или «только структура».", + rebuildUnsupportedDisabled: "Выбранный целевой движок не поддерживает перестроение целевых таблиц.", + rebuildPreviewUnavailable: "Серверная часть не предоставила план перестроения. Перенос не начат; обновите предпросмотр на серверной части с поддержкой перестроения.", + rebuildMissingTargets: "Некоторые целевые таблицы ещё не существуют и будут созданы без резервной копии.", + previewFailed: "Не удалось подготовить перенос: {message}", + start: "Начать перенос", + startConfirmTitle: "Подтвердите перенос", + startConfirmMessage: "Перенести выбранных объектов: {count} из {source} в {target}. Начать сейчас?", + cancel: "Отмена", + progress: "Перенос...", + transferring: "Перенос {table}...", + completed: "Перенос завершён", + completedWithErrors: "Завершено с {count} таблицей с ошибкой | Завершено с таблицами с ошибкой: {count}", + failed: "Перенос не выполнен", + cancelled: "Перенос отменён", + rowsTransferred: "Перенесено строк: {count}", + tableProgress: "Таблиц: {current} / {total}", + noSqlConnections: "Нет доступных подключений SQL", + selectTables: "Выберите таблицы для переноса", + searchTables: "Поиск таблиц...", + noTables: "Нет таблиц", + selectSourceFirst: "Сначала выберите исходное подключение и базу данных", + tableError: "Таблица {table}: ошибка — {error}", + overallProgress: "Общий прогресс", + dataTransfer: "Перенос данных", + runInBackground: "Выполнить в фоне", + newTask: "Новый перенос", + editConfig: "Изменить конфигурацию", + retry: "Повторить", + targetTableBusy: "Другой перенос уже выполняет запись в целевые таблицы: {tables}", + ownershipTitle: "Подтвердите владение", + ownershipMessage: "В целевой базе данных отсутствуют следующие пользователи-владельцы или роли: {owners}. Применение исходного владения может завершиться ошибкой.", + ownershipSkipDetails: "При пропуске операторы изменения владельца объектов выполняться не будут. Синхронизация данных таблиц и остальной структуры продолжится.", + ownershipTargetOwner: "При подтверждении объекты с отсутствующими владельцами будут переназначены пользователю целевого подключения: {owner}.", + ownershipSkip: "Пропустить", + ownershipConfirm: "Подтвердить", + selectConnection: "Выбрать подключение", + selectDatabase: "Выбрать базу данных", + selectSchema: "Выбрать схему", + searchConnection: "Поиск подключений...", + searchDatabase: "Поиск баз данных...", + searchSchema: "Поиск схем...", + saveConfig: "Сохранить конфигурацию", + saveAsNewTask: "Сохранить как задачу", + taskSaved: "Задача сохранена", + unsavedTitle: "Несохранённые изменения", + unsavedMessage: "В текущей конфигурации есть несохранённые изменения. Отменить их?", + unsavedDiscard: "Отменить", + tasks: { + title: "Задачи переноса", + searchTasks: "Поиск задач...", + newTask: "Новая задача", + newFolder: "Новая папка", + newSubfolder: "Новая подпапка", + rename: "Переименовать", + duplicate: "Дублировать", + delete: "Удалить", + open: "Открыть", + moveToFolder: "Переместить в папку", + ungrouped: "Без группы", + empty: "Нет сохранённых задач переноса", + newFolderDefault: "Новая папка", + newTaskDefault: "Новая задача переноса", + deleteFolderTitle: "Удалить папку", + deleteFolderConfirm: "Удалить «{name}» и все задачи переноса внутри неё?", + deleteTaskTitle: "Удалить задачу", + deleteTaskConfirm: "Удалить задачу переноса «{name}»?", + nameConflict: "«{name}» уже существует в этом расположении", + moveFailed: "Не удалось переместить: {message}", + saveFailed: "Не удалось сохранить: {message}", + deleteFailed: "Не удалось удалить: {message}", + }, + }, + tableImport: { + title: "Импорт данных таблицы", + selectedTasks: "Выбрано элементов импорта: {selected} / {total}", + selectTask: "Импортировать {name}", + noTasksSelected: "Выберите хотя бы один элемент для импорта.", + target: "Целевая таблица", + selectFile: "Выбрать файл", + changeFile: "Изменить файл", + noFileSelected: "Файл не выбран", + sourceFile: "Исходный файл", + sourceFormat: "Исходный формат", + targetMode: "Цель", + existingTable: "Существующая таблица", + createTable: "Создать таблицу", + createTableHint: "Определить столбцы по файлу", + targetTableName: "Имя таблицы", + noExistingTarget: "Таблица не выбрана", + searchExistingTables: "Поиск таблиц...", + loadingTables: "Загрузка таблиц...", + noTables: "Нет доступных таблиц", + targetColumnsTimeout: "Время загрузки столбцов целевой таблицы истекло. Проверьте подключение и повторите попытку.", + retry: "Повторить", + stepSource: "Источник", + stepOptions: "Параметры", + stepMapping: "Сопоставление", + stepReview: "Проверка", + stepExecution: "Запуск", + formatCsv: "CSV", + formatCsvDescription: "Текст с разделителем-запятой", + formatTsv: "TSV", + formatTsvDescription: "Текст с разделителем-табуляцией", + formatDelimited: "С разделителем", + formatDelimitedDescription: "Пользовательский текстовый разделитель", + formatJson: "JSON", + formatJsonDescription: "Строки в виде объектов или массивов", + formatExcel: "Excel", + formatExcelDescription: "XLS, XLSX, XLSM", + formatSql: "SQL", + formatSqlDescription: "Операторы INSERT в скриптах SQL", + previewRows: "Строк предпросмотра", + delimiter: "Разделитель", + encoding: "Кодировка", + encodingAuto: "Автоопределение", + encodingUtf8: "UTF-8", + encodingGbk: "GBK / GB18030", + encodingUtf16Le: "UTF-16 LE", + encodingUtf16Be: "UTF-16 BE", + encodingDetected: "Определено: {encoding}", + hasHeader: "Первая строка — заголовок", + titleRow: "Строка заголовка (0 — нет)", + dataStartRow: "Начальная строка данных", + lastDataRow: "Последняя строка данных (0 — до конца)", + trimValues: "Обрезать значения", + emptyStringAsNull: "Пустая строка как NULL", + jsonShape: "Строки JSON", + jsonShapeAuto: "Автоопределение", + jsonShapeObjects: "Объекты", + jsonShapeArrays: "Массивы", + sheet: "Лист", + firstSheet: "Первый лист", + loadPreview: "Загрузить предпросмотр", + reloadPreview: "Обновить предпросмотр", + previewReady: "Строк: {rows}, столбцов: {columns}", + previewReadyPartial: "Показано строк: {rows}, столбцов: {columns}; итог будет подтверждён во время импорта", + previewPartial: "Показано строк: {rows}", + rowsImported: "строк импортировано", + file: "Файл", + rows: "Строки", + mapped: "Сопоставлено", + mapping: "Сопоставление столбцов", + sourceColumn: "Источник", + targetColumn: "Цель", + targetDataType: "Тип", + createColumns: "Создаваемые столбцы", + skipColumn: "Пропустить", + preview: "Предпросмотр", + mode: "Режим импорта", + append: "Добавить данные", + truncate: "Очистить и импортировать", + progress: "Прогресс", + start: "Начать импорт", + success: "Импортировано строк: {count}", + elapsed: "Прошло {duration}", + back: "Назад", + next: "Далее", + truncateWarning: "Существующие строки целевой таблицы будут удалены перед началом импорта.", + requiredUnmapped: "Обязательные целевые столбцы не сопоставлены: {columns}", + status_idle: "Готово к импорту", + status_running: "Импорт данных", + phase_preparing: "Подготовка импорта", + phase_detectingEncoding: "Определение кодировки текста", + phase_reading: "Чтение исходного файла", + phase_writing: "Запись данных", + phase_finalizing: "Завершение импорта", + status_done: "Импорт завершён", + status_error: "Импорт не выполнен", + status_cancelled: "Импорт отменён", + }, + dataGenerate: { + title: "Генерация данных", + target: "Цель", + rowCount: "Количество генерируемых строк", + columns: "Столбцы", + column: "Столбец", + type: "Тип", + generator: "Генератор", + columnProps: "Свойства столбца", + databaseObjects: "Объекты базы данных", + selectTable: "Выберите таблицу слева", + saveProfile: "Сохранить профиль", + loadProfile: "Загрузить профиль", + options: "Параметры", + generateOrder: "Порядок генерации", + nextStep: "Далее", + insertSuccess: "Вставлено строк: {count}", + noData: "Данных пока нет, сначала настройте правила генерации", + noResult: "Нет результатов выполнения", + regenerate: "Сгенерировать заново", + first50Rows: "Показаны первые 50 строк, всего строк: {count}", + resultTitle: "Результаты выполнения", + successLabel: "Успешно: {count}", + failLabel: "С ошибкой: {count}", + totalLabel: "/ всего записей: {count}", + copySampleSql: "Копировать пример SQL", + prevStep: "Назад", + startInsert: "Начать вставку", + confirm: "Подтвердить", + back: "Назад", + reset: "Сбросить", + selectGenerator: "Выберите генератор...", + selectGeneratorHint: "Выберите генератор", + preview: "Предпросмотр", + noValue: "(нет)", + startDate: "Начальная дата", + endDate: "Конечная дата", + allDay: "Весь день", + startTime: "Время начала", + endTime: "Время окончания", + weekday: "День недели", + all: "Все", + weekdayOnly: "Будние дни", + custom: "Свой", + values: "Значения", + min: "Минимум", + max: "Максимум", + increment: "Шаг", + cycle: "Циклически при превышении", + includeDefault: "Включать DEFAULT", + includeNull: "Включать NULL", + unique: "Задать уникальность", + uniqueExhausted: "Не удалось сгенерировать уникальное значение для {table}.{column} за {attempts} попыток. Увеличьте доступный диапазон значений или уменьшите число строк.", + disableLinks: "Отключить связи данных между столбцами", + imageMode: "Режим", + generate: "Сгенерировать", + fromFolder: "Из папки", + imageWidth: "Ширина изображения", + imageHeight: "Высота изображения", + imageFormat: "Формат изображения", + folderPath: "Путь к папке", + filterByExtension: "Фильтр по расширениям", + errorContinue: "Продолжать при ошибке", + truncateBefore: "Очистить таблицу перед генерацией", + useTransaction: "Использовать транзакцию", + extendedInsert: "Использовать расширенный INSERT", + ok: "OK", + noTablesSelected: "Таблицы не выбраны", + orderHint: "Используйте кнопки со стрелками для изменения порядка", + language: "Язык", + regionLabel: "Регион", + formatLabel: "Формат", + formatType: "Тип формата", + typeLabel: "Тип", + loading: "Загрузка...", + regex: "Regex", + rawPattern: "Режим исходного шаблона", + notSet: "(не задано)", + noMatch: "(нет совпадений)", + invalidRegex: "(неверный regex)", + noDomain: "(нет домена)", + schema: "Схема", + tableLabel: "Таблица", + columnLabel: "Столбец", + genMode: "Режим генерации", + dateType: "Тип даты", + yearOffsetRange: "Диапазон лет (смещение от текущего года)", + numberType: "Тип числа", + integer: "Целое", + decimal: "Десятичное", + decimalPlaces: "Знаков после запятой", + uuidFormat: "Формат UUID", + uuidWithHyphens: "С дефисами", + uuidNoHyphens: "Без дефисов", + includeSeparators: "Включать разделители", + phoneDomestic: "Внутренний", + phoneInternational: "Международный", + charCount: "Символы", + start: "Начало", + valueList: "Список значений", + domainList: "Список доменов", + subdomains: "Поддомены", + tlds: "Домены верхнего уровня", + extensionType: "Тип расширения", + extensionList: "Список расширений:", + availableExtensions: "Доступные расширения:", + includeExtension: "Включать расширение", + includeFileName: "Включать имя файла", + pathType: "Тип пути", + ipType: "Тип IP-адреса", + nameFormat: "Формат имени", + transformTo: "Преобразовать значения в", + generateOptions: "Параметры генерации", + previewRowCount: "{count} строк", + useKeywords: "Генерировать из ключевых слов", + weekdayShort: { + sun: "Вс", + mon: "Пн", + tue: "Вт", + wed: "Ср", + thu: "Чт", + fri: "Пт", + sat: "Сб", + }, + countries: { + us: "США", + uk: "Великобритания", + cn: "Китай", + jp: "Япония", + other: "Другое", + cnEnglish: "Китай (английский)", + jpEnglish: "Япония (английский)", + }, + cityLanguages: { + native: "Родной язык", + english: "Английский", + }, + addressTypes: { + line1: "Адресная строка 1", + line2: "Адресная строка 2", + full: "Полный адрес", + }, + nameFormats: { + full: "Полное имя", + last: "Только фамилия", + first: "Только имя", + }, + regionFormats: { + name: "Название", + code: "Код", + codeName: "Код + название", + }, + transforms: { + none: "Как есть", + upper: "ВЕРХНИЙ РЕГИСТР", + lower: "нижний регистр", + title: "С Заглавных Букв", + }, + extensionCategories: { + image: "Изображение", + document: "Документ", + spreadsheet: "Таблица", + presentation: "Презентация", + audio: "Аудио", + video: "Видео", + code: "Код", + archive: "Архив", + web: "Веб", + database: "База данных", + }, + placeholders: { + enumValues: "Одно значение на строку\nпервое\nвторое\nтретье", + subdomains: "Один поддомен на строку\nauth.\nwww.\napi.", + tlds: "Один TLD на строку\n.com\n.cn\n.io", + fileExtensions: "Одно расширение на строку\npng\njpg\ntxt", + paymentMethods: "Один способ оплаты на строку\nБанковская карта\nPayPal\nApple Pay", + keywords: "Одно ключевое слово на строку\nЯблоко\nВишня\nАпельсин", + weightUnits: "Одна единица на строку\ng\nkg\nlb", + }, + genModes: { + random: "Случайно", + unique: "Без дубликатов", + repeat: "Повторять каждое значение", + }, + gen: { + general: "Общее", + personal: "Личные данные", + payment: "Платёжные данные", + business: "Бизнес", + location: "Местоположение", + product: "Товар", + computer: "Компьютер", + number: "Число", + datetime: "Дата и время", + date: "Дата", + time: "Время", + sequence: "Последовательность", + enum: "Перечисление", + text: "Текст", + image: "Изображение или двоичные данные", + foreign_key: "Внешний ключ", + uuid: "UUID", + regex: "Regex", + full_name: "Полное имя", + gender: "Пол", + title: "Обращение", + marital_status: "Семейное положение", + phone: "Телефон", + email: "Email", + job_title: "Должность", + social_id: "Идентификатор соцстрахования", + payment_method: "Способ оплаты", + credit_card_type: "Тип банковской карты", + credit_card_number: "Номер банковской карты", + credit_card_date: "Срок действия карты", + company_name: "Название компании", + department: "Отдел", + industry: "Отрасль", + address: "Адрес", + city: "Город", + region: "Регион", + product_name: "Название товара", + product_category: "Категория товара", + color: "Цвет", + size: "Размер", + weight_unit: "Единица веса", + barcode: "Штрихкод", + sku: "SKU", + ip_address: "IP-адрес", + mac_address: "MAC-адрес", + file_path: "Путь к файлу", + file_name: "Имя файла", + file_extension: "Расширение файла", + url: "URL", + hostname: "Имя хоста", + id_number: "Номер документа", + }, + idTypes: { + title: "Тип документа", + customPattern: "Свой шаблон", + customPatternPlaceholder: "например, ([A-Z]{'{'}2{'}'})-([0-9]{'{'}8{'}'})", + customPatternHint: "Поддерживаются простые шаблоны: буквы [A-Z], цифры [0-9], повторы {'{'}n{'}'}, дефисы", + id_card: "Китайское удостоверение личности", + passport: "Паспорт", + hk_macau_pass: "Разрешение Гонконг/Макао", + taiwan_pass: "Разрешение Тайваня", + uscc: "Единый код социального кредита", + bank_card: "Банковская карта", + drivers_license: "Водительские права", + custom: "Свой", + }, + insertingTable: "Запись в {table} (таблица {index}/{count})", + elapsed: "прошло {seconds} с", + samplePreviewNotice: "Показаны первые {shown} примеров строк; все {count} строк генерируются во время вставки", + largeRowCountHint: "Большое число строк ({count}); строки генерируются и вставляются пакетами, отмену можно выполнить в любой момент", + timeoutSecs: "Тайм-аут (секунды)", + timeoutHint: "0 означает отсутствие тайм-аута; оставьте 0 или увеличьте его для больших объёмов данных", + batchRows: "Строк в пакете", + batchRowsHint: "Число строк, генерируемых и вставляемых за один проход; слишком большие пакеты разбиваются автоматически", + cancelInsert: "Отменить вставку", + cancelledLabel: "Отменено; уже записанные строки остаются в таблице", + }, + tableToolbox: { + title: "Инструменты данных", + generateData: "Генерировать данные", + importData: "Импорт данных", + exportData: "Экспорт данных", + generateDataComingSoon: "Скоро", + }, + sqlFile: { + manualTransactionHint: "Изменения ожидают Commit или Rollback. При ошибках выполняется откат. DDL и COMMIT внутри файла всё равно могут зафиксировать изменения.", + manualCancelHint: "Отмена ожидает завершения текущего оператора, затем откатывает незафиксированные изменения.", + pendingTransaction: "Ожидание Commit или Rollback", + rollbackBeforeClose: "Есть незафиксированные изменения. Откатить и закрыть?", + transactionEnded: "Транзакция завершена или была отменена. При необходимости запустите файл снова.", + restoreScope: "Область восстановления", + restoreAll: "Всё содержимое", + restoreSelectedTables: "Выбранные таблицы", + restoreTablesOnly: "Восстанавливать только структуру и данные таблиц. Представления, процедуры, триггеры и события исключены. Существующие внешние ключи и триггеры могут повлиять на восстановление.", + scanningTables: "Сканирование таблиц резервной копии...", + searchBackupTables: "Поиск таблиц резервной копии...", + selectVisibleTables: "Выбрать видимые таблицы", + selectedTableCount: "Выбрано таблиц: {selected} / {total}", + noBackupTables: "В резервной копии нет подходящих таблиц", + title: "Выполнить SQL-файл", + file: "Файл", + selectSqlFile: "Выбрать SQL-файл", + browse: "Обзор", + previewingLines: "Предпросмотр {count} строк", + previewingFirstLines: "Предпросмотр первых {count} строк", + tooLargeForEditor: "Этот SQL-файл имеет размер {size}, что превышает лимит редактора {limit}. Используйте «Выполнить SQL-файл» для потоковой обработки.", + largeFileExecutionOpened: "Этот SQL-файл размером {size} слишком велик для редактора. Открыто окно «Выполнить SQL-файл» для потоковой обработки.", + target: "Цель", + connection: "Подключение", + selectConnection: "Выбрать подключение", + database: "База данных", + selectDatabase: "Выбрать базу данных", + databasePlaceholder: "Имя базы данных", + options: "Параметры", + continueOnError: "Продолжать при ошибке", + skipRelationalConstraints: "Временно отключить реляционные ограничения во время импорта", + packageParts: "{count} частей SQL", + runInBackground: "Выполнять в фоне", + cancelling: "Отмена...", + cancel: "Отмена", + execute: "Выполнить", + statement: "Оператор", + succeeded: "Успешно", + failed: "Ошибка", + affectedRows: "Затронуто строк", + currentStatement: "Текущий оператор", + status: { + idle: "Ожидание", + started: "Запущено", + running: "Выполняется", + statementDone: "Оператор выполнен", + statementFailed: "Оператор не выполнен", + done: "Готово", + error: "Ошибка", + cancelled: "Отменено", + }, + fileProgress: "Файл {current} из {total}", + byteProgress: "Прогресс файла", + byteProgressHint: "Основано на прочитанных байтах файла, а не на оставшемся времени выполнения. Достигает 100% только по завершении выполнения. Для сжатых файлов используются сжатые байты.", + bytesRead: "Прочитано {read}", + bytesReadOfTotal: "Прочитано {read} / {total}", + progressPhase: { + preparing: "Подготовка SQL-файла", + reading: "Чтение SQL-файла", + executing: "Выполнение SQL", + }, + fileColumn: "Файл", + totalFiles: "{count} файлов", + }, + sqlFileTree: { + title: "SQL-файлы", + openFolder: "Открыть папку", + closePanel: "Закрыть", + loading: "Загрузка...", + noFolder: "Папка не открыта", + noSqlFiles: "SQL-файлы не найдены", + folderAlreadyOpen: "Эта папка уже открыта", + removeFolder: "Удалить папку", + openFailed: "Не удалось открыть папку: {message}", + loadFailed: "Не удалось загрузить SQL-файлы: {message}", + desktopOnly: "Эта функция доступна только в настольной версии", + refreshFolder: "Обновить папку", + refreshAll: "Обновить всё", + refreshed: "Обновлено", + revealInFileManager: "Показать в файловом менеджере", + revealFailed: "Не удалось открыть файловый менеджер: {message}", + copyPath: "Копировать путь", + pathCopied: "Путь скопирован", + copyFailed: "Не удалось скопировать путь", + openFile: "Открыть", + executeSqlFile: "Выполнить SQL-файл", + newSqlFile: "Новый SQL-файл", + newSqlFileDescription: "Расширение .sql добавляется автоматически.", + createFile: "Создать", + fileCreated: "SQL-файл создан", + createFailed: "Не удалось создать SQL-файл: {message}", + renameFile: "Переименовать", + renameFileDescription: "Расширение .sql добавляется автоматически.", + fileRenamed: "SQL-файл переименован", + renameFailed: "Не удалось переименовать SQL-файл: {message}", + deleteFile: "Удалить файл", + deleteFileConfirm: "Удалить {name}? Это действие необратимо.", + fileDeleted: "SQL-файл удалён", + deleteFailed: "Не удалось удалить SQL-файл: {message}", + expandAll: "Развернуть всё", + collapseAll: "Свернуть всё", + filterSettings: "Фильтр файлов", + fileFilter: "Фильтр по имени файла", + fileFilterPlaceholder: "Фильтр по имени файла", + filterInvalid: "Неверный фильтр файлов, оставлен предыдущий: {message}", + fileFilterHint: "Используйте шаблон, например *.sql или *.sh, либо регулярное выражение, например {regex}.", + }, + diff: { + progress: { + loadingObjects: "Чтение объектов исходной и целевой баз данных...", + loadingSourceDetails: "Чтение структур таблиц исходной базы данных", + loadingTargetDetails: "Чтение структур таблиц целевой базы данных", + loadingExtraObjects: "Чтение других объектов базы данных...", + comparing: "Анализ различий схем...", + generating: "Формирование результата сравнения...", + next: "Далее: {step}", + nextSourceDetails: "Чтение структур таблиц исходной базы данных", + nextTargetDetails: "Чтение структур таблиц целевой базы данных", + nextExtraObjects: "Чтение других объектов базы данных", + nextComparing: "Анализ различий схем", + nextGenerating: "Формирование результата сравнения", + nextComplete: "Завершение", + count: "{current} / {total}", + }, + title: "Сравнение схем", + source: "Источник", + target: "Цель", + selectConnection: "Выбрать подключение", + selectDatabase: "Выбрать базу данных", + selectSchema: "Выбрать схему", + connection: "Подключение", + database: "База данных", + schema: "Схема", + recentConfigs: "Недавние конфигурации", + selectRecentConfig: "Выбрать недавнюю конфигурацию", + ignoreComments: "Игнорировать различия комментариев", + compare: "Сравнить", + comparing: "Сравнение схем...", + noDifferences: "Различия не найдены", + table: "Таблица", + status: "Статус", + details: "Подробности", + added: "Добавлено", + removed: "Удалено", + modified: "Изменено", + indexes: "Индексы", + foreignKeys: "Внешние ключи", + triggers: "Триггеры", + comments: "Комментарии", + newTable: "Новая таблица", + dropTable: "Удалить таблицу", + generatedSql: "SQL синхронизации", + copySql: "Копировать SQL", + executeSync: "Выполнить синхронизацию", + syncSuccess: "Синхронизация выполнена успешно", + swap: "Поменять источник и цель местами", + syncProgress: "Выполнение: {current}/{total}", + syncSummary: "Успешно: {success}, с ошибками: {failed}", + configSaved: "Конфигурация сохранена", + configDeleted: "Конфигурация удалена", + comparisonObjects: "Сравниваемые объекты", + searchObjects: "Поиск имён объектов...", + selectAllObjects: "Выбрать всё", + deselectAllObjects: "Снять выбор", + objectPickerAll: "Все", + objectGroupDisabled: "Этот тип объектов не включён в сравнение.", + noObjects: "Нет объектов", + noObjectMatches: "Нет совпадений", + tableSelection: "Таблицы", + chooseTables: "Выбрать таблицы...", + compareAllTables: "Сравнивать все таблицы", + compareTablesSwitch: "Сравнивать таблицы", + tableCompareDisabled: "Сравнение таблиц отключено. Включите переключатель, чтобы включить таблицы.", + tableSelectionUnrestricted: "Сравниваются все таблицы (после фильтров regex). Выберите конкретные таблицы, чтобы ограничить сравнение.", + sourceTables: "Таблицы источника", + routineSelection: "Процедуры", + chooseRoutines: "Выбрать процедуры...", + compareAllRoutines: "Сравнивать все процедуры", + compareRoutinesSwitch: "Сравнивать процедуры", + routineCompareDisabled: "Сравнение процедур отключено. Включите переключатель, чтобы включить процедуры и функции.", + routineSelectionUnrestricted: "Сравниваются все функции и процедуры. Выберите конкретные процедуры, чтобы ограничить сравнение.", + routineSelectionTooLarge: "В этой схеме {count} процедур (лимит {limit} для неограниченного сравнения). Выберите конкретные процедуры перед сравнением.", + routineSelectionNeedSource: "Сначала выберите исходное подключение и базу данных, чтобы выбрать процедуры.", + routineSelectionUnsupported: "Для сравнения процедур и функций требуется один и тот же поддерживаемый диалект с обеих сторон (MySQL, SQL Server или семейство PostgreSQL).", + routineSameNameMatchingOnly: "Процедуры сопоставляются по одинаковому имени (и сигнатуре). Сопоставление с переименованием вручную в этой версии недоступно.", + sourceRoutines: "Процедуры источника", + noRoutines: "Процедуры не найдены", + targetRoutineMatching: "Сопоставление целевых процедур", + matchedRoutines: "Сопоставлено процедур: {matched}/{total}", + selectTargetRoutine: "Выбрать целевую процедуру", + searchSourceRoutines: "Поиск объектов...", + searchTargetRoutine: "Поиск целевых процедур...", + noTargetRoutines: "Нет доступных целевых процедур", + unmatchedRoutineWarning: "{count} выбранных процедур источника не имеют целевых с тем же именем", + targetRoutineInUse: "Эта целевая процедура уже используется другой процедурой источника", + targetRoutine: "Целевая процедура", + resultTabTables: "Таблицы ({count})", + resultTabRoutines: "Процедуры ({count})", + nextStepDeployRoutines: "Далее (проверить развёртывание процедур)", + routineSyncDeferredHint: "Синхронизация и развёртывание процедур пока недоступны. Сравните определения здесь и скопируйте DDL для применения вручную.", + dependencyGraph: "Граф зависимостей", + routineDiffPoints: "Различия", + routineDiffStats: "+{added} −{removed} ~{modified}", + selectRoutineToCompare: "Выберите процедуру для сравнения определений", + routinesNotCompared: "Сравнение процедур отключено. Включите переключатель процедур и повторите сравнение.", + routineDdlCopied: "DDL скопирован", + copySourceDdl: "Копировать DDL источника", + copyTargetDdl: "Копировать DDL цели", + autoMatchHint: "Целевые таблицы сопоставляются по одинаковому имени.", + matchedTables: "Сопоставлено таблиц: {matched}/{total}", + missingTargetTables: "Отсутствуют целевые таблицы с тем же именем: {tables}", + targetTableMatching: "Сопоставление целевых таблиц", + sourceTable: "Таблица источника", + targetTable: "Целевая таблица", + similarity: "Сходство", + selectTargetTable: "Выбрать целевую таблицу", + searchTargetTable: "Поиск целевых таблиц...", + noTargetTables: "Нет доступных целевых таблиц", + tableMatchStatus: { + automatic: "Автоматически", + manual: "Вручную", + unmatched: "Не сопоставлено", + }, + unmatchedTableWarning: "{count} выбранных таблиц источника не имеют сопоставления с целью", + targetTableInUse: "Эта целевая таблица уже используется другой таблицей источника", + sourceObject: "Объект источника", + targetObject: "Целевой объект", + operation: "Операция", + selectedCount: "Выбрано {selected} из {total}", + saveConfig: "Сохранить конфигурацию", + loadConfig: "Загрузить конфигурацию", + options: "Параметры", + ddlCompare: "Сравнение DDL", + deployScript: "Скрипт развёртывания", + deployScriptAll: "Все скрипты развёртывания", + deployScriptDesc: "SQL-скрипт для выбранного объекта", + deployScriptAllDesc: "SQL-скрипт для всех выбранных объектов", + copy: "Копировать", + execute: "Выполнить", + executeAll: "Выполнить всё", + executeSuccess: "Выполнено успешно", + selectObjectToCompare: "Выберите объект для просмотра сравнения DDL", + noDdlAvailable: "DDL недоступен", + noDeployScript: "Нет скрипта развёртывания", + noDeployScriptAll: "Нет скрипта развёртывания для выбранных объектов", + sourceDdl: "DDL источника", + targetDdl: "DDL цели", + objectNotExistsInSource: "Этот объект отсутствует в исходной базе данных", + objectNotExistsInTarget: "Этот объект отсутствует в целевой базе данных", + nextStepDeploy: "Далее (проверить развёртывание)", + deployReview: "Проверка развёртывания", + backToResult: "Назад к результату", + copyScript: "Копировать скрипт", + exportSql: "Экспорт .sql", + deployToServer: "Развернуть на сервере", + deployConfirmTitle: "Финальное подтверждение", + deployConfirmMessage: "Вы собираетесь развернуть следующие изменения в целевой базе данных", + destructiveSqlDetected: "Обнаружено разрушительных операций: {count}; требуется явное подтверждение", + compatibilityWarnings: "Предупреждения о совместимости", + compatibilityWarningsDetected: "Предупреждения о совместимости: {count}", + targetServer: "Целевой сервер", + dbVersion: "Версия базы данных", + targetDatabase: "Целевая база данных", + targetSchema: "Целевая схема", + useTransaction: "Выполнять в транзакции (автоматический откат при ошибке)", + confirmDeploy: "Подтвердить развёртывание", + exportSuccess: "Экспорт выполнен успешно", + create: "Создать", + delete: "Удалить", + modify: "Изменить", + cancel: "Отмена", + prevStep: "Назад", + recompare: "Сравнить снова", + maximize: "Развернуть", + restore: "Восстановить", + operationLabel: { + modify: "Объекты для изменения", + create: "Объекты для создания", + delete: "Объекты для удаления", + none: "Нет операции", + }, + objectKindLabel: { + table: "Таблица", + view: "Представление", + function: "Функция", + sequence: "Последовательность", + rule: "Правило", + owner: "Владелец", + column: "Столбец", + index: "Индекс", + foreignKey: "Внешний ключ", + trigger: "Триггер", + tableOption: "Параметры таблицы", + }, + noObjectsSelected: "Выберите объекты для развёртывания", + deploySuccess: "Развёртывание выполнено", + deployFailed: "Развёртывание не выполнено", + deploySuccessMessage: "SQL-скрипт успешно выполнен в целевой базе данных", + deployFailedMessage: "Во время выполнения произошла ошибка", + affectedRows: "Затронуто строк", + executedStatements: "Выполненные операторы", + serverVersion: "Версия сервера", + info: "Информация", + connType: "Тип подключения", + connName: "Имя подключения", + host: "Хост", + addHost: "Добавить хост", + port: "Порт", + copied: "Скопировано в буфер обмена", + saveConfigPrompt: "Введите имя конфигурации:", + defaultConfigName: "По умолчанию", + dependsOn: "зависит от", + dependedBy: "зависит от него", + close: "Закрыть", + searchConnection: "Поиск подключений...", + searchDatabase: "Поиск баз данных...", + searchSchema: "Поиск схем...", + openFieldMapping: "Сопоставление полей", + fieldMapping: { + title: "Сопоставление типов полей", + sameTypeHint: "Источник и цель — один и тот же тип базы данных. Сопоставление полей нужно только при сравнении разных типов баз данных.", + preset: "Встроенный шаблон", + selectPreset: "Выбрать шаблон...", + noMappings: "Сопоставления полей не заданы", + sourceType: "Тип источника", + targetType: "Тип цели", + paramStrategy: "Стратегия параметров", + strategyPreserve: "Сохранять", + strategyStrip: "Удалять", + strategyCustom: "Свой", + customParamsPlaceholder: "напр. (100)", + addMapping: "Добавить сопоставление", + autoGenerate: "Автосоздание", + import: "Импорт", + export: "Экспорт", + done: "Готово", + importTypeMismatch: "Импортированные сопоставления были экспортированы для {src} → {tgt}, но текущее сравнение — {curSrc} → {curTgt}. Сопоставления типов могут быть неточными. Продолжить?", + importSuccess: "Сопоставления полей успешно импортированы", + importError: "Не удалось импортировать сопоставления полей. Проверьте формат JSON.", + clearMappings: "Очистить", + staleMappingWarning: "Тип базы данных изменился с {prevSrc} → {prevTgt} на {curSrc} → {curTgt}. Существующие сопоставления полей могут быть недействительны. Очистить их?", + }, + deployMode: "Развернуть", + forwardSql: "Прямой SQL", + rollbackSql: "SQL отката", + rollbackMode: "Откат", + deployMixed: "Развёртывание выполнено частично. Некоторые инструкции могли уже примениться ({executedCount}/{statementCount}). DDL может не поддерживать транзакции.", + deployRolledBack: "Все изменения откатаны.", + rollbackIncompleteBlocked: "SQL отката неполный (отсутствуют объекты). Выполнение заблокировано.", + rollbackIncompleteBanner: "Откат неполный — отсутствует DDL триггера/таблицы. Исправьте отсутствующие объекты перед выполнением.", + deployMixedTitle: "Частично развёрнуто", + deployRolledBackTitle: "Откатано", + deployMixedWarning: "Некоторые инструкции могли уже примениться, а другие завершились ошибкой. База данных может находиться в несогласованном состоянии. Проверьте журнал транзакций и выполните ручные исправления перед повторной попыткой.", + }, + rollbackComparison: { + title: "Сравнение отката", + forwardSql: "Прямой SQL", + rollbackSql: "SQL отката", + }, + schemaDiff: { + optionsTitle: "Параметры сравнения", + selectConfig: "Выбрать конфигурацию", + newConfigName: "Новая конфигурация", + newConfig: "Новая конфигурация", + renameConfig: "Переименовать конфигурацию", + duplicateConfig: "Дублировать конфигурацию", + deleteConfig: "Удалить конфигурацию", + exportConfig: "Экспорт конфигурации", + exportAllConfigs: "Экспорт всех конфигураций", + importConfig: "Импорт конфигурации", + importFromFile: "Импорт из файла", + importFromText: "Импорт из текста", + importPlaceholder: "Вставьте конфигурацию JSON...", + importInvalidJson: "Неверный формат JSON", + configName: "Имя конфигурации", + tableFilter: "Фильтр таблиц", + tableFilterHint: "Сопоставляет полные имена таблиц по регулярному выражению. Не вводите /.../. ^ означает начало, $ — конец, | — или.", + tableFilterHintShort: "Ограничить сравнение регулярным выражением имени таблицы", + tableFilterHelp: "Справка по фильтру таблиц", + tableFilterHelpRule: "Сопоставляет полные имена таблиц. Не вводите /.../.", + tableFilterHelpBlank: "Пустое поле включения — все таблицы. Пустое поле исключения — без исключений.", + tableFilterHelpExample: "^user_ означает начало с user_; _bak$ — конец на _bak; a|b — a или b.", + tableIncludePattern: "Сравнивать только совпавшие таблицы", + tableIncludePatternPlaceholder: "напр. ^user_", + tableExcludePattern: "Пропускать совпавшие таблицы", + tableExcludePatternPlaceholder: "напр. _bak$", + tableFilterPriority: "Если совпадают оба", + tableFilterPriorityExclude: "Приоритет у исключения", + tableFilterPriorityInclude: "Приоритет у включения", + options: { + tables: "Сравнивать таблицы", + primaryKeys: "Сравнивать первичные ключи", + foreignKeys: "Сравнивать внешние ключи", + uniqueKeys: "Сравнивать уникальные ключи", + checks: "Сравнивать ограничения CHECK", + exclusions: "Сравнивать ограничения исключения", + views: "Сравнивать представления", + functions: "Сравнивать функции", + indexes: "Сравнивать индексы", + sequences: "Сравнивать последовательности", + triggers: "Сравнивать триггеры", + rules: "Сравнивать правила", + owners: "Сравнивать владельцев", + cascadeDelete: "Использовать каскадное удаление CASCADE", + sequenceLastValues: "Сравнивать последние значения последовательностей", + compareColumnOrder: "Сравнивать порядок столбцов", + ignoreTableNameCase: "Игнорировать регистр имён таблиц", + ignoreColumnNameCase: "Игнорировать регистр имён столбцов", + detectRenames: "Обнаруживать переименования", + detectTableRenames: "Обнаруживать переименования таблиц", + enableRollback: "Включить откат", + advancedSection: "Дополнительно", + renameThreshold: "Порог переименования", + compatibilityThreshold: "Порог совместимости", + sourceDialect: "Диалект источника", + targetDialect: "Диалект цели", + batchSection: "Пакетно", + batchPatterns: "Шаблоны таблиц (через запятую)", + dialectAuto: "авто", + }, + }, + tableMultiSelect: { + tables: "Таблицы", + selected: "Выбрано {selected}/{total}", + search: "Поиск таблиц...", + selectAll: "Выбрать все", + deselectAll: "Снять выделение", + noTables: "Нет доступных таблиц", + }, + dataCompare: { + manualTransactionHint: "Изменения ожидают фиксации или отката. При ошибке транзакция откатывается.", + pendingTransaction: "Ожидание фиксации или отката", + rollbackBeforeClose: "Есть незафиксированные изменения. Откатить и закрыть?", + transactionEnded: "Транзакция завершена или была откатана. Повторите сравнение перед новой попыткой.", + title: "Сравнение данных", + selectTable: "Выбрать таблицу", + searchTable: "Поиск таблиц...", + sourceTables: "Таблицы источника", + targetTable: "Целевая таблица", + searchTables: "Поиск таблиц...", + selectedTables: "Выбрано {selected}/{total}", + selectAllTables: "Выбрать все", + deselectAllTables: "Снять выделение", + selectSourceTables: "Сначала выберите подключение и базу данных источника, затем таблицы для сравнения", + noTables: "Нет таблиц для сравнения", + autoMatchHint: "Пакетный режим автоматически сопоставляет целевые таблицы по одинаковому имени", + matchedTables: "Сопоставлено таблиц: {matched}/{total}", + missingTargetTables: "Отсутствуют одноимённые целевые таблицы: {tables}", + keyColumns: "Ключевые столбцы", + keyColumnsAutoHint: "По умолчанию используются первичные ключи; также можно выбрать другие столбцы как столбцы сопоставления.", + keyColumnsSelectPlaceholder: "Выберите столбцы сопоставления", + keyColumnsSearch: "Поиск столбцов...", + keyColumnsEmpty: "Нет доступных столбцов", + keyColumnsLoading: "Загрузка столбцов...", + keyColumnsSelectedCount: "Выбрано столбцов: {selected}/{total}", + keyColumnsPrimaryKeyBadge: "PK", + keyColumnsStatusAuto: "Авто", + keyColumnsStatusManual: "Вручную", + keyColumnsAutoSummary: "Автоматически используется первичный ключ: {columns}", + keyColumnsManualHint: "Столбцы сопоставления, выбранные вручную: {columns}", + keyColumnsNoneSelected: "Столбец не выбран", + keyColumnsNeedsSelection: "Выберите столбцы", + keyColumnsNoPrimaryKey: "У этой таблицы нет первичного ключа. Выберите столбцы сопоставления вручную.", + keyColumnsResetAuto: "Использовать первичный ключ", + keyColumnsPerTableHint: "Каждая таблица сохраняет свои столбцы сопоставления; по умолчанию используются первичные ключи.", + keyColumnsSelectTableHint: "Сначала выберите таблицы источника", + keyColumnsTargetMissingHint: "Нет одноимённой целевой таблицы, поэтому столбцы сопоставления не нужны", + rowCounts: "Строк в источнике: {source}, в цели: {target}; полное сравнение завершено", + previewLimitOption: "Предпросмотр {count}", + compare: "Сравнить данные", + recompare: "Сравнить снова", + summary: "Добавлено {added}, удалено {removed}, изменено {modified}", + batchSummary: "Сравнено таблиц: {tables}; различных: {different}, идентичных: {same}, с ошибкой: {failed}; добавлено {added}, удалено {removed}, изменено {modified}", + comparingTable: "Сравнение {current}/{total}: {table}", + keyColumnsInline: "Ключевые столбцы: {columns}", + selectedInline: "Выбрано {selected}/{total}", + selectedSummary: "Выбрано: добавлено {added}, удалено {removed}, изменено {modified}", + selectAllKind: "Выбрать все {kind}", + clearKind: "Очистить {kind}", + clearSelection: "Очистить весь выбор", + showAllRows: "Показать все {count}", + showLessRows: "Показать меньше", + remainingRows: "Ещё {count} строк скрыто в предпросмотре", + planningSync: "Обновление плана синхронизации...", + noSelectedDifferences: "Не выбрано ни одного различия для выполнения", + planSummary: "План: вставок — {inserts}, обновлений — {updates}, удалений — {deletes}, инструкций — {statements}", + statusDifferent: "Различаются", + statusSame: "Одинаковые", + statusError: "Ошибка", + noKeyColumns: "Выберите хотя бы один ключевой столбец", + missingKeyColumns: "Ключевые столбцы должны существовать и в таблице источника, и в целевой таблице: {columns}", + noCommonColumns: "В таблицах источника и цели нет общих столбцов для сравнения", + targetTableMissing: "Целевая таблица не найдена: {table}", + noComparableTables: "Не найдено таблиц для сравнения. Проверьте наличие одноимённых целевых таблиц.", + noDifferences: "Данные идентичны, SQL синхронизации не требуется", + syncSuccess: "Синхронизация данных выполнена успешно", + }, + settings: { + historyRetentionLimit: "Хранение истории запросов", + historyRetentionDescription: "Снижение лимита удаляет старые записи при следующей записи истории запросов. Увеличение лимита или выбор «Без ограничений» не восстанавливает удалённые записи. Лимит применяется ко всем подключениям и источникам выполнения.", + historyRetentionUnlimited: "Без ограничения", + historyRetentionLoadFailed: "Не удалось загрузить настройку хранения истории: {error}", + tableOpenSortMode: "Сортировка таблиц по умолчанию", + tableDatabaseSortDirection: "Направление сортировки базы данных по умолчанию", + tableLocalSortDirection: "Направление сортировки текущей страницы по умолчанию", + tableOpenSortDescription: "Для вновь открытых таблиц сортировка базы данных использует полный первичный ключ; сортировка текущей страницы использует его первый столбец и только загруженные строки. Если недоступно или не поддерживается, сохраняется текущее поведение.", + tableSortUnchanged: "Сохранить текущее поведение", + tableSortDatabase: "Сортировка базы данных", + tableSortLocal: "Сортировка текущей страницы", + tableSortAscending: "По возрастанию ASC", + tableSortDescending: "По убыванию DESC", + title: "Настройки", + searchSettings: "Поиск настроек", + searchSettingsNoResults: "Подходящих настроек нет", + searchSettingsResults: "Результаты поиска настроек", + clearSettingsSearch: "Очистить поиск настроек", + exitSettingsSearch: "Назад к настройкам", + editorTab: "Редактор", + globalConnectTimeout: "Глобальный тайм-аут подключения (секунды)", + globalConnectTimeoutDescription: "Используется подключениями, наследующими глобальную настройку.", + globalQueryTimeout: "Глобальный тайм-аут запроса (секунды)", + globalQueryTimeoutDescription: "Используется подключениями, наследующими глобальную настройку. Укажите 0, чтобы отключить тайм-аут.", + sqlFormatterTab: "Форматировщик SQL", + sqlFormatterImport: "Импорт конфигурации", + sqlFormatterExport: "Экспорт конфигурации", + sqlFormatterImportSuccess: "Конфигурация форматировщика импортирована.", + sqlFormatterCopyJson: "Копировать JSON", + sqlFormatterCopyJsonSuccess: "JSON скопирован.", + sqlFormatterCopyJsonFailed: "Не удалось скопировать: {message}", + sqlFormatterJsonEditorLoadFailed: "Не удалось загрузить редактор JSON. Переключено на базовый ввод: {message}", + sqlFormatterRestoreDefaults: "Восстановить значения по умолчанию", + sqlFormatterFormMode: "Форма", + sqlFormatterJsonMode: "JSON", + sqlFormatterKeywordCase: "Регистр ключевых слов", + sqlFormatterFunctionCase: "Регистр функций", + sqlFormatterDataTypeCase: "Регистр типов данных", + sqlFormatterIdentifierCase: "Регистр идентификаторов", + sqlFormatterCaseUpper: "Верхний регистр", + sqlFormatterCaseLower: "Нижний регистр", + sqlFormatterCasePreserve: "Сохранять", + sqlFormatterIndent: "Отступ", + sqlFormatterIndentSpaces: "Пробелы", + sqlFormatterIndentTabs: "Табуляция", + sqlFormatterTabWidth: "Ширина табуляции", + sqlFormatterIndentStyle: "Стиль отступа", + sqlFormatterIndentStyleStandard: "Стандартный", + sqlFormatterIndentStyleTabularLeft: "Табличный слева", + sqlFormatterIndentStyleTabularRight: "Табличный справа", + sqlFormatterLogicalOperatorNewline: "Перенос логических операторов", + sqlFormatterLogicalBefore: "Перед оператором", + sqlFormatterLogicalAfter: "После оператора", + sqlFormatterLogicalSameLine: "Оставлять в той же строке", + sqlFormatterFromClauseLayout: "Размещение предложения FROM", + sqlFormatterFromNewLine: "Таблица на следующей строке", + sqlFormatterFromSameLine: "FROM с первой таблицей", + sqlFormatterExpressionWidth: "Ширина выражения", + sqlFormatterLinesBetweenQueries: "Строк между запросами", + sqlFormatterPreserveEmptyLines: "Сохранять пустые строки", + sqlFormatterDenseOperators: "Плотные операторы", + sqlFormatterNewlineBeforeSemicolon: "Точка с запятой на новой строке", + sqlFormatterAdvancedOptions: "Дополнительные параметры", + sqlFormatterParams: "Параметры", + sqlFormatterParamTypes: "Типы параметров", + sqlFormatterEditorShortcuts: "Сочетания клавиш", + sqlFormatterShortcutAction: "Действие", + sqlFormatterShortcutEnabled: "Включено", + sqlFormatterShortcutWindows: "Windows", + sqlFormatterShortcutLinux: "Linux", + sqlFormatterShortcutMacos: "macOS", + sqlFormatterShortcutFind: "Найти", + sqlFormatterShortcutReplace: "Заменить", + sqlFormatterShortcutIndentMore: "Увеличить отступ", + sqlFormatterShortcutIndentLess: "Уменьшить отступ", + sqlFormatterShortcutDuplicateLine: "Дублировать текущую строку", + sqlFormatterShortcutDeleteLine: "Удалить текущую строку", + sqlFormatterShortcutMoveLine: "Переместить строку", + sqlFormatterShortcutMoveLineUp: "Переместить строку вверх", + sqlFormatterShortcutMoveLineDown: "Переместить строку вниз", + sqlFormatterShortcutCopyLine: "Копировать строку", + sqlFormatterShortcutCopyLineUp: "Копировать строку вверх", + sqlFormatterShortcutCopyLineDown: "Копировать строку вниз", + sqlFormatterShortcutUndo: "Отменить", + sqlFormatterShortcutRedo: "Повторить", + sqlFormatterShortcutSelectAll: "Выбрать все", + sqlFormatterShortcutFormatJson: "Форматировать JSON", + sqlFormatterShortcutApply: "Применить конфигурацию", + sqlFormatterConfigErrorInvalidJson: "Неверный JSON.", + sqlFormatterConfigErrorObject: "Конфигурация должна быть объектом JSON.", + sqlFormatterConfigErrorVersion: "Неподдерживаемая версия конфигурации.", + sqlFormatterConfigErrorFormatter: "Неподдерживаемый форматировщик.", + sqlFormatterConfigErrorUnsupportedParams: "Параметр замены параметров не поддерживается. Форматирование SQL не будет заменять заполнители.", + sqlFormatterConfigErrorOptionsObject: "Параметры конфигурации должны быть объектом JSON.", + sqlFormatterConfigErrorEditorObject: "Конфигурация редактора должна быть объектом JSON.", + sqlFormatterConfigErrorEditorScope: "Неподдерживаемая область редактора.", + sqlFormatterConfigErrorEditorPlatforms: "Неверные платформы редактора.", + sqlFormatterConfigErrorEditorShortcutsArray: "Сочетания клавиш редактора должны быть массивом.", + sqlFormatterConfigErrorEditorShortcutValue: "Неверное сочетание клавиш редактора.", + sqlFormatterConfigErrorUnknownOption: "Неизвестный параметр форматировщика: {option}.", + sqlFormatterConfigErrorInvalidOptionValue: "Неверное значение для {option}.", + sqlFormatterConfigErrorUnknownEditorShortcut: "Неизвестное сочетание клавиш редактора: {shortcut}.", + sqlFormatterConfigErrorInvalidEditorShortcut: "Неверное сочетание клавиш редактора: {shortcut}.", + sqlFormatterConfigErrorDuplicateEditorShortcut: "Дублирующееся сочетание клавиш редактора: {shortcut}.", + sqlFormatterConfigErrorInvalidConfig: "Неверная конфигурация форматировщика.", + appearanceTab: "Внешний вид", + navigationTab: "Навигация", + dataTab: "Данные", + sqlFileSection: "Файлы SQL", + tunnelsTab: "Туннели", + tunnelsDescription: "Многоразовые конфигурации туннелей SSH / прокси / HTTP. Настройте один раз, затем выберите профиль на вкладке туннеля подключения; изменения здесь применяются ко всем подключениям, использующим профиль.", + tunnelsEmpty: "Профилей туннелей пока нет. Создайте здесь, затем выберите его в настройках туннеля подключения.", + tunnelsAddSsh: "Добавить SSH", + tunnelsAddProxy: "Добавить прокси", + tunnelsAddHttp: "Добавить туннель HTTP", + tunnelsProfileName: "Имя профиля", + tunnelsProfileNamePlaceholder: "напр. Офисный бастион", + tunnelsDelete: "Удалить", + tunnelsUnnamedProfile: "Профиль без имени", + tunnelsSave: "Сохранить", + tunnelsReset: "Сбросить", + tunnelsSaved: "Профили туннелей сохранены", + tunnelsSaveFailed: "Не удалось сохранить профили туннелей: {message}", + tunnelsUnsavedHint: "Несохранённые изменения", + tunnelsTest: "Проверить", + tunnelsTesting: "Проверка...", + tunnelsTestSuccess: "Проверка туннеля успешна", + tunnelsTestFailed: "Проверка туннеля не удалась: {message}", + tunnelsHttpTestSuccess: "Подключение к прокси HTTP CONNECT успешно ({code})", + tunnelsSocks5TestSuccess: "Подключение к прокси SOCKS5 успешно", + tunnelsProxyHostRequired: "Требуется хост прокси.", + tunnelsProxyPortRequired: "Требуется порт прокси.", + tunnelsSshHostRequired: "Требуется хост SSH.", + tunnelsHttpTunnelUnsupported: "Проверка туннеля не поддерживается для профилей туннелей HTTP.", + tunnelsProxyTimedOut: "Таймаут подключения к прокси ({duration})", + tunnelsProxyConnectFailed: "Не удалось подключиться к прокси: {error}", + tunnelsProxyHandshakeFailed: "Сбой рукопожатия с прокси: {error}", + tunnelsProxyHandshakeTimedOut: "Таймаут рукопожатия с прокси ({duration})", + tunnelsHttpConnectFailed: "Сбой CONNECT прокси HTTP: {detail}", + tunnelsSocksInvalidVersion: "Неверная версия прокси SOCKS: {version}", + tunnelsSocksAuthTooLong: "Имя пользователя или пароль SOCKS слишком длинные", + tunnelsSocksAuthFailed: "Сбой аутентификации на прокси SOCKS", + tunnelsSocksAuthRejected: "Прокси SOCKS отклонил все поддерживаемые методы аутентификации", + tunnelsSocksUnsupportedAuth: "Прокси SOCKS выбрал неподдерживаемый метод аутентификации: {method}", + tunnelsSocksHostTooLong: "Хост прокси слишком длинный для доменного адреса SOCKS5", + tunnelsSocksConnectRejected: "Подключение через прокси SOCKS отклонено (код {code})", + tunnelsSocksUnsupportedAddrType: "Неподдерживаемый тип связанного адреса SOCKS: {type}", + redisTab: "Redis", + shortcutsTab: "Сочетания клавиш", + snippetsTab: "Сниппеты", + syncTab: "Синхронизация", + aiTab: "AI", + aiSkillRoot: "Пользовательский каталог навыков", + aiSkillRootDesc: "Сканировать дополнительный каталог на наличие навыков SKILL.md. Каталог ~/.agents/skills сканируется всегда.", + aiSkillRootPath: "Путь к каталогу", + aiSkillRootBrowse: "Обзор", + mcpTab: "MCP", + jdbcTab: "Драйверы JDBC", + securityTab: "Безопасность", + aboutTab: "О программе", + fontFamily: "Семейство шрифтов", + dataGridFontFamily: "Шрифт таблицы результатов", + dataGridFontFamilyDescription: "Применяется к результатам запросов, данным таблиц, заголовкам столбцов и встроенным редакторам ячеек.", + uiFontFamily: "Шрифт интерфейса", + uiFontAppDefault: "По умолчанию DBX", + uiFontSystemDefault: "Системный по умолчанию", + uiFontFamilyDescription: "Применяется к элементам интерфейса приложения, таким как панель инструментов, вкладки, боковая панель, диалоги и другие элементы вне редактора.", + selectFont: "Выбрать шрифт...", + searchFont: "Поиск шрифтов...", + loadingFonts: "Загрузка шрифтов...", + noFontsFound: "Шрифты не найдены", + useCustomFont: "Использовать «{font}»", + languageTitle: "Язык / 语言", + fontSize: "Размер шрифта", + toolbarTitle: "Панель инструментов", + toolbarHiddenHint: "Некоторые скрытые или не поместившиеся кнопки отображаются в раскрывающемся меню «Ещё».", + exclusiveRightSidebarPanels: "Показывать по одной панели правой боковой панели за раз", + exclusiveRightSidebarPanelsDescription: "Открытие панели правой боковой панели закрывает остальные. Отключите, чтобы разрешить несколько панелей.", + uiScale: "Масштаб интерфейса", + uiScaleDescription: "Масштабировать весь интерфейс приложения для дисплеев с высоким DPI. Изменения применяются сразу и восстанавливаются при следующем запуске.", + theme: "Тема", + cornerStyle: "Стиль углов", + backgroundImage: "Фоновое изображение", + backgroundImageDescription: "Установить изображение за всем приложением. Карточки и диалоги остаются непрозрачными для читаемости.", + backgroundImageChoose: "Выбрать изображение…", + backgroundImageClear: "Очистить", + backgroundImageNone: "Изображение не задано", + backgroundImageTransparency: "Прозрачность", + backgroundImageDisplayMode: "Режим отображения", + backgroundImageModeFill: "Заполнение", + backgroundImageModeFit: "Вписать", + backgroundImageModeStretch: "Растянуть", + backgroundImageModeCenter: "По центру", + backgroundImageModeTile: "Мозаика", + backgroundImageBlur: "Размытие", + backgroundImageMissing: "Файл изображения больше не существует. Выберите его снова.", + backgroundImageTooLarge: "Изображение превышает ограничение в 20 МБ.", + backgroundImageSaveFailed: "Не удалось сохранить фоновое изображение.", + backgroundImageFilterName: "Изображение", + cornerStyleNone: "Прямые", + cornerStyleSmall: "Малые", + cornerStyleLarge: "Большие", + selectTheme: "Выбрать тему...", + colorTheme: "Цветовая тема", + selectColorTheme: "Выбрать цветовую тему...", + themePalettePearl: "Белый", + themePaletteMist: "Туманно-серый", + themePaletteGraphite: "Титаново-серый", + themePaletteCobalt: "Кобальтово-синий", + themePaletteSage: "Шалфейно-зелёный", + themePaletteAmber: "Тёплый жёлтый", + themePaletteBlush: "Сакура-розовый", + themePaletteVscode: "VS Code", + themePaletteIdea: "IDEA", + themePaletteXcode: "Xcode", + themePaletteJetbrains: "JetBrains", + themePaletteCursor: "Cursor", + themePaletteClaude: "Claude Code", + themePaletteCustom: "Своя", + customUiReset: "Сбросить к значениям по умолчанию", + customUiEditingLight: "Редактирование цветов светлого режима", + customUiEditingDark: "Редактирование цветов тёмного режима", + customUiBackground: "Фон", + customUiForeground: "Передний план", + customUiPrimary: "Основной", + customUiBorder: "Граница", + customUiSidebar: "Боковая панель", + followAppTheme: "Следовать теме приложения", + appLayout: "Макет интерфейса", + appLayoutSeparated: "Современный разделённый", + appLayoutSeparatedDescription: "Чёткое разделение панелей с блочными вкладками.", + appLayoutClassic: "Классический компактный", + appLayoutClassicDescription: "Непрерывная панель вкладок с компактными заголовками панелей.", + tabLayout: "Переполнение панели вкладок", + tabLayoutScroll: "Прокрутка в одну строку", + tabLayoutScrollDescription: "При переполнении вкладки прокручиваются горизонтально в одну строку.", + tabLayoutWrap: "Перенос на несколько строк", + tabLayoutWrapDescription: "Вкладки переносятся на несколько строк, показывая все сразу.", + tabPlacement: "Расположение панели вкладок", + tabPlacementTop: "Сверху", + tabPlacementBottom: "Снизу", + tabPlacementLeft: "Слева", + tabPlacementRight: "Справа", + tabPlacementDescription: "Боковые панели вкладок прокручиваются вертикально; перенос на несколько строк применяется только сверху или снизу от содержимого.", + tabOrganization: "Расположение, группировка, сортировка", + tabGroup: "Группировать по", + tabGroupNone: "Без группировки", + tabGroupDatabaseType: "Группировать по типу базы данных", + tabGroupDatabase: "Группировать по базе данных", + tabGroupConnection: "Группировать по подключению", + tabSort: "Сортировать по", + tabSortManual: "Ручной порядок", + tabSortCreated: "Время создания", + tabSortTitle: "Имя вкладки", + tabOrganizationDescription: "Группировка и сортировка влияют только на отображаемый порядок. Перетаскивание доступно при ручном порядке.", + iconTheme: "Стиль значка и логотипа", + iconThemeDefault: "По умолчанию", + iconThemeDefaultDescription: "Использовать цветной значок приложения DBX.", + iconThemeBlack: "Чёрный", + iconThemeBlackDescription: "Использовать чёрный логотип DBX в приложении.", + iconThemeBlackDescriptionMac: "Использовать чёрный логотип в приложении; Dock использует чёрную пластину, строка меню следует системе.", + showTrayIcon: "Показывать значок в трее/строке меню", + showTrayIconDescription: "Если отключено, значок не отображается, но закрытие окна по-прежнему скрывает DBX в фоне, как и раньше.", + quitOnClose: "Выходить при закрытии окна", + quitOnCloseDescription: "Если включено, нажатие кнопки закрытия полностью завершает DBX вместо сворачивания в трей. Это можно изменить позже в настройках внешнего вида.", + closeActionPromptTitle: "Закрытие окна", + closeActionPromptDescription: "Выберите, что происходит при нажатии кнопки закрытия. Это можно изменить позже в разделе «Настройки > Внешний вид».", + closeActionQuit: "Завершить DBX", + closeActionMinimize: "Свернуть в трей", + updateNotificationsEnabled: "Включить напоминания об обновлениях", + updateNotificationsEnabledDescription: "Автоматически проверять обновления приложения и компонентов и показывать напоминания. Страница обновлений определяет, устанавливается ли каждая категория автоматически.", + autoDownloadUpdates: "Автоматически скачивать обновления приложения", + autoDownloadUpdatesDescription: "Устаревшая настройка совместимости. Теперь она повторяет «Автоматически обновлять DBX» на странице обновлений. Установка по-прежнему требует подтверждения.", + updatesTab: "Управление обновлениями", + updatesDescription: "Управляйте обновлениями приложения, драйверов баз данных, JDBC, сервера MCP и плагинов в одном месте.", + autoUpdateApp: "Автоматически обновлять DBX", + autoUpdateAppDescription: "Скачивать новые версии DBX в фоне. Вы выбираете, когда перезапустить и установить.", + autoUpdateDrivers: "Автоматически обновлять драйверы баз данных", + autoUpdateDriversDescription: "После перезапуска DBX установить доступные обновления драйверов, когда их не блокирует активное подключение.", + autoUpdateJdbc: "Автоматически обновлять JDBC", + autoUpdateJdbcDescription: "После перезапуска DBX автоматически обновлять среду выполнения плагина JDBC.", + autoUpdateMcp: "Автоматически обновлять MCP", + autoUpdateMcpDescription: "После перезапуска DBX обновлять управляемый DBX MCP Server при наличии более новой версии.", + autoUpdatePlugins: "Автоматически обновлять плагины", + autoUpdatePluginsDescription: "После перезапуска DBX устанавливать подписанные обновления плагинов из магазина.", + autoUpdate: "Автообновление", + updateStatusTitle: "Состояние обновлений", + updateStatusDescription: "Просмотрите состояние обновления каждого компонента и выберите, обновляется ли он автоматически.", + checkUpdates: "Проверить сейчас", + updateAll: "Обновить все", + updateClient: "DBX", + updateDrivers: "Драйверы баз данных", + updateJdbc: "JDBC", + updateMcp: "MCP", + updatePlugins: "Плагины", + updateAvailable: "Доступно обновление", + updateCount: "Доступно: {count}", + upToDate: "Актуально", + openDriverManager: "Открыть менеджер драйверов", + openPluginCenter: "Открыть центр плагинов", + openMcpSettings: "Открыть настройки MCP", + updateRestartHint: "Обновления компонентов выполняются после успешного перезапуска DBX при обновлении. Активные подключения могут отложить обновления драйверов до безопасного момента.", + updateDownloadSource: "Источник загрузки обновлений", + updateDownloadSourceDescription: "Выберите, откуда скачиваются обновления приложения, агенты баз данных, драйверы и управляемые JRE. Рекомендуется официальный источник; CNB может быть быстрее в сетях материкового Китая.", + updateDownloadSourceOfficial: "Официальный источник (рекомендуется)", + updateDownloadSourceCnb: "CNB", + debugLoggingEnabled: "Включить отладочные журналы", + debugLoggingEnabledDescription: "Записывать более подробные локальные диагностические журналы на стороне пользователя при устранении неполадок. По умолчанию отключено.", + metadataCacheMemoryLimit: "Лимит кэша метаданных в памяти", + metadataCacheMemoryLimitDescription: "По умолчанию 64 МБ. По возможности держите не выше 256 МБ; жёсткий лимит — 512 МБ. Охватывает DDL, столбцы, индексы, внешние ключи, триггеры и комментарии.", + duckDbWorkerProcessIsolation: "Режим изоляции процессов DuckDB (экспериментально)", + duckDbWorkerProcessIsolationDescription: "Выполняет запросы DuckDB в отдельном рабочем процессе. Если длительный запрос не реагирует на отмену, DBX может остановить рабочий процесс, чтобы освободить блокировку файла базы данных.", + duckDbWorkerMaxProcesses: "Максимум одновременных рабочих процессов DuckDB", + duckDbWorkerMaxProcessesDescription: "Ограничивает число рабочих процессов DuckDB, которые DBX может запускать одновременно. Диапазон: 1-16. По умолчанию: 4.", + duckDbWorkerProcessIsolationRestartRequired: "Перезапустите DBX, чтобы изменение вступило в силу.", + restartDbx: "Перезапустить DBX", + restartDbxFailed: "Не удалось перезапустить DBX: {error}", + applyFailed: "Не удалось применить настройки: {error}", + unsavedChangesCloseTitle: "Несохранённые изменения", + unsavedChangesCloseMessage: "У вас есть несохранённые изменения настроек, которые будут потеряны при закрытии. Отменить эти изменения?", + unsavedChangesCloseCancel: "Продолжить редактирование", + unsavedChangesCloseDiscard: "Отменить изменения", + debugLogsCopy: "Копировать журналы", + debugLogsCopied: "Скопировано", + debugLogsDownload: "Скачать журналы", + debugLogsDownloaded: "Скачано", + debugLogsClear: "Очистить журналы", + tableStructureSection: "Структура таблицы", + dataGridDisplay: "Отображение таблицы данных", + dataGridToolbarLayout: "Макет панели инструментов таблицы данных", + dataGridToolbarLayoutDescription: "Выберите отдельные строки для панели действий и элементов фильтрации/сортировки или восстановите исходный однострочный макет.", + dataGridToolbarLayoutSplit: "Отдельные строки (действия и фильтры раздельно)", + dataGridToolbarLayoutSingle: "Одна строка (исходный макет)", + dataGridFilterView: "Вид фильтра таблицы", + dataGridFilterViewDescription: "Используйте всплывающее окно фильтра, фиксированную панель условий или компактную текстовую панель условий.", + dataGridKeepFilterEditorExpanded: "Держать редактор фильтра развёрнутым", + dataGridKeepFilterEditorExpandedDescription: "Всегда держать редактор развёрнутым в видах «Условия» и «Текст».", + dataGridFilterViewPreview: "Предпросмотр результата", + dataGridFilterViewPreviewExpand: "Развернуть предпросмотр", + dataGridFilterViewPreviewCollapse: "Свернуть предпросмотр", + tableOpenPageSize: "Строк на странице по умолчанию при открытии таблиц", + tableOpenPageSizeDescription: "Строк загружается на страницу при открытии новой таблицы. Временные изменения не обновляют это значение по умолчанию; это делает только выбор «Задать по умолчанию».", + queryPageSize: "Строк на страницу запроса по умолчанию", + queryPageSizeDescription: "Строк загружается на страницу результата запроса. Максимальный поддерживаемый размер страницы — {max}.", + defaultAutoKeepResults: "Автосохранение результатов запроса по умолчанию", + defaultAutoKeepResultsDescription: "Применение этой настройки обновляет открытые вкладки запросов и задаёт значение по умолчанию для новых. Переключать её для каждой вкладки всё равно можно.", + multiStatementDefaultView: "Вид по умолчанию для нескольких операторов", + multiStatementDefaultViewDescription: "Выберите, открывать пакеты с несколькими SQL-операторами в таблице результатов или в сводке выполнения.", + queryResultMaxRows: "Максимум строк результата запроса", + queryResultMaxRowsEnabled: "Ограничить строки результата запроса", + queryResultMaxRowsDescription: "Ограничивает строки, возвращаемые запросами, данными таблиц, хранимыми процедурами и непрерывной загрузкой.", + queryResultMaxRowsTooSmall: "Должно быть не меньше размера страницы запроса ({pageSize}).", + externalSqlEditorMaxMb: "Максимальный размер файла в SQL-редакторе", + externalSqlEditorMaxMbDescription: "Файлы SQL больше этого размера открываются в диалоге потокового выполнения SQL-файла вместо редактора ({min}–{max} МБ).", + webSqlFileUploadMaxMb: "Максимальный размер загружаемого SQL-файла в веб-режиме", + webSqlFileUploadMaxMbDescription: "Наибольший SQL-файл, принимаемый веб-сервером для потокового выполнения ({min}–{max} МБ).", + sqlFileUploadMaxMbSaved: "Размер загрузки SQL-файла в веб-режиме сохранён.", + showColumnCommentsInHeader: "Показывать комментарии столбцов под именами", + showColumnCommentsInHeaderDescription: "Показывать комментарии столбцов таблицы непосредственно под именами столбцов сетки.", + showColumnTypesInHeader: "Показывать типы столбцов под именами", + showColumnTypesInHeaderDescription: "Показывать тип данных каждого столбца непосредственно под именами столбцов сетки.", + dataGridShowTransposeFieldMetadata: "Показывать метаданные поля в транспонированном виде", + dataGridShowTransposeFieldMetadataDescription: "Показывать включённые типы столбцов и комментарии отдельными строками в транспонированном виде. Это увеличивает высоту строк.", + colorizeDataGridCellTypes: "Раскрашивать значения сетки данных по типам", + colorizeDataGridCellTypesDescription: "Использовать приглушённые цвета текста, соответствующие теме, чтобы различать значения по типу данных столбца.", + dataGridTypeColorScheme: "Цветовая схема типов данных", + dataGridTypeColorSchemeDescription: "Выберите палитру, которой сетка раскрашивает значения по типу данных.", + dataGridTypeColorSchemeConfigure: "Настроить", + dataGridTypeColorSchemeTitle: "Цвета типов данных", + dataGridTypeColorSchemeAuto: "Как в теме", + dataGridTypeColorSchemeAutoHint: "Используются встроенные цвета с автоматическим переключением между светлой и тёмной палитрой.", + dataGridTypeColorSchemeCreateFromCurrent: "Создать схему из этих цветов", + dataGridTypeColorSchemeAdd: "Новая схема", + dataGridTypeColorSchemeDuplicate: "Дублировать схему", + dataGridTypeColorSchemeRename: "Переименовать схему", + dataGridTypeColorSchemeRenameConfirm: "Переименовать", + dataGridTypeColorSchemeDelete: "Удалить схему", + dataGridTypeColorSchemeReset: "Сбросить цвета", + dataGridTypeColorSchemeDone: "Готово", + dataGridTypeColorSchemeDefaultName: "Цветовая схема", + dataGridTypeColorSchemeCopySuffix: " копия", + dataGridTypeColorInteger: "Целое", + dataGridTypeColorNumeric: "Десятичное", + dataGridTypeColorString: "Текст", + dataGridTypeColorBoolean: "Логическое", + dataGridTypeColorTemporal: "Дата и время", + dataGridTypeColorStructured: "Структурированное", + dataGridTypeColorIdentifier: "Идентификатор", + dataGridTypeColorBinary: "Бинарное", + dataGridTypeColorSpatial: "Пространственное", + showIndexIndicatorsInHeader: "Показывать индикаторы индексов рядом с именами столбцов", + showIndexIndicatorsInHeaderDescription: "Показывать значками тип индекса каждого столбца в заголовке сетки: первичный ключ (оранжевый), уникальный индекс (красный), обычный индекс (зелёный).", + compactColumnHeaderActions: "Компактные инструменты заголовка столбца", + compactColumnHeaderActionsDescription: "Перенести инструменты форматирования и локального фильтра в меню «ещё», чтобы имена столбцов были приоритетнее.", + dataGridQuickEntry: "Быстрый ввод в сетке", + dataGridQuickEntryDescription: "Если включено, изменение ячейки или заполнение нижней пустой строки сохраняется в базу данных сразу при потере фокуса. Удобно при частом вводе, но может привести к случайной записи.", + dataGridAutoTransposeSingleRow: "Автоматически транспонировать результаты запроса с одной строкой", + dataGridAutoTransposeSingleRowDescription: "Если включено, результаты SQL-запроса ровно с одной строкой и несколькими столбцами автоматически открываются в транспонированном виде.", + dataGridCellDetailButtonVisible: "Показывать кнопку подробностей ячейки", + dataGridCellDetailButtonVisibleDescription: "Показывать кнопку подробностей при наведении на ячейку.", + dataGridCrosshairHighlight: "Подсветка строки и столбца перекрестием", + dataGridCrosshairHighlightDescription: "Если включено, слегка подсвечиваются вся строка и столбец активной ячейки (как в Excel). Ячейка в фокусе сохраняет свой выделенный стиль.", + infiniteScroll: "Бесконечная прокрутка с подгрузкой", + autoCalculateTotalRows: "Автоматически считать общее число строк", + autoCalculateTotalRowsDescription: "Автоматически выполнять COUNT(*) после каждого запроса, чтобы показать общее число подходящих строк. По умолчанию выключено, чтобы большие запросы оставались быстрыми — счёт можно запустить вручную из нижней панели результатов.", + infiniteScrollDescription: "Автоматически загружать следующую порцию при прокрутке до конца.", + dataGridShowWhitespace: "Показывать пробельные символы", + dataGridShowWhitespaceDescription: "Показывать пробелы как ·, а табуляции как → в ячейках данных. Копируемые и редактируемые значения не меняются.", + flatteningMultiLineText: "Объединение многострочного текста", + flatteningMultiLineTextDescription: "Многострочный текст отображается одной строкой, переносы строк показаны как ¶ .", + regexMaxMatchCount: "Максимум совпадений при выборе всех", + regexMaxMatchCountDescription: "Ограничивает число выделений, создаваемых командой «Выделить все совпадения»; подсчёт совпадений при поиске остаётся полным (100–10000).", + tableColumnTemplateFields: "Предустановленные поля новой таблицы", + tableColumnTemplateFieldsDescription: "Выберите тип базы данных, затем настройте предустановленные типы полей, используемые при создании новых таблиц.", + tableColumnTemplateAdd: "Добавить поле", + tableColumnTemplateColumn: "Поле", + tableColumnTemplateDatabase: "База данных", + tableColumnTemplateType: "Тип", + tableColumnTemplateLength: "Длина", + tableColumnTemplateDefault: "По умолчанию", + tableColumnTemplateNoPresetType: "Без предустановленного типа", + tableColumnTemplateRequired: "Обязательное", + tableColumnTemplateComment: "Описание", + tableColumnTemplateDragHandle: "Перетащите для изменения порядка", + sidebarActivation: "Активация в боковой панели", + sidebarActivationSingle: "Один клик", + sidebarActivationSingleDescription: "Открывать активные элементы боковой панели одним кликом.", + sidebarActivationDouble: "Двойной клик", + sidebarActivationDoubleDescription: "Один клик выделяет строки; двойной клик открывает элементы.", + sidebarObjectDisplay: "Расположение объектов в боковой панели", + sidebarObjectDisplayGrouped: "Расширенный вид", + sidebarObjectDisplayGroupedDescription: "Группировать объекты по таблицам, представлениям, процедурам и функциям для баз данных с большим числом типов объектов.", + sidebarObjectDisplaySimple: "Простой вид", + sidebarObjectDisplaySimpleDescription: "Показывать таблицы и представления сразу под каждой базой данных или схемой, чтобы уменьшить число уровней.", + routineSourceOpenMode: "Режим открытия функций / процедур / представлений", + routineSourceOpenModeQueryTab: "Вкладка данных", + routineSourceOpenModeQueryTabDescription: "Открывать исходный код в новой вкладке данных, как при выполнении SQL-запросов.", + routineSourceOpenModeDialog: "Диалоговое окно", + routineSourceOpenModeDialogDescription: "Открывать исходный код во всплывающем диалоге для быстрого просмотра и редактирования.", + autoSelectActiveSidebarNode: "Всегда выделять открытый элемент", + autoSelectActiveSidebarNodeDescription: "При переключении вкладок выделять соответствующую видимую таблицу, коллекцию или SQL-файл в боковой панели.", + sidebarBrowseObjectsOnDatabaseActivation: "Просматривать объекты при активации базы данных", + sidebarBrowseObjectsOnDatabaseActivationDescription: "Если включено, активация узла базы данных или схемы выбранным режимом (один или двойной клик) также открывает вкладку «Просмотр объектов».", + openTabsRestoreMode: "Восстанавливать вкладки при запуске", + openTabsRestoreModeDescription: "Выберите, как DBX восстанавливает вкладки, открытые в прошлый раз.", + openTabsRestoreModeAll: "Сохранять все вкладки", + openTabsRestoreModePinned: "Сохранять только закреплённые вкладки", + openTabsRestoreModeNone: "Не сохранять вкладки", + openTabsRestoreModeHint: "Закреплённые вкладки остаются слева на панели вкладок и удобны как точки частого доступа.", + disconnectTabHandlingMode: "Вкладки после отключения", + disconnectTabHandlingModeDescription: "Выберите, что делать со связанными вкладками после закрытия подключения или базы данных.", + disconnectTabHandlingModeCloseTabs: "Закрывать все вкладки", + disconnectTabHandlingModeCloseTabsDescription: "Закрывать все связанные вкладки подключения или базы данных.", + disconnectTabHandlingModeKeepTabsClearResults: "Закрывать вкладки объектов, сохранять вкладки SQL", + disconnectTabHandlingModeKeepTabsClearResultsDescription: "Закрывать вкладки данных таблиц, просмотра объектов и структуры, сохраняя вкладки SQL-запросов и текст SQL, а также сбрасывать состояние выполнения и сеансы результатов.", + disconnectTabHandlingModeKeepTabsKeepResults: "Не закрывать связанные вкладки", + disconnectTabHandlingModeKeepTabsKeepResultsDescription: "Сохранять связанные вкладки, текст SQL и текущие результаты без дополнительной очистки.", + deleteConnectionTabHandlingMode: "Вкладки после удаления подключения", + deleteConnectionTabHandlingModeDescription: "Выберите, что делать со связанными вкладками после удаления подключения. Удалённое подключение нельзя восстановить, поэтому сохранённые вкладки SQL — лишь временные рабочие области.", + deleteConnectionTabHandlingModeCloseTabs: "Закрывать все вкладки", + deleteConnectionTabHandlingModeCloseTabsDescription: "Закрывать все вкладки, принадлежащие удалённому подключению.", + deleteConnectionTabHandlingModeKeepSqlTabs: "Сохранять все вкладки SQL", + deleteConnectionTabHandlingModeKeepSqlTabsDescription: "Закрывать вкладки таблиц, просмотра объектов и структуры, сохраняя все вкладки SQL этого подключения (закреплённые или нет) и их текст SQL, а также сбрасывать состояние выполнения и результаты.", + deleteConnectionTabHandlingModeKeepPinnedSqlTabs: "Сохранять закреплённые вкладки SQL", + deleteConnectionTabHandlingModeKeepPinnedSqlTabsDescription: "Сохранять только закреплённые вкладки SQL; все остальные вкладки, включая незакреплённые вкладки SQL, закрываются.", + deleteConnectionTabHandlingModeKeepAllTabs: "Сохранять все вкладки", + deleteConnectionTabHandlingModeKeepAllTabsDescription: "Ничего не закрывать и сохранять текст SQL и текущие результаты. Открытые транзакции откатываются, так как подключение потеряно.", + rememberConnectionDatabaseOnDelete: "Запоминать имена подключений и баз данных", + rememberConnectionDatabaseOnDeleteDescription: "Запоминать имя и базу данных подключения при его удалении и подставлять их при повторном создании подключения с тем же именем.", + rememberConnectionDatabaseOnDeleteHint: "Если включено, при создании подключения с тем же именем и типом базы данных эта база подставляется, а сохранённые вкладки SQL автоматически привязываются к новому подключению.", + rememberedConnectionDatabaseCount: "Сохранённых записей: {count}", + clearRememberedConnectionDatabases: "Очистить сохранённые записи", + reuseDataTab: "Переиспользовать вкладку данных", + reuseDataTabDescription: "Выберите, как открытие таблицы использует вкладки данных.", + openDataTabsNextToActive: "Открывать новые вкладки данных рядом с активной", + openDataTabsNextToActiveDescription: "Размещать новые вкладки данных таблиц сразу после активной вкладки.", + dataTabReuseAlwaysNew: "Всегда открывать новую вкладку", + dataTabReuseAlwaysNewDescription: "Каждый раз создавать новую вкладку данных, даже если таблица уже открыта.", + dataTabReuseSameTable: "Переиспользовать вкладку той же таблицы", + dataTabReuseSameTableDescription: "Переключаться на существующую вкладку той же таблицы, а разные таблицы открывать отдельно.", + dataTabReuseActiveTab: "Переиспользовать активную вкладку данных", + dataTabReuseActiveTabDescription: "Переиспользовать активную безопасную вкладку данных для другой таблицы; защищённые вкладки открываются отдельно.", + sidebarHiddenTablePrefixes: "Скрытые префиксы имён таблиц", + sidebarHiddenTablePrefixesDescription: "Один префикс на строку. Сокращаются только подписи таблиц, представлений и коллекций в боковой панели; подсказки и действия по-прежнему используют полное имя.", + sidebarHiddenTablePrefixesPlaceholder: "Пример:\nODS_\nT8Y2_LONG_", + sidebarCopyTableNameSeparator: "Разделитель имён таблиц при копировании", + sidebarCopyTableNameSeparatorDescription: "Разделитель, используемый при копировании или перетаскивании нескольких имён таблиц или столбцов из боковой панели в SQL-редактор.", + sidebarCopyTableNameIncludeSchema: "Включать схему в копируемые имена таблиц", + sidebarCopyTableNameIncludeSchemaDescription: "Если включено, копируемые или перетаскиваемые имена таблиц используют форму с указанием схемы и правилами кавычек идентификаторов активного подключения.", + sidebarTablePageSize: "Размер страницы боковой панели", + sidebarTablePageSizeDescription: "Максимальное число таблиц/объектов, загружаемых на страницу в дереве боковой панели. Увеличьте, если у вас много таблиц и нужно меньше страниц.", + sidebarTableSearchEnabled: "Включить поиск таблиц внутри баз данных", + sidebarTableSearchEnabledDescription: "Показывать поле локального поиска таблиц под развёрнутыми базами данных, схемами или группами таблиц, чтобы в каждой области можно было фильтровать таблицы независимо.", + sidebarObjectInfoMode: "Дополнительная информация в боковой панели", + sidebarObjectInfoModeDescription: + "Выберите комментарии, размеры объектов или отсутствие дополнительного текста после имён. Комментарии и размеры взаимоисключающи. Итоги по базе данных сейчас поддерживаются в PostgreSQL; размеры таблиц поддерживаются в MySQL, PostgreSQL, GaussDB, KingbaseES, GBase 8a, SQL Server, Oracle, Dameng и ClickHouse.", + sidebarObjectInfoModeCommentInline: "Комментарии (после имени)", + sidebarObjectInfoModeCommentAligned: "Комментарии (выравнивать соседей)", + sidebarObjectInfoModeCommentRight: "Комментарии (по правому краю)", + sidebarObjectInfoModeSize: "Размер объекта", + sidebarObjectInfoModeHidden: "Нет", + sidebarAllowHorizontalScroll: "Разрешить горизонтальную прокрутку боковой панели", + sidebarAllowHorizontalScrollDescription: "Показывать длинные имена таблиц, представлений и коллекций полностью, разрешив горизонтальную прокрутку боковой панели.", + sidebarShowTooltips: "Подсказки при наведении в боковой панели", + sidebarShowTooltipsDescription: "Показывать подробные подсказки при наведении на подключения и объекты базы данных в боковой панели. Отключите, чтобы убрать всплывающие подсказки.", + sidebarIndent: "Отступ боковой панели", + sidebarIndentDescription: "Горизонтальный отступ, добавляемый на каждый уровень глубины дерева, в пикселях.", + sidebarFontSize: "Размер шрифта боковой панели", + sidebarFontSizeDescription: "Размер шрифта дерева объектов боковой панели в пикселях. Не зависит от размера шрифта редактора.", + snippetsDescription: "Настройка шаблонов SQL-сниппетов, вызываемых в редакторе.", + snippetsPlaceholderHint: "Используйте {'${number:default text}'} для создания редактируемого заполнителя. Заполнители с одинаковым номером остаются связанными; например:", + snippetsAdd: "Добавить сниппет", + snippetsLabel: "Название", + snippetsPrefix: "Префикс", + snippetsStatus: "Статус", + snippetsEnabled: "Включён", + snippetsDisabled: "Отключён", + snippetsToggle: "Включить или отключить сниппет", + snippetsBody: "Тело SQL", + snippetsLabelPlaceholder: "напр. select *", + snippetsPrefixPlaceholder: "напр. sel", + snippetsBodyPlaceholder: "SELECT *\nFROM table\nLIMIT 100;", + snippetsRestoreDefaults: "Восстановить значения по умолчанию", + snippetsAddTitle: "Добавить сниппет", + snippetsEditTitle: "Изменить сниппет", + sqlShortcutsTitle: "Быстрые действия SQL", + sqlShortcutsDescription: "Встроенные шаблоны и пользовательские действия SQL после выделения имени таблицы в SQL-редакторе (кроме Redis/Mongo/ES). По умолчанию включены первые N строк и подсчёт.", + sqlShortcutsAdd: "Добавить", + sqlShortcutsAddTitle: "Добавить быстрое действие SQL", + sqlShortcutsEditTitle: "Изменить быстрое действие SQL", + sqlShortcutsLabel: "Название", + sqlShortcutsLabelPlaceholder: "напр. Подсчёт строк", + sqlShortcutsLabelRequired: "Укажите название.", + sqlShortcutsSql: "Шаблон SQL", + sqlShortcutsSqlPlaceholder: "SELECT COUNT(*) FROM ${table}", + sqlShortcutsSqlDatabase: "Изменить для базы данных", + sqlShortcutsApplySqlToAllSelected: "Применить ко всем выбранным", + sqlShortcutsApplySqlToAllSelectedDone: "Применено ко всем выбранным базам данных.", + sqlShortcutsVariableHint: "Используйте {token} для имени выбранной таблицы.", + sqlShortcutsEmpty: "Быстрых действий SQL пока нет.", + sqlShortcutsUnbound: "Не привязано", + sqlShortcutsToggle: "Включить или отключить действие SQL", + sqlShortcutsDeleteConfirm: 'Удалить действие SQL "{name}"?', + sqlShortcutsBuiltinDeleteBlocked: "Встроенные шаблоны нельзя удалить. Вместо этого отключите их.", + sqlShortcutBuiltinSelectLimit: "Выбрать первые N строк", + sqlShortcutBuiltinCount: "Подсчитать строки", + sqlShortcutsSource: "Тип", + sqlShortcutsSourceBuiltin: "Встроенное", + sqlShortcutsSourceCustom: "Пользовательское", + sqlShortcutsKind: "Тип действия", + sqlShortcutsKindTemplate: "Шаблон SQL", + sqlShortcutsKindTemplateHint: "Выполнять собственный SQL с ${table}.", + sqlShortcutsKindSelectLimit: "Выбрать первые N строк", + sqlShortcutsKindSelectLimitHint: "Автоматически подбирает LIMIT / TOP / ROWNUM для текущей базы данных.", + sqlShortcutsLimit: "Лимит строк", + sqlShortcutsDatabaseTypes: "Базы данных", + sqlShortcutsDatabaseTypesAll: "Все базы данных", + sqlShortcutsDatabaseTypesSelected: "Выбрано: {count}", + sqlShortcutsDatabaseTypesHint: + "Оставьте «Все базы данных» или ограничьте конкретными типами. При ограничении для каждого типа тело хранится отдельно; используйте «Применить ко всем выбранным», чтобы скопировать текущий шаблон. Одно и то же действие может повторяться для непересекающихся типов.", + sqlShortcutsPreview: "Предпросмотр SQL", + sqlShortcutsPreviewDatabase: "Диалект предпросмотра", + sqlShortcutsSelectLimitHint: "Во время выполнения SQL формируется для диалекта активного подключения.", + syncWebDavTitle: "Синхронизация WebDAV", + syncWebDavDescription: "Загружать или восстанавливать снимок DBX, включая сохранённые записи библиотеки SQL, из совместимого с WebDAV хранилища.", + syncWebDavWebDescription: "В веб-режиме сервер DBX обращается к WebDAV без ограничений CORS браузера. Сохранённые пароли остаются в текущем экземпляре DBX.", + syncEndpoint: "URL WebDAV", + syncUsername: "Имя пользователя", + syncPassword: "Пароль", + syncPasswordPlaceholder: "Введите пароль", + syncClearSavedPassword: "Очистить сохранённый пароль", + syncRememberWebDavPassword: "Запомнить пароль приложения WebDAV", + syncSavedPassword: "(сохранён)", + syncRememberWebDavPasswordDescription: "Пароль шифруется и хранится только в текущем экземпляре DBX. Он не синхронизируется с WebDAV и не заменяет пароль синхронизации.", + syncRemotePath: "Путь к удалённому снимку", + syncRemotePathDescription: "DBX создаст отсутствующие родительские папки при загрузке.", + syncSecretNotice: "По умолчанию DBX синхронизирует только параметры подключений и настройки. Пароли баз данных, пароли SSH, пароли прокси, токены HTTP-туннелей, строки подключения и ключи AI API остаются локально.", + syncSecrets: "Синхронизировать зашифрованные секреты", + syncSecretsDescription: "Если включено, DBX шифрует пароли баз данных, пароли SSH, пароли прокси, токены HTTP-туннелей и ключи AI API перед загрузкой в удалённое хранилище.", + syncSecretsSharedDescription: "Для WebDAV этот пароль шифрует включаемые учётные данные. Сниппеты GitHub, Gitee и GitLab используют независимое шифрование и управление учётными данными.", + syncSecretsPassphrase: "Пароль синхронизации", + syncSecretsPassphraseDescription: "Этот пароль используется только для шифрования и восстановления конфиденциальных данных. Он шифруется в текущем экземпляре DBX; в других экземплярах введите его снова.", + syncTest: "Проверить", + syncUpload: "Загрузить", + syncDownload: "Скачать", + syncTestSuccess: "Цель WebDAV доступна.", + syncUploadSuccess: "Загружено {bytes} байт в {path}.", + syncAutoUpload: "Автоматически загружать снимки", + syncAutoUploadInterval: "Каждые", + syncAutoUploadMinutes: "мин.", + syncAutoUploadDescription: "Выполняется, пока DBX открыт. Скачивание по-прежнему требует ручного подтверждения, чтобы не заменить локальный сохранённый SQL неожиданно.", + syncAutoUploadSuccess: "Автоматически загружено {bytes} байт в {path}.", + syncDownloadSuccess: "Скачано и применено {bytes} байт из {path}.", + syncSecretsApplied: "Зашифрованные секреты восстановлены.", + syncSecretsSkipped: "Зашифрованные секреты присутствовали, но не были восстановлены.", + syncDownloadConfirm: "Скачать и применить удалённый снимок DBX? Локальные метаданные и сохранённый SQL будут заменены.", + syncSnippetTitle: "Синхронизация через сниппеты", + syncSnippetDescription: "Хранить тот же снимок DBX в приватном сниппете кода. Первая загрузка создаёт сниппет и сохраняет его ID.", + syncSnippetProvider: "Провайдер", + syncSnippetProviderGitee: "Gitee Snippets", + syncGitLabInstance: "URL экземпляра GitLab", + syncGitLabInstanceInvalid: "Введите URL HTTP или HTTPS без учётных данных, параметров запроса и фрагмента.", + syncGitLabHttpWarning: "HTTP передаёт токен доступа в открытом виде. Используйте его только в доверенной внутренней сети; предпочитайте HTTPS.", + syncSnippetId: "ID сниппета", + syncSnippetIdPlaceholder: "Оставьте пустым для первой загрузки", + syncSnippetToken: "Токен доступа", + syncSnippetRememberToken: "Хранить зашифрованным на этом устройстве", + syncSnippetTokenDescription: "Токенам GitHub нужно разрешение на запись Gists; персональным токенам доступа GitLab нужна область api. Токены никогда не включаются в снимок синхронизации.", + syncSnippetPassphrase: "Пароль шифрования сниппета", + syncSnippetPassphraseDescription: "Шифрует весь снимок сниппета. Он не сохраняется и отделён от пароля для синхронизируемых учётных данных.", + syncSnippetIncludeSecrets: "Включать зашифрованные учётные данные при загрузке", + syncSnippetRestoreSecrets: "Восстанавливать зашифрованные учётные данные при скачивании", + syncSnippetTestSuccess: "Цель синхронизации через сниппеты доступна.", + syncSnippetUploadSuccess: "Загружено {bytes} байт в сниппет {id}.", + syncSnippetDownloadSuccess: "Скачано и применено {bytes} байт из сниппета {id}.", + syncSnippetMigrateLegacy: "Перенести устаревший сниппет", + syncSnippetMigrateLegacyRequired: "Этот устаревший сниппет с открытым текстом необходимо перенести с помощью действия «Перенести устаревший сниппет».", + syncSnippetMigrateLegacyConfirm: "DBX сначала создаст зашифрованную замену, а затем навсегда удалит устаревший сниппет с открытым текстом {id}. Это нельзя отменить. Продолжить?", + syncSnippetMigrateLegacySuccess: "Создан зашифрованный сниппет {id}, а устаревший сниппет с открытым текстом удалён.", + syncSnippetMigrateLegacyCreated: "Создан зашифрованный сниппет {id}.", + syncSnippetMigrateLegacyCleanupRequired: "Зашифрованный сниппет создан, но устаревший сниппет {id} удалить не удалось. Удалите его вручную и смените все раскрытые учётные данные.", + syncSnippetRetryLegacyCleanup: "Повторить очистку устаревшего сниппета", + syncSnippetLegacyCleanupSuccess: "Устаревший сниппет с открытым текстом {id} удалён.", + syncSnippetGuide: "Руководство по настройке", + apply: "Применить", + applyAndClose: "Применить и закрыть", + reset: "Сбросить", + resetDefaults: "Сбросить к значениям по умолчанию", + resetAllDefaults: "Сбросить все значения по умолчанию", + save: "Сохранить", + cancel: "Отмена", + executeMode: "Режим выполнения", + executeModeDescription: "Сочетание для выполнения SQL: {shortcut}. Определяет, выполнять ли по умолчанию весь SQL или оператор под курсором.", + executeModeAll: "Выполнять весь SQL", + executeModeCurrent: "Выполнять оператор под курсором", + defaultTransactionMode: "Режим фиксации транзакций по умолчанию", + defaultTransactionModeDescription: + "Режим транзакций по умолчанию при открытии нового SQL-редактора. При «Ручной транзакции» новые редакторы запускаются в режиме ручных транзакций, требующем ручного коммита или отката; при «Автокоммите» каждый оператор фиксируется автоматически. Применяется только к базам данных, поддерживающим транзакции.", + defaultTransactionModeAuto: "Автокоммит", + defaultTransactionModeManual: "Ручная транзакция", + keepExplicitTransactionInAutoCommit: "Сохранять явные транзакции в режиме автокоммита", + keepExplicitTransactionInAutoCommitDescription: + "После BEGIN / START TRANSACTION на вкладке с автокоммитом оставлять транзакцию открытой до выполнения COMMIT или ROLLBACK. Если выключено, каждое выполнение откатывает оставленную открытой явную транзакцию, что не даёт зависшей транзакции удерживать снимок чтения вкладки.", + executeAllOnBlankLine: "Выполнять весь SQL с пустых строк", + executeAllOnBlankLineDescription: "В режиме выполнения текущего оператора выполнять весь SQL, когда под курсором нет оператора. По умолчанию отключено.", + showExecutionTargetPicker: "Показывать выбор цели выполнения", + showExecutionTargetPickerDescription: "Если включено, при запуске без выделения можно выбрать между текущим оператором и всем SQL.", + showStatementRunButtons: "Показывать кнопки запуска слева", + showStatementRunButtonsDescription: "Показывать кнопки запуска для каждого оператора на полосе SQL-редактора. Горячие клавиши и выполнение из контекстного меню работают и при отключении.", + showLineNumbers: "Показывать номера строк", + showLineNumbersDescription: "Показывать номера строк на полосе SQL-редактора", + showCurrentStatementFrame: "Показывать рамку текущего оператора", + showCurrentStatementFrameDescription: "Если включено, SQL-редактор обводит текущий исполняемый оператор; если выключено, рамка скрыта.", + showInsertValueHints: "Показывать подсказки столбцов в значениях INSERT", + showInsertValueHintsDescription: "Если включено, SQL-редактор показывает подсказки имён столбцов рядом с каждым значением или проекцией SELECT в конструкциях INSERT ... VALUES и INSERT ... SELECT.", + previewStatementRunButton: "Кнопка предпросмотра запуска оператора", + wordWrap: "Перенос строк", + wordWrapDescription: "Переносить длинные строки по ширине редактора", + showWhitespace: "Показывать пробельные символы", + showWhitespaceDescription: "Показывать пробелы как ·, а табуляции как → в SQL-редакторе. Меняется только отображение, а не текст SQL.", + vimMode: "Режим Vim", + vimModeDescription: "Использовать модальное редактирование в стиле Vim в SQL-редакторе", + autoCloseBrackets: "Автозакрытие скобок", + autoCloseBracketsDescription: "Автоматически вставлять закрывающие скобки и кавычки при вводе открывающих", + sqlCompletionSection: "Автодополнение SQL", + insertSpaceAfterCompletion: "Вставлять пробел после автодополнения", + insertSpaceAfterCompletionDescription: "Добавлять пробел после принятия автодополнения ключевого слова, таблицы или столбца, если следующий символ это позволяет", + sortCompletionColumnsAlphabetically: "Сортировать столбцы в автодополнении по алфавиту", + sortCompletionColumnsAlphabeticallyDescription: "Отключите, чтобы сохранять исходный порядок полей таблицы в базе данных", + selectFirstCompletionOnOpen: "Автоматически выбирать первое автодополнение", + selectFirstCompletionOnOpenDescription: "Если включено, при открытии списка выбирается первый кандидат, и Enter или Tab его принимает. Если отключено, Enter вставляет новую строку, а Tab принимает первого кандидата.", + completionTriggerMode: "Режим вызова автодополнения SQL", + completionTriggerModeDescription: "Выберите, как показывать кандидатов автодополнения SQL.", + completionTriggerModeManual: "Только вручную", + completionTriggerModeManualDescription: "Показывать кандидатов только при использовании сочетания автодополнения {shortcut}.", + completionTriggerModeRequirePrefix: "Префикс введённого идентификатора", + completionTriggerModeRequirePrefixDescription: "Показывать кандидатов после ввода хотя бы одного символа идентификатора.", + completionTriggerModePositional: "Умная позиция", + completionTriggerModePositionalDescription: "Показывать кандидатов автоматически в зависимости от текущей синтаксической позиции SQL.", + sqlSemanticDiagnosticsEnabled: "Семантическая диагностика SQL", + sqlSemanticDiagnosticsEnabledDescription: "Если включено, редактор сообщает о семантических проблемах, таких как неизвестные таблицы и столбцы. Отключите, чтобы уменьшить разбор и проверки метаданных для больших SQL.", + confirmDangerousSqlExecution: "Подтверждать перед опасными операциями", + confirmDangerousSqlExecutionDescription: "Если отключено, опасный SQL и удаление строк таблиц или документов выполняются без предупреждающего диалога.", + continueOnErrorOnBatch: "Продолжать при ошибке", + continueOnErrorOnBatchDescription: "Если включено, выполнение нескольких операторов продолжается после ошибки, а не останавливается на первой неудаче.", + confirmUnsavedSqlClose: "Подтверждать закрытие несохранённого SQL", + confirmUnsavedSqlCloseDescription: "Если отключено, вкладки SQL с несохранёнными изменениями закрываются или приложение завершается без диалога подтверждения сохранения.", + appCloseUnsavedTabsMode: "Несохранённый SQL при выходе", + appCloseUnsavedTabsModeDescription: "Выберите, что делать при выходе из DBX, когда на вкладках SQL есть несохранённые изменения.", + appCloseUnsavedTabsModePrompt: "Спрашивать о сохранении", + appCloseUnsavedTabsModeKeepDrafts: "Выйти и сохранить черновики", + appCloseUnsavedTabsModeHint: "Черновики сохраняются как несохранённые вкладки и восстанавливаются при следующем запуске DBX. Для этого параметр «Восстанавливать вкладки при запуске» не должен быть установлен в «Не сохранять вкладки».", + appCloseDraftPersistFailed: "DBX не смог сохранить черновики открытых вкладок, поэтому выход отменён. Проверьте место на диске и права на файлы, затем повторите попытку. Подробности: {message}", + savedSqlOpenTarget: "Цель по умолчанию для сохранённого SQL", + savedSqlOpenTargetSaved: "Сохранённая цель", + savedSqlOpenTargetSavedDescription: "Использовать подключение, базу данных и схему, сохранённые вместе с SQL-файлом.", + savedSqlOpenTargetCurrent: "Текущая вкладка", + savedSqlOpenTargetCurrentDescription: "Использовать подключение, базу данных, схему и каталог активной вкладки, когда они доступны; иначе использовать сохранённую цель.", + prefillNewQueryWithSelect: "Заполнять новый запрос через SELECT *", + prefillNewQueryWithSelectDescription: "При создании нового запроса заполнять редактор конструкцией SELECT * FROM на основе активной вкладки таблицы или таблицы, выбранной в боковой панели.", + generateSqlIncludeDatabaseName: "Включать имя базы данных в генерируемый SQL", + generateSqlIncludeDatabaseNameDescription: "Когда база данных это поддерживает, генерируемый SQL таблицы использует полное имя (database.schema.table в SQL Server), а не только имя таблицы.", + generateSqlQuoteIdentifiers: "Заключать идентификаторы в кавычки в генерируемом SQL", + generateSqlQuoteIdentifiersDescription: "Если отключено, ссылки на таблицы в новых запросах не используют кавычки, специфичные для диалекта. Зарезервированные слова, специальные символы и имена с учётом регистра могут требовать кавычек для выполнения.", + formatSqlOnSqlFileSave: "Форматировать SQL при сохранении SQL-файлов", + formatSqlOnSqlFileSaveDescription: "Автоматически форматировать SQL при сохранении SQL-файла, включая файлы библиотеки сохранённого SQL и запросы, сохранённые как .sql-файлы.", + clickTableNavigationTarget: "Ctrl+клик по таблице открывает DDL", + clickTableNavigationTargetDescription: "Если включено, Ctrl/Cmd+клик по имени таблицы открывает редактор структуры таблицы (DDL). Если отключено, открывается просмотр данных таблицы.", + showTableDdlHoverPreview: "Показывать DDL таблицы при наведении", + showTableDdlHoverPreviewDescription: "Показывать предпросмотр DDL при наведении на имя таблицы в SQL-редакторе.", + tableHoverLookupMode: "Область поиска таблиц при наведении", + tableHoverLookupModeDescription: "Как разрешаются имена таблиц без квалификатора при наведении или Ctrl/Cmd+клике в SQL-редакторе.", + tableHoverLookupModeCurrent: "Только текущая схема", + tableHoverLookupModeFallback: "Текущая схема, затем все схемы", + tableHoverLookupModeAlways: "Сначала все схемы", + tableHoverLookupModeCurrentDescription: "Искать таблицы только в схеме, выбранной на панели инструментов.", + tableHoverLookupModeFallbackDescription: "Сначала искать в выбранной схеме, затем, если не найдено, искать другие схемы по имени таблицы.", + tableHoverLookupModeAlwaysDescription: "Сначала искать все схемы по имени таблицы. Предпочтительно при написании межсхемных процедур.", + sqlVariableSyntax: "Подстановка переменных и заполнителей SQL", + sqlVariableSyntaxDescription: "Выберите, какие синтаксисы переменных и заполнителей DBX подставляет перед выполнением SQL, для каждого типа базы данных. По умолчанию включены все.", + sqlVariableSubstitutionEnabled: "Включено", + sqlVariableSyntax_positional: "Позиционный заполнитель", + sqlVariableSyntax_positionalDescription: "Запрашивать значение для последовательной подстановки каждого позиционного заполнителя.", + sqlVariableSyntax_named: "Именованный заполнитель", + sqlVariableSyntax_namedDescription: "Запрашивать значение для подстановки именованных заполнителей.", + sqlVariableSyntax_shell: "Заполнитель в стиле shell", + sqlVariableSyntax_shellDescription: "Запрашивать значение для подстановки заполнителей в стиле shell.", + sqlVariableSyntax_mybatis: "Заполнитель в стиле MyBatis", + sqlVariableSyntax_mybatisDescription: "Запрашивать значение для подстановки заполнителей в стиле MyBatis.", + sqlVariableSyntax_sqlserver: "Заполнитель в стиле SQL Server", + sqlVariableSyntax_sqlserverDescription: "Запрашивать значение для подстановки заполнителей в стиле SQL Server (может конфликтовать с переменными сеанса).", + sqlVariableSyntax_atSet: "Раскрытие встроенных переменных", + sqlVariableSyntax_atSetDescription: "Раскрывать встроенные объявления переменных и подставлять их значения перед выполнением.", + autoAliasTables: "Автоматически добавлять псевдонимы таблиц", + autoAliasTablesDescription: "При выборе автодополнения таблицы в FROM или JOIN вставлять сгенерированный псевдоним, например order_items AS oi.", + sqlServerSpaceConfirmsCompletion: "Пробел подтверждает автодополнение (стиль SQL Server)", + sqlServerSpaceConfirmsCompletionDescription: "Пока список автодополнения открыт, нажатие пробела принимает выбранное ключевое слово, таблицу или столбец и сохраняет пробел. Enter и Tab работают как раньше.", + redisKeyTemplatesSection: "Redis", + redisKeyTemplates: "Шаблоны поиска ключей", + redisKeyTemplatesPlaceholder: "Пример:\nuser:{'{'}$userId{'}'}\nv3:adui:{'{'}$positionID{'}'}", + redisKeyTemplatesDescription: "Один шаблон на строку. Используется как запасные подсказки, когда у подключения Redis нет собственных шаблонов.", + redisScanPageSize: "Количество ключей при сканировании Redis", + redisScanPageSizeDescription: "Число ключей, запрашиваемых за одну страницу Redis SCAN при просмотре ключей.", + redisScanPageSizeOption: "{count} ключей", + redisDatabaseDisplayLimit: "Лимит списка баз данных в боковой панели", + redisDatabaseDisplayLimitDescription: "Максимальное число баз данных, показываемых сразу в боковой панели; остальные можно показать кнопкой «Загрузить ещё».", + redisDatabaseDisplayLimitOption: "{count} баз данных", + exportBatchSize: "Размер порции при экспорте", + dateTimeSection: "Дата и время", + globalDateTimeDisplayFormat: "Глобальный формат отображения", + globalDateTimeDisplayFormatDescription: "Применяется к временным столбцам без собственного форматтера в любой базе данных.", + globalDateTimeExportFormat: "Глобальный формат экспорта", + globalDateTimeExportFormatDescription: "Единообразно форматирует временные столбцы при экспорте в CSV, Excel, JSON, Markdown и текст.", + globalDateTimeImportFormat: "Глобальный формат импорта", + globalDateTimeImportFormatDescription: "Разбирает импортируемые временные значения с этим форматом. Оставьте пустым для автоматического определения распространённых форматов.", + dateTimeFormatRaw: "Сохранять значение базы данных", + dateTimeFormatAuto: "Автоопределение", + dateTimeFormatSearchPlaceholder: "Выберите или введите формат", + dateTimeFormatEmpty: "Введите пользовательский формат даты и времени", + exportBatchSizeDescription: "Строк, извлекаемых за одну порцию при экспорте данных (100–100000).", + exportRowLimitEnabled: "Ограничить число экспортируемых строк", + exportRowLimitEnabledDescription: "Если включено, экспорт результатов запросов и данных таблиц останавливается на указанном ниже лимите строк.", + exportRowLimit: "Лимит строк при экспорте данных", + exportRowLimitDescription: "Максимальное число строк для экспорта результатов запросов и данных таблиц.", + exportRowLimitUnlimited: "Без ограничений", + queryExportKeysetOptimizationEnabled: "Пробовать оптимизацию по ключу", + queryExportKeysetOptimizationEnabledDescription: "Применяется только к надёжно распознанным запросам к одной таблице; сложные запросы автоматически переключаются на обычный режим.", + exportSection: "Экспорт", + csvQuoteMode: "Кавычки в полях CSV", + csvQuoteModeDescription: "Выберите, как поля CSV используют двойные кавычки.", + csvQuoteModeAll: "Все поля", + csvQuoteModeNecessary: "Только когда нужно", + performanceSection: "Производительность", + shortcutExecuteSql: "Выполнить SQL", + shortcutExecuteSqlInNewResultTab: "Выполнить SQL в новой вкладке результатов", + shortcutFind: "Найти", + shortcutGotoLine: "Перейти к строке", + shortcutReplace: "Заменить", + shortcutSaveSql: "Сохранить SQL", + shortcutAcceptCompletion: "Принять автодополнение", + shortcutTriggerCompletion: "Вызвать автодополнение", + shortcutFormatSql: "Форматировать SQL", + shortcutExpandSelectStar: "Развернуть * в столбцы", + shortcutToggleLineComment: "Переключить однострочный комментарий", + shortcutToggleBlockComment: "Переключить блочный комментарий", + shortcutIndentMore: "Увеличить отступ", + shortcutIndentLess: "Уменьшить отступ", + shortcutInsertLineBelow: "Вставить строку ниже", + shortcutJoinLines: "Объединить строки", + shortcutDuplicateLine: "Дублировать текущую строку", + shortcutDeleteLine: "Удалить текущую строку", + shortcutMoveLineUp: "Переместить строку вверх", + shortcutMoveLineDown: "Переместить строку вниз", + shortcutCopyLineUp: "Копировать строку вверх", + shortcutCopyLineDown: "Копировать строку вниз", + shortcutUndo: "Отменить", + shortcutRedo: "Повторить", + shortcutSelectAll: "Выделить всё", + shortcutAddNextSelectionOccurrence: "Добавить следующее вхождение", + shortcutSelectAllSelectionOccurrences: "Выделить все вхождения", + shortcutExtendSelection: "Расширить выделение", + shortcutEditTableStructure: "Изменить структуру таблицы", + shortcutCopyCurrentRow: "Копировать текущую строку данных", + shortcutDeleteCurrentRow: "Удалить текущую строку данных", + shortcutGoToColumn: "Перейти к столбцу", + shortcutGoToFirstPage: "Первая страница", + shortcutGoToPreviousPage: "Предыдущая страница", + shortcutGoToNextPage: "Следующая страница", + shortcutGoToLastPage: "Последняя страница", + shortcutNewQuery: "Новый запрос", + shortcutOpenSettings: "Открыть настройки", + shortcutCloseTab: "Закрыть вкладку", + shortcutFocusSearch: "Фокус на поиске в текущем представлении", + shortcutQuickOpen: "Быстрое открытие (поиск по всем объектам базы данных)", + shortcutGlobalSearch: "Глобальный поиск по содержимому файлов", + shortcutNavigateTabHistoryBack: "Вернуться к предыдущей просмотренной вкладке", + shortcutTabSwitcher: "Переключатель вкладок (удерживайте, чтобы показать, отпустите, чтобы переключиться)", + shortcutNavigateTabHistoryForward: "Перейти к следующей просмотренной вкладке", + shortcutSwitchToPreviousTab: "Переключиться на предыдущую вкладку", + shortcutSwitchToNextTab: "Переключиться на следующую вкладку", + shortcutSwitchToTab1: "Переключиться на вкладку 1", + shortcutSwitchToTab2: "Переключиться на вкладку 2", + shortcutSwitchToTab3: "Переключиться на вкладку 3", + shortcutSwitchToTab4: "Переключиться на вкладку 4", + shortcutSwitchToTab5: "Переключиться на вкладку 5", + shortcutSwitchToTab6: "Переключиться на вкладку 6", + shortcutSwitchToTab7: "Переключиться на вкладку 7", + shortcutSwitchToTab8: "Переключиться на вкладку 8", + shortcutSwitchToTab9: "Переключиться на вкладку 9", + shortcutZoomInUi: "Увеличить масштаб интерфейса", + shortcutZoomOutUi: "Уменьшить масштаб интерфейса", + shortcutResetUiZoom: "Сбросить масштаб интерфейса", + shortcutRefreshData: "Обновить данные", + shortcutToggleResultsPane: "Переключить панель результатов", + shortcutToggleTranspose: "Переключить транспонированный вид", + shortcutCancelSearch: "Отменить поиск", + shortcutToggleSidebar: "Переключить боковую панель", + shortcutToggleZenMode: "Переключить режим Zen", + shortcutCopySidebarSelection: "Копировать выделенное в боковой панели", + shortcutPasteSidebarSelection: "Вставить в боковую панель", + shortcutEditSidebarConnection: "Изменить подключение в боковой панели", + shortcutOpenDataInNewTab: "Открыть данные в новой вкладке (клик мышью)", + shortcutViewTableDdl: "Просмотреть DDL таблицы", + shortcutSendSelectionToAi: "Отправить выделенное в AI", + shortcutToggleAiPanel: "Переключить панель AI", + shortcutSqlIntentionActions: "SQL-действия по намерению (развернуть * / уточнить идентификатор)", + intentionExpandWildcard: "Развернуть * в список столбцов", + intentionQualifyIdentifier: "Уточнить идентификатор", + intentionUnqualifyIdentifier: "Убрать уточнение идентификатора", + intentionBatchQualifyIdentifiers: "Пакетное уточнение идентификаторов", + shortcutToggleFold: "Свернуть/развернуть", + shortcutScopeGlobal: "Глобально", + shortcutScopeEditor: "SQL-редактор", + shortcutScopeGrid: "Таблица данных", + shortcutScopeSearch: "Поля поиска", + shortcutScopeSidebar: "Боковая панель", + shortcutScopeHintGlobal: "Действует на любом экране", + shortcutScopeHintEditor: "Действует, когда фокус в редакторе", + shortcutScopeHintGrid: "Действует, когда фокус в таблице результатов", + shortcutScopeHintSearch: "Действует, когда фокус в поле поиска", + shortcutScopeHintSidebar: "Действует, когда фокус на боковой панели", + shortcutGroupCount: "{count} действий", + shortcutGroupUnbound: "{count} без привязки", + shortcutGroupUnboundTooltip: "У этих действий нет назначенных сочетаний клавиш; используйте значок карандаша в строке, чтобы задать его.", + shortcutModifiedTag: "Изменено", + shortcutModifiedTagTooltip: "Отличается от сочетания по умолчанию; используйте значок сброса в строке, чтобы восстановить его.", + shortcutConflictBadge: "{count} конфликтов", + shortcutConflictTooltip: "Дублирует «{label}» ({scope}). В одной области только одно действие может владеть сочетанием, поэтому одно из них нужно изменить перед применением.", + shortcutConflictSummaryTooltip: "{count} конфликтов в одной области ({pairs} дублирующихся пар). В одной области только одно действие может владеть сочетанием, поэтому это нужно устранить перед применением.", + shortcutCrossScopeBadge: "{count} пересечений между областями", + shortcutCrossScopeTooltip: "Совпадает с {targets}. Каждая область разрешает свою привязку, поэтому срабатывает только одна за раз — исправлять нечего.", + shortcutCrossScopeTooltipSeparator: ", ", + shortcutCrossScopeSummaryTooltip: "{count} пересечений между областями ({pairs} дублирующихся пар). Разные области разрешают свои привязки, поэтому срабатывает только одна за раз; это только для сведения и не блокирует применение.", + shortcutConflictBlocksApply: "{count} конфликтов в одной области ({pairs} дублирующихся пар)", + shortcutPressShortcut: "Нажмите сочетание клавиш", + shortcutSearchPlaceholder: "Поиск сочетаний клавиш", + shortcutSearchNoResults: "Нет сочетаний клавиш, соответствующих запросу.", + shortcutConflict: "Это сочетание клавиш конфликтует с другим действием в той же области.", + shortcutReserved: "Это сочетание клавиш зарезервировано системой.", + shortcutPlatformDefault: "Эта комбинация является сочетанием клавиш по умолчанию для другой платформы и не может быть назначена здесь. Используйте другую.", + shortcutClear: "Очистить сочетание клавиш", + preview: "Предпросмотр в реальном времени", + previewSyntaxErrorHint: "Предпросмотр только для чтения. Опечатка FOM в демонстрационном SQL намеренна и показывает подсветку синтаксических ошибок.", + customTheme: "Своя тема", + customThemeConfigure: "Настроить свою тему", + customThemeTitle: "Настройка своей темы", + customThemeMyThemes: "Мои темы", + customThemeNewTheme: "Новая тема", + customThemeVisualEdit: "Визуальный редактор", + customThemeJsonConfig: "Конфигурация JSON", + customThemeLivePreview: "Предпросмотр в реальном времени", + customThemePreviewExample: "-- Пример запроса", + customThemePreset: "Готовая тема", + customThemeSelectPreset: "Выберите готовую тему...", + customThemeApply: "Применить", + customThemePasteImport: "Вставить для импорта", + customThemeExportJson: "Экспорт JSON", + customThemeSaveAndApply: "Сохранить и применить", + customThemeKeyword: "Ключевое слово", + customThemeField: "Поле/переменная", + customThemeFunction: "Функция", + customThemeString: "Строка", + customThemeNumber: "Число", + customThemeComment: "Комментарий", + customThemeTable: "Таблица", + customThemeOperator: "Оператор", + customThemeType: "Тип", + customThemeBuiltin: "Встроенный", + customThemeBackground: "Фон", + customThemeForeground: "Передний план", + customThemeDefaultName: "Своя тема", + customThemeCopySuffix: " (копия)", + customThemeApplied: "Применена цветовая схема «{name}»", + customThemeKeepOne: "Оставьте хотя бы одну тему", + customThemeJsonError: "Неверный формат JSON, проверьте", + jdbcPlugin: "Плагин DBX JDBC", + jdbcPluginInstall: "Установить плагин JDBC", + jdbcPluginInstallSuccess: "Плагин JDBC установлен", + jdbcPluginUpdate: "Обновить", + jdbcPluginUninstall: "Удалить", + jdbcPluginUninstallSuccess: "Плагин JDBC удалён", + jdbcPluginInstalled: "Установлено: v{version}", + jdbcPluginIncompatible: "Несовместимый протокол", + jdbcPluginNotInstalled: "Не установлено", + jdbcDrivers: "JAR-файлы драйверов JDBC", + jdbcImport: "Импортировать JAR", + jdbcImportPath: "Путь импорта", + jdbcDriverPathPlaceholder: "/путь/к/driver.jar", + jdbcImportSuccess: "Импортировано файлов драйверов: {count}", + jdbcDeleteSuccess: "Драйвер удалён", + jdbcNoDrivers: "Драйверы JDBC ещё не импортированы.", + mcpTitle: "Сервер MCP", + mcpDescription: "Проверьте установку и версию сервера DBX MCP, используемого Claude Code, Cursor и другими агентами.", + mcpChecking: "Проверка", + mcpStatusUnknown: "Не проверено", + mcpStatusError: "Проверка не удалась", + mcpReady: "Готово", + mcpNotInstalled: "Не установлено", + mcpUpdateAvailable: "Доступно обновление", + mcpCurrent: "Текущая версия", + mcpLatest: "Последняя версия", + mcpVersionMissing: "Глобальная установка не обнаружена", + mcpVersionUnknown: "Неизвестно", + mcpAvailable: "Доступно", + mcpUnavailable: "Недоступно", + mcpBinPath: "Путь к команде", + mcpInstallCommand: "Команда установки", + mcpUpdateCommand: "Команда обновления", + mcpUninstallCommand: "Команда удаления", + mcpInstallButton: "Установить", + mcpUpdateButton: "Обновить", + mcpUpToDate: "Актуальная версия", + mcpInstalling: "Установка...", + mcpInstallSuccess: "Установка выполнена", + mcpInstallFailed: "Установка не удалась", + mcpUninstallButton: "Удалить", + mcpUninstalling: "Удаление...", + mcpUninstallConfirm: "Удалить сервер DBX MCP? Настроенные клиенты MCP больше не смогут его запустить.", + mcpUninstallFailed: "Удаление не удалось: {error}", + mcpConfig: "Конфигурация MCP", + mcpConfigOptionsHint: + "DBX централизованно управляет доступом к подключениям и разрешениями на выполнение для каждого клиента MCP. Созданные конфигурации содержат только параметры среды выполнения, необходимые для запуска сервера MCP и подключения к этому экземпляру DBX, без переменных разрешений или области подключений.", + mcpScopeConnection: "Подключения, разрешённые для MCP", + mcpScopeConnectionDescription: "DBX предоставляет MCP только выбранные подключения. Изменения применяются ко всем клиентам MCP.", + mcpScopeMode: "Режим области подключений", + mcpScopeModeAll: "Все подключения", + mcpScopeModeAllDescription: "Автоматически включает будущие подключения", + mcpScopeModeSelected: "Определённые подключения", + mcpScopeModeSelectedDescription: "Только явно добавленные подключения", + mcpScopeAllowedPane: "Разрешённые", + mcpScopeAvailablePane: "Доступные", + mcpScopeAddAll: "Добавить все", + mcpScopeRemoveAll: "Удалить все", + mcpScopeAddMatches: "Добавить совпадения ({count})", + mcpScopeRemoveMatches: "Удалить совпадения ({count})", + mcpScopeAddConnection: "Разрешить доступ MCP к {name}", + mcpScopeRemoveConnection: "Удалить доступ MCP к {name}", + mcpScopeAvailableEmpty: "Нет подключений для добавления", + mcpScopeAllowedEmpty: "Сейчас нет разрешённых подключений", + mcpScopeUnavailableGroup: "Недоступные подключения ({count})", + mcpScopeRemoveUnavailableConnection: "Удалить недоступное подключение {id} из списка разрешённых", + mcpScopeUpdatedAnnouncement: "Сейчас MCP разрешает {selected} из {total} доступных подключений", + mcpConnectionSearchPlaceholder: "Поиск по имени, типу, адресу, базе данных или ID подключения", + mcpConnectionSearchEmpty: "Нет подходящих подключений", + mcpConnectionListEmpty: "Нет доступных подключений", + mcpScopeAllAction: "Разрешить все", + mcpScopeNoneAction: "Очистить все", + mcpScopeAllSummary: "Все {count} подключений", + mcpScopeSelectedSummary: "Выбрано {selected}/{total}", + mcpScopeAllConnections: "Все подключения", + mcpScopeNoConnections: "Нет подключений", + mcpScopeConnectionUnavailable: "Ранее выбранное подключение (недоступно)", + mcpScopeConnectionUnavailableDescription: "{count} выбранных подключений больше не существуют. Их ID остаются в списке разрешённых, но текущие подключения для них не предоставляются.", + mcpScopeSelectedCount: "Выбрано подключений: {count}", + mcpCodexConfig: "Конфигурация Codex", + mcpCodexConfigPath: "Codex может использовать ~/.codex/config.toml или .codex/config.toml уровня проекта.", + mcpDeepSeekHarnessConfigPath: "Для dsh web добавьте эту запись вставки в $DSH_HOME/profiles/web/cordis.patch.yml; замените web на другой профиль. Не перезаписывайте существующие записи патча. Проверьте с помощью dsh web --dump-config или дайте HMR перезагрузить изменение.", + mcpCursorConfigPath: "Cursor может использовать .cursor/mcp.json в проекте или ~/.cursor/mcp.json глобально.", + mcpCodeBuddyConfigPath: "CodeBuddy Code может использовать ~/.codebuddy/.mcp.json глобально или .mcp.json в проекте.", + mcpZCodeConfigPath: "ZCode: Settings > MCP Servers > New MCP Server > Full configuration; выберите область User или Workspace, затем вставьте конфигурацию JSON.", + mcpTraeConfigPath: "TRAE: Settings > MCP > Add > Add Manually, затем вставьте конфигурацию JSON.", + mcpQoderConfigPath: "Qoder: Settings > MCP > Add Manually, затем вставьте конфигурацию JSON.", + mcpWorkBuddyConfigPath: "WorkBuddy: откройте Plugins на боковой панели, нажмите MCP Servers (справа вверху) > Configure MCP и вставьте JSON; или сохраните его в ~/.workbuddy/mcp.json (глобально) либо в .workbuddy/mcp.json в вашем проекте.", + mcpCherryStudioConfigPath: "Cherry Studio: Settings > MCP Servers > Add Server > Import JSON, затем вставьте конфигурацию.", + mcpVsCodeConfigPath: "VS Code/Copilot может использовать .vscode/mcp.json в рабочей области или mcp.json в профиле пользователя.", + mcpWindsurfConfigPath: "Windsurf может использовать ~/.codeium/windsurf/mcp_config.json.", + mcpOpenCodeConfigPath: "~/.config/opencode/opencode.json глобально или opencode.json на уровне проекта.", + mcpPiConfigPath: "Сначала установите плагин адаптера Pi MCP: pi install npm:pi-mcp-adapter. Затем сохраните в ~/.pi/agent/mcp.json (глобально) или .mcp.json (проект), выполните /mcp для проверки и /reload, чтобы применить в Pi.", + mcpExecutionMode: "Глобальное разрешение MCP по умолчанию", + mcpExecutionModeDescription: "Задаёт значение по умолчанию, используемое, когда разрешение для подключения или базы данных не настроено. Значения по умолчанию для подключений и параметры баз данных могут переопределять его по области.", + mcpExecutionModeReadOnly: "Только чтение", + mcpExecutionModeSafeWrite: "Чтение/запись данных", + mcpExecutionModeRecommended: "Рекомендуется", + mcpExecutionModeHighRiskWrite: "Полный доступ", + mcpExecutionModeReadOnlyDescription: "Разрешает только запросы, которые DBX классифицирует как чтение; блокирует распознанные записи в базу данных и изменения подключений. Разрешения учётной записи базы данных остаются окончательной жёсткой границей.", + mcpExecutionModeSafeWriteDescription: "Разрешает обычные INSERT, UPDATE/DELETE с фильтром, проверяемо ограниченные изменения MongoDB и обычные записи Redis или удаление по явному ключу; блокирует изменения всей таблицы и структурные изменения.", + mcpExecutionModeHighRiskWriteDescription: "Помимо чтения/записи данных разрешает изменения всей таблицы, DDL, TRUNCATE, очистку базы данных и другие операции высокого риска. Защита продакшена и подключений только для чтения по-прежнему действует.", + mcpExecutionModeHighRiskConfirm: "Полный доступ разрешает изменения всей таблицы, DDL, TRUNCATE, очистку базы данных и другие операции высокого риска. Включить его?", + mcpCapabilityTitle: "Сравнение возможностей", + mcpCapabilityDescription: "Это типовые операции; запросы, которые DBX не может надёжно классифицировать, требуют полного доступа.", + mcpCapabilityOperation: "Возможность", + mcpCapabilityRead: "Запросы и чтение", + mcpCapabilityScopedMutation: "Ограниченные изменения данных (INSERT, UPDATE/DELETE с фильтром, запись/удаление по явному ключу)", + mcpCapabilityBroadMutation: "Обновление/удаление всей таблицы и очистка данных", + mcpCapabilitySchemaAdmin: "DDL, структурные изменения и администрирование высокого риска", + mcpCapabilityConnectionManagement: "Добавление/удаление подключений MCP", + mcpCapabilityAllowed: "Разрешено", + mcpCapabilityBlocked: "Заблокировано", + mcpQueryTimeout: "Тайм-аут запроса (секунды)", + mcpQueryTimeoutDescription: "Оставьте пустым, чтобы наследовать тайм-аут запроса подключения. 0 = без ограничения. Положительное значение переопределяет параметр подключения для каждого запроса MCP.", + mcpQueryTimeoutInvalid: "Введите неотрицательное целое число секунд или оставьте пустым, чтобы наследовать параметр подключения.", + mcpQueryTimeoutSaveStatus_saving: "Сохранение...", + mcpQueryTimeoutSaveStatus_saved: "Сохранено", + mcpQueryTimeoutSaveStatus_failed: "Не удалось сохранить", + mcpCapabilityAlwaysEnforced: "Каждый режим по-прежнему подчиняется списку разрешённых подключений, защите подключения только для чтения, защите продакшена и разрешениям учётной записи базы данных.", + mcpPolicySaveFailed: "Не удалось сохранить политику доступа MCP: {error}", + mcpPolicyLoadFailed: "Не удалось загрузить политику доступа MCP: {error}", + mcpDetectionTiming: "DBX проверяет автоматически при открытии этой страницы; нажмите «Проверить снова», чтобы обновить.", + mcpNpmBoundary: "DBX проверяет состояние MCP; установка, обновление и удаление выполняются через обнаруженную среду выполнения npm, pnpm или bun.", + mcpRefresh: "Проверить снова", + mcpGuide: "Руководство MCP", + mcpAuthTitle: "Авторизация MCP", + mcpAuthDescription: "Выполните авторизацию по порядку: задайте глобальное значение по умолчанию, выберите группы и подключения, ограничьте базы данных, затем проверьте итоговую политику.", + mcpAuthStepsLabel: "Шаги авторизации MCP", + mcpAuthStepConnectionsTitle: "Группы и подключения", + mcpAuthStepConnectionsDescription: "Выберите, что видит MCP, и задайте разрешения для подключений", + mcpAuthStepDatabasesTitle: "Область баз данных", + mcpAuthStepDatabasesDescription: "Ограничьте базы данных каждого подключения и задайте разрешения для баз данных", + mcpAuthStepOverridesTitle: "Разрешения по умолчанию", + mcpAuthStepOverridesDescription: "Задайте глобальное значение по умолчанию для всех последующих областей", + mcpAuthStepCapabilitiesTitle: "Сводка и проверка", + mcpAuthStepCapabilitiesDescription: "Проверьте действующие разрешения, выберите инструменты и подтвердите", + mcpAuthStepRegionLabel: "Шаг {step}: {title}", + mcpAuthPreviousStep: "Назад", + mcpAuthNextStep: "Далее", + mcpAuthStepProgress: "Шаг {current} из {total}", + mcpResourceScopeTitle: "Подключения, видимые для MCP", + mcpResourceScopeDescription: "Выберите группы для динамического охвата и отдельные подключения для точных исключений.", + mcpResourceScopeModeCustom: "Своя область", + mcpResourceScopeAllSummary: "Все {count} подключений", + mcpResourceScopeCustomSummary: "{effective} действующих · {groups} правил групп · {connections} прямых правил", + mcpResourceScopeSearch: "Поиск групп или подключений", + mcpResourceScopeTreeLabel: "Дерево ресурсов подключений MCP", + mcpResourceScopeInherited: "Из {group}", + mcpResourceScopeDynamic: "Динамически", + mcpResourceScopeDirect: "Напрямую", + mcpResourceScopePartial: "Частично разрешено", + mcpResourceScopeEmpty: "Нет подходящих групп или подключений.", + mcpResourceScopeHint: "Выбранная группа включает свои текущие и будущие дочерние подключения. Прямые выборы — независимые исключения.", + mcpResourceScopeAllConfirm: "Переключение на все подключения удалит текущие пользовательские правила групп и подключений. Продолжить?", + mcpPermissionGlobalDefaultHint: "Разрешения групп, подключений и баз данных переопределяют это значение по умолчанию, но никогда не расширяют видимость подключений.", + mcpDatabasePolicyHighRiskConfirm: "Разрешить записи высокого риска для этой базы данных? Защита подключения только для чтения и продакшена по-прежнему действует.", + mcpDatabaseScopeClearsPermissionExceptions: "Изменение области этой базы данных удалит её исключения разрешений. Продолжить?", + mcpPerPage: "На странице", + mcpPreviousPage: "Предыдущая страница", + mcpNextPage: "Следующая страница", + mcpDatabaseScopeTitle: "Подключения и область баз данных", + mcpDatabaseScopeDescription: "Выберите подключение, предоставляемое MCP, слева, затем ограничьте базы данных, к которым оно может обращаться. Имена баз данных сопоставляются точно.", + mcpDatabaseScopeEmptyHint: "Сначала разрешите хотя бы одно подключение в разделе «Область подключений».", + mcpDatabaseScopeAllowedConnections: "Разрешённые подключения", + mcpDatabaseScopeSummaryAll: "Все базы данных", + mcpDatabaseScopeSummaryNone: "Нет доступа к базам данных", + mcpDatabaseScopeSummarySelected: "Выбрано: {count}", + mcpDatabaseScopePermissionNote: "Выбранная область не изменяет существующие разрешения баз данных подключения в DBX.", + mcpDatabaseLoadButton: "Загрузить список ресурсов", + mcpDatabaseScopeAriaLabel: "Область доступа к базам данных", + mcpDatabaseScopeAllTitle: "Все базы данных", + mcpDatabaseScopeAllDescription: "Сохранить текущую область доступа", + mcpDatabaseScopeSelectedTitle: "Только выбранные базы данных", + mcpDatabaseScopeSelectedDescription: "Предоставить только отмеченные элементы", + mcpDatabaseScopeNoneTitle: "Нет доступа", + mcpDatabaseScopeNoneDescription: "Сохранить правила, но запретить все базы данных", + mcpDatabaseScopeSelectedSummary: "Разрешено баз данных: {count}. Неотмеченные базы данных и межбазовые запросы отклоняются сервером MCP.", + mcpDatabasePolicyInherit: "Наследовать подключение", + mcpDatabasePolicySetting: "Настройка приоритета базы данных", + mcpDatabasePolicyEffective: "Действует: {mode}", + mcpPermissionPreviewTitle: "Предпросмотр разрешений", + mcpPermissionPreviewDescription: "Приоритет разрешений: база данных, подключение, ближайшая группа, родительская группа, затем глобальное значение по умолчанию.", + mcpPermissionPreviewConnection: "Подключение", + mcpPermissionPreviewDatabase: "База данных", + mcpPermissionPreviewConnectionDefault: "По умолчанию для подключения", + mcpPermissionPreviewGroupDefault: "По умолчанию для группы", + mcpGroupScopeTitle: "Группы подключений", + mcpGroupScopeDescription: "Выбор группы динамически предоставляет все её текущие и будущие дочерние подключения. Другие подключения всё ещё можно добавить явно.", + mcpGroupScopeSelected: "Выбрано групп: {count}", + mcpGroupScopeSearch: "Поиск путей групп", + mcpGroupScopeNoResults: "Подходящие группы не найдены.", + mcpGroupScopeEmpty: "Нет групп подключений для настройки.", + mcpGroupPolicyTitle: "Разрешения группы по умолчанию", + mcpGroupPolicyDescription: "Дочерняя группа переопределяет родительскую; параметры подключения и базы данных могут переопределять значение группы по умолчанию.", + mcpGroupPolicyInherit: "Наследовать родительскую или глобальную", + mcpGroupPolicyHighRiskConfirm: "Разрешить записи высокого риска для этой группы? Защита подключения только для чтения и продакшена по-прежнему действует.", + mcpPermissionPreviewDatabaseOverride: "Настройка приоритета базы данных", + mcpPermissionPreviewEffective: "Действует", + mcpPermissionPreviewResource: "Ресурс", + mcpPermissionPreviewSource: "Источник", + mcpPermissionSourceDatabase: "Исключение базы данных", + mcpPermissionSourceConnection: "Исключение подключения", + mcpPermissionSourceGroup: "Группа: {group}", + mcpPermissionSourceGlobal: "Глобальное значение по умолчанию", + mcpPermissionPreviewEmpty: "Сначала разрешите хотя бы одно подключение и настройте его область баз данных.", + mcpPermissionPreviewSearchPlaceholder: "Поиск подключений или баз данных", + mcpPermissionPreviewSearchNoResults: "Подходящие подключения или базы данных не найдены.", + mcpDatabaseSearchPlaceholder: "Фильтр загруженных баз данных", + mcpDatabaseManualPlaceholder: "Добавьте имя базы данных вручную", + mcpDatabaseLoadFailed: "Не удалось загрузить базы данных: {error}. Вы можете добавить точные имена баз данных вручную.", + mcpDatabaseEmptyHint: "Нажмите «Загрузить список ресурсов», чтобы получить список баз данных, или добавьте разрешённые базы данных вручную.", + mcpManagementAccess: "Способы доступа", + mcpManagementPermissions: "Управление разрешениями", + mcpTransportLabel: "Тип подключения", + mcpRuntimeSettings: "Параметры среды выполнения", + mcpTransportLocalStdio: "Локальный stdio", + mcpTransportHttpService: "Служба HTTP", + mcpHttpWebServiceTitle: "Веб-служба Streamable HTTP", + mcpHttpWebServiceDescription: "Web/Docker повторно использует текущий порт веб-прослушивания. Включите её переменными среды развёртывания; страница настроек никогда не хранит токен.", + mcpHttpStatusLabelEnabled: "Включено", + mcpHttpStatusLabelDisabled: "Не включено", + mcpHttpNotConfigured: "Не настроено", + mcpHttpWebTokenSourceAndHosts: "Источник токена: {tokenSource}; разрешённые хосты: {hosts}", + mcpHttpWebAllowedOrigins: "Разрешённые источники: {origins}", + mcpHttpReloadStatus: "Состояние перезагрузки", + mcpHttpServiceTitle: "Служба Streamable HTTP", + mcpHttpStatusLabelRunning: "Работает", + mcpHttpStatusLabelPending: "Ожидает настройки", + mcpHttpServiceDescription: "По умолчанию отключена. При включении DBX Desktop размещает службу; приведённая выше конфигурация применяется к фактической службе прослушивания только после сохранения.", + mcpHttpListenerTitle: "Конфигурация прослушивания", + mcpHttpListenerHintPrefix: "Рекомендуем оставить ", + mcpHttpListenerHintSuffix: ", чтобы подключаться могли только клиенты MCP на том же компьютере.", + mcpHttpHostLabel: "Адрес прослушивания", + mcpHttpPortLabel: "Порт", + mcpHttpPathLabel: "Путь MCP", + mcpHttpRemoteTitle: "Удалённый доступ", + mcpHttpRemoteHintPrefix: "Требуется только когда адрес прослушивания не ", + mcpHttpRemoteHintMiddle: " или ", + mcpHttpRemoteHintSuffix: ". После включения обязательны списки разрешённых Host и Origin.", + mcpHttpAllowedHostsLabel: "Разрешённые хосты", + mcpHttpHostsHint: "По одному в строке или через запятую.", + mcpHttpAllowedOriginsLabel: "Разрешённые источники", + mcpHttpOriginsHintPrefix: "Должен включать протокол, например ", + mcpHttpOriginsHintSuffix: ".", + mcpHttpRemoteDisabledHint: "Пока удалённый доступ отключён, списки разрешённых не нужны.", + mcpHttpUnsavedChangesHint: "Приведённая выше конфигурация ещё не сохранена; работающая служба не изменится немедленно.", + mcpHttpSaveHint: "Сохранение запускает или перезапускает службу и обновляет сведения о подключении ниже.", + mcpHttpReload: "Перезагрузить", + mcpHttpSaveAndStart: "Сохранить и запустить службу", + mcpHttpDisabledHint: "Включите службу, чтобы настроить адрес прослушивания, списки разрешённых для удалённого доступа и сведения о подключении клиента.", + mcpHttpSaveAndStop: "Сохранить и остановить службу", + mcpHttpConnectionInfoTitle: "Сведения о подключении активного клиента", + mcpHttpServiceNotRunning: "Служба не запущена", + mcpHttpRunningConfigBadge: "Работающая конфигурация", + mcpHttpLastStatusBadge: "Последнее состояние", + mcpHttpRunningDraftDiffersHint: "Ниже приведены сведения о подключении текущей работающей службы; они могут отличаться от несохранённого черновика выше.", + mcpHttpEndpointLabel: "Адрес службы", + mcpHttpRotateToken: "Сменить токен", + mcpHttpRotateTokenConfirm: "После смены токена клиенты MCP, использующие старый токен, немедленно отключаются. Продолжить?", + mcpHttpTokenHintPrefix: "Используйте это значение как ", + mcpHttpTokenHintSuffix: " учётные данные HTTP в клиенте.", + mcpHttpClientConfigTitle: "Общая конфигурация HTTP-клиента", + mcpHttpClientConfigHint: "Имена полей клиентов различаются; сохраняйте значения URL и Authorization.", + mcpHttpLogsTitle: "Диагностические журналы службы", + mcpHttpValidationHostRequired: "Введите адрес прослушивания.", + mcpHttpValidationPortRange: "Порт должен быть целым числом от 1 до 65535.", + mcpHttpValidationPathPrefix: "Путь MCP должен начинаться с /.", + mcpHttpValidationRemoteRequired: "Включите «Удалённый доступ», чтобы прослушивать адрес, отличный от loopback.", + mcpHttpValidationHostsRequired: "Удалённый доступ требует хотя бы одного разрешённого хоста.", + mcpHttpValidationOriginsRequired: "Удалённый доступ требует хотя бы одного разрешённого источника.", + mcpHttpErrorRemoteHostsAndOrigins: "Удалённый доступ требует как разрешённых хостов, так и разрешённых источников.", + mcpHttpErrorRemoteBinding: "Удалённое прослушивание требует удалённого доступа и списков разрешённых Host и Origin.", + mcpHttpErrorPortInUse: "Порт уже используется другим приложением. DBX перезапускает свою службу MCP при сохранении; закройте другое приложение, использующее порт, или выберите другой порт.", + mcpConnectionPolicyTitle: "Разрешение подключения по умолчанию", + mcpConnectionPolicyDescription: "Задаёт значение по умолчанию для каждой базы данных в каждом предоставляемом подключении; параметры базы данных имеют приоритет над значениями подключения и глобальными.", + mcpConnectionPolicyEmptyHint: "Сначала разрешите хотя бы одно подключение на шаге 1, затем задайте разрешения подключения по умолчанию.", + mcpConnectionPolicyInherit: "Наследовать глобальное", + mcpConnectionPolicyReadOnly: "Только чтение", + mcpConnectionPolicySafeWrite: "Разрешить безопасные записи", + mcpConnectionPolicyHighRiskWrite: "Разрешить операции высокого риска", + mcpToolPermissionsTitle: "Разрешения инструментов MCP", + mcpToolPermissionsDescription: "Предоставляйте только нужные инструменты MCP. После снятия выбора клиенты отклоняются сервером, даже если они кэшировали определения инструментов.", + mcpToolListConnections: "Список подключений", + mcpToolListDatabases: "Список баз данных", + mcpToolListTables: "Список таблиц", + mcpToolDescribeTable: "Описать таблицу", + mcpToolListRoutines: "Список процедур", + mcpToolGetRoutineSource: "Исходный код процедуры", + mcpToolGetSchemaContext: "Контекст схемы", + mcpToolExecuteQuery: "Выполнить SQL / команды Mongo", + mcpToolExecuteBatch: "Выполнить пакет SQL", + mcpToolOpenSession: "Открыть сеанс запросов", + mcpToolBeginTransaction: "Начать транзакцию", + mcpToolCommitTransaction: "Зафиксировать транзакцию", + mcpToolRollbackTransaction: "Откатить транзакцию", + mcpToolCloseSession: "Закрыть сеанс запросов", + mcpToolExecuteRedisCommand: "Выполнить команду Redis", + mcpToolPeekMessages: "Читать сообщения Kafka", + mcpToolSendMessage: "Отправить сообщение в очередь", + mcpToolAddConnection: "Добавить подключение", + mcpToolDuplicateConnection: "Дублировать подключение", + mcpToolRemoveConnection: "Удалить подключение", + mcpToolOpenTable: "Открыть таблицу в DBX", + mcpToolExecuteAndShow: "Выполнить и показать в DBX", + supportInfoTitle: "Информация для поддержки", + supportInfoDescription: "Скопируйте эти сведения о среде при создании обращений или запросе помощи.", + supportInfoCopy: "Скопировать информацию для поддержки", + supportInfoCopied: "Скопировано", + supportInfoLoading: "Загрузка информации для поддержки...", + supportInfoLoadFailed: "Не удалось загрузить полную информацию для поддержки: {message}", + supportInfoAppVersion: "Версия DBX", + supportInfoRuntime: "Среда выполнения", + supportInfoRuntimeDesktop: "Настольное приложение", + supportInfoRuntimeWeb: "Веб", + supportInfoOperatingSystem: "Операционная система", + supportInfoArchitecture: "Архитектура", + supportInfoUserAgent: "User-Agent", + supportInfoDatabaseTypes: "Типы баз данных", + supportInfoLocalDriverVersions: "Версии локальных драйверов", + supportInfoAiProviders: "Поставщики ИИ", + supportInfoUnknown: "Неизвестно", + settingsTransferTitle: "Импорт и экспорт настроек", + settingsTransferDescription: "Экспортируйте настройки приложения в файл для резервной копии конфигурации или восстановите настройки из файла резервной копии.", + settingsTransferExport: "Экспорт", + settingsTransferImport: "Импорт", + settingsTransferExportSuccess: "Настройки экспортированы", + settingsTransferExportFailed: "Не удалось экспортировать настройки: {message}", + settingsTransferExportChoiceTitle: "Неприменённые изменения", + settingsTransferExportChoiceMessage: "У вас есть неприменённые изменения настроек. Экспорт сохранённых настроек не включит их.", + settingsTransferExportChoiceSaved: "Экспортировать сохранённые настройки", + settingsTransferExportChoiceApplied: "Применить и экспортировать", + settingsTransferApplyBlocked: "Неустранённые конфликты настроек мешают применению и экспорту.", + settingsTransferImportReadFailed: "Не удалось прочитать файл настроек: {message}", + settingsTransferImportInvalidJson: "Файл не является допустимым файлом настроек JSON.", + settingsTransferImportUnsupportedVersion: "Неподдерживаемая версия формата файла настроек: v{version}. Поддерживаемая версия: v{supported}.", + settingsTransferImportInvalidStructure: "Структура файла настроек недопустима.", + settingsTransferImportEmpty: "Файл настроек не содержит настроек для импорта.", + settingsTransferImportFieldInvalid: "Файл настроек содержит недопустимые поля. Импорт отменён: {fields}", + settingsTransferImportFileTooLarge: "Файл настроек слишком большой. Максимальный размер: {limit}.", + settingsTransferImportConfirmTitle: "Импорт настроек", + settingsTransferImportConfirmFile: "Файл", + settingsTransferImportConfirmSourceVersion: "Версия исходного приложения", + settingsTransferImportConfirmIncludes: "Включает", + settingsTransferImportConfirmDraftWarning: "В этих категориях есть неприменённые изменения, которые будут заменены: {categories}", + settingsTransferImportConfirmAction: "Загрузить настройки", + settingsTransferImportLoaded: "Настройки загружены. Нажмите «Применить», чтобы сохранить их.", + settingsTransferCategoryOther: "Прочее", + qqGroup: "Группа QQ", + feishuGroup: "Группа Feishu", + wechatGroup: "Группа WeChat", + wechatGroupInvite: "Приглашение Tencent Docs", + openSource: "Репозиторий с открытым исходным кодом", + officialDocs: "Официальная документация", + changelogTitle: "Список изменений", + changelogDescription: "Просмотрите нововведения каждого выпуска.", + changelogLoading: "Загрузка списка изменений...", + changelogLoadFailed: "Не удалось загрузить список изменений.", + changelogEmpty: "Записей в списке изменений пока нет.", + changelogPublishedOn: "Опубликовано {date}", + changelogNew: "НОВОЕ", + changelogLoadMore: "Загрузить ещё", + changelogOpenWebsite: "Посмотреть на сайте", + changelogOpenGitHub: "Выпуск на GitHub", + changelogNoDetails: "Подробности см. в выпуске на GitHub.", + changelogRetry: "Повторить", + changelogSectionAdded: "Новые возможности", + changelogSectionImproved: "Улучшения", + changelogSectionFixed: "Исправления ошибок", + changelogSectionChanged: "Изменения", + changelogSectionRemoved: "Удалено", + shortcutUppercaseSelection: "Преобразовать выделенное в верхний регистр", + shortcutLowercaseSelection: "Преобразовать выделенное в нижний регистр", + shortcutConvertNamingStyle: "Переключить стиль именования", + shortcutExPasteSqlInCondition: "ExPaste: вставить как условие IN", + }, + driverStore: { + jreDirRemoveFailed: "Не удалось удалить старый каталог JRE: {path} (исходная ошибка: {error})", + jreDirRemoveFailedWindows: + "Не удалось удалить старый каталог JRE: {path}\nВозможные причины:\n - процесс dbx Agent / java всё ещё удерживает каталог\n - антивирус сканирует его\nЗакройте любой процесс, который может удерживать каталог, или перезапустите dbx и повторите попытку.\n(исходная ошибка: {error})", + jreInUseByDrivers: "JRE {jre} используется драйверами: {drivers}. Сначала удалите их.", + offlinePackageRegistryMissing: "agent-registry.json не найден в ZIP; это не допустимый автономный пакет драйверов.", + progressJreExtract: "Извлечение JRE...", + progressDownloadJre: "Загрузка JRE", + progressDownloadDriver: "Загрузка драйвера", + progressDownloadJdbcPlugin: "Загрузка плагина JDBC", + progressJdbcPluginExtract: "Установка плагина JDBC...", + usageTitle: "Использование хранилища", + usageTotal: "Всего {size}", + usageTotalLabel: "Всего", + calculating: "Вычисление...", + usageManagedJre: "Управляемая JRE", + usageAgentDrivers: "Встроенные агенты драйверов", + usageDownloadCache: "Кэш загрузок", + usageJdbcPlugin: "Плагин JDBC", + usageJdbcDriverJars: "JAR-файлы драйверов JDBC", + clearDownloadCache: "Очистить кэш", + downloadCacheClearSuccess: "Кэш загрузок очищен", + downloadCacheClearFailed: "Не удалось очистить кэш загрузок: {error}", + driverCategoryAll: "Все драйверы", + driverCategoryLabel: "Категория", + offlineDownloadHint: "Для изолированных сред загрузите автономные пакеты драйверов на машине с доступом в интернет, затем импортируйте их здесь.", + offlineDownloadLink: "Автономные загрузки драйверов", + searchDrivers: "Поиск по имени, типу, версии драйвера...", + searchJdbcDrivers: "Поиск имени или пути драйвера JDBC...", + jdbcMavenCoordinatePlaceholder: "Координата Maven, например org.postgresql:postgresql:42.7.7", + jdbcMavenInstall: "Установить из Maven", + jdbcMavenInstallSuccess: "Драйвер JDBC из Maven установлен", + jdbcSourceMaven: "Maven", + jdbcSourceManual: "Вручную", + noMatchingDrivers: "Нет подходящих драйверов.", + statusFilterLabel: "Состояние установки", + statusFilterAll: "Все {count}", + statusFilterInstalled: "Установлено {count}", + statusFilterAvailable: "Доступно {count}", + installedBadge: "Установлено", + noInstalledDrivers: "Встроенные драйверы ещё не установлены.", + noInstalledDriversHint: "Переключитесь на «Все», чтобы просмотреть и установить нужные драйверы.", + noAvailableDrivers: "Все встроенные драйверы уже установлены.", + noAvailableDriversHint: "Переключитесь на «Все» или «Установлено», чтобы управлять драйверами на этом компьютере.", + showAllDrivers: "Показать все драйверы", + javaRuntimeSaved: "Параметры среды выполнения Java сохранены", + javaRuntimeSaveFailed: "Не удалось сохранить параметры среды выполнения Java: {error}", + chooseJavaExecutable: "Выбрать исполняемый файл Java", + driverInstallSuccess: "Драйвер {label} установлен", + driverInstallFailed: "Не удалось установить драйвер {label}: {error}", + driverInstallCancelled: "Установка драйвера {label} отменена", + driverUpdateBlocked: "Закройте эти подключения к базе данных перед обновлением драйверов: {labels}", + upgradeAllSuccess: "Обновлено драйверов: {count}", + upgradeAllPartial: "Обновлено драйверов: {count}. Пропущено: {failed}", + upgradeAllFailed: "Пакетное обновление не удалось: {error}", + upgradeAllCancelled: "Обновление отменено (прервано драйверов: {count})", + cancelInstall: "Отменить установку", + cancelUpgradeAll: "Отменить пакетное обновление", + driverUninstallSuccess: "Драйвер {label} удалён", + driverUninstallFailed: "Не удалось удалить драйвер {label}: {error}", + chooseOfflineDriverPackage: "Выбрать офлайн-пакет драйвера", + offlineImportSuccess: "Офлайн-импорт завершён. Установлено драйверов: {count}.", + offlineJreImportSuccess: "Офлайн-импорт завершён. Установлено JRE: {jreCount}.", + offlineImportWithJreSuccess: "Офлайн-импорт завершён. Установлено JRE: {jreCount} и драйверов: {count}.", + offlineImportFailed: "Офлайн-импорт не удался: {error}", + offlineImportPartial: "Офлайн-импорт завершён с проблемами: ошибок — {failed}, установлено JRE: {jreCount} и драйверов: {count}. {item}: {error}", + driverImportSuccess: "Драйвер {label} импортирован", + driverImportFailed: "Не удалось импортировать драйвер {label}: {error}", + chooseDriverJar: "Выбрать файл драйвера", + jreReinstallSuccess: "JRE {jre} переустановлен", + jreReinstallFailed: "Не удалось переустановить JRE {jre}: {error}", + jreUninstallSuccess: "JRE {jre} удалён", + chooseJdbcPluginZip: "Выбрать zip-файл плагина JDBC", + agentDrivers: "Встроенные драйверы", + jdbcDrivers: "Драйверы JDBC", + importing: "Импорт...", + importOfflinePackage: "Импортировать офлайн-пакет", + offlineExport: "Экспортировать офлайн-пакет", + offlineExportTitle: "Экспорт офлайн-пакета Agent", + offlineExportDescription: "Выберите управляемые DBX драйверы Agent для включения. Пакет совместим только с текущей платформой.", + offlineExportPlatform: "Платформа", + offlineExportSelectedCount: "Выбрано {selected} из {total}", + offlineExportSelectAll: "Выбрать все", + offlineExportClear: "Очистить", + offlineExportNoDrivers: "Подходящие управляемые DBX драйверы Agent не установлены.", + offlineExportArtifactJar: "Java JAR", + offlineExportArtifactNative: "Нативный", + offlineExportArtifactUnknown: "Неизвестно", + offlineExportPreparing: "Подготовка предпросмотра экспорта...", + offlineExportJreSummary: "Управляемые JRE будут включены автоматически: {count}.", + offlineExportSecurityHint: "Включаются только управляемые DBX артефакты и необходимые управляемые JRE. Локальные пути, настройки и внешние драйверы исключаются.", + offlineExportStart: "Экспортировать драйверов: {count}", + offlineExporting: "Экспорт...", + offlineExportPreviewFailed: "Не удалось подготовить экспорт: {error}", + offlineExportChooseDestination: "Сохранить офлайн-пакет Agent", + offlineExportSuccess: "Экспортировано {file}: драйверов — {drivers}, JRE — {jres}, {size}.", + offlineExportFailed: "Экспорт офлайн-пакета не удался: {error}", + offlineExportUnavailable_unmanagedInstall: "Этот артефакт не отслеживается как установка, управляемая DBX.", + offlineExportUnavailable_localInstall: "Локально импортированные сборки Agent не включаются.", + offlineExportUnavailable_launchConfig: "Пользовательские конфигурации запуска привязаны к конкретной машине.", + offlineExportUnavailable_missingArtifact: "Установленный артефакт Agent отсутствует.", + offlineExportUnavailable_invalidArtifact: "Установленный артефакт Agent недействителен или повреждён.", + offlineExportUnavailable_unsafeSource: "Артефакт находится вне управляемого хранилища или использует символическую ссылку.", + offlineExportUnavailable_externalDriverRequired: "Для этого Agent требуется внешний драйвер, предоставленный пользователем.", + offlineExportUnavailable_missingManagedJre: "Необходимая управляемая DBX JRE не установлена.", + offlineExportUnavailable_invalidManagedJre: "Необходимая управляемая DBX JRE недействительна или небезопасна.", + refresh: "Обновить", + javaRuntime: "Среда Java", + javaRuntimeManaged: "JRE, управляемая DBX", + javaRuntimeSystem: "Системная java", + javaRuntimeCustom: "Пользовательский путь", + saving: "Сохранение...", + customJavaPathPlaceholder: "/путь/к/java или /путь/к/jdk", + choose: "Выбрать", + systemJavaHint: "java определяется сначала из JAVA_HOME, затем из PATH.", + jreRuntimeTitle: "Среда выполнения JRE {jre}", + notInstalled: "Не установлено", + reinstalling: "Переустановка", + installing: "Установка", + install: "Установить", + reinstall: "Переустановить", + uninstall: "Удалить", + jreRuntime: "Среда выполнения JRE", + jreRuntimeAutoDownloadHint: "Скачивается автоматически при первой установке драйвера", + driversUpdatable: "Доступно обновлений драйверов: {count}", + updatesAvailableTitle: "Доступны обновления", + updatesAvailableDescription: "Для указанных ниже драйверов доступны новые версии. Обновите их, чтобы получить новые возможности и исправления.", + allDriversTitle: "Все драйверы", + upgradingProgress: "Обновление ({current}/{total})", + upgradeAll: "Обновить все", + queued: "В очереди", + importLocalJar: "Импортировать локальный файл драйвера", + updating: "Обновление", + update: "Обновить", + localInstall: "Локальная установка", + localInstallHint: "Для машин без доступа к сети: на другом компьютере с интернетом скачайте официальный файл dbx-jdbc-plugin-*.zip со страницы DBX GitHub Releases, перенесите его сюда и выберите — сеть на этой машине не требуется.", + runtimeDrivers: "Среда выполнения", + pluginsTab: "Плагины", + pluginContributionsTitle: "Вклад плагинов во фронтенд", + pluginContributionsDescription: "Установленные плагины могут описывать формы подключения и другие элементы интерфейса, не внедряя код в главное окно DBX.", + noInstalledPlugins: "Нет установленных плагинов", + noInstalledPluginsDescription: "Установите бэкенд-плагин, чтобы увидеть здесь его вклад во фронтенд.", + pluginHostPreview: "Предпросмотр Host API", + pluginNoFrontendContribution: "Этот плагин пока не объявляет вклад во фронтенд.", + storageTab: "Хранилище", + runtimeTitle: "Среда выполнения драйвера", + runtimeHint: "Метрики среды выполнения собираются только пока эта панель открыта.", + runtimeRunning: "Работает", + runtimeMemory: "Память", + runtimeHealth: "Состояние", + runtimeHealth_healthy: "В норме", + runtimeHealth_warning: "Предупреждение", + runtimeHealth_error: "Ошибка", + runtimeLastError: "Последняя ошибка", + runtimeEmpty: "Сред выполнения драйверов пока нет. Откройте подключение через Agent, чтобы запустить её.", + runtimeKindAgent: "Agent", + runtimeKindPlugin: "Плагин", + runtimeSourceDaemon: "Демон", + runtimeSourceConnection: "Подключение", + runtimeStatus_running: "Работает", + runtimeStatus_stopped: "Остановлено", + runtimeStatus_error: "Ошибка", + runtimeStatus_unknown: "Неизвестно", + runtimePid: "PID", + runtimeUptime: "Время работы", + runtimeActions: "Действия", + runtimeStop: "Остановить", + runtimeRestart: "Перезапустить", + runtimeControlConnectionOwned: "Закройте подключение к базе данных, чтобы остановить эту среду выполнения.", + runtimeStopSuccess: "Среда выполнения {label} остановлена", + runtimeStopFailed: "Не удалось остановить {label}: {error}", + runtimeRestartSuccess: "Среда выполнения {label} перезапущена", + runtimeRestartFailed: "Не удалось перезапустить {label}: {error}", + driverStoreDir: "Путь к хранилищу драйверов", + driverStoreDirDescription: "Задайте отдельные места хранения для плагина JDBC и данных Agent/JRE. После миграции приложение перезапустится автоматически.", + pluginStoreDir: "Каталог плагина JDBC", + pluginStoreDirDescription: "Хранит плагин JDBC, Maven-резолвер и jar-файлы драйверов JDBC.", + agentStoreDir: "Каталог Agent / JRE", + agentStoreDirDescription: "Хранит пакеты драйверов Agent, управляемые JRE и кэш среды выполнения.", + driverStoreDirDefault: "По умолчанию (каталог установки)", + driverStoreDirChange: "Изменить", + driverStoreDirReset: "Сбросить по умолчанию", + driverStoreDirMigrating: "Миграция {target}…", + driverStoreDirConfirm: "Изменение {target} перенесёт связанные данные драйверов в новое место. Во время миграции связанные подключения драйверов могут быть разорваны. После миграции приложение перезапустится автоматически. Продолжить?", + driverStoreDirMigrationFailed: "Миграция хранилища драйверов не удалась: {error}", + driverStoreDirDialogTitle: "Выберите {target}", + driverStoreDirSuccess: "{target} изменён, перезапуск…", + }, + databaseExport: { + title: "Экспорт базы данных", + options: "Параметры", + includeStructure: "Структура таблиц (DDL)", + includeCreateDatabase: "Включить создание базы данных (CREATE DATABASE / USE)", + dropTableIfExists: "Добавлять DROP TABLE IF EXISTS перед DDL", + omitAutoIncrement: "Пропускать AUTO_INCREMENT (для скриптов чистой установки)", + includeData: "Данные таблиц (INSERT)", + includeObjects: "Представления / Процедуры / Функции / Последовательности", + splitSqlOutput: "Разделить экспорт SQL на ZIP-архив", + splitSqlPartMaxMb: "Максимальный размер одной части SQL (МБ)", + splitSqlOutputDescription: "Создаёт ZIP-архив с пронумерованными частями SQL и манифестом. Части разделяются между целыми SQL-операторами ({min}–{max} МБ).", + databaseSelection: "Базы данных", + selectedDatabases: "Выбрано {selected}/{total}", + selectAllDatabases: "Выбрать все", + filterDatabases: "Поиск баз данных...", + clearDatabases: "Очистить", + tableSelection: "Таблицы", + selectedTables: "Выбрано {selected}/{total}", + selectAllTables: "Выбрать все", + filterTables: "Поиск таблиц...", + clearTables: "Очистить", + loadingTables: "Загрузка таблиц...", + tableLoadError: "Не удалось загрузить таблицы: {error}", + noTables: "Таблицы не найдены", + export: "Экспортировать", + exportAllDatabases: "Экспортировать все базы данных", + allSchemas: "Все схемы", + exporting: "Экспорт...", + preparing: "Подготовка экспорта (чтение таблиц и метаданных)...", + preparingObject: "Подготовка: {object}", + selectExportDirectory: "Выберите каталог экспорта", + currentDatabase: "База данных {current}/{total}", + currentTable: "Текущая: {table} ({current}/{total})", + rowsExported: "Обработано объектов: {current}/{total}, экспортировано строк: {count}", + allRowsExported: "Всего экспортировано строк: {count}", + exportSuccess: "База данных успешно экспортирована", + exportAllSuccess: "Успешно экспортировано баз данных: {count}", + exportSuccessWithErrors: "Экспорт завершён с ошибками объектов: {count}: {firstError}… Подробности см. в комментариях -- ERROR внутри экспортированного файла.", + exportAllSuccessWithErrors: "Экспортировано баз данных: {count}, но объектов с ошибками: {errorCount}: {firstError}… Подробности см. в комментариях -- ERROR внутри экспортированных файлов.", + allDatabasesTask: "Все базы данных ({count})", + exportError: "Экспорт не удался: {error}", + exportCancelled: "Экспорт отменён", + runInBackground: "Выполнять в фоне", + }, + databaseBackup: { + savedTimeZoneHint: "Следующий запуск использует сохранённый часовой пояс расписания.", + backgroundWorker: "Фоновые резервные копии после закрытия DBX", + backgroundLoginScope: "Работает, пока вы вошли в систему. Компьютер не должен уходить в сон.", + serverRuntime: "Сервер выполняет резервное копирование даже при закрытом браузере.", + workerLastSeen: "Последний сигнал воркера: {time}", + workerStarting: "Ожидание воркера резервного копирования", + serverDestination: "Корневой каталог резервных копий на сервере: {path}", + timeZone: "Часовой пояс (IANA)", + title: "Резервные копии баз данных", + schedules: "Расписания резервного копирования", + runtimeRequirement: "Запланированное резервное копирование выполняется, пока DBX открыт, в том числе свёрнутый в трей.", + addSchedule: "Добавить расписание", + oneShotBackup: "Создать копию сейчас", + oneShotDescription: "Запустить разовое резервное копирование базы данных. По завершении оно появится в истории.", + startBackup: "Начать копирование", + noSupportedConnections: "Перед добавлением расписания создайте подключение MySQL или PostgreSQL.", + editSchedule: "Изменить расписание", + defaultScheduleName: "Резервная копия базы данных", + oneShotName: "Разовое резервное копирование", + noSchedules: "Нет расписаний резервного копирования", + noSchedulesHint: "Создайте повторяющееся расписание резервного копирования или запустите разовое копирование сейчас.", + scheduleName: "Название расписания", + connection: "Подключение", + missingConnection: "Подключение отсутствует", + destination: "Каталог назначения", + selectDestination: "Выберите каталог резервных копий", + outputPathTemplate: "Шаблон пути вывода", + outputPathPreview: "Предпросмотр пути вывода", + fileNamePattern: "Шаблон имени файла", + fileNamePatternHint: "Используйте {'{'}schedule{'}'}, {'{'}date{'}'}, {'{'}timestamp{'}'}, {'{'}database{'}'} и {'{'}runId{'}'}. DBX добавит отсутствующее значение {'{'}database{'}'} и расширение автоматически.", + templateVariablesHelp: "Показать описания доступных переменных", + templateVariablesTitle: "Доступные переменные", + templateVariableSchedule: "Название расписания резервного копирования", + templateVariableDate: "Дата резервного копирования в формате YYYYMMDD", + templateVariableTimestamp: "Метка времени, используемая в пути вывода резервной копии", + templateVariableDatabase: "Название текущей целевой базы данных копирования", + templateVariableRunId: "Первые 8 символов идентификатора этого запуска копирования", + fileNamePatternInvalid: "Используйте имя файла без разделителей пути, зарезервированных символов и без завершающей точки или пробела.", + runDirectoryPattern: "Шаблон каталога запуска", + runDirectoryPatternHint: + "Относительный путь внутри каталога назначения. Используйте {'{'}schedule{'}'}, {'{'}date{'}'}, {'{'}timestamp{'}'} и {'{'}runId{'}'}. По умолчанию добавляется {'{'}runId{'}'} для дополнительной изоляции. Пример: {'{'}schedule{'}'}/{'{'}date{'}'}/{'{'}timestamp{'}'}-{'{'}runId{'}'}", + runDirectoryPreview: "Предпросмотр каталога", + runDirectoryPatternInvalid: "Используйте относительный путь без сегментов . или ..", + compression: "Сжатие", + compressionNone: "Без сжатия (.sql)", + compressionGzip: "Gzip (.sql.gz)", + searchConnections: "Поиск подключений…", + noMatchingConnections: "Подходящие подключения не найдены", + searchDatabases: "Поиск баз данных…", + noMatchingDatabases: "Подходящие базы данных не найдены", + databaseListLoadFailed: "Не удалось загрузить базы данных для {name}. Проверьте это подключение или выберите другое.", + databases: "Базы данных", + allDatabases: "Все базы данных", + databaseCount: "Баз данных: {count}", + tableScope: "Область таблиц", + allTables: "Все таблицы и представления", + includeTables: "Только совпадения", + excludeTables: "Исключить совпадения", + tablePatterns: "Правила имён таблиц", + tablePatternsPlaceholder: "orders, audit_*, public.users", + tablePatternsHint: "Разделяйте правила запятыми. Поддерживаются подстановочные знаки * и ?, а также schema.table.", + includedTablePatterns: "Правил включения: {count}", + excludedTablePatterns: "Правил исключения: {count}", + frequency: "Частота", + frequencyHourly: "Каждые несколько часов", + frequencyDaily: "Ежедневно", + frequencyWeekly: "Еженедельно", + intervalHours: "Интервал (часы)", + time: "Время", + weekday: "День недели", + retention: "Хранить последние запуски", + contents: "Содержимое копии", + enabled: "Расписание включено", + enabledHint: "Следующий запуск рассчитывается по вашему местному часовому поясу.", + nextRun: "Далее: {time}", + nextRunPreview: "Следующий запуск: {time}", + keepRuns: "Хранить {count}", + everyHours: "Каждые {count} ч.", + dailyAt: "Ежедневно в {time}", + weeklyAt: "{weekday} в {time}", + never: "Никогда", + enable: "Включить расписание", + disable: "Отключить расписание", + runNow: "Создать копию сейчас", + cancel: "Отменить копирование", + cancelling: "Отмена…", + cancelRequested: "Запрошена отмена. Остановка текущей операции.", + edit: "Изменить", + delete: "Удалить", + scheduleCreated: "Расписание резервного копирования создано", + scheduleUpdated: "Расписание резервного копирования обновлено", + deleteSchedule: "Удалить расписание", + deleteScheduleConfirm: "Удалить расписание «{name}»? Существующие файлы копий останутся в истории.", + cannotDeleteRunningSchedule: "Нельзя удалить запущенное расписание резервного копирования", + history: "История резервного копирования", + noHistory: "Резервных копий пока нет", + allConnections: "Все подключения", + searchHistoryConnections: "Поиск подключений…", + backupMethod: "Способ копирования", + allBackupMethods: "Все способы", + backupStatus: "Статус копирования", + allStatuses: "Все статусы", + noFilteredHistory: "Подходящих записей копирования нет", + selectAllFiltered: "Выбрать все отфильтрованные", + selectRun: "Выбрать {name}", + selectedRuns: "Выбрано: {count}", + deleteSelected: "Удалить выбранные", + showFiles: "Показать файлы копий", + scheduledTrigger: "По расписанию", + manualTrigger: "Вручную", + oneShotTrigger: "Разовое", + fileCount: "Файлов: {count}", + progress: "Ход резервного копирования", + renameBackup: "Переименовать копию", + backupName: "Название копии", + backupRenamed: "Копия переименована", + revealFile: "Показать в файловом менеджере", + restore: "Восстановить", + deleteBackup: "Удалить копию", + deleteBackupConfirm: "Удалить эту резервную копию и её SQL-файлы ({count} шт.)? Это действие необратимо.", + deleteBackupsConfirm: "Удалить резервных копий: {count} и их SQL-файлы ({files} шт.)? Это действие необратимо.", + backupDeleted: "Копия удалена", + backupsDeleted: "Удалено копий: {count}", + runSuccess: "Копирование завершено, файлов: {count}", + runCancelled: "Копирование отменено", + runFailed: "Копирование не удалось: {error}", + unknownError: "Неизвестная ошибка", + status: { + running: "Выполняется", + success: "Завершено", + failed: "Ошибка", + cancelled: "Отменено", + }, + weekdays: { + sunday: "Воскресенье", + monday: "Понедельник", + tuesday: "Вторник", + wednesday: "Среда", + thursday: "Четверг", + friday: "Пятница", + saturday: "Суббота", + }, + }, + mqTopics: { + title: "Топики", + searchPlaceholder: "Поиск топиков", + includeNonPersistent: "Включать непостоянные топики", + refresh: "Обновить", + refreshing: "Обновление...", + createTopic: "Создать топик", + selectTenantNamespace: "Сначала выберите тенант и пространство имён", + loading: "Загрузка...", + noTopics: "В этом пространстве имён нет топиков", + noMatches: "Подходящие топики не найдены", + name: "Имя", + type: "Тип", + partitions: "Партиции", + actions: "Действия", + nonPersistent: "Непостоянный", + partitionedTopic: "Партиционированный топик", + normalTopic: "Обычный топик", + systemTopic: "Системный топик", + includeSystemTopics: "Включать системные топики", + noUserTopics: "Пользовательских топиков нет. Включите фильтры типов, чтобы просмотреть внутренние топики, топики повторов или DLQ.", + typeFilter: "Фильтры типов", + messageType: "Тип сообщения", + messageTypeHint: "Сохраняет RocketMQ message.type в конфигурации топика брокера, как в RocketMQ Dashboard.", + rocketmqType: { + normal: "Обычный", + delay: "С задержкой", + fifo: "Упорядоченный", + transaction: "Транзакционный", + unspecified: "Не указан", + retry: "Повтор", + dlq: "Недоставленные", + system: "Системный", + }, + partitionCount: "Партиций: {count}", + partitionsUnknown: "Неизвестное число партиций", + adjustPartitions: "Изменить партиции", + delete: "Удалить", + tenantNamespace: "Тенант / пространство имён", + topicName: "Имя топика", + topicNamePlaceholder: "напр. my-topic", + persistentRecommended: "Постоянный топик (рекомендуется)", + persistentHint: "Постоянные топики хранят сообщения на диске; непостоянные — только в памяти.", + enablePartitions: "Включить партиции", + partitionQuantity: "Число партиций", + partitionHint: "Партиции повышают параллелизм, но увеличивают потребление ресурсов.", + cancel: "Отмена", + create: "Создать", + updatePartitionsTitle: "Изменение партиций: {name}", + currentPartitions: "Текущие партиции", + newPartitions: "Новые партиции", + partitionMinHint: "Число партиций можно только увеличивать, но не уменьшать. Минимум: {min}", + update: "Обновить", + readOnly: "Это подключение доступно только для чтения, операции записи невозможны.", + topicNameRequired: "Укажите имя топика", + currentPartitionsUnknown: "Текущее число партиций неизвестно, поэтому безопасно изменить партиции нельзя.", + partitionMustIncrease: "Новое число партиций должно быть больше текущего.", + confirmDelete: "Удалить топик «{name}»? Это действие необратимо.", + queues: "Очереди", + tabQueues: "Очереди", + tabExchanges: "Exchange", + queueCount: "Очередей: {count}", + clusterName: "Кластер", + brokerName: "Брокер", + allBrokers: "Все мастер-брокеры", + readQueues: "Очереди чтения", + writeQueues: "Очереди записи", + perm: "Разрешение", + permReadWrite: "Чтение + запись (6)", + permRead: "Только чтение (4)", + permWrite: "Только запись (2)", + actionStatus: "Статус", + actionRoute: "Маршрут", + actionConsumers: "Потребители", + actionConfig: "Конфигурация", + actionSend: "Отправить", + actionMessageQuery: "Запрос сообщений", + actionReset: "Сбросить смещение", + actionSkip: "Пропустить накопленное", + topicStatusTitle: "Статус топика: {name}", + topicRouteTitle: "Маршрут топика: {name}", + topicConsumersTitle: "Потребители: {name}", + topicConfigTitle: "Конфигурация топика: {name}", + topicConfigHint: "Как в RocketMQ Dashboard: редактируются только счётчики очередей чтения/записи и разрешения. Тип сообщения задаётся при создании топика.", + topicResetTitle: "Сброс смещения: {name}", + topicSkipTitle: "Пропуск накопленного: {name}", + confirmSkip: "Пропустить накопленное для всех групп потребителей топика «{name}»?", + skipHint: "Сбрасывает все подписанные группы потребителей на последнее смещение для этого топика.", + saveConfig: "Сохранить конфигурацию", + resetPosition: "Сбросить позицию", + positionEarliest: "Сначала", + positionLatest: "С конца", + positionTimestamp: "По времени", + timestamp: "Время", + invalidTimestamp: "Введите корректное время", + resetTimePreview: "Выбранное время: {time}", + noConsumerGroups: "Нет групп потребителей", + noConsumers: "На этот топик не подписана ни одна группа потребителей", + manageConsumers: "Управление", + routeQueues: "Данные очередей", + routeBrokers: "Данные брокера", + brokerAddrs: "Адреса брокеров", + noRouteData: "Нет данных маршрута", + noQueueStats: "Нет статистики очередей", + noConfig: "Конфигурация топика не получена", + queueId: "Очередь", + beginOffset: "Минимальное смещение", + endOffset: "Максимальное смещение", + messageCount: "Сообщения", + rabbitmqQueueType: "Тип", + rabbitmqQueueTypeHint: "Тип очереди, сообщаемый management API (type или x-queue-type); classic / quorum / stream", + rabbitmqQueueTypeUnknown: "Очередь", + rabbitmqFeatures: "Свойства", + rabbitmqState: "Состояние", + rabbitmqArguments: "Аргументы", + consumers: "Потребители", + rabbitmqRates: "Показатели", + rabbitmqPublishRate: "Публикация", + rabbitmqDeliverRate: "Доставка/получение", + rabbitmqAckRate: "Подтверждение", + }, + mqExchanges: { + searchPlaceholder: "Поиск exchange", + refresh: "Обновить", + refreshing: "Обновление...", + createExchange: "Создать exchange", + selectNamespace: "Сначала выберите виртуальный хост", + loading: "Загрузка...", + noExchanges: "В этом виртуальном хосте нет exchange", + noMatches: "Подходящие exchange не найдены", + name: "Имя", + type: "Тип", + durable: "Устойчивый", + autoDelete: "Автоудаление", + actions: "Действия", + builtin: "Встроенный", + viewBindings: "Привязки", + delete: "Удалить", + yes: "Да", + no: "Нет", + bindingsTitle: "Привязки из {name}", + bindDestination: "Привязать", + noBindings: "Из этого exchange нет привязок", + bindingSource: "Источник", + bindingDestination: "Назначение", + bindingType: "Тип", + routingKey: "Ключ маршрутизации", + arguments: "Аргументы", + unbind: "Отвязать", + destinationTypeQueue: "Очередь", + destinationTypeExchange: "Exchange", + virtualHost: "Виртуальный хост", + namePlaceholder: "напр. dbx-events", + cancel: "Отмена", + create: "Создать", + bind: "Привязать", + bindDialogTitle: "Привязать к {name}", + queueNamePlaceholder: "напр. dbx-queue", + exchangeNamePlaceholder: "напр. dbx-events", + routingKeyPlaceholder: "напр. orders.*", + argumentsPlaceholder: "Необязательный объект JSON, напр. {'{'}\"x-match\": \"all\"{'}'}", + nameRequired: "Укажите имя exchange", + destinationRequired: "Укажите назначение", + argumentsMustBeObject: "Аргументы должны быть объектом JSON", + readOnly: "Это подключение доступно только для чтения, операции записи невозможны.", + confirmDelete: "Удалить exchange «{name}»? Это действие необратимо.", + confirmUnbind: "Удалить привязку из «{source}» в «{destination}»?", + }, + mqClientConnections: { + searchPlaceholder: "Поиск подключений", + refresh: "Обновить", + refreshing: "Обновление...", + loading: "Загрузка...", + noConnections: "Нет клиентских подключений", + noMatches: "Подходящие подключения не найдены", + name: "Имя", + user: "Пользователь", + peerAddress: "Адрес узла", + state: "Состояние", + channels: "Каналы", + recvRate: "Скорость приёма", + sendRate: "Скорость отправки", + connectedAt: "Подключено в", + actions: "Действия", + closeConnection: "Закрыть подключение", + confirmClose: "Закрыть подключение «{name}»? Все его каналы будут закрыты, действие необратимо.", + readOnly: "Это подключение доступно только для чтения; операции записи отключены.", + noChannels: "У этого подключения нет каналов", + channelName: "Канал", + prefetch: "Предвыборка", + unacked: "Неподтверждённые", + consumers: "Потребители", + }, + mqUserPermissions: { + usersTitle: "Пользователи", + permissionsTitle: "Разрешения", + refresh: "Обновить", + refreshing: "Обновление...", + loading: "Загрузка...", + createUser: "Создать пользователя", + grantPermission: "Предоставить разрешение", + searchUsers: "Поиск пользователей", + noUsers: "Нет пользователей", + noUserMatches: "Нет подходящих пользователей", + name: "Имя", + tags: "Теги", + actions: "Действия", + delete: "Удалить", + confirmDeleteUser: 'Удалить пользователя "{name}"? Это действие нельзя отменить.', + password: "Пароль", + tagsPlaceholder: "Через запятую, например: administrator, monitoring", + nameRequired: "Укажите имя пользователя", + passwordRequired: "Укажите пароль", + cancel: "Отмена", + create: "Создать", + user: "Пользователь", + vhost: "Виртуальный хост", + configure: "Настройка", + write: "Запись", + read: "Чтение", + noPermissions: "Нет разрешений", + revoke: "Отозвать", + confirmRevoke: 'Отозвать разрешение пользователя "{user}" на виртуальном хосте "{vhost}"?', + grant: "Предоставить", + selectUser: "Выберите пользователя", + selectVhost: "Выберите виртуальный хост", + patternHint: "Регулярное выражение для сопоставления с именами ресурсов; пустое значение по умолчанию — .* (все).", + userRequired: "Выберите пользователя", + vhostRequired: "Выберите виртуальный хост", + readOnly: "Это подключение доступно только для чтения; операции записи отключены.", + }, + mqRabbitMqPolicies: { + title: "Политики", + refresh: "Обновить", + refreshing: "Обновление...", + loading: "Загрузка...", + createPolicy: "Создать политику", + editPolicy: "Изменить политику", + noPolicies: "Нет политик", + name: "Имя", + vhost: "Виртуальный хост", + pattern: "Шаблон", + applyTo: "Применить к", + priority: "Приоритет", + definition: "Определение", + actions: "Действия", + edit: "Изменить", + delete: "Удалить", + confirmDelete: 'Удалить политику "{name}" на виртуальном хосте "{vhost}"?', + cancel: "Отмена", + save: "Сохранить", + selectVhost: "Выберите виртуальный хост", + definitionKey: "Ключ", + definitionValue: "Значение", + addDefinition: "Добавить запись определения", + patternHint: "Регулярное выражение для сопоставления с именами очередей/обменников.", + nameRequired: "Укажите имя политики", + vhostRequired: "Выберите виртуальный хост", + patternRequired: "Укажите шаблон", + readOnly: "Это подключение доступно только для чтения; операции записи отключены.", + }, + mqRabbitMqMonitoring: { + title: "Мониторинг кластера", + loading: "Загрузка...", + overviewTitle: "Обзор", + messagesReady: "Готовые сообщения", + messagesUnacked: "Неподтверждённые сообщения", + publishRate: "Скорость публикации", + deliverRate: "Скорость доставки", + ackRate: "Скорость подтверждения", + totalQueues: "Очереди", + totalExchanges: "Обменники", + totalConnections: "Подключения", + totalChannels: "Каналы", + totalConsumers: "Потребители", + nodesTitle: "Узлы", + nodeName: "Узел", + status: "Статус", + running: "Работает", + stopped: "Остановлен", + memory: "Память", + diskFree: "Свободно на диске", + fileDescriptors: "Файловые дескрипторы", + sockets: "Сокеты", + uptime: "Время работы", + noNodes: "Нет узлов", + }, + mqRocketmq: { + consumerGroupTitle: "Группы потребителей", + searchConsumerGroup: "Поиск группы потребителей", + connectionNotReady: "Подключение не готово. Обновите данные кластера.", + tabSend: "Отправить сообщение", + tabQuery: "Поиск сообщений", + noDlqTopics: "Темы DLQ не найдены. Включите фильтр типа DLQ на вкладке «Темы» и обновите.", + topicFilterAll: "Все", + topicFilterBusiness: "Бизнес", + topicFilterDlq: "DLQ", + actionProduce: "Публикация", + actionConsume: "Потребление", + aclTitle: "Контроль доступа", + actionMessageQuery: "Поиск сообщений", + actionSendMessage: "Отправить сообщение", + actionMore: "Ещё", + actionDetailGroup: "Подробности", + actionResetOffset: "Сбросить смещение", + dlqConsumerGroup: "Группа потребителей", + dlqConsumerGroupPlaceholder: "Группа потребителей (необязательно)", + dlqQueryByKey: "Поиск по ключу", + viewDlqMessages: "Просмотр сообщений DLQ", + namesrvAddr: "NameServer", + }, + mqAdmin: { + viewTenant: "Просмотр тенанта", + viewNamespace: "Просмотр пространства имён", + viewTopic: "Просмотр темы", + connectionMissing: "Подключение не найдено. Переподключитесь и повторите попытку.", + writeDeniedReadOnly: "Это подключение доступно только для чтения, операции записи недоступны.", + readOnly: "Только чтение", + allNamespaces: "Все пространства имён", + newNamespace: "Новое пространство имён", + namespace: "Пространство имён", + selectNamespaceToCreate: "Выберите конкретное пространство имён для создания", + selectNamespaceToWrite: "Выберите конкретное пространство имён для выполнения этого действия", + tabTenants: "Тенанты", + tabNamespaces: "Пространства имён", + tabTopics: "Темы", + tabSubscriptions: "Подписки", + tabConsumerGroups: "Группы потребителей", + tabMonitoring: "Мониторинг", + tabClients: "Клиенты", + tabMessages: "Сообщения", + tabBroker: "Брокер", + tabCluster: "Кластер", + tabConsumers: "Потребители", + tabProducers: "Производители", + tabDlq: "DLQ", + tabTrace: "Трассировка", + tabAcl: "ACL", + tabPolicies: "Политики", + tabPermissions: "Разрешения", + tabRawApi: "Raw API", + }, + mqMessages: { + title: "Отправить сообщение", + clear: "Очистить", + selectNamespaceOrTopicFirst: "Сначала выберите пространство имён или тему", + readOnlyCannotSend: "Это подключение доступно только для чтения, отправка сообщений недоступна", + selectTargetTopic: "Выберите целевую тему", + messageContentRequired: "Укажите содержимое сообщения", + sendSuccess: "Сообщение отправлено — раздел: {partition}, смещение: {offset}", + targetTopic: "Целевая тема", + topicLoading: "Загрузка...", + topicSearchPlaceholder: "Выберите тему", + refreshTopicList: "Обновить список тем", + topicOptionWithPartitions: "{label} (разделов: {partitions})", + noTopicsAvailable: "Нет доступных тем", + topicSearchHint: "Введите текст для фильтрации списка. Выбор темы выполняет запрос. Нажмите ещё раз, чтобы выполнить поиск; текущая тема будет показана серым.", + messageKey: "Ключ сообщения", + messageTag: "Тег сообщения", + exchange: "Обменник", + exchangePlaceholder: "Пусто = обменник по умолчанию", + exchangeHint: "Если указано, сообщение публикуется в этот обменник, а не напрямую в очередь.", + routingKey: "Ключ маршрутизации", + optional: "Необязательно", + messageContent: "Содержимое сообщения", + formatJson: "Форматировать JSON", + messageHeaders: "Заголовки", + headersPlaceholder: "ключ: значение (по одному в строке)", + sending: "Отправка...", + sendMessage: "Отправить сообщение", + messageList: "Сообщения", + loadMessages: "Загрузить сообщения", + loading: "Загрузка...", + peekDefaultHint: "Без указания раздела читает все разделы с самого начала.", + count: "Количество", + advancedFilter: "Расширенные (раздел / смещение)", + partition: "Раздел", + partitionPlaceholderAll: "Пусто = все", + offset: "Смещение", + offsetPlaceholderEarliest: "Пусто = с начала", + offsetPlaceholderRequired: "Обязательно", + startPosition: "Начальная позиция", + kafkaLatest: "Последние N сообщений (по умолчанию)", + kafkaEarliest: "Самые ранние сообщения", + kafkaOffset: "С указанного смещения", + timeOrder: "Порядок по времени", + newestFirst: "Сначала новые", + oldestFirst: "Сначала старые", + kafkaLatestHint: "Читает до N кандидатов из каждого раздела, затем выбирает N самых новых по времени во всей теме.", + kafkaEarliestHint: "Читает с самого раннего доступного сообщения в каждом выбранном разделе.", + kafkaOffsetHint: "Читает с указанного смещения в выбранном разделе или во всех разделах, если оставить пустым.", + messagesLoading: "Загрузка сообщений...", + noMessages: "Нет сообщений", + filterLoadedPlaceholder: "Фильтр загруженных сообщений", + filterLoadedCount: "{matched} / {loaded}", + noMatchingMessages: "Нет загруженных сообщений, соответствующих фильтру", + peekIncomplete: "Результаты неполные: брокер не завершил формирование снимка.", + selectTopicBeforeLoad: "Выберите тему перед загрузкой сообщений", + partitionMustBeNonNegativeInt: "Раздел должен быть целым числом ≥ 0; оставьте пустым для всех разделов", + offsetMustBeNonNegativeInt: "Смещение должно быть целым числом ≥ 0; оставьте пустым для чтения с начала", + offsetMustBeNonNegativeIntRequired: "Смещение должно быть целым числом ≥ 0", + offsetRequiredForOffset: "При чтении с указанного смещения необходимо указать смещение", + metaPartition: "раздел {partition}", + metaOffset: "смещение {offset}", + metaKey: "ключ {key}", + jsonBodyPlaceholder: "{'{'}\"key\": \"value\"{'}'}", + queryTitle: "Поиск сообщений", + queryTabTopic: "Тема", + queryTabKey: "Ключ сообщения", + queryTabMsgId: "ID сообщения", + queryTopicLabel: "Тема", + selectTopicPlaceholder: "Выберите тему", + noQueryResults: "По заданным условиям ничего не найдено", + tableMessageId: "ID сообщения", + tableTag: "Тег", + tableKey: "Ключ", + tableStoreTime: "StoreTime", + tableOperation: "Операция", + viewDetails: "Просмотр", + messageDetails: "Детали сообщения", + search: "Поиск", + messageQuery: "Поиск сообщений", + queryByMsgId: "По ID сообщения", + queryByKey: "По ключу", + queryByTopic: "По теме и времени", + msgId: "ID сообщения", + msgIdPlaceholder: "например, 7F000001...", + msgIdRequired: "Укажите ID сообщения", + queryKey: "Ключ сообщения", + queryKeyPlaceholder: "Бизнес-ключ", + queryKeyRequired: "Укажите ключ сообщения", + beginTime: "Время начала", + endTime: "Время окончания", + maxNum: "Макс. сообщений", + invalidTimeRange: "Неверное время начала или окончания", + endTimeMustBeAfterBegin: "Время окончания должно быть позже времени начала", + query: "Запрос", + querying: "Выполнение запроса...", + messageOverview: "Обзор", + messageBody: "Тело", + resendMessage: "Отправить повторно", + payloadCopied: "Скопировано", + dlqConsumerGroupPlaceholder: "Группа потребителей (необязательно)", + }, + mqMonitoring: { + title: "Мониторинг", + autoRefresh: "Автообновление", + refreshInterval5s: "5 с", + refreshInterval10s: "10 с", + refreshInterval30s: "30 с", + refreshInterval60s: "60 с", + refreshing: "Обновление...", + refreshNow: "Обновить", + selectTopicFirst: "Сначала выберите тему", + loadingStats: "Загрузка данных мониторинга...", + kafkaTopicOverview: "Обзор темы Kafka", + partitionCount: "Разделы", + replicationFactor: "Фактор репликации", + messageCount: "Сообщения", + logEndOffset: "Смещение конца журнала", + offsetAndReplicaStatus: "Смещения и реплики", + beginOffset: "Начальное смещение", + leaderCount: "Лидеры", + isrHealthyPartitions: "ISR в норме", + noLeaderPartitions: "Нет лидера", + kafkaPartitionDetails: "Разделы Kafka", + noKafkaPartitionMetrics: "В ответе Kafka нет метрик разделов", + tablePartition: "Раздел", + tableBeginOffset: "Начальное смещение", + tableLogEndOffset: "Смещение конца журнала", + tableMessageCount: "Сообщения", + tableLeader: "Лидер", + tableReplicas: "Реплики", + tableIsr: "ISR", + tableStatus: "Статус", + statusNoLeader: "Нет лидера", + statusIsrIncomplete: "ISR неполный", + statusHealthy: "Норма", + messagesLoading: "Загрузка сообщений...", + noMessages: "Нет сообщений", + messageRate: "Скорость сообщений", + inboundRate: "Скорость входящих", + outboundRate: "Скорость исходящих", + inboundThroughput: "Входящая пропускная способность", + outboundThroughput: "Исходящая пропускная способность", + rateTrend: "Динамика скорости", + backlogTrend: "Динамика накопления", + consumerLag: "Отставание потребителя", + storageAndBacklog: "Хранилище и накопление", + storageSize: "Размер хранилища", + backlogSize: "Размер накопления", + backlogMessageCount: "Накопленные сообщения", + messageCounters: "Счётчики сообщений", + publishedMessages: "Опубликовано", + consumedMessages: "Получено", + connectionStats: "Подключения", + subscriptionCount: "Подписки", + producerCount: "Производители", + partitionDetails: "Разделы", + tableInbound: "Вход", + tableOutbound: "Выход", + tableInboundThroughput: "Вх. пропускная способность", + tableOutboundThroughput: "Исх. пропускная способность", + tableBacklogMessages: "Накопл. сообщ.", + tableBacklogSize: "Размер накопления", + tableProducers: "Производители", + tableSubscriptions: "Подписки", + producers: "Производители", + subscriptions: "Подписки", + tableName: "Имя", + tableRate: "Скорость", + tableAddress: "Адрес", + tableType: "Тип", + tableBacklog: "Накопление", + tableConsumers: "Потребители", + noProducers: "Нет производителей", + noSubscriptions: "Нет подписок", + noPartitionMetricsFromBroker: "Брокер не вернул метрики разделов", + nonPartitionedTopicNoDetails: "У неразделённых тем нет данных о разделах", + healthIndicators: "Состояние", + messageFlow: "Поток сообщений", + backlogStatus: "Накопление", + producersLabel: "Производители", + subscriptionsLabel: "Подписки", + flowActive: "Активен", + flowIdle: "Простой", + backlogNormal: "Норма", + backlogHigh: "Высокое", + producerConnected: "Подключён", + producerDisconnected: "Нет", + subscriptionActive: "Активна", + subscriptionNone: "Нет", + chartLegendIn: "Вход", + chartLegendOut: "Выход", + chartLegendMessages: "Сообщения", + chartLegendBytes: "Байты", + chartLegendConsumerLag: "Отставание потребителя", + chartAxisMsgPerSec: "сообщ/с", + chartAxisMsg: "сообщ", + chartAxisBytes: "байты", + chartAxisMs: "мс", + metaPartition: "раздел {partition}", + metaOffset: "смещение {offset}", + metaKey: "ключ {key}", + rocketmqTopicOverview: "Обзор темы RocketMQ", + rocketmqQueueDetails: "Детали смещений очередей", + queueCount: "Очереди", + brokerCount: "Брокеры", + tableQueue: "Очередь", + tableBroker: "Брокер", + noRocketMqQueueMetrics: "Метрики очередей не возвращены", + }, + mqTenants: { + title: "Управление тенантами", + createTenant: "Создать тенант", + notSupported: "Управление тенантами не поддерживается для этой системы обмена сообщениями", + readOnly: "Это подключение доступно только для чтения, операции записи недоступны.", + loading: "Загрузка...", + name: "Имя", + adminRoles: "Роли администратора", + allowedClusters: "Разрешённые кластеры*", + actions: "Действия", + none: "Нет", + edit: "Изменить", + delete: "Удалить", + createDialogTitle: "Создать тенант", + editDialogTitle: "Изменить тенант: {name}", + tenantName: "Имя тенанта*", + tenantNamePlaceholder: "например, my-tenant", + addRolePlaceholder: "Добавить роль", + add: "Добавить", + selectClustersPlaceholder: "Выберите разрешённые кластеры", + noClustersDetectedPlaceholder: "Кластеры не обнаружены; добавьте вручную", + clustersNotReturned: "Подключение не вернуло список кластеров", + addClusterPlaceholder: "Добавить кластер вручную", + clustersRequiredHint: "Выберите или добавьте хотя бы один разрешённый кластер", + cancel: "Отмена", + create: "Создать", + save: "Сохранить", + confirmDelete: 'Удалить тенант "{name}"? Это действие нельзя отменить.', + tenantNameRequired: "Укажите имя тенанта", + allowedClustersRequired: "Укажите разрешённые кластеры", + }, + mqNamespaces: { + title: "Управление пространствами имён", + createNamespace: "Создать пространство имён", + notSupported: "Управление пространствами имён не поддерживается для этой системы обмена сообщениями", + selectTenantFirst: "Сначала выберите тенант", + readOnly: "Это подключение доступно только для чтения, операции записи недоступны.", + loading: "Загрузка...", + name: "Имя", + tenant: "Тенант", + adminRoles: "Роли администратора", + actions: "Действия", + none: "Нет", + editRoles: "Изменить роли", + delete: "Удалить", + createDialogTitle: "Создать пространство имён", + namespaceName: "Имя пространства имён*", + namespaceNamePlaceholder: "например, my-namespace", + cancel: "Отмена", + create: "Создать", + confirmDelete: 'Удалить пространство имён "{name}"? Это действие нельзя отменить.', + namespaceNameRequired: "Укажите имя пространства имён", + }, + mqSubscriptions: { + title: "Управление подписками", + createSubscription: "Создать подписку", + selectTopicFirst: "Сначала выберите тему", + searchPlaceholder: "Поиск по имени подписки", + subscribedTopics: "Темы подписки", + readOnly: "Это подключение доступно только для чтения, операции записи недоступны.", + loading: "Загрузка...", + refresh: "Обновить", + refreshing: "Обновление...", + enriching: "Загрузка данных о подключённых клиентах...", + truncatedHint: "Показаны первые {count} групп потребителей (список ограничен). Уточните поиск, чтобы найти остальные.", + enrichFailedHint: "Не удалось загрузить данные об онлайн-участниках/темах ({error}). Показан только быстрый список.", + noSubscriptions: "Нет подписок для этой темы", + noConsumerGroups: "Нет групп потребителей", + noMatches: "Нет подходящих групп потребителей", + backlogPartialFailed: "Не удалось загрузить накопление для {count} тем(ы): {error}", + viewDetail: "Подробности", + editConfig: "Конфигурация", + save: "Сохранить", + consumerDetailTitle: "Детали группы потребителей: {name}", + consumerConfigTitle: "Конфигурация группы потребителей: {name}", + consumerOverview: "Обзор", + consumerTerminals: "Подключённые клиенты", + consumerConsumeDetail: "Детали потребления", + noOnlineConsumers: "Нет подключённых потребителей", + noConsumeDetail: "Нет данных о потреблении", + noQueueConsumeProgress: "Нет прогресса потребления очередей", + operationTopic: "Тема", + consumeDelay: "Накопление", + invalidTopicScope: "Недопустимая область темы", + lastConsumeTime: "Время последнего потребления", + broker: "broker", + queue: "queue", + consumerClient: "consumerClient", + brokerOffset: "brokerOffset", + consumerOffset: "consumerOffset", + diffTotal: "diffTotal", + lastTimestamp: "lastTimestamp", + consumeEnable: "Потребление включено", + consumeBroadcastEnable: "Широковещательное потребление включено", + consumeFromMinEnable: "Потребление с минимального смещения", + consumeMessageOrderly: "Упорядоченное потребление", + retryQueueNums: "Количество очередей повторов", + retryMaxTimes: "Макс. число повторов", + brokerId: "ID брокера", + whichBrokerWhenConsumeSlowly: "ID брокера для медленного потребления", + subscriptionName: "Имя подписки", + type: "Тип", + mode: "Режим", + typeFilter: "Фильтр по типу", + rocketmqGroupType: { + normal: "Обычная", + fifo: "Упорядоченная", + system: "Системная", + unknown: "Неизвестно", + }, + rocketmqGroupMode: { + clustering: "Кластерный", + broadcasting: "Широковещательный", + }, + backlog: "Накопление", + consumeRate: "Скорость потребления", + consumers: "Потребители", + actions: "Действия", + consumerCount: "{count} потребителей", + msgRate: "{rate} сообщ/с", + resetCursor: "Сбросить курсор", + skipMessages: "Пропустить сообщения", + clearBacklog: "Очистить накопление", + peek: "Просмотр сообщений", + expireMessages: "Устаревание сообщений", + delete: "Удалить", + createDialogTitle: "Создать подписку", + topic: "Тема", + subscriptionNameLabel: "Имя подписки*", + subscriptionNamePlaceholder: "например, my-subscription", + startPosition: "Начальная позиция", + startFromEarliest: "С самого раннего сообщения (Earliest)", + startFromLatest: "С самого позднего сообщения (Latest)", + resetDialogTitle: "Сбросить курсор: {name}", + resetTo: "Сбросить к", + earliest: "Самое раннее сообщение (Earliest)", + latest: "Самое позднее сообщение (Latest)", + timestamp: "Определённая метка времени", + timestampMs: "Метка времени (мс)", + partitionOffset: "Раздел и абсолютное смещение", + partition: "Раздел", + offset: "Смещение", + nonNegativeIntegerRequired: "Раздел и смещение должны быть неотрицательными целыми числами", + currentTime: "Текущее время: {time}", + reset: "Сбросить", + skipDialogTitle: "Пропустить сообщения: {name}", + skipMode: "Режим пропуска", + skipCount: "Пропустить указанное количество", + skipAll: "Пропустить всё накопление", + skipCountLabel: "Количество пропускаемых", + skip: "Пропустить", + peekDialogTitle: "Просмотр сообщений: {name}", + count: "Количество", + noPeekMessages: "Нет сообщений для просмотра", + close: "Закрыть", + expireDialogTitle: "Устаревание сообщений: {name}", + expireSeconds: "Время устаревания (секунды)", + expireHint: "Будут удалены все сообщения старше {seconds} секунд", + expire: "Сделать устаревшими", + cancel: "Отмена", + create: "Создать", + confirmDelete: 'Удалить подписку "{name}"? Это действие нельзя отменить.', + confirmClearBacklog: 'Очистить все накопленные сообщения подписки "{name}"?', + subscriptionNameRequired: "Укажите имя подписки", + peekMessageKey: "key={key}", + }, + mqKafkaConsumerGroups: { + title: "Группы потребителей", + searchPlaceholder: "Поиск группы или темы", + refresh: "Обновить", + refreshing: "Обновление...", + loading: "Загрузка групп потребителей...", + empty: "Нет групп потребителей", + noMatches: "Нет подходящих групп потребителей", + groupId: "ID группы", + state: "Состояние", + members: "Участники", + topics: "Темы", + totalLag: "Общее отставание", + partialData: "Некоторые метрики недоступны", + partitionDetail: "Детали отставания разделов", + noCommittedOffsets: "Нет зафиксированных смещений или назначенных разделов", + topic: "Тема", + openTopicSubscriptions: "Открыть подписки для {topic}", + partition: "Раздел", + committedOffset: "Зафиксированное смещение", + logEndOffset: "Конечное смещение журнала", + lag: "Отставание", + }, + mqClients: { + unloadTopicUnsupportedKafka: "Kafka не поддерживает выгрузку тем", + title: "Производители / потребители", + unloadTopic: "Выгрузить тему", + unloading: "Выгрузка...", + refresh: "Обновить", + refreshing: "Обновление...", + selectTopicFirst: "Сначала выберите тему", + rocketmqClusterHint: "Показывает всех активных производителей и узлы групп потребителей на брокере. Выберите тему, чтобы увидеть клиентов этой темы.", + confirmUnload: "Выгрузить эту тему? Активные производители и потребители переподключатся.", + aggregateTopic: "Сводная тема", + kafkaPartitionStatus: "Состояние разделов Kafka", + partitionCount: "{count} разделов", + partition: "Раздел", + beginOffset: "Начальное смещение", + latestOffset: "Последнее смещение", + messageCount: "Сообщения", + leader: "Лидер", + replicas: "Реплики", + isr: "ISR", + partitionClients: "Клиенты раздела", + inboundRate: "Скорость входящих", + outboundRate: "Скорость исходящих", + producers: "Производители", + subscriptions: "Подписки", + consumers: "Потребители", + activeProducers: "Активные производители", + noActiveProducers: "Нет активных производителей", + name: "Имя", + id: "ID", + address: "Адрес", + version: "Версия", + rate: "Скорость", + throughput: "Пропускная способность", + rateValue: "{value} сообщ/с", + activeConsumers: "Активные потребители", + noSubscriptions: "У этой темы нет подписок", + noConsumersOnPartition: "Нет активных потребителей у подписки этого раздела", + noConsumersOnSubscription: "Нет активных потребителей у этой подписки", + permits: "Разрешения", + }, + mqPolicies: { + title: "Управление политиками", + refresh: "Обновить", + refreshing: "Обновление...", + selectTopicFirst: "Сначала выберите тему", + selectNamespaceOrTopic: "Выберите пространство имён или тему", + readOnly: "Это подключение доступно только для чтения и не может выполнять операции записи.", + readonlyHint: "Это подключение только для чтения; редактирование политик отключено.", + publishRate: "Лимит скорости публикации", + msgsPerSecond: "Сообщений / секунда", + bytesPerSecond: "Байт / секунда", + save: "Сохранить", + dispatchRate: "Лимит скорости доставки", + msgsPerPeriod: "Сообщений / период", + bytesPerPeriod: "Байт / период", + periodSeconds: "Период (секунды)", + subscribeRate: "Лимит скорости подписки", + msgsPerConsumerPerPeriod: "Сообщений на потребителя / период", + backlogQuota: "Квота отставания", + sizeLimitBytes: "Ограничение размера (байты)", + timeLimitSeconds: "Ограничение времени (секунды)", + policy: "Политика", + type: "Тип", + backlogPolicyProducerRequestHold: "Задерживать запросы производителей", + backlogPolicyProducerException: "Отклонять с исключением", + backlogPolicyConsumerBacklogEviction: "Вытеснять отставание потребителей", + retention: "Хранение сообщений", + retentionTimeMinutes: "Время хранения (минуты)", + retentionSizeMb: "Размер хранения (МБ)", + effectivePolicies: "Действующие политики", + savedNotice: "{policy} сохранено", + }, + mqPermissions: { + title: "Разрешения", + refresh: "Обновить", + refreshing: "Обновление...", + selectNamespaceOrTopic: "Сначала выберите пространство имён или тему", + readOnly: "Это подключение доступно только для чтения и не может выполнять операции записи.", + readonlyHint: "Это подключение только для чтения; выдача и отзыв разрешений отключены.", + grantRole: "Выдать роль", + roleName: "Имя роли", + roleNamePlaceholder: "напр. app-producer", + actions: "Действия", + grant: "Выдать", + currentPermissions: "Текущие разрешения", + role: "Роль", + operations: "Операции", + token: "Токен", + revoke: "Отозвать", + noPermissions: "Нет записей о разрешениях", + clientTokenTitle: "Токен клиента: {role}", + missingSigningKeyTitle: "Ключ подписи токена не настроен", + missingSigningKeyMessage: "У этого подключения MQ не настроен ключ подписи токенов брокера, поэтому токены клиентов нельзя выпустить.", + missingSigningKeyDetail: "Измените подключение и укажите для «Подписи токенов брокера» HS256 SECRET или RS256 PRIVATE, затем задайте ключ подписи перед созданием токенов.", + tokenShowOnceWarning: "Токен отображается только один раз. Скопируйте и сохраните его сразу.", + copyToken: "Копировать токен", + issueNewToken: "Выпустить новый токен", + neverExpires: "Никогда не истекает", + expiryDays: "Срок действия (дни)", + note: "Примечание", + notePlaceholder: "напр. для rt-erp-server", + issuing: "Выпуск...", + generateToken: "Создать токен", + tokenRevokeHint: "Отзыв разрешений роли не аннулирует выданные JWT сразу; дождитесь истечения срока или смените ключ подписи брокера.", + issueRecords: "Записи о выпуске", + time: "Время", + algorithm: "Алгоритм", + expires: "Истекает", + fingerprint: "Отпечаток", + noteColumn: "Примечание", + unlimited: "Бессрочно", + loading: "Загрузка...", + noIssueRecords: "Нет записей о выпуске", + close: "Закрыть", + kafkaAuthorizerNotConfigured: "В этом кластере Kafka авторизатор не настроен. Добавьте authorizer.class.name в конфигурацию брокера для поддержки ACL.", + kafkaAuthorizerDisabled: "В этом кластере Kafka авторизатор не включён. Включите авторизатор в конфигурации брокера, чтобы выдавать разрешения.", + roleNameRequired: "Требуется имя роли", + selectAtLeastOneAction: "Выберите хотя бы одно действие", + grantedRole: "Выдана роль {role}", + confirmRevoke: "Отозвать разрешения у роли «{role}»?", + revokedRole: "Отозвана роль {role}", + roleNameEmpty: "Имя роли не может быть пустым", + expiryMustBePositive: "Срок действия должен быть больше 0 дней", + }, + mqBroker: { + title: "Кластер брокеров", + autoRefresh: "Автообновление", + refreshInterval5s: "5 с", + refreshInterval10s: "10 с", + refreshInterval30s: "30 с", + refreshInterval60s: "60 с", + refreshing: "Обновление...", + refreshNow: "Обновить сейчас", + loading: "Загрузка...", + clusterOverview: "Обзор кластера", + clusterId: "ID кластера", + unknown: "Неизвестно", + brokerCount: "Брокеры", + controller: "Контроллер", + controllerNode: "Узел {id} · {host}", + brokerNodes: "Узлы брокеров", + brokerName: "Имя брокера", + brokerEndpoints: "Конечные точки брокера", + nodeId: "ID узла", + host: "Хост", + addHost: "Добавить хост", + port: "Порт", + rack: "Стойка", + role: "Роль", + roleController: "Контроллер", + roleFollower: "Follower", + roleMaster: "Master", + roleSlave: "Slave", + noBrokerNodes: "Нет сведений об узлах брокеров", + clusterTitle: "Кластер", + }, + mqDlq: { + title: "Очередь недоставленных сообщений", + refresh: "Обновить", + refreshing: "Обновление...", + loading: "Загрузка...", + selectContext: "Сначала выберите контекст пространства имён", + selectTopic: "Выберите тему DLQ", + topic: "Тема DLQ", + consumerGroup: "Группа потребителей", + groupPlaceholder: "Необязательная группа для просмотра", + queryByKey: "Поиск по ключу сообщения", + queryKey: "Ключ сообщения", + queryKeyPlaceholder: "Ключ для поиска", + loadMessages: "Загрузить сообщения", + loadingMessages: "Загрузка сообщений...", + noDlqTopics: "Темы DLQ не найдены. Включите фильтр типа DLQ на вкладке «Темы», чтобы отобразить их.", + noMessages: "Нет сообщений", + }, + mqTrace: { + title: "Трассировка сообщений", + msgId: "ID сообщения", + msgIdPlaceholder: "Исходный ID сообщения", + msgIdRequired: "Требуется ID сообщения", + queryKeyRequired: "Требуется ключ сообщения", + selectTopicBeforeQuery: "Выберите тему перед запросом трассировок", + traceTopic: "Тема трассировки", + traceTopicPlaceholder: "RMQ_SYS_TRACE_TOPIC", + query: "Запросить трассировку", + querying: "Запрос...", + noTrace: "Записи трассировки не найдены", + searchHint: "Сначала найдите сообщения, затем нажмите «Просмотреть трассировку»", + viewTrace: "Просмотреть трассировку", + detailTitle: "Детали трассировки сообщения", + typePub: "Pub", + typeSubBefore: "SubBefore", + typeSubAfter: "SubAfter", + typeEndTransaction: "EndTransaction", + typeUnknown: "Неизвестно", + statusSuccess: "Успешно", + statusFail: "Ошибка", + fieldRegionId: "Регион", + fieldGroup: "Группа", + fieldTopic: "Тема", + fieldMsgId: "MsgId", + fieldTags: "Теги", + fieldKeys: "Ключи", + fieldStoreHost: "Хост хранилища", + fieldClientHost: "Хост клиента", + fieldBodyLength: "Длина тела", + fieldCostTime: "Затрачено", + fieldMsgType: "Тип сообщения", + fieldOffsetMsgId: "Offset MsgId", + fieldRequestId: "ID запроса", + fieldRetryTimes: "Повтор", + fieldContextCode: "Код контекста", + rawPayload: "Необработанная трассировка", + traceTopicRouteMissing: + "У темы трассировки нет маршрута на NameServer (CODE: 17).\n\nЧастые причины:\n1. Трассировка брокера отключена: установите traceTopicEnable=true в broker.conf и перезапустите брокер\n2. Трассировка производителя/потребителя отключена: вызовите setEnableTrace(true)\n3. Используется пользовательская тема трассировки: выберите правильную тему трассировки выше", + }, + mqRaw: { + title: "Raw API", + sending: "Отправка...", + sendRequest: "Отправить запрос", + readOnlyHint: "Это подключение только для чтения; разрешены только запросы GET, HEAD и OPTIONS.", + commonEndpoints: "Частые конечные точки", + fillFromSelection: "Заполнить запрос из текущего выбора", + expand: "Развернуть", + collapse: "Свернуть", + method: "Метод", + path: "Путь", + pathPlaceholder: "/admin/v2/...", + queryParams: "Параметры запроса", + queryPlaceholder: "key=value, по одному в строке", + jsonBody: "Тело JSON", + format: "Форматировать", + bodyPlaceholder: "напр. {'{'}\"key\":\"value\"{'}'}", + response: "Ответ", + textResponse: "Текстовый ответ", + noRequestYet: "Запрос ещё не отправлен", + readOnly: "Это подключение доступно только для чтения и не может выполнять операции записи.", + pathRequired: "Требуется путь запроса", + jsonBodyInvalid: "Недопустимое тело JSON: {error}", + presetBrokerVersion: "Версия брокера", + presetBrokerVersionDesc: "Строка версии брокера", + presetClusters: "Список кластеров", + presetClustersDesc: "Список настроенных кластеров Pulsar", + presetTenant: "Детали арендатора", + presetTenantDesc: "Просмотр adminRoles / allowedClusters", + presetNamespacePolicies: "Политики пространства имён", + presetNamespacePoliciesDesc: "Необработанная структура политик пространства имён", + presetBundles: "Список пакетов", + presetBundlesDesc: "Распределение пакетов пространства имён", + presetTopicInternalStats: "Внутренняя статистика темы", + presetTopicInternalStatsDesc: "Детали журнала / курсора / отставания", + presetPartitionedStats: "Метрики разделов", + presetPartitionedStatsDesc: "Скорости, производители и потребители по разделам", + presetSchema: "Последняя схема", + presetSchemaDesc: "Текущее определение схемы темы", + }, + nacos: { + openConsole: "Открыть консоль", + consoleUrlMissing: "Настройте URL веб-консоли Nacos, чтобы открыть её в браузере.", + consoleOpenFailed: "Не удалось открыть консоль Nacos.", + enterZenMode: "Развернуть рабочую область", + exitZenMode: "Выйти из развёрнутой рабочей области", + dashboard: "Панель мониторинга", + dashboardTitle: "Панель операций", + dashboardUpdatedAt: "Обновлено {time}", + dashboardAutoRefresh: "Автообновление", + dashboardOff: "Выкл.", + dashboardNamespaces: "Пространства имён", + dashboardConfigs: "Конфигурации", + dashboardServices: "Сервисы", + dashboardInstances: "Экземпляры", + dashboardClients: "Клиенты", + dashboardConnections: "{count} подключений", + dashboardNodes: "Работоспособные узлы", + dashboardCpu: "ЦП", + dashboardMemory: "Память", + dashboardLoad: "Нагрузка {value}", + dashboardCountsChart: "Обнаружение сервисов", + dashboardResourcesChart: "Использование ресурсов", + dashboardClusterNodes: "Узлы кластера", + dashboardSite: "Сайт", + dashboardLastRefresh: "Последнее обновление", + dashboardNoNodes: "Детали узлов кластера недоступны", + dashboardPartial: "{count} источников панели недоступны", + dashboardMemoryUsed: "Использовано кучи / памяти", + dashboardMemoryMax: "Максимум {value}", + dashboardRss: "Память RSS", + dashboardVms: "Виртуальная память", + dashboardJvmThreads: "Потоки демонов JVM", + dashboardGcPauses: "Паузы GC", + dashboardTrafficSection: "Трафик запросов", + dashboardRequestRateChart: "Запросов HTTP / gRPC в секунду", + dashboardLatencyChart: "Задержка запросов", + dashboardHttpQps: "HTTP QPS", + dashboardGrpcQps: "gRPC QPS", + dashboardHttpAverage: "Среднее HTTP", + dashboardHttpP50: "HTTP P50", + dashboardHttpP95: "HTTP P95", + dashboardHttpP99: "HTTP P99", + dashboardGrpcAverage: "Среднее gRPC", + dashboardGrpcP50: "gRPC P50", + dashboardGrpcP95: "gRPC P95", + dashboardGrpcP99: "gRPC P99", + dashboardReliabilitySection: "Надёжность", + dashboardErrorRateChart: "Доля ошибок запросов", + dashboardExecutorChart: "Исполнитель gRPC", + dashboardHttpErrors: "Ошибки HTTP", + dashboardGrpcErrors: "Ошибки gRPC", + dashboardExecutorPool: "Размер пула", + dashboardExecutorActive: "Активные", + dashboardExecutorQueue: "В очереди", + dashboardConfigSection: "Центр конфигурации", + dashboardConfigRateChart: "Операций с конфигурацией в секунду", + dashboardConfigStateChart: "Слушатели и ожидающие задачи", + dashboardConfigGets: "Чтения", + dashboardConfigPublishes: "Публикации", + dashboardLongPolling: "Длинный опрос", + dashboardListenerClients: "Клиенты-слушатели", + dashboardListenerKeys: "Ключи слушателей", + dashboardNotifyTasks: "Задачи уведомления", + dashboardNotifyClientTasks: "Задачи уведомления клиентов", + dashboardDumpTasks: "Задачи дампа", + dashboardNamingSection: "Обнаружение сервисов", + dashboardNamingStateChart: "Сервисы, экземпляры и клиенты", + dashboardPushRateChart: "Отправок в секунду", + dashboardPushDetailChart: "Задержка отправки и ожидающие задачи", + dashboardPushAverage: "Средняя задержка", + dashboardPushMaximum: "Максимальная задержка", + dashboardPushPending: "Ожидающие задачи", + dashboardSubscribers: "Подписчики", + dashboardPushes: "Отправки", + dashboardFailedPushes: "Неудачные отправки", + dashboardEmptyPushes: "Пустые отправки", + configs: "Конфигурации", + services: "Сервисы", + loading: "Загрузка...", + accessControlSidebarLabel: "Пользователи и роли", + accessControlTitle: "Управление доступом", + accessControlDescription: "Управление пользователями Nacos и назначением ролей", + users: "Пользователи", + roleBindings: "Роли", + accessControlUnavailable: "Управление пользователями и ролями недоступно для этого подключения.", + accessPermissionEndpointUnavailable: "Разрешения пространств имён недоступны текущей учётной записи. Привязки пользователей и ролей остаются видимыми в режиме совместимости.", + searchUsers: "Поиск пользователей", + filterUsername: "Фильтр по имени пользователя", + filterRole: "Фильтр по роли", + username: "Имя пользователя", + password: "Пароль", + passwordUnchanged: "Оставьте пустым, чтобы сохранить текущий пароль", + nickname: "Псевдоним", + roles: "Роли", + role: "Роль", + disabled: "Отключён", + createUser: "Создать пользователя", + editUser: "Изменить пользователя", + resetUserPassword: "Сбросить пароль", + passwordResetSucceeded: "Пароль сброшен для {username}", + passwordResetFailed: "Не удалось сбросить пароль: {message}", + currentPasswordSaved: "Сохранённые учётные данные подключения обновлены, и подключение будет использовать новый пароль.", + currentSessionPasswordUpdated: "Учётные данные подключения обновлены в памяти для этого сеанса и не сохранены на диск.", + currentPasswordNotSaved: "Это подключение не сохраняет пароли. Введите новый пароль при повторном подключении.", + deleteUser: "Удалить пользователя", + noUsers: "Пользователи не найдены", + noRoleBindings: "Привязки ролей не найдены", + createUserTitle: "Создать пользователя Nacos", + createUserDescription: "Создайте пользователя для этого сервиса Nacos.", + editUserTitle: "Изменить пользователя r-nacos", + editUserDescription: "Обновите профиль пользователя, роли и права на пространства имён.", + resetUserTitle: "Сбросить пароль пользователя Nacos", + resetUserDescription: "Задайте новый пароль для этого пользователя.", + userCredentialsRequired: "Требуются имя пользователя и пароль.", + deleteUserTitle: "Удалить пользователя Nacos", + deleteUserDescription: "Удалить пользователя {username}? Это действие необратимо.", + rnacosUserEnabledHint: "Отключённые пользователи не могут войти в r-nacos.", + rnacosRole0: "Менеджер", + rnacosRole0Hint: "Полный доступ к управлению консолью", + rnacosRole1: "Разработчик", + rnacosRole1Hint: "Доступ к разработке конфигураций и сервисов", + rnacosRole2: "Посетитель", + rnacosRole2Hint: "Доступ к консоли только для чтения", + namespacePrivileges: "Права на пространства имён", + namespaceWhitelist: "Белый список пространств имён", + namespaceBlacklist: "Чёрный список пространств имён", + namespaceListPlaceholder: "Одно пространство имён в строке или через запятую", + namespaceSelectPlaceholder: "Выберите пространства имён", + namespaceSearchPlaceholder: "Поиск пространств имён", + namespaceSelectedCount: "Выбрано: {count}", + namespaceRemoveSelection: "Удалить {namespace}", + noNamespacesAvailable: "Нет доступных пространств имён", + retryNamespaceList: "Повторить", + assignRole: "Назначить роль", + assignRoleTitle: "Назначить роль Nacos", + assignRoleDescription: "Привяжите роль к одному пользователю Nacos.", + roleBindingRequired: "Требуются имя пользователя и роль.", + removeRole: "Удалить роль", + removeRoleTitle: "Удалить роль Nacos", + removeRoleDescription: "Удалить роль {role} у пользователя {username}?", + protectedRole: "Встроенную роль администратора нельзя удалить из DBX.", + close: "Закрыть", + accessSearchRoles: "Поиск ролей", + accessRoleCounts: "Участников: {members} · разрешений: {permissions}", + accessNoRoles: "Роли не найдены", + accessUserSubtitle: "Роли и действующий доступ к пространствам имён", + accessAssociatedRoles: "Связанные роли", + accessAssociatedRolesHint: "Разрешения наследуются от каждой связанной роли.", + accessNoAssociatedRoles: "Связанные роли отсутствуют", + accessEffectivePermissions: "Действующие разрешения", + accessEffectivePermissionsHint: "Совокупный доступ с указанием роли, дающей каждое разрешение.", + accessAction: "Действие", + accessSourceRole: "Исходная роль", + accessNoEffectivePermissions: "У этого пользователя нет действующих разрешений", + accessGlobalAdministrator: "Глобальный администратор", + accessNeedsRepair: "Требует исправления", + accessRoleSubtitle: "Связанных участников: {members}", + accessIncompleteRoleHint: "У этой роли нет участников или разрешений на пространства имён. Добавьте разрешения на пространства имён перед сохранением; участники могут остаться пустыми.", + accessPermissionScope: "Область разрешений", + accessPermissionScopeHint: "Правила пространств имён, управляемые этой ролью.", + accessAllResources: "Все ресурсы", + accessAdminBypassHint: "ROLE_ADMIN обходит обычные проверки разрешений пространств имён.", + accessNoRolePermissions: "Разрешения на пространства имён не настроены", + accessMembers: "Участники", + accessMembersHint: "Пользователи, связанные с этой ролью в данный момент.", + accessNoMembers: "Связанные участники отсутствуют", + accessOpenUser: "Просмотреть пользователя {username}", + accessOpenRole: "Просмотреть роль {role}", + accessAdvancedPermissions: "Расширенные разрешения", + accessAdvancedPermissionsHint: "Необработанные правила сохраняются точно и не перезаписываются при редактировании пространств имён.", + accessRevokeRawPermission: "Отозвать необработанное разрешение", + accessRevokeRawPermissionHint: "Это удаляет ровно отображаемый набор роли, ресурса и действия.", + accessSelectItem: "Выберите элемент из каталога", + accessCreateRole: "Создать роль", + accessDeleteRole: "Удалить роль", + accessReadOnly: "Только чтение", + accessWriteOnly: "Только запись", + accessReadWrite: "Чтение и запись", + accessDeletedNamespace: "удалённое пространство имён", + accessPasswordRequired: "Введите новый пароль.", + accessCredentialsRequired: "Требуются имя пользователя и пароль.", + accessRoleMemberRequired: "Роли требуется хотя бы один участник.", + accessRolePermissionRequired: "Роли требуется хотя бы одно разрешение на пространство имён.", + accessInlineUserRequired: "Каждому новому пользователю требуются имя пользователя и пароль.", + accessNoAssignableRoles: "Нет доступных полных ролей", + accessTypeUsername: "Введите {value} для подтверждения этого рискованного изменения учётной записи", + accessDeleteUserConfirmationLabel: "Введите полное имя пользователя для подтверждения удаления", + accessDeleteUserConfirmationHint: "Введите этот текст точно (с учётом регистра):", + accessDeleteUserConfirmationPlaceholder: "Полное имя пользователя", + accessMembersRequiredHint: "Выберите существующих пользователей или создайте их на месте. Требуется хотя бы один.", + accessMembersOptionalHint: "Существующая обычная роль может сохранять разрешения без связанных участников.", + accessInlineCreateUser: "Создать пользователя на месте", + accessAdminPermissionImmutable: "Разрешение глобального администратора встроено в Nacos и не может редактироваться как правила пространств имён.", + accessPermissionRequiredHint: "Выберите пространства имён, затем задайте действие для каждого.", + accessUnassignedNamespaces: "Неназначенные пространства имён", + accessGrantedNamespaces: "Предоставленные пространства имён", + accessSearchNamespaces: "Поиск по имени или ID пространства имён", + accessNoUnassignedNamespaces: "Нет пространств имён для добавления", + accessNoGrantedNamespaces: "Выберите пространства имён для предоставления доступа", + accessGrantNamespaces: "Предоставить выбранные пространства имён", + accessRevokeNamespaces: "Удалить выбранные пространства имён", + accessDeleteRoleHint: "Удаление {role} удаляет все разрешения и привязки участников. Успешные удаления не восстанавливаются после частичной ошибки.", + accessTypeRole: "Введите {value} для подтверждения удаления роли", + accessDeleteRoleConfirmationLabel: "Введите полное имя роли для подтверждения удаления", + accessDeleteRoleConfirmationHint: "Введите этот текст точно (с учётом регистра):", + accessDeleteRoleConfirmationPlaceholder: "Полное имя роли", + accessOperationResult: "Результат операции", + accessReenterPassword: "Введите пароль ещё раз для повторной попытки", + accessUndoCreated: "Отменить созданные элементы", + accessRetryFailed: "Повторить неудачные шаги", + accessUserDialog: { + create: "Создать пользователя", + createHint: "Создайте учётную запись и при необходимости свяжите существующие роли.", + roles: "Изменить роли пользователя", + rolesHint: "Обновите роли, связанные с {username}.", + password: "Сбросить пароль", + passwordHint: "Задайте новый пароль для {username}.", + delete: "Удалить пользователя", + deleteHint: "Проверьте целостность ролей перед удалением {username}.", + }, + accessRoleDialog: { + create: "Создать роль", + createHint: "Настройте участников и разрешения на пространства имён вместе.", + edit: "Изменить роль", + editHint: "Изменения применяются как согласованный набор операций с участниками и разрешениями.", + delete: "Удалить роль", + deleteHint: "Эта операция может выполниться частично и не может быть отменена автоматически.", + }, + accessOperationStatus: { + running: "Операция всё ещё выполняется.", + partial: "Некоторые шаги выполнены успешно, некоторые требуют внимания.", + succeeded: "Все шаги выполнены успешно.", + failed: "Операция не завершена.", + undoing: "Созданные элементы удаляются.", + undone: "Созданные элементы удалены.", + }, + accessStep: { + createUser: "Создать пользователя", + deleteUser: "Удалить пользователя", + assignRole: "Связать роль", + removeRole: "Удалить связь с ролью", + grantPermission: "Предоставить разрешение", + revokePermission: "Отозвать разрешение", + }, + rnacosAccessControlAuthDescription: "Введите код подтверждения консоли r-nacos для управления пользователями и ролями.", + raw: "Raw", + namespace: "Пространство имён", + createNamespace: "Создать пространство имён", + editNamespace: "Изменить пространство имён", + deleteNamespace: "Удалить пространство имён", + deleteNamespaceDescription: "Удалить пространство имён {name} ({id})? Его конфигурации и сервисы могут стать недоступными. Это действие необратимо.", + creatingNamespace: "Создание...", + updatingNamespace: "Обновление...", + deletingNamespace: "Удаление...", + namespaceCreated: 'Пространство имён "{name}" создано', + namespaceUpdated: 'Пространство имён "{name}" обновлено', + namespaceDeleted: 'Пространство имён "{name}" удалено', + namespaceId: "ID пространства имён", + namespaceIdPlaceholder: "Оставьте пустым, чтобы DBX сгенерировал UUID", + namespaceName: "Имя пространства имён", + namespaceNamePlaceholder: "Введите имя пространства имён", + namespaceDesc: "Описание", + namespaceDescPlaceholder: "По умолчанию совпадает с именем пространства имён", + dataId: "Data ID", + group: "Группа", + format: "Формат", + content: "Содержимое", + tags: "Теги", + application: "Приложение", + description: "Описание", + advanced: "Дополнительно", + collapse: "Свернуть", + configIdentity: "Идентификатор конфигурации", + newConfigDraft: "Новая конфигурация", + draft: "Черновик", + unsaved: "Не сохранено", + published: "Опубликовано", + readOnlyState: "Только чтение", + load: "Загрузить", + save: "Сохранить", + saveAs: "Сохранить как", + saving: "Сохранение...", + saved: "Конфигурация сохранена", + createdAndLoaded: "Создано и загружено {dataId}", + savedAndLoaded: "Сохранено и обновлено {dataId}", + deleted: "Конфигурация удалена", + delete: "Удалить", + copy: "Копировать", + copied: "Скопировано", + copyVerifyFailed: "Не удалось проверить буфер обмена после записи", + export: "Экспорт", + exported: "Экспортировано", + exportedTo: "Экспортировано в {path}", + exportFailed: "Ошибка экспорта: {message}", + contentSearch: "Полнотекстовый поиск", + contentSearchTitle: "Полнотекстовый поиск по конфигурациям Nacos", + contentSearchDescription: "Выполняет буквальный поиск с учётом регистра по текущему опубликованному содержимому конфигураций. Версии истории не проверяются.", + contentSearchPlaceholder: "URL базы данных, учётная запись или любой фрагмент конфигурации", + search: "Поиск", + cancel: "Отмена", + currentNamespace: "Текущее пространство имён", + allNamespaces: "Все пространства имён в этом подключении", + allNamespacesSearchWarning: "Поиск по всем пространствам имён может перебрать множество конфигураций. На Nacos 2.x и r-nacos это может быть медленно и создаёт нагрузку на сервер.", + scannedCount: "Просканировано: {count}", + matchCount: "Совпадений: {count}", + incompleteResult: "Результаты могут быть неполными", + lineNumber: "Строка {line}", + noContentMatches: "Ни одна конфигурация не содержит это содержимое", + contentSearchEmptyHint: "Введите ключевое слово для поиска. Ключевые слова, содержимое и фрагменты не сохраняются на диск или в журналы.", + searchResults: "Результаты поиска", + searchResultsRetainedHint: "Откройте результат в области содержимого. Этот набор результатов остаётся доступным через «Результаты поиска» на верхней панели.", + openedSearchResult: "Открыто", + exportSearchResults: "Экспортировать результаты", + clearSearchResults: "Очистить результаты поиска", + searchResultsExported: "Результаты поиска экспортированы", + searchResultsExportedTo: "Результаты поиска экспортированы в {path}", + contentReplace: "Глобальная замена", + contentReplaceTitle: "Замена содержимого во всех конфигурациях Nacos", + contentReplaceDescription: "Перед публикацией просмотрите точную замену с учётом регистра во всех подходящих Data ID.", + contentReplaceSearch: "Найти значение", + contentReplaceValue: "Заменить на", + contentReplaceScope: "Область", + contentReplaceAllGroups: "Все группы", + contentReplaceAllDataIds: "Все Data ID", + contentReplaceAllNamespacesWarning: "Это действие просканирует и может опубликовать каждую подходящую конфигурацию во всех пространствах имён этого подключения. Перед применением изучите полный план.", + contentReplaceScanning: "Сканирование конфигураций: {scanned}, найдено совпадений: {matched}", + contentReplaceIncomplete: "Результат глобального поиска неполный, поэтому план замены не создан. Сузьте фильтры или повторите попытку.", + contentReplaceConfigCount: "Конфигураций: {count}", + contentReplaceSelectAll: "Выбрать все конфигурации", + contentReplaceSelectConfig: "Выбрать {dataId}", + contentReplaceSelectedCount: "Выбрано {selected} из {total} конфигураций", + contentReplaceOccurrenceCount: "Замен: {count}", + contentReplaceNoMatches: "Ни одна опубликованная конфигурация не содержит это точное значение.", + contentReplaceViewDiff: "Просмотреть различия замены", + contentReplacePreview: "Предварительный просмотр замен", + contentReplaceApply: "Заменить в выбранных конфигурациях ({count})", + contentReplaceRollback: "Откатить заменённые конфигурации", + contentReplaceReport: "Заменено: {replaced}, конфликтов: {conflicts}, ошибок: {failed}", + contentReplaceRollbackReport: "Откат: восстановлено {restored}, конфликтов {conflicts}, ошибок {failed}", + contentReplaceStatus: { + replaced: "Заменено", + conflict: "Конфликт", + failed: "Ошибка", + }, + replaceHistory: { + replaceTab: "Замена", + historyTab: "История", + batchCount: "Пакетов: {count}", + empty: "Пакеты замен пока не зафиксированы.", + refresh: "Обновить историю", + details: "Просмотреть детали пакета", + delete: "Удалить запись", + deleteTitle: "Удалить историю пакета", + deleteConfirm: "Удалить эту локальную запись и её снимки отката? Опубликованные конфигурации Nacos не изменятся. Вы больше не сможете откатить этот пакет здесь.", + rollbackTitle: "Откатить этот пакет замен", + rollbackConfirm: "Опубликовать сохранённое исходное содержимое для подтверждённых замен? Конфигурации, изменённые после замены, будут пропущены. Уже восстановленные конфигурации не будут опубликованы повторно.", + storageUnavailable: "Безопасное локальное хранилище истории недоступно. Используйте HTTPS или localhost с включёнными IndexedDB, Web Crypto и Web Locks. Больше ничего не будет опубликовано.", + storageFailed: "Не удалось сохранить или прочитать историю пакетов. Дальнейшая публикация остановлена. Проверьте место в локальном хранилище и просмотрите историю перед повторной попыткой; для неопределённых элементов может потребоваться проверка истории конфигураций Nacos.", + targetMismatch: "Это подключение теперь указывает на другой сервер Nacos или больше не существует. Выполните предварительный просмотр заново; исторический откат заблокирован для защиты другого сервера.", + busy: "Другая вкладка выполняет операцию с этим подключением. Повторите попытку после её завершения.", + uncertain: "Неопределённо", + notExecuted: "Не выполнено", + interrupted: "Некоторые операции записи были прерваны до сохранения результатов. Неопределённые элементы исключены из автоматического отката. Проверьте их индивидуальную историю конфигураций Nacos.", + state: { + applying: "Незавершённая замена", + completed: "Замена завершена", + rollingBack: "Незавершённый откат", + rollbackCompleted: "Откат обработан", + }, + rollbackStatus: { + restored: "Восстановлено", + conflict: "Конфликт отката", + failed: "Ошибка отката", + }, + }, + batchExport: "Пакетный экспорт", + batchImport: "Пакетный импорт", + copyToNamespace: "Синхронизация конфигураций", + batchDelete: "Пакетное удаление", + batchDeleteTitle: "Удалить выбранные конфигурации Nacos", + batchDeleteConfirm: "Удалить выбранные конфигурации ({count})? Это действие нельзя отменить.", + batchDeleteSuccess: "Удалено конфигураций: {count}", + batchDeletePartial: "Удалено конфигураций: {deleted}; ошибок: {failed}.", + batchDeleteInterrupted: "Пакетное удаление остановлено после удаления конфигураций ({deleted}).", + configPageSize: "На странице", + selectedCount: "Выбрано: {count}", + retryConnectionInfo: "Повторить проверку сведений о подключении", + resizeColumn: "Перетащите для изменения ширины столбца", + visibleColumns: "Видимые столбцы", + configListGroup: "Группа", + configListApplication: "Приложение", + configListFormat: "Формат", + selectCurrentPage: "Выбрать текущую страницу", + selectConfigForBatch: "Выбрать конфигурацию {dataId}", + batchExportTitle: "Пакетный экспорт конфигураций Nacos", + batchExportDescription: "Создаёт ZIP, совместимый с консолью Nacos. Он содержит расшифрованную конфигурацию в открытом виде и должен храниться в безопасном месте.", + batchImportTitle: "Пакетный импорт конфигураций Nacos", + batchImportDescription: "Безопасно разбирает архив и показывает конфликты перед публикацией каждого элемента в текущее пространство имён.", + batchCopyTitle: "Синхронизировать конфигурации в другое пространство имён", + batchCopyDescription: "Синхронизация использует одностороннее копирование и никогда не удаляет и не изменяет исходные конфигурации. Для конфликтов в целевом расположении применяется выбранная политика.", + exportScope: "Область конфигураций", + selectedConfigs: "Выбранные конфигурации ({count})", + filteredConfigs: "Все, соответствующие текущему фильтру (приблизительно {count})", + namespaceAllConfigs: "Все конфигурации в этом пространстве имён", + importArchive: "ZIP-архив Nacos", + noArchiveSelected: "ZIP не выбран", + chooseZip: "Выбрать ZIP", + importSensitiveWarning: "Совместимый ZIP может содержать пароли к базам данных, ключи и другие секреты в открытом виде. Импортируйте только доверенные архивы.", + targetConnection: "Целевое подключение", + chooseTargetConnection: "Выберите целевое подключение Nacos", + noTargetConnections: "Нет доступных подключений Nacos с правом записи. Добавьте подключение или снимите настройку «только чтение» у целевого подключения.", + targetNamespace: "Целевое пространство имён", + chooseTargetNamespace: "Выберите другое пространство имён", + targetGroup: "Целевая группа (необязательно)", + targetGroupPlaceholder: "Как в исходной группе", + targetDataIds: "Целевые Data ID (необязательно)", + targetDataIdsHint: "Выбранные конфигурации можно переименовать по отдельности. Оставьте поле пустым, чтобы сохранить исходный Data ID.", + copyKeepsSource: "Синхронизация использует одностороннее копирование. Конфигурации исходного пространства имён остаются без изменений.", + conflictPolicy: "Политика конфликтов", + policyABORT: "Прервать при конфликте", + policyABORTHint: "Ничего не записывать, если предпросмотр обнаружил конфликт", + policySKIP: "Пропускать конфликты", + policySKIPHint: "Создавать только конфигурации, отсутствующие в целевом расположении", + policyOVERWRITE: "Перезаписать в целевом расположении", + policyOVERWRITEHint: "Заменять конфигурации с тем же ключом в целевом расположении исходными", + overwriteWarning: "Перезапись изменяет опубликованные целевые конфигурации и требует дополнительного подтверждения.", + overwriteConfirm: "Перезаписать все конфликтующие конфигурации в целевом пространстве имён? Это нельзя откатить автоматически.", + preview: "Предпросмотр", + apply: "Применить", + exportZip: "Экспортировать ZIP", + previewTotal: "Всего: {count}", + previewCreated: "Новых: {count}", + previewConflicts: "Конфликтов: {count}", + previewInvalid: "Недопустимых: {count}", + previewExpired: "Предпросмотр устарел. Запустите его снова.", + batchFinished: "Синхронизация завершена: записано {written}", + batchAborted: "Синхронизация не выполнена: конфликт предотвратил все записи", + batchPartial: "Пакетная операция выполнена частично; проверьте элементы с ошибками", + batchCancelled: "Отменено", + batchCancelledSummary: "Синхронизация отменена: обработано {processed}/{total}", + batchFailedSummary: "Синхронизация выполнена частично: записано {written}, ошибок {failed}", + batchPartialSummary: "Синхронизация не завершена: обработано {processed}/{total}", + batchFinishedWithSkipped: "Синхронизация завершена: записано {written}, пропущено {skipped}", + batchStatusCreate: "Будет создано", + batchStatusConflict: "Конфликт", + batchStatusInvalid: "Недопустимо", + batchStatusCreated: "Создано", + batchStatusOverwritten: "Перезаписано", + batchStatusSkipped: "Пропущено", + batchStatusFailed: "Ошибка", + batchStatusAborted: "Не выполнено", + batchStatusExported: "Экспортировано", + batchStatusUnknown: "{status}", + reportWritten: "Записано: {count}", + reportCreated: "Создано: {count}", + reportOverwritten: "Перезаписано: {count}", + reportSkipped: "Пропущено: {count}", + reportFailed: "Ошибок: {count}", + reportItems: "Детали конфигурации ({count})", + history: "История", + configHistory: "История конфигурации", + historyUnavailable: "История конфигурации недоступна для этого подключения. Настройте URL консоли r-nacos и переподключитесь, чтобы включить её.", + historyDisabled: "История конфигурации отключена для этого подключения.", + historyConsoleUrlMissing: "Для истории конфигурации нужен адрес консоли r-nacos.", + historyConsoleCredentialsMissing: "Для истории конфигурации нужны учётные данные консоли r-nacos.", + rnacosConsoleAuthTitle: "Проверка консоли r-nacos", + rnacosConsoleAuthDescription: "Введите код проверки консоли r-nacos, чтобы прочитать типы конфигураций, описания и историю.", + rnacosCaptchaLabel: "Код проверки", + rnacosCaptchaPlaceholder: "Введите код, показанный выше", + rnacosCaptchaRequired: "Требуется код проверки.", + rnacosCaptchaUnavailable: "r-nacos не вернул изображение проверки.", + rnacosRefreshCaptcha: "Обновить код", + rnacosConsoleAuthSubmit: "Проверить и продолжить", + historyDetail: "Детали истории", + historyCompareTitle: "Сравнение версий истории", + currentPublishedContent: "Текущее опубликованное содержимое:", + historyVersionContent: "Содержимое версии из истории:", + updatedAt: "Обновлено", + operationType: "Операция", + operator: "Оператор", + view: "Просмотр", + compare: "Сравнить", + rollback: "Откат", + loadingHistory: "Загрузка истории...", + noHistory: "Нет версий истории", + noHistoryHint: "Обновите, если эта конфигурация была только что опубликована. Некоторые версии Nacos могут не предоставлять API истории.", + historyCreate: "Создание", + historyUpdate: "Обновление", + historyDelete: "Удаление", + historyRollback: "Откат", + confirmRollbackTitle: "Откатить конфигурацию Nacos", + confirmRollbackMessage: "Текущая конфигурация будет откатана к выбранной версии из истории.", + rollbackSuccess: "Конфигурация откатана", + publish: "Опубликовать", + validate: "Проверить", + validationPassed: "Синтаксис конфигурации корректен", + validationErrorTitle: "Ошибка синтаксиса конфигурации", + validationErrorDescription: "Исправьте синтаксические ошибки перед публикацией этой конфигурации.", + validationLine: "Строка: {line}", + validationColumn: "Столбец: {column}", + validationLocate: "Перейти к ошибке", + yamlDiagnosticDuplicateKey: "Дублирующийся ключ сопоставления: {key}", + yamlDiagnosticTabIndent: "В отступах YAML нельзя использовать символы табуляции; используйте пробелы", + yamlDiagnosticSyntaxError: "Ошибка синтаксиса YAML: {reason}", + yamlDiagnosticParserWarning: "Предупреждение парсера YAML: {reason}", + validationWarningTitle: "Конфигурация содержит предупреждения", + validationWarningDescription: "Эти предупреждения не блокируют публикацию, но проверьте их перед публикацией этой конфигурации.", + validationSeverityError: "Ошибка", + validationSeverityWarning: "Предупреждение", + dataIdRequired: "Требуется Data ID", + allGroups: "Все группы", + noConfigs: "Нет конфигураций", + selectConfig: "Выберите или создайте конфигурацию", + noServices: "Нет сервисов", + selectService: "Выберите сервис", + service: "Сервис", + instances: "Экземпляры", + instanceCount: "Экземпляров: {count}", + refresh: "Обновить", + address: "Адрес", + cluster: "Кластер", + weight: "Вес", + state: "Состояние", + actions: "Действия", + query: "Запрос", + body: "Тело", + response: "Ответ", + template: "Шаблон", + configDiffTitle: "Сравнение содержимого конфигураций", + inlineCompare: "Встроенное сравнение", + diffStats: "+{added} / -{removed} / ~{modified} строк", + previousDifference: "Предыдущее различие", + nextDifference: "Следующее различие", + currentVersionContent: "Текущая официальная версия:", + publishVersionContent: "Содержимое этого выпуска:", + confirmSaveTitle: "Проверьте изменения конфигурации Nacos", + confirmDeleteTitle: "Удалить конфигурацию Nacos", + confirmDeleteMessage: "Это удаляет выбранную конфигурацию из Nacos.", + confirmInstanceTitle: "Обновить экземпляр Nacos", + confirmInstanceMessage: "Подтвердите состояние экземпляра целевого сервиса.", + confirmRawTitle: "Отправить изменяющий запрос Raw API", + confirmRawMessage: "Этот запрос Raw API может изменить состояние Nacos.", + rawTemplate: { + serverState: "Состояние сервера", + namespaceList: "Список пространств имён", + configDetail: "Детали конфигурации", + serviceList: "Список сервисов", + instanceList: "Список экземпляров", + }, + healthy: "Здоровый", + unhealthy: "Нездоровый", + enabled: "Включено", + offline: "Не в сети", + ephemeral: "Временный", + persistent: "Постоянный", + enable: "Включить", + disable: "Отключить", + markHealthy: "Здоровый", + markUnhealthy: "Нездоровый", + send: "Отправить", + total: "Всего: {count}", + prev: "Назад", + next: "Далее", + test: "Проверить", + readOnly: "Только чтение", + nacosConnectionPlan: "План подключения", + nacosConnectionPlanDescription: "Выберите реализацию сервиса и версию API.", + nacosApiPlane: "Nacos 3 API", + nacosApiPlaneAdmin: "Admin API", + nacosApiPlaneAdminHint: "Рекомендуется · полное управление", + nacosApiPlaneConsole: "Console API", + nacosApiPlaneConsoleHint: "Ограниченный · работает только через доступ к консоли", + nacosServiceAddress: "Адрес сервиса", + nacosServiceAddressHint: "Введите адрес сервиса. Порт по умолчанию — 8848, например http://host:8848/nacos.", + nacosConsoleServiceAddressHint: "Введите адрес Console API. Порт по умолчанию — 8080, например http://host:8080.", + nacosManagedNamespaces: "Управляемые ID пространств имён", + nacosManagedNamespacesNameOrId: "Управляемые имена или ID пространств имён", + nacosManagedNamespacesPlaceholder: "Например: public, team-a", + nacosManagedNamespacesIdPlaceholder: "Например: public, f8b8c4e2-8195-4041-adb2-683a8259384b", + nacosManagedNamespacesHint: "Введите ID пространств имён, к которым имеет доступ этот обычный пользователь, разделяя их запятыми или переносами строк. Проверка подключения проверяет доступ на чтение конфигураций и сервисов для каждого ID.", + nacosOrdinaryAccount: "Обычный пользователь", + nacosOrdinaryAccountHint: "Если указанная выше учётная запись является обычным пользователем, включите эту опцию и выберите его авторизованные пространства имён; иначе подключение не будет работать корректно.", + nacosManagedNamespacesSeparator: "Через запятую или с новой строки", + nacosOrdinaryNamespacesRequired: "Введите хотя бы один ID пространства имён, которым разрешено управлять этому обычному пользователю.", + nacosManagedNamespacesRequired: "Этот обычный пользователь Nacos не может получить список пространств имён или данные авторизации. Введите хотя бы один ID пространства имён, которым ему разрешено управлять, и повторите попытку.", + nacosManagedNamespaceAccessDenied: "Эти пространства имён не прошли проверку доступа на чтение конфигураций или сервисов: {detail}", + nacosNamespaceAccessScope: "Область доступа к пространствам имён", + nacosNamespaceAccessScopeHint: "Сначала определите доступные пространства имён. Если перечисление недоступно, введите проверенные ID пространств имён вручную.", + nacosNamespaceAccessAutomatic: "Определить автоматически", + nacosNamespaceAccessManual: "Ввести вручную", + nacosDetectAccessibleNamespaces: "Определить и выбрать доступные пространства имён", + nacosDetectAccessibleNamespacesHint: "DBX проверяет доступ на чтение конфигураций и сервисов, прежде чем предложить пространства имён для {name}.", + nacosV3AdminNamespaceScopeHint: "Admin API Nacos 3 обычно требует учётной записи администратора. Для ограниченной учётной записи используйте плоскость Console API и её область доступа к пространствам имён.", + nacosV3AdminManagedNamespacesHint: "Используется Nacos 3 Admin API (обычно порт 8848). Обычный пользователь должен вводить ID пространств имён, а не отображаемые имена. Скопируйте ID из деталей пространства имён в консоли Nacos или из ресурсов ролей и разрешений.", + nacosV3ConsoleManagedNamespacesHint: "Используется Nacos 3 Console API (обычно порт 8080). Введите имя или ID пространства имён; DBX преобразует имя в его фактический ID, когда сможет прочитать справочник.", + rnacosNamespaceAccessScopeHint: "r-nacos определяет доступ к пространствам имён на основе привилегий текущего пользователя, когда доступен его профиль консоли.", + nacosAuth: "Аутентификация", + nacosAuthHint: "Эти учётные данные используются для проверки подключения и повседневного управления.", + nacosUsernamePassword: "Имя пользователя / пароль", + nacosAdvancedHint: "Дополнительные параметры подключения доступны на вкладке «Дополнительно».", + nacosAdvancedHintDescription: "Настройте там метрики Prometheus, размер страницы, проверку TLS и расширения r-nacos.", + nacosGoAdvanced: "Перейти к «Дополнительно»", + nacosV3ConsolePortWarning: "8080 — порт веб-консоли Nacos 3 по умолчанию. Для управления сервисами используйте адрес Server / Admin API на порту 8848, например http://127.0.0.1:8848/nacos.", + nacosV3AdminPortWarning: "8848 обычно является портом Admin API. Для режима Console API используйте адрес консоли, обычно http://127.0.0.1:8080.", + nacosAdvancedTitle: "Дополнительные параметры подключения Nacos", + nacosAdvancedDescription: "Эти настройки имеют безопасные значения по умолчанию и обычно требуют изменения только для нестандартных развёртываний, метрик или расширений r-nacos.", + nacosContextPathHint: "Оставьте пустым, чтобы использовать значение выбранного профиля по умолчанию. Введите /, чтобы явно использовать корень сервера, или укажите префикс обратного прокси, например /nacos.", + nacosPageSizeHint: "Используется для списков конфигураций и сервисов; 1–500 элементов на страницу.", + nacosMetricsHint: "Автоматически запрашивать метрики по адресу сервиса; выберите пользовательский URL, если конечная точка метрик отличается.", + nacosRnacosExtension: "Функции консоли r-nacos", + nacosRnacosExtensionHint: "Адрес и учётные данные консоли включают управление пользователями, детали конфигураций и управление отключёнными экземплярами. История конфигурации настраивается отдельно ниже.", + nacosEnabled: "Включено", + nacosRnacosConsoleUrlHint: "Обычно http://host:10848. Требуется для управления пользователями r-nacos и других функций консоли.", + nacosRnacosDisabledHint: "История конфигурации отключена. Управление пользователями остаётся доступным, если настроены адрес и учётные данные консоли.", + nacosTlsHint: "Включайте только для доверенного самоподписанного сертификата HTTPS.", + nacosVisibleNamespacesTitle: "Выберите видимые пространства имён", + nacosVisibleNamespacesDetailLabel: "Видимые пространства имён", + nacosVisibleNamespacesDetailActionLabel: 'Настроить видимые пространства имён для "{connection}"', + nacosVisibleNamespacesDescription: "Выберите пространства имён для отображения на боковой панели для {name}.", + nacosSearchNamespaces: "Поиск пространств имён...", + nacosSelectedNamespaces: "Выбрано {selected}/{total}", + nacosSelectAll: "Выбрать все", + nacosClearSelection: "Очистить", + nacosShowAll: "Показать все", + nacosNamespaceSelectionRequired: "Выберите хотя бы одно пространство имён или используйте «Показать все», чтобы снять фильтр.", + nacosLoadNamespacesFailed: "Не удалось загрузить пространства имён: {message}", + capabilityReadOnly: "Это подключение доступно только для чтения.", + capabilityReadOnlyWrite: "В настоящее время эта реализация предоставляет только операции чтения; совместимость записи не проверена.", + capabilityVersionUnsupported: "Эта версия Nacos не поддерживает данную операцию.", + capabilityEndpointUnavailable: "Это подключение не предоставляет конечную точку управления.", + capabilityNotVerified: "Эта операция не проверена для текущей реализации.", + capabilityHeaderReadOnly: "Это подключение доступно только для чтения; запись сервисов и экземпляров отключена.", + protectionTriggeredDescription: "Режим защиты активирован, поскольку доля здоровых экземпляров ниже настроенного порога. Nacos может всё равно возвращать нездоровые экземпляры вместо пустого списка.", + instanceEphemeral: "Временный экземпляр", + instancePersistent: "Постоянный экземпляр", + instanceUnknown: "Неизвестный тип экземпляра", + instanceConfirmDetails: "Пространство имён: {namespace}\nСервис: {service}\nАдрес: {ip}:{port}\nКластер: {cluster}\nТип: {type}", + serviceUpdateUnconfirmed: "Обновление сервиса отправлено, но Nacos не вернул целевое состояние. Обновите детали сервиса для подтверждения.", + invalidWeight: "Вес должен быть конечным числом, большим или равным 0.", + invalidWeightInput: "Введите конечный вес, больший или равный 0.", + metadataLabel: "Метаданные", + viewMetadataTable: "Просмотреть таблицу", + instanceMetadataTitle: "Метаданные экземпляра", + metadataKey: "Ключ", + metadataValue: "Значение", + selectorLabel: "Селектор", + instanceUpdateUnconfirmed: "Обновление экземпляра отправлено, но Nacos не вернул новое состояние. Обновите, чтобы проверить состояние сервера.", + instanceRegisterUnconfirmed: "Регистрация экземпляра отправлена, но Nacos не вернул экземпляр. Обновите для подтверждения.", + instanceDeregisterUnconfirmed: "Дерегистрация экземпляра отправлена, но Nacos всё ещё возвращает экземпляр. Обновите для подтверждения.", + serviceValidation: "Требуются имя сервиса и группа; порог защиты должен быть между 0 и 1.", + serviceHasInstances: "Сервис всё ещё содержит экземпляры и не может быть удалён.", + serviceDeleteUnconfirmed: "Удаление сервиса отправлено, но Nacos всё ещё возвращает сервис. Перезагрузите и подтвердите.", + instanceValidation: "Введите корректный IP, порт и неотрицательный вес.", + protectionTriggered: "Режим защиты активирован", + loadedInstances: "Загружено экземпляров: {count}", + filterInstanceCluster: "Фильтр кластера экземпляров", + filter: "Фильтр", + clear: "Очистить", + serviceSettings: "Настройки сервиса", + serviceDetails: "Детали сервиса", + expand: "Развернуть", + instanceStat: "Экземпляры", + healthyInstances: "Здоровые экземпляры", + clusterCount: "Кластеры", + protectThreshold: "Порог защиты", + itemCount: "Элементов: {count}", + temporaryService: "Временный сервис", + loadingServiceDetail: "Загрузка деталей сервиса…", + refreshDetail: "Обновить детали", + noMetadata: "Нет метаданных", + noInstances: "Нет экземпляров", + createNacosService: "Создать сервис Nacos", + editNacosService: "Редактировать сервис Nacos", + manageServiceMetadata: "Управление метаданными сервиса и порогом защиты.", + serviceName: "Имя сервиса", + groupName: "Группа", + thresholdExample: "Например 0.5", + jsonObject: "Объект JSON", + optionalJsonObject: "Объект JSON, необязательно", + jsonObjectValidation: " должен быть объектом JSON.", + registerPersistentInstance: "Зарегистрировать постоянный экземпляр", + persistentInstanceHint: "DBX не регистрирует временные экземпляры, так как не может поддерживать их heartbeat.", + ipAddress: "IP-адрес", + port: "Порт", + instanceEditorTitle: "Редактировать экземпляр", + deleteNacosService: "Удалить сервис Nacos", + confirmEmptyServiceDelete: "Удалить этот пустой сервис? Это действие нельзя отменить.", + deregisterNacosInstance: "Дерегистрировать экземпляр Nacos", + confirmInstanceDeregister: "Дерегистрировать этот экземпляр из текущего сервиса?", + edit: "Редактировать", + restore: "Восстановить", + registerInstance: "Зарегистрировать экземпляр", + deregister: "Дерегистрировать", + }, + doltVersionControl: { + title: "Управление версиями Dolt", + open: "Управление версиями", + branches: "Ветки", + branchTreeView: "Древовидный вид", + branchFlatView: "Плоский вид", + expandBranch: "Развернуть группу веток", + collapseBranch: "Свернуть группу веток", + tags: "Теги", + filterRefs: "Фильтр веток и тегов", + noBranches: "Нет веток", + noTags: "Нет тегов", + unknownBranch: "Неизвестная ветка", + switchDatabase: "Переключить базу данных", + switchBranch: "Переключить ветку", + workingTree: "Рабочее дерево", + stagedChanges: "В индексе: {count}", + unstagedChanges: "Вне индекса: {count}", + uncommitted: "Не зафиксировано", + stageAllChanges: "Добавить все изменения в индекс", + commitWorkingTree: "Зафиксировать рабочее дерево", + commitWorkingTreeDescription: "Введите сообщение коммита, чтобы добавить изменения рабочего дерева в индекс и зафиксировать их.", + commitMessage: "Сообщение коммита", + commitMessagePlaceholder: "Например: Исправить статус заказа", + commitMessageRequired: "Введите сообщение коммита.", + changesStaged: "Изменения рабочего дерева добавлены в индекс", + workingTreeCommitted: "Изменения рабочего дерева зафиксированы", + comparison: "Текущее сравнение", + swapComparison: "Поменять стороны сравнения", + noRevision: "Нет ревизии", + compareCurrent: "Сравнить с текущей веткой", + checkoutBranch: "Переключиться на ветку", + branchCheckedOut: "Переключено на ветку {name}", + graph: "Граф", + commit: "Коммит", + author: "Автор", + date: "Дата", + loadingGraph: "Загрузка графа коммитов...", + noCommits: "Коммиты не найдены", + noMessage: "Нет сообщения коммита", + changedTables: "Изменённые таблицы", + loadingDiff: "Загрузка различий ревизий...", + noChanges: "Изменения таблиц между этими ревизиями не найдены.", + rowDiff: "Различия строк", + rows: "Строк: {count}", + loadingRows: "Загрузка различий строк...", + selectTable: "Выберите изменённую таблицу", + noRowChanges: "Изменения строк не возвращены. Возможно, изменение касается только схемы.", + createBranch: "Создать ветку", + createTag: "Создать тег", + mergeBranch: "Слить ветку", + deleteBranch: "Удалить ветку", + deleteTag: "Удалить тег", + createBranchDescription: "Создать ветку от выбранной ревизии или текущей ветки.", + createTagDescription: "Создать тег от выбранной ревизии или текущей ветки.", + mergeBranchDescription: "Слить ветку {name} в активную ветку.", + deleteBranchDescription: "Удалить ветку {name}. Это действие нельзя отменить.", + deleteTagDescription: "Удалить тег {name}. Это действие нельзя отменить.", + branchName: "Имя ветки", + branchNamePlaceholder: "feature/my-branch", + tagName: "Имя тега", + tagNamePlaceholder: "v1.0.0", + branchSource: "Исходная ревизия: {revision}", + branchNameRequired: "Введите имя ветки.", + tagNameRequired: "Введите имя тега.", + branchCreated: "Ветка {name} создана", + branchMerged: "Ветка {name} слита", + branchDeleted: "Ветка {name} удалена", + tagCreated: "Тег {name} создан", + tagDeleted: "Тег {name} удалён", + copyHash: "Копировать хеш коммита", + revertCommit: "Отменить этот коммит", + hardResetToCommit: "Жёстко сбросить текущую ветку к этому коммиту", + revertCommitTitle: "Отмена коммита", + hardResetTitle: "Жёсткий сброс текущей ветки", + revertCommitDescription: "Создать новый коммит, отменяющий изменения, внесённые коммитом {hash}.", + hardResetDescription: "Жёстко сбросить ветку {branch} к коммиту {hash}. Коммиты после него и все проиндексированные и неиндексированные изменения рабочего дерева будут удалены из текущего состояния.", + highRiskConfirmation: "Это операция с высоким риском. Подтвердите целевой коммит перед продолжением.", + revertCommitComplete: "Коммит {hash} отменён", + hardResetComplete: "Текущая ветка жёстко сброшена к {hash}", + discardWorkingTree: "Отменить изменения рабочего дерева", + discardWorkingTreeDescription: "Отменить все проиндексированные и неиндексированные изменения рабочего дерева. Это действие необратимо.", + discardWorkingTreeComplete: "Изменения рабочего дерева отменены", + sqlPreview: "Предпросмотр SQL", + hashCopied: "Хеш коммита скопирован", + copyCurrentValue: "Копировать текущее значение", + copyBeforeValue: "Копировать значение до", + copyAfterValue: "Копировать значение после", + cellValueCopied: "Значение ячейки скопировано", + viewCellDiff: "Показать детали различий", + cellDiffTitle: "Различие {table}.{column}", + cellDiffFormat: "Формат сравнения", + cellDiffFormatAuto: "Авто", + cellDiffFormatRaw: "Исходный", + cellDiffDetectedFormat: "Определено: {format}", + cellDiffFormatFailed: "Не удалось отформатировать; показано исходное значение: {message}", + cellNullValue: "NULL", + cellRowMissing: "Строка не существует", + cellColumnMissing: "Столбец не существует", + }, + codeSnapshot: { + title: "Снимок кода", + close: "Закрыть", + copy: "Копировать в буфер обмена", + save: "Сохранить PNG", + copied: "Скопировано", + saved: "Сохранено", + failed: "Ошибка: {message}", + take: "Сделать снимок кода", + theme: "Тема", + themeLight: "Светлая", + themeDark: "Тёмная", + windowControls: "Элементы управления окном", + lineNumbers: "Номера строк", + titleLabel: "Заголовок (необязательно)", + titlePlaceholder: "например, Пример запроса", + }, + gridSnapshot: { + open: "Снимок выбранных ячеек", + openRows: "Снимок выбранных строк", + openColumns: "Снимок выбранных столбцов", + title: "Снимок таблицы", + copied: "Скопировано", + saved: "Сохранено", + failed: "Ошибка: {message}", + reset: "Сбросить", + rows: "Строк: {count}", + columns: "Столбцов: {count}", + cells: "Ячеек: {count}", + appearance: "Внешний вид", + layout: "Макет", + fieldMetadata: "Метаданные полей", + theme: "Тема", + windowControls: "Элементы управления окном", + fieldNames: "Имена полей", + columnTypes: "Типы столбцов", + columnDetails: "Описания полей", + rowNumbers: "Номера строк", + wrapCells: "Переносить содержимое ячеек", + transpose: "Транспонировать", + compact: "Компактные ячейки", + titleLabel: "Заголовок (необязательно)", + titlePlaceholder: "например, Результат запроса", + }, + migration: { + eyebrow: "Первый запуск после обновления", + title: "Обновление защиты данных", + stepsLabel: "Этапы миграции", + language: "Язык", + step1: "Проверка и подтверждение", + step2: "Миграция данных", + step3: "Завершение и резервная копия", + successTitle: "Миграция завершена", + connectionCountLabel: "Подключения: ", + secretCountLabel: "Конфиденциальные элементы: ", + backupRequiredLabel: "Требуется резервная копия: ", + keyProviderLabel: "Статус ключа: ", + ready: "готово", + pending: "требуется настройка", + intro: "Вы только что обновили и перезапустили DBX. Это обновление повышает защиту локальных данных; выполните этот однократный шаг, чтобы продолжить использовать подключения.", + whyTitle: "Что делает это обновление?", + whyBody: "Новая версия использует более надёжное шифрование для защиты подключений, плагинов и других конфиденциальных настроек. Этот шаг выполняется один раз после обновления и больше не появится.", + whyItem1: "Перед обновлением создаётся резервная копия, чтобы при необходимости можно было восстановить данные.", + whyItem2: "Результат проверяется перед завершением, чтобы подтвердить успешность обновления защиты.", + successIntro: "Миграция завершена, проверка шифротекста пройдена. Проверьте подключения перед удалением резервной копии.", + connectionCount: "Подключения: {count}", + secretCount: "Конфиденциальные элементы для миграции: {count}", + backupPath: "Резервная копия: ", + dataDir: "Каталог данных: ", + backupDir: "Каталог резервных копий: ", + keyFileStatus: "Настроенный файл ключа: {configured}; доступен для чтения: {readable}", + persistentKeyStatus: "Постоянный поставщик ключей доступен: {available}", + yes: "да", + no: "нет", + keyUnavailable: "Ключ устройства недоступен. Разрешите доступ к связке ключей или настройте постоянный ключ.", + keyRecoveryHint: "Восстановите исходный ключ, использованный для этого каталога данных, или настройте тот же внешний ключ, которым были зашифрованы существующие данные. Не заменяйте его новым ключом.", + progress: "Создание резервной копии, миграция и проверка. Не закрывайте DBX…", + failed: "Миграция не завершена. Исходные данные сохранены.", + cleanupFailed: "Миграция завершена, но резервную копию не удалось удалить.", + retryCleanup: "Повторить удаление резервной копии", + statusFailed: "Не удалось проверить статус миграции.", + errorCode: "Код ошибки: {code}", + retryStatus: "Повторить проверку статуса", + start: "Начать миграцию", + running: "Миграция…", + retryMigration: "Повторить миграцию", + enter: "Войти в DBX", + launching: "Запуск DBX…", + deleteBackup: "Удалить резервную копию", + exportDiagnostic: "Экспортировать отредактированную диагностику", + openDataDir: "Открыть каталог данных", + openBackupDir: "Открыть расположение резервной копии", + exit: "Выйти из DBX", + confirmDelete: "Удалить эту резервную копию обновления? Ваши подключения и пароли уже хранятся на этом устройстве, поэтому удаление резервной копии не удалит список подключений или пароли, но вы больше не сможете использовать её для отката этого обновления.", + confirm: "Удалить", + cancel: "Отмена", + errors: { + persistentKeyAdvice: "Настройте DBX_SECRET_KEY_FILE или DBX_SECRET_KEY с постоянным ключом, затем повторите проверку статуса.", + cleanupAdvice: "Проверьте права доступа к каталогу резервных копий и повторите удаление резервной копии. Ваши мигрированные данные готовы к использованию.", + genericAdvice: "Устраните указанную выше проблему и повторите. Ваши исходные данные по-прежнему доступны.", + keyProviderAdvice: "Разрешите DBX доступ к связке ключей или укажите постоянный DBX_SECRET_KEY_FILE.", + backupAdvice: "Проверьте, что каталог данных доступен для записи и имеет достаточно свободного места.", + jsonAdvice: "Исправьте указанный устаревший JSON-файл, затем повторите миграцию.", + verifyAdvice: "Сохраните резервную копию и повторите. Не удаляйте резервные копии миграции, пока проверка не завершится успешно.", + }, + checking: "Проверка состояния защиты локальных данных…", + authFailed: "Не удалось проверить аутентификацию DBX.", + retry: "Повторить", + }, +}); diff --git a/apps/desktop/src/lib/app/localeOptions.ts b/apps/desktop/src/lib/app/localeOptions.ts index 17a8d41b8c..389a195a24 100644 --- a/apps/desktop/src/lib/app/localeOptions.ts +++ b/apps/desktop/src/lib/app/localeOptions.ts @@ -8,6 +8,7 @@ export const LOCALE_OPTIONS: { value: Locale; flag: string; label: string }[] = { value: "ja", flag: "🇯🇵", label: "日本語" }, { value: "ko", flag: "🇰🇷", label: "한국어" }, { value: "pt-BR", flag: "🇧🇷", label: "Português" }, + { value: "ru", flag: "🇷🇺", label: "Русский" }, { value: "tr", flag: "🇹🇷", label: "Türkçe" }, { value: "zh-CN", flag: "🇨🇳", label: "简体中文" }, { value: "zh-TW", flag: "繁", label: "繁體中文" }, diff --git a/packages/app-tests/sidebarMutationRuntime.test.ts b/packages/app-tests/sidebarMutationRuntime.test.ts index bd3ac6f21b..9f12b346af 100644 --- a/packages/app-tests/sidebarMutationRuntime.test.ts +++ b/packages/app-tests/sidebarMutationRuntime.test.ts @@ -6,7 +6,7 @@ const runtimeHost = readFileSync("apps/desktop/src/components/sidebar/SidebarTre const connectionMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarConnectionMutationRuntime.ts", "utf8"); const databaseSpecificMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarDatabaseSpecificMutationRuntime.ts", "utf8"); const tableMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarTableMutationRuntime.ts", "utf8"); -const localeSources = Object.fromEntries(["az", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"].map((locale) => [locale, readFileSync(`apps/desktop/src/i18n/locales/${locale}.ts`, "utf8")])); +const localeSources = Object.fromEntries(["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map((locale) => [locale, readFileSync(`apps/desktop/src/i18n/locales/${locale}.ts`, "utf8")])); function functionBody(name: string): string { const source = [runtimeHost, connectionMutationRuntime, databaseSpecificMutationRuntime, tableMutationRuntime].find((candidate) => candidate.includes(`function ${name}(`)); diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 64f8d108cd..81a571c062 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -726,6 +726,7 @@ enum LocaleFamily { Spanish, Italian, Portuguese, + Russian, Turkish, } @@ -758,6 +759,8 @@ fn locale_family(locale: &str) -> LocaleFamily { LocaleFamily::Italian } else if is_language("pt") { LocaleFamily::Portuguese + } else if is_language("ru") { + LocaleFamily::Russian } else { LocaleFamily::English } @@ -774,6 +777,7 @@ fn tray_menu_labels_for_locale(locale: &str) -> (&'static str, &'static str) { LocaleFamily::Italian => ("Mostra DBX", "Esci da DBX"), LocaleFamily::Turkish => ("DBX'i Göster", "DBX'ten Çık"), LocaleFamily::Portuguese => ("Mostrar DBX", "Sair do DBX"), + LocaleFamily::Russian => ("Показать DBX", "Выйти из DBX"), LocaleFamily::English => ("Show DBX", "Quit DBX"), } } @@ -791,6 +795,7 @@ fn app_menu_copy_support_info_label(locale: &str) -> &'static str { LocaleFamily::Italian => "Copia informazioni", LocaleFamily::Turkish => "Destek bilgilerini kopyala", LocaleFamily::Portuguese => "Copiar informações", + LocaleFamily::Russian => "Копировать сведения о поддержке", LocaleFamily::English => "Copy Support Info", } } @@ -807,6 +812,7 @@ fn app_menu_close_tab_label(locale: &str) -> &'static str { LocaleFamily::Italian => "Chiudi scheda", LocaleFamily::Turkish => "Sekmeyi kapat", LocaleFamily::Portuguese => "Fechar aba", + LocaleFamily::Russian => "Закрыть вкладку", LocaleFamily::English => "Close Tab", } } @@ -822,6 +828,7 @@ fn app_menu_quit_label(locale: &str, app_name: &str) -> String { LocaleFamily::Italian => format!("Esci da {app_name}"), LocaleFamily::Turkish => format!("{app_name} Uygulamasından Çık"), LocaleFamily::Portuguese => format!("Sair do {app_name}"), + LocaleFamily::Russian => format!("Выйти из {app_name}"), LocaleFamily::English => format!("Quit {app_name}"), } } @@ -1034,6 +1041,7 @@ mod tests { assert_eq!(tray_menu_labels_for_locale("it-IT"), ("Mostra DBX", "Esci da DBX")); assert_eq!(tray_menu_labels_for_locale("pt-BR"), ("Mostrar DBX", "Sair do DBX")); assert_eq!(tray_menu_labels_for_locale("tr-TR"), ("DBX'i Göster", "DBX'ten Çık")); + assert_eq!(tray_menu_labels_for_locale("ru-RU"), ("Показать DBX", "Выйти из DBX")); assert_eq!(tray_menu_labels_for_locale("en-US"), ("Show DBX", "Quit DBX")); // Unknown and empty locales fall back to English; "ita" must not match "it". assert_eq!(tray_menu_labels_for_locale("ita"), ("Show DBX", "Quit DBX")); @@ -1047,6 +1055,7 @@ mod tests { assert_eq!(app_menu_quit_label("ja-JP", "DBX"), "DBXを終了"); assert_eq!(app_menu_quit_label("ko-KR", "DBX"), "DBX 종료"); assert_eq!(app_menu_quit_label("tr-TR", "DBX"), "DBX Uygulamasından Çık"); + assert_eq!(app_menu_quit_label("ru-RU", "DBX"), "Выйти из DBX"); assert_eq!(app_menu_quit_label("az-AZ", "DBX"), "DBX-dən çıx"); assert_eq!(app_menu_quit_label("en-US", "DBX"), "Quit DBX"); assert_eq!(app_menu_quit_label("", "DBX"), "Quit DBX"); @@ -1054,6 +1063,7 @@ mod tests { assert_eq!(app_menu_copy_support_info_label("zh-TW"), "複製支援資訊"); assert_eq!(app_menu_copy_support_info_label("ko-KR"), "지원 정보 복사"); assert_eq!(app_menu_copy_support_info_label("tr-TR"), "Destek bilgilerini kopyala"); + assert_eq!(app_menu_copy_support_info_label("ru-RU"), "Копировать сведения о поддержке"); assert_eq!(app_menu_copy_support_info_label("az-AZ"), "Dəstək məlumatlarını kopyala"); assert_eq!(app_menu_copy_support_info_label("en-US"), "Copy Support Info"); assert_eq!(app_menu_close_tab_label("zh-CN"), "关闭标签页");