diff --git a/README.md b/README.md index 2723e9b..4952adf 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Use with **Qwen Code:** - **Cross-platform** - Desktop app and web interface - **File @-mentions** - Reference files directly in conversations - **MCP server integration** - Model Context Protocol support -- **Multi-language UI** - English, Chinese (Simplified & Traditional) +- **Multi-language UI** - English, Chinese (Simplified & Traditional), Russian ## Development & Building diff --git a/crates/backend/src/lib.rs b/crates/backend/src/lib.rs index db93952..9eceadf 100644 --- a/crates/backend/src/lib.rs +++ b/crates/backend/src/lib.rs @@ -483,7 +483,6 @@ impl GeminiBackend { let output = { #[cfg(windows)] { - use std::os::windows::process::CommandExt; const CREATE_NO_WINDOW: u32 = 0x08000000; Command::new("cmd.exe") .args(["/C", &command]) diff --git a/frontend/src/components/common/SettingsDialog.tsx b/frontend/src/components/common/SettingsDialog.tsx index 44ed66c..e2d8475 100644 --- a/frontend/src/components/common/SettingsDialog.tsx +++ b/frontend/src/components/common/SettingsDialog.tsx @@ -252,6 +252,7 @@ export const SettingsDialog: React.FC = ({ English 简体中文 繁體中文 + Русский diff --git a/frontend/src/i18n/config.ts b/frontend/src/i18n/config.ts index f84a0ef..59d1daf 100644 --- a/frontend/src/i18n/config.ts +++ b/frontend/src/i18n/config.ts @@ -6,9 +6,10 @@ import LanguageDetector from "i18next-browser-languagedetector"; import en from "./locales/en/translation.json"; import zhCN from "./locales/zh-CN/translation.json"; import zhTW from "./locales/zh-TW/translation.json"; +import ru from "./locales/ru/translation.json"; // Define supported languages -export const supportedLanguages = ["en", "zh-CN", "zh-TW"] as const; +export const supportedLanguages = ["en", "zh-CN", "zh-TW", "ru"] as const; export type SupportedLanguage = (typeof supportedLanguages)[number]; // Language names for display @@ -16,6 +17,7 @@ export const languageNames: Record = { en: "English", "zh-CN": "简体中文", "zh-TW": "繁體中文", + ru: "Русский", }; // Translation resources @@ -29,6 +31,9 @@ const resources = { "zh-TW": { translation: zhTW, }, + ru: { + translation: ru, + }, }; // Initialize i18next diff --git a/frontend/src/i18n/index.ts b/frontend/src/i18n/index.ts index 11851a9..67599d9 100644 --- a/frontend/src/i18n/index.ts +++ b/frontend/src/i18n/index.ts @@ -9,20 +9,21 @@ export { // Re-export commonly used react-i18next functions for convenience export { useTranslation, Trans, Translation } from "react-i18next"; -// Import the type for use in function definitions -import type { SupportedLanguage } from "./config"; +// Import the type and constant for use in function definitions +import { supportedLanguages, type SupportedLanguage } from "./config"; // Export language detection utility export const isValidLanguage = (lang: string): lang is SupportedLanguage => { - return ["en", "zh-CN", "zh-TW"].includes(lang); + return supportedLanguages.includes(lang as SupportedLanguage); }; // Export language display utility export const getLanguageDisplayName = (lang: SupportedLanguage): string => { - const names = { + const names: Record = { en: "English", "zh-CN": "简体中文", "zh-TW": "繁體中文", + ru: "Русский", }; return names[lang]; }; diff --git a/frontend/src/i18n/locales/ru/translation.json b/frontend/src/i18n/locales/ru/translation.json new file mode 100644 index 0000000..275b3d4 --- /dev/null +++ b/frontend/src/i18n/locales/ru/translation.json @@ -0,0 +1,559 @@ +{ + "common": { + "user": "Пользователь", + "cancel": "Отмена", + "save": "Сохранить", + "create": "Создать", + "delete": "Удалить", + "edit": "Редактировать", + "close": "Закрыть", + "back": "Назад", + "yes": "Да", + "no": "Нет", + "loading": "Загрузка...", + "error": "Ошибка", + "success": "Успешно", + "warning": "Предупреждение", + "info": "Информация", + "ok": "OK", + "apply": "Применить", + "confirm": "Подтвердить", + "add": "Добавить", + "remove": "Удалить", + "select": "Выбрать", + "search": "Поиск", + "filter": "Фильтр", + "clear": "Очистить", + "name": "Имя", + "type": "Тип", + "value": "Значение", + "size": "Размер", + "date": "Дата", + "status": "Статус", + "active": "Активный", + "inactive": "Неактивный", + "enabled": "Включено", + "disabled": "Отключено", + "required": "Обязательно", + "optional": "Необязательно", + "copy": "Копировать", + "copied": "Скопировано!", + "thinking": "Думает", + "unknownFile": "неизвестный файл", + "unknownSize": "неизвестный размер", + "currentDirectory": "текущая директория", + "showLess": "Показать меньше", + "showMoreLines": "Показать ещё {{count}} строк", + "completedSuccessfully": "Выполнено успешно.", + "settings": "Настройки", + "settingsTab": "Настройки" + }, + + "navigation": { + "backToHome": "Вернуться на главную", + "backToProjects": "Вернуться к проектам", + "home": "Главная", + "projects": "Проекты", + "mcpServers": "Серверы MCP" + }, + + "dashboard": { + "tagline": "{{appName}} на вашем компьютере и в вашем браузере.", + "user": "Пользователь", + "generating": "Генерация...", + "rawJsonButton": "Исходный JSON", + "rawJsonTitle": "Исходный JSON сообщения", + "projectsCard": { + "title": "Проекты", + "description": "Управление проектами, просмотр прошлых обсуждений." + }, + "mcpCard": { + "title": "Серверы MCP", + "description": "Управление конфигурацией и настройками MCP." + }, + "recentChats": { + "title": "Недавние разговоры" + } + }, + + "titleBar": { + "file": "Файл", + "view": "Вид", + "help": "Помощь", + "home": "Главная", + "projects": "Проекты", + "mcpServers": "Серверы MCP", + "toggleDarkMode": "Переключить темный режим", + "refresh": "Обновить", + "about": "О {{name}}", + "quit": "Выйти из {{name}}", + "exit": "Выход", + "settingsMenu": "Настройки..." + }, + + "projects": { + "title": "Проекты", + "addProject": "Добавить проект", + "addingProject": "Добавление проекта...", + "noProjectsFound": "Проекты не найдены.", + "loadingProjects": "Загрузка проектов…", + "failedToLoad": "Не удалось загрузить проекты.", + "failedToAdd": "Не удалось добавить проект. Пожалуйста, попробуйте снова.", + "projectDetails": "Детали проекта", + "previousDiscussions": "Предыдущие обсуждения", + "newDiscussion": "Новое обсуждение", + "creating": "Создание...", + "firstUsed": "Первое использование:", + "lastUpdated": "Последнее обновление:", + "noDiscussions": "У вас ещё нет обсуждений с {{backendName}}.", + "loadingDiscussions": "Загрузка обсуждений…", + "invalidProjectId": "Неверный ID проекта", + "failedToCreateDiscussion": "Не удалось создать обсуждение. Убедитесь, что требуемый CLI установлен.", + "newDiscussionTitle": "Новое обсуждение - {{projectName}}", + "started": "Начато", + "messages": "сообщения", + "message": "сообщение", + "startTimeUnavailable": "Время начала недоступно", + "messagesUnavailable": "Сообщения: —", + "backToHome": "Вернуться на главную", + "sha256Label": "SHA256:", + "nameLabel": "Имя:", + "firstUsedLabel": "Первое использование:", + "lastUpdatedLabel": "Последнее обновление:", + "discussionDeleted": "Обсуждение успешно удалено.", + "failedToDeleteDiscussion": "Не удалось удалить обсуждение.", + "deleteDiscussionConfirm": "Вы уверены, что хотите удалить обсуждение \"{{name}}\"? Это действие нельзя отменить.", + "deleteProjectConfirm": "Вы уверены, что хотите удалить проект \"{{name}}\"? Это действие нельзя отменить.", + "failedToDelete": "Не удалось удалить проект.", + "chatSessionLoadedSuccessfully": "Сессия чата успешно загружена." + }, + + "conversations": { + "title": "Разговоры", + "noConversationsYet": "Разговоров пока нет", + "startNewChat": "Начните новый чат, чтобы начать", + "searchingIn": "Поиск в {{count}} разговоре", + "searchingIn_other": "Поиск в {{count}} разговорах", + "conversationCount": "{{count}} разговор", + "conversationCount_other": "{{count}} разговоров", + "count": "{{count}} разговор", + "count_other": "{{count}} разговоров", + "endChat": "Завершить чат", + "endChatConfirmation": "Вы уверены, что хотите завершить чат \"{{title}}\"? Это прервет активную сессию.", + "endChatConfirm": "Вы уверены, что хотите завершить чат \"{{title}}\"? Это прервет активную сессию.", + "deleteConversationConfirm": "Вы уверены, что хотите удалить разговор \"{{title}}\"? Это действие нельзя отменить.", + "endChatButton": "Завершить чат", + "generating": "Генерация...", + "justNow": "Только что", + "minutesAgo": "{{count}}м назад", + "hoursAgo": "{{count}}ч назад", + "daysAgo": "{{count}}д назад", + "pid": "PID: {{pid}}", + "pidLabel": "PID: {{pid}}", + "active": "Активный", + "inactive": "Неактивный", + "noConversations": "Разговоров пока нет", + "backend": "Бэкенд", + "selectBackend": "Выбрать бэкенд", + "language": "Язык", + "selectLanguage": "Выбрать язык", + "model": "Модель", + "selectModel": "Выбрать модель", + "authMethod": "Метод аутентификации", + "selectAuthMethod": "Выбрать метод аутентификации", + "apiKey": "API ключ", + "baseUrl": "Базовый URL", + "oauth": "OAuth", + "provider": "Провайдер", + "qwenConfiguration": "Конфигурация Qwen Code", + "llxprtConfiguration": "Конфигурация LLxprt Code", + "geminiApiKey": "Gemini API ключ", + "enterGeminiApiKey": "Введите ваш Gemini API ключ", + "getApiKeyFrom": "Получите ваш API ключ из", + "gcpProjectId": "ID проекта Google Cloud", + "locationRegion": "Локация/Регион", + "oauthLimits": "1000 бесплатных запросов в день, 60 бесплатных запросов в минуту.", + "cloudShellInfo": "Этот метод автоматически работает в средах Google Cloud Shell", + "yoloMode": "YOLO режим", + "stillWaiting": "Всё ещё ждём...", + "messageCount": "{{count}} сообщение", + "messageCount_other": "{{count}} сообщений" + }, + + "messages": { + "typeToMention": "Введите @, чтобы упомянуть файлы, Shift+Enter для новой строки", + "rawJson": "Исходный JSON", + "messageRawJson": "Исходный JSON сообщения", + "cliInputOutputLogs": "Журналы CLI ввода/вывода", + "noCLILogs": "Журналы CLI ещё не доступны. Начните разговор, чтобы увидеть необработанное общение.", + "viewCLILogs": "Просмотр CLI ввода/вывода" + }, + + "messageInput": { + "placeholder": "Введите @, чтобы упомянуть файлы, Shift+Enter для новой строки", + "viewCliLogs": "Просмотр CLI ввода/вывода", + "cliLogsTitle": "Журналы CLI ввода/вывода", + "logTypeIn": "ВХОД", + "logTypeOut": "ВЫХОД", + "noLogsMessage": "Журналы CLI для этой сессии ещё не доступны.", + "continueConversation": "Продолжить этот разговор", + "startingConversation": "Начало разговора..." + }, + + "toolCalls": { + "pendingApproval": "Ожидает одобрения...", + "waitingForApproval": "Ожидание одобрения пользователя", + "approve": "Одобрить?", + "allow": "Разрешить", + "deny": "Отказать", + "reject": "Отклонить", + "executing": "Выполнение...", + "running": "Выполняется...", + "completed": "Завершено", + "failed": "Ошибка", + "rejected": "Отклонено", + "userRejected": "Вызов инструмента отклонен пользователем", + "commandFailed": "Команда не выполнена.", + "failedToExecute": "Не удалось выполнить.", + "googling": "Поиск в Google...", + "fetching": "Получение...", + "searchingFiles": "Поиск файлов...", + "input": "Ввод:", + "output": "Вывод:", + "fetchingUrls": "Получение {{count}} URL", + "fetchingUrl": "Получение {{url}}", + "rejectedFetch": "Получение отклонено", + "failedToFetch": "Не удалось получить", + "success": "Успешно", + "searching": "Поиск", + "searched": "Найдено", + "fetchingContent": "Получение", + "fetchedContent": "Получено", + "webSearchCompleted": "Поиск в вебе завершён", + "webFetchCompleted": "Получение из веба завершено", + "listedDirectory": "Список директории", + "fileContentNotAvailable": "Содержимое файла недоступно" + }, + + "search": { + "project": "Проект", + "allProjects": "Все проекты", + "maxResults": "Макс. результатов", + "dateRange": "Диапазон дат", + "clearFilters": "Очистить фильтры", + "noItemsMatch": "Нет совпадений по фильтру", + "directoryEmpty": "Директория пуста", + "filterItems": "Фильтровать элементы...", + "noResultsFound": "Результатов не найдено", + "searchResults": "Результаты поиска", + "searching": "Поиск...", + "searchConversations": "Поиск разговоров...", + "searchFilters": "Фильтры поиска", + "startTyping": "Начните вводить для поиска", + "hint": "Введите ключевые слова для поиска сообщений", + "tryDifferentTerms": "Попробуйте другие поисковые запросы", + "includeThinking": "Включить думание" + }, + + "fileSystem": { + "selectDirectory": "Выбрать директорию", + "selectDirectoryButton": "Выбрать директорию", + "goToParent": "Перейти к родительской директории", + "goToHome": "Перейти в домашнюю директорию", + "name": "Имя", + "size": "Размер", + "dateModified": "Дата изменения", + "failedToLoadHome": "Не удалось загрузить домашнюю директорию", + "failedToLoadDirectory": "Не удалось загрузить содержимое директории", + "failedToLoadVolumes": "Не удалось загрузить тома", + "failedToNavigateUp": "Не удалось перейти к родительской директории", + "failedToNavigateTo": "Не удалось перейти к указанному пути", + "computer": "Компьютер", + "clickToEditPath": "Нажмите для редактирования пути" + }, + + "mcp": { + "title": "Серверы MCP", + "description": "Управление конфигурациями сервера Model Context Protocol", + "noServersConfigured": "Серверы MCP не настроены", + "addFirstServer": "Добавьте ваш первый сервер", + "addNewServer": "Добавить новый сервер", + "importFromJson": "Импорт из JSON", + "pasteJson": "Вставить JSON", + "loadingSettings": "Загрузка файла настроек...", + "serverName": "Имя сервера", + "command": "Команда", + "url": "URL", + "httpUrl": "HTTP URL", + "environment": "Окружение", + "headers": "Заголовки", + "workingDirectory": "Рабочая директория", + "timeout": "Таймаут (миллисекунды)", + "trust": "Доверять этому серверу (обход подтверждений вызовов инструментов)", + "includedTools": "Включённые инструменты", + "excludedTools": "Исключённые инструменты", + "requiresAuthentication": "Требуется аутентификация", + "supportsOAuthDiscovery": "Поддерживает OAuth Discovery", + "clientId": "ID клиента", + "clientSecret": "Секрет клиента", + "authorizationUrl": "URL авторизации", + "tokenUrl": "URL токена", + "scopes": "Области", + "redirectUri": "URI перенаправления", + "tokenParameterName": "Имя параметра токена", + "audiences": "Аудитории", + "trusted": "Доверенный", + "notTrusted": "Недоверенный", + "deleteServer": "Удалить MCP сервер", + "deleteConfirmation": "Вы уверены, что хотите удалить MCP сервер {{serverName}}? Это действие нельзя отменить и навсегда удалит сервер из вашего файла settings.json.", + "deleteServerButton": "Удалить сервер", + "addNewMcpServer": "Добавить новый MCP сервер", + "sseEndpoint": "URL конечной точки SSE для сервера MCP.", + "httpEndpoint": "URL конечной точки HTTP для сервера MCP.", + "environmentDescription": "Переменные окружения, необходимые для этого сервера MCP.", + "headersDescription": "Заголовки, необходимые для этого сервера MCP. Применимо только к серверам MCP с URL и HTTP URL.", + "workingDirectoryDescription": "Рабочая директория для команды сервера.", + "oauthClientDescription": "Идентификатор клиента OAuth. Необязательно с динамической регистрацией.", + "oauthSecretDescription": "Секрет клиента OAuth. Необязательно для публичных клиентов.", + "oauthAuthUrlDescription": "Конечная точка авторизации OAuth. Автообнаружение, если опущено.", + "oauthTokenUrlDescription": "Конечная точка токена OAuth. Автообнаружение, если опущено.", + "oauthScopesDescription": "Требуемые области OAuth.", + "oauthRedirectDescription": "Пользовательский URI перенаправления. По умолчанию http://localhost:7777/oauth/callback.", + "oauthTokenParamDescription": "Имя параметра запроса для токенов в URL SSE.", + "oauthAudiencesDescription": "Аудитории, для которых действителен токен.", + "argumentsDescription": "Аргументы для передачи в команду выше.", + "enterArgument": "Введите аргумент", + "enterScope": "Введите область", + "enterAudience": "Введите аудиторию", + "writeArgsHere": "Пишите аргументы здесь", + "basicConfiguration": "Базовая конфигурация", + "transportType": "Тип транспорта", + "stdioTransport": "Stdio (локальная команда)", + "sseTransport": "SSE (Server-Sent Events)", + "httpTransport": "HTTP (HTTP Streaming)", + "commandPlaceholder": "например, python -m my_mcp_server", + "arguments": "Аргументы (через запятую)", + "argumentsPlaceholder": "например, --port, 8080, --verbose", + "sseUrl": "SSE URL", + "sseUrlPlaceholder": "http://localhost:8080/sse", + "httpUrlPlaceholder": "http://localhost:3000/mcp", + "advancedSettings": "Расширенные настройки", + "workingDirectoryPlaceholder": "./server-directory", + "authentication": "Аутентификация", + "enableOAuth": "Включить аутентификацию OAuth 2.0", + "scopesPlaceholder": "например, read, write, admin", + "toolFiltering": "Фильтрация инструментов", + "includeTools": "Включить инструменты (белый список, через запятую)", + "excludeTools": "Исключить инструменты (чёрный список, через запятую)", + "includeToolsPlaceholder": "например, safe_tool, file_reader, data_processor", + "excludeToolsPlaceholder": "например, dangerous_tool, file_deleter", + "toolFilteringDescription": "Исключённые инструменты имеют приоритет над включёнными. Оставьте оба пустыми, чтобы использовать все доступные инструменты.", + "notConfigured": "Не настроено", + "oauth": "OAuth", + "tools": "инструменты", + "enterServerName": "Введите имя сервера", + "enterCommand": "Введите команду", + "enterClientId": "Введите ID клиента MCP сервера", + "enterClientSecret": "Введите секрет клиента MCP сервера", + "enterAuthUrl": "Введите URL авторизации MCP сервера", + "enterTokenUrl": "Введите URL токена MCP сервера", + "enterRedirectUri": "Введите URI перенаправления MCP сервера", + "enterTokenParam": "Введите имя параметра токена MCP сервера" + }, + + "backend": { + "geminiCli": "Gemini CLI", + "qwenCode": "Qwen Code", + "llxprtCli": "LLxprt Code", + "geminiCliDesktop": "Gemini CLI Desktop", + "qwenCodeDesktop": "Qwen Code Desktop", + "llxprtDesktop": "LLxprt Desktop", + "gemini": "Gemini", + "qwen": "Qwen", + "llxprt": "LLxprt", + "backend": "Бэкенд", + "configuration": "Конфигурация", + "authenticationMethod": "Метод аутентификации", + "apiKey": "API ключ", + "baseUrl": "Базовый URL", + "model": "Модель", + "oauth": "OAuth", + "googleOAuth": "Google OAuth", + "vertexAi": "Vertex AI", + "cloudShell": "Cloud Shell", + "googleCloudProjectId": "ID проекта Google Cloud", + "locationRegion": "Локация/Регион", + "geminiApiKey": "Gemini API ключ", + "enterApiKey": "Введите ваш Gemini API ключ", + "getApiKeyFrom": "Получите ваш API ключ из", + "googleAiStudio": "Google AI Studio", + "enterProjectId": "ваш-проект-id", + "enterLocation": "us-central1", + "oauthFreeRequests": "1000 бесплатных запросов в день, 60 бесплатных запросов в минуту.", + "cloudShellAutomatic": "Этот метод автоматически работает в средах Google Cloud Shell", + "qwenConfiguration": "Конфигурация Qwen Code", + "geminiModels": { + "pro3": "Gemini 3 Pro (Preview)", + "pro": "Gemini 2.5 Pro", + "flash": "Gemini 2.5 Flash", + "flashLite": "Gemini 2.5 Flash-Lite" + }, + "gemini3ProRequirement": "Требуется Gemini CLI 0.16.x или новее", + "stillWaiting": "Всё ещё ждём...", + "installMessage": "Пожалуйста, установите {{backendName}} и убедитесь, что он доступен в вашем PATH.", + "installMessageGemini": "Пожалуйста, установите {{backendName}} и убедитесь, что он доступен в вашем PATH. Вы можете установить его из {{downloadUrl}}.", + "mcpCapabilities": "Серверы MCP расширяют возможности {{modelName}}, предоставляя доступ к внешним инструментам и источникам данных.", + "mcpToolExecution": "Инструменты MCP, включённые в этот сервер MCP, которые {{backendName}} может выполнить.", + "mcpToolExclusion": "Инструменты MCP, включённые в этот сервер MCP, которые {{backendName}} не может выполнить. Имеют приоритет над включёнными инструментами.", + "mcpCommandDescription": "Команда, выполняемая {{backendName}} для запуска сервера MCP.", + "projectsDescription": "Все ваши предыдущие обсуждения с {{appName}}." + }, + + "validation": { + "apiKeyRequired": "API ключ требуется для аутентификации по API ключу", + "providerRequired": "Провайдер обязателен", + "unsupportedProvider": "Выбран неподдерживаемый провайдер", + "projectIdRequired": "ID проекта Google Cloud требуется для Vertex AI", + "locationRequired": "Локация Google Cloud требуется для Vertex AI", + "modelRequired": "Как минимум одна модель должна быть доступна", + "defaultModelRequired": "Модель по умолчанию обязательна", + "defaultModelMustBeAvailable": "Модель по умолчанию должна быть одной из доступных моделей", + "baseUrlRequired": "Базовый URL обязателен", + "invalidBaseUrl": "Неверный формат базового URL", + "invalidUrlScheme": "URL должен использовать протокол HTTP или HTTPS", + "httpsRequired": "HTTPS требуется для удалённых провайдеров (HTTP разрешён только для localhost)", + "privateIpBlocked": "Невозможно использовать приватные IP-адреса. Приватные IP (10.x.x.x, 172.16.x.x, 192.168.x.x, 169.254.x.x) заблокированы для безопасности", + "metadataEndpointBlocked": "Конечные точки облачных метаданных заблокированы для безопасности", + "urlTooLong": "URL слишком длинный (максимум 500 символов)", + "apiKeyTooLong": "API ключ слишком длинный. Вы вставили весь ответ?", + "invalidApiKeyFormat": "Неверный формат API ключа. Ожидаемый формат начинается с: {{prefix}}", + "modelProviderMismatch": "Модель '{{model}}' несовместима с {{provider}}. Ожидаемый: {{expected}}", + "unknownBackendType": "Неизвестный тип бэкенда", + "serverNameRequired": "Имя сервера обязательно", + "serverNameTooShort": "Имя сервера должно быть не менее 2 символов", + "serverNameInvalidChars": "Имя сервера может содержать только буквы, цифры, подчёркивания и дефисы", + "commandRequired": "Команда обязательна для транспорта stdio", + "invalidWorkingDirectory": "Рабочая директория не должна содержать относительные пути (..)", + "urlRequired": "URL обязателен для транспорта SSE", + "httpUrlRequired": "HTTP URL обязателен для транспорта HTTP", + "invalidUrl": "Пожалуйста, введите действительный URL", + "invalidHttpUrl": "Пожалуйста, введите действительный HTTP URL", + "timeoutTooLow": "Таймаут должен быть не менее 1000мс (1 секунда)", + "timeoutTooHigh": "Таймаут не может превышать 3600000мс (1 час)", + "oauthScopesEmpty": "Области OAuth не могут быть пустыми", + "invalidRedirectUri": "URI перенаправления OAuth должен быть действительным URL", + "invalidAuthUrl": "URL авторизации OAuth должен быть действительным URL", + "invalidTokenUrl": "URL токена OAuth должен быть действительным URL", + "toolsOverlap": "Инструменты не могут быть одновременно включены и исключены: {{tools}}", + "duplicateServerName": "Дубликат имени сервера: \"{{name}}\"" + }, + + "warnings": { + "cliNotFound": "{{backendName}} не найден", + "modelUnavailable": "Модель недоступна", + "geminiFlashLiteUnavailable": "К сожалению, Gemini 2.5 Flash-Lite не пригоден к использованию из-за проблем с мышлением. Подробности смотрите здесь:", + "officialRepository": "официальный репозиторий", + "loginNotSupported": "Вход не поддерживается в {{appName}}", + "oauthNotSupported": "В настоящее время аутентификация с OAuth через {{appName}} не поддерживается.", + "oauthNotSupportedQwen": "В настоящее время аутентификация с OAuth через {{appName}} не поддерживается при использовании бэкенда {{backendName}}.", + "loginInstructions": "Для входа сначала используйте CLI напрямую для аутентификации." + }, + + "header": { + "fromCreatorsOf": "От создателей", + "languageSwitcher": "Сменить язык", + "currentLanguage": "Текущий язык: {{language}}", + "directoryPanel": "Директория", + "returnToDashboard": "Вернуться на главную", + "clickToReturnHome": "Нажмите, чтобы вернуться на главную" + }, + + "about": { + "title": "{{appName}}", + "version": "Версия {{version}}", + "description": "Мощный, современный десктопный и веб-интерфейс для **Gemini CLI** и **Qwen Code**. Создан с использованием Tauri и веб-технологий. Кроссплатформенный, с открытым исходным кодом на", + "github": "GitHub", + "features": { + "geminiModels": "• Выбор между моделями Gemini (Gemini 3 Pro, Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash-Lite)", + "qwenProviders": "• Использование **Qwen.ai OAuth/пользовательских провайдеров, совместимых с OpenAI** и моделей с Qwen Code", + "messaging": "• Отправка сообщений AI и получение ответа; обработка запросов вызова инструментов; поддержка Markdown", + "thoughtProcess": "• Наблюдение за **мышлением** Gemini", + "fileDiffs": "• Просмотр и обработка запросов редактирования с чёткими различиями файлов" + }, + "feature1": "Выбор между моделями Gemini (Gemini 3 Pro, Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash-Lite)", + "feature2": "Использование **Qwen.ai OAuth/пользовательских провайдеров, совместимых с OpenAI** и моделей с Qwen Code", + "feature3": "Отправка сообщений AI и получение ответа; обработка запросов вызова инструментов; поддержка Markdown", + "feature4": "Наблюдение за **мышлением** Gemini", + "feature5": "Просмотр и обработка запросов редактирования с чёткими различиями файлов", + "copyright": "© {{year}} {{appName}}. Все права защищены.", + "fromCreators": "От создателей" + }, + + "errors": { + "failedToLoadProjects": "Не удалось загрузить проекты.", + "failedToAddProject": "Не удалось добавить проект. Пожалуйста, попробуйте снова.", + "failedToCreateDiscussion": "Не удалось создать новое обсуждение:", + "failedToLoadChats": "Не удалось загрузить недавние чаты", + "failedToLoadConversation": "Не удалось загрузить разговор", + "noChatsFound": "Нет предыдущих чатов.", + "searchFailed": "Поиск не удался:", + "failedToOpenDialog": "Не удалось открыть диалоговое окно. Пожалуйста, попробуйте снова.", + "networkError": "Произошла сетевая ошибка", + "unknownError": "Произошла неизвестная ошибка", + "invalidInput": "Предоставлен неверный ввод", + "permissionDenied": "Доступ запрещён", + "fileNotFound": "Файл не найден", + "directoryNotFound": "Директория не найдена", + "failedToDelete": "Не удалось удалить проект.", + "failedToGetSettingsPath": "Не удалось получить путь к файлу настроек:", + "failedToLoadSettings": "Не удалось загрузить серверы MCP из файла настроек:", + "failedToSaveSettings": "Не удалось сохранить серверы MCP в файл настроек:", + "failedToLoadProjectData": "Не удалось загрузить данные проекта." + }, + + "time": { + "justNow": "Только что", + "minutesAgo": "{{count}}м назад", + "hoursAgo": "{{count}}ч назад", + "daysAgo": "{{count}}д назад", + "minuteAgo": "{{count}} минуту назад", + "minuteAgo_other": "{{count}} минут назад", + "hourAgo": "{{count}} час назад", + "hourAgo_other": "{{count}} часов назад", + "dayAgo": "{{count}} день назад", + "dayAgo_other": "{{count}} дней назад", + "weekAgo": "{{count}} неделю назад", + "weekAgo_other": "{{count}} недель назад", + "monthAgo": "{{count}} месяц назад", + "monthAgo_other": "{{count}} месяцев назад", + "yearAgo": "{{count}} год назад", + "yearAgo_other": "{{count}} лет назад" + }, + + "recentChats": { + "title": "Недавние чаты", + "started": "Начат {{date}}", + "messageCount": "{{count}} сообщение", + "messageCount_other": "{{count}} сообщений" + }, + + "accessibility": { + "backToHome": "Вернуться на главную", + "backToProjects": "Вернуться к проектам", + "goToParentDirectory": "Перейти к родительской директории", + "goToHomeDirectory": "Перейти в домашнюю директорию", + "endChat": "Завершить чат" + }, + "directoryPanel": { + "title": "Директория", + "noContent": "Нет содержимого директории" + }, + + "newChatPlaceholder": { + "title": "Готовы начать чат", + "description": "Введите ваше сообщение ниже, чтобы начать разговор с {{model}} с использованием {{backendName}}.", + "descriptionBefore": "Введите ваше сообщение ниже, чтобы начать разговор с ", + "descriptionAfter": " с использованием {{backendName}}.", + "tip": "Попробуйте задать вопросы о вашем коде, документации или любых программных темах" + } +}