diff --git a/fe-app-tachyon/extract-calls.js b/fe-app-tachyon/extract-calls.js index bae81019..c7824ab1 100644 --- a/fe-app-tachyon/extract-calls.js +++ b/fe-app-tachyon/extract-calls.js @@ -19,15 +19,15 @@ function stripIllegalReturn(code) { const files = await glob([ 'src/**/*.ts', - '../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/**/*.js', + 'src/**/*.tsx', ], { + cwd: __dirname, ignore: [ '**/*.test.ts', - '**/main.js', - '../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js', ], absolute: true, }); +console.log('Found files:', files.length); const results = {}; diff --git a/fe-app-tachyon/fill-po-translations.js b/fe-app-tachyon/fill-po-translations.js new file mode 100644 index 00000000..9a22fc35 --- /dev/null +++ b/fe-app-tachyon/fill-po-translations.js @@ -0,0 +1,62 @@ +import fs from 'fs/promises'; + +const dictionary = { + "Service Health Check": "Проверка доступности сервисов", + "Total Targets": "Всего целей", + "Passed": "Успешно", + "Failed": "Ошибки", + "Avg Latency": "Ср. задержка", + "Search domain...": "Поиск домена...", + "Section / Target": "Секция / Цель", + "Outbound Route": "Маршрут", + "Resolved IP / DNS": "IP / DNS", + "Verdict": "Статус", + "Pending": "Ожидает запуска", + "Check domain or IP (e.g. example.com)...": "Проверить домен или IP (напр. example.com)...", + "Check Custom": "Проверить свой", + "Check All": "Проверить все", + "Checking...": "Проверка...", + "Check Again": "Проверить снова", + "Testing...": "Тестирование...", + "Fetching service targets...": "Получение списка сервисов...", + "Failed to run service check.": "Не удалось выполнить проверку сервисов.", + "Failed to parse target list.": "Ошибка обработки списка целей.", + "No targets found in section configs.": "Цели в конфигурациях секций не найдены.", + "AI Chat & Tachyon Assistant": "ИИ Чат & Ассистент Tachyon", + "Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings.": "Привет! Я ИИ-ассистент Tachyon. Чем могу помочь? Задайте вопрос о блокировках, диагностике или настройках роутера.", + "Ask Tachyon AI Assistant a question...": "Задайте вопрос ИИ-ассистенту...", + "Send": "Отправить", + "Thinking...": "Думаю...", + "Failed to receive response from AI service.": "Не удалось получить ответ от ИИ-сервиса.", + "Server unavailable": "Сервер недоступен", + "AI service error": "Ошибка ИИ-сервиса", + "Check YouTube": "Проверить YouTube", + "Check YouTube availability": "Проверить доступность YouTube", + "Why Discord fails?": "Почему не работает Discord?", + "Check Mode:": "Режим проверки:", + "Active Sections": "Активные секции", + "All Profiles": "Все сервисы и профили" +}; + +async function run() { + const poPaths = [ + 'locales/tachyon.ru.po', + '../luci-app-tachyon/po/ru/tachyon.po' + ]; + + for (const p of poPaths) { + let content = await fs.readFile(p, 'utf8'); + for (const [key, val] of Object.entries(dictionary)) { + const searchTarget = `msgid "${key}"\nmsgstr ""`; + const searchTargetCRLF = `msgid "${key}"\r\nmsgstr ""`; + const replaceWith = `msgid "${key}"\nmsgstr "${val}"`; + + content = content.replace(searchTarget, replaceWith); + content = content.replace(searchTargetCRLF, replaceWith); + } + await fs.writeFile(p, content, 'utf8'); + console.log(`Updated ${p}`); + } +} + +run().catch(console.error); diff --git a/fe-app-tachyon/locales/calls.json b/fe-app-tachyon/locales/calls.json index b6a1c9c1..15ae1a14 100644 --- a/fe-app-tachyon/locales/calls.json +++ b/fe-app-tachyon/locales/calls.json @@ -1,61 +1,4 @@ [ - { - "call": "-- Select --", - "key": "-- Select --", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2062", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2439", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2818", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2833", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3031", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3046", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3282", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3434", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3444" - ] - }, - { - "call": ".lst Lists", - "key": ".lst Lists", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10205" - ] - }, - { - "call": "(provider default)", - "key": "(provider default)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1285" - ] - }, - { - "call": "+ Add JSON outbound", - "key": "+ Add JSON outbound", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8865" - ] - }, - { - "call": "+ Add level", - "key": "+ Add level", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3198" - ] - }, - { - "call": "+ Add priority", - "key": "+ Add priority", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8951" - ] - }, - { - "call": "+ Add URLTest", - "key": "+ Add URLTest", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8892" - ] - }, { "call": "⏹ Stop", "key": "⏹ Stop", @@ -77,20 +20,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1196" ] }, - { - "call": "⚠️ If all Bootstrap DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss.", - "key": "⚠️ If all Bootstrap DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:592" - ] - }, - { - "call": "⚠️ If all Main DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss.", - "key": "⚠️ If all Main DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:583" - ] - }, { "call": "✔ Running", "key": "✔ Running", @@ -116,28 +45,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:722" ] }, - { - "call": "Accept external proxy connections and route them with sing-box.", - "key": "Accept external proxy connections and route them with sing-box.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:444" - ] - }, - { - "call": "Accept routes", - "key": "Accept routes", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3132" - ] - }, - { - "call": "Action", - "key": "Action", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7236", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7266" - ] - }, { "call": "Active", "key": "Active", @@ -176,68 +83,10 @@ ] }, { - "call": "Add a section", - "key": "Add a section", + "call": "Active Sections", + "key": "Active Sections", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:433" - ] - }, - { - "call": "Add a server inbound", - "key": "Add a server inbound", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:450" - ] - }, - { - "call": "Add at least one DNS server", - "key": "Add at least one DNS server", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1843", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:122", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:166" - ] - }, - { - "call": "Add prefix to nodes", - "key": "Add prefix to nodes", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2529" - ] - }, - { - "call": "Add URLs or local paths to .lst lists containing domains and subnets.", - "key": "Add URLs or local paths to .lst lists containing domains and subnets.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9429" - ] - }, - { - "call": "Add URLs or local paths to .lst lists containing domains. IP entries are ignored.", - "key": "Add URLs or local paths to .lst lists containing domains. IP entries are ignored.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9455" - ] - }, - { - "call": "Add URLs or local paths to .srs / .json lists. Only domain rules are supported.", - "key": "Add URLs or local paths to .srs / .json lists. Only domain rules are supported.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9404" - ] - }, - { - "call": "Add URLs or local paths to .srs / .json lists. Subnets are ignored by default.", - "key": "Add URLs or local paths to .srs / .json lists. Subnets are ignored by default.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9375" - ] - }, - { - "call": "Add URLTest / Priority group", - "key": "Add URLTest / Priority group", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3456" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:130" ] }, { @@ -247,50 +96,6 @@ "src/tachyon/tabs/diagnostic/checks/runNftCheck.ts:106" ] }, - { - "call": "Additionally exclude servers by protocol, transport, and security. Exclude only servers matching the specified parameters.", - "key": "Additionally exclude servers by protocol, transport, and security. Exclude only servers matching the specified parameters.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2748", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2958" - ] - }, - { - "call": "Additionally filter servers by protocol, transport, and security. Add only servers matching the specified parameters.", - "key": "Additionally filter servers by protocol, transport, and security. Add only servers matching the specified parameters.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2731", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2940" - ] - }, - { - "call": "Additionally hide servers by protocol, transport, and security. Hide servers matching the specified parameters.", - "key": "Additionally hide servers by protocol, transport, and security. Hide servers matching the specified parameters.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3356" - ] - }, - { - "call": "Additionally show servers by protocol, transport, and security. Add only servers matching the specified parameters.", - "key": "Additionally show servers by protocol, transport, and security. Add only servers matching the specified parameters.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3336" - ] - }, - { - "call": "Address", - "key": "Address", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1652" - ] - }, - { - "call": "Administrator Chat IDs", - "key": "Administrator Chat IDs", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1691" - ] - }, { "call": "Advanced self-healing features. Requires Watchdog to be enabled.", "key": "Advanced self-healing features. Requires Watchdog to be enabled.", @@ -298,41 +103,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:579" ] }, - { - "call": "Advanced System", - "key": "Advanced System", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:508" - ] - }, - { - "call": "Advertise exit node", - "key": "Advertise exit node", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3115" - ] - }, - { - "call": "Advertise routes", - "key": "Advertise routes", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3125" - ] - }, - { - "call": "AEAD Method", - "key": "AEAD Method", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8603" - ] - }, - { - "call": "AI & Watchdog", - "key": "AI & Watchdog", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:507" - ] - }, { "call": "AI Agent REST API (12 Endpoints)", "key": "AI Agent REST API (12 Endpoints)", @@ -340,21 +110,27 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:684" ] }, - { - "call": "AI Agent REST API Bearer Token", - "key": "AI Agent REST API Bearer Token", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1237" - ] - }, { "call": "AI API Key", "key": "AI API Key", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1304", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:893" ] }, + { + "call": "AI Chat & Tachyon Assistant", + "key": "AI Chat & Tachyon Assistant", + "places": [ + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:220" + ] + }, + { + "call": "AI Chat Assistant", + "key": "AI Chat Assistant", + "places": [ + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:138" + ] + }, { "call": "AI Doctor (ChatGPT / DeepSeek API)", "key": "AI Doctor (ChatGPT / DeepSeek API)", @@ -366,31 +142,22 @@ "call": "AI Doctor Diagnosis", "key": "AI Doctor Diagnosis", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:855", - "src/tachyon/tabs/diagnostic/initController.ts:1211" - ] - }, - { - "call": "AI Doctor Diagnostic Scan in Progress...", - "key": "AI Doctor Diagnostic Scan in Progress...", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:827" + "src/tachyon/tabs/diagnostic/initController.ts:1154" ] }, { "call": "AI Doctor failed", "key": "AI Doctor failed", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:878", - "src/tachyon/tabs/diagnostic/initController.ts:1217", - "src/tachyon/tabs/diagnostic/initController.ts:1226" + "src/tachyon/tabs/diagnostic/initController.ts:843", + "src/tachyon/tabs/diagnostic/initController.ts:1160", + "src/tachyon/tabs/diagnostic/initController.ts:1168" ] }, { "call": "AI Doctor Language", "key": "AI Doctor Language", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1291", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:860" ] }, @@ -398,7 +165,6 @@ "call": "AI Model", "key": "AI Model", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1278", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:836" ] }, @@ -406,10 +172,16 @@ "call": "AI Provider", "key": "AI Provider", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1262", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:766" ] }, + { + "call": "AI service error", + "key": "AI service error", + "places": [ + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:138" + ] + }, { "call": "AI Watchdog", "key": "AI Watchdog", @@ -429,42 +201,15 @@ "key": "All", "places": [ "src/tachyon/tabs/monitoring/initController.ts:672", - "src/tachyon/tabs/monitoring/render.ts:40" + "src/tachyon/tabs/monitoring/render.ts:40", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:318" ] }, { - "call": "All except selected", - "key": "All except selected", + "call": "All Profiles", + "key": "All Profiles", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1959" - ] - }, - { - "call": "All fixes applied successfully", - "key": "All fixes applied successfully", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1068" - ] - }, - { - "call": "All remaining except selected", - "key": "All remaining except selected", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1969" - ] - }, - { - "call": "All remaining servers", - "key": "All remaining servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1967" - ] - }, - { - "call": "All remaining servers means every server not already assigned to a higher-priority level.", - "key": "All remaining servers means every server not already assigned to a higher-priority level.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2914" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:140" ] }, { @@ -475,158 +220,18 @@ "src/tachyon/tabs/monitoring/render.ts:49" ] }, - { - "call": "All servers", - "key": "All servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1958" - ] - }, - { - "call": "All traffic from these IP addresses will be routed through the section unconditionally, ignoring all other conditions.", - "key": "All traffic from these IP addresses will be routed through the section unconditionally, ignoring all other conditions.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9487" - ] - }, - { - "call": "Allow Insecure TLS", - "key": "Allow Insecure TLS", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8505" - ] - }, - { - "call": "Allowed domain prefixes are full:, keyword:, and regex:", - "key": "Allowed domain prefixes are full:, keyword:, and regex:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5323" - ] - }, - { - "call": "Allows access to YACD from the WAN. Make sure to open the appropriate port in your firewall.", - "key": "Allows access to YACD from the WAN. Make sure to open the appropriate port in your firewall.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:883" - ] - }, - { - "call": "Allows limiting the list of servers for URLTest", - "key": "Allows limiting the list of servers for URLTest", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2708" - ] - }, - { - "call": "Allows Tachyon to send diagnostic snapshots to ChatGPT or DeepSeek API for intelligent root-cause analysis and auto-repair recommendations.", - "key": "Allows Tachyon to send diagnostic snapshots to ChatGPT or DeepSeek API for intelligent root-cause analysis and auto-repair recommendations.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1251" - ] - }, - { - "call": "ALPN", - "key": "ALPN", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2644" - ] - }, - { - "call": "Alter ID", - "key": "Alter ID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2878" - ] - }, - { - "call": "AmneziaWG config loaded successfully!", - "key": "AmneziaWG config loaded successfully!", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8292" - ] - }, - { - "call": "AmneziaWG Generator", - "key": "AmneziaWG Generator", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8005" - ] - }, - { - "call": "An error occurred while checking services.", - "key": "An error occurred while checking services.", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:165" - ] - }, - { - "call": "Analyzing system log (logread & errors)", - "key": "Analyzing system log (logread & errors)", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:809" - ] - }, - { - "call": "API Key for OpenAI (sk-...) or DeepSeek (optional for Ollama / LM Studio)", - "key": "API Key for OpenAI (sk-...) or DeepSeek (optional for Ollama / LM Studio)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1305" - ] - }, - { - "call": "Apply rules of this section only to selected protocols.", - "key": "Apply rules of this section only to selected protocols.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9543" - ] - }, - { - "call": "Apply section rules only to the specified local IP addresses", - "key": "Apply section rules only to the specified local IP addresses", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9478" - ] - }, - { - "call": "Applying all fixes...", - "key": "Applying all fixes...", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1057" - ] - }, { "call": "Applying fix", "key": "Applying fix", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1024" + "src/tachyon/tabs/diagnostic/initController.ts:995" ] }, { - "call": "At least one Admin Chat ID is required", - "key": "At least one Admin Chat ID is required", + "call": "Ask Tachyon AI Assistant a question...", + "key": "Ask Tachyon AI Assistant a question...", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1702" - ] - }, - { - "call": "At least one valid domain must be specified.", - "key": "At least one valid domain must be specified.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5354" - ] - }, - { - "call": "At least one valid IP or subnet must be specified.", - "key": "At least one valid IP or subnet must be specified.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5436" - ] - }, - { - "call": "Auth Digest", - "key": "Auth Digest", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8686" + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:60" ] }, { @@ -636,120 +241,32 @@ "src/partials/modal/renderModal.ts:286" ] }, - { - "call": "Auto update", - "key": "Auto update", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3035" - ] - }, - { - "call": "Auto-detected domains", - "key": "Auto-detected domains", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1494" - ] - }, - { - "call": "Auto-detected Domains", - "key": "Auto-detected Domains", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9300" - ] - }, { "call": "Auto-detects blocked domains from logs and adds them to the first section where they work via proxy.", "key": "Auto-detects blocked domains from logs and adds them to the first section where they work via proxy.", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1454", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1053" ] }, - { - "call": "Auto-generate HWID", - "key": "Auto-generate HWID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2455" - ] - }, - { - "call": "Auto-update Hosts Lists", - "key": "Auto-update Hosts Lists", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7978" - ] - }, - { - "call": "Automatic component update checks", - "key": "Automatic component update checks", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1018" - ] - }, - { - "call": "Automatic User-Agent selection", - "key": "Automatic User-Agent selection", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2424" - ] - }, - { - "call": "Automatically add text to the name of each server from this subscription for convenient filtering.", - "key": "Automatically add text to the name of each server from this subscription for convenient filtering.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2530" - ] - }, - { - "call": "Automatically check installed components for new versions", - "key": "Automatically check installed components for new versions", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1019" - ] - }, - { - "call": "Automatically generate a Cloudflare WARP account and configure all AmneziaWG settings.", - "key": "Automatically generate a Cloudflare WARP account and configure all AmneziaWG settings.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8006" - ] - }, - { - "call": "Automatically increase check intervals when healthy (to 5 min) and decrease on problems (to 120s).", - "key": "Automatically increase check intervals when healthy (to 5 min) and decrease on problems (to 120s).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1428" - ] - }, { "call": "Automatically select the fastest node in the current level", "key": "Automatically select the fastest node in the current level", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3148", "src/tachyon/tabs/dashboard/initController.ts:1243" ] }, - { - "call": "Automatically update remote hosts lists on schedule", - "key": "Automatically update remote hosts lists on schedule", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7979" - ] - }, { "call": "Available actions", "key": "Available actions", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:52" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:54" ] }, { - "call": "Backend validation failed: %s", - "key": "Backend validation failed: %s", + "call": "Avg Latency", + "key": "Avg Latency", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5569", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6014", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6426" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:270" ] }, { @@ -759,21 +276,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:694" ] }, - { - "call": "Belarus (by)", - "key": "Belarus (by)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9249" - ] - }, - { - "call": "BitTorrent / P2P", - "key": "BitTorrent / P2P", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9526", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9545" - ] - }, { "call": "Bootstrap DNS", "key": "Bootstrap DNS", @@ -781,20 +283,6 @@ "src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:57" ] }, - { - "call": "Bootstrap DNS Servers", - "key": "Bootstrap DNS Servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:546" - ] - }, - { - "call": "Bot Status", - "key": "Bot Status", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1653" - ] - }, { "call": "Browser FakeIP check could not be completed", "key": "Browser FakeIP check could not be completed", @@ -821,52 +309,7 @@ "call": "Bug report downloaded", "key": "Bug report downloaded", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1351" - ] - }, - { - "call": "Built-in rule sets", - "key": "Built-in rule sets", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9321" - ] - }, - { - "call": "By flag emoji from name", - "key": "By flag emoji from name", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1976" - ] - }, - { - "call": "ByeDPI listen address and port are assigned by Tachyon and must not be set in the strategy.", - "key": "ByeDPI listen address and port are assigned by Tachyon and must not be set in the strategy.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6495" - ] - }, - { - "call": "ByeDPI option does not accept a compact value: %s", - "key": "ByeDPI option does not accept a compact value: %s", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6672" - ] - }, - { - "call": "ByeDPI option does not accept a value: %s", - "key": "ByeDPI option does not accept a value: %s", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6601" - ] - }, - { - "call": "ByeDPI option requires a value: %s", - "key": "ByeDPI option requires a value: %s", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6593", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6619", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6653", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6662" + "src/tachyon/tabs/diagnostic/initController.ts:1258" ] }, { @@ -911,62 +354,6 @@ "src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:108" ] }, - { - "call": "ByeDPI Strategy", - "key": "ByeDPI Strategy", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7435" - ] - }, - { - "call": "ByeDPI strategy cannot be empty", - "key": "ByeDPI strategy cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6698" - ] - }, - { - "call": "Bypasses UDP traffic for selected game consoles (PS5/Xbox) to achieve NAT Type 1 / 2 (Full Cone NAT) for P2P matchmaking, while keeping TCP (PSN/Auth) routed through the proxy.", - "key": "Bypasses UDP traffic for selected game consoles (PS5/Xbox) to achieve NAT Type 1 / 2 (Full Cone NAT) for P2P matchmaking, while keeping TCP (PSN/Auth) routed through the proxy.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:932" - ] - }, - { - "call": "CA Certificate", - "key": "CA Certificate", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8697" - ] - }, - { - "call": "Cache all built-in lists and databases even if they are not currently selected in any section. Recommended if you have plenty of storage space or USB drive.", - "key": "Cache all built-in lists and databases even if they are not currently selected in any section. Recommended if you have plenty of storage space or USB drive.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1006" - ] - }, - { - "call": "Cache File Path", - "key": "Cache File Path", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1149" - ] - }, - { - "call": "Cache file path cannot be empty", - "key": "Cache file path cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1163" - ] - }, - { - "call": "Cancel", - "key": "Cancel", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7712" - ] - }, { "call": "Cannot receive checks result", "key": "Cannot receive checks result", @@ -982,38 +369,17 @@ ] }, { - "call": "Cannot save server", - "key": "Cannot save server", + "call": "Check Again", + "key": "Check Again", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2240" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:760" ] }, { - "call": "Cannot save settings", - "key": "Cannot save settings", + "call": "Check All", + "key": "Check All", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3584" - ] - }, - { - "call": "Cascade connection", - "key": "Cascade connection", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8984" - ] - }, - { - "call": "Certificate path", - "key": "Certificate path", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2654" - ] - }, - { - "call": "Certificate pin is unavailable. Apply or restart the server to generate the default certificate, then open this dialog again.", - "key": "Certificate pin is unavailable. Apply or restart the server to generate the default certificate, then open this dialog again.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1597" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:661" ] }, { @@ -1025,34 +391,39 @@ ] }, { - "call": "Check Custom Domain", - "key": "Check Custom Domain", + "call": "Check Custom", + "key": "Check Custom", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:115", - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:131" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:549", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:646" + ] + }, + { + "call": "Check domain or IP (e.g. example.com)...", + "key": "Check domain or IP (e.g. example.com)...", + "places": [ + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:543" ] }, { "call": "Check interval", "key": "Check interval", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2636", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3099", "src/tachyon/tabs/dashboard/initController.ts:1230" ] }, + { + "call": "Check Mode:", + "key": "Check Mode:", + "places": [ + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:159" + ] + }, { "call": "Check Services", "key": "Check Services", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:136" - ] - }, - { - "call": "Check timeout after which the server is considered dead", - "key": "Check timeout after which the server is considered dead", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3112" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:148" ] }, { @@ -1066,11 +437,16 @@ "call": "Check URL", "key": "Check URL", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2662", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3086", "src/tachyon/tabs/dashboard/initController.ts:1228" ] }, + { + "call": "Check YouTube", + "key": "Check YouTube", + "places": [ + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:155" + ] + }, { "call": "Checking Connection...", "key": "Checking Connection...", @@ -1078,39 +454,11 @@ "src/tachyon/tabs/dashboard/initController.ts:1404" ] }, - { - "call": "Checking nftables filtering tables", - "key": "Checking nftables filtering tables", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:808" - ] - }, - { - "call": "Checking sing-box service & DNSmasq", - "key": "Checking sing-box service & DNSmasq", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:807" - ] - }, - { - "call": "Checking WAN interfaces & network routing", - "key": "Checking WAN interfaces & network routing", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:806" - ] - }, - { - "call": "Checking Zapret & ByeDPI rules", - "key": "Checking Zapret & ByeDPI rules", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:810" - ] - }, { "call": "Checking, please wait", "key": "Checking, please wait", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1639", + "src/tachyon/tabs/diagnostic/initController.ts:1552", "src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:14", "src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:15", "src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:15", @@ -1129,15 +477,8 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:322", "src/tachyon/tabs/dashboard/partials/renderSections.ts:420", "src/tachyon/tabs/dashboard/partials/renderSections.ts:775", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:849" - ] - }, - { - "call": "Checking…", - "key": "Checking…", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:275", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1545" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:849", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:665" ] }, { @@ -1151,17 +492,17 @@ "call": "Checks failed", "key": "Checks failed", "places": [ - "src/tachyon/tabs/diagnostic/helpers/getMeta.ts:26", - "src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:10" + "src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:10", + "src/tachyon/tabs/diagnostic/helpers/getMeta.ts:26" ] }, { "call": "Checks passed", "key": "Checks passed", "places": [ - "src/tachyon/tabs/diagnostic/helpers/getMeta.ts:13", "src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:23", - "src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:43" + "src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:43", + "src/tachyon/tabs/diagnostic/helpers/getMeta.ts:13" ] }, { @@ -1171,27 +512,6 @@ "src/tachyon/tabs/diagnostic/checks/getDnsCheckPresentation.ts:27" ] }, - { - "call": "China (cn)", - "key": "China (cn)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9246" - ] - }, - { - "call": "Choose Hosts File...", - "key": "Choose Hosts File...", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7531" - ] - }, - { - "call": "Choose whether to route traffic to all destinations except selected countries (Exclude) or only to selected countries (Include).", - "key": "Choose whether to route traffic to all destinations except selected countries (Exclude) or only to selected countries (Include).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9215" - ] - }, { "call": "CIDR must be between 0 and 32 for IPv4 or 0 and 128 for IPv6", "key": "CIDR must be between 0 and 32 for IPv4 or 0 and 128 for IPv6", @@ -1199,82 +519,18 @@ "src/validators/validateSubnet.ts:35" ] }, - { - "call": "Cipher", - "key": "Cipher", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8675" - ] - }, - { - "call": "Clean Comments", - "key": "Clean Comments", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7815" - ] - }, - { - "call": "Clear", - "key": "Clear", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10013" - ] - }, - { - "call": "Client Certificate", - "key": "Client Certificate", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8709" - ] - }, - { - "call": "Client fingerprint", - "key": "Client fingerprint", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2752" - ] - }, - { - "call": "Client Key", - "key": "Client Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8721" - ] - }, - { - "call": "Client link", - "key": "Client link", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1669" - ] - }, - { - "call": "Client link is not available yet", - "key": "Client link is not available yet", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1577" - ] - }, - { - "call": "Client link QR code", - "key": "Client link QR code", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1610" - ] - }, { "call": "Close", "key": "Close", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3651", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10221", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1717", "src/partials/modal/renderModal.ts:263", "src/tachyon/tabs/dashboard/initController.ts:1085", - "src/tachyon/tabs/diagnostic/initController.ts:1199", "src/tachyon/tabs/monitoring/initController.ts:884", "src/tachyon/tabs/monitoring/initController.ts:934", - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:28" + "src/tachyon/tabs/diagnostic/initController.ts:1144", + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:212", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:62", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:766" ] }, { @@ -1301,48 +557,6 @@ "src/tachyon/tabs/monitoring/render.ts:29" ] }, - { - "call": "Cloudflare account / device ID", - "key": "Cloudflare account / device ID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8629" - ] - }, - { - "call": "Cloudflare API access token", - "key": "Cloudflare API access token", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8641" - ] - }, - { - "call": "Cloudflare WARP account / device ID", - "key": "Cloudflare WARP account / device ID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8434" - ] - }, - { - "call": "Cloudflare WARP API access token", - "key": "Cloudflare WARP API access token", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8446" - ] - }, - { - "call": "Comma-separated list of Telegram user IDs authorized to control the bot.", - "key": "Comma-separated list of Telegram user IDs authorized to control the bot.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1692" - ] - }, - { - "call": "Community Lists", - "key": "Community Lists", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10201" - ] - }, { "call": "Component update available", "key": "Component update available", @@ -1350,20 +564,6 @@ "src/tachyon/services/core.service.ts:43" ] }, - { - "call": "Component update check interval", - "key": "Component update check interval", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1028" - ] - }, - { - "call": "Components", - "key": "Components", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:520" - ] - }, { "call": "compressed", "key": "compressed", @@ -1371,41 +571,6 @@ "src/tachyon/helpers/singBoxVariant.ts:60" ] }, - { - "call": "Concurrency", - "key": "Concurrency", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2987" - ] - }, - { - "call": "Conditions", - "key": "Conditions", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7224" - ] - }, - { - "call": "Config File Path", - "key": "Config File Path", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1135" - ] - }, - { - "call": "Configuration for Tachyon service", - "key": "Configuration for Tachyon service", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:367" - ] - }, - { - "call": "Configure User-Agent in the item settings", - "key": "Configure User-Agent in the item settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4749" - ] - }, { "call": "Conflict", "key": "Conflict", @@ -1422,13 +587,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:745" ] }, - { - "call": "Connect through", - "key": "Connect through", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9022" - ] - }, { "call": "Connected", "key": "Connected", @@ -1436,13 +594,6 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:782" ] }, - { - "call": "Connection URL", - "key": "Connection URL", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8745" - ] - }, { "call": "Connections are unavailable", "key": "Connections are unavailable", @@ -1461,7 +612,6 @@ "call": "Copied", "key": "Copied", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1564", "src/helpers/copyToClipboard.ts:10" ] }, @@ -1469,9 +619,7 @@ "call": "Copy", "key": "Copy", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1693", - "src/partials/modal/renderModal.ts:258", - "src/tachyon/tabs/diagnostic/initController.ts:1194" + "src/partials/modal/renderModal.ts:258" ] }, { @@ -1490,32 +638,11 @@ "src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:89" ] }, - { - "call": "Country code (e.g. ru, us, de)", - "key": "Country code (e.g. ru, us, de)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9252" - ] - }, { "call": "Current Diagnosis", "key": "Current Diagnosis", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1162" - ] - }, - { - "call": "Current section cannot be used as its own transit section", - "key": "Current section cannot be used as its own transit section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9039" - ] - }, - { - "call": "Current section cannot download its own subscription", - "key": "Current section cannot download its own subscription", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2416" + "src/tachyon/tabs/diagnostic/initController.ts:1110" ] }, { @@ -1529,59 +656,9 @@ "call": "Custom API Endpoint URL", "key": "Custom API Endpoint URL", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1315", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:915" ] }, - { - "call": "Custom device headers", - "key": "Custom device headers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2492" - ] - }, - { - "call": "Custom DNS Records (Hosts)", - "key": "Custom DNS Records (Hosts)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7720" - ] - }, - { - "call": "Custom domain (e.g. google.com)", - "key": "Custom domain (e.g. google.com)", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:113" - ] - }, - { - "call": "Custom OpenAI-Compatible API (OpenRouter)", - "key": "Custom OpenAI-Compatible API (OpenRouter)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1271" - ] - }, - { - "call": "Custom OpenAI-compatible API endpoint URL (e.g. http://192.168.1.100:11434/v1/chat/completions)", - "key": "Custom OpenAI-compatible API endpoint URL (e.g. http://192.168.1.100:11434/v1/chat/completions)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1316" - ] - }, - { - "call": "Custom outbound configurations in JSON format", - "key": "Custom outbound configurations in JSON format", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8860" - ] - }, - { - "call": "Dashboard", - "key": "Dashboard", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:496" - ] - }, { "call": "Dashboard currently unavailable", "key": "Dashboard currently unavailable", @@ -1589,57 +666,6 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:44" ] }, - { - "call": "Default (auto)", - "key": "Default (auto)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1818" - ] - }, - { - "call": "Default address for checking server availability and latency. URLTest uses its own address.", - "key": "Default address for checking server availability and latency. URLTest uses its own address.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1065" - ] - }, - { - "call": "Delay in milliseconds before reloading Tachyon after interface UP", - "key": "Delay in milliseconds before reloading Tachyon after interface UP", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:856" - ] - }, - { - "call": "Delay value cannot be empty", - "key": "Delay value cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:863" - ] - }, - { - "call": "Delete", - "key": "Delete", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1744" - ] - }, - { - "call": "Detect server country", - "key": "Detect server country", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2718", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2927", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3323" - ] - }, - { - "call": "Detects and drops STUN/TURN packets in nftables to prevent real IP leaks via WebRTC.", - "key": "Detects and drops STUN/TURN packets in nftables to prevent real IP leaks via WebRTC.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1205" - ] - }, { "call": "detour must be a non-empty string", "key": "detour must be a non-empty string", @@ -1647,13 +673,6 @@ "src/validators/validateOutboundJson.ts:115" ] }, - { - "call": "Device filter", - "key": "Device filter", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9477" - ] - }, { "call": "Device IPs (one per line):", "key": "Device IPs (one per line):", @@ -1668,13 +687,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:265" ] }, - { - "call": "Device or IP", - "key": "Device or IP", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6961" - ] - }, { "call": "Devices listed here are always routed through the assigned section, regardless of global rules.", "key": "Devices listed here are always routed through the assigned section, regardless of global rules.", @@ -1696,97 +708,11 @@ "src/tachyon/tabs/diagnostic/checks/getDnsCheckPresentation.ts:36" ] }, - { - "call": "Diagnostics", - "key": "Diagnostics", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:484" - ] - }, - { - "call": "Direct", - "key": "Direct", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2562" - ] - }, - { - "call": "Direct (Default)", - "key": "Direct (Default)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8464" - ] - }, - { - "call": "Direct connection", - "key": "Direct connection", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2904" - ] - }, { "call": "Disable autostart", "key": "Disable autostart", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:88" - ] - }, - { - "call": "Disable QUIC", - "key": "Disable QUIC", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:907" - ] - }, - { - "call": "Disable the QUIC protocol to improve compatibility or fix issues with video streaming", - "key": "Disable the QUIC protocol to improve compatibility or fix issues with video streaming", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:908" - ] - }, - { - "call": "Disabling interception is incompatible with action=zapret2 because Tachyon sends matched traffic through NFQUEUE.", - "key": "Disabling interception is incompatible with action=zapret2 because Tachyon sends matched traffic through NFQUEUE.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6096" - ] - }, - { - "call": "Display name", - "key": "Display name", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2618", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3075" - ] - }, - { - "call": "DNS", - "key": "DNS", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9529", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9548" - ] - }, - { - "call": "DNS Check Interval", - "key": "DNS Check Interval", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:601" - ] - }, - { - "call": "DNS Check Interval (s)", - "key": "DNS Check Interval (s)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1372" - ] - }, - { - "call": "DNS Failures Before Switching", - "key": "DNS Failures Before Switching", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:630" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:90" ] }, { @@ -1796,76 +722,6 @@ "src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:75" ] }, - { - "call": "DNS over HTTPS (DoH)", - "key": "DNS over HTTPS (DoH)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1814", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:519" - ] - }, - { - "call": "DNS over QUIC (DoQ)", - "key": "DNS over QUIC (DoQ)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1816", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:521" - ] - }, - { - "call": "DNS over TLS (DoT)", - "key": "DNS over TLS (DoT)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1815", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:520" - ] - }, - { - "call": "DNS protocol", - "key": "DNS protocol", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2585", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7294" - ] - }, - { - "call": "DNS Protocol Type", - "key": "DNS Protocol Type", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:516" - ] - }, - { - "call": "DNS protocol used by the resolver", - "key": "DNS protocol used by the resolver", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2586", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7295" - ] - }, - { - "call": "DNS requests through section", - "key": "DNS requests through section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7357", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:711" - ] - }, - { - "call": "DNS Rewrite TTL", - "key": "DNS Rewrite TTL", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:658" - ] - }, - { - "call": "DNS server", - "key": "DNS server", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2595", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7308" - ] - }, { "call": "DNS server address cannot be empty", "key": "DNS server address cannot be empty", @@ -1873,68 +729,10 @@ "src/validators/validateDns.ts:8" ] }, - { - "call": "DNS server used by the resolver", - "key": "DNS server used by the resolver", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2596", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7309" - ] - }, - { - "call": "DNS server used to obtain IP addresses for upstream DNS and proxies. If multiple servers are selected, a timeout switches to a backup.", - "key": "DNS server used to obtain IP addresses for upstream DNS and proxies. If multiple servers are selected, a timeout switches to a backup.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:547" - ] - }, - { - "call": "DNS Servers", - "key": "DNS Servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:532" - ] - }, - { - "call": "DNS Settings", - "key": "DNS Settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:503" - ] - }, - { - "call": "DNS Strategy", - "key": "DNS Strategy", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:690" - ] - }, - { - "call": "DNS Successful Checks Before Recovery", - "key": "DNS Successful Checks Before Recovery", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:644" - ] - }, - { - "call": "DNS through proxy", - "key": "DNS through proxy", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:702" - ] - }, - { - "call": "DNS through section", - "key": "DNS through section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7345" - ] - }, { "call": "DNS Turbo Cache", "key": "DNS Turbo Cache", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:680", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:479" ] }, @@ -1945,13 +743,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:289" ] }, - { - "call": "DNS Unavailability Timeout", - "key": "DNS Unavailability Timeout", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:619" - ] - }, { "call": "Do not panic, everything can be fixed, just...", "key": "Do not panic, everything can be fixed, just...", @@ -1959,63 +750,21 @@ "src/tachyon/tabs/diagnostic/partials/renderWikiDisclaimer.ts:26" ] }, - { - "call": "Do not test servers from these countries.", - "key": "Do not test servers from these countries.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2791" - ] - }, - { - "call": "Do not test servers whose names match the expression.", - "key": "Do not test servers whose names match the expression.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2807" - ] - }, - { - "call": "Do not test servers with one of the selected protocols.", - "key": "Do not test servers with one of the selected protocols.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2752" - ] - }, - { - "call": "Do not test servers with one of the selected security types.", - "key": "Do not test servers with one of the selected security types.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2758" - ] - }, - { - "call": "Do not test servers with one of the selected transports.", - "key": "Do not test servers with one of the selected transports.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2755" - ] - }, - { - "call": "Do not test specified servers.", - "key": "Do not test specified servers.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2799" - ] - }, { "call": "Doctor failed", "key": "Doctor failed", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:720", - "src/tachyon/tabs/diagnostic/initController.ts:758", - "src/tachyon/tabs/diagnostic/initController.ts:766" + "src/tachyon/tabs/diagnostic/initController.ts:721", + "src/tachyon/tabs/diagnostic/initController.ts:759", + "src/tachyon/tabs/diagnostic/initController.ts:767" ] }, { "call": "Doctor repair", "key": "Doctor repair", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:736", - "src/tachyon/tabs/diagnostic/initController.ts:745" + "src/tachyon/tabs/diagnostic/initController.ts:737", + "src/tachyon/tabs/diagnostic/initController.ts:746" ] }, { @@ -2025,63 +774,6 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:54" ] }, - { - "call": "Domain and IP lists", - "key": "Domain and IP lists", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9428" - ] - }, - { - "call": "Domain lists", - "key": "Domain lists", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9454" - ] - }, - { - "call": "Domain Resolver", - "key": "Domain Resolver", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2576" - ] - }, - { - "call": "Domain test sections", - "key": "Domain test sections", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1466" - ] - }, - { - "call": "Domains", - "key": "Domains", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9271", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10202" - ] - }, - { - "call": "Domains automatically detected by Smart Detect or added via Telegram bot. You can manually edit or remove them here.", - "key": "Domains automatically detected by Smart Detect or added via Telegram bot. You can manually edit or remove them here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9301" - ] - }, - { - "call": "Done", - "key": "Done", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8292" - ] - }, - { - "call": "Dont Touch My DHCP!", - "key": "Dont Touch My DHCP!", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1125" - ] - }, { "call": "Downlink", "key": "Downlink", @@ -2097,69 +789,6 @@ "src/partials/modal/renderModal.ts:253" ] }, - { - "call": "Download component packages via the selected section", - "key": "Download component packages via the selected section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1104" - ] - }, - { - "call": "Download components through", - "key": "Download components through", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1112" - ] - }, - { - "call": "Download components through a section", - "key": "Download components through a section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1103" - ] - }, - { - "call": "Download lists through", - "key": "Download lists through", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1090" - ] - }, - { - "call": "Download lists through a section", - "key": "Download lists through a section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1081" - ] - }, - { - "call": "Download remote lists and rule sets via the selected section", - "key": "Download remote lists and rule sets via the selected section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1082" - ] - }, - { - "call": "Download subscription through a section", - "key": "Download subscription through a section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2390" - ] - }, - { - "call": "Download subscriptions via the selected section", - "key": "Download subscriptions via the selected section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2391" - ] - }, - { - "call": "Download through", - "key": "Download through", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2399" - ] - }, { "call": "Downloaded", "key": "Downloaded", @@ -2168,21 +797,6 @@ "src/tachyon/tabs/monitoring/initController.ts:931" ] }, - { - "call": "Drag rows to change priority. The rule at the top is checked first.", - "key": "Drag rows to change priority. The rule at the top is checked first.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:427" - ] - }, - { - "call": "DSCP marks (QoS)", - "key": "DSCP marks (QoS)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9514", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10209" - ] - }, { "call": "Duplicate JSON outbound tag", "key": "Duplicate JSON outbound tag", @@ -2190,64 +804,6 @@ "src/validators/validateOutboundJson.ts:75" ] }, - { - "call": "Duplicate value", - "key": "Duplicate value", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4795" - ] - }, - { - "call": "e.g. AES-256-GCM — leave empty for default", - "key": "e.g. AES-256-GCM — leave empty for default", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8676" - ] - }, - { - "call": "e.g. google.com, 1.1.1.1, 443", - "key": "e.g. google.com, 1.1.1.1, 443", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10011" - ] - }, - { - "call": "e.g. SHA256 — leave empty for default", - "key": "e.g. SHA256 — leave empty for default", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8687" - ] - }, - { - "call": "Edit rule action", - "key": "Edit rule action", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1737", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:68" - ] - }, - { - "call": "Enable", - "key": "Enable", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7226", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2479" - ] - }, - { - "call": "Enable Adaptive Intervals", - "key": "Enable Adaptive Intervals", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1427" - ] - }, - { - "call": "Enable AI Doctor (ChatGPT / LLM Analysis)", - "key": "Enable AI Doctor (ChatGPT / LLM Analysis)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1250" - ] - }, { "call": "Enable AI Doctor (LLM Integration)", "key": "Enable AI Doctor (LLM Integration)", @@ -2255,53 +811,11 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:760" ] }, - { - "call": "Enable Anomaly Detection", - "key": "Enable Anomaly Detection", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1434" - ] - }, - { - "call": "Enable authentication", - "key": "Enable authentication", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2839" - ] - }, - { - "call": "Enable automatic updates for remote lists and rule sets", - "key": "Enable automatic updates for remote lists and rule sets", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:959" - ] - }, { "call": "Enable autostart", "key": "Enable autostart", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:98" - ] - }, - { - "call": "Enable built-in DNS resolver for domains handled by this section", - "key": "Enable built-in DNS resolver for domains handled by this section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2577" - ] - }, - { - "call": "Enable Config Validation", - "key": "Enable Config Validation", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1406" - ] - }, - { - "call": "Enable DNS Continuous Check", - "key": "Enable DNS Continuous Check", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1366" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:100" ] }, { @@ -2311,316 +825,13 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:498" ] }, - { - "call": "Enable Firewall Reload Dedup", - "key": "Enable Firewall Reload Dedup", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1379" - ] - }, - { - "call": "Enable Graceful Degradation", - "key": "Enable Graceful Degradation", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1413" - ] - }, - { - "call": "Enable Health Metrics", - "key": "Enable Health Metrics", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1386" - ] - }, - { - "call": "Enable list updates", - "key": "Enable list updates", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:958" - ] - }, - { - "call": "Enable Mixed Proxy", - "key": "Enable Mixed Proxy", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9060" - ] - }, - { - "call": "Enable Mixed Proxy Authentication", - "key": "Enable Mixed Proxy Authentication", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9101" - ] - }, - { - "call": "Enable Output Network Interface", - "key": "Enable Output Network Interface", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:758" - ] - }, - { - "call": "Enable Proxy Health Monitor", - "key": "Enable Proxy Health Monitor", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1342" - ] - }, - { - "call": "Enable Smart Cooldowns", - "key": "Enable Smart Cooldowns", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1399" - ] - }, { "call": "Enable Smart Detect", "key": "Enable Smart Detect", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1453", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1070" ] }, - { - "call": "Enable Telegram Bot", - "key": "Enable Telegram Bot", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1663" - ] - }, - { - "call": "Enable WAN DNS Fallback for Bootstrap DNS", - "key": "Enable WAN DNS Fallback for Bootstrap DNS", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:591" - ] - }, - { - "call": "Enable WAN DNS Fallback for Main DNS", - "key": "Enable WAN DNS Fallback for Main DNS", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:582" - ] - }, - { - "call": "Enable Watchdog", - "key": "Enable Watchdog", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1224" - ] - }, - { - "call": "Enable YACD", - "key": "Enable YACD", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:872" - ] - }, - { - "call": "Enable YACD WAN Access", - "key": "Enable YACD WAN Access", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:882" - ] - }, - { - "call": "Enables the background daemon that polls Telegram for commands and sends notifications.", - "key": "Enables the background daemon that polls Telegram for commands and sends notifications.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1664" - ] - }, - { - "call": "Enables the background watchdog process to monitor services and auto-recover on failures.", - "key": "Enables the background watchdog process to monitor services and auto-recover on failures.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1225" - ] - }, - { - "call": "Enter a complete sing-box inbound object", - "key": "Enter a complete sing-box inbound object", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2585" - ] - }, - { - "call": "Enter a complete sing-box outbound object", - "key": "Enter a complete sing-box outbound object", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4001" - ] - }, - { - "call": "Enter a display name", - "key": "Enter a display name", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2630", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3080", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3956", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3972" - ] - }, - { - "call": "Enter a level name", - "key": "Enter a level name", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2877", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2898" - ] - }, - { - "call": "Enter HWID", - "key": "Enter HWID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2473" - ] - }, - { - "call": "Enter the API token obtained from @BotFather.", - "key": "Enter the API token obtained from @BotFather.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1675" - ] - }, - { - "call": "Enter the HWID sent with subscription requests", - "key": "Enter the HWID sent with subscription requests", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2465" - ] - }, - { - "call": "Enter the subscription URL", - "key": "Enter the subscription URL", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8771" - ] - }, - { - "call": "Error", - "key": "Error", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8083", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8085", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8092", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8094", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8146", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8148", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8152", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8154", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8233", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8244", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8246" - ] - }, - { - "call": "Error running generator:", - "key": "Error running generator:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8154" - ] - }, - { - "call": "Error running trace:", - "key": "Error running trace:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10124" - ] - }, - { - "call": "Exclude by proxy parameters", - "key": "Exclude by proxy parameters", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2747", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2957", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3355" - ] - }, - { - "call": "Exclude by regular expression", - "key": "Exclude by regular expression", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2806", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3019", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3415" - ] - }, - { - "call": "Exclude countries", - "key": "Exclude countries", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2790", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3003", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3399" - ] - }, - { - "call": "Exclude selected countries", - "key": "Exclude selected countries", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9219" - ] - }, - { - "call": "Exclude servers", - "key": "Exclude servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2798", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3011", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3407" - ] - }, - { - "call": "Exclude servers with one of the selected protocols from this level.", - "key": "Exclude servers with one of the selected protocols from this level.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2965" - ] - }, - { - "call": "Exclude servers with one of the selected security types from this level.", - "key": "Exclude servers with one of the selected security types from this level.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2971" - ] - }, - { - "call": "Exclude servers with one of the selected transports from this level.", - "key": "Exclude servers with one of the selected transports from this level.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2968" - ] - }, - { - "call": "Exclude traffic types", - "key": "Exclude traffic types", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9523" - ] - }, - { - "call": "Exclude URLTest / Priority group", - "key": "Exclude URLTest / Priority group", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3470" - ] - }, - { - "call": "Excluded devices", - "key": "Excluded devices", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9497" - ] - }, - { - "call": "Expecting: %s", - "key": "Expecting: %s", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:54" - ] - }, { "call": "Expires", "key": "Expires", @@ -2629,31 +840,18 @@ ] }, { - "call": "Expose this section as a local HTTP+SOCKS proxy", - "key": "Expose this section as a local HTTP+SOCKS proxy", + "call": "Failed", + "key": "Failed", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9061" - ] - }, - { - "call": "External nfqws config files bypass Tachyon queue management and explicit validation.", - "key": "External nfqws config files bypass Tachyon queue management and explicit validation.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5630" - ] - }, - { - "call": "External nfqws2 config files bypass Tachyon queue management and explicit validation.", - "key": "External nfqws2 config files bypass Tachyon queue management and explicit validation.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6075" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:255", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:752" ] }, { "call": "Failed to apply fix", "key": "Failed to apply fix", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1044" + "src/tachyon/tabs/diagnostic/initController.ts:1015" ] }, { @@ -2676,7 +874,6 @@ "call": "Failed to copy!", "key": "Failed to copy!", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1566", "src/helpers/copyToClipboard.ts:12" ] }, @@ -2692,47 +889,33 @@ "src/tachyon/tabs/updates/initController.ts:774" ] }, - { - "call": "Failed to execute service check.", - "key": "Failed to execute service check.", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:44" - ] - }, { "call": "Failed to generate bug report", "key": "Failed to generate bug report", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1354" + "src/tachyon/tabs/diagnostic/initController.ts:1261" ] }, { - "call": "Failed to generate WARP config:", - "key": "Failed to generate WARP config:", + "call": "Failed to parse target list.", + "key": "Failed to parse target list.", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8085", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8094" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:115" ] }, { - "call": "Failed to parse file:", - "key": "Failed to parse file:", + "call": "Failed to receive response from AI service.", + "key": "Failed to receive response from AI service.", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8246" + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:106" ] }, { - "call": "Failed to parse service check results.", - "key": "Failed to parse service check results.", + "call": "Failed to run service check.", + "key": "Failed to run service check.", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:52" - ] - }, - { - "call": "Failed to parse WARP config:", - "key": "Failed to parse WARP config:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8148" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:97", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:785" ] }, { @@ -2763,34 +946,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:239" ] }, - { - "call": "Failed to start bot", - "key": "Failed to start bot", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1609" - ] - }, - { - "call": "Failed to start watchdog", - "key": "Failed to start watchdog", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:341" - ] - }, - { - "call": "Failed to stop bot", - "key": "Failed to stop bot", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1623" - ] - }, - { - "call": "Failed to stop watchdog", - "key": "Failed to stop watchdog", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:355" - ] - }, { "call": "Failed to update subscriptions", "key": "Failed to update subscriptions", @@ -2825,32 +980,10 @@ "src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:46" ] }, - { - "call": "FakeTLS host", - "key": "FakeTLS host", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2962" - ] - }, - { - "call": "Fallback on unknown DC", - "key": "Fallback on unknown DC", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3044" - ] - }, - { - "call": "Faster DNS health monitoring than the default cycle. Switches bootstrap DNS on failure.", - "key": "Faster DNS health monitoring than the default cycle. Switches bootstrap DNS on failure.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1367" - ] - }, { "call": "Faster server search interval", "key": "Faster server search interval", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3159", "src/tachyon/tabs/dashboard/initController.ts:1249" ] }, @@ -2862,24 +995,11 @@ ] }, { - "call": "Fetching service status, please wait...", - "key": "Fetching service status, please wait...", + "call": "Fetching service targets...", + "key": "Fetching service targets...", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:19" - ] - }, - { - "call": "Filter the servers that will be displayed on the dashboard.", - "key": "Filter the servers that will be displayed on the dashboard.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3312" - ] - }, - { - "call": "Finland (fi)", - "key": "Finland (fi)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9243" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:34", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:79" ] }, { @@ -2889,135 +1009,33 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:136" ] }, - { - "call": "Fix All", - "key": "Fix All", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1055" - ] - }, { "call": "Fix applied", "key": "Fix applied", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1039" - ] - }, - { - "call": "Fix the highlighted fields and save again.", - "key": "Fix the highlighted fields and save again.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3585", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2241" + "src/tachyon/tabs/diagnostic/initController.ts:1010" ] }, { "call": "Fixed", "key": "Fixed", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:742", - "src/tachyon/tabs/diagnostic/initController.ts:1035" + "src/tachyon/tabs/diagnostic/initController.ts:743", + "src/tachyon/tabs/diagnostic/initController.ts:1006" ] }, { - "call": "Forced device routing", - "key": "Forced device routing", + "call": "Full System Diagnostic", + "key": "Full System Diagnostic", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9486" - ] - }, - { - "call": "Forces sing-box to tunnel DNS requests via DoQ with Encrypted Client Hello (ECH) for SNI hiding.", - "key": "Forces sing-box to tunnel DNS requests via DoQ with Encrypted Client Hello (ECH) for SNI hiding.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1215" - ] - }, - { - "call": "France (fr)", - "key": "France (fr)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9242" - ] - }, - { - "call": "Fronting IP", - "key": "Fronting IP", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3007" - ] - }, - { - "call": "Fronting port", - "key": "Fronting port", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2996" - ] - }, - { - "call": "Fronting proxy protocol", - "key": "Fronting proxy protocol", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3017" - ] - }, - { - "call": "Fuzzing is not supported here because Tachyon needs deterministic runtime validation.", - "key": "Fuzzing is not supported here because Tachyon needs deterministic runtime validation.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6093" - ] - }, - { - "call": "Game Console IPs", - "key": "Game Console IPs", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:941" - ] - }, - { - "call": "Game Console Optimizer (NAT Type 1)", - "key": "Game Console Optimizer (NAT Type 1)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:931" - ] - }, - { - "call": "Generate a random 16-character hexadecimal HWID", - "key": "Generate a random 16-character hexadecimal HWID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2480" + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:158" ] }, { "call": "Generate bug report", "key": "Generate bug report", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:163" - ] - }, - { - "call": "Generate HWID", - "key": "Generate HWID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2479", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2484" - ] - }, - { - "call": "Generate HWID from router hardware information for this subscription", - "key": "Generate HWID from router hardware information for this subscription", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2456" - ] - }, - { - "call": "Generate WARP Config", - "key": "Generate WARP Config", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8009", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8047", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8063" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:175" ] }, { @@ -3027,48 +1045,6 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:89" ] }, - { - "call": "Generated!", - "key": "Generated!", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8142" - ] - }, - { - "call": "Generating…", - "key": "Generating…", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8078" - ] - }, - { - "call": "GeoIP Countries", - "key": "GeoIP Countries", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9232" - ] - }, - { - "call": "GeoIP Mode", - "key": "GeoIP Mode", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9214" - ] - }, - { - "call": "GeoSite / GeoIP", - "key": "GeoSite / GeoIP", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10206" - ] - }, - { - "call": "Germany (de)", - "key": "Germany (de)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9239" - ] - }, { "call": "GET endpoints are open on LAN. POST endpoints require Authorization: Bearer .", "key": "GET endpoints are open on LAN. POST endpoints require Authorization: Bearer .", @@ -3080,28 +1056,14 @@ "call": "Get global check", "key": "Get global check", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:107" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:109" ] }, { "call": "Global check", "key": "Global check", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:696" - ] - }, - { - "call": "gRPC service", - "key": "gRPC service", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2819" - ] - }, - { - "call": "Handshake timeout", - "key": "Handshake timeout", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3072" + "src/tachyon/tabs/diagnostic/initController.ts:697" ] }, { @@ -3112,80 +1074,10 @@ ] }, { - "call": "Hide cascade connection nodes", - "key": "Hide cascade connection nodes", + "call": "Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings.", + "key": "Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings.", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2565" - ] - }, - { - "call": "Hide individual nodes that are already included in imported subscription URLTest groups", - "key": "Hide individual nodes that are already included in imported subscription URLTest groups", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2554" - ] - }, - { - "call": "Hide intermediate nodes used as detours by other subscription nodes", - "key": "Hide intermediate nodes used as detours by other subscription nodes", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2566" - ] - }, - { - "call": "Hide selected servers.", - "key": "Hide selected servers.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3408" - ] - }, - { - "call": "Hide servers from selected groups without repeating their filtering criteria.", - "key": "Hide servers from selected groups without repeating their filtering criteria.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3471" - ] - }, - { - "call": "Hide servers from the specified countries.", - "key": "Hide servers from the specified countries.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3400" - ] - }, - { - "call": "Hide servers whose names match the expression.", - "key": "Hide servers whose names match the expression.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3416" - ] - }, - { - "call": "Hide servers with one of the selected protocols.", - "key": "Hide servers with one of the selected protocols.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3363" - ] - }, - { - "call": "Hide servers with one of the selected security types.", - "key": "Hide servers with one of the selected security types.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3367" - ] - }, - { - "call": "Hide servers with one of the selected transports.", - "key": "Hide servers with one of the selected transports.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3364" - ] - }, - { - "call": "Hide URLTest group nodes", - "key": "Hide URLTest group nodes", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2553" + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:14" ] }, { @@ -3199,15 +1091,14 @@ "call": "Higher-level check interval", "key": "Higher-level check interval", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3123", "src/tachyon/tabs/dashboard/initController.ts:1235" ] }, { - "call": "Higher-priority DNS Check", - "key": "Higher-priority DNS Check", + "call": "History", + "key": "History", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:610" + "src/tachyon/tabs/diagnostic/initController.ts:1122" ] }, { @@ -3218,89 +1109,11 @@ "src/tachyon/tabs/monitoring/initController.ts:927" ] }, - { - "call": "Hosts", - "key": "Hosts", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4264" - ] - }, - { - "call": "Hosts Lists Update Interval", - "key": "Hosts Lists Update Interval", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7985" - ] - }, - { - "call": "How many hours of metrics to keep (default 24).", - "key": "How many hours of metrics to keep (default 24).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1393" - ] - }, - { - "call": "How often higher priority levels are checked while a lower level is active", - "key": "How often higher priority levels are checked while a lower level is active", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3124" - ] - }, - { - "call": "How often the currently selected server is checked", - "key": "How often the currently selected server is checked", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3100" - ] - }, - { - "call": "How often to check DNS health in seconds (default 60).", - "key": "How often to check DNS health in seconds (default 60).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1373" - ] - }, - { - "call": "How often to check proxy health in seconds (fast tier, default 30).", - "key": "How often to check proxy health in seconds (fast tier, default 30).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1349" - ] - }, - { - "call": "How often to check Telegram for new messages (default: 5).", - "key": "How often to check Telegram for new messages (default: 5).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1715" - ] - }, - { - "call": "How often to check the active DNS servers.", - "key": "How often to check the active DNS servers.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:602" - ] - }, - { - "call": "How often to check whether a higher-priority DNS server has recovered.", - "key": "How often to check whether a higher-priority DNS server has recovered.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:611" - ] - }, { "call": "HTTP", "key": "HTTP", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9530", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9549" - ] - }, - { - "call": "HTTP (ms)", - "key": "HTTP (ms)", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:67" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:387" ] }, { @@ -3310,13 +1123,6 @@ "src/tachyon/api.ts:27" ] }, - { - "call": "HTTP hosts", - "key": "HTTP hosts", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2812" - ] - }, { "call": "HTTP REST API for external AI agents (Claude, GPT, Open-WebUI) served at /cgi-bin/tachyon-agent/", "key": "HTTP REST API for external AI agents (Claude, GPT, Open-WebUI) served at /cgi-bin/tachyon-agent/", @@ -3324,201 +1130,13 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:689" ] }, - { - "call": "HWID", - "key": "HWID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2464" - ] - }, { "call": "Idle timeout", "key": "Idle timeout", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2675", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3062", "src/tachyon/tabs/dashboard/initController.ts:1110" ] }, - { - "call": "If one health check fails with an error, continue running other checks instead of stopping.", - "key": "If one health check fails with an error, continue running other checks instead of stopping.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1414" - ] - }, - { - "call": "Import", - "key": "Import", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7577", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7590", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7640" - ] - }, - { - "call": "Import (%d records)", - "key": "Import (%d records)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7637" - ] - }, - { - "call": "Import AmneziaWG settings from .conf file", - "key": "Import AmneziaWG settings from .conf file", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8164" - ] - }, - { - "call": "Import Hosts File", - "key": "Import Hosts File", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7691", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7824" - ] - }, - { - "call": "Import subscription URLTest groups", - "key": "Import subscription URLTest groups", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2544" - ] - }, - { - "call": "Import URLTest groups returned by this subscription provider", - "key": "Import URLTest groups returned by this subscription provider", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2545" - ] - }, - { - "call": "Inbound JSON", - "key": "Inbound JSON", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2584" - ] - }, - { - "call": "Inbound JSON cannot be empty", - "key": "Inbound JSON cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1970" - ] - }, - { - "call": "Inbound JSON must be an object with a type field", - "key": "Inbound JSON must be an object with a type field", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1981" - ] - }, - { - "call": "Include by proxy parameters", - "key": "Include by proxy parameters", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2730", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2939", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3335" - ] - }, - { - "call": "Include by regular expression", - "key": "Include by regular expression", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2782", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2995", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3391" - ] - }, - { - "call": "Include countries", - "key": "Include countries", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2766", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2979", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3375" - ] - }, - { - "call": "Include IP addresses and subnets", - "key": "Include IP addresses and subnets", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4076" - ] - }, - { - "call": "Include selected countries", - "key": "Include selected countries", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9220" - ] - }, - { - "call": "Include servers", - "key": "Include servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2774", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2987", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3383" - ] - }, - { - "call": "Information", - "key": "Information", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1745" - ] - }, - { - "call": "Init Packet Magic Header (S1)", - "key": "Init Packet Magic Header (S1)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8401" - ] - }, - { - "call": "Init Packet Magic Header (S3)", - "key": "Init Packet Magic Header (S3)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8403" - ] - }, - { - "call": "Init Packet Payload (I1)", - "key": "Init Packet Payload (I1)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8409" - ] - }, - { - "call": "Init Packet Payload (I2)", - "key": "Init Packet Payload (I2)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8410" - ] - }, - { - "call": "Init Packet Payload (I3)", - "key": "Init Packet Payload (I3)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8411" - ] - }, - { - "call": "Init Packet Payload (I4)", - "key": "Init Packet Payload (I4)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8412" - ] - }, - { - "call": "Init Packet Payload (I5)", - "key": "Init Packet Payload (I5)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8413" - ] - }, { "call": "Install", "key": "Install", @@ -3548,51 +1166,14 @@ "src/tachyon/tabs/updates/initController.ts:1144" ] }, - { - "call": "Interface Monitoring", - "key": "Interface Monitoring", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:821" - ] - }, - { - "call": "Interface Monitoring Delay", - "key": "Interface Monitoring Delay", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:855" - ] - }, - { - "call": "Interface monitoring for Bad WAN", - "key": "Interface monitoring for Bad WAN", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:822" - ] - }, { "call": "Interrupt connections", "key": "Interrupt connections", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2689", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3175", "src/tachyon/tabs/dashboard/initController.ts:1112", "src/tachyon/tabs/dashboard/initController.ts:1255" ] }, - { - "call": "Interrupt connections when priority failover switches server", - "key": "Interrupt connections when priority failover switches server", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3176" - ] - }, - { - "call": "Interrupt connections when URLTest switches the selected server", - "key": "Interrupt connections when URLTest switches the selected server", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2690" - ] - }, { "call": "Interval", "key": "Interval", @@ -3600,13 +1181,6 @@ "src/tachyon/tabs/dashboard/initController.ts:1108" ] }, - { - "call": "Invalid ByeDPI strategy", - "key": "Invalid ByeDPI strategy", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7456" - ] - }, { "call": "Invalid CIDR prefix", "key": "Invalid CIDR prefix", @@ -3632,7 +1206,6 @@ "call": "Invalid domain address", "key": "Invalid domain address", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5303", "src/validators/validateDomain.ts:67", "src/validators/validateDomain.ts:73" ] @@ -3754,17 +1327,9 @@ "call": "Invalid JSON format", "key": "Invalid JSON format", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1983", "src/validators/validateOutboundJson.ts:58" ] }, - { - "call": "Invalid line: \"%s\". Use: domain ip or ip domain", - "key": "Invalid line: \"%s\". Use: domain ip or ip domain", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7754" - ] - }, { "call": "Invalid path format. Path must start with \"/\" and contain valid characters", "key": "Invalid path format. Path must start with \"/\" and contain valid characters", @@ -3776,24 +1341,9 @@ "call": "Invalid port number. Must be between 1 and 65535", "key": "Invalid port number. Must be between 1 and 65535", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9094", "src/validators/validateShadowsocksUrl.ts:91" ] }, - { - "call": "Invalid port or range. Use 80 or 1000-2000", - "key": "Invalid port or range. Use 80 or 1000-2000", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5452" - ] - }, - { - "call": "Invalid regular expression", - "key": "Invalid regular expression", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4678" - ] - }, { "call": "Invalid Shadowsocks URL: decoded credentials must contain method:password", "key": "Invalid Shadowsocks URL: decoded credentials must contain method:password", @@ -4084,78 +1634,19 @@ "src/validators/validateVmessUrl.ts:68" ] }, - { - "call": "IP / DNS", - "key": "IP / DNS", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:64" - ] - }, - { - "call": "IP Addresses (IP CIDR)", - "key": "IP Addresses (IP CIDR)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10203" - ] - }, - { - "call": "IPs", - "key": "IPs", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9311" - ] - }, - { - "call": "IPv4 only", - "key": "IPv4 only", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:692" - ] - }, - { - "call": "IPv6 only", - "key": "IPv6 only", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:694" - ] - }, - { - "call": "Isolate BitTorrent traffic and force it direct to prevent VPN bans", - "key": "Isolate BitTorrent traffic and force it direct to prevent VPN bans", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:920" - ] - }, { "call": "Issues", "key": "Issues", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:738" + "src/tachyon/tabs/diagnostic/initController.ts:739" ] }, { "call": "Issues detected", "key": "Issues detected", "places": [ - "src/tachyon/tabs/diagnostic/helpers/getMeta.ts:20", - "src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:17" - ] - }, - { - "call": "Japan (jp)", - "key": "Japan (jp)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9247" - ] - }, - { - "call": "JSON outbound", - "key": "JSON outbound", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1082", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4000", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4266", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8859" + "src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:17", + "src/tachyon/tabs/diagnostic/helpers/getMeta.ts:20" ] }, { @@ -4186,91 +1677,13 @@ "src/validators/validateOutboundJson.ts:66" ] }, - { - "call": "JSON outbound settings", - "key": "JSON outbound settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4024" - ] - }, - { - "call": "Junk Max Size (Jmax)", - "key": "Junk Max Size (Jmax)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8400" - ] - }, - { - "call": "Junk Min Size (Jmin)", - "key": "Junk Min Size (Jmin)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8399" - ] - }, - { - "call": "Junk Packet Count (Jc)", - "key": "Junk Packet Count (Jc)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8398" - ] - }, - { - "call": "Kazakhstan (kz)", - "key": "Kazakhstan (kz)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9250" - ] - }, - { - "call": "Keep Priority before latency-sorted servers", - "key": "Keep Priority before latency-sorted servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3185" - ] - }, - { - "call": "Keep URLTest before latency-sorted servers", - "key": "Keep URLTest before latency-sorted servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2699" - ] - }, { "call": "Keeps FakeIP cache persistent across reboots and pre-resolves popular blocked domains on startup so first-visit latency is 0 ms.", "key": "Keeps FakeIP cache persistent across reboots and pre-resolves popular blocked domains on startup so first-visit latency is 0 ms.", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:681", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:484" ] }, - { - "call": "Key", - "key": "Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8592" - ] - }, - { - "call": "Key path", - "key": "Key path", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2669" - ] - }, - { - "call": "Keyword must not contain spaces or commas", - "key": "Keyword must not contain spaces or commas", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4688" - ] - }, - { - "call": "Language for AI Doctor diagnosis responses", - "key": "Language for AI Doctor diagnosis responses", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1292" - ] - }, { "call": "Latency test failed", "key": "Latency test failed", @@ -4279,13 +1692,6 @@ "src/tachyon/methods/shell/index.ts:501" ] }, - { - "call": "Latency test URL", - "key": "Latency test URL", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1064" - ] - }, { "call": "Latest version is installed", "key": "Latest version is installed", @@ -4301,13 +1707,6 @@ "src/tachyon/tabs/updates/initController.ts:1144" ] }, - { - "call": "Leave empty to omit this header", - "key": "Leave empty to omit this header", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2510" - ] - }, { "call": "Level", "key": "Level", @@ -4315,48 +1714,6 @@ "src/tachyon/tabs/dashboard/initController.ts:1191" ] }, - { - "call": "Level name", - "key": "Level name", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2893" - ] - }, - { - "call": "List must be an HTTP(S) URL or a local .lst path", - "key": "List must be an HTTP(S) URL or a local .lst path", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7157" - ] - }, - { - "call": "List of domains automatically detected and the section they were added to. To edit or remove them, open the routing rules of the respective section.", - "key": "List of domains automatically detected and the section they were added to. To edit or remove them, open the routing rules of the respective section.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1495" - ] - }, - { - "call": "List Update Frequency", - "key": "List Update Frequency", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:968" - ] - }, - { - "call": "Listen address", - "key": "Listen address", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2534" - ] - }, - { - "call": "Listen port", - "key": "Listen port", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2541" - ] - }, { "call": "Listening port", "key": "Listening port", @@ -4368,53 +1725,9 @@ "call": "LM Studio (Local PC / Server)", "key": "LM Studio (Local PC / Server)", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1270", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:821" ] }, - { - "call": "Load .conf", - "key": "Load .conf", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8215", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8224" - ] - }, - { - "call": "Load .conf config", - "key": "Load .conf config", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8163" - ] - }, - { - "call": "Load Current Records", - "key": "Load Current Records", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7550" - ] - }, - { - "call": "Loaded %d current record(s)", - "key": "Loaded %d current record(s)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7547" - ] - }, - { - "call": "Loaded!", - "key": "Loaded!", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8290" - ] - }, - { - "call": "Loading client link...", - "key": "Loading client link...", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1702" - ] - }, { "call": "Loading connections", "key": "Loading connections", @@ -4441,20 +1754,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1174" ] }, - { - "call": "Local Address", - "key": "Local Address", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8312" - ] - }, - { - "call": "Log Level", - "key": "Log Level", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1186" - ] - }, { "call": "lx", "key": "lx", @@ -4469,76 +1768,6 @@ "src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:67" ] }, - { - "call": "Main DNS server. If multiple servers are selected, a timeout switches to a backup.", - "key": "Main DNS server. If multiple servers are selected, a timeout switches to a backup.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:533" - ] - }, - { - "call": "MASQUE Access Token", - "key": "MASQUE Access Token", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8640" - ] - }, - { - "call": "MASQUE Account ID", - "key": "MASQUE Account ID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8628" - ] - }, - { - "call": "MASQUE Private Key", - "key": "MASQUE Private Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8616" - ] - }, - { - "call": "Match destination IPs or subnets", - "key": "Match destination IPs or subnets", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9312" - ] - }, - { - "call": "Match destination ports. Use a single port or a range", - "key": "Match destination ports. Use a single port or a range", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9507" - ] - }, - { - "call": "Match Found", - "key": "Match Found", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10064" - ] - }, - { - "call": "Match traffic by packet DSCP mark (assigned in Windows via Policy-Based QoS). Examples: 46 (EF), 0x2e, 34 (AF41)", - "key": "Match traffic by packet DSCP mark (assigned in Windows via Policy-Based QoS). Examples: 46 (EF), 0x2e, 34 (AF41)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9515" - ] - }, - { - "call": "Max reconnects per hour before alert (default 10).", - "key": "Max reconnects per hour before alert (default 10).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1441" - ] - }, - { - "call": "Maximum time to wait for example.com to resolve during a DNS health check.", - "key": "Maximum time to wait for example.com to resolve during a DNS health check.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:620" - ] - }, { "call": "Memory Usage", "key": "Memory Usage", @@ -4546,69 +1775,6 @@ "src/tachyon/tabs/dashboard/initController.ts:1656" ] }, - { - "call": "Method", - "key": "Method", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2826" - ] - }, - { - "call": "Metrics Retention (hours)", - "key": "Metrics Retention (hours)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1392" - ] - }, - { - "call": "Minimum latency difference in milliseconds that triggers switching to a faster server.", - "key": "Minimum latency difference in milliseconds that triggers switching to a faster server.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2649" - ] - }, - { - "call": "Mixed Proxy Password", - "key": "Mixed Proxy Password", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9152" - ] - }, - { - "call": "Mixed Proxy Port", - "key": "Mixed Proxy Port", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9075" - ] - }, - { - "call": "Mixed Proxy Username", - "key": "Mixed Proxy Username", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9116" - ] - }, - { - "call": "Model name to use. Leave empty to use default (gpt-4o-mini / claude-3-5-haiku / deepseek-chat / llama3:latest).", - "key": "Model name to use. Leave empty to use default (gpt-4o-mini / claude-3-5-haiku / deepseek-chat / llama3:latest).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1279" - ] - }, - { - "call": "Monitored Interfaces", - "key": "Monitored Interfaces", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:831" - ] - }, - { - "call": "Monitoring", - "key": "Monitoring", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:508" - ] - }, { "call": "Monitoring & Analytics", "key": "Monitoring & Analytics", @@ -4616,13 +1782,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:633" ] }, - { - "call": "Monitors sing-box reconnect frequency. Alerts if too many reconnects per hour.", - "key": "Monitors sing-box reconnect frequency. Alerts if too many reconnects per hour.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1435" - ] - }, { "call": "Move down", "key": "Move down", @@ -4637,79 +1796,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:993" ] }, - { - "call": "MTU", - "key": "MTU", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8375" - ] - }, - { - "call": "Must be a comma-separated list of numeric IDs", - "key": "Must be a comma-separated list of numeric IDs", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1705" - ] - }, - { - "call": "Must be a number in the range of 0 - 10000", - "key": "Must be a number in the range of 0 - 10000", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2074", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2089" - ] - }, - { - "call": "Name displayed on the dashboard", - "key": "Name displayed on the dashboard", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2619", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3076" - ] - }, - { - "call": "Name shown in the priority level list", - "key": "Name shown in the priority level list", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2894" - ] - }, - { - "call": "Netherlands (nl)", - "key": "Netherlands (nl)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9240" - ] - }, - { - "call": "Network & Interfaces", - "key": "Network & Interfaces", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:504" - ] - }, - { - "call": "Network Interface", - "key": "Network Interface", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1889", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8818" - ] - }, - { - "call": "Network interface settings", - "key": "Network interface settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3775" - ] - }, - { - "call": "New domains:", - "key": "New domains:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7631" - ] - }, { "call": "New version %s is available for %s", "key": "New version %s is available for %s", @@ -4733,34 +1819,6 @@ "src/tachyon/tabs/diagnostic/checks/runZapretCheck.ts:96" ] }, - { - "call": "NFQWS Strategy", - "key": "NFQWS Strategy", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7374" - ] - }, - { - "call": "NFQWS strategy cannot be empty", - "key": "NFQWS strategy cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5760" - ] - }, - { - "call": "NFQWS2 Strategy", - "key": "NFQWS2 Strategy", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7407" - ] - }, - { - "call": "NFQWS2 strategy cannot be empty", - "key": "NFQWS2 strategy cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6234" - ] - }, { "call": "No", "key": "No", @@ -4789,7 +1847,6 @@ "call": "No active routing sections found.", "key": "No active routing sections found.", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:389", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1112" ] }, @@ -4807,32 +1864,11 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:32" ] }, - { - "call": "No Custom Rules Matched", - "key": "No Custom Rules Matched", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10113" - ] - }, { "call": "No diagnostic history available yet.", "key": "No diagnostic history available yet.", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1097" - ] - }, - { - "call": "No domains detected yet", - "key": "No domains detected yet", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1510" - ] - }, - { - "call": "No domains found to check.", - "key": "No domains found to check.", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:57" + "src/tachyon/tabs/diagnostic/initController.ts:1042" ] }, { @@ -4842,18 +1878,11 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:187" ] }, - { - "call": "No file selected", - "key": "No file selected", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7554" - ] - }, { "call": "No issues found", "key": "No issues found", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:745" + "src/tachyon/tabs/diagnostic/initController.ts:746" ] }, { @@ -4874,7 +1903,7 @@ "call": "No quick fix required", "key": "No quick fix required", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1087" + "src/tachyon/tabs/diagnostic/initController.ts:1032" ] }, { @@ -4898,6 +1927,13 @@ "src/tachyon/tabs/diagnostic/checks/runZapret2Check.ts:82" ] }, + { + "call": "No targets found in section configs.", + "key": "No targets found in section configs.", + "places": [ + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:123" + ] + }, { "call": "Node list is empty", "key": "Node list is empty", @@ -4912,16 +1948,6 @@ "src/tachyon/tabs/dashboard/initController.ts:975" ] }, - { - "call": "None", - "key": "None", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:449", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2599", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2891", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2900" - ] - }, { "call": "Not configured", "key": "Not configured", @@ -4994,169 +2020,19 @@ "key": "Not running", "places": [ "src/tachyon/tabs/diagnostic/diagnostic.store.ts:140", - "src/tachyon/tabs/diagnostic/initController.ts:123", - "src/tachyon/tabs/diagnostic/initController.ts:353", - "src/tachyon/tabs/diagnostic/initController.ts:411", - "src/tachyon/tabs/diagnostic/initController.ts:497" - ] - }, - { - "call": "Not set", - "key": "Not set", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10179" - ] - }, - { - "call": "Notify on Certificate Warnings", - "key": "Notify on Certificate Warnings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1787" - ] - }, - { - "call": "Notify on Core Crashes", - "key": "Notify on Core Crashes", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1735" - ] - }, - { - "call": "Notify on DNS Leaks", - "key": "Notify on DNS Leaks", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1800" - ] - }, - { - "call": "Notify on Server Switches", - "key": "Notify on Server Switches", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1761" - ] - }, - { - "call": "Notify on Service Restarts", - "key": "Notify on Service Restarts", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1748" - ] - }, - { - "call": "Notify on Subscription Updates", - "key": "Notify on Subscription Updates", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1774" - ] - }, - { - "call": "Number of consecutive failed checks required before switching DNS servers.", - "key": "Number of consecutive failed checks required before switching DNS servers.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:631" - ] - }, - { - "call": "Number of consecutive failures before restarting (default 3).", - "key": "Number of consecutive failures before restarting (default 3).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1355" - ] - }, - { - "call": "Number of consecutive successful checks required before returning to a higher-priority DNS server.", - "key": "Number of consecutive successful checks required before returning to a higher-priority DNS server.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:645" - ] - }, - { - "call": "Obfuscation", - "key": "Obfuscation", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2899" - ] - }, - { - "call": "Obfuscation password", - "key": "Obfuscation password", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2922" + "src/tachyon/tabs/diagnostic/initController.ts:124", + "src/tachyon/tabs/diagnostic/initController.ts:354", + "src/tachyon/tabs/diagnostic/initController.ts:412", + "src/tachyon/tabs/diagnostic/initController.ts:498" ] }, { "call": "Ollama (Local PC / Server)", "key": "Ollama (Local PC / Server)", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1269", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:813" ] }, - { - "call": "One record per line: example.com 192.168.1.100 or 192.168.1.100 example.com. Lines starting with # are ignored.", - "key": "One record per line: example.com 192.168.1.100 or 192.168.1.100 example.com. Lines starting with # are ignored.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7721" - ] - }, - { - "call": "Only from the specified countries.", - "key": "Only from the specified countries.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2980" - ] - }, - { - "call": "Only selected", - "key": "Only selected", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1960", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1968" - ] - }, - { - "call": "Only selected except exclusions", - "key": "Only selected except exclusions", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1961", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1970" - ] - }, - { - "call": "Only servers whose names match the expression.", - "key": "Only servers whose names match the expression.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2996" - ] - }, - { - "call": "Only servers with one of the selected protocols.", - "key": "Only servers with one of the selected protocols.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2947" - ] - }, - { - "call": "Only servers with one of the selected security types.", - "key": "Only servers with one of the selected security types.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2951" - ] - }, - { - "call": "Only servers with one of the selected transports.", - "key": "Only servers with one of the selected transports.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2948" - ] - }, - { - "call": "Only the specified servers.", - "key": "Only the specified servers.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2988" - ] - }, { "call": "Open", "key": "Open", @@ -5165,13 +2041,6 @@ "src/tachyon/tabs/updates/initController.ts:1157" ] }, - { - "call": "Open priority settings and enter a display name", - "key": "Open priority settings and enter a display name", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3968" - ] - }, { "call": "Open Project Page", "key": "Open Project Page", @@ -5195,21 +2064,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:664" ] }, - { - "call": "Option \"%s\" contains an invalid input value.", - "key": "Option \"%s\" contains an invalid input value.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1399", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6836" - ] - }, - { - "call": "Optional — leave empty for default", - "key": "Optional — leave empty for default", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8604" - ] - }, { "call": "Optional for local LLM", "key": "Optional for local LLM", @@ -5218,38 +2072,10 @@ ] }, { - "call": "Optional tls-auth or tls-crypt key", - "key": "Optional tls-auth or tls-crypt key", + "call": "Outbound Route", + "key": "Outbound Route", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8734" - ] - }, - { - "call": "Optional values must be attached with '=' here; a separate token would be ignored by nfqws.", - "key": "Optional values must be attached with '=' here; a separate token would be ignored by nfqws.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5838" - ] - }, - { - "call": "Optional values must be attached with '=' here; a separate token would be ignored by nfqws2.", - "key": "Optional values must be attached with '=' here; a separate token would be ignored by nfqws2.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6312" - ] - }, - { - "call": "Or paste hosts file content:", - "key": "Or paste hosts file content:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7696" - ] - }, - { - "call": "Outbound", - "key": "Outbound", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:63" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:358" ] }, { @@ -5260,69 +2086,10 @@ ] }, { - "call": "Output Network Interface", - "key": "Output Network Interface", + "call": "Passed", + "key": "Passed", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:768" - ] - }, - { - "call": "Override the default OpenWrt device headers for this subscription", - "key": "Override the default OpenWrt device headers for this subscription", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2493" - ] - }, - { - "call": "Overwrite existing records (if unchecked, merge with existing records)", - "key": "Overwrite existing records (if unchecked, merge with existing records)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7705" - ] - }, - { - "call": "P2P Leak Protection", - "key": "P2P Leak Protection", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:919" - ] - }, - { - "call": "Padding", - "key": "Padding", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2981" - ] - }, - { - "call": "Parsed records:", - "key": "Parsed records:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7628" - ] - }, - { - "call": "Password", - "key": "Password", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8483", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8571", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2862" - ] - }, - { - "call": "Password cannot be empty", - "key": "Password cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9178" - ] - }, - { - "call": "Paste content or upload a file to preview imported DNS records.", - "key": "Paste content or upload a file to preview imported DNS records.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7573", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7588" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:240" ] }, { @@ -5332,27 +2099,6 @@ "src/validators/validatePath.ts:7" ] }, - { - "call": "Path must be absolute (start with /)", - "key": "Path must be absolute (start with /)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1167" - ] - }, - { - "call": "Path must contain at least one directory (like /tmp/cache.db)", - "key": "Path must contain at least one directory (like /tmp/cache.db)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1176" - ] - }, - { - "call": "Path must end with cache.db", - "key": "Path must end with cache.db", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1171" - ] - }, { "call": "Pause updates", "key": "Pause updates", @@ -5362,39 +2108,12 @@ "src/tachyon/tabs/monitoring/render.ts:81" ] }, - { - "call": "Peer Public Key", - "key": "Peer Public Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8335" - ] - }, - { - "call": "PEM-encoded CA certificate", - "key": "PEM-encoded CA certificate", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8698" - ] - }, - { - "call": "PEM-encoded client certificate", - "key": "PEM-encoded client certificate", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8710" - ] - }, - { - "call": "PEM-encoded client private key", - "key": "PEM-encoded client private key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8722" - ] - }, { "call": "Pending", "key": "Pending", "places": [ - "src/tachyon/tabs/diagnostic/diagnostic.store.ts:63" + "src/tachyon/tabs/diagnostic/diagnostic.store.ts:63", + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:442" ] }, { @@ -5405,63 +2124,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1159" ] }, - { - "call": "Periodically check the current level and switch to a faster server even when the current one works.", - "key": "Periodically check the current level and switch to a faster server even when the current one works.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3149" - ] - }, - { - "call": "Periodically checks if the proxy is responding. Restarts Tachyon after consecutive failures.", - "key": "Periodically checks if the proxy is responding. Restarts Tachyon after consecutive failures.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1343" - ] - }, - { - "call": "Persistent Keepalive", - "key": "Persistent Keepalive", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8382" - ] - }, - { - "call": "Persistent Smart Detect", - "key": "Persistent Smart Detect", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1420" - ] - }, - { - "call": "Pin on dashboard", - "key": "Pin on dashboard", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2698", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3184" - ] - }, - { - "call": "Polling Interval (seconds)", - "key": "Polling Interval (seconds)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1714" - ] - }, - { - "call": "Polling interval must be at least 1 second", - "key": "Polling interval must be at least 1 second", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1727" - ] - }, - { - "call": "Port cannot be empty", - "key": "Port cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9086" - ] - }, { "call": "Port conflict", "key": "Port conflict", @@ -5469,100 +2131,6 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:19" ] }, - { - "call": "Port for the local mixed proxy of this section", - "key": "Port for the local mixed proxy of this section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9076" - ] - }, - { - "call": "Port must be between 1 and 65535", - "key": "Port must be between 1 and 65535", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5459", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1813" - ] - }, - { - "call": "Port range start must be less than or equal to end", - "key": "Port range start must be less than or equal to end", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5463" - ] - }, - { - "call": "Ports", - "key": "Ports", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9506", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10208" - ] - }, - { - "call": "Pre-download all preset lists", - "key": "Pre-download all preset lists", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1005" - ] - }, - { - "call": "Pre-shared key", - "key": "Pre-shared key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8526" - ] - }, - { - "call": "Prefer IPv4", - "key": "Prefer IPv4", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:691" - ] - }, - { - "call": "Prefer IPv6", - "key": "Prefer IPv6", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:693" - ] - }, - { - "call": "Preferred IP", - "key": "Preferred IP", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3024" - ] - }, - { - "call": "Prefix text", - "key": "Prefix text", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2537" - ] - }, - { - "call": "Preshared Key", - "key": "Preshared Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8369" - ] - }, - { - "call": "Prevents multiple reload_firewall calls within 120 seconds to avoid connection drops.", - "key": "Prevents multiple reload_firewall calls within 120 seconds to avoid connection drops.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1380" - ] - }, - { - "call": "Priority", - "key": "Priority", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8945", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10103" - ] - }, { "call": "Priority details", "key": "Priority details", @@ -5579,37 +2147,6 @@ "src/tachyon/tabs/dashboard/initController.ts:1216" ] }, - { - "call": "Priority level settings", - "key": "Priority level settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3853", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3854" - ] - }, - { - "call": "Priority levels", - "key": "Priority levels", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3193" - ] - }, - { - "call": "Priority settings", - "key": "Priority settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3913", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3918", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3919" - ] - }, - { - "call": "Private Key", - "key": "Private Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8324" - ] - }, { "call": "Protection", "key": "Protection", @@ -5617,37 +2154,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:613" ] }, - { - "call": "Protocol", - "key": "Protocol", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2030", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8663", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2485", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2519" - ] - }, - { - "call": "Proxy Fail Threshold", - "key": "Proxy Fail Threshold", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1354" - ] - }, - { - "call": "Proxy Health Check Interval (s)", - "key": "Proxy Health Check Interval (s)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1348" - ] - }, - { - "call": "Proxy Health Check URL", - "key": "Proxy Health Check URL", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1360" - ] - }, { "call": "Proxy link is unavailable", "key": "Proxy link is unavailable", @@ -5655,114 +2161,13 @@ "src/tachyon/tabs/dashboard/initController.ts:807" ] }, - { - "call": "Proxy Section for Bot", - "key": "Proxy Section for Bot", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1811" - ] - }, - { - "call": "Proxy to use for WARP API registration (api.cloudflareclient.com)", - "key": "Proxy to use for WARP API registration (api.cloudflareclient.com)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8457" - ] - }, - { - "call": "PSK", - "key": "PSK", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8526" - ] - }, { "call": "Public host", "key": "Public host", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2548", "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:40" ] }, - { - "call": "QR code is too large", - "key": "QR code is too large", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1612" - ] - }, - { - "call": "QUIC (HTTP/3)", - "key": "QUIC (HTTP/3)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9527", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9546" - ] - }, - { - "call": "RDP", - "key": "RDP", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9533", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9552" - ] - }, - { - "call": "Read error", - "key": "Read error", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8296" - ] - }, - { - "call": "Reality fake site", - "key": "Reality fake site", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2687" - ] - }, - { - "call": "Reality fake site port", - "key": "Reality fake site port", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2698" - ] - }, - { - "call": "Reality max time difference", - "key": "Reality max time difference", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2741" - ] - }, - { - "call": "Reality private key", - "key": "Reality private key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2709" - ] - }, - { - "call": "Reality public key", - "key": "Reality public key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2716" - ] - }, - { - "call": "Reality short ID", - "key": "Reality short ID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2722" - ] - }, - { - "call": "Reality short ID must contain 1-8 hex digits", - "key": "Reality short ID must contain 1-8 hex digits", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2094" - ] - }, { "call": "Rebuilt release", "key": "Rebuilt release", @@ -5771,31 +2176,10 @@ ] }, { - "call": "Recommended Smart Quick Fixes:", - "key": "Recommended Smart Quick Fixes:", + "call": "Recommended Quick Fixes:", + "key": "Recommended Quick Fixes:", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1007" - ] - }, - { - "call": "Reconnect Threshold", - "key": "Reconnect Threshold", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1440" - ] - }, - { - "call": "Records proxy/DNS latency and health status in hourly buckets for analysis.", - "key": "Records proxy/DNS latency and health status in hourly buckets for analysis.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1387" - ] - }, - { - "call": "Records: %d", - "key": "Records: %d", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7779" + "src/tachyon/tabs/diagnostic/initController.ts:979" ] }, { @@ -5805,20 +2189,6 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:132" ] }, - { - "call": "Registration Detour", - "key": "Registration Detour", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8456" - ] - }, - { - "call": "Regular expression must not contain spaces or commas", - "key": "Regular expression must not contain spaces or commas", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5345" - ] - }, { "call": "Reinstall", "key": "Reinstall", @@ -5826,110 +2196,25 @@ "src/tachyon/tabs/updates/initController.ts:898" ] }, - { - "call": "Remote Hosts Lists", - "key": "Remote Hosts Lists", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7838" - ] - }, { "call": "Remove", "key": "Remove", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7918", "src/tachyon/tabs/updates/initController.ts:854" ] }, { - "call": "Remove servers from the specified countries from this level.", - "key": "Remove servers from the specified countries from this level.", + "call": "Resolved IP / DNS", + "key": "Resolved IP / DNS", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3004" - ] - }, - { - "call": "Remove servers whose names match the expression from this level.", - "key": "Remove servers whose names match the expression from this level.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3020" - ] - }, - { - "call": "Remove the specified servers from this level.", - "key": "Remove the specified servers from this level.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3012" - ] - }, - { - "call": "Require a username and password for the local mixed proxy", - "key": "Require a username and password for the local mixed proxy", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9102" - ] - }, - { - "call": "Resolve domain names before routing so sing-box can use real destination IPs.", - "key": "Resolve domain names before routing so sing-box can use real destination IPs.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9189" - ] - }, - { - "call": "Resolve real IP for routing", - "key": "Resolve real IP for routing", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9188" - ] - }, - { - "call": "Resource selection by hostname inside nfqws is not supported here; sing-box selects resources before NFQUEUE.", - "key": "Resource selection by hostname inside nfqws is not supported here; sing-box selects resources before NFQUEUE.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5633" - ] - }, - { - "call": "Resource selection by hostname inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE.", - "key": "Resource selection by hostname inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6078" - ] - }, - { - "call": "Resource selection by IP or CIDR inside nfqws is not supported here; sing-box selects resources before NFQUEUE.", - "key": "Resource selection by IP or CIDR inside nfqws is not supported here; sing-box selects resources before NFQUEUE.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5636" - ] - }, - { - "call": "Resource selection by IP or CIDR inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE.", - "key": "Resource selection by IP or CIDR inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6081" - ] - }, - { - "call": "Response Packet Magic Header (S2)", - "key": "Response Packet Magic Header (S2)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8402" - ] - }, - { - "call": "Response Packet Magic Header (S4)", - "key": "Response Packet Magic Header (S4)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8404" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:363" ] }, { "call": "Restart Tachyon", "key": "Restart Tachyon", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:58" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:60" ] }, { @@ -5954,41 +2239,6 @@ "src/tachyon/tabs/monitoring/initController.ts:929" ] }, - { - "call": "Route bot API requests through this section. Leave empty to use the default mixed proxy.", - "key": "Route bot API requests through this section. Leave empty to use the default mixed proxy.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1812" - ] - }, - { - "call": "Route main DNS requests through the selected section.", - "key": "Route main DNS requests through the selected section.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:703" - ] - }, - { - "call": "Route requests to this DNS server through another section.", - "key": "Route requests to this DNS server through another section.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7346" - ] - }, - { - "call": "Routing mode", - "key": "Routing mode", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2560" - ] - }, - { - "call": "Routing Rule Tracer", - "key": "Routing Rule Tracer", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10008" - ] - }, { "call": "Routing rules", "key": "Routing rules", @@ -5998,58 +2248,6 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:144" ] }, - { - "call": "Routing section", - "key": "Routing section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2569" - ] - }, - { - "call": "Rule", - "key": "Rule", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10074" - ] - }, - { - "call": "Rule set must be an HTTP(S) URL or a local .srs / .json path", - "key": "Rule set must be an HTTP(S) URL or a local .srs / .json path", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7148" - ] - }, - { - "call": "Rule set settings", - "key": "Rule set settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4083" - ] - }, - { - "call": "Rule sets", - "key": "Rule sets", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9374", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9403" - ] - }, - { - "call": "Rule Sets (.srs / .json)", - "key": "Rule Sets (.srs / .json)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10204" - ] - }, - { - "call": "Rules", - "key": "Rules", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2561", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:101", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:107" - ] - }, { "call": "Rules mangle counters", "key": "Rules mangle counters", @@ -6096,7 +2294,7 @@ "call": "Run AI Doctor", "key": "Run AI Doctor", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:126" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:128" ] }, { @@ -6110,40 +2308,22 @@ "call": "Run doctor repair", "key": "Run doctor repair", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:116" - ] - }, - { - "call": "Run History", - "key": "Run History", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1174" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:118" ] }, { "call": "Running", "key": "Running", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:301", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1573", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1574", "src/tachyon/methods/custom/getDashboardSections.ts:1567", "src/tachyon/tabs/dashboard/partials/renderSections.ts:581", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135" ] }, - { - "call": "Russia (ru)", - "key": "Russia (ru)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9237" - ] - }, { "call": "Save", "key": "Save", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3660", "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1151" ] }, @@ -6179,24 +2359,10 @@ ] }, { - "call": "Secret", - "key": "Secret", + "call": "Search domain...", + "key": "Search domain...", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2938" - ] - }, - { - "call": "Secret key for authenticating remote access to YACD when WAN access is enabled.", - "key": "Secret key for authenticating remote access to YACD when WAN access is enabled.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:896" - ] - }, - { - "call": "Secret token for authorizing WRITE operations (POST/PUT) on /cgi-bin/tachyon-agent/. Leave empty if auth is not required.", - "key": "Secret token for authorizing WRITE operations (POST/PUT) on /cgi-bin/tachyon-agent/. Leave empty if auth is not required.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1238" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:328" ] }, { @@ -6207,38 +2373,10 @@ ] }, { - "call": "Section", - "key": "Section", + "call": "Section / Target", + "key": "Section / Target", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:432" - ] - }, - { - "call": "Section / Domain", - "key": "Section / Domain", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:62" - ] - }, - { - "call": "Section action", - "key": "Section action", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10198" - ] - }, - { - "call": "Section name", - "key": "Section name", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7253" - ] - }, - { - "call": "Section Rules Content", - "key": "Section Rules Content", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10213" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:353" ] }, { @@ -6248,191 +2386,13 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1078" ] }, - { - "call": "Sections", - "key": "Sections", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:426" - ] - }, - { - "call": "Security", - "key": "Security", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2042", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2596" - ] - }, - { - "call": "Select a common client profile or enter a custom User-Agent", - "key": "Select a common client profile or enter a custom User-Agent", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2436" - ] - }, - { - "call": "Select a file with .conf extension", - "key": "Select a file with .conf extension", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8233" - ] - }, - { - "call": "Select a network interface", - "key": "Select a network interface", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8824" - ] - }, - { - "call": "Select a predefined domain list", - "key": "Select a predefined domain list", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9322" - ] - }, - { - "call": "Select a section", - "key": "Select a section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7367", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:87" - ] - }, - { - "call": "Select a section for downloading this subscription", - "key": "Select a section for downloading this subscription", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2413" - ] - }, - { - "call": "Select a transit section", - "key": "Select a transit section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9023" - ] - }, - { - "call": "Select AI LLM provider for diagnostics", - "key": "Select AI LLM provider for diagnostics", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1263" - ] - }, - { - "call": "Select an existing network interface", - "key": "Select an existing network interface", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1940" - ] - }, - { - "call": "Select an existing URLTest or Priority group", - "key": "Select an existing URLTest or Priority group", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3295" - ] - }, - { - "call": "Select an intermediate section", - "key": "Select an intermediate section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9036" - ] - }, - { - "call": "Select and order the sections through which blocked domains are tested. Checked sections are tried top-to-bottom.", - "key": "Select and order the sections through which blocked domains are tested. Checked sections are tried top-to-bottom.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1467" - ] - }, - { - "call": "Select DNS protocol to use", - "key": "Select DNS protocol to use", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:517" - ] - }, - { - "call": "Select network interface for VPN connection", - "key": "Select network interface for VPN connection", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8819" - ] - }, - { - "call": "Select one or more country ISO codes (e.g. ru, us, de, nl, fr, fi, se, tr, cn, jp, sg, by, kz, ua).", - "key": "Select one or more country ISO codes (e.g. ru, us, de, nl, fr, fi, se, tr, cn, jp, sg, by, kz, ua).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9233" - ] - }, - { - "call": "Select or enter a User-Agent", - "key": "Select or enter a User-Agent", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2449" - ] - }, - { - "call": "Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing", - "key": "Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1150" - ] - }, - { - "call": "Select or enter the IP addresses of your game consoles.", - "key": "Select or enter the IP addresses of your game consoles.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:942" - ] - }, - { - "call": "Select path for sing-box config file. Change this ONLY if you know what you are doing", - "key": "Select path for sing-box config file. Change this ONLY if you know what you are doing", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1136" - ] - }, { "call": "Select the fastest node", "key": "Select the fastest node", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3137", "src/tachyon/tabs/dashboard/initController.ts:1239" ] }, - { - "call": "Select the log level for sing-box", - "key": "Select the log level for sing-box", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1187" - ] - }, - { - "call": "Select the network interface from which the traffic will originate", - "key": "Select the network interface from which the traffic will originate", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:721" - ] - }, - { - "call": "Select the network interface to which the traffic will originate", - "key": "Select the network interface to which the traffic will originate", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:769" - ] - }, - { - "call": "Select the WAN interfaces to be monitored", - "key": "Select the WAN interfaces to be monitored", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:832" - ] - }, { "call": "Selected", "key": "Selected", @@ -6441,13 +2401,6 @@ "src/tachyon/tabs/dashboard/initController.ts:1225" ] }, - { - "call": "Selected section", - "key": "Selected section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2563" - ] - }, { "call": "Selector and URLTest outbounds must contain a non-empty outbounds array", "key": "Selector and URLTest outbounds must contain a non-empty outbounds array", @@ -6456,115 +2409,10 @@ ] }, { - "call": "Send a Telegram notification if a potential DNS leak is detected.", - "key": "Send a Telegram notification if a potential DNS leak is detected.", + "call": "Send", + "key": "Send", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1801" - ] - }, - { - "call": "Send a Telegram notification if sing-box or nftables rules crash and get auto-restored.", - "key": "Send a Telegram notification if sing-box or nftables rules crash and get auto-restored.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1736" - ] - }, - { - "call": "Send a Telegram notification if SSL/TLS certificates are close to expiration.", - "key": "Send a Telegram notification if SSL/TLS certificates are close to expiration.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1788" - ] - }, - { - "call": "Send a Telegram notification if the Tachyon service is restarted by the watchdog.", - "key": "Send a Telegram notification if the Tachyon service is restarted by the watchdog.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1749" - ] - }, - { - "call": "Send a Telegram notification when a URLTest group switches to a new server.", - "key": "Send a Telegram notification when a URLTest group switches to a new server.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1762" - ] - }, - { - "call": "Send a Telegram notification when proxy subscriptions are successfully updated.", - "key": "Send a Telegram notification when proxy subscriptions are successfully updated.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1775" - ] - }, - { - "call": "Server", - "key": "Server", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:449" - ] - }, - { - "call": "Server Address", - "key": "Server Address", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8346", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8471", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8514", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8545", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8580", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8650" - ] - }, - { - "call": "Server filtering", - "key": "Server filtering", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2707", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2913" - ] - }, - { - "call": "Server group for automatic lowest-latency selection", - "key": "Server group for automatic lowest-latency selection", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8887" - ] - }, - { - "call": "Server group for priority failover", - "key": "Server group for priority failover", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8946" - ] - }, - { - "call": "Server information", - "key": "Server information", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1706" - ] - }, - { - "call": "Server name", - "key": "Server name", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1622", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2496" - ] - }, - { - "call": "Server name / SNI", - "key": "Server name / SNI", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2625" - ] - }, - { - "call": "Server Name Indication — leave empty to use server address", - "key": "Server Name Indication — leave empty to use server address", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8495" + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:67" ] }, { @@ -6582,15 +2430,10 @@ ] }, { - "call": "Server Port", - "key": "Server Port", + "call": "Server unavailable", + "key": "Server unavailable", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8357", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8477", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8520", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8551", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8586", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8656" + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:135" ] }, { @@ -6600,48 +2443,20 @@ "src/validators/validateOutboundJson.ts:107" ] }, - { - "call": "Servers", - "key": "Servers", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:443" - ] - }, - { - "call": "Servers on dashboard", - "key": "Servers on dashboard", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3311" - ] - }, { "call": "Service action failed", "key": "Service action failed", "places": [ "src/tachyon/methods/shell/index.ts:401", "src/tachyon/methods/shell/index.ts:422", - "src/tachyon/tabs/diagnostic/initController.ts:604" + "src/tachyon/tabs/diagnostic/initController.ts:605" ] }, { "call": "Service Health Check", "key": "Service Health Check", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:24" - ] - }, - { - "call": "Service list", - "key": "Service list", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9325" - ] - }, - { - "call": "Services & Access", - "key": "Services & Access", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:505" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:70" ] }, { @@ -6651,84 +2466,12 @@ "src/tachyon/tabs/dashboard/initController.ts:1666" ] }, - { - "call": "Settings", - "key": "Settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1143", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7223", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:461" - ] - }, - { - "call": "Show metadata on dashboard", - "key": "Show metadata on dashboard", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2520" - ] - }, - { - "call": "Show only selected servers.", - "key": "Show only selected servers.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3384" - ] - }, - { - "call": "Show only servers with one of the selected protocols.", - "key": "Show only servers with one of the selected protocols.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3343" - ] - }, - { - "call": "Show only servers with one of the selected security types.", - "key": "Show only servers with one of the selected security types.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3349" - ] - }, - { - "call": "Show only servers with one of the selected transports.", - "key": "Show only servers with one of the selected transports.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3346" - ] - }, - { - "call": "Show servers from selected groups without repeating their filtering criteria.", - "key": "Show servers from selected groups without repeating their filtering criteria.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3457" - ] - }, - { - "call": "Show servers only from the specified countries.", - "key": "Show servers only from the specified countries.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3376" - ] - }, - { - "call": "Show servers whose names match the expression.", - "key": "Show servers whose names match the expression.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3392" - ] - }, { "call": "Show sing-box config", "key": "Show sing-box config", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1287", - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:154" - ] - }, - { - "call": "Show subscription metadata for this source on the dashboard", - "key": "Show subscription metadata for this source on the dashboard", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2521" + "src/tachyon/tabs/diagnostic/initController.ts:1194", + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:166" ] }, { @@ -6787,41 +2530,6 @@ "src/tachyon/tabs/diagnostic/checks/runSingBoxCheck.ts:67" ] }, - { - "call": "Singapore (sg)", - "key": "Singapore (sg)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9248" - ] - }, - { - "call": "Skip loopback & local entries (127.0.0.1, ::1, 0.0.0.0, localhost)", - "key": "Skip loopback & local entries (127.0.0.1, ::1, 0.0.0.0, localhost)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7701" - ] - }, - { - "call": "Skip TLS certificate verification (not recommended)", - "key": "Skip TLS certificate verification (not recommended)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8506" - ] - }, - { - "call": "Skipped comments/invalid:", - "key": "Skipped comments/invalid:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7630" - ] - }, - { - "call": "Skipped loopback:", - "key": "Skipped loopback:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7629" - ] - }, { "call": "Smart Detect", "key": "Smart Detect", @@ -6836,87 +2544,14 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:237" ] }, - { - "call": "Snell Version", - "key": "Snell Version", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8533" - ] - }, - { - "call": "Some fixes failed", - "key": "Some fixes failed", - "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1072" - ] - }, - { - "call": "Sort Alphabetically", - "key": "Sort Alphabetically", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7801" - ] - }, - { - "call": "Sort by latency", - "key": "Sort by latency", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9048" - ] - }, - { - "call": "Sorts servers in this section by lowest latency in the dashboard.", - "key": "Sorts servers in this section by lowest latency in the dashboard.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9049" - ] - }, { "call": "Source", "key": "Source", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10081", "src/tachyon/tabs/monitoring/initController.ts:883", "src/tachyon/tabs/monitoring/initController.ts:933" ] }, - { - "call": "Source Devices", - "key": "Source Devices", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10207" - ] - }, - { - "call": "Source Network Interface", - "key": "Source Network Interface", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:720" - ] - }, - { - "call": "Specify a file path", - "key": "Specify a file path", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1929" - ] - }, - { - "call": "Specify different files", - "key": "Specify different files", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1940", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1952" - ] - }, - { - "call": "SSH", - "key": "SSH", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9532", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9551" - ] - }, { "call": "Standalone ByeDPI autostart is enabled", "key": "Standalone ByeDPI autostart is enabled", @@ -6994,25 +2629,11 @@ "src/tachyon/tabs/diagnostic/checks/runZapret2Check.ts:124" ] }, - { - "call": "Start", - "key": "Start", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:285" - ] - }, - { - "call": "Start bot", - "key": "Start bot", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1555" - ] - }, { "call": "Start Tachyon", "key": "Start Tachyon", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:78" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:80" ] }, { @@ -7022,14 +2643,6 @@ "src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:954" ] }, - { - "call": "Starting…", - "key": "Starting…", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:334", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1602" - ] - }, { "call": "Status", "key": "Status", @@ -7038,89 +2651,22 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:633" ] }, - { - "call": "Stop", - "key": "Stop", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:292" - ] - }, - { - "call": "Stop bot", - "key": "Stop bot", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1562" - ] - }, - { - "call": "Stop checking when URLTest group is not used. Use sing-box duration format like 1d, 12h or 30m.", - "key": "Stop checking when URLTest group is not used. Use sing-box duration format like 1d, 12h or 30m.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2676" - ] - }, { "call": "Stop Tachyon", "key": "Stop Tachyon", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:68" + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:70" ] }, { "call": "Stopped", "key": "Stopped", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:307", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1579", "src/tachyon/methods/custom/getDashboardSections.ts:1571", "src/tachyon/tabs/dashboard/partials/renderSections.ts:585", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147" ] }, - { - "call": "Stopping…", - "key": "Stopping…", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:348", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1616" - ] - }, - { - "call": "Store auto-detected domains in /etc instead of /tmp to survive reboots.", - "key": "Store auto-detected domains in /etc instead of /tmp to survive reboots.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1421" - ] - }, - { - "call": "Strict ECH + DoQ DNS Enforcer", - "key": "Strict ECH + DoQ DNS Enforcer", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1214" - ] - }, - { - "call": "STUN (P2P Calls)", - "key": "STUN (P2P Calls)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9528", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9547" - ] - }, - { - "call": "Subnets from the list will be extracted and added to nftables", - "key": "Subnets from the list will be extracted and added to nftables", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4077" - ] - }, - { - "call": "Subscription auto update", - "key": "Subscription auto update", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2367" - ] - }, { "call": "Subscription info:", "key": "Subscription info:", @@ -7136,27 +2682,6 @@ "src/tachyon/methods/shell/index.ts:766" ] }, - { - "call": "Subscription update interval", - "key": "Subscription update interval", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2376" - ] - }, - { - "call": "Subscription URL", - "key": "Subscription URL", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8770" - ] - }, - { - "call": "Subscription URL settings", - "key": "Subscription URL settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3764" - ] - }, { "call": "Subscriptions updated", "key": "Subscriptions updated", @@ -7164,27 +2689,6 @@ "src/tachyon/tabs/dashboard/initController.ts:335" ] }, - { - "call": "Success", - "key": "Success", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8144" - ] - }, - { - "call": "Successfully imported %d DNS record(s)", - "key": "Successfully imported %d DNS record(s)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7688" - ] - }, - { - "call": "Sweden (se)", - "key": "Sweden (se)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9244" - ] - }, { "call": "System info", "key": "System info", @@ -7213,34 +2717,6 @@ "src/tachyon/services/core.service.ts:52" ] }, - { - "call": "Tachyon manages ciadpi pid files itself, so pidfile options are not allowed here.", - "key": "Tachyon manages ciadpi pid files itself, so pidfile options are not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6504" - ] - }, - { - "call": "Tachyon manages the ciadpi process lifecycle itself, so daemon mode is not allowed here.", - "key": "Tachyon manages the ciadpi process lifecycle itself, so daemon mode is not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6501" - ] - }, - { - "call": "Tachyon manages the nfqws process lifecycle itself, so daemon mode is not allowed here.", - "key": "Tachyon manages the nfqws process lifecycle itself, so daemon mode is not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5648" - ] - }, - { - "call": "Tachyon manages the nfqws2 process lifecycle itself, so daemon mode is not allowed here.", - "key": "Tachyon manages the nfqws2 process lifecycle itself, so daemon mode is not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6099" - ] - }, { "call": "Tachyon service is stopped. Start the service to display connections.", "key": "Tachyon service is stopped. Start the service to display connections.", @@ -7255,20 +2731,6 @@ "src/tachyon/tabs/dashboard/render.ts:17" ] }, - { - "call": "Tachyon Settings", - "key": "Tachyon Settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:366" - ] - }, - { - "call": "Tachyon will not modify your DHCP configuration", - "key": "Tachyon will not modify your DHCP configuration", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1126" - ] - }, { "call": "Tachyon-managed ciadpi runtime has restarted", "key": "Tachyon-managed ciadpi runtime has restarted", @@ -7339,20 +2801,6 @@ "src/tachyon/tabs/diagnostic/checks/runZapret2Check.ts:89" ] }, - { - "call": "Tailscale auth key", - "key": "Tailscale auth key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3080" - ] - }, - { - "call": "Tailscale control URL", - "key": "Tailscale control URL", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3089" - ] - }, { "call": "Tailscale endpoint", "key": "Tailscale endpoint", @@ -7361,31 +2809,10 @@ ] }, { - "call": "Tailscale hostname", - "key": "Tailscale hostname", + "call": "TCP", + "key": "TCP", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3097" - ] - }, - { - "call": "TCP (ms)", - "key": "TCP (ms)", - "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:65" - ] - }, - { - "call": "Telegram Bot", - "key": "Telegram Bot", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:473" - ] - }, - { - "call": "Telegram Bot Token", - "key": "Telegram Bot Token", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1674" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:371" ] }, { @@ -7397,48 +2824,6 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:860" ] }, - { - "call": "Test only selected servers.", - "key": "Test only selected servers.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2775" - ] - }, - { - "call": "Test only servers with one of the selected protocols.", - "key": "Test only servers with one of the selected protocols.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2735" - ] - }, - { - "call": "Test only servers with one of the selected security types.", - "key": "Test only servers with one of the selected security types.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2741" - ] - }, - { - "call": "Test only servers with one of the selected transports.", - "key": "Test only servers with one of the selected transports.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2738" - ] - }, - { - "call": "Test servers only from the specified countries.", - "key": "Test servers only from the specified countries.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2767" - ] - }, - { - "call": "Test servers whose names match the expression.", - "key": "Test servers whose names match the expression.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2783" - ] - }, { "call": "Testing URL", "key": "Testing URL", @@ -7447,26 +2832,10 @@ ] }, { - "call": "The desync fwmark is managed by Tachyon for loop prevention and must not be overridden here.", - "key": "The desync fwmark is managed by Tachyon for loop prevention and must not be overridden here.", + "call": "Testing...", + "key": "Testing...", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5645", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6090" - ] - }, - { - "call": "The NFQUEUE number is assigned by Tachyon for each rule and must not be overridden here.", - "key": "The NFQUEUE number is assigned by Tachyon for each rule and must not be overridden here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5642", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6087" - ] - }, - { - "call": "The rule applies to the domain and all its subdomains. Use full:, keyword:, or regex: prefixes for exact match, keyword match, or regular expression.", - "key": "The rule applies to the domain and all its subdomains. Use full:, keyword:, or regex: prefixes for exact match, keyword match, or regular expression.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9272" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:685" ] }, { @@ -7491,66 +2860,10 @@ ] }, { - "call": "This field is required", - "key": "This field is required", + "call": "Thinking...", + "key": "Thinking...", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10265", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1828", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1833", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1923", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2085", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2885" - ] - }, - { - "call": "This field must start a working ciadpi strategy; help/version options exit immediately and are not allowed here.", - "key": "This field must start a working ciadpi strategy; help/version options exit immediately and are not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6507" - ] - }, - { - "call": "This field must start a working nfqws strategy; --dry-run exits immediately and is not allowed here.", - "key": "This field must start a working nfqws strategy; --dry-run exits immediately and is not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5651" - ] - }, - { - "call": "This field must start a working nfqws strategy; --version exits immediately and is not allowed here.", - "key": "This field must start a working nfqws strategy; --version exits immediately and is not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5654" - ] - }, - { - "call": "This field must start a working nfqws2 strategy; --dry-run exits immediately and is not allowed here.", - "key": "This field must start a working nfqws2 strategy; --dry-run exits immediately and is not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6102" - ] - }, - { - "call": "This field must start a working nfqws2 strategy; --version exits immediately and is not allowed here.", - "key": "This field must start a working nfqws2 strategy; --version exits immediately and is not allowed here.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6105" - ] - }, - { - "call": "This flag does not accept a value.", - "key": "This flag does not accept a value.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5823", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6297" - ] - }, - { - "call": "This option requires a value.", - "key": "This option requires a value.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5854", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6328" + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:91" ] }, { @@ -7561,20 +2874,6 @@ "src/tachyon/tabs/monitoring/initController.ts:930" ] }, - { - "call": "Time in seconds for DNS record caching (default: 60)", - "key": "Time in seconds for DNS record caching (default: 60)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:659" - ] - }, - { - "call": "Time skew tolerance", - "key": "Time skew tolerance", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3054" - ] - }, { "call": "tiny", "key": "tiny", @@ -7583,75 +2882,24 @@ ] }, { - "call": "TLS (ms)", - "key": "TLS (ms)", + "call": "TLS", + "key": "TLS", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:66" - ] - }, - { - "call": "TLS / HTTPS", - "key": "TLS / HTTPS", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9531", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9550" - ] - }, - { - "call": "TLS Auth/Crypt Key", - "key": "TLS Auth/Crypt Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8733" - ] - }, - { - "call": "TLS SNI", - "key": "TLS SNI", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8494" - ] - }, - { - "call": "Token is required when the bot is enabled", - "key": "Token is required when the bot is enabled", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1683" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:379" ] }, { "call": "Tolerance", "key": "Tolerance", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2648", "src/tachyon/tabs/dashboard/initController.ts:1109" ] }, { - "call": "Top level has the highest priority; lower levels are used as fallback", - "key": "Top level has the highest priority; lower levels are used as fallback", + "call": "Total Targets", + "key": "Total Targets", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3194" - ] - }, - { - "call": "Total lines:", - "key": "Total lines:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7627" - ] - }, - { - "call": "Trace", - "key": "Trace", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10012" - ] - }, - { - "call": "Tracing routing rules...", - "key": "Tracing routing rules...", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10049" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:225" ] }, { @@ -7662,27 +2910,6 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:127" ] }, - { - "call": "Traffic for this level goes directly.", - "key": "Traffic for this level goes directly.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2905" - ] - }, - { - "call": "Traffic from these IP addresses will never be routed through this section, even if other conditions match.", - "key": "Traffic from these IP addresses will never be routed through this section, even if other conditions match.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9498" - ] - }, - { - "call": "Traffic of specified protocols (e.g. BitTorrent, QUIC, STUN) will bypass this section.", - "key": "Traffic of specified protocols (e.g. BitTorrent, QUIC, STUN) will bypass this section.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9524" - ] - }, { "call": "Traffic Total", "key": "Traffic Total", @@ -7690,57 +2917,6 @@ "src/tachyon/tabs/dashboard/initController.ts:1640" ] }, - { - "call": "Traffic type filter", - "key": "Traffic type filter", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9542" - ] - }, - { - "call": "Traffic will go through the default route (Direct/Default).", - "key": "Traffic will go through the default route (Direct/Default).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10114" - ] - }, - { - "call": "Transparent proxy mode is incompatible with action=byedpi because Tachyon connects to ciadpi through SOCKS.", - "key": "Transparent proxy mode is incompatible with action=byedpi because Tachyon connects to ciadpi through SOCKS.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6498" - ] - }, - { - "call": "Transport", - "key": "Transport", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2036", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8557", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2763" - ] - }, - { - "call": "Transport host", - "key": "Transport host", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2787" - ] - }, - { - "call": "Transport path", - "key": "Transport path", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2771" - ] - }, - { - "call": "Transport path must start with /", - "key": "Transport path must start with /", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2006" - ] - }, { "call": "Troubleshooting", "key": "Troubleshooting", @@ -7748,132 +2924,21 @@ "src/tachyon/tabs/diagnostic/partials/renderWikiDisclaimer.ts:25" ] }, - { - "call": "Try compatible User-Agent profiles automatically when downloading this subscription", - "key": "Try compatible User-Agent profiles automatically when downloading this subscription", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2425" - ] - }, - { - "call": "TTL must be a positive number", - "key": "TTL must be a positive number", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:670" - ] - }, - { - "call": "TTL value cannot be empty", - "key": "TTL value cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:665" - ] - }, - { - "call": "Turkey (tr)", - "key": "Turkey (tr)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9245" - ] - }, { "call": "Type", "key": "Type", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1637", "src/tachyon/tabs/monitoring/initController.ts:868", "src/tachyon/tabs/monitoring/initController.ts:928" ] }, - { - "call": "UDP (Unprotected DNS)", - "key": "UDP (Unprotected DNS)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:522" - ] - }, - { - "call": "Ukraine (ua)", - "key": "Ukraine (ua)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9251" - ] - }, - { - "call": "Unable to validate the ByeDPI strategy through the backend parser.", - "key": "Unable to validate the ByeDPI strategy through the backend parser.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6422" - ] - }, - { - "call": "Unable to validate the NFQWS strategy through the backend parser.", - "key": "Unable to validate the NFQWS strategy through the backend parser.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5565", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6900" - ] - }, - { - "call": "Unable to validate the NFQWS2 strategy through the backend parser.", - "key": "Unable to validate the NFQWS2 strategy through the backend parser.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6010", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6909" - ] - }, { "call": "Unavailability timeout", "key": "Unavailability timeout", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3111", "src/tachyon/tabs/dashboard/initController.ts:1233" ] }, - { - "call": "Underload Packet Magic Header (H1)", - "key": "Underload Packet Magic Header (H1)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8405" - ] - }, - { - "call": "Underload Packet Magic Header (H2)", - "key": "Underload Packet Magic Header (H2)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8406" - ] - }, - { - "call": "Underload Packet Magic Header (H3)", - "key": "Underload Packet Magic Header (H3)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8407" - ] - }, - { - "call": "Underload Packet Magic Header (H4)", - "key": "Underload Packet Magic Header (H4)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8408" - ] - }, - { - "call": "Unexpected ByeDPI strategy argument: %s", - "key": "Unexpected ByeDPI strategy argument: %s", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6639", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6688" - ] - }, - { - "call": "Unexpected standalone token. Use explicit flags such as --name or --name=value.", - "key": "Unexpected standalone token. Use explicit flags such as --name or --name=value.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5803", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6277" - ] - }, { "call": "Unexpected Tachyon-managed ciadpi runtime is running", "key": "Unexpected Tachyon-managed ciadpi runtime is running", @@ -7895,27 +2960,6 @@ "src/tachyon/tabs/diagnostic/checks/runZapret2Check.ts:92" ] }, - { - "call": "unique UCI identifier", - "key": "unique UCI identifier", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:54" - ] - }, - { - "call": "United Kingdom (gb)", - "key": "United Kingdom (gb)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9241" - ] - }, - { - "call": "United States (us)", - "key": "United States (us)", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9238" - ] - }, { "call": "unknown", "key": "unknown", @@ -7938,50 +2982,18 @@ "call": "Unknown", "key": "Unknown", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:328", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1596", "src/tachyon/methods/custom/getDashboardSections.ts:1573" ] }, - { - "call": "Unknown ByeDPI option: %s", - "key": "Unknown ByeDPI option: %s", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6608", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6630", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6681" - ] - }, - { - "call": "Unknown country", - "key": "Unknown country", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:616" - ] - }, { "call": "Unknown error", "key": "Unknown error", "places": [ "src/tachyon/api.ts:40", - "src/tachyon/tabs/diagnostic/initController.ts:720", - "src/tachyon/tabs/diagnostic/initController.ts:757", - "src/tachyon/tabs/diagnostic/initController.ts:878", - "src/tachyon/tabs/diagnostic/initController.ts:1216" - ] - }, - { - "call": "Unknown NFQWS flag.", - "key": "Unknown NFQWS flag.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5814" - ] - }, - { - "call": "Unknown NFQWS2 flag.", - "key": "Unknown NFQWS2 flag.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6288" + "src/tachyon/tabs/diagnostic/initController.ts:721", + "src/tachyon/tabs/diagnostic/initController.ts:758", + "src/tachyon/tabs/diagnostic/initController.ts:843", + "src/tachyon/tabs/diagnostic/initController.ts:1159" ] }, { @@ -7998,13 +3010,6 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:675" ] }, - { - "call": "Unsupported security mode for this protocol", - "key": "Unsupported security mode for this protocol", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2119" - ] - }, { "call": "Update", "key": "Update", @@ -8042,27 +3047,6 @@ "src/tachyon/tabs/dashboard/partials/renderSections.ts:232" ] }, - { - "call": "Update this subscription automatically", - "key": "Update this subscription automatically", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2368" - ] - }, - { - "call": "Updated/duplicates:", - "key": "Updated/duplicates:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7632" - ] - }, - { - "call": "Updates & Downloads", - "key": "Updates & Downloads", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:506" - ] - }, { "call": "Uplink", "key": "Uplink", @@ -8093,41 +3077,6 @@ "src/validators/validateUrl.ts:18" ] }, - { - "call": "URL to test through the proxy (default: Cloudflare 204).", - "key": "URL to test through the proxy (default: Cloudflare 204).", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1361" - ] - }, - { - "call": "URL used to check whether a server is alive", - "key": "URL used to check whether a server is alive", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3087" - ] - }, - { - "call": "URL used to test server latency", - "key": "URL used to test server latency", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2663" - ] - }, - { - "call": "URLs of remote hosts files to download and apply. Supports standard hosts format: IP domain.", - "key": "URLs of remote hosts files to download and apply. Supports standard hosts format: IP domain.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7839" - ] - }, - { - "call": "URLTest", - "key": "URLTest", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8886" - ] - }, { "call": "URLTest details", "key": "URLTest details", @@ -8144,141 +3093,6 @@ "src/tachyon/tabs/dashboard/initController.ts:1095" ] }, - { - "call": "URLTest settings", - "key": "URLTest settings", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3803", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3804" - ] - }, - { - "call": "Use 3-tier check intervals: fast (15s), normal (120s), slow (300s) instead of a single interval.", - "key": "Use 3-tier check intervals: fast (15s), normal (120s), slow (300s) instead of a single interval.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1400" - ] - }, - { - "call": "Use 32 hex characters", - "key": "Use 32 hex characters", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2103" - ] - }, - { - "call": "Use a domain name or IP address", - "key": "Use a domain name or IP address", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1893", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1899", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2015" - ] - }, - { - "call": "Use a duration like 30s, 5m, or 1h30m", - "key": "Use a duration like 30s, 5m, or 1h30m", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1994" - ] - }, - { - "call": "Use a non-negative integer", - "key": "Use a non-negative integer", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2000", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2887" - ] - }, - { - "call": "Use a non-zero secret", - "key": "Use a non-zero secret", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2106" - ] - }, - { - "call": "Use an HTTP or HTTPS URL", - "key": "Use an HTTP or HTTPS URL", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1962", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1964" - ] - }, - { - "call": "Use an IP address", - "key": "Use an IP address", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1916" - ] - }, - { - "call": "Use an IP listen address", - "key": "Use an IP listen address", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1909" - ] - }, - { - "call": "Use another section as an intermediate hop to connect to servers in this section. Does not apply to network interfaces or JSON outbounds.", - "key": "Use another section as an intermediate hop to connect to servers in this section. Does not apply to network interfaces or JSON outbounds.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8985" - ] - }, - { - "call": "Use CIDR prefixes like 192.168.1.0/24 or 2001:db8::/32", - "key": "Use CIDR prefixes like 192.168.1.0/24 or 2001:db8::/32", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2063" - ] - }, - { - "call": "Use CIDR prefixes or IP addresses like 192.168.1.0/24, 192.168.1.10, or 2001:db8::1", - "key": "Use CIDR prefixes or IP addresses like 192.168.1.0/24, 192.168.1.10, or 2001:db8::1", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2077" - ] - }, - { - "call": "Use letters, digits, dots, underscores, or hyphens", - "key": "Use letters, digits, dots, underscores, or hyphens", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2021" - ] - }, - { - "call": "Use sing-box duration format like 10s, 1m or 2m30s", - "key": "Use sing-box duration format like 10s, 1m or 2m30s", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:252" - ] - }, - { - "call": "Use sing-box duration format like 1d, 12h or 30m", - "key": "Use sing-box duration format like 1d, 12h or 30m", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2377", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2637", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3160", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4722", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4729", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4736", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:969", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:991", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:998", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1029", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1057" - ] - }, - { - "call": "Use sing-box duration format like 1d, 12h or 6h", - "key": "Use sing-box duration format like 1d, 12h or 6h", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7986", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7997" - ] - }, { "call": "Used by", "key": "Used by", @@ -8286,34 +3100,10 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:25" ] }, - { - "call": "User-Agent", - "key": "User-Agent", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2435" - ] - }, - { - "call": "Username", - "key": "Username", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8565", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2846" - ] - }, - { - "call": "Username cannot be empty", - "key": "Username cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9142" - ] - }, { "call": "Valid", "key": "Valid", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5338", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5351", "src/validators/validateDns.ts:25", "src/validators/validateDns.ts:29", "src/validators/validateDomain.ts:57", @@ -8332,76 +3122,19 @@ "src/validators/validateVmessUrl.ts:66" ] }, - { - "call": "Validates sing-box config before restart to prevent boot loops on broken configs.", - "key": "Validates sing-box config before restart to prevent boot loops on broken configs.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1407" - ] - }, - { - "call": "Validation errors:", - "key": "Validation errors:", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4791" - ] - }, - { - "call": "Value cannot be empty", - "key": "Value cannot be empty", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5328" - ] - }, - { - "call": "Value must not contain control characters", - "key": "Value must not contain control characters", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10268", - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1837" - ] - }, { "call": "Verdict", "key": "Verdict", "places": [ - "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:68" - ] - }, - { - "call": "Via country.is", - "key": "Via country.is", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1977" + "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:395" ] }, { "call": "View logs", "key": "View logs", "places": [ - "src/tachyon/tabs/diagnostic/initController.ts:1252", - "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:145" - ] - }, - { - "call": "Visible name of this section", - "key": "Visible name of this section", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7254" - ] - }, - { - "call": "VLESS flow", - "key": "VLESS flow", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2890" - ] - }, - { - "call": "vless://, vmess://, ss://, trojan://, socks4/5://, hy2/hysteria2:// links", - "key": "vless://, vmess://, ss://, trojan://, socks4/5://, hy2/hysteria2:// links", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8746" + "src/tachyon/tabs/diagnostic/initController.ts:817", + "src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:157" ] }, { @@ -8418,34 +3151,6 @@ "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:198" ] }, - { - "call": "WARP Access Token", - "key": "WARP Access Token", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8445" - ] - }, - { - "call": "WARP Account ID", - "key": "WARP Account ID", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8433" - ] - }, - { - "call": "WARP Configuration generated and loaded successfully!", - "key": "WARP Configuration generated and loaded successfully!", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8144" - ] - }, - { - "call": "WARP Private Key", - "key": "WARP Private Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8421" - ] - }, { "call": "Watchdog", "key": "Watchdog", @@ -8454,59 +3159,10 @@ ] }, { - "call": "Watchdog Status", - "key": "Watchdog Status", + "call": "Why Discord fails?", + "key": "Why Discord fails?", "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1331" - ] - }, - { - "call": "WebRTC Leak Protection", - "key": "WebRTC Leak Protection", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1204" - ] - }, - { - "call": "What Tachyon should do when this section matches", - "key": "What Tachyon should do when this section matches", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7267" - ] - }, - { - "call": "When switching to another level, test every server and select the fastest instead of the first working one.", - "key": "When switching to another level, test every server and select the fastest instead of the first working one.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3138" - ] - }, - { - "call": "WireGuard private key from your Cloudflare account", - "key": "WireGuard private key from your Cloudflare account", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8617" - ] - }, - { - "call": "WireGuard private key from your Cloudflare WARP account", - "key": "WireGuard private key from your Cloudflare WARP account", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8422" - ] - }, - { - "call": "XHTTP mode", - "key": "XHTTP mode", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2800" - ] - }, - { - "call": "YACD Secret Key", - "key": "YACD Secret Key", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:895" + "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:156" ] }, { @@ -8516,20 +3172,6 @@ "src/tachyon/tabs/dashboard/initController.ts:812" ] }, - { - "call": "You can select Output Network Interface, by default autodetect", - "key": "You can select Output Network Interface, by default autodetect", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:759" - ] - }, - { - "call": "Zapret hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS strategies.", - "key": "Zapret hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS strategies.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5639" - ] - }, { "call": "Zapret package is installed", "key": "Zapret package is installed", @@ -8572,13 +3214,6 @@ "src/tachyon/tabs/diagnostic/checks/runZapretCheck.ts:104" ] }, - { - "call": "Zapret2 hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS2 strategies.", - "key": "Zapret2 hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS2 strategies.", - "places": [ - "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6084" - ] - }, { "call": "Zapret2 package is installed", "key": "Zapret2 package is installed", diff --git a/fe-app-tachyon/locales/tachyon.pot b/fe-app-tachyon/locales/tachyon.pot index 6eed4a3a..ef056583 100644 --- a/fe-app-tachyon/locales/tachyon.pot +++ b/fe-app-tachyon/locales/tachyon.pot @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: TACHYON\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-12 07:20+0300\n" -"PO-Revision-Date: 2026-08-12 07:20+0300\n" +"POT-Creation-Date: 2026-08-12 09:15+0300\n" +"PO-Revision-Date: 2026-08-12 09:15+0300\n" "Last-Translator: Dushnilin \n" "Language-Team: LANGUAGE \n" "Language: \n" @@ -16,42 +16,6 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2062 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2439 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2818 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2833 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3031 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3046 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3282 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3434 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3444 -msgid "-- Select --" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10205 -msgid ".lst Lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1285 -msgid "(provider default)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8865 -msgid "+ Add JSON outbound" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3198 -msgid "+ Add level" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8951 -msgid "+ Add priority" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8892 -msgid "+ Add URLTest" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:467 msgid "⏹ Stop" msgstr "" @@ -64,14 +28,6 @@ msgstr "" msgid "⚙ Advanced Settings" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:592 -msgid "⚠️ If all Bootstrap DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:583 -msgid "⚠️ If all Main DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss." -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1670 #: src/tachyon/tabs/dashboard/initController.ts:1679 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:457 @@ -88,19 +44,6 @@ msgstr "" msgid "🔑 Generate" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:444 -msgid "Accept external proxy connections and route them with sing-box." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3132 -msgid "Accept routes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7236 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7266 -msgid "Action" -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:713 #: src/tachyon/tabs/monitoring/render.ts:20 msgid "Active" @@ -123,145 +66,64 @@ msgstr "" msgid "Active Main DNS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:433 -msgid "Add a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:450 -msgid "Add a server inbound" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1843 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:122 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:166 -msgid "Add at least one DNS server" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2529 -msgid "Add prefix to nodes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9429 -msgid "Add URLs or local paths to .lst lists containing domains and subnets." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9455 -msgid "Add URLs or local paths to .lst lists containing domains. IP entries are ignored." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9404 -msgid "Add URLs or local paths to .srs / .json lists. Only domain rules are supported." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9375 -msgid "Add URLs or local paths to .srs / .json lists. Subnets are ignored by default." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3456 -msgid "Add URLTest / Priority group" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:130 +msgid "Active Sections" msgstr "" #: src/tachyon/tabs/diagnostic/checks/runNftCheck.ts:106 msgid "Additional marking rules found" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2748 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2958 -msgid "Additionally exclude servers by protocol, transport, and security. Exclude only servers matching the specified parameters." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2731 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2940 -msgid "Additionally filter servers by protocol, transport, and security. Add only servers matching the specified parameters." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3356 -msgid "Additionally hide servers by protocol, transport, and security. Hide servers matching the specified parameters." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3336 -msgid "Additionally show servers by protocol, transport, and security. Add only servers matching the specified parameters." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1652 -msgid "Address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1691 -msgid "Administrator Chat IDs" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:579 msgid "Advanced self-healing features. Requires Watchdog to be enabled." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:508 -msgid "Advanced System" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3115 -msgid "Advertise exit node" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3125 -msgid "Advertise routes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8603 -msgid "AEAD Method" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:507 -msgid "AI & Watchdog" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:684 msgid "AI Agent REST API (12 Endpoints)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1237 -msgid "AI Agent REST API Bearer Token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1304 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:893 msgid "AI API Key" msgstr "" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:220 +msgid "AI Chat & Tachyon Assistant" +msgstr "" + +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:138 +msgid "AI Chat Assistant" +msgstr "" + #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:740 msgid "AI Doctor (ChatGPT / DeepSeek API)" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:855 -#: src/tachyon/tabs/diagnostic/initController.ts:1211 +#: src/tachyon/tabs/diagnostic/initController.ts:1154 msgid "AI Doctor Diagnosis" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:827 -msgid "AI Doctor Diagnostic Scan in Progress..." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:878 -#: src/tachyon/tabs/diagnostic/initController.ts:1217 -#: src/tachyon/tabs/diagnostic/initController.ts:1226 +#: src/tachyon/tabs/diagnostic/initController.ts:843 +#: src/tachyon/tabs/diagnostic/initController.ts:1160 +#: src/tachyon/tabs/diagnostic/initController.ts:1168 msgid "AI Doctor failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1291 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:860 msgid "AI Doctor Language" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1278 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:836 msgid "AI Model" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1262 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:766 msgid "AI Provider" msgstr "" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:138 +msgid "AI service error" +msgstr "" + #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:574 msgid "AI Watchdog" msgstr "" @@ -272,27 +134,12 @@ msgstr "" #: src/tachyon/tabs/monitoring/initController.ts:672 #: src/tachyon/tabs/monitoring/render.ts:40 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:318 msgid "All" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1959 -msgid "All except selected" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1068 -msgid "All fixes applied successfully" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1969 -msgid "All remaining except selected" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1967 -msgid "All remaining servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2914 -msgid "All remaining servers means every server not already assigned to a higher-priority level." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:140 +msgid "All Profiles" msgstr "" #: src/tachyon/tabs/monitoring/initController.ts:635 @@ -300,191 +147,42 @@ msgstr "" msgid "All Routes" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1958 -msgid "All servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9487 -msgid "All traffic from these IP addresses will be routed through the section unconditionally, ignoring all other conditions." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8505 -msgid "Allow Insecure TLS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5323 -msgid "Allowed domain prefixes are full:, keyword:, and regex:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:883 -msgid "Allows access to YACD from the WAN. Make sure to open the appropriate port in your firewall." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2708 -msgid "Allows limiting the list of servers for URLTest" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1251 -msgid "Allows Tachyon to send diagnostic snapshots to ChatGPT or DeepSeek API for intelligent root-cause analysis and auto-repair recommendations." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2644 -msgid "ALPN" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2878 -msgid "Alter ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8292 -msgid "AmneziaWG config loaded successfully!" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8005 -msgid "AmneziaWG Generator" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:165 -msgid "An error occurred while checking services." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:809 -msgid "Analyzing system log (logread & errors)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1305 -msgid "API Key for OpenAI (sk-...) or DeepSeek (optional for Ollama / LM Studio)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9543 -msgid "Apply rules of this section only to selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9478 -msgid "Apply section rules only to the specified local IP addresses" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1057 -msgid "Applying all fixes..." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1024 +#: src/tachyon/tabs/diagnostic/initController.ts:995 msgid "Applying fix" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1702 -msgid "At least one Admin Chat ID is required" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5354 -msgid "At least one valid domain must be specified." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5436 -msgid "At least one valid IP or subnet must be specified." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8686 -msgid "Auth Digest" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:60 +msgid "Ask Tachyon AI Assistant a question..." msgstr "" #: src/partials/modal/renderModal.ts:286 msgid "Auto refresh" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3035 -msgid "Auto update" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1494 -msgid "Auto-detected domains" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9300 -msgid "Auto-detected Domains" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1454 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1053 msgid "Auto-detects blocked domains from logs and adds them to the first section where they work via proxy." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2455 -msgid "Auto-generate HWID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7978 -msgid "Auto-update Hosts Lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1018 -msgid "Automatic component update checks" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2424 -msgid "Automatic User-Agent selection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2530 -msgid "Automatically add text to the name of each server from this subscription for convenient filtering." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1019 -msgid "Automatically check installed components for new versions" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8006 -msgid "Automatically generate a Cloudflare WARP account and configure all AmneziaWG settings." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1428 -msgid "Automatically increase check intervals when healthy (to 5 min) and decrease on problems (to 120s)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3148 #: src/tachyon/tabs/dashboard/initController.ts:1243 msgid "Automatically select the fastest node in the current level" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7979 -msgid "Automatically update remote hosts lists on schedule" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:52 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:54 msgid "Available actions" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5569 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6014 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6426 -msgid "Backend validation failed: %s" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:270 +msgid "Avg Latency" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:694 msgid "Bearer Auth Token" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9249 -msgid "Belarus (by)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9526 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9545 -msgid "BitTorrent / P2P" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:57 msgid "Bootstrap DNS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:546 -msgid "Bootstrap DNS Servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1653 -msgid "Bot Status" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:51 #: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:79 msgid "Browser FakeIP check could not be completed" @@ -498,37 +196,10 @@ msgstr "" msgid "Browser is using FakeIP correctly" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1351 +#: src/tachyon/tabs/diagnostic/initController.ts:1258 msgid "Bug report downloaded" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9321 -msgid "Built-in rule sets" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1976 -msgid "By flag emoji from name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6495 -msgid "ByeDPI listen address and port are assigned by Tachyon and must not be set in the strategy." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6672 -msgid "ByeDPI option does not accept a compact value: %s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6601 -msgid "ByeDPI option does not accept a value: %s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6593 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6619 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6653 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6662 -msgid "ByeDPI option requires a value: %s" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:71 msgid "ByeDPI package is installed" msgstr "" @@ -553,38 +224,6 @@ msgstr "" msgid "ByeDPI sing-box outbound is not configured" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7435 -msgid "ByeDPI Strategy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6698 -msgid "ByeDPI strategy cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:932 -msgid "Bypasses UDP traffic for selected game consoles (PS5/Xbox) to achieve NAT Type 1 / 2 (Full Cone NAT) for P2P matchmaking, while keeping TCP (PSN/Auth) routed through the proxy." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8697 -msgid "CA Certificate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1006 -msgid "Cache all built-in lists and databases even if they are not currently selected in any section. Recommended if you have plenty of storage space or USB drive." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1149 -msgid "Cache File Path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1163 -msgid "Cache file path cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7712 -msgid "Cancel" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:26 #: src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:27 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:172 @@ -596,24 +235,12 @@ msgstr "" msgid "Cannot receive checks result" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2240 -msgid "Cannot save server" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:760 +msgid "Check Again" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3584 -msgid "Cannot save settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8984 -msgid "Cascade connection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2654 -msgid "Certificate path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1597 -msgid "Certificate pin is unavailable. Apply or restart the server to generate the default certificate, then open this dialog again." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:661 +msgid "Check All" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderSections.ts:426 @@ -621,56 +248,44 @@ msgstr "" msgid "Check Connection" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:115 -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:131 -msgid "Check Custom Domain" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:549 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:646 +msgid "Check Custom" +msgstr "" + +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:543 +msgid "Check domain or IP (e.g. example.com)..." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2636 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3099 #: src/tachyon/tabs/dashboard/initController.ts:1230 msgid "Check interval" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:136 -msgid "Check Services" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:159 +msgid "Check Mode:" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3112 -msgid "Check timeout after which the server is considered dead" +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:148 +msgid "Check Services" msgstr "" #: src/tachyon/tabs/updates/initController.ts:795 msgid "Check update" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2662 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3086 #: src/tachyon/tabs/dashboard/initController.ts:1228 msgid "Check URL" msgstr "" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:155 +msgid "Check YouTube" +msgstr "" + #: src/tachyon/tabs/dashboard/initController.ts:1404 msgid "Checking Connection..." msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:808 -msgid "Checking nftables filtering tables" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:807 -msgid "Checking sing-box service & DNSmasq" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:806 -msgid "Checking WAN interfaces & network routing" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:810 -msgid "Checking Zapret & ByeDPI rules" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1639 +#: src/tachyon/tabs/diagnostic/initController.ts:1552 #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:14 #: src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:15 #: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:15 @@ -687,26 +302,22 @@ msgstr "" #: src/tachyon/tabs/dashboard/partials/renderSections.ts:420 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:775 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:849 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:665 msgid "Checking..." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:275 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1545 -msgid "Checking…" -msgstr "" - #: src/tachyon/tabs/diagnostic/helpers/getCheckTitle.ts:2 msgid "checks" msgstr "" -#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:26 #: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:10 +#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:26 msgid "Checks failed" msgstr "" -#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:13 #: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:23 #: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:43 +#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:13 msgid "Checks passed" msgstr "" @@ -714,67 +325,18 @@ msgstr "" msgid "Checks passed with manual DHCP" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9246 -msgid "China (cn)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7531 -msgid "Choose Hosts File..." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9215 -msgid "Choose whether to route traffic to all destinations except selected countries (Exclude) or only to selected countries (Include)." -msgstr "" - #: src/validators/validateSubnet.ts:35 msgid "CIDR must be between 0 and 32 for IPv4 or 0 and 128 for IPv6" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8675 -msgid "Cipher" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7815 -msgid "Clean Comments" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10013 -msgid "Clear" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8709 -msgid "Client Certificate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2752 -msgid "Client fingerprint" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8721 -msgid "Client Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1669 -msgid "Client link" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1577 -msgid "Client link is not available yet" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1610 -msgid "Client link QR code" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3651 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10221 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1717 #: src/partials/modal/renderModal.ts:263 #: src/tachyon/tabs/dashboard/initController.ts:1085 -#: src/tachyon/tabs/diagnostic/initController.ts:1199 #: src/tachyon/tabs/monitoring/initController.ts:884 #: src/tachyon/tabs/monitoring/initController.ts:934 -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:28 +#: src/tachyon/tabs/diagnostic/initController.ts:1144 +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:212 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:62 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:766 msgid "Close" msgstr "" @@ -793,66 +355,14 @@ msgstr "" msgid "Closed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8629 -msgid "Cloudflare account / device ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8641 -msgid "Cloudflare API access token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8434 -msgid "Cloudflare WARP account / device ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8446 -msgid "Cloudflare WARP API access token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1692 -msgid "Comma-separated list of Telegram user IDs authorized to control the bot." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10201 -msgid "Community Lists" -msgstr "" - #: src/tachyon/services/core.service.ts:43 msgid "Component update available" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1028 -msgid "Component update check interval" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:520 -msgid "Components" -msgstr "" - #: src/tachyon/helpers/singBoxVariant.ts:60 msgid "compressed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2987 -msgid "Concurrency" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7224 -msgid "Conditions" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1135 -msgid "Config File Path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:367 -msgid "Configuration for Tachyon service" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4749 -msgid "Configure User-Agent in the item settings" -msgstr "" - #: src/tachyon/methods/custom/getDashboardSections.ts:1569 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:583 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141 @@ -863,18 +373,10 @@ msgstr "" msgid "Connect ChatGPT, DeepSeek or local LLM to get automated diagnostic reports and intelligent root-cause analysis." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9022 -msgid "Connect through" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderSections.ts:782 msgid "Connected" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8745 -msgid "Connection URL" -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:998 msgid "Connections are unavailable" msgstr "" @@ -883,14 +385,11 @@ msgstr "" msgid "Connectivity probe failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1564 #: src/helpers/copyToClipboard.ts:10 msgid "Copied" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1693 #: src/partials/modal/renderModal.ts:258 -#: src/tachyon/tabs/diagnostic/initController.ts:1194 msgid "Copy" msgstr "" @@ -904,101 +403,26 @@ msgstr "" msgid "Could not compare FakeIP and control public IPs" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9252 -msgid "Country code (e.g. ru, us, de)" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1162 +#: src/tachyon/tabs/diagnostic/initController.ts:1110 msgid "Current Diagnosis" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9039 -msgid "Current section cannot be used as its own transit section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2416 -msgid "Current section cannot download its own subscription" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderWidget.ts:22 msgid "Currently unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1315 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:915 msgid "Custom API Endpoint URL" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2492 -msgid "Custom device headers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7720 -msgid "Custom DNS Records (Hosts)" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:113 -msgid "Custom domain (e.g. google.com)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1271 -msgid "Custom OpenAI-Compatible API (OpenRouter)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1316 -msgid "Custom OpenAI-compatible API endpoint URL (e.g. http://192.168.1.100:11434/v1/chat/completions)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8860 -msgid "Custom outbound configurations in JSON format" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:496 -msgid "Dashboard" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderSections.ts:44 msgid "Dashboard currently unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1818 -msgid "Default (auto)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1065 -msgid "Default address for checking server availability and latency. URLTest uses its own address." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:856 -msgid "Delay in milliseconds before reloading Tachyon after interface UP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:863 -msgid "Delay value cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1744 -msgid "Delete" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2718 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2927 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3323 -msgid "Detect server country" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1205 -msgid "Detects and drops STUN/TURN packets in nftables to prevent real IP leaks via WebRTC." -msgstr "" - #: src/validators/validateOutboundJson.ts:115 msgid "detour must be a non-empty string" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9477 -msgid "Device filter" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1126 msgid "Device IPs (one per line):" msgstr "" @@ -1007,10 +431,6 @@ msgstr "" msgid "Device IPs saved" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6961 -msgid "Device or IP" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1164 msgid "Devices listed here are always routed through the assigned section, regardless of global rules." msgstr "" @@ -1023,145 +443,18 @@ msgstr "" msgid "DHCP is managed manually" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:484 -msgid "Diagnostics" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2562 -msgid "Direct" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8464 -msgid "Direct (Default)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2904 -msgid "Direct connection" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:88 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:90 msgid "Disable autostart" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:907 -msgid "Disable QUIC" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:908 -msgid "Disable the QUIC protocol to improve compatibility or fix issues with video streaming" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6096 -msgid "Disabling interception is incompatible with action=zapret2 because Tachyon sends matched traffic through NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2618 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3075 -msgid "Display name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9529 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9548 -msgid "DNS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:601 -msgid "DNS Check Interval" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1372 -msgid "DNS Check Interval (s)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:630 -msgid "DNS Failures Before Switching" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:75 msgid "DNS on router" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1814 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:519 -msgid "DNS over HTTPS (DoH)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1816 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:521 -msgid "DNS over QUIC (DoQ)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1815 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:520 -msgid "DNS over TLS (DoT)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2585 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7294 -msgid "DNS protocol" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:516 -msgid "DNS Protocol Type" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2586 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7295 -msgid "DNS protocol used by the resolver" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7357 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:711 -msgid "DNS requests through section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:658 -msgid "DNS Rewrite TTL" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2595 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7308 -msgid "DNS server" -msgstr "" - #: src/validators/validateDns.ts:8 msgid "DNS server address cannot be empty" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2596 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7309 -msgid "DNS server used by the resolver" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:547 -msgid "DNS server used to obtain IP addresses for upstream DNS and proxies. If multiple servers are selected, a timeout switches to a backup." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:532 -msgid "DNS Servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:503 -msgid "DNS Settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:690 -msgid "DNS Strategy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:644 -msgid "DNS Successful Checks Before Recovery" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:702 -msgid "DNS through proxy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7345 -msgid "DNS through section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:680 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:479 msgid "DNS Turbo Cache" msgstr "" @@ -1170,46 +463,18 @@ msgstr "" msgid "DNS Turbo Cache saved" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:619 -msgid "DNS Unavailability Timeout" -msgstr "" - #: src/tachyon/tabs/diagnostic/partials/renderWikiDisclaimer.ts:26 msgid "Do not panic, everything can be fixed, just..." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2791 -msgid "Do not test servers from these countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2807 -msgid "Do not test servers whose names match the expression." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2752 -msgid "Do not test servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2758 -msgid "Do not test servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2755 -msgid "Do not test servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2799 -msgid "Do not test specified servers." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:720 -#: src/tachyon/tabs/diagnostic/initController.ts:758 -#: src/tachyon/tabs/diagnostic/initController.ts:766 +#: src/tachyon/tabs/diagnostic/initController.ts:721 +#: src/tachyon/tabs/diagnostic/initController.ts:759 +#: src/tachyon/tabs/diagnostic/initController.ts:767 msgid "Doctor failed" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:736 -#: src/tachyon/tabs/diagnostic/initController.ts:745 +#: src/tachyon/tabs/diagnostic/initController.ts:737 +#: src/tachyon/tabs/diagnostic/initController.ts:746 msgid "Doctor repair" msgstr "" @@ -1217,39 +482,6 @@ msgstr "" msgid "Does not resolve" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9428 -msgid "Domain and IP lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9454 -msgid "Domain lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2576 -msgid "Domain Resolver" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1466 -msgid "Domain test sections" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9271 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10202 -msgid "Domains" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9301 -msgid "Domains automatically detected by Smart Detect or added via Telegram bot. You can manually edit or remove them here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8292 -msgid "Done" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1125 -msgid "Dont Touch My DHCP!" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1630 #: src/tachyon/tabs/dashboard/initController.ts:1643 msgid "Downlink" @@ -1259,334 +491,41 @@ msgstr "" msgid "Download" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1104 -msgid "Download component packages via the selected section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1112 -msgid "Download components through" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1103 -msgid "Download components through a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1090 -msgid "Download lists through" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1081 -msgid "Download lists through a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1082 -msgid "Download remote lists and rule sets via the selected section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2390 -msgid "Download subscription through a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2391 -msgid "Download subscriptions via the selected section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2399 -msgid "Download through" -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:877 #: src/tachyon/tabs/monitoring/initController.ts:931 msgid "Downloaded" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:427 -msgid "Drag rows to change priority. The rule at the top is checked first." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9514 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10209 -msgid "DSCP marks (QoS)" -msgstr "" - #: src/validators/validateOutboundJson.ts:75 msgid "Duplicate JSON outbound tag" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4795 -msgid "Duplicate value" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8676 -msgid "e.g. AES-256-GCM — leave empty for default" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10011 -msgid "e.g. google.com, 1.1.1.1, 443" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8687 -msgid "e.g. SHA256 — leave empty for default" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1737 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:68 -msgid "Edit rule action" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7226 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2479 -msgid "Enable" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1427 -msgid "Enable Adaptive Intervals" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1250 -msgid "Enable AI Doctor (ChatGPT / LLM Analysis)" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:760 msgid "Enable AI Doctor (LLM Integration)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1434 -msgid "Enable Anomaly Detection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2839 -msgid "Enable authentication" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:959 -msgid "Enable automatic updates for remote lists and rule sets" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:98 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:100 msgid "Enable autostart" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2577 -msgid "Enable built-in DNS resolver for domains handled by this section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1406 -msgid "Enable Config Validation" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1366 -msgid "Enable DNS Continuous Check" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:498 msgid "Enable DNS Turbo Cache" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1379 -msgid "Enable Firewall Reload Dedup" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1413 -msgid "Enable Graceful Degradation" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1386 -msgid "Enable Health Metrics" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:958 -msgid "Enable list updates" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9060 -msgid "Enable Mixed Proxy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9101 -msgid "Enable Mixed Proxy Authentication" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:758 -msgid "Enable Output Network Interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1342 -msgid "Enable Proxy Health Monitor" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1399 -msgid "Enable Smart Cooldowns" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1453 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1070 msgid "Enable Smart Detect" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1663 -msgid "Enable Telegram Bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:591 -msgid "Enable WAN DNS Fallback for Bootstrap DNS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:582 -msgid "Enable WAN DNS Fallback for Main DNS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1224 -msgid "Enable Watchdog" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:872 -msgid "Enable YACD" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:882 -msgid "Enable YACD WAN Access" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1664 -msgid "Enables the background daemon that polls Telegram for commands and sends notifications." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1225 -msgid "Enables the background watchdog process to monitor services and auto-recover on failures." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2585 -msgid "Enter a complete sing-box inbound object" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4001 -msgid "Enter a complete sing-box outbound object" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2630 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3080 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3956 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3972 -msgid "Enter a display name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2877 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2898 -msgid "Enter a level name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2473 -msgid "Enter HWID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1675 -msgid "Enter the API token obtained from @BotFather." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2465 -msgid "Enter the HWID sent with subscription requests" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8771 -msgid "Enter the subscription URL" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8083 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8085 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8092 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8094 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8146 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8148 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8152 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8154 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8233 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8244 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8246 -msgid "Error" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8154 -msgid "Error running generator:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10124 -msgid "Error running trace:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2747 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2957 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3355 -msgid "Exclude by proxy parameters" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2806 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3019 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3415 -msgid "Exclude by regular expression" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2790 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3003 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3399 -msgid "Exclude countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9219 -msgid "Exclude selected countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2798 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3011 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3407 -msgid "Exclude servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2965 -msgid "Exclude servers with one of the selected protocols from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2971 -msgid "Exclude servers with one of the selected security types from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2968 -msgid "Exclude servers with one of the selected transports from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9523 -msgid "Exclude traffic types" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3470 -msgid "Exclude URLTest / Priority group" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9497 -msgid "Excluded devices" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:54 -msgid "Expecting: %s" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderSections.ts:131 msgid "Expires" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9061 -msgid "Expose this section as a local HTTP+SOCKS proxy" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:255 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:752 +msgid "Failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5630 -msgid "External nfqws config files bypass Tachyon queue management and explicit validation." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6075 -msgid "External nfqws2 config files bypass Tachyon queue management and explicit validation." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1044 +#: src/tachyon/tabs/diagnostic/initController.ts:1015 msgid "Failed to apply fix" msgstr "" @@ -1600,7 +539,6 @@ msgstr "" msgid "Failed to close connections" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1566 #: src/helpers/copyToClipboard.ts:12 msgid "Failed to copy!" msgstr "" @@ -1614,29 +552,21 @@ msgstr "" msgid "Failed to execute" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:44 -msgid "Failed to execute service check." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1354 +#: src/tachyon/tabs/diagnostic/initController.ts:1261 msgid "Failed to generate bug report" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8085 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8094 -msgid "Failed to generate WARP config:" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:115 +msgid "Failed to parse target list." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8246 -msgid "Failed to parse file:" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:106 +msgid "Failed to receive response from AI service." msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:52 -msgid "Failed to parse service check results." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8148 -msgid "Failed to parse WARP config:" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:97 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:785 +msgid "Failed to run service check." msgstr "" #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:405 @@ -1655,22 +585,6 @@ msgstr "" msgid "Failed to save Smart Detect settings" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1609 -msgid "Failed to start bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:341 -msgid "Failed to start watchdog" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1623 -msgid "Failed to stop bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:355 -msgid "Failed to stop watchdog" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:309 #: src/tachyon/tabs/dashboard/initController.ts:310 #: src/tachyon/tabs/dashboard/initController.ts:329 @@ -1693,19 +607,6 @@ msgstr "" msgid "FakeIP works; public IP comparison is inconclusive" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2962 -msgid "FakeTLS host" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3044 -msgid "Fallback on unknown DC" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1367 -msgid "Faster DNS health monitoring than the default cycle. Switches bootstrap DNS on failure." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3159 #: src/tachyon/tabs/dashboard/initController.ts:1249 msgid "Faster server search interval" msgstr "" @@ -1714,206 +615,66 @@ msgstr "" msgid "Fastest" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:19 -msgid "Fetching service status, please wait..." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3312 -msgid "Filter the servers that will be displayed on the dashboard." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9243 -msgid "Finland (fi)" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:34 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:79 +msgid "Fetching service targets..." msgstr "" #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:136 msgid "Firewall WAN port" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1055 -msgid "Fix All" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1039 +#: src/tachyon/tabs/diagnostic/initController.ts:1010 msgid "Fix applied" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3585 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2241 -msgid "Fix the highlighted fields and save again." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:742 -#: src/tachyon/tabs/diagnostic/initController.ts:1035 +#: src/tachyon/tabs/diagnostic/initController.ts:743 +#: src/tachyon/tabs/diagnostic/initController.ts:1006 msgid "Fixed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9486 -msgid "Forced device routing" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:158 +msgid "Full System Diagnostic" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1215 -msgid "Forces sing-box to tunnel DNS requests via DoQ with Encrypted Client Hello (ECH) for SNI hiding." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9242 -msgid "France (fr)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3007 -msgid "Fronting IP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2996 -msgid "Fronting port" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3017 -msgid "Fronting proxy protocol" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6093 -msgid "Fuzzing is not supported here because Tachyon needs deterministic runtime validation." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:941 -msgid "Game Console IPs" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:931 -msgid "Game Console Optimizer (NAT Type 1)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2480 -msgid "Generate a random 16-character hexadecimal HWID" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:163 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:175 msgid "Generate bug report" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2479 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2484 -msgid "Generate HWID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2456 -msgid "Generate HWID from router hardware information for this subscription" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8009 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8047 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8063 -msgid "Generate WARP Config" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:89 msgid "Generated inbound" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8142 -msgid "Generated!" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8078 -msgid "Generating…" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9232 -msgid "GeoIP Countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9214 -msgid "GeoIP Mode" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10206 -msgid "GeoSite / GeoIP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9239 -msgid "Germany (de)" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:729 msgid "GET endpoints are open on LAN. POST endpoints require Authorization: Bearer ." msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:107 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:109 msgid "Get global check" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:696 +#: src/tachyon/tabs/diagnostic/initController.ts:697 msgid "Global check" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2819 -msgid "gRPC service" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3072 -msgid "Handshake timeout" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:584 msgid "Health Checks" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2565 -msgid "Hide cascade connection nodes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2554 -msgid "Hide individual nodes that are already included in imported subscription URLTest groups" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2566 -msgid "Hide intermediate nodes used as detours by other subscription nodes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3408 -msgid "Hide selected servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3471 -msgid "Hide servers from selected groups without repeating their filtering criteria." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3400 -msgid "Hide servers from the specified countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3416 -msgid "Hide servers whose names match the expression." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3363 -msgid "Hide servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3367 -msgid "Hide servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3364 -msgid "Hide servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2553 -msgid "Hide URLTest group nodes" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:14 +msgid "Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings." msgstr "" #: src/partials/modal/renderModal.ts:310 msgid "Hide values" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3123 #: src/tachyon/tabs/dashboard/initController.ts:1235 msgid "Higher-level check interval" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:610 -msgid "Higher-priority DNS Check" +#: src/tachyon/tabs/diagnostic/initController.ts:1122 +msgid "History" msgstr "" #: src/tachyon/tabs/monitoring/initController.ts:867 @@ -1921,184 +682,22 @@ msgstr "" msgid "Host" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4264 -msgid "Hosts" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7985 -msgid "Hosts Lists Update Interval" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1393 -msgid "How many hours of metrics to keep (default 24)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3124 -msgid "How often higher priority levels are checked while a lower level is active" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3100 -msgid "How often the currently selected server is checked" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1373 -msgid "How often to check DNS health in seconds (default 60)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1349 -msgid "How often to check proxy health in seconds (fast tier, default 30)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1715 -msgid "How often to check Telegram for new messages (default: 5)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:602 -msgid "How often to check the active DNS servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:611 -msgid "How often to check whether a higher-priority DNS server has recovered." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9530 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9549 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:387 msgid "HTTP" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:67 -msgid "HTTP (ms)" -msgstr "" - #: src/tachyon/api.ts:27 msgid "HTTP error" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2812 -msgid "HTTP hosts" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:689 msgid "HTTP REST API for external AI agents (Claude, GPT, Open-WebUI) served at /cgi-bin/tachyon-agent/" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2464 -msgid "HWID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2675 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3062 #: src/tachyon/tabs/dashboard/initController.ts:1110 msgid "Idle timeout" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1414 -msgid "If one health check fails with an error, continue running other checks instead of stopping." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7577 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7590 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7640 -msgid "Import" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7637 -msgid "Import (%d records)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8164 -msgid "Import AmneziaWG settings from .conf file" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7691 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7824 -msgid "Import Hosts File" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2544 -msgid "Import subscription URLTest groups" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2545 -msgid "Import URLTest groups returned by this subscription provider" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2584 -msgid "Inbound JSON" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1970 -msgid "Inbound JSON cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1981 -msgid "Inbound JSON must be an object with a type field" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2730 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2939 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3335 -msgid "Include by proxy parameters" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2782 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2995 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3391 -msgid "Include by regular expression" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2766 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2979 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3375 -msgid "Include countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4076 -msgid "Include IP addresses and subnets" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9220 -msgid "Include selected countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2774 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2987 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3383 -msgid "Include servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1745 -msgid "Information" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8401 -msgid "Init Packet Magic Header (S1)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8403 -msgid "Init Packet Magic Header (S3)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8409 -msgid "Init Packet Payload (I1)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8410 -msgid "Init Packet Payload (I2)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8411 -msgid "Init Packet Payload (I3)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8412 -msgid "Init Packet Payload (I4)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8413 -msgid "Init Packet Payload (I5)" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:809 msgid "Install" msgstr "" @@ -2116,41 +715,15 @@ msgstr "" msgid "Installed version is newer than release" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:821 -msgid "Interface Monitoring" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:855 -msgid "Interface Monitoring Delay" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:822 -msgid "Interface monitoring for Bad WAN" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2689 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3175 #: src/tachyon/tabs/dashboard/initController.ts:1112 #: src/tachyon/tabs/dashboard/initController.ts:1255 msgid "Interrupt connections" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3176 -msgid "Interrupt connections when priority failover switches server" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2690 -msgid "Interrupt connections when URLTest switches the selected server" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1108 msgid "Interval" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7456 -msgid "Invalid ByeDPI strategy" -msgstr "" - #: src/validators/validateSubnet.ts:25 msgid "Invalid CIDR prefix" msgstr "" @@ -2163,7 +736,6 @@ msgstr "" msgid "Invalid DNS server port" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5303 #: src/validators/validateDomain.ts:67 #: src/validators/validateDomain.ts:73 msgid "Invalid domain address" @@ -2234,32 +806,18 @@ msgstr "" msgid "Invalid IP address" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1983 #: src/validators/validateOutboundJson.ts:58 msgid "Invalid JSON format" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7754 -msgid "Invalid line: \"%s\". Use: domain ip or ip domain" -msgstr "" - #: src/validators/validatePath.ts:22 msgid "Invalid path format. Path must start with \"/\" and contain valid characters" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9094 #: src/validators/validateShadowsocksUrl.ts:91 msgid "Invalid port number. Must be between 1 and 65535" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5452 -msgid "Invalid port or range. Use 80 or 1000-2000" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4678 -msgid "Invalid regular expression" -msgstr "" - #: src/validators/validateShadowsocksUrl.ts:38 msgid "Invalid Shadowsocks URL: decoded credentials must contain method:password" msgstr "" @@ -2427,50 +985,15 @@ msgstr "" msgid "Invalid VMess URL: parsing failed" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:64 -msgid "IP / DNS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10203 -msgid "IP Addresses (IP CIDR)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9311 -msgid "IPs" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:692 -msgid "IPv4 only" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:694 -msgid "IPv6 only" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:920 -msgid "Isolate BitTorrent traffic and force it direct to prevent VPN bans" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:738 +#: src/tachyon/tabs/diagnostic/initController.ts:739 msgid "Issues" msgstr "" -#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:20 #: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:17 +#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:20 msgid "Issues detected" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9247 -msgid "Japan (jp)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1082 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4000 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4266 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8859 -msgid "JSON outbound" -msgstr "" - #: src/validators/validateOutboundJson.ts:50 msgid "JSON outbound cannot be empty" msgstr "" @@ -2487,64 +1010,15 @@ msgstr "" msgid "JSON outbound must contain a non-empty type field" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4024 -msgid "JSON outbound settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8400 -msgid "Junk Max Size (Jmax)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8399 -msgid "Junk Min Size (Jmin)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8398 -msgid "Junk Packet Count (Jc)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9250 -msgid "Kazakhstan (kz)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3185 -msgid "Keep Priority before latency-sorted servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2699 -msgid "Keep URLTest before latency-sorted servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:681 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:484 msgid "Keeps FakeIP cache persistent across reboots and pre-resolves popular blocked domains on startup so first-visit latency is 0 ms." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8592 -msgid "Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2669 -msgid "Key path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4688 -msgid "Keyword must not contain spaces or commas" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1292 -msgid "Language for AI Doctor diagnosis responses" -msgstr "" - #: src/tachyon/methods/shell/index.ts:480 #: src/tachyon/methods/shell/index.ts:501 msgid "Latency test failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1064 -msgid "Latency test URL" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:302 #: src/tachyon/tabs/updates/initController.ts:1142 msgid "Latest version is installed" @@ -2554,72 +1028,18 @@ msgstr "" msgid "Latest version:" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2510 -msgid "Leave empty to omit this header" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1191 msgid "Level" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2893 -msgid "Level name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7157 -msgid "List must be an HTTP(S) URL or a local .lst path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1495 -msgid "List of domains automatically detected and the section they were added to. To edit or remove them, open the routing rules of the respective section." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:968 -msgid "List Update Frequency" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2534 -msgid "Listen address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2541 -msgid "Listen port" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:125 msgid "Listening port" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1270 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:821 msgid "LM Studio (Local PC / Server)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8215 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8224 -msgid "Load .conf" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8163 -msgid "Load .conf config" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7550 -msgid "Load Current Records" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7547 -msgid "Loaded %d current record(s)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8290 -msgid "Loaded!" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1702 -msgid "Loading client link..." -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:988 #: src/tachyon/tabs/monitoring/render.ts:101 msgid "Loading connections" @@ -2637,14 +1057,6 @@ msgstr "" msgid "Loading…" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8312 -msgid "Local Address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1186 -msgid "Log Level" -msgstr "" - #: src/tachyon/helpers/singBoxVariant.ts:62 msgid "lx" msgstr "" @@ -2653,94 +1065,14 @@ msgstr "" msgid "Main DNS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:533 -msgid "Main DNS server. If multiple servers are selected, a timeout switches to a backup." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8640 -msgid "MASQUE Access Token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8628 -msgid "MASQUE Account ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8616 -msgid "MASQUE Private Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9312 -msgid "Match destination IPs or subnets" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9507 -msgid "Match destination ports. Use a single port or a range" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10064 -msgid "Match Found" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9515 -msgid "Match traffic by packet DSCP mark (assigned in Windows via Policy-Based QoS). Examples: 46 (EF), 0x2e, 34 (AF41)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1441 -msgid "Max reconnects per hour before alert (default 10)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:620 -msgid "Maximum time to wait for example.com to resolve during a DNS health check." -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1656 msgid "Memory Usage" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2826 -msgid "Method" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1392 -msgid "Metrics Retention (hours)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2649 -msgid "Minimum latency difference in milliseconds that triggers switching to a faster server." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9152 -msgid "Mixed Proxy Password" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9075 -msgid "Mixed Proxy Port" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9116 -msgid "Mixed Proxy Username" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1279 -msgid "Model name to use. Leave empty to use default (gpt-4o-mini / claude-3-5-haiku / deepseek-chat / llama3:latest)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:831 -msgid "Monitored Interfaces" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:508 -msgid "Monitoring" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:633 msgid "Monitoring & Analytics" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1435 -msgid "Monitors sing-box reconnect frequency. Alerts if too many reconnects per hour." -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1004 msgid "Move down" msgstr "" @@ -2749,49 +1081,6 @@ msgstr "" msgid "Move up" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8375 -msgid "MTU" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1705 -msgid "Must be a comma-separated list of numeric IDs" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2074 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2089 -msgid "Must be a number in the range of 0 - 10000" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2619 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3076 -msgid "Name displayed on the dashboard" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2894 -msgid "Name shown in the priority level list" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9240 -msgid "Netherlands (nl)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:504 -msgid "Network & Interfaces" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1889 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8818 -msgid "Network Interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3775 -msgid "Network interface settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7631 -msgid "New domains:" -msgstr "" - #: src/tachyon/services/core.service.ts:38 msgid "New version %s is available for %s" msgstr "" @@ -2806,22 +1095,6 @@ msgstr "" msgid "NFQUEUE range overlaps with another rule" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7374 -msgid "NFQWS Strategy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5760 -msgid "NFQWS strategy cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7407 -msgid "NFQWS2 Strategy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6234 -msgid "NFQWS2 strategy cannot be empty" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:812 #: src/tachyon/tabs/dashboard/initController.ts:816 #: src/tachyon/tabs/dashboard/initController.ts:892 @@ -2837,7 +1110,6 @@ msgstr "" msgid "No active connections" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:389 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1112 msgid "No active routing sections found." msgstr "" @@ -2850,31 +1122,15 @@ msgstr "" msgid "No conflict detected" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10113 -msgid "No Custom Rules Matched" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1097 +#: src/tachyon/tabs/diagnostic/initController.ts:1042 msgid "No diagnostic history available yet." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1510 -msgid "No domains detected yet" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:57 -msgid "No domains found to check." -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:187 msgid "No enabled server inbounds configured" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7554 -msgid "No file selected" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:745 +#: src/tachyon/tabs/diagnostic/initController.ts:746 msgid "No issues found" msgstr "" @@ -2886,7 +1142,7 @@ msgstr "" msgid "No public firewall port required" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1087 +#: src/tachyon/tabs/diagnostic/initController.ts:1032 msgid "No quick fix required" msgstr "" @@ -2902,6 +1158,10 @@ msgstr "" msgid "No rules use Zapret2" msgstr "" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:123 +msgid "No targets found in section configs." +msgstr "" + #: src/tachyon/tabs/dashboard/initController.ts:1070 msgid "Node list is empty" msgstr "" @@ -2910,13 +1170,6 @@ msgstr "" msgid "Nodes" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:449 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2599 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2891 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2900 -msgid "None" -msgstr "" - #: src/tachyon/methods/custom/getDashboardSections.ts:1572 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:586 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46 @@ -2961,113 +1214,22 @@ msgid "Not responding" msgstr "" #: src/tachyon/tabs/diagnostic/diagnostic.store.ts:140 -#: src/tachyon/tabs/diagnostic/initController.ts:123 -#: src/tachyon/tabs/diagnostic/initController.ts:353 -#: src/tachyon/tabs/diagnostic/initController.ts:411 -#: src/tachyon/tabs/diagnostic/initController.ts:497 +#: src/tachyon/tabs/diagnostic/initController.ts:124 +#: src/tachyon/tabs/diagnostic/initController.ts:354 +#: src/tachyon/tabs/diagnostic/initController.ts:412 +#: src/tachyon/tabs/diagnostic/initController.ts:498 msgid "Not running" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10179 -msgid "Not set" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1787 -msgid "Notify on Certificate Warnings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1735 -msgid "Notify on Core Crashes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1800 -msgid "Notify on DNS Leaks" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1761 -msgid "Notify on Server Switches" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1748 -msgid "Notify on Service Restarts" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1774 -msgid "Notify on Subscription Updates" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:631 -msgid "Number of consecutive failed checks required before switching DNS servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1355 -msgid "Number of consecutive failures before restarting (default 3)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:645 -msgid "Number of consecutive successful checks required before returning to a higher-priority DNS server." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2899 -msgid "Obfuscation" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2922 -msgid "Obfuscation password" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1269 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:813 msgid "Ollama (Local PC / Server)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7721 -msgid "One record per line: example.com 192.168.1.100 or 192.168.1.100 example.com. Lines starting with # are ignored." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2980 -msgid "Only from the specified countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1960 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1968 -msgid "Only selected" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1961 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1970 -msgid "Only selected except exclusions" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2996 -msgid "Only servers whose names match the expression." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2947 -msgid "Only servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2951 -msgid "Only servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2948 -msgid "Only servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2988 -msgid "Only the specified servers." -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:1118 #: src/tachyon/tabs/updates/initController.ts:1157 msgid "Open" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3968 -msgid "Open priority settings and enter a display name" -msgstr "" - #: src/tachyon/tabs/diagnostic/partials/renderWikiDisclaimer.ts:31 msgid "Open Project Page" msgstr "" @@ -3082,121 +1244,34 @@ msgstr "" msgid "Optimization" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1399 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6836 -msgid "Option \"%s\" contains an invalid input value." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8604 -msgid "Optional — leave empty for default" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:901 msgid "Optional for local LLM" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8734 -msgid "Optional tls-auth or tls-crypt key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5838 -msgid "Optional values must be attached with '=' here; a separate token would be ignored by nfqws." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6312 -msgid "Optional values must be attached with '=' here; a separate token would be ignored by nfqws2." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7696 -msgid "Or paste hosts file content:" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:63 -msgid "Outbound" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:358 +msgid "Outbound Route" msgstr "" #: src/validators/validateOutboundJson.ts:111 msgid "outbounds must be a non-empty array of strings" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:768 -msgid "Output Network Interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2493 -msgid "Override the default OpenWrt device headers for this subscription" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7705 -msgid "Overwrite existing records (if unchecked, merge with existing records)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:919 -msgid "P2P Leak Protection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2981 -msgid "Padding" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7628 -msgid "Parsed records:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8483 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8571 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2862 -msgid "Password" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9178 -msgid "Password cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7573 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7588 -msgid "Paste content or upload a file to preview imported DNS records." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:240 +msgid "Passed" msgstr "" #: src/validators/validatePath.ts:7 msgid "Path cannot be empty" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1167 -msgid "Path must be absolute (start with /)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1176 -msgid "Path must contain at least one directory (like /tmp/cache.db)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1171 -msgid "Path must end with cache.db" -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:737 #: src/tachyon/tabs/monitoring/render.ts:80 #: src/tachyon/tabs/monitoring/render.ts:81 msgid "Pause updates" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8335 -msgid "Peer Public Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8698 -msgid "PEM-encoded CA certificate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8710 -msgid "PEM-encoded client certificate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8722 -msgid "PEM-encoded client private key" -msgstr "" - #: src/tachyon/tabs/diagnostic/diagnostic.store.ts:63 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:442 msgid "Pending" msgstr "" @@ -3205,98 +1280,10 @@ msgstr "" msgid "Per-Device Routing" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3149 -msgid "Periodically check the current level and switch to a faster server even when the current one works." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1343 -msgid "Periodically checks if the proxy is responding. Restarts Tachyon after consecutive failures." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8382 -msgid "Persistent Keepalive" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1420 -msgid "Persistent Smart Detect" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2698 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3184 -msgid "Pin on dashboard" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1714 -msgid "Polling Interval (seconds)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1727 -msgid "Polling interval must be at least 1 second" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9086 -msgid "Port cannot be empty" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:19 msgid "Port conflict" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9076 -msgid "Port for the local mixed proxy of this section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5459 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1813 -msgid "Port must be between 1 and 65535" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5463 -msgid "Port range start must be less than or equal to end" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9506 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10208 -msgid "Ports" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1005 -msgid "Pre-download all preset lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8526 -msgid "Pre-shared key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:691 -msgid "Prefer IPv4" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:693 -msgid "Prefer IPv6" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3024 -msgid "Preferred IP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2537 -msgid "Prefix text" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8369 -msgid "Preshared Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1380 -msgid "Prevents multiple reload_firewall calls within 120 seconds to avoid connection drops." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8945 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10103 -msgid "Priority" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1274 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:514 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:515 @@ -3307,209 +1294,43 @@ msgstr "" msgid "Priority details are unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3853 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3854 -msgid "Priority level settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3193 -msgid "Priority levels" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3913 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3918 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3919 -msgid "Priority settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8324 -msgid "Private Key" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:613 msgid "Protection" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2030 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8663 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2485 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2519 -msgid "Protocol" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1354 -msgid "Proxy Fail Threshold" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1348 -msgid "Proxy Health Check Interval (s)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1360 -msgid "Proxy Health Check URL" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:807 msgid "Proxy link is unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1811 -msgid "Proxy Section for Bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8457 -msgid "Proxy to use for WARP API registration (api.cloudflareclient.com)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8526 -msgid "PSK" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2548 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:40 msgid "Public host" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1612 -msgid "QR code is too large" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9527 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9546 -msgid "QUIC (HTTP/3)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9533 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9552 -msgid "RDP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8296 -msgid "Read error" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2687 -msgid "Reality fake site" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2698 -msgid "Reality fake site port" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2741 -msgid "Reality max time difference" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2709 -msgid "Reality private key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2716 -msgid "Reality public key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2722 -msgid "Reality short ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2094 -msgid "Reality short ID must contain 1-8 hex digits" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:1138 msgid "Rebuilt release" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1007 -msgid "Recommended Smart Quick Fixes:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1440 -msgid "Reconnect Threshold" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1387 -msgid "Records proxy/DNS latency and health status in hourly buckets for analysis." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7779 -msgid "Records: %d" +#: src/tachyon/tabs/diagnostic/initController.ts:979 +msgid "Recommended Quick Fixes:" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderSections.ts:132 msgid "Refill" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8456 -msgid "Registration Detour" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5345 -msgid "Regular expression must not contain spaces or commas" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:898 msgid "Reinstall" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7838 -msgid "Remote Hosts Lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7918 #: src/tachyon/tabs/updates/initController.ts:854 msgid "Remove" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3004 -msgid "Remove servers from the specified countries from this level." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:363 +msgid "Resolved IP / DNS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3020 -msgid "Remove servers whose names match the expression from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3012 -msgid "Remove the specified servers from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9102 -msgid "Require a username and password for the local mixed proxy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9189 -msgid "Resolve domain names before routing so sing-box can use real destination IPs." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9188 -msgid "Resolve real IP for routing" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5633 -msgid "Resource selection by hostname inside nfqws is not supported here; sing-box selects resources before NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6078 -msgid "Resource selection by hostname inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5636 -msgid "Resource selection by IP or CIDR inside nfqws is not supported here; sing-box selects resources before NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6081 -msgid "Resource selection by IP or CIDR inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8402 -msgid "Response Packet Magic Header (S2)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8404 -msgid "Response Packet Magic Header (S4)" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:58 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:60 msgid "Restart Tachyon" msgstr "" @@ -3526,63 +1347,12 @@ msgstr "" msgid "Route" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1812 -msgid "Route bot API requests through this section. Leave empty to use the default mixed proxy." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:703 -msgid "Route main DNS requests through the selected section." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7346 -msgid "Route requests to this DNS server through another section." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2560 -msgid "Routing mode" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10008 -msgid "Routing Rule Tracer" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:103 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:114 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:144 msgid "Routing rules" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2569 -msgid "Routing section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10074 -msgid "Rule" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7148 -msgid "Rule set must be an HTTP(S) URL or a local .srs / .json path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4083 -msgid "Rule set settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9374 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9403 -msgid "Rule sets" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10204 -msgid "Rule Sets (.srs / .json)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2561 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:101 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:107 -msgid "Rules" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runNftCheck.ts:79 msgid "Rules mangle counters" msgstr "" @@ -3607,7 +1377,7 @@ msgstr "" msgid "Rules proxy exist" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:126 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:128 msgid "Run AI Doctor" msgstr "" @@ -3615,28 +1385,16 @@ msgstr "" msgid "Run Diagnostic" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:116 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:118 msgid "Run doctor repair" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1174 -msgid "Run History" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:301 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1573 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1574 #: src/tachyon/methods/custom/getDashboardSections.ts:1567 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:581 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135 msgid "Running" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9237 -msgid "Russia (ru)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3660 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1151 msgid "Save" msgstr "" @@ -3660,231 +1418,37 @@ msgstr "" msgid "Search" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2938 -msgid "Secret" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:896 -msgid "Secret key for authenticating remote access to YACD when WAN access is enabled." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1238 -msgid "Secret token for authorizing WRITE operations (POST/PUT) on /cgi-bin/tachyon-agent/. Leave empty if auth is not required." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:328 +msgid "Search domain..." msgstr "" #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:700 msgid "Secret token for WRITE requests" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:432 -msgid "Section" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:62 -msgid "Section / Domain" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10198 -msgid "Section action" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7253 -msgid "Section name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10213 -msgid "Section Rules Content" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:353 +msgid "Section / Target" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1078 msgid "Section test order (checked = active, drag rows with △▽):" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:426 -msgid "Sections" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2042 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2596 -msgid "Security" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2436 -msgid "Select a common client profile or enter a custom User-Agent" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8233 -msgid "Select a file with .conf extension" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8824 -msgid "Select a network interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9322 -msgid "Select a predefined domain list" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7367 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:87 -msgid "Select a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2413 -msgid "Select a section for downloading this subscription" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9023 -msgid "Select a transit section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1263 -msgid "Select AI LLM provider for diagnostics" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1940 -msgid "Select an existing network interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3295 -msgid "Select an existing URLTest or Priority group" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9036 -msgid "Select an intermediate section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1467 -msgid "Select and order the sections through which blocked domains are tested. Checked sections are tried top-to-bottom." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:517 -msgid "Select DNS protocol to use" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8819 -msgid "Select network interface for VPN connection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9233 -msgid "Select one or more country ISO codes (e.g. ru, us, de, nl, fr, fi, se, tr, cn, jp, sg, by, kz, ua)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2449 -msgid "Select or enter a User-Agent" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1150 -msgid "Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:942 -msgid "Select or enter the IP addresses of your game consoles." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1136 -msgid "Select path for sing-box config file. Change this ONLY if you know what you are doing" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3137 #: src/tachyon/tabs/dashboard/initController.ts:1239 msgid "Select the fastest node" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1187 -msgid "Select the log level for sing-box" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:721 -msgid "Select the network interface from which the traffic will originate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:769 -msgid "Select the network interface to which the traffic will originate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:832 -msgid "Select the WAN interfaces to be monitored" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1104 #: src/tachyon/tabs/dashboard/initController.ts:1225 msgid "Selected" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2563 -msgid "Selected section" -msgstr "" - #: src/validators/validateOutboundJson.ts:85 msgid "Selector and URLTest outbounds must contain a non-empty outbounds array" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1801 -msgid "Send a Telegram notification if a potential DNS leak is detected." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1736 -msgid "Send a Telegram notification if sing-box or nftables rules crash and get auto-restored." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1788 -msgid "Send a Telegram notification if SSL/TLS certificates are close to expiration." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1749 -msgid "Send a Telegram notification if the Tachyon service is restarted by the watchdog." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1762 -msgid "Send a Telegram notification when a URLTest group switches to a new server." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1775 -msgid "Send a Telegram notification when proxy subscriptions are successfully updated." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:449 -msgid "Server" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8346 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8471 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8514 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8545 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8580 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8650 -msgid "Server Address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2707 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2913 -msgid "Server filtering" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8887 -msgid "Server group for automatic lowest-latency selection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8946 -msgid "Server group for priority failover" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1706 -msgid "Server information" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1622 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2496 -msgid "Server name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2625 -msgid "Server name / SNI" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8495 -msgid "Server Name Indication — leave empty to use server address" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:67 +msgid "Send" msgstr "" #: src/validators/validateOutboundJson.ts:94 @@ -3895,96 +1459,33 @@ msgstr "" msgid "Server outbound must contain a numeric server_port from 1 to 65535" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8357 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8477 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8520 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8551 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8586 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8656 -msgid "Server Port" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:135 +msgid "Server unavailable" msgstr "" #: src/validators/validateOutboundJson.ts:107 msgid "server_port must be a number from 1 to 65535" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:443 -msgid "Servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3311 -msgid "Servers on dashboard" -msgstr "" - #: src/tachyon/methods/shell/index.ts:401 #: src/tachyon/methods/shell/index.ts:422 -#: src/tachyon/tabs/diagnostic/initController.ts:604 +#: src/tachyon/tabs/diagnostic/initController.ts:605 msgid "Service action failed" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:24 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:70 msgid "Service Health Check" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9325 -msgid "Service list" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:505 -msgid "Services & Access" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1666 msgid "Services info" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1143 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7223 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:461 -msgid "Settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2520 -msgid "Show metadata on dashboard" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3384 -msgid "Show only selected servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3343 -msgid "Show only servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3349 -msgid "Show only servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3346 -msgid "Show only servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3457 -msgid "Show servers from selected groups without repeating their filtering criteria." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3376 -msgid "Show servers only from the specified countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3392 -msgid "Show servers whose names match the expression." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1287 -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:154 +#: src/tachyon/tabs/diagnostic/initController.ts:1194 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:166 msgid "Show sing-box config" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2521 -msgid "Show subscription metadata for this source on the dashboard" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runSingBoxCheck.ts:77 msgid "Sing-box autostart disabled" msgstr "" @@ -4017,26 +1518,6 @@ msgstr "" msgid "Sing-box version is compatible (newer than 1.12.4)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9248 -msgid "Singapore (sg)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7701 -msgid "Skip loopback & local entries (127.0.0.1, ::1, 0.0.0.0, localhost)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8506 -msgid "Skip TLS certificate verification (not recommended)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7630 -msgid "Skipped comments/invalid:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7629 -msgid "Skipped loopback:" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1048 msgid "Smart Detect" msgstr "" @@ -4045,54 +1526,11 @@ msgstr "" msgid "Smart Detect settings saved" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8533 -msgid "Snell Version" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1072 -msgid "Some fixes failed" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7801 -msgid "Sort Alphabetically" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9048 -msgid "Sort by latency" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9049 -msgid "Sorts servers in this section by lowest latency in the dashboard." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10081 #: src/tachyon/tabs/monitoring/initController.ts:883 #: src/tachyon/tabs/monitoring/initController.ts:933 msgid "Source" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10207 -msgid "Source Devices" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:720 -msgid "Source Network Interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1929 -msgid "Specify a file path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1940 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1952 -msgid "Specify different files" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9532 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9551 -msgid "SSH" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:122 msgid "Standalone ByeDPI autostart is enabled" msgstr "" @@ -4137,15 +1575,7 @@ msgstr "" msgid "Standalone Zapret2 service is inactive" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:285 -msgid "Start" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1555 -msgid "Start bot" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:78 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:80 msgid "Start Tachyon" msgstr "" @@ -4153,66 +1583,21 @@ msgstr "" msgid "Start Watchdog first" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:334 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1602 -msgid "Starting…" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:449 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:633 msgid "Status" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:292 -msgid "Stop" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1562 -msgid "Stop bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2676 -msgid "Stop checking when URLTest group is not used. Use sing-box duration format like 1d, 12h or 30m." -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:68 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:70 msgid "Stop Tachyon" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:307 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1579 #: src/tachyon/methods/custom/getDashboardSections.ts:1571 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:585 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147 msgid "Stopped" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:348 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1616 -msgid "Stopping…" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1421 -msgid "Store auto-detected domains in /etc instead of /tmp to survive reboots." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1214 -msgid "Strict ECH + DoQ DNS Enforcer" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9528 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9547 -msgid "STUN (P2P Calls)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4077 -msgid "Subnets from the list will be extracted and added to nftables" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2367 -msgid "Subscription auto update" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderSections.ts:146 msgid "Subscription info:" msgstr "" @@ -4222,34 +1607,10 @@ msgstr "" msgid "Subscription update failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2376 -msgid "Subscription update interval" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8770 -msgid "Subscription URL" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3764 -msgid "Subscription URL settings" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:335 msgid "Subscriptions updated" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8144 -msgid "Success" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7688 -msgid "Successfully imported %d DNS record(s)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9244 -msgid "Sweden (se)" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1653 msgid "System info" msgstr "" @@ -4266,22 +1627,6 @@ msgstr "" msgid "Tachyon Error" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6504 -msgid "Tachyon manages ciadpi pid files itself, so pidfile options are not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6501 -msgid "Tachyon manages the ciadpi process lifecycle itself, so daemon mode is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5648 -msgid "Tachyon manages the nfqws process lifecycle itself, so daemon mode is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6099 -msgid "Tachyon manages the nfqws2 process lifecycle itself, so daemon mode is not allowed here." -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:977 msgid "Tachyon service is stopped. Start the service to display connections." msgstr "" @@ -4290,14 +1635,6 @@ msgstr "" msgid "Tachyon service is stopped. Start the service to display the dashboard." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:366 -msgid "Tachyon Settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1126 -msgid "Tachyon will not modify your DHCP configuration" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:91 msgid "Tachyon-managed ciadpi runtime has restarted" msgstr "" @@ -4338,32 +1675,12 @@ msgstr "" msgid "Tachyon-managed nfqws2 runtime is ready" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3080 -msgid "Tailscale auth key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3089 -msgid "Tailscale control URL" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:98 msgid "Tailscale endpoint" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3097 -msgid "Tailscale hostname" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:65 -msgid "TCP (ms)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:473 -msgid "Telegram Bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1674 -msgid "Telegram Bot Token" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:371 +msgid "TCP" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderSections.ts:241 @@ -4372,46 +1689,12 @@ msgstr "" msgid "Test latency" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2775 -msgid "Test only selected servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2735 -msgid "Test only servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2741 -msgid "Test only servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2738 -msgid "Test only servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2767 -msgid "Test servers only from the specified countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2783 -msgid "Test servers whose names match the expression." -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1107 msgid "Testing URL" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5645 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6090 -msgid "The desync fwmark is managed by Tachyon for loop prevention and must not be overridden here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5642 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6087 -msgid "The NFQUEUE number is assigned by Tachyon for each rule and must not be overridden here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9272 -msgid "The rule applies to the domain and all its subdomains. Use full:, keyword:, or regex: prefixes for exact match, keyword match, or regular expression." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:685 +msgid "Testing..." msgstr "" #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:78 @@ -4426,43 +1709,8 @@ msgstr "" msgid "There are rules using Zapret2" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10265 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1828 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1833 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1923 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2085 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2885 -msgid "This field is required" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6507 -msgid "This field must start a working ciadpi strategy; help/version options exit immediately and are not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5651 -msgid "This field must start a working nfqws strategy; --dry-run exits immediately and is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5654 -msgid "This field must start a working nfqws strategy; --version exits immediately and is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6102 -msgid "This field must start a working nfqws2 strategy; --dry-run exits immediately and is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6105 -msgid "This field must start a working nfqws2 strategy; --version exits immediately and is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5823 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6297 -msgid "This flag does not accept a value." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5854 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6328 -msgid "This option requires a value." +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:91 +msgid "Thinking..." msgstr "" #: src/tachyon/tabs/monitoring/initController.ts:874 @@ -4470,58 +1718,20 @@ msgstr "" msgid "Time" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:659 -msgid "Time in seconds for DNS record caching (default: 60)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3054 -msgid "Time skew tolerance" -msgstr "" - #: src/tachyon/helpers/singBoxVariant.ts:64 msgid "tiny" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:66 -msgid "TLS (ms)" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:379 +msgid "TLS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9531 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9550 -msgid "TLS / HTTPS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8733 -msgid "TLS Auth/Crypt Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8494 -msgid "TLS SNI" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1683 -msgid "Token is required when the bot is enabled" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2648 #: src/tachyon/tabs/dashboard/initController.ts:1109 msgid "Tolerance" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3194 -msgid "Top level has the highest priority; lower levels are used as fallback" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7627 -msgid "Total lines:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10012 -msgid "Trace" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10049 -msgid "Tracing routing rules..." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:225 +msgid "Total Targets" msgstr "" #: src/tachyon/tabs/dashboard/initController.ts:1627 @@ -4529,131 +1739,23 @@ msgstr "" msgid "Traffic" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2905 -msgid "Traffic for this level goes directly." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9498 -msgid "Traffic from these IP addresses will never be routed through this section, even if other conditions match." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9524 -msgid "Traffic of specified protocols (e.g. BitTorrent, QUIC, STUN) will bypass this section." -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1640 msgid "Traffic Total" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9542 -msgid "Traffic type filter" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10114 -msgid "Traffic will go through the default route (Direct/Default)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6498 -msgid "Transparent proxy mode is incompatible with action=byedpi because Tachyon connects to ciadpi through SOCKS." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2036 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8557 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2763 -msgid "Transport" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2787 -msgid "Transport host" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2771 -msgid "Transport path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2006 -msgid "Transport path must start with /" -msgstr "" - #: src/tachyon/tabs/diagnostic/partials/renderWikiDisclaimer.ts:25 msgid "Troubleshooting" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2425 -msgid "Try compatible User-Agent profiles automatically when downloading this subscription" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:670 -msgid "TTL must be a positive number" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:665 -msgid "TTL value cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9245 -msgid "Turkey (tr)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1637 #: src/tachyon/tabs/monitoring/initController.ts:868 #: src/tachyon/tabs/monitoring/initController.ts:928 msgid "Type" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:522 -msgid "UDP (Unprotected DNS)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9251 -msgid "Ukraine (ua)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6422 -msgid "Unable to validate the ByeDPI strategy through the backend parser." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5565 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6900 -msgid "Unable to validate the NFQWS strategy through the backend parser." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6010 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6909 -msgid "Unable to validate the NFQWS2 strategy through the backend parser." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3111 #: src/tachyon/tabs/dashboard/initController.ts:1233 msgid "Unavailability timeout" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8405 -msgid "Underload Packet Magic Header (H1)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8406 -msgid "Underload Packet Magic Header (H2)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8407 -msgid "Underload Packet Magic Header (H3)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8408 -msgid "Underload Packet Magic Header (H4)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6639 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6688 -msgid "Unexpected ByeDPI strategy argument: %s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5803 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6277 -msgid "Unexpected standalone token. Use explicit flags such as --name or --name=value." -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:96 msgid "Unexpected Tachyon-managed ciadpi runtime is running" msgstr "" @@ -4666,18 +1768,6 @@ msgstr "" msgid "Unexpected Tachyon-managed nfqws2 runtime is running" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:54 -msgid "unique UCI identifier" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9241 -msgid "United Kingdom (gb)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9238 -msgid "United States (us)" -msgstr "" - #: src/tachyon/helpers/singBoxVariant.ts:37 #: src/tachyon/services/systemInfo.service.ts:10 #: src/tachyon/services/systemInfo.service.ts:12 @@ -4693,38 +1783,18 @@ msgstr "" msgid "unknown" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:328 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1596 #: src/tachyon/methods/custom/getDashboardSections.ts:1573 msgid "Unknown" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6608 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6630 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6681 -msgid "Unknown ByeDPI option: %s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:616 -msgid "Unknown country" -msgstr "" - #: src/tachyon/api.ts:40 -#: src/tachyon/tabs/diagnostic/initController.ts:720 -#: src/tachyon/tabs/diagnostic/initController.ts:757 -#: src/tachyon/tabs/diagnostic/initController.ts:878 -#: src/tachyon/tabs/diagnostic/initController.ts:1216 +#: src/tachyon/tabs/diagnostic/initController.ts:721 +#: src/tachyon/tabs/diagnostic/initController.ts:758 +#: src/tachyon/tabs/diagnostic/initController.ts:843 +#: src/tachyon/tabs/diagnostic/initController.ts:1159 msgid "Unknown error" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5814 -msgid "Unknown NFQWS flag." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6288 -msgid "Unknown NFQWS2 flag." -msgstr "" - #: src/validators/validateSubnet.ts:17 msgid "Unspecified IP address is not allowed" msgstr "" @@ -4733,10 +1803,6 @@ msgstr "" msgid "Unstable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2119 -msgid "Unsupported security mode for this protocol" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:809 msgid "Update" msgstr "" @@ -4759,18 +1825,6 @@ msgstr "" msgid "Update subscriptions" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2368 -msgid "Update this subscription automatically" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7632 -msgid "Updated/duplicates:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:506 -msgid "Updates & Downloads" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1629 #: src/tachyon/tabs/dashboard/initController.ts:1642 msgid "Uplink" @@ -4789,26 +1843,6 @@ msgstr "" msgid "URL must use one of the following protocols:" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1361 -msgid "URL to test through the proxy (default: Cloudflare 204)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3087 -msgid "URL used to check whether a server is alive" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2663 -msgid "URL used to test server latency" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7839 -msgid "URLs of remote hosts files to download and apply. Supports standard hosts format: IP domain." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8886 -msgid "URLTest" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1131 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:495 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:496 @@ -4819,109 +1853,10 @@ msgstr "" msgid "URLTest details are unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3803 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3804 -msgid "URLTest settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1400 -msgid "Use 3-tier check intervals: fast (15s), normal (120s), slow (300s) instead of a single interval." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2103 -msgid "Use 32 hex characters" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1893 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1899 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2015 -msgid "Use a domain name or IP address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1994 -msgid "Use a duration like 30s, 5m, or 1h30m" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2000 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2887 -msgid "Use a non-negative integer" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2106 -msgid "Use a non-zero secret" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1962 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1964 -msgid "Use an HTTP or HTTPS URL" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1916 -msgid "Use an IP address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1909 -msgid "Use an IP listen address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8985 -msgid "Use another section as an intermediate hop to connect to servers in this section. Does not apply to network interfaces or JSON outbounds." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2063 -msgid "Use CIDR prefixes like 192.168.1.0/24 or 2001:db8::/32" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2077 -msgid "Use CIDR prefixes or IP addresses like 192.168.1.0/24, 192.168.1.10, or 2001:db8::1" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2021 -msgid "Use letters, digits, dots, underscores, or hyphens" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:252 -msgid "Use sing-box duration format like 10s, 1m or 2m30s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2377 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2637 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3160 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4722 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4729 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4736 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:969 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:991 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:998 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1029 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1057 -msgid "Use sing-box duration format like 1d, 12h or 30m" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7986 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7997 -msgid "Use sing-box duration format like 1d, 12h or 6h" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:25 msgid "Used by" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2435 -msgid "User-Agent" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8565 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2846 -msgid "Username" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9142 -msgid "Username cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5338 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5351 #: src/validators/validateDns.ts:25 #: src/validators/validateDns.ts:29 #: src/validators/validateDomain.ts:57 @@ -4941,48 +1876,15 @@ msgstr "" msgid "Valid" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1407 -msgid "Validates sing-box config before restart to prevent boot loops on broken configs." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4791 -msgid "Validation errors:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5328 -msgid "Value cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10268 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1837 -msgid "Value must not contain control characters" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:68 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:395 msgid "Verdict" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1977 -msgid "Via country.is" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1252 -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:145 +#: src/tachyon/tabs/diagnostic/initController.ts:817 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:157 msgid "View logs" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7254 -msgid "Visible name of this section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2890 -msgid "VLESS flow" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8746 -msgid "vless://, vmess://, ss://, trojan://, socks4/5://, hy2/hysteria2:// links" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:70 msgid "WAN" msgstr "" @@ -4991,70 +1893,18 @@ msgstr "" msgid "WAN public IP" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8445 -msgid "WARP Access Token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8433 -msgid "WARP Account ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8144 -msgid "WARP Configuration generated and loaded successfully!" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8421 -msgid "WARP Private Key" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:446 msgid "Watchdog" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1331 -msgid "Watchdog Status" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1204 -msgid "WebRTC Leak Protection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7267 -msgid "What Tachyon should do when this section matches" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3138 -msgid "When switching to another level, test every server and select the fastest instead of the first working one." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8617 -msgid "WireGuard private key from your Cloudflare account" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8422 -msgid "WireGuard private key from your Cloudflare WARP account" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2800 -msgid "XHTTP mode" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:895 -msgid "YACD Secret Key" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:156 +msgid "Why Discord fails?" msgstr "" #: src/tachyon/tabs/dashboard/initController.ts:812 msgid "Yes" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:759 -msgid "You can select Output Network Interface, by default autodetect" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5639 -msgid "Zapret hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS strategies." -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runZapretCheck.ts:71 msgid "Zapret package is installed" msgstr "" @@ -5079,10 +1929,6 @@ msgstr "" msgid "Zapret sing-box outbound is not configured" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6084 -msgid "Zapret2 hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS2 strategies." -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runZapret2Check.ts:74 msgid "Zapret2 package is installed" msgstr "" diff --git a/fe-app-tachyon/locales/tachyon.ru.po b/fe-app-tachyon/locales/tachyon.ru.po index fa4ef976..6e6139d0 100644 --- a/fe-app-tachyon/locales/tachyon.ru.po +++ b/fe-app-tachyon/locales/tachyon.ru.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: TACHYON\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-12 10:20+0300\n" -"PO-Revision-Date: 2026-08-12 10:20+0300\n" +"POT-Creation-Date: 2026-08-12 12:15+0300\n" +"PO-Revision-Date: 2026-08-12 12:15+0300\n" "Last-Translator: Dushnilin\n" "Language-Team: none\n" "Language: ru\n" @@ -17,27 +17,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -msgid "-- Select --" -msgstr "-- Выбрать --" - -msgid ".lst Lists" -msgstr ".lst списки" - -msgid "(provider default)" -msgstr "" - -msgid "+ Add JSON outbound" -msgstr "+ Добавить JSON outbound" - -msgid "+ Add level" -msgstr "+ Добавить уровень" - -msgid "+ Add priority" -msgstr "+ Добавить приоритет" - -msgid "+ Add URLTest" -msgstr "+ Добавить URLTest" - msgid "⏹ Stop" msgstr "⏹ Стоп" @@ -47,12 +26,6 @@ msgstr "▶ Старт" msgid "⚙ Advanced Settings" msgstr "⚙ Настройки" -msgid "⚠️ If all Bootstrap DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss." -msgstr "⚠️ Если все Bootstrap DNS недоступны 3 раза, запросы будут отправлены через DNS провайдера в открытом виде. Используйте только как крайнюю меру." - -msgid "⚠️ If all Main DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss." -msgstr "⚠️ Если все Main DNS недоступны 3 раза, запросы будут отправлены через DNS провайдера в открытом виде. Используйте только как крайнюю меру." - msgid "✔ Running" msgstr "✔ Работает" @@ -62,15 +35,6 @@ msgstr "✘ Остановлено" msgid "🔑 Generate" msgstr "🔑 Сгенерировать" -msgid "Accept external proxy connections and route them with sing-box." -msgstr "Принимает внешние прокси-подключения и маршрутизирует их через sing-box." - -msgid "Accept routes" -msgstr "Принимать маршруты" - -msgid "Action" -msgstr "Действие" - msgid "Active" msgstr "Активные" @@ -86,90 +50,33 @@ msgstr "Активные соединения" msgid "Active Main DNS" msgstr "Активный основной DNS" -msgid "Add a section" -msgstr "Добавить секцию" - -msgid "Add a server inbound" -msgstr "Добавить серверный inbound" - -msgid "Add at least one DNS server" -msgstr "Добавьте хотя бы один DNS-сервер" - -msgid "Add prefix to nodes" -msgstr "Добавить префикс к узлам" - -msgid "Add URLs or local paths to .lst lists containing domains and subnets." -msgstr "Добавьте URL или локальные пути к .lst спискам с доменами и подсетями." - -msgid "Add URLs or local paths to .lst lists containing domains. IP entries are ignored." -msgstr "Добавьте URL или локальные пути к .lst спискам с доменами. IP-адреса игнорируются." - -msgid "Add URLs or local paths to .srs / .json lists. Only domain rules are supported." -msgstr "Добавьте URL или локальные пути к .srs / .json спискам. Поддерживаются только доменные правила." - -msgid "Add URLs or local paths to .srs / .json lists. Subnets are ignored by default." -msgstr "Добавьте URL или локальные пути к .srs / .json спискам. Подсети по умолчанию игнорируются." - -msgid "Add URLTest / Priority group" -msgstr "Добавить URLTest / группу приоритетов" +msgid "Active Sections" +msgstr "Активные секции" msgid "Additional marking rules found" msgstr "Найдены дополнительные правила маркировки" -msgid "Additionally exclude servers by protocol, transport, and security. Exclude only servers matching the specified parameters." -msgstr "Дополнительно исключить серверы по протоколу, транспорту и безопасности. Исключаются только серверы, соответствующие указанным параметрам." - -msgid "Additionally filter servers by protocol, transport, and security. Add only servers matching the specified parameters." -msgstr "Дополнительно фильтровать серверы по протоколу, транспорту и безопасности. Добавляются только серверы, соответствующие указанным параметрам." - -msgid "Additionally hide servers by protocol, transport, and security. Hide servers matching the specified parameters." -msgstr "Дополнительно скрыть серверы по протоколу, транспорту и безопасности. Скрываются серверы, соответствующие указанным параметрам." - -msgid "Additionally show servers by protocol, transport, and security. Add only servers matching the specified parameters." -msgstr "Дополнительно показать серверы по протоколу, транспорту и безопасности. Добавляются только серверы, соответствующие указанным параметрам." - -msgid "Address" -msgstr "Адрес" - -msgid "Administrator Chat IDs" -msgstr "Telegram ID администраторов" - msgid "Advanced self-healing features. Requires Watchdog to be enabled." msgstr "Расширенные функции самовосстановления. Требуется включённый Watchdog." -msgid "Advanced System" -msgstr "" - -msgid "Advertise exit node" -msgstr "Анонсировать exit node" - -msgid "Advertise routes" -msgstr "Анонсировать маршруты" - -msgid "AEAD Method" -msgstr "Метод AEAD" - -msgid "AI & Watchdog" -msgstr "" - msgid "AI Agent REST API (12 Endpoints)" msgstr "HTTP REST API ИИ-агента (12 эндпоинтов)" -msgid "AI Agent REST API Bearer Token" -msgstr "Токен авторизации AI Agent REST API" - msgid "AI API Key" msgstr "API-ключ ИИ" +msgid "AI Chat & Tachyon Assistant" +msgstr "ИИ Чат & Ассистент Tachyon" + +msgid "AI Chat Assistant" +msgstr "" + msgid "AI Doctor (ChatGPT / DeepSeek API)" msgstr "AI Doctor (ChatGPT / DeepSeek API)" msgid "AI Doctor Diagnosis" msgstr "" -msgid "AI Doctor Diagnostic Scan in Progress..." -msgstr "" - msgid "AI Doctor failed" msgstr "" @@ -182,6 +89,9 @@ msgstr "" msgid "AI Provider" msgstr "Провайдер ИИ" +msgid "AI service error" +msgstr "Ошибка ИИ-сервиса" + msgid "AI Watchdog" msgstr "ИИ Watchdog" @@ -191,159 +101,39 @@ msgstr "Настройки AI Watchdog сохранены. Перезапуст msgid "All" msgstr "Все" -msgid "All except selected" -msgstr "Все кроме выбранных" - -msgid "All fixes applied successfully" -msgstr "" - -msgid "All remaining except selected" -msgstr "Все оставшиеся кроме выбранных" - -msgid "All remaining servers" -msgstr "Все оставшиеся серверы" - -msgid "All remaining servers means every server not already assigned to a higher-priority level." -msgstr "Все оставшиеся серверы — это все серверы, не назначенные на уровень с более высоким приоритетом." +msgid "All Profiles" +msgstr "Все сервисы и профили" msgid "All Routes" msgstr "Все маршруты" -msgid "All servers" -msgstr "Все серверы" - -msgid "All traffic from these IP addresses will be routed through the section unconditionally, ignoring all other conditions." -msgstr "Весь трафик с этих IP-адресов будет направляться через секцию безусловно, игнорируя все остальные условия." - -msgid "Allow Insecure TLS" -msgstr "Разрешить небезопасный TLS" - -msgid "Allowed domain prefixes are full:, keyword:, and regex:" -msgstr "Допустимые префиксы доменов: full:, keyword: и regex:" - -msgid "Allows access to YACD from the WAN. Make sure to open the appropriate port in your firewall." -msgstr "Обеспечивает доступ к YACD из WAN. Убедитесь, что в брандмауэре открыт соответствующий порт." - -msgid "Allows limiting the list of servers for URLTest" -msgstr "Позволяет ограничить список серверов для URLTest" - -msgid "Allows Tachyon to send diagnostic snapshots to ChatGPT or DeepSeek API for intelligent root-cause analysis and auto-repair recommendations." -msgstr "Позволяет Tachyon отправлять снимки диагностики в ChatGPT или DeepSeek API для интеллектуального анализа причин неисправностей и рекомендаций по авто-ремонту." - -msgid "ALPN" -msgstr "ALPN" - -msgid "Alter ID" -msgstr "Alter ID" - -msgid "AmneziaWG config loaded successfully!" -msgstr "Конфиг AmneziaWG успешно загружен!" - -msgid "AmneziaWG Generator" -msgstr "Генератор AmneziaWG" - -msgid "An error occurred while checking services." -msgstr "" - -msgid "Analyzing system log (logread & errors)" -msgstr "" - -msgid "API Key for OpenAI (sk-...) or DeepSeek (optional for Ollama / LM Studio)" -msgstr "" - -msgid "Apply rules of this section only to selected protocols." -msgstr "Применять правила этой секции только к выбранным протоколам." - -msgid "Apply section rules only to the specified local IP addresses" -msgstr "Применять правила секции только к указанным локальным IP-адресам" - -msgid "Applying all fixes..." -msgstr "" - msgid "Applying fix" msgstr "" -msgid "At least one Admin Chat ID is required" -msgstr "Требуется хотя бы один Admin Chat ID" - -msgid "At least one valid domain must be specified." -msgstr "Необходимо указать хотя бы один корректный домен." - -msgid "At least one valid IP or subnet must be specified." -msgstr "Необходимо указать хотя бы один корректный IP или подсеть." - -msgid "Auth Digest" -msgstr "Алгоритм аутентификации" +msgid "Ask Tachyon AI Assistant a question..." +msgstr "Задайте вопрос ИИ-ассистенту..." msgid "Auto refresh" msgstr "Автообновление" -msgid "Auto update" -msgstr "Автообновление" - -msgid "Auto-detected domains" -msgstr "Авто-добавленные домены" - -msgid "Auto-detected Domains" -msgstr "Авто-добавленные домены" - msgid "Auto-detects blocked domains from logs and adds them to the first section where they work via proxy." msgstr "Автоматически определяет заблокированные домены из логов и добавляет их в первую секцию, где они работают через прокси." -msgid "Auto-generate HWID" -msgstr "Автогенерация HWID" - -msgid "Auto-update Hosts Lists" -msgstr "Автообновление списков хостов" - -msgid "Automatic component update checks" -msgstr "Автоматическая проверка обновлений компонентов" - -msgid "Automatic User-Agent selection" -msgstr "Автоматический выбор User-Agent" - -msgid "Automatically add text to the name of each server from this subscription for convenient filtering." -msgstr "Автоматически добавлять текст к имени каждого сервера из этой подписки для удобной фильтрации." - -msgid "Automatically check installed components for new versions" -msgstr "Автоматически проверять наличие новых версий установленных компонентов" - -msgid "Automatically generate a Cloudflare WARP account and configure all AmneziaWG settings." -msgstr "Автоматически сгенерировать аккаунт Cloudflare WARP и настроить все параметры AmneziaWG." - -msgid "Automatically increase check intervals when healthy (to 5 min) and decrease on problems (to 120s)." -msgstr "Автоматически увеличивает интервалы при стабильности (до 5 мин) и уменьшает при проблемах (до 120с)." - msgid "Automatically select the fastest node in the current level" msgstr "Автовыбор самого быстрого узла уровня" -msgid "Automatically update remote hosts lists on schedule" -msgstr "Автоматически обновлять удалённые списки хостов по расписанию" - msgid "Available actions" msgstr "Доступные действия" -msgid "Backend validation failed: %s" -msgstr "Ошибка валидации на бэкенде: %s" +msgid "Avg Latency" +msgstr "Ср. задержка" msgid "Bearer Auth Token" msgstr "Токен авторизации (Bearer)" -msgid "Belarus (by)" -msgstr "Беларусь (by)" - -msgid "BitTorrent / P2P" -msgstr "BitTorrent / P2P Торренты" - msgid "Bootstrap DNS" msgstr "Bootstrap DNS" -msgid "Bootstrap DNS Servers" -msgstr "Bootstrap DNS-серверы" - -msgid "Bot Status" -msgstr "Статус бота" - msgid "Browser FakeIP check could not be completed" msgstr "Не удалось выполнить проверку FakeIP в браузере" @@ -356,24 +146,6 @@ msgstr "Браузер использует FakeIP" msgid "Bug report downloaded" msgstr "Отчёт об ошибке загружен" -msgid "Built-in rule sets" -msgstr "Встроенные наборы правил" - -msgid "By flag emoji from name" -msgstr "По эмодзи флага из имени" - -msgid "ByeDPI listen address and port are assigned by Tachyon and must not be set in the strategy." -msgstr "Адрес и порт прослушивания ByeDPI назначаются Tachyon и не должны указываться в стратегии." - -msgid "ByeDPI option does not accept a compact value: %s" -msgstr "Опция ByeDPI не принимает компактное значение: %s" - -msgid "ByeDPI option does not accept a value: %s" -msgstr "Опция ByeDPI не принимает значение: %s" - -msgid "ByeDPI option requires a value: %s" -msgstr "Опция ByeDPI требует значение: %s" - msgid "ByeDPI package is installed" msgstr "Пакет ByeDPI установлен" @@ -392,93 +164,51 @@ msgstr "Outbound ByeDPI в sing-box настроен" msgid "ByeDPI sing-box outbound is not configured" msgstr "Outbound ByeDPI в sing-box не настроен" -msgid "ByeDPI Strategy" -msgstr "Стратегия ByeDPI" - -msgid "ByeDPI strategy cannot be empty" -msgstr "Стратегия ByeDPI не может быть пустой" - -msgid "Bypasses UDP traffic for selected game consoles (PS5/Xbox) to achieve NAT Type 1 / 2 (Full Cone NAT) for P2P matchmaking, while keeping TCP (PSN/Auth) routed through the proxy." -msgstr "Направляет UDP трафик выбранных консолей (PS5/Xbox) в обход прокси напрямую (Full Cone NAT) для идеального P2P матчмейкинга, оставляя TCP трафик (PSN/Auth) под защитой прокси." - -msgid "CA Certificate" -msgstr "CA сертификат" - -msgid "Cache all built-in lists and databases even if they are not currently selected in any section. Recommended if you have plenty of storage space or USB drive." -msgstr "Кешировать все встроенные списки и базы (даже если они не выбраны ни в одной секции). Рекомендуется при наличии свободного места или USB-накопителя." - -msgid "Cache File Path" -msgstr "Путь к файлу кэша" - -msgid "Cache file path cannot be empty" -msgstr "Путь к файлу кэша не может быть пустым" - -msgid "Cancel" -msgstr "Отмена" - msgid "Cannot receive checks result" msgstr "Не удалось получить результаты проверки" -msgid "Cannot save server" -msgstr "Не удалось сохранить сервер" +msgid "Check Again" +msgstr "Проверить снова" -msgid "Cannot save settings" -msgstr "Не удалось сохранить настройки" - -msgid "Cascade connection" -msgstr "Каскадное подключение" - -msgid "Certificate path" -msgstr "Путь к сертификату" - -msgid "Certificate pin is unavailable. Apply or restart the server to generate the default certificate, then open this dialog again." -msgstr "Пин сертификата недоступен. Примените или перезапустите сервер, чтобы сгенерировать дефолтный сертификат, затем откройте это окно снова." +msgid "Check All" +msgstr "Проверить все" msgid "Check Connection" msgstr "Проверить подключение" -msgid "Check Custom Domain" -msgstr "" +msgid "Check Custom" +msgstr "Проверить свой" + +msgid "Check domain or IP (e.g. example.com)..." +msgstr "Проверить домен или IP (напр. example.com)..." msgid "Check interval" msgstr "Интервал проверки" +msgid "Check Mode:" +msgstr "Режим проверки:" + msgid "Check Services" msgstr "" -msgid "Check timeout after which the server is considered dead" -msgstr "Таймаут проверки, после которого сервер считается недоступным" - msgid "Check update" msgstr "Проверить обновление" msgid "Check URL" msgstr "URL проверки" +msgid "Check YouTube" +msgstr "Проверить YouTube" + msgid "Checking Connection..." msgstr "Проверка соединения..." -msgid "Checking nftables filtering tables" -msgstr "" - -msgid "Checking sing-box service & DNSmasq" -msgstr "" - -msgid "Checking WAN interfaces & network routing" -msgstr "" - -msgid "Checking Zapret & ByeDPI rules" -msgstr "" - msgid "Checking, please wait" msgstr "Проверяем, пожалуйста подождите" msgid "Checking..." msgstr "Проверка..." -msgid "Checking…" -msgstr "Проверка…" - msgid "checks" msgstr "проверки" @@ -491,45 +221,9 @@ msgstr "Проверки пройдены" msgid "Checks passed with manual DHCP" msgstr "Проверки пройдены с ручным DHCP" -msgid "China (cn)" -msgstr "Китай (cn)" - -msgid "Choose Hosts File..." -msgstr "Выбрать hosts-файл..." - -msgid "Choose whether to route traffic to all destinations except selected countries (Exclude) or only to selected countries (Include)." -msgstr "Выберите, направлять ли трафик во все назначения кроме выбранных стран (Исключить) или только в выбранные страны (Включить)." - msgid "CIDR must be between 0 and 32 for IPv4 or 0 and 128 for IPv6" msgstr "CIDR должен быть от 0 до 32 для IPv4 или от 0 до 128 для IPv6" -msgid "Cipher" -msgstr "Шифрование" - -msgid "Clean Comments" -msgstr "Очистить комментарии" - -msgid "Clear" -msgstr "Сбросить" - -msgid "Client Certificate" -msgstr "Сертификат клиента" - -msgid "Client fingerprint" -msgstr "Отпечаток клиента" - -msgid "Client Key" -msgstr "Ключ клиента" - -msgid "Client link" -msgstr "Ссылка клиента" - -msgid "Client link is not available yet" -msgstr "Ссылка клиента пока недоступна" - -msgid "Client link QR code" -msgstr "QR-код клиентской ссылки" - msgid "Close" msgstr "Закрыть" @@ -542,66 +236,21 @@ msgstr "Закрыть подключение" msgid "Closed" msgstr "Закрытые" -msgid "Cloudflare account / device ID" -msgstr "ID аккаунта / устройства Cloudflare" - -msgid "Cloudflare API access token" -msgstr "Токен доступа Cloudflare API" - -msgid "Cloudflare WARP account / device ID" -msgstr "ID аккаунта / устройства Cloudflare WARP" - -msgid "Cloudflare WARP API access token" -msgstr "Токен доступа к API Cloudflare WARP" - -msgid "Comma-separated list of Telegram user IDs authorized to control the bot." -msgstr "Список ID пользователей Telegram через запятую, которым разрешено управлять ботом." - -msgid "Community Lists" -msgstr "Списки сообщества (Community Lists)" - msgid "Component update available" msgstr "Доступно обновление компонента" -msgid "Component update check interval" -msgstr "Период проверки обновлений" - -msgid "Components" -msgstr "Компоненты" - msgid "compressed" msgstr "compressed" -msgid "Concurrency" -msgstr "Параллелизм" - -msgid "Conditions" -msgstr "Условия" - -msgid "Config File Path" -msgstr "Путь к файлу конфигурации" - -msgid "Configuration for Tachyon service" -msgstr "Настройки сервиса Tachyon" - -msgid "Configure User-Agent in the item settings" -msgstr "Настройте User-Agent в настройках элемента" - msgid "Conflict" msgstr "Конфликт" msgid "Connect ChatGPT, DeepSeek or local LLM to get automated diagnostic reports and intelligent root-cause analysis." msgstr "Подключите ChatGPT, DeepSeek или локальную модель LLM для получения автоматических диагностических отчётов и умного анализа сетевых проблем." -msgid "Connect through" -msgstr "Подключаться через" - msgid "Connected" msgstr "Подключено" -msgid "Connection URL" -msgstr "URL подключения" - msgid "Connections are unavailable" msgstr "Подключения недоступны" @@ -620,84 +269,27 @@ msgstr "Скопировать ссылку прокси" msgid "Could not compare FakeIP and control public IPs" msgstr "Не удалось сравнить публичные IP FakeIP и контрольной проверки" -msgid "Country code (e.g. ru, us, de)" -msgstr "Код страны (например, ru, us, de)" - msgid "Current Diagnosis" msgstr "" -msgid "Current section cannot be used as its own transit section" -msgstr "Текущая секция не может быть транзитной для самой себя" - -msgid "Current section cannot download its own subscription" -msgstr "Текущая секция не может скачивать собственную подписку" - msgid "Currently unavailable" msgstr "Временно недоступно" msgid "Custom API Endpoint URL" msgstr "Пользовательский URL эндпоинта API" -msgid "Custom device headers" -msgstr "Кастомные заголовки устройства" - -msgid "Custom DNS Records (Hosts)" -msgstr "Пользовательские записи DNS (Hosts)" - -msgid "Custom domain (e.g. google.com)" -msgstr "" - -msgid "Custom OpenAI-Compatible API (OpenRouter)" -msgstr "" - -msgid "Custom OpenAI-compatible API endpoint URL (e.g. http://192.168.1.100:11434/v1/chat/completions)" -msgstr "" - -msgid "Custom outbound configurations in JSON format" -msgstr "Пользовательские конфигурации outbound в формате JSON" - -msgid "Dashboard" -msgstr "Дашборд" - msgid "Dashboard currently unavailable" msgstr "Дашборд сейчас недоступен" -msgid "Default (auto)" -msgstr "По умолчанию (авто)" - -msgid "Default address for checking server availability and latency. URLTest uses its own address." -msgstr "Адрес по умолчанию для проверки доступности и задержки серверов. Для URLTest используется собственный адрес." - -msgid "Delay in milliseconds before reloading Tachyon after interface UP" -msgstr "Задержка в миллисекундах перед перезапуском Tachyon после поднятия интерфейса" - -msgid "Delay value cannot be empty" -msgstr "Значение задержки не может быть пустым" - -msgid "Delete" -msgstr "Удалить" - -msgid "Detect server country" -msgstr "Определять страну сервера" - -msgid "Detects and drops STUN/TURN packets in nftables to prevent real IP leaks via WebRTC." -msgstr "Детектирует и отбрасывает пакеты STUN/TURN в nftables для предотвращения утечек реального IP-адреса через WebRTC." - msgid "detour must be a non-empty string" msgstr "detour должен быть непустой строкой" -msgid "Device filter" -msgstr "Фильтр устройств" - msgid "Device IPs (one per line):" msgstr "IP устройств (по одному на строку):" msgid "Device IPs saved" msgstr "IP устройств сохранены" -msgid "Device or IP" -msgstr "Устройство или IP" - msgid "Devices listed here are always routed through the assigned section, regardless of global rules." msgstr "Устройства из этого списка всегда маршрутизируются через назначенную секцию, независимо от глобальных правил." @@ -707,132 +299,24 @@ msgstr "DHCP содержит DNS сервер" msgid "DHCP is managed manually" msgstr "DHCP управляется вручную" -msgid "Diagnostics" -msgstr "Диагностика" - -msgid "Direct" -msgstr "Напрямую" - -msgid "Direct (Default)" -msgstr "Напрямую (по умолчанию)" - -msgid "Direct connection" -msgstr "Прямое подключение" - msgid "Disable autostart" msgstr "Отключить автостарт" -msgid "Disable QUIC" -msgstr "Отключить QUIC" - -msgid "Disable the QUIC protocol to improve compatibility or fix issues with video streaming" -msgstr "Отключить QUIC протокол для улучшения совместимости или исправления видео стриминга" - -msgid "Disabling interception is incompatible with action=zapret2 because Tachyon sends matched traffic through NFQUEUE." -msgstr "Отключение перехвата несовместимо с action=zapret2, так как Tachyon направляет совпадающий трафик через NFQUEUE." - -msgid "Display name" -msgstr "Отображаемое имя" - -msgid "DNS" -msgstr "DNS" - -msgid "DNS Check Interval" -msgstr "Период проверки DNS" - -msgid "DNS Check Interval (s)" -msgstr "Интервал проверки DNS (с)" - -msgid "DNS Failures Before Switching" -msgstr "Ошибок DNS перед переключением" - msgid "DNS on router" msgstr "DNS на роутере" -msgid "DNS over HTTPS (DoH)" -msgstr "DNS через HTTPS (DoH)" - -msgid "DNS over QUIC (DoQ)" -msgstr "DNS over QUIC (DoQ)" - -msgid "DNS over TLS (DoT)" -msgstr "DNS через TLS (DoT)" - -msgid "DNS protocol" -msgstr "DNS протокол" - -msgid "DNS Protocol Type" -msgstr "Тип протокола DNS" - -msgid "DNS protocol used by the resolver" -msgstr "Протокол DNS, используемый резолвером" - -msgid "DNS requests through section" -msgstr "DNS-запросы через секцию" - -msgid "DNS Rewrite TTL" -msgstr "Перезапись TTL для DNS" - -msgid "DNS server" -msgstr "DNS сервер" - msgid "DNS server address cannot be empty" msgstr "Адрес DNS-сервера не может быть пустым" -msgid "DNS server used by the resolver" -msgstr "DNS сервер, используемый резолвером" - -msgid "DNS server used to obtain IP addresses for upstream DNS and proxies. If multiple servers are selected, a timeout switches to a backup." -msgstr "DNS-сервер для получения IP вышестоящих DNS и прокси. Если выбрать несколько, то при таймауте произойдёт переключение на резервный." - -msgid "DNS Servers" -msgstr "DNS-серверы" - -msgid "DNS Settings" -msgstr "" - -msgid "DNS Strategy" -msgstr "Стратегия DNS" - -msgid "DNS Successful Checks Before Recovery" -msgstr "Успешных проверок DNS перед восстановлением" - -msgid "DNS through proxy" -msgstr "DNS через прокси" - -msgid "DNS through section" -msgstr "DNS через секцию" - msgid "DNS Turbo Cache" msgstr "Быстрый DNS-кэш" msgid "DNS Turbo Cache saved" msgstr "DNS Turbo Cache сохранён" -msgid "DNS Unavailability Timeout" -msgstr "Таймаут недоступности DNS" - msgid "Do not panic, everything can be fixed, just..." msgstr "Не паникуйте, всё можно исправить, просто..." -msgid "Do not test servers from these countries." -msgstr "Не тестировать серверы из этих стран." - -msgid "Do not test servers whose names match the expression." -msgstr "Не тестировать серверы, имена которых совпадают с выражением." - -msgid "Do not test servers with one of the selected protocols." -msgstr "Не тестировать серверы с одним из выбранных протоколов." - -msgid "Do not test servers with one of the selected security types." -msgstr "Не тестировать серверы с одним из выбранных типов безопасности." - -msgid "Do not test servers with one of the selected transports." -msgstr "Не тестировать серверы с одним из выбранных транспортов." - -msgid "Do not test specified servers." -msgstr "Не тестировать указанные серверы." - msgid "Doctor failed" msgstr "Доктор завершился с ошибкой" @@ -842,260 +326,35 @@ msgstr "Исправление доктором" msgid "Does not resolve" msgstr "Не резолвится" -msgid "Domain and IP lists" -msgstr "Списки доменов и IP" - -msgid "Domain lists" -msgstr "Списки доменов" - -msgid "Domain Resolver" -msgstr "Резолвер доменов" - -msgid "Domain test sections" -msgstr "Секции тестирования доменов" - -msgid "Domains" -msgstr "Домены (Domains)" - -msgid "Domains automatically detected by Smart Detect or added via Telegram bot. You can manually edit or remove them here." -msgstr "Домены, автоматически обнаруженные Smart Detect или добавленные через Telegram-бота. Вы можете вручную изменить или удалить их здесь." - -msgid "Done" -msgstr "Готово" - -msgid "Dont Touch My DHCP!" -msgstr "Отключить управление DHCP" - msgid "Downlink" msgstr "Входящий" msgid "Download" msgstr "Скачать" -msgid "Download component packages via the selected section" -msgstr "Скачивать пакеты компонентов через выбранную секцию" - -msgid "Download components through" -msgstr "Скачивать компоненты через" - -msgid "Download components through a section" -msgstr "Скачивать компоненты через секцию" - -msgid "Download lists through" -msgstr "Скачивать списки через" - -msgid "Download lists through a section" -msgstr "Скачивать списки через секцию" - -msgid "Download remote lists and rule sets via the selected section" -msgstr "Скачивать удаленные списки и наборы правил через выбранную секцию" - -msgid "Download subscription through a section" -msgstr "Скачивать подписку через секцию" - -msgid "Download subscriptions via the selected section" -msgstr "Скачивать подписки через выбранную секцию" - -msgid "Download through" -msgstr "Скачивать через" - msgid "Downloaded" msgstr "Загружено" -msgid "Drag rows to change priority. The rule at the top is checked first." -msgstr "Перетаскивайте строки, чтобы изменить приоритет. Правило сверху проверяется первым." - -msgid "DSCP marks (QoS)" -msgstr "DSCP-метки (QoS)" - msgid "Duplicate JSON outbound tag" msgstr "Такой тег JSON outbound уже используется" -msgid "Duplicate value" -msgstr "Дублирующееся значение" - -msgid "e.g. AES-256-GCM — leave empty for default" -msgstr "например AES-256-GCM — оставьте пустым для значения по умолчанию" - -msgid "e.g. google.com, 1.1.1.1, 443" -msgstr "например: google.com, 1.1.1.1, 443" - -msgid "e.g. SHA256 — leave empty for default" -msgstr "например SHA256 — оставьте пустым для значения по умолчанию" - -msgid "Edit rule action" -msgstr "Изменить" - -msgid "Enable" -msgstr "Включить" - -msgid "Enable Adaptive Intervals" -msgstr "Адаптивные интервалы" - -msgid "Enable AI Doctor (ChatGPT / LLM Analysis)" -msgstr "Включить AI Doctor (анализ через ChatGPT / LLM)" - msgid "Enable AI Doctor (LLM Integration)" msgstr "Включить AI Doctor (интеграция с LLM)" -msgid "Enable Anomaly Detection" -msgstr "Обнаружение аномалий" - -msgid "Enable authentication" -msgstr "Включить авторизацию" - -msgid "Enable automatic updates for remote lists and rule sets" -msgstr "Включить автоматическое обновление удалённых списков и наборов правил" - msgid "Enable autostart" msgstr "Включить автостарт" -msgid "Enable built-in DNS resolver for domains handled by this section" -msgstr "Включить встроенный DNS резолвер для доменов, обрабатываемых этой секцией" - -msgid "Enable Config Validation" -msgstr "Валидация конфига" - -msgid "Enable DNS Continuous Check" -msgstr "Непрерывная проверка DNS" - msgid "Enable DNS Turbo Cache" msgstr "Включить быстрый DNS-кэш" -msgid "Enable Firewall Reload Dedup" -msgstr "Дедупликация перезагрузки файрвола" - -msgid "Enable Graceful Degradation" -msgstr "Graceful Degradation" - -msgid "Enable Health Metrics" -msgstr "Метрики здоровья" - -msgid "Enable list updates" -msgstr "Включить обновление списков" - -msgid "Enable Mixed Proxy" -msgstr "Включить смешанный прокси" - -msgid "Enable Mixed Proxy Authentication" -msgstr "Включить аутентификацию смешанного прокси" - -msgid "Enable Output Network Interface" -msgstr "Включить выходной сетевой интерфейс" - -msgid "Enable Proxy Health Monitor" -msgstr "Мониторинг здоровья прокси" - -msgid "Enable Smart Cooldowns" -msgstr "Smart Cooldowns" - msgid "Enable Smart Detect" msgstr "Включить Smart Detect" -msgid "Enable Telegram Bot" -msgstr "Включить Telegram-бота" - -msgid "Enable WAN DNS Fallback for Bootstrap DNS" -msgstr "Разрешить резервный WAN DNS для Bootstrap DNS" - -msgid "Enable WAN DNS Fallback for Main DNS" -msgstr "Разрешить резервный WAN DNS для Main DNS" - -msgid "Enable Watchdog" -msgstr "Включить сторожевой таймер (Watchdog)" - -msgid "Enable YACD" -msgstr "Включить YACD" - -msgid "Enable YACD WAN Access" -msgstr "Включить доступ YACD WAN" - -msgid "Enables the background daemon that polls Telegram for commands and sends notifications." -msgstr "Включает фоновый процесс, который опрашивает Telegram на наличие команд и отправляет уведомления." - -msgid "Enables the background watchdog process to monitor services and auto-recover on failures." -msgstr "Включает фоновый процесс watchdog для мониторинга служб и автоматического восстановления при сбоях." - -msgid "Enter a complete sing-box inbound object" -msgstr "Введите полный объект inbound sing-box" - -msgid "Enter a complete sing-box outbound object" -msgstr "Введите полный объект outbound для sing-box" - -msgid "Enter a display name" -msgstr "Введите отображаемое имя" - -msgid "Enter a level name" -msgstr "Введите название уровня" - -msgid "Enter HWID" -msgstr "Введите HWID" - -msgid "Enter the API token obtained from @BotFather." -msgstr "Введите токен API, полученный от @BotFather." - -msgid "Enter the HWID sent with subscription requests" -msgstr "Введите HWID, отправляемый с запросами подписки" - -msgid "Enter the subscription URL" -msgstr "Введите URL подписки" - -msgid "Error" -msgstr "Ошибка" - -msgid "Error running generator:" -msgstr "Ошибка запуска генератора:" - -msgid "Error running trace:" -msgstr "Ошибка при выполнении трассировки:" - -msgid "Exclude by proxy parameters" -msgstr "Исключить по параметрам прокси" - -msgid "Exclude by regular expression" -msgstr "Исключить по регулярному выражению" - -msgid "Exclude countries" -msgstr "Исключить страны" - -msgid "Exclude selected countries" -msgstr "Исключить выбранные страны" - -msgid "Exclude servers" -msgstr "Исключить серверы" - -msgid "Exclude servers with one of the selected protocols from this level." -msgstr "Исключить с этого уровня серверы с одним из выбранных протоколов." - -msgid "Exclude servers with one of the selected security types from this level." -msgstr "Исключить с этого уровня серверы с одним из выбранных типов безопасности." - -msgid "Exclude servers with one of the selected transports from this level." -msgstr "Исключить с этого уровня серверы с одним из выбранных транспортов." - -msgid "Exclude traffic types" -msgstr "Исключать типы трафика" - -msgid "Exclude URLTest / Priority group" -msgstr "Исключить URLTest / группу приоритетов" - -msgid "Excluded devices" -msgstr "Исключённые устройства" - -msgid "Expecting: %s" -msgstr "Ожидается: %s" - msgid "Expires" msgstr "Истекает" -msgid "Expose this section as a local HTTP+SOCKS proxy" -msgstr "Предоставить эту секцию как локальный HTTP+SOCKS прокси" - -msgid "External nfqws config files bypass Tachyon queue management and explicit validation." -msgstr "Внешние файлы конфигурации nfqws обходят управление очередями Tachyon и явную валидацию." - -msgid "External nfqws2 config files bypass Tachyon queue management and explicit validation." -msgstr "Внешние файлы конфигурации nfqws2 обходят управление очередями Tachyon и явную валидацию." +msgid "Failed" +msgstr "Ошибки" msgid "Failed to apply fix" msgstr "" @@ -1112,23 +371,17 @@ msgstr "Не удалось скопировать!" msgid "Failed to execute" msgstr "Не удалось выполнить" -msgid "Failed to execute service check." -msgstr "" - msgid "Failed to generate bug report" msgstr "Не удалось создать отчёт об ошибке" -msgid "Failed to generate WARP config:" -msgstr "Не удалось создать конфиг WARP:" +msgid "Failed to parse target list." +msgstr "Ошибка обработки списка целей." -msgid "Failed to parse file:" -msgstr "Не удалось разобрать файл:" +msgid "Failed to receive response from AI service." +msgstr "Не удалось получить ответ от ИИ-сервиса." -msgid "Failed to parse service check results." -msgstr "" - -msgid "Failed to parse WARP config:" -msgstr "Не удалось разобрать конфиг WARP:" +msgid "Failed to run service check." +msgstr "Не удалось выполнить проверку сервисов." msgid "Failed to save AI Watchdog settings" msgstr "Ошибка сохранения настроек AI Watchdog" @@ -1142,18 +395,6 @@ msgstr "Не удалось сохранить DNS Turbo Cache" msgid "Failed to save Smart Detect settings" msgstr "Ошибка сохранения настроек Smart Detect" -msgid "Failed to start bot" -msgstr "Ошибка запуска бота" - -msgid "Failed to start watchdog" -msgstr "Ошибка запуска watchdog" - -msgid "Failed to stop bot" -msgstr "Ошибка остановки бота" - -msgid "Failed to stop watchdog" -msgstr "Ошибка остановки watchdog" - msgid "Failed to update subscriptions" msgstr "Не удалось обновить подписки" @@ -1166,108 +407,33 @@ msgstr "FakeIP и контрольная проверка используют msgid "FakeIP works; public IP comparison is inconclusive" msgstr "FakeIP работает; сравнение публичных IP не дает однозначного результата" -msgid "FakeTLS host" -msgstr "FakeTLS-хост" - -msgid "Fallback on unknown DC" -msgstr "Fallback для неизвестного DC" - -msgid "Faster DNS health monitoring than the default cycle. Switches bootstrap DNS on failure." -msgstr "Быстрый мониторинг DNS по умолчанию. Переключает bootstrap DNS при сбое." - msgid "Faster server search interval" msgstr "Интервал поиска более быстрого сервера" msgid "Fastest" msgstr "Самый быстрый" -msgid "Fetching service status, please wait..." -msgstr "" - -msgid "Filter the servers that will be displayed on the dashboard." -msgstr "Фильтровать серверы, отображаемые на дашборде." - -msgid "Finland (fi)" -msgstr "Финляндия (fi)" +msgid "Fetching service targets..." +msgstr "Получение списка сервисов..." msgid "Firewall WAN port" msgstr "Порт в firewall для WAN" -msgid "Fix All" -msgstr "" - msgid "Fix applied" msgstr "" -msgid "Fix the highlighted fields and save again." -msgstr "Исправьте подсвеченные поля и сохраните снова." - msgid "Fixed" msgstr "Исправлено" -msgid "Forced device routing" -msgstr "Принудительная маршрутизация устройств" - -msgid "Forces sing-box to tunnel DNS requests via DoQ with Encrypted Client Hello (ECH) for SNI hiding." -msgstr "Принудительно направляет DNS-запросы через DoQ с Encrypted Client Hello (ECH) для скрытия SNI." - -msgid "France (fr)" -msgstr "Франция (fr)" - -msgid "Fronting IP" -msgstr "IP фронтинга" - -msgid "Fronting port" -msgstr "Порт фронтинга" - -msgid "Fronting proxy protocol" -msgstr "Proxy protocol для фронтинга" - -msgid "Fuzzing is not supported here because Tachyon needs deterministic runtime validation." -msgstr "Фаззинг здесь не поддерживается, так как Tachyon требует детерминированной валидации во время выполнения." - -msgid "Game Console IPs" -msgstr "IP-адреса игровых консолей" - -msgid "Game Console Optimizer (NAT Type 1)" -msgstr "Оптимизатор игровых консолей (NAT Type 1)" - -msgid "Generate a random 16-character hexadecimal HWID" -msgstr "Сгенерировать случайный 16-символьный шестнадцатеричный HWID" +msgid "Full System Diagnostic" +msgstr "Полная диагностика" msgid "Generate bug report" msgstr "Сгенерировать баг-репорт" -msgid "Generate HWID" -msgstr "Сгенерировать HWID" - -msgid "Generate HWID from router hardware information for this subscription" -msgstr "Генерировать HWID из аппаратной информации роутера для этой подписки" - -msgid "Generate WARP Config" -msgstr "Сгенерировать конфиг WARP" - msgid "Generated inbound" msgstr "Созданный inbound" -msgid "Generated!" -msgstr "Сгенерировано!" - -msgid "Generating…" -msgstr "Генерация…" - -msgid "GeoIP Countries" -msgstr "Страны для фильтрации GeoIP" - -msgid "GeoIP Mode" -msgstr "Режим фильтрации GeoIP" - -msgid "GeoSite / GeoIP" -msgstr "GeoSite / GeoIP" - -msgid "Germany (de)" -msgstr "Германия (de)" - msgid "GET endpoints are open on LAN. POST endpoints require Authorization: Bearer ." msgstr "GET-эндпоинты открыты в локальной сети. POST-эндпоинты требуют Authorization: Bearer ." @@ -1277,47 +443,11 @@ msgstr "Получить глобальную проверку" msgid "Global check" msgstr "Глобальная проверка" -msgid "gRPC service" -msgstr "gRPC-сервис" - -msgid "Handshake timeout" -msgstr "Таймаут рукопожатия" - msgid "Health Checks" msgstr "Проверки здоровья" -msgid "Hide cascade connection nodes" -msgstr "Скрыть узлы каскадных подключений" - -msgid "Hide individual nodes that are already included in imported subscription URLTest groups" -msgstr "Скрыть отдельные узлы, уже включённые в импортированные группы URLTest подписки" - -msgid "Hide intermediate nodes used as detours by other subscription nodes" -msgstr "Скрыть промежуточные узлы, используемые как транзиты другими узлами подписки" - -msgid "Hide selected servers." -msgstr "Скрыть выбранные серверы." - -msgid "Hide servers from selected groups without repeating their filtering criteria." -msgstr "Скрыть серверы из выбранных групп без повторения их критериев фильтрации." - -msgid "Hide servers from the specified countries." -msgstr "Скрыть серверы из указанных стран." - -msgid "Hide servers whose names match the expression." -msgstr "Скрыть серверы, имена которых совпадают с выражением." - -msgid "Hide servers with one of the selected protocols." -msgstr "Скрыть серверы с одним из выбранных протоколов." - -msgid "Hide servers with one of the selected security types." -msgstr "Скрыть серверы с одним из выбранных типов безопасности." - -msgid "Hide servers with one of the selected transports." -msgstr "Скрыть серверы с одним из выбранных транспортов." - -msgid "Hide URLTest group nodes" -msgstr "Скрыть узлы группы URLTest" +msgid "Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings." +msgstr "Привет! Я ИИ-ассистент Tachyon. Чем могу помочь? Задайте вопрос о блокировках, диагностике или настройках роутера." msgid "Hide values" msgstr "Скрывать значения" @@ -1325,135 +455,24 @@ msgstr "Скрывать значения" msgid "Higher-level check interval" msgstr "Интервал проверки высших уровней" -msgid "Higher-priority DNS Check" -msgstr "Проверка верхних DNS" +msgid "History" +msgstr "" msgid "Host" msgstr "Хост" -msgid "Hosts" -msgstr "Хосты" - -msgid "Hosts Lists Update Interval" -msgstr "Интервал обновления списков хостов" - -msgid "How many hours of metrics to keep (default 24)." -msgstr "Сколько часов хранить метрики (по умолчанию 24)." - -msgid "How often higher priority levels are checked while a lower level is active" -msgstr "Как часто проверяются уровни с более высоким приоритетом, пока активен уровень с более низким" - -msgid "How often the currently selected server is checked" -msgstr "Как часто проверяется текущий выбранный сервер" - -msgid "How often to check DNS health in seconds (default 60)." -msgstr "Как часто проверять DNS в секундах (по умолчанию 60)." - -msgid "How often to check proxy health in seconds (fast tier, default 30)." -msgstr "Как часто проверять прокси в секундах (быстрый тир, по умолчанию 30)." - -msgid "How often to check Telegram for new messages (default: 5)." -msgstr "Как часто проверять Telegram на наличие новых сообщений (по умолчанию: 5)." - -msgid "How often to check the active DNS servers." -msgstr "Как часто проверять активные DNS-серверы." - -msgid "How often to check whether a higher-priority DNS server has recovered." -msgstr "Как часто проверять, восстановился ли DNS-сервер с более высоким приоритетом." - msgid "HTTP" msgstr "HTTP" -msgid "HTTP (ms)" -msgstr "" - msgid "HTTP error" msgstr "Ошибка HTTP" -msgid "HTTP hosts" -msgstr "HTTP-хосты" - msgid "HTTP REST API for external AI agents (Claude, GPT, Open-WebUI) served at /cgi-bin/tachyon-agent/" msgstr "HTTP REST API для внешних ИИ-агентов (Claude, GPT, Open-WebUI), доступен по адресу /cgi-bin/tachyon-agent/" -msgid "HWID" -msgstr "HWID" - msgid "Idle timeout" msgstr "Таймаут простоя" -msgid "If one health check fails with an error, continue running other checks instead of stopping." -msgstr "Если одна проверка падает с ошибкой, продолжает другие проверки вместо остановки." - -msgid "Import" -msgstr "Импортировать" - -msgid "Import (%d records)" -msgstr "Импортировать (%d записей)" - -msgid "Import AmneziaWG settings from .conf file" -msgstr "Импортировать настройки AmneziaWG из файла .conf" - -msgid "Import Hosts File" -msgstr "Импортировать hosts-файл" - -msgid "Import subscription URLTest groups" -msgstr "Импортировать группы URLTest подписки" - -msgid "Import URLTest groups returned by this subscription provider" -msgstr "Импортировать группы URLTest, возвращаемые этим провайдером подписок" - -msgid "Inbound JSON" -msgstr "Inbound JSON" - -msgid "Inbound JSON cannot be empty" -msgstr "Inbound JSON не может быть пустым" - -msgid "Inbound JSON must be an object with a type field" -msgstr "Inbound JSON должен быть объектом с полем type" - -msgid "Include by proxy parameters" -msgstr "Включить по параметрам прокси" - -msgid "Include by regular expression" -msgstr "Включить по регулярному выражению" - -msgid "Include countries" -msgstr "Включить страны" - -msgid "Include IP addresses and subnets" -msgstr "Включить IP-адреса и подсети" - -msgid "Include selected countries" -msgstr "Включить выбранные страны" - -msgid "Include servers" -msgstr "Включить серверы" - -msgid "Information" -msgstr "Информация" - -msgid "Init Packet Magic Header (S1)" -msgstr "Magic Header: Инициализация (S1)" - -msgid "Init Packet Magic Header (S3)" -msgstr "Magic Header: Инициализация (S3)" - -msgid "Init Packet Payload (I1)" -msgstr "Payload: Инициализация (I1)" - -msgid "Init Packet Payload (I2)" -msgstr "Payload: Инициализация (I2)" - -msgid "Init Packet Payload (I3)" -msgstr "Payload: Инициализация (I3)" - -msgid "Init Packet Payload (I4)" -msgstr "Payload: Инициализация (I4)" - -msgid "Init Packet Payload (I5)" -msgstr "Payload: Инициализация (I5)" - msgid "Install" msgstr "Установить" @@ -1466,30 +485,12 @@ msgstr "Установленная сборка → Доступная сбор msgid "Installed version is newer than release" msgstr "Установлена версия новее релиза" -msgid "Interface Monitoring" -msgstr "Мониторинг интерфейса" - -msgid "Interface Monitoring Delay" -msgstr "Задержка при мониторинге интерфейсов" - -msgid "Interface monitoring for Bad WAN" -msgstr "Мониторинг интерфейса для Bad WAN" - msgid "Interrupt connections" msgstr "Прерывать соединения" -msgid "Interrupt connections when priority failover switches server" -msgstr "Прерывать соединения при переключении сервера в режиме приоритета" - -msgid "Interrupt connections when URLTest switches the selected server" -msgstr "Прерывать соединения при переключении URLTest на другой сервер" - msgid "Interval" msgstr "Интервал" -msgid "Invalid ByeDPI strategy" -msgstr "Некорректная стратегия ByeDPI" - msgid "Invalid CIDR prefix" msgstr "Неверный префикс CIDR" @@ -1553,21 +554,12 @@ msgstr "Неверный IP-адрес" msgid "Invalid JSON format" msgstr "Неверный формат JSON" -msgid "Invalid line: \"%s\". Use: domain ip or ip domain" -msgstr "Неверная строка: \"%s\". Формат: домен ip или ip домен" - msgid "Invalid path format. Path must start with \"/\" and contain valid characters" msgstr "Неверный формат пути. Должен начинаться с \"/\" и содержать допустимые символы" msgid "Invalid port number. Must be between 1 and 65535" msgstr "Неверный номер порта. Допустимо от 1 до 65535" -msgid "Invalid port or range. Use 80 or 1000-2000" -msgstr "Некорректный порт или диапазон. Используйте 80 или 1000-2000" - -msgid "Invalid regular expression" -msgstr "Некорректное регулярное выражение" - msgid "Invalid Shadowsocks URL: decoded credentials must contain method:password" msgstr "Неверный URL Shadowsocks: декодированные данные должны содержать method:password" @@ -1691,36 +683,12 @@ msgstr "Неверный URL VLESS: ошибка разбора" msgid "Invalid VMess URL: parsing failed" msgstr "Некорректный VMess URL: ошибка разбора" -msgid "IP / DNS" -msgstr "" - -msgid "IP Addresses (IP CIDR)" -msgstr "IP-адреса и подсети (IP CIDR)" - -msgid "IPs" -msgstr "IP-адреса" - -msgid "IPv4 only" -msgstr "Только IPv4" - -msgid "IPv6 only" -msgstr "Только IPv6" - -msgid "Isolate BitTorrent traffic and force it direct to prevent VPN bans" -msgstr "Изолировать BitTorrent-трафик и направлять напрямую во избежание банов VPN" - msgid "Issues" msgstr "Проблемы" msgid "Issues detected" msgstr "Обнаружены проблемы" -msgid "Japan (jp)" -msgstr "Япония (jp)" - -msgid "JSON outbound" -msgstr "JSON outbound" - msgid "JSON outbound cannot be empty" msgstr "JSON outbound не может быть пустым" @@ -1733,102 +701,27 @@ msgstr "JSON outbound должен содержать непустое поле msgid "JSON outbound must contain a non-empty type field" msgstr "JSON outbound должен содержать непустое поле type" -msgid "JSON outbound settings" -msgstr "Настройки JSON outbound" - -msgid "Junk Max Size (Jmax)" -msgstr "Макс. размер Junk (Jmax)" - -msgid "Junk Min Size (Jmin)" -msgstr "Мин. размер Junk (Jmin)" - -msgid "Junk Packet Count (Jc)" -msgstr "Количество Junk-пакетов (Jc)" - -msgid "Kazakhstan (kz)" -msgstr "Казахстан (kz)" - -msgid "Keep Priority before latency-sorted servers" -msgstr "Держать Priority перед серверами, отсортированными по задержке" - -msgid "Keep URLTest before latency-sorted servers" -msgstr "Держать URLTest перед серверами, отсортированными по задержке" - msgid "Keeps FakeIP cache persistent across reboots and pre-resolves popular blocked domains on startup so first-visit latency is 0 ms." msgstr "Сохраняет FakeIP-кэш между перезагрузками и заранее резолвит популярные заблокированные домены при старте — задержка при первом визите 0 мс." -msgid "Key" -msgstr "Ключ" - -msgid "Key path" -msgstr "Путь к ключу" - -msgid "Keyword must not contain spaces or commas" -msgstr "Ключевое слово не должно содержать пробелы или запятые" - -msgid "Language for AI Doctor diagnosis responses" -msgstr "" - msgid "Latency test failed" msgstr "Проверка задержки не удалась" -msgid "Latency test URL" -msgstr "URL для проверки задержки" - msgid "Latest version is installed" msgstr "Установлена последняя версия" msgid "Latest version:" msgstr "Последняя версия:" -msgid "Leave empty to omit this header" -msgstr "Оставьте пустым, чтобы опустить этот заголовок" - msgid "Level" msgstr "Уровень" -msgid "Level name" -msgstr "Название уровня" - -msgid "List must be an HTTP(S) URL or a local .lst path" -msgstr "Список должен быть HTTP(S) URL или локальным путём .lst" - -msgid "List of domains automatically detected and the section they were added to. To edit or remove them, open the routing rules of the respective section." -msgstr "Список автоматически обнаруженных доменов и секций, в которые они были добавлены. Чтобы изменить или удалить их, откройте правила маршрутизации соответствующей секции." - -msgid "List Update Frequency" -msgstr "Частота обновления списков" - -msgid "Listen address" -msgstr "Адрес прослушивания" - -msgid "Listen port" -msgstr "Порт прослушивания" - msgid "Listening port" msgstr "Слушающий порт" msgid "LM Studio (Local PC / Server)" msgstr "" -msgid "Load .conf" -msgstr "Загрузить .conf" - -msgid "Load .conf config" -msgstr "Загрузить конфиг .conf" - -msgid "Load Current Records" -msgstr "Загрузить текущие записи" - -msgid "Loaded %d current record(s)" -msgstr "Загружено %d текущих записей" - -msgid "Loaded!" -msgstr "Загружено!" - -msgid "Loading client link..." -msgstr "Загрузка клиентской ссылки..." - msgid "Loading connections" msgstr "Загрузка подключений" @@ -1838,120 +731,24 @@ msgstr "Загрузка..." msgid "Loading…" msgstr "Загрузка…" -msgid "Local Address" -msgstr "Локальный адрес" - -msgid "Log Level" -msgstr "Уровень логов" - msgid "lx" msgstr "lx" msgid "Main DNS" msgstr "Основной DNS" -msgid "Main DNS server. If multiple servers are selected, a timeout switches to a backup." -msgstr "Основной DNS-сервер. Если выбрать несколько, то при таймауте произойдёт переключение на резервный." - -msgid "MASQUE Access Token" -msgstr "Токен доступа MASQUE" - -msgid "MASQUE Account ID" -msgstr "ID аккаунта MASQUE" - -msgid "MASQUE Private Key" -msgstr "Приватный ключ MASQUE" - -msgid "Match destination IPs or subnets" -msgstr "Совпадение по IP или подсети назначения" - -msgid "Match destination ports. Use a single port or a range" -msgstr "Совпадение по портам назначения. Используйте один порт или диапазон" - -msgid "Match Found" -msgstr "Совпадение найдено" - -msgid "Match traffic by packet DSCP mark (assigned in Windows via Policy-Based QoS). Examples: 46 (EF), 0x2e, 34 (AF41)" -msgstr "Сопоставление трафика по DSCP-метке пакета (назначается в Windows через Policy-Based QoS). Примеры: 46 (EF), 0x2e, 34 (AF41)" - -msgid "Max reconnects per hour before alert (default 10)." -msgstr "Макс. переподключений в час перед алертом (по умолчанию 10)." - -msgid "Maximum time to wait for example.com to resolve during a DNS health check." -msgstr "Максимальное время ожидания разрешения example.com при проверке доступности DNS." - msgid "Memory Usage" msgstr "Использование памяти" -msgid "Method" -msgstr "Метод" - -msgid "Metrics Retention (hours)" -msgstr "Хранение метрик (часов)" - -msgid "Minimum latency difference in milliseconds that triggers switching to a faster server." -msgstr "Минимальная разница в задержке (мс), при которой происходит переключение на более быстрый сервер." - -msgid "Mixed Proxy Password" -msgstr "Пароль смешанного прокси" - -msgid "Mixed Proxy Port" -msgstr "Порт смешанного прокси" - -msgid "Mixed Proxy Username" -msgstr "Имя пользователя смешанного прокси" - -msgid "Model name to use. Leave empty to use default (gpt-4o-mini / claude-3-5-haiku / deepseek-chat / llama3:latest)." -msgstr "" - -msgid "Monitored Interfaces" -msgstr "Наблюдаемые интерфейсы" - -msgid "Monitoring" -msgstr "Мониторинг" - msgid "Monitoring & Analytics" msgstr "Мониторинг и аналитика" -msgid "Monitors sing-box reconnect frequency. Alerts if too many reconnects per hour." -msgstr "Мониторит частоту переподключений sing-box. Уведомляет при превышении лимита." - msgid "Move down" msgstr "Вниз" msgid "Move up" msgstr "Вверх" -msgid "MTU" -msgstr "MTU" - -msgid "Must be a comma-separated list of numeric IDs" -msgstr "Должен быть список числовых ID через запятую" - -msgid "Must be a number in the range of 0 - 10000" -msgstr "Должно быть числом в диапазоне от 0 до 10000" - -msgid "Name displayed on the dashboard" -msgstr "Имя, отображаемое на дашборде" - -msgid "Name shown in the priority level list" -msgstr "Имя, отображаемое в списке уровней приоритета" - -msgid "Netherlands (nl)" -msgstr "Нидерланды (nl)" - -msgid "Network & Interfaces" -msgstr "" - -msgid "Network Interface" -msgstr "Сетевой интерфейс" - -msgid "Network interface settings" -msgstr "Настройки сетевого интерфейса" - -msgid "New domains:" -msgstr "Новых доменов:" - msgid "New version %s is available for %s" msgstr "Доступна новая версия %s для %s" @@ -1961,18 +758,6 @@ msgstr "Диапазон NFQUEUE свободен" msgid "NFQUEUE range overlaps with another rule" msgstr "Диапазон NFQUEUE пересекается с другим правилом" -msgid "NFQWS Strategy" -msgstr "Стратегия NFQWS" - -msgid "NFQWS strategy cannot be empty" -msgstr "Стратегия NFQWS не может быть пустой" - -msgid "NFQWS2 Strategy" -msgstr "Стратегия NFQWS2" - -msgid "NFQWS2 strategy cannot be empty" -msgstr "Стратегия NFQWS2 не может быть пустой" - msgid "No" msgstr "Нет" @@ -1991,24 +776,12 @@ msgstr "Нет закрытых подключений" msgid "No conflict detected" msgstr "Конфликт не обнаружен" -msgid "No Custom Rules Matched" -msgstr "Пользовательские правила не совпали" - msgid "No diagnostic history available yet." msgstr "" -msgid "No domains detected yet" -msgstr "Домены пока не обнаружены" - -msgid "No domains found to check." -msgstr "" - msgid "No enabled server inbounds configured" msgstr "Включённые серверные inbounds не настроены" -msgid "No file selected" -msgstr "Файл не выбран" - msgid "No issues found" msgstr "Проблем не обнаружено" @@ -2030,15 +803,15 @@ msgstr "Нет правил, использующих Zapret" msgid "No rules use Zapret2" msgstr "Нет правил, использующих Zapret2" +msgid "No targets found in section configs." +msgstr "Цели в конфигурациях секций не найдены." + msgid "Node list is empty" msgstr "Список узлов пуст" msgid "Nodes" msgstr "Узлы" -msgid "None" -msgstr "Нет" - msgid "Not configured" msgstr "Не настроено" @@ -2066,78 +839,12 @@ msgstr "Не отвечает" msgid "Not running" msgstr "Не запущено" -msgid "Not set" -msgstr "Не заданы" - -msgid "Notify on Certificate Warnings" -msgstr "Уведомлять о предупреждениях сертификатов" - -msgid "Notify on Core Crashes" -msgstr "Уведомлять о сбоях ядра" - -msgid "Notify on DNS Leaks" -msgstr "Уведомлять об утечках DNS" - -msgid "Notify on Server Switches" -msgstr "Уведомлять о переключениях серверов" - -msgid "Notify on Service Restarts" -msgstr "Уведомлять о перезапусках службы" - -msgid "Notify on Subscription Updates" -msgstr "Уведомлять об обновлениях подписок" - -msgid "Number of consecutive failed checks required before switching DNS servers." -msgstr "Количество последовательных неудачных проверок, необходимое для переключения DNS-сервера." - -msgid "Number of consecutive failures before restarting (default 3)." -msgstr "Количество последовательных сбоев перед перезапуском (по умолчанию 3)." - -msgid "Number of consecutive successful checks required before returning to a higher-priority DNS server." -msgstr "Количество последовательных успешных проверок, необходимое для возврата к DNS-серверу с более высоким приоритетом." - -msgid "Obfuscation" -msgstr "Обфускация" - -msgid "Obfuscation password" -msgstr "Пароль обфускации" - msgid "Ollama (Local PC / Server)" msgstr "" -msgid "One record per line: example.com 192.168.1.100 or 192.168.1.100 example.com. Lines starting with # are ignored." -msgstr "По одной записи на строку: example.com 192.168.1.100 или 192.168.1.100 example.com. Строки, начинающиеся с #, игнорируются." - -msgid "Only from the specified countries." -msgstr "Только из указанных стран." - -msgid "Only selected" -msgstr "Только выбранные" - -msgid "Only selected except exclusions" -msgstr "Только выбранные, кроме исключений" - -msgid "Only servers whose names match the expression." -msgstr "Только серверы, имена которых совпадают с выражением." - -msgid "Only servers with one of the selected protocols." -msgstr "Только серверы с одним из выбранных протоколов." - -msgid "Only servers with one of the selected security types." -msgstr "Только серверы с одним из выбранных типов безопасности." - -msgid "Only servers with one of the selected transports." -msgstr "Только серверы с одним из выбранных транспортов." - -msgid "Only the specified servers." -msgstr "Только указанные серверы." - msgid "Open" msgstr "Открыть" -msgid "Open priority settings and enter a display name" -msgstr "Откройте настройки приоритета и введите отображаемое имя" - msgid "Open Project Page" msgstr "Открыть страницу проекта" @@ -2147,308 +854,65 @@ msgstr "Время ожидания истекло" msgid "Optimization" msgstr "Оптимизация" -msgid "Option \"%s\" contains an invalid input value." -msgstr "Параметр \"%s\" содержит недопустимое значение." - -msgid "Optional — leave empty for default" -msgstr "Опционально — оставьте пустым для значения по умолчанию" - msgid "Optional for local LLM" msgstr "" -msgid "Optional tls-auth or tls-crypt key" -msgstr "Опциональный ключ tls-auth или tls-crypt" - -msgid "Optional values must be attached with '=' here; a separate token would be ignored by nfqws." -msgstr "Опциональные значения должны быть указаны через '=' здесь; отдельный токен будет проигнорирован nfqws." - -msgid "Optional values must be attached with '=' here; a separate token would be ignored by nfqws2." -msgstr "Опциональные значения должны быть указаны через '=' здесь; отдельный токен будет проигнорирован nfqws2." - -msgid "Or paste hosts file content:" -msgstr "Или вставьте содержимое hosts-файла:" - -msgid "Outbound" -msgstr "" +msgid "Outbound Route" +msgstr "Маршрут" msgid "outbounds must be a non-empty array of strings" msgstr "outbounds должен быть непустым массивом строк" -msgid "Output Network Interface" -msgstr "Выходной сетевой интерфейс" - -msgid "Override the default OpenWrt device headers for this subscription" -msgstr "Переопределить стандартные заголовки OpenWrt для этой подписки" - -msgid "Overwrite existing records (if unchecked, merge with existing records)" -msgstr "Перезаписать существующие записи (если сброшено — объединить)" - -msgid "P2P Leak Protection" -msgstr "Изоляция торрент-трафика (P2P)" - -msgid "Padding" -msgstr "Padding" - -msgid "Parsed records:" -msgstr "Распознано записей:" - -msgid "Password" -msgstr "Пароль" - -msgid "Password cannot be empty" -msgstr "Пароль не может быть пустым" - -msgid "Paste content or upload a file to preview imported DNS records." -msgstr "Вставьте содержимое или загрузите файл для предварительного просмотра." +msgid "Passed" +msgstr "Успешно" msgid "Path cannot be empty" msgstr "Путь не может быть пустым" -msgid "Path must be absolute (start with /)" -msgstr "Путь должен быть абсолютным (начинаться с /)" - -msgid "Path must contain at least one directory (like /tmp/cache.db)" -msgstr "Путь должен содержать хотя бы одну директорию (например /tmp/cache.db)" - -msgid "Path must end with cache.db" -msgstr "Путь должен заканчиваться на cache.db" - msgid "Pause updates" msgstr "Приостановить обновление" -msgid "Peer Public Key" -msgstr "Публичный ключ пира" - -msgid "PEM-encoded CA certificate" -msgstr "CA сертификат в формате PEM" - -msgid "PEM-encoded client certificate" -msgstr "Клиентский сертификат в формате PEM" - -msgid "PEM-encoded client private key" -msgstr "Приватный ключ клиента в формате PEM" - msgid "Pending" msgstr "Ожидает запуска" msgid "Per-Device Routing" msgstr "Маршрутизация по устройствам" -msgid "Periodically check the current level and switch to a faster server even when the current one works." -msgstr "Периодически проверять текущий уровень и переключаться на более быстрый сервер, даже если текущий работает." - -msgid "Periodically checks if the proxy is responding. Restarts Tachyon after consecutive failures." -msgstr "Периодически проверяет работоспособность прокси. Перезапускает Tachyon после последовательных сбоев." - -msgid "Persistent Keepalive" -msgstr "Persistent Keepalive" - -msgid "Persistent Smart Detect" -msgstr "Persistent Smart Detect" - -msgid "Pin on dashboard" -msgstr "Закрепить на дашборде" - -msgid "Polling Interval (seconds)" -msgstr "Интервал опроса (секунды)" - -msgid "Polling interval must be at least 1 second" -msgstr "Интервал опроса должен быть не менее 1 секунды" - -msgid "Port cannot be empty" -msgstr "Порт не может быть пустым" - msgid "Port conflict" msgstr "Конфликт порта" -msgid "Port for the local mixed proxy of this section" -msgstr "Порт локального смешанного прокси этой секции" - -msgid "Port must be between 1 and 65535" -msgstr "Порт должен быть от 1 до 65535" - -msgid "Port range start must be less than or equal to end" -msgstr "Начало диапазона портов должно быть меньше или равно концу" - -msgid "Ports" -msgstr "Порты" - -msgid "Pre-download all preset lists" -msgstr "Скачивать все предустановленные списки" - -msgid "Pre-shared key" -msgstr "Предварительно распределённый ключ" - -msgid "Prefer IPv4" -msgstr "Предпочитать IPv4" - -msgid "Prefer IPv6" -msgstr "Предпочитать IPv6" - -msgid "Preferred IP" -msgstr "Предпочитаемый IP" - -msgid "Prefix text" -msgstr "Текст префикса" - -msgid "Preshared Key" -msgstr "Общий ключ" - -msgid "Prevents multiple reload_firewall calls within 120 seconds to avoid connection drops." -msgstr "Предотвращает множественные вызовы reload_firewall в течение 120 секунд для избежания обрывов." - -msgid "Priority" -msgstr "Приоритет" - msgid "Priority details" msgstr "Детали Priority" msgid "Priority details are unavailable" msgstr "Детали Priority недоступны" -msgid "Priority level settings" -msgstr "Настройки уровня приоритета" - -msgid "Priority levels" -msgstr "Уровни приоритета" - -msgid "Priority settings" -msgstr "Настройки приоритета" - -msgid "Private Key" -msgstr "Приватный ключ" - msgid "Protection" msgstr "Защита" -msgid "Protocol" -msgstr "Протокол" - -msgid "Proxy Fail Threshold" -msgstr "Порог ошибок прокси" - -msgid "Proxy Health Check Interval (s)" -msgstr "Интервал проверки прокси (с)" - -msgid "Proxy Health Check URL" -msgstr "URL проверки прокси" - msgid "Proxy link is unavailable" msgstr "Ссылка прокси недоступна" -msgid "Proxy Section for Bot" -msgstr "Секция прокси для бота" - -msgid "Proxy to use for WARP API registration (api.cloudflareclient.com)" -msgstr "Прокси для регистрации WARP API (api.cloudflareclient.com)" - -msgid "PSK" -msgstr "PSK" - msgid "Public host" msgstr "Публичный хост" -msgid "QR code is too large" -msgstr "QR-код слишком большой" - -msgid "QUIC (HTTP/3)" -msgstr "QUIC (HTTP/3)" - -msgid "RDP" -msgstr "RDP" - -msgid "Read error" -msgstr "Ошибка чтения" - -msgid "Reality fake site" -msgstr "Fake-сайт Reality" - -msgid "Reality fake site port" -msgstr "Порт fake-сайта Reality" - -msgid "Reality max time difference" -msgstr "Максимальная разница времени Reality" - -msgid "Reality private key" -msgstr "Приватный ключ Reality" - -msgid "Reality public key" -msgstr "Публичный ключ Reality" - -msgid "Reality short ID" -msgstr "Reality short ID" - -msgid "Reality short ID must contain 1-8 hex digits" -msgstr "Reality short ID должен содержать 1-8 hex-символов" - msgid "Rebuilt release" msgstr "Пересобранный релиз" -msgid "Recommended Smart Quick Fixes:" +msgid "Recommended Quick Fixes:" msgstr "" -msgid "Reconnect Threshold" -msgstr "Порог переподключений" - -msgid "Records proxy/DNS latency and health status in hourly buckets for analysis." -msgstr "Записывает латентность прокси/DNS и статус здоровья в часовые интервалы для анализа." - -msgid "Records: %d" -msgstr "Записей: %d" - msgid "Refill" msgstr "Сброс" -msgid "Registration Detour" -msgstr "Обходной путь регистрации" - -msgid "Regular expression must not contain spaces or commas" -msgstr "Регулярное выражение не должно содержать пробелы или запятые" - msgid "Reinstall" msgstr "Переустановить" -msgid "Remote Hosts Lists" -msgstr "Удалённые списки хостов" - msgid "Remove" msgstr "Удалить" -msgid "Remove servers from the specified countries from this level." -msgstr "Удалить серверы из указанных стран с этого уровня." - -msgid "Remove servers whose names match the expression from this level." -msgstr "Удалить с этого уровня серверы, имена которых совпадают с выражением." - -msgid "Remove the specified servers from this level." -msgstr "Удалить указанные серверы с этого уровня." - -msgid "Require a username and password for the local mixed proxy" -msgstr "Требовать имя пользователя и пароль для локального смешанного прокси" - -msgid "Resolve domain names before routing so sing-box can use real destination IPs." -msgstr "Разрешать доменные имена до маршрутизации, чтобы sing-box мог использовать реальные IP назначения." - -msgid "Resolve real IP for routing" -msgstr "Определять реальный IP для маршрутизации" - -msgid "Resource selection by hostname inside nfqws is not supported here; sing-box selects resources before NFQUEUE." -msgstr "Выбор ресурсов по имени хоста внутри nfqws не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE." - -msgid "Resource selection by hostname inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE." -msgstr "Выбор ресурсов по имени хоста внутри nfqws2 не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE." - -msgid "Resource selection by IP or CIDR inside nfqws is not supported here; sing-box selects resources before NFQUEUE." -msgstr "Выбор ресурсов по IP или CIDR внутри nfqws не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE." - -msgid "Resource selection by IP or CIDR inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE." -msgstr "Выбор ресурсов по IP или CIDR внутри nfqws2 не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE." - -msgid "Response Packet Magic Header (S2)" -msgstr "Magic Header: Ответ (S2)" - -msgid "Response Packet Magic Header (S4)" -msgstr "Magic Header: Ответ (S4)" +msgid "Resolved IP / DNS" +msgstr "IP / DNS" msgid "Restart Tachyon" msgstr "Перезапустить Tachyon" @@ -2462,45 +926,9 @@ msgstr "Продолжить обновление" msgid "Route" msgstr "Маршрут" -msgid "Route bot API requests through this section. Leave empty to use the default mixed proxy." -msgstr "Направлять запросы бота к Telegram API через эту секцию. Оставьте пустым для использования стандартного прокси." - -msgid "Route main DNS requests through the selected section." -msgstr "Маршрутизировать основные DNS-запросы через выбранную секцию." - -msgid "Route requests to this DNS server through another section." -msgstr "Маршрутизировать запросы к этому DNS серверу через другую секцию." - -msgid "Routing mode" -msgstr "Режим маршрутизации" - -msgid "Routing Rule Tracer" -msgstr "Трассировщик правил маршрутизации" - msgid "Routing rules" msgstr "Правила маршрутизации" -msgid "Routing section" -msgstr "Секция маршрутизации" - -msgid "Rule" -msgstr "Правило" - -msgid "Rule set must be an HTTP(S) URL or a local .srs / .json path" -msgstr "Набор правил должен быть HTTP(S) URL или локальным путём .srs / .json" - -msgid "Rule set settings" -msgstr "Настройки набора правил" - -msgid "Rule sets" -msgstr "Наборы правил" - -msgid "Rule Sets (.srs / .json)" -msgstr "Наборы правил (.srs / .json)" - -msgid "Rules" -msgstr "Правила" - msgid "Rules mangle counters" msgstr "Счётчики правил mangle" @@ -2528,15 +956,9 @@ msgstr "Запустить диагностику" msgid "Run doctor repair" msgstr "Запустить восстановление" -msgid "Run History" -msgstr "" - msgid "Running" msgstr "Запущен" -msgid "Russia (ru)" -msgstr "Россия (ru)" - msgid "Save" msgstr "Сохранить" @@ -2552,167 +974,29 @@ msgstr "Сохранение…" msgid "Search" msgstr "Поиск" -msgid "Secret" -msgstr "Секрет" - -msgid "Secret key for authenticating remote access to YACD when WAN access is enabled." -msgstr "Секретный ключ для аутентификации удаленного доступа к YACD при включенном доступе через WAN." - -msgid "Secret token for authorizing WRITE operations (POST/PUT) on /cgi-bin/tachyon-agent/. Leave empty if auth is not required." -msgstr "Секретный токен для авторизации WRITE-операций (POST/PUT) по адресу /cgi-bin/tachyon-agent/. Оставьте пустым, если авторизация не требуется." +msgid "Search domain..." +msgstr "Поиск домена..." msgid "Secret token for WRITE requests" msgstr "Секретный токен для POST/PUT запросов" -msgid "Section" -msgstr "Секция" - -msgid "Section / Domain" -msgstr "" - -msgid "Section action" -msgstr "Действие секции" - -msgid "Section name" -msgstr "Название секции" - -msgid "Section Rules Content" -msgstr "Содержимое правил секции" +msgid "Section / Target" +msgstr "Секция / Цель" msgid "Section test order (checked = active, drag rows with △▽):" msgstr "Порядок проверки секций (галочка = активна, перетаскивайте △▽):" -msgid "Sections" -msgstr "Секции" - -msgid "Security" -msgstr "Защита" - -msgid "Select a common client profile or enter a custom User-Agent" -msgstr "Выберите стандартный профиль клиента или введите пользовательский User-Agent" - -msgid "Select a file with .conf extension" -msgstr "Выберите файл с расширением .conf" - -msgid "Select a network interface" -msgstr "Выберите сетевой интерфейс" - -msgid "Select a predefined domain list" -msgstr "Выберите предопределённый список доменов" - -msgid "Select a section" -msgstr "Выберите секцию" - -msgid "Select a section for downloading this subscription" -msgstr "Выберите секцию для скачивания этой подписки" - -msgid "Select a transit section" -msgstr "Выберите транзитную секцию" - -msgid "Select AI LLM provider for diagnostics" -msgstr "Выберите провайдера LLM для диагностики" - -msgid "Select an existing network interface" -msgstr "Выберите существующий сетевой интерфейс" - -msgid "Select an existing URLTest or Priority group" -msgstr "Выберите существующий URLTest или группу приоритетов" - -msgid "Select an intermediate section" -msgstr "Выберите промежуточную секцию" - -msgid "Select and order the sections through which blocked domains are tested. Checked sections are tried top-to-bottom." -msgstr "Выберите и упорядочьте секции для тестирования заблокированных доменов. Отмеченные секции проверяются сверху вниз." - -msgid "Select DNS protocol to use" -msgstr "Выберите протокол DNS" - -msgid "Select network interface for VPN connection" -msgstr "Выберите сетевой интерфейс для VPN соединения" - -msgid "Select one or more country ISO codes (e.g. ru, us, de, nl, fr, fi, se, tr, cn, jp, sg, by, kz, ua)." -msgstr "Выберите одну или несколько стран по двухбуквенному коду ISO (например: ru, us, de, nl, fr, fi, se, tr, cn, jp, sg, by, kz, ua)." - -msgid "Select or enter a User-Agent" -msgstr "Выберите или введите User-Agent" - -msgid "Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing" -msgstr "Выберите или введите путь к файлу кеша sing-box. Изменяйте это, ТОЛЬКО если вы знаете, что делаете" - -msgid "Select or enter the IP addresses of your game consoles." -msgstr "Выберите или введите IP-адреса ваших игровых приставок." - -msgid "Select path for sing-box config file. Change this ONLY if you know what you are doing" -msgstr "Выберите путь к файлу конфигурации sing-box. Изменяйте это, ТОЛЬКО если вы знаете, что делаете" - msgid "Select the fastest node" msgstr "Выбирать самый быстрый узел" -msgid "Select the log level for sing-box" -msgstr "Выберите уровень логов для sing-box" - -msgid "Select the network interface from which the traffic will originate" -msgstr "Выберите сетевой интерфейс, с которого будет исходить трафик" - -msgid "Select the network interface to which the traffic will originate" -msgstr "Выберите сетевой интерфейс, на который будет поступать трафик." - -msgid "Select the WAN interfaces to be monitored" -msgstr "Выберите WAN интерфейсы для мониторинга" - msgid "Selected" msgstr "Выбран" -msgid "Selected section" -msgstr "Выбранная секция" - msgid "Selector and URLTest outbounds must contain a non-empty outbounds array" msgstr "Selector и URLTest outbound должны содержать непустой массив outbounds" -msgid "Send a Telegram notification if a potential DNS leak is detected." -msgstr "Отправлять уведомление в Telegram при обнаружении возможной утечки DNS." - -msgid "Send a Telegram notification if sing-box or nftables rules crash and get auto-restored." -msgstr "Отправлять уведомление в Telegram, если правила sing-box или nftables упали и были автоматически восстановлены." - -msgid "Send a Telegram notification if SSL/TLS certificates are close to expiration." -msgstr "Отправлять уведомление в Telegram, если срок действия SSL/TLS-сертификатов близок к истечению." - -msgid "Send a Telegram notification if the Tachyon service is restarted by the watchdog." -msgstr "Отправлять уведомление в Telegram при перезапуске службы Tachyon сторожевым таймером." - -msgid "Send a Telegram notification when a URLTest group switches to a new server." -msgstr "Отправлять уведомление в Telegram при переключении группы URLTest на новый сервер." - -msgid "Send a Telegram notification when proxy subscriptions are successfully updated." -msgstr "Отправлять уведомление в Telegram при успешном обновлении подписок прокси." - -msgid "Server" -msgstr "Сервер" - -msgid "Server Address" -msgstr "Адрес сервера" - -msgid "Server filtering" -msgstr "Фильтрация серверов" - -msgid "Server group for automatic lowest-latency selection" -msgstr "Группа серверов для автоматического выбора с наименьшей задержкой" - -msgid "Server group for priority failover" -msgstr "Группа серверов для резервного переключения по приоритету" - -msgid "Server information" -msgstr "Информация о сервере" - -msgid "Server name" -msgstr "Имя сервера" - -msgid "Server name / SNI" -msgstr "Имя сервера / SNI" - -msgid "Server Name Indication — leave empty to use server address" -msgstr "Server Name Indication — оставьте пустым для использования адреса сервера" +msgid "Send" +msgstr "Отправить" msgid "Server outbound must contain a non-empty server field" msgstr "Серверный outbound должен содержать непустое поле server" @@ -2720,66 +1004,24 @@ msgstr "Серверный outbound должен содержать непуст msgid "Server outbound must contain a numeric server_port from 1 to 65535" msgstr "Серверный outbound должен содержать числовой server_port от 1 до 65535" -msgid "Server Port" -msgstr "Порт сервера" +msgid "Server unavailable" +msgstr "Сервер недоступен" msgid "server_port must be a number from 1 to 65535" msgstr "server_port должен быть числом от 1 до 65535" -msgid "Servers" -msgstr "Серверы" - -msgid "Servers on dashboard" -msgstr "Серверы на дашборде" - msgid "Service action failed" msgstr "Действие сервиса не выполнено" msgid "Service Health Check" -msgstr "" - -msgid "Service list" -msgstr "Список сервисов" - -msgid "Services & Access" -msgstr "" +msgstr "Проверка доступности сервисов" msgid "Services info" msgstr "Информация о сервисах" -msgid "Settings" -msgstr "Настройки" - -msgid "Show metadata on dashboard" -msgstr "Показывать метаданные на дашборде" - -msgid "Show only selected servers." -msgstr "Показывать только выбранные серверы." - -msgid "Show only servers with one of the selected protocols." -msgstr "Показывать только серверы с одним из выбранных протоколов." - -msgid "Show only servers with one of the selected security types." -msgstr "Показывать только серверы с одним из выбранных типов безопасности." - -msgid "Show only servers with one of the selected transports." -msgstr "Показывать только серверы с одним из выбранных транспортов." - -msgid "Show servers from selected groups without repeating their filtering criteria." -msgstr "Показывать серверы из выбранных групп без повторения их критериев фильтрации." - -msgid "Show servers only from the specified countries." -msgstr "Показывать серверы только из указанных стран." - -msgid "Show servers whose names match the expression." -msgstr "Показывать серверы, имена которых совпадают с выражением." - msgid "Show sing-box config" msgstr "Показать sing-box конфигурацию" -msgid "Show subscription metadata for this source on the dashboard" -msgstr "Показывать метаданные подписки для этого источника на дашборде" - msgid "Sing-box autostart disabled" msgstr "Автостарт sing-box отключен" @@ -2804,60 +1046,15 @@ msgstr "Сервис sing-box существует" msgid "Sing-box version is compatible (newer than 1.12.4)" msgstr "Версия Sing-box совместима (новее 1.12.4)" -msgid "Singapore (sg)" -msgstr "Сингапур (sg)" - -msgid "Skip loopback & local entries (127.0.0.1, ::1, 0.0.0.0, localhost)" -msgstr "Пропускать локальные и loopback-записи (127.0.0.1, ::1, 0.0.0.0, localhost)" - -msgid "Skip TLS certificate verification (not recommended)" -msgstr "Пропустить проверку TLS-сертификата (не рекомендуется)" - -msgid "Skipped comments/invalid:" -msgstr "Пропущено комментариев/невалидных:" - -msgid "Skipped loopback:" -msgstr "Пропущено loopback:" - msgid "Smart Detect" msgstr "Smart Detect" msgid "Smart Detect settings saved" msgstr "Настройки Smart Detect сохранены" -msgid "Snell Version" -msgstr "Версия Snell" - -msgid "Some fixes failed" -msgstr "" - -msgid "Sort Alphabetically" -msgstr "Сортировать по алфавиту" - -msgid "Sort by latency" -msgstr "Сортировка по задержке" - -msgid "Sorts servers in this section by lowest latency in the dashboard." -msgstr "Сортирует серверы в этой секции по наименьшей задержке на дашборде." - msgid "Source" msgstr "Источник" -msgid "Source Devices" -msgstr "Устройства-источники" - -msgid "Source Network Interface" -msgstr "Сетевой интерфейс источника" - -msgid "Specify a file path" -msgstr "Укажите путь к файлу" - -msgid "Specify different files" -msgstr "Укажите разные файлы" - -msgid "SSH" -msgstr "SSH" - msgid "Standalone ByeDPI autostart is enabled" msgstr "Автозапуск отдельной службы ByeDPI включен" @@ -2891,84 +1088,30 @@ msgstr "Отдельная служба Zapret2 активна" msgid "Standalone Zapret2 service is inactive" msgstr "Отдельная служба Zapret2 неактивна" -msgid "Start" -msgstr "Запустить" - -msgid "Start bot" -msgstr "Запустить бота" - msgid "Start Tachyon" msgstr "Запустить Tachyon" msgid "Start Watchdog first" msgstr "Сначала запустите Watchdog" -msgid "Starting…" -msgstr "Запуск…" - msgid "Status" msgstr "Статус" -msgid "Stop" -msgstr "Остановить" - -msgid "Stop bot" -msgstr "Остановить бота" - -msgid "Stop checking when URLTest group is not used. Use sing-box duration format like 1d, 12h or 30m." -msgstr "Прекратить проверку, когда группа URLTest не используется. Используйте формат длительности sing-box, например 1d, 12h или 30m." - msgid "Stop Tachyon" msgstr "Остановить Tachyon" msgid "Stopped" msgstr "Остановлен" -msgid "Stopping…" -msgstr "Остановка…" - -msgid "Store auto-detected domains in /etc instead of /tmp to survive reboots." -msgstr "Хранить авто-обнаруженные домены в /etc вместо /tmp для сохранения после перезагрузок." - -msgid "Strict ECH + DoQ DNS Enforcer" -msgstr "Strict ECH Enforcer" - -msgid "STUN (P2P Calls)" -msgstr "STUN (P2P Звонки)" - -msgid "Subnets from the list will be extracted and added to nftables" -msgstr "Подсети из списка будут извлечены и добавлены в nftables" - -msgid "Subscription auto update" -msgstr "Автообновление подписки" - msgid "Subscription info:" msgstr "Информация о подписке:" msgid "Subscription update failed" msgstr "Обновление подписки завершилось ошибкой" -msgid "Subscription update interval" -msgstr "Интервал обновления подписки" - -msgid "Subscription URL" -msgstr "URL подписки" - -msgid "Subscription URL settings" -msgstr "Настройки URL подписки" - msgid "Subscriptions updated" msgstr "Подписки обновлены" -msgid "Success" -msgstr "Успешно" - -msgid "Successfully imported %d DNS record(s)" -msgstr "Успешно импортировано %d DNS-записей" - -msgid "Sweden (se)" -msgstr "Швеция (se)" - msgid "System info" msgstr "Системная информация" @@ -2981,30 +1124,12 @@ msgstr "Таблица существует" msgid "Tachyon Error" msgstr "Ошибка Tachyon" -msgid "Tachyon manages ciadpi pid files itself, so pidfile options are not allowed here." -msgstr "Tachyon самостоятельно управляет pid файлами ciadpi, поэтому параметры pidfile недопустимы здесь." - -msgid "Tachyon manages the ciadpi process lifecycle itself, so daemon mode is not allowed here." -msgstr "Tachyon самостоятельно управляет жизненным циклом процесса ciadpi, поэтому режим демона недопустим здесь." - -msgid "Tachyon manages the nfqws process lifecycle itself, so daemon mode is not allowed here." -msgstr "Tachyon самостоятельно управляет жизненным циклом процесса nfqws, поэтому режим демона недопустим здесь." - -msgid "Tachyon manages the nfqws2 process lifecycle itself, so daemon mode is not allowed here." -msgstr "Tachyon самостоятельно управляет жизненным циклом процесса nfqws2, поэтому режим демона недопустим здесь." - msgid "Tachyon service is stopped. Start the service to display connections." msgstr "Служба Tachyon остановлена. Запустите сервис для отображения подключений." msgid "Tachyon service is stopped. Start the service to display the dashboard." msgstr "Служба Tachyon остановлена. Запустите сервис для отображения дашборда." -msgid "Tachyon Settings" -msgstr "Настройки Tachyon" - -msgid "Tachyon will not modify your DHCP configuration" -msgstr "Tachyon не будет изменять вашу конфигурацию DHCP" - msgid "Tachyon-managed ciadpi runtime has restarted" msgstr "ciadpi Tachyon перезапускался" @@ -3035,59 +1160,20 @@ msgstr "NFQWS2 Tachyon не запущен" msgid "Tachyon-managed nfqws2 runtime is ready" msgstr "NFQWS2 Tachyon готов" -msgid "Tailscale auth key" -msgstr "Ключ авторизации Tailscale" - -msgid "Tailscale control URL" -msgstr "URL control plane Tailscale" - msgid "Tailscale endpoint" msgstr "Tailscale endpoint" -msgid "Tailscale hostname" -msgstr "Hostname Tailscale" - -msgid "TCP (ms)" +msgid "TCP" msgstr "" -msgid "Telegram Bot" -msgstr "Telegram-бот" - -msgid "Telegram Bot Token" -msgstr "Токен Telegram-бота" - msgid "Test latency" msgstr "Тестирование задержки" -msgid "Test only selected servers." -msgstr "Тестировать только выбранные серверы." - -msgid "Test only servers with one of the selected protocols." -msgstr "Тестировать только серверы с одним из выбранных протоколов." - -msgid "Test only servers with one of the selected security types." -msgstr "Тестировать только серверы с одним из выбранных типов безопасности." - -msgid "Test only servers with one of the selected transports." -msgstr "Тестировать только серверы с одним из выбранных транспортов." - -msgid "Test servers only from the specified countries." -msgstr "Тестировать серверы только из указанных стран." - -msgid "Test servers whose names match the expression." -msgstr "Тестировать серверы, имена которых совпадают с выражением." - msgid "Testing URL" msgstr "URL проверки" -msgid "The desync fwmark is managed by Tachyon for loop prevention and must not be overridden here." -msgstr "Метка fwmark для десинхронизации управляется Tachyon для предотвращения петель и не должна переопределяться здесь." - -msgid "The NFQUEUE number is assigned by Tachyon for each rule and must not be overridden here." -msgstr "Номер NFQUEUE назначается Tachyon для каждого правила и не должен переопределяться здесь." - -msgid "The rule applies to the domain and all its subdomains. Use full:, keyword:, or regex: prefixes for exact match, keyword match, or regular expression." -msgstr "Правило применяется к домену и всем его поддоменам. Используйте префиксы full:, keyword: или regex: для точного совпадения, совпадения по ключевому слову или регулярного выражения." +msgid "Testing..." +msgstr "Тестирование..." msgid "There are rules using ByeDPI" msgstr "Есть правила, использующие ByeDPI" @@ -3098,162 +1184,39 @@ msgstr "Есть правила использующие Zapret" msgid "There are rules using Zapret2" msgstr "Есть правила, использующие Zapret2" -msgid "This field is required" -msgstr "Заполните это поле" - -msgid "This field must start a working ciadpi strategy; help/version options exit immediately and are not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии ciadpi; опции help/version немедленно завершаются и недопустимы здесь." - -msgid "This field must start a working nfqws strategy; --dry-run exits immediately and is not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии nfqws; --dry-run немедленно завершается и недопустим здесь." - -msgid "This field must start a working nfqws strategy; --version exits immediately and is not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии nfqws; --version немедленно завершается и недопустим здесь." - -msgid "This field must start a working nfqws2 strategy; --dry-run exits immediately and is not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии nfqws2; --dry-run немедленно завершается и недопустим здесь." - -msgid "This field must start a working nfqws2 strategy; --version exits immediately and is not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии nfqws2; --version немедленно завершается и недопустим здесь." - -msgid "This flag does not accept a value." -msgstr "Этот флаг не принимает значение." - -msgid "This option requires a value." -msgstr "Эта опция требует значение." +msgid "Thinking..." +msgstr "Думаю..." msgid "Time" msgstr "Время" -msgid "Time in seconds for DNS record caching (default: 60)" -msgstr "Время в секундах для кэширования DNS записей (по умолчанию: 60)" - -msgid "Time skew tolerance" -msgstr "Допуск расхождения времени" - msgid "tiny" msgstr "tiny" -msgid "TLS (ms)" +msgid "TLS" msgstr "" -msgid "TLS / HTTPS" -msgstr "TLS / HTTPS" - -msgid "TLS Auth/Crypt Key" -msgstr "Ключ TLS Auth/Crypt" - -msgid "TLS SNI" -msgstr "TLS SNI" - -msgid "Token is required when the bot is enabled" -msgstr "Токен обязателен при включённом боте" - msgid "Tolerance" msgstr "Допуск" -msgid "Top level has the highest priority; lower levels are used as fallback" -msgstr "Верхний уровень имеет наивысший приоритет; нижние уровни используются как резерв" - -msgid "Total lines:" -msgstr "Всего строк:" - -msgid "Trace" -msgstr "Проверить" - -msgid "Tracing routing rules..." -msgstr "Выполняется трассировка..." +msgid "Total Targets" +msgstr "Всего целей" msgid "Traffic" msgstr "Трафик" -msgid "Traffic for this level goes directly." -msgstr "Трафик для этого уровня проходит напрямую." - -msgid "Traffic from these IP addresses will never be routed through this section, even if other conditions match." -msgstr "Трафик с этих IP-адресов никогда не будет направляться через эту секцию, даже если другие условия совпадают." - -msgid "Traffic of specified protocols (e.g. BitTorrent, QUIC, STUN) will bypass this section." -msgstr "Трафик указанных протоколов (например, BitTorrent, QUIC, STUN) будет идти в обход этой секции." - msgid "Traffic Total" msgstr "Всего трафика" -msgid "Traffic type filter" -msgstr "Фильтр по типам трафика" - -msgid "Traffic will go through the default route (Direct/Default)." -msgstr "Трафик пройдёт через маршрут по умолчанию (Напрямую/По умолчанию)." - -msgid "Transparent proxy mode is incompatible with action=byedpi because Tachyon connects to ciadpi through SOCKS." -msgstr "Режим прозрачного прокси несовместим с action=byedpi, так как Tachyon подключается к ciadpi через SOCKS." - -msgid "Transport" -msgstr "Транспорт" - -msgid "Transport host" -msgstr "Хост транспорта" - -msgid "Transport path" -msgstr "Путь транспорта" - -msgid "Transport path must start with /" -msgstr "Путь транспорта должен начинаться с /" - msgid "Troubleshooting" msgstr "Устранение неполадок" -msgid "Try compatible User-Agent profiles automatically when downloading this subscription" -msgstr "Автоматически пробовать совместимые профили User-Agent при скачивании этой подписки" - -msgid "TTL must be a positive number" -msgstr "TTL должно быть положительным числом" - -msgid "TTL value cannot be empty" -msgstr "Значение TTL не может быть пустым" - -msgid "Turkey (tr)" -msgstr "Турция (tr)" - msgid "Type" msgstr "Тип" -msgid "UDP (Unprotected DNS)" -msgstr "UDP (Незащищённый DNS)" - -msgid "Ukraine (ua)" -msgstr "Украина (ua)" - -msgid "Unable to validate the ByeDPI strategy through the backend parser." -msgstr "Не удалось валидировать стратегию ByeDPI через парсер бэкенда." - -msgid "Unable to validate the NFQWS strategy through the backend parser." -msgstr "Не удалось валидировать стратегию NFQWS через парсер бэкенда." - -msgid "Unable to validate the NFQWS2 strategy through the backend parser." -msgstr "Не удалось валидировать стратегию NFQWS2 через парсер бэкенда." - msgid "Unavailability timeout" msgstr "Таймаут недоступности" -msgid "Underload Packet Magic Header (H1)" -msgstr "Magic Header: Underload (H1)" - -msgid "Underload Packet Magic Header (H2)" -msgstr "Magic Header: Underload (H2)" - -msgid "Underload Packet Magic Header (H3)" -msgstr "Magic Header: Underload (H3)" - -msgid "Underload Packet Magic Header (H4)" -msgstr "Magic Header: Underload (H4)" - -msgid "Unexpected ByeDPI strategy argument: %s" -msgstr "Неожиданный аргумент стратегии ByeDPI: %s" - -msgid "Unexpected standalone token. Use explicit flags such as --name or --name=value." -msgstr "Неожиданный отдельный токен. Используйте явные флаги, например --name или --name=value." - msgid "Unexpected Tachyon-managed ciadpi runtime is running" msgstr "Обнаружен лишний ciadpi Tachyon" @@ -3263,45 +1226,21 @@ msgstr "Обнаружен лишний NFQWS Tachyon" msgid "Unexpected Tachyon-managed nfqws2 runtime is running" msgstr "Обнаружен лишний NFQWS2 Tachyon" -msgid "unique UCI identifier" -msgstr "уникальный идентификатор UCI" - -msgid "United Kingdom (gb)" -msgstr "Великобритания (gb)" - -msgid "United States (us)" -msgstr "США (us)" - msgid "unknown" msgstr "неизвестно" msgid "Unknown" msgstr "Неизвестно" -msgid "Unknown ByeDPI option: %s" -msgstr "Неизвестная опция ByeDPI: %s" - -msgid "Unknown country" -msgstr "Неизвестная страна" - msgid "Unknown error" msgstr "Неизвестная ошибка" -msgid "Unknown NFQWS flag." -msgstr "Неизвестный флаг NFQWS." - -msgid "Unknown NFQWS2 flag." -msgstr "Неизвестный флаг NFQWS2." - msgid "Unspecified IP address is not allowed" msgstr "Неуказанный IP-адрес не разрешён" msgid "Unstable" msgstr "Нестабильно" -msgid "Unsupported security mode for this protocol" -msgstr "Этот протокол не поддерживает выбранный режим защиты" - msgid "Update" msgstr "Обновить" @@ -3317,15 +1256,6 @@ msgstr "Доступна новая версия:" msgid "Update subscriptions" msgstr "Обновить подписки" -msgid "Update this subscription automatically" -msgstr "Автоматически обновлять эту подписку" - -msgid "Updated/duplicates:" -msgstr "Обновлено/дубликатов:" - -msgid "Updates & Downloads" -msgstr "" - msgid "Uplink" msgstr "Исходящий" @@ -3338,177 +1268,39 @@ msgstr "URL должен начинаться с vless://, vmess://, ss://, troj msgid "URL must use one of the following protocols:" msgstr "URL должен использовать один из следующих протоколов:" -msgid "URL to test through the proxy (default: Cloudflare 204)." -msgstr "URL для теста через прокси (по умолчанию: Cloudflare 204)." - -msgid "URL used to check whether a server is alive" -msgstr "URL для проверки доступности сервера" - -msgid "URL used to test server latency" -msgstr "URL для тестирования задержки сервера" - -msgid "URLs of remote hosts files to download and apply. Supports standard hosts format: IP domain." -msgstr "URL удалённых файлов hosts для загрузки и применения. Поддерживается стандартный формат hosts: IP domain." - -msgid "URLTest" -msgstr "URLTest" - msgid "URLTest details" msgstr "Детали URLTest" msgid "URLTest details are unavailable" msgstr "Детали URLTest недоступны" -msgid "URLTest settings" -msgstr "Настройки URLTest" - -msgid "Use 3-tier check intervals: fast (15s), normal (120s), slow (300s) instead of a single interval." -msgstr "3-уровневые интервалы проверок: быстрый (15с), нормальный (120с), медленный (300с)." - -msgid "Use 32 hex characters" -msgstr "Укажите 32 hex-символа" - -msgid "Use a domain name or IP address" -msgstr "Используйте доменное имя или IP-адрес" - -msgid "Use a duration like 30s, 5m, or 1h30m" -msgstr "Укажите длительность в формате 30s, 5m или 1h30m" - -msgid "Use a non-negative integer" -msgstr "Используйте неотрицательное целое число" - -msgid "Use a non-zero secret" -msgstr "Укажите ненулевой секрет" - -msgid "Use an HTTP or HTTPS URL" -msgstr "Укажите HTTP или HTTPS URL" - -msgid "Use an IP address" -msgstr "Используйте IP-адрес" - -msgid "Use an IP listen address" -msgstr "Используйте IP-адрес для прослушивания" - -msgid "Use another section as an intermediate hop to connect to servers in this section. Does not apply to network interfaces or JSON outbounds." -msgstr "Использовать другую секцию как промежуточный узел для подключения к серверам этой секции. Не применяется к сетевым интерфейсам и JSON outbound." - -msgid "Use CIDR prefixes like 192.168.1.0/24 or 2001:db8::/32" -msgstr "Используйте CIDR-префиксы, например 192.168.1.0/24 или 2001:db8::/32" - -msgid "Use CIDR prefixes or IP addresses like 192.168.1.0/24, 192.168.1.10, or 2001:db8::1" -msgstr "Используйте CIDR-префиксы или IP-адреса, например 192.168.1.0/24, 192.168.1.10 или 2001:db8::1" - -msgid "Use letters, digits, dots, underscores, or hyphens" -msgstr "Используйте буквы, цифры, точки, подчёркивания или дефисы" - -msgid "Use sing-box duration format like 10s, 1m or 2m30s" -msgstr "Используйте формат длительности sing-box, например 10s, 1m или 2m30s" - -msgid "Use sing-box duration format like 1d, 12h or 30m" -msgstr "Используйте формат длительности sing-box, например 1d, 12h или 30m" - -msgid "Use sing-box duration format like 1d, 12h or 6h" -msgstr "Используйте формат длительности sing-box: 1d, 12h или 6h" - msgid "Used by" msgstr "Используется" -msgid "User-Agent" -msgstr "User-Agent" - -msgid "Username" -msgstr "Имя пользователя" - -msgid "Username cannot be empty" -msgstr "Имя пользователя не может быть пустым" - msgid "Valid" msgstr "Валидно" -msgid "Validates sing-box config before restart to prevent boot loops on broken configs." -msgstr "Проверяет конфиг sing-box перед перезапуском для предотвращения boot loop на сломанных конфигах." - -msgid "Validation errors:" -msgstr "Ошибки валидации:" - -msgid "Value cannot be empty" -msgstr "Значение не может быть пустым" - -msgid "Value must not contain control characters" -msgstr "Значение не должно содержать управляющие символы" - msgid "Verdict" -msgstr "" - -msgid "Via country.is" -msgstr "Через country.is" +msgstr "Статус" msgid "View logs" msgstr "Посмотреть логи" -msgid "Visible name of this section" -msgstr "Видимое имя этой секции" - -msgid "VLESS flow" -msgstr "VLESS flow" - -msgid "vless://, vmess://, ss://, trojan://, socks4/5://, hy2/hysteria2:// links" -msgstr "ссылки vless://, vmess://, ss://, trojan://, socks4/5://, hy2/hysteria2://" - msgid "WAN" msgstr "WAN" msgid "WAN public IP" msgstr "Публичный WAN IP" -msgid "WARP Access Token" -msgstr "Токен доступа WARP" - -msgid "WARP Account ID" -msgstr "ID аккаунта WARP" - -msgid "WARP Configuration generated and loaded successfully!" -msgstr "Конфигурация WARP успешно сгенерирована и загружена!" - -msgid "WARP Private Key" -msgstr "Приватный ключ WARP" - msgid "Watchdog" msgstr "Сторожевой таймер" -msgid "Watchdog Status" -msgstr "Статус watchdog" - -msgid "WebRTC Leak Protection" -msgstr "Защита от утечек WebRTC" - -msgid "What Tachyon should do when this section matches" -msgstr "Что должен делать Tachyon, когда эта секция совпадает" - -msgid "When switching to another level, test every server and select the fastest instead of the first working one." -msgstr "При переключении на другой уровень проверить каждый сервер и выбрать самый быстрый, а не первый рабочий." - -msgid "WireGuard private key from your Cloudflare account" -msgstr "WireGuard приватный ключ из вашего аккаунта Cloudflare" - -msgid "WireGuard private key from your Cloudflare WARP account" -msgstr "Приватный ключ WireGuard от вашего аккаунта Cloudflare WARP" - -msgid "XHTTP mode" -msgstr "Режим XHTTP" - -msgid "YACD Secret Key" -msgstr "Секретный ключ YACD" +msgid "Why Discord fails?" +msgstr "Почему не работает Discord?" msgid "Yes" msgstr "Да" -msgid "You can select Output Network Interface, by default autodetect" -msgstr "Вы можете выбрать выходной сетевой интерфейс, по умолчанию он определяется автоматически." - -msgid "Zapret hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS strategies." -msgstr "Шаблоны списков хостов Zapret не поддерживаются здесь, так как Tachyon не разворачивает их для поправильных стратегий NFQWS." - msgid "Zapret package is installed" msgstr "Пакет Zapret установлен" @@ -3527,9 +1319,6 @@ msgstr "sing-box outbound для Zapret настроен" msgid "Zapret sing-box outbound is not configured" msgstr "sing-box outbound для Zapret не настроен" -msgid "Zapret2 hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS2 strategies." -msgstr "Шаблоны списков хостов Zapret2 не поддерживаются здесь, так как Tachyon не разворачивает их для поправильных стратегий NFQWS2." - msgid "Zapret2 package is installed" msgstr "Пакет Zapret2 установлен" diff --git a/fe-app-tachyon/package.json b/fe-app-tachyon/package.json index 9c7e0981..5ec04059 100644 --- a/fe-app-tachyon/package.json +++ b/fe-app-tachyon/package.json @@ -1,6 +1,6 @@ { "name": "fe-app-tachyon", - "version": "1.2.76", + "version": "1.2.75", "license": "MIT", "type": "module", "scripts": { diff --git a/fe-app-tachyon/src/tachyon/tabs/diagnostic/initController.ts b/fe-app-tachyon/src/tachyon/tabs/diagnostic/initController.ts index f3b23923..e71f10e6 100644 --- a/fe-app-tachyon/src/tachyon/tabs/diagnostic/initController.ts +++ b/fe-app-tachyon/src/tachyon/tabs/diagnostic/initController.ts @@ -37,6 +37,7 @@ import { renderRunAction, renderSystemInfo, renderServiceCheckModal, + renderAiChatModal, } from './partials'; import { TachyonShellMethods } from '../../methods'; import { fetchServicesInfo } from '../../fetchers/fetchServicesInfo'; @@ -624,9 +625,9 @@ async function handleServiceRuntimeAction({ } } - function handleCheckServicesAction() { - renderServiceCheckModal(); - } +function handleCheckServicesAction() { + renderServiceCheckModal(); +} async function handleRestart() { await handleServiceRuntimeAction({ @@ -795,88 +796,51 @@ function saveAiDoctorHistory(entry: AiDoctorHistoryEntry) { } } +async function handleViewLogs() { + setDiagnosticActionLoading('viewLogs', true); + + try { + const viewLogs = await TachyonShellMethods.checkLogs(); + + if (viewLogs.success) { + const getLatestLogs = async () => { + const latestLogs = await TachyonShellMethods.checkLogs(); + + if (!latestLogs.success) { + throw latestLogs; + } + + return (latestLogs.data as string) ?? ''; + }; + + ui.showModal( + _('View logs'), + renderModal(viewLogs.data as string, 'view_logs', { + getText: getLatestLogs, + refreshMs: 250, + initialAutoRefresh: true, + showAutoRefreshToggle: true, + startAtEnd: true, + }), + ); + } else { + logger.error('[DIAGNOSTIC]', 'handleViewLogs - e', viewLogs); + } + } catch (e) { + logger.error('[DIAGNOSTIC]', 'handleViewLogs - e', e); + } finally { + setDiagnosticActionLoading('viewLogs', false); + } +} + async function handleRunAiDoctor() { setDiagnosticActionLoading('aiDoctor', true); - let activeTab: 'diagnosis' | 'history' = 'diagnosis'; - let historyEntries = getAiDoctorHistory(); - - // Create Live Stepper Container - const stepperSteps = [ - _('Checking WAN interfaces & network routing'), - _('Checking sing-box service & DNSmasq'), - _('Checking nftables filtering tables'), - _('Analyzing system log (logread & errors)'), - _('Checking Zapret & ByeDPI rules'), - ]; - - const modalBody = E('div', { class: 'tachyon-partial-modal__body' }, [ - E( - 'div', - { - style: - 'padding: 18px; background: rgba(0,0,0,0.02); border-radius: 8px; border: 1px solid rgba(0,0,0,0.06); text-align: center;', - }, - [ - E( - 'div', - { - style: - 'font-weight: 600; font-size: 15px; margin-bottom: 15px; color: #1976d2;', - }, - '⚡ ' + _('AI Doctor Diagnostic Scan in Progress...'), - ), - E( - 'div', - { - id: 'tachyon_ai_stepper', - style: - 'display: flex; flex-direction: column; gap: 10px; text-align: left; max-width: 480px; margin: 0 auto;', - }, - stepperSteps.map((step, idx) => - E( - 'div', - { - id: `tachyon_step_${idx}`, - style: - 'display: flex; align-items: center; gap: 10px; font-size: 13px; color: #666;', - }, - [ - E('span', { class: 'step-icon' }, '⏳'), - E('span', { class: 'step-text' }, step), - ], - ), - ), - ), - ], - ), - ]); - - ui.showModal(_('AI Doctor Diagnosis'), modalBody); - - // Animate Live Stepper - const updateStep = (idx: number, icon: string, color: string) => { - const el = document.getElementById(`tachyon_step_${idx}`); - if (el) { - const iconEl = el.querySelector('.step-icon'); - if (iconEl) iconEl.textContent = icon; - el.style.color = color; - el.style.fontWeight = icon === '✅' ? '500' : 'normal'; - } - }; - - for (let i = 0; i < stepperSteps.length; i++) { - updateStep(i, '🔄', '#1976d2'); - await new Promise((r) => setTimeout(r, 120)); - updateStep(i, '✅', '#2e7d32'); - } - try { const aiRes = await TachyonShellMethods.aiDoctor(); if (!aiRes || typeof aiRes !== 'object') { showToast(_('AI Doctor failed') + ': ' + _('Unknown error'), 'error'); - ui.hideModal(); return; } @@ -886,10 +850,15 @@ async function handleRunAiDoctor() { ? (rawData as Record) : null; - if ((aiRes as { success?: boolean }).success || (data && data.success)) { - const report = data ? String(data.report ?? '') : String(rawData ?? ''); + if ( + (aiRes as { success?: boolean }).success || + (data && data.success !== false) + ) { + const report = data + ? String(data.report ?? data.summary ?? rawData ?? '') + : String(rawData ?? ''); const quickFixes: string[] = Array.isArray(data?.quick_fixes) - ? (data.quick_fixes as string[]) + ? (data!.quick_fixes as string[]) : String(data?.quick_fix ?? '') .split(',') .map((s) => s.trim()) @@ -898,7 +867,8 @@ async function handleRunAiDoctor() { // Save to History const nowStr = new Date().toLocaleTimeString(); saveAiDoctorHistory({ timestamp: nowStr, report, quickFixes }); - historyEntries = getAiDoctorHistory(); + let historyEntries = getAiDoctorHistory(); + let activeTab: 'diagnosis' | 'history' = 'diagnosis'; // Root Cause Analysis from Report const repLower = report.toLowerCase(); @@ -941,28 +911,34 @@ async function handleRunAiDoctor() { 'div', { style: - 'display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; padding: 10px 14px; background: rgba(0,0,0,0.03); border-radius: 6px; margin-bottom: 14px; border: 1px solid rgba(0,0,0,0.06); font-size: 12px; font-weight: 500;', + 'display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; padding: 10px 14px; background: rgba(255,255,255,0.03); border-radius: 8px; margin-bottom: 14px; border: 1px solid var(--border-color, rgba(255,255,255,0.1)); font-size: 12px; font-weight: 500; width: 100%; box-sizing: border-box;', }, nodes.flatMap((node, idx) => { const badgeBg = node.status === 'OK' - ? '#e8f5e9' + ? 'rgba(40, 167, 69, 0.18)' : node.status === 'WARN' - ? '#fff3e0' - : '#ffebee'; + ? 'rgba(255, 193, 7, 0.18)' + : 'rgba(220, 53, 69, 0.18)'; + const badgeBorder = + node.status === 'OK' + ? 'rgba(40, 167, 69, 0.4)' + : node.status === 'WARN' + ? 'rgba(255, 193, 7, 0.4)' + : 'rgba(220, 53, 69, 0.4)'; const badgeFg = node.status === 'OK' - ? '#2e7d32' + ? '#28a745' : node.status === 'WARN' - ? '#e65100' - : '#c62828'; + ? '#ffc107' + : '#dc3545'; const badgeIcon = node.status === 'OK' ? '✓' : node.status === 'WARN' ? '⚠️' : '❌'; const itemEl = E( 'span', { - style: `padding: 4px 8px; border-radius: 4px; background: ${badgeBg}; color: ${badgeFg}; display: inline-flex; align-items: center; gap: 4px;`, + style: `padding: 4px 10px; border-radius: 12px; background: ${badgeBg}; border: 1px solid ${badgeBorder}; color: ${badgeFg}; display: inline-flex; align-items: center; gap: 4px; font-weight: 600;`, }, `${node.name} [${badgeIcon} ${node.status}]`, ); @@ -970,11 +946,7 @@ async function handleRunAiDoctor() { return idx < nodes.length - 1 ? [ itemEl, - E( - 'span', - { style: 'color: #999; font-weight: bold;' }, - '\u2794', - ), + E('span', { style: 'opacity: 0.5; font-weight: bold;' }, '➔'), ] : [itemEl]; }), @@ -982,14 +954,14 @@ async function handleRunAiDoctor() { }; const renderDiagnosisTabContent = () => { - return E('div', {}, [ + return E('div', { style: 'width: 100%; box-sizing: border-box;' }, [ renderRootCauseBanner(), E( 'pre', { class: 'tachyon-partial-modal__content', style: - 'white-space: pre-wrap; font-family: inherit; font-size: 13px; line-height: 1.5; max-height: 360px; overflow-y: auto; background: #fafafa; padding: 12px; border-radius: 6px; border: 1px solid #eee;', + 'white-space: pre-wrap; font-family: inherit; font-size: 13px; line-height: 1.5; max-height: 360px; overflow-y: auto; overflow-x: hidden; background: rgba(0, 0, 0, 0.25); padding: 12px; border-radius: 8px; border: 1px solid var(--border-color, rgba(255, 255, 255, 0.15)); color: inherit; width: 100%; box-sizing: border-box;', }, E('code', {}, report), ), @@ -998,13 +970,13 @@ async function handleRunAiDoctor() { 'div', { style: - 'margin-top: 14px; padding: 12px; background: rgba(0,0,0,0.02); border-radius: 6px; border: 1px solid rgba(0,0,0,0.08);', + 'margin-top: 14px; padding: 12px; background: rgba(40, 167, 69, 0.08); border-radius: 8px; border: 1px solid rgba(40, 167, 69, 0.3); width: 100%; box-sizing: border-box;', }, [ E( 'b', - { style: 'font-size: 13px;' }, - _('Recommended Smart Quick Fixes:'), + { style: 'font-size: 13px; color: #28a745;' }, + '🛠️ ' + _('Recommended Quick Fixes:'), ), E( 'div', @@ -1012,69 +984,42 @@ async function handleRunAiDoctor() { style: 'display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px;', }, - [ - ...quickFixes.map((code) => { - let applied = false; - const btn = renderButton({ - classNames: ['cbi-button-apply'], - text: `⚡ ${code}`, - onClick: async () => { - if (applied) return; + quickFixes.map((code) => { + let applied = false; + const btn = renderButton({ + classNames: ['cbi-button-apply'], + text: `⚡ ${code}`, + onClick: async () => { + if (applied) return; + showToast( + _('Applying fix') + ': ' + code + '...', + 'success', + ); + const fixRes = + await TachyonShellMethods.applyQuickFix(code); + if ( + fixRes && + typeof fixRes === 'object' && + (fixRes as { success?: boolean }).success + ) { + applied = true; + btn.textContent = `✓ ${code} (${_('Fixed')})`; + btn.classList.remove('cbi-button-apply'); + btn.classList.add('cbi-button-neutral'); showToast( - _('Applying fix') + ': ' + code + '...', + _('Fix applied') + ': ' + code, 'success', ); - const fixRes = - await TachyonShellMethods.applyQuickFix(code); - if ( - fixRes && - typeof fixRes === 'object' && - (fixRes as { success?: boolean }).success - ) { - applied = true; - btn.textContent = `✓ ${code} (${_('Fixed')})`; - btn.classList.remove('cbi-button-apply'); - btn.classList.add('cbi-button-neutral'); - showToast( - _('Fix applied') + ': ' + code, - 'success', - ); - } else { - showToast( - _('Failed to apply fix') + ': ' + code, - 'error', - ); - } - }, - }); - return btn; - }), - quickFixes.length > 1 - ? renderButton({ - classNames: ['cbi-button-action'], - text: `⚡ ${_('Fix All')}`, - onClick: async () => { - showToast(_('Applying all fixes...'), 'success'); - const fixRes = - await TachyonShellMethods.applyQuickFix( - quickFixes.join(','), - ); - if ( - fixRes && - typeof fixRes === 'object' && - (fixRes as { success?: boolean }).success - ) { - showToast( - _('All fixes applied successfully'), - 'success', - ); - } else { - showToast(_('Some fixes failed'), 'error'); - } - }, - }) - : E('span', {}), - ], + } else { + showToast( + _('Failed to apply fix') + ': ' + code, + 'error', + ); + } + }, + }); + return btn; + }), ), ], ) @@ -1082,7 +1027,7 @@ async function handleRunAiDoctor() { 'div', { style: - 'margin-top: 12px; color: #2e7d32; font-weight: 500; font-size: 13px;', + 'margin-top: 12px; color: #28a745; font-weight: 500; font-size: 13px;', }, '✅ ' + _('No quick fix required'), ), @@ -1093,7 +1038,7 @@ async function handleRunAiDoctor() { if (historyEntries.length === 0) { return E( 'div', - { style: 'padding: 20px; text-align: center; color: #777;' }, + { style: 'padding: 20px; text-align: center; opacity: 0.6;' }, _('No diagnostic history available yet.'), ); } @@ -1102,32 +1047,32 @@ async function handleRunAiDoctor() { 'div', { style: - 'display: flex; flex-direction: column; gap: 10px; max-height: 400px; overflow-y: auto;', + 'display: flex; flex-direction: column; gap: 10px; max-height: 400px; overflow-y: auto; width: 100%; box-sizing: border-box;', }, historyEntries.map((h, i) => E( 'div', { style: - 'padding: 10px 14px; background: #fafafa; border: 1px solid #eee; border-radius: 6px;', + 'padding: 12px; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--border-color, rgba(255, 255, 255, 0.12)); border-radius: 8px; width: 100%; box-sizing: border-box;', }, [ E( 'div', { style: - 'display: flex; justify-content: space-between; font-weight: 600; font-size: 12px; color: #333; margin-bottom: 6px;', + 'display: flex; justify-content: space-between; font-weight: 600; font-size: 12px; margin-bottom: 8px;', }, [ - E('span', {}, `Run #${historyEntries.length - i}`), - E('span', { style: 'color: #888;' }, h.timestamp), + E('span', {}, `#${historyEntries.length - i}`), + E('span', { style: 'opacity: 0.65;' }, h.timestamp), ], ), E( 'pre', { style: - 'margin: 0; white-space: pre-wrap; font-size: 11px; max-height: 120px; overflow-y: auto; color: #555;', + 'margin: 0; white-space: pre-wrap; font-size: 12px; max-height: 140px; overflow-y: auto; overflow-x: hidden; background: rgba(0, 0, 0, 0.25); padding: 10px; border-radius: 6px; border: 1px solid var(--border-color, rgba(255, 255, 255, 0.1)); color: inherit; width: 100%; box-sizing: border-box;', }, h.report, ), @@ -1139,7 +1084,10 @@ async function handleRunAiDoctor() { const mainContainer = E( 'div', - { class: 'tachyon-partial-modal__body' }, + { + class: 'tachyon-partial-modal__body', + style: 'width: 100%; max-width: 680px; box-sizing: border-box;', + }, [], ); @@ -1150,7 +1098,7 @@ async function handleRunAiDoctor() { 'div', { style: - 'display: flex; gap: 10px; margin-bottom: 14px; border-bottom: 1px solid #eee; padding-bottom: 8px;', + 'display: flex; gap: 10px; margin-bottom: 14px; border-bottom: 1px solid var(--border-color, #eee); padding-bottom: 8px;', }, [ renderButton({ @@ -1159,7 +1107,7 @@ async function handleRunAiDoctor() { ? 'cbi-button-action' : 'cbi-button-neutral', ], - text: `📋 ${_('Current Diagnosis')}`, + text: _('Current Diagnosis'), onClick: () => { activeTab = 'diagnosis'; renderModalLayout(); @@ -1171,8 +1119,9 @@ async function handleRunAiDoctor() { ? 'cbi-button-action' : 'cbi-button-neutral', ], - text: `🕒 ${_('Run History')} (${historyEntries.length})`, + text: `${_('History')} (${historyEntries.length})`, onClick: () => { + historyEntries = getAiDoctorHistory(); activeTab = 'history'; renderModalLayout(); }, @@ -1186,20 +1135,14 @@ async function handleRunAiDoctor() { 'div', { class: 'tachyon-partial-modal__footer', - style: 'margin-top: 15px;', + style: + 'margin-top: 15px; display: flex; justify-content: flex-end; gap: 8px;', }, [ renderButton({ - classNames: ['cbi-button-apply'], - text: _('Copy'), - onClick: () => copyToClipboard(`\`\`\`\n${report}\n\`\`\``), - }), - renderButton({ - classNames: ['cbi-button-remove'], + classNames: ['cbi-button-neutral'], text: _('Close'), - onClick: () => { - ui.hideModal(); - }, + onClick: () => ui.hideModal(), }), ], ), @@ -1215,7 +1158,6 @@ async function handleRunAiDoctor() { ? (aiRes as { error?: string }).error : _('Unknown error'); showToast(_('AI Doctor failed') + ': ' + errorMsg, 'error'); - ui.hideModal(); } } catch (e) { logger.error( @@ -1224,48 +1166,13 @@ async function handleRunAiDoctor() { e instanceof Error ? e.message : String(e), ); showToast(_('AI Doctor failed'), 'error'); - ui.hideModal(); } finally { setDiagnosticActionLoading('aiDoctor', false); - runChecks(); } } -async function handleViewLogs() { - setDiagnosticActionLoading('viewLogs', true); - - try { - const viewLogs = await TachyonShellMethods.checkLogs(); - - if (viewLogs.success) { - const getLatestLogs = async () => { - const latestLogs = await TachyonShellMethods.checkLogs(); - - if (!latestLogs.success) { - throw latestLogs; - } - - return (latestLogs.data as string) ?? ''; - }; - - ui.showModal( - _('View logs'), - renderModal(viewLogs.data as string, 'view_logs', { - getText: getLatestLogs, - refreshMs: 250, - initialAutoRefresh: true, - showAutoRefreshToggle: true, - startAtEnd: true, - }), - ); - } else { - logger.error('[DIAGNOSTIC]', 'handleViewLogs - e', viewLogs); - } - } catch (e) { - logger.error('[DIAGNOSTIC]', 'handleViewLogs - e', e); - } finally { - setDiagnosticActionLoading('viewLogs', false); - } +function handleOpenAiChat() { + renderAiChatModal(); } async function handleShowSingBoxConfig() { @@ -1480,6 +1387,12 @@ function renderDiagnosticAvailableActionsWidget() { onClick: handleRunAiDoctor, disabled: diagnosticsActions.aiDoctor.loading, }, + aiChat: { + loading: false, + visible: true, + onClick: handleOpenAiChat, + disabled: false, + }, checkServices: { visible: true, loading: diagnosticsActions.checkServices.loading, diff --git a/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/index.ts b/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/index.ts index 3e7c0694..aadbbd2c 100644 --- a/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/index.ts +++ b/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/index.ts @@ -2,4 +2,5 @@ export * from './renderAvailableActions'; export * from './renderCheckSection'; export * from './renderRunAction'; export * from './renderServiceCheckModal'; +export * from './renderAiChatModal'; export * from './renderSystemInfo'; diff --git a/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts b/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts new file mode 100644 index 00000000..5cca0ad6 --- /dev/null +++ b/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts @@ -0,0 +1,221 @@ +import { callBaseMethod } from '../../../methods/shell/callBaseMethod'; +import { renderButton } from '../../../../partials'; +import { Tachyon } from '../../../types'; + +interface ChatMessage { + sender: 'user' | 'assistant'; + text: string; + timestamp: string; +} + +const chatHistory: ChatMessage[] = [ + { + sender: 'assistant', + text: _( + 'Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings.', + ), + timestamp: new Date().toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }), + }, +]; + +export function renderAiChatModal() { + const messageListContainer = E('div', { + style: + 'height: 360px; overflow-y: auto; padding: 12px; background: var(--background-color-secondary, rgba(0,0,0,0.2)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 8px; display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; width: 100%; box-sizing: border-box;', + }); + + const renderMessages = () => { + messageListContainer.innerHTML = ''; + chatHistory.forEach((msg) => { + const isUser = msg.sender === 'user'; + const bubble = E( + 'div', + { + style: `max-width: 82%; align-self: ${isUser ? 'flex-end' : 'flex-start'}; background: ${isUser ? '#007bff' : 'var(--background-color-primary, #2a2a2a)'}; color: #fff; padding: 8px 12px; border-radius: 12px; font-size: 13px; border: 1px solid ${isUser ? '#0056b3' : 'var(--border-color, rgba(255,255,255,0.15))'}; line-height: 1.4; word-break: break-word;`, + }, + [ + E('div', {}, msg.text), + E( + 'small', + { + style: + 'display: block; opacity: 0.65; text-align: right; font-size: 10px; margin-top: 4px;', + }, + msg.timestamp, + ), + ], + ); + messageListContainer.appendChild(bubble); + }); + messageListContainer.scrollTop = messageListContainer.scrollHeight; + }; + + renderMessages(); + + const chatInput = E('input', { + type: 'text', + placeholder: _('Ask Tachyon AI Assistant a question...'), + class: 'cbi-input-text', + style: + 'flex: 1 1 auto; min-width: 0; font-size: 13px; padding: 6px 10px; border-radius: 6px; box-sizing: border-box;', + }); + + const sendBtn = renderButton({ + text: _('Send'), + classNames: ['cbi-button-action'], + onClick: () => handleSend(), + }); + + const handleSend = async (queryText?: string) => { + const text = (queryText || chatInput.value).trim(); + if (!text) return; + + const userMsg: ChatMessage = { + sender: 'user', + text, + timestamp: new Date().toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }), + }; + chatHistory.push(userMsg); + chatInput.value = ''; + renderMessages(); + + // Typing indicator + const typingMsg: ChatMessage = { + sender: 'assistant', + text: '🤖 ' + _('Thinking...'), + timestamp: new Date().toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }), + }; + chatHistory.push(typingMsg); + renderMessages(); + + try { + const res = (await callBaseMethod( + Tachyon.AvailableMethods.AI_DOCTOR, + )) as { success?: boolean; data?: unknown }; + chatHistory.pop(); // Remove typing indicator + + let answerText = _('Failed to receive response from AI service.'); + if (res && res.success) { + if (typeof res.data === 'string') { + try { + const parsed = JSON.parse(res.data); + answerText = + parsed.summary || parsed.message || parsed.raw || res.data; + } catch (_e) { + answerText = res.data; + } + } else if ( + typeof res.data === 'object' && + res.data !== null && + 'message' in res.data + ) { + answerText = String((res.data as { message: string }).message); + } + } + + chatHistory.push({ + sender: 'assistant', + text: answerText, + timestamp: new Date().toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }), + }); + } catch (e: unknown) { + chatHistory.pop(); + const errMsg = e instanceof Error ? e.message : _('Server unavailable'); + chatHistory.push({ + sender: 'assistant', + text: '❌ ' + _('AI service error') + ': ' + errMsg, + timestamp: new Date().toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }), + }); + } + + renderMessages(); + }; + + chatInput.onkeydown = (e: KeyboardEvent) => { + if (e.key === 'Enter') handleSend(); + }; + + // Quick prompt buttons + const quickPrompts = [ + { label: '🩺 ' + _('Check YouTube'), query: 'Check YouTube availability' }, + { label: '🔍 ' + _('Why Discord fails?'), query: 'Why Discord fails?' }, + { + label: '🛠️ ' + _('Full System Diagnostic'), + query: 'Run full system diagnostic', + }, + ]; + + const quickPromptsBar = E( + 'div', + { + style: + 'display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; width: 100%; box-sizing: border-box;', + }, + quickPrompts.map((qp) => { + const btn = E( + 'button', + { + type: 'button', + class: 'cbi-button cbi-button-neutral', + style: 'font-size: 11px; padding: 2px 8px; border-radius: 10px;', + }, + qp.label, + ); + btn.onclick = () => handleSend(qp.query); + return btn; + }), + ); + + const inputToolbar = E( + 'div', + { + style: + 'display: flex; gap: 8px; align-items: center; width: 100%; box-sizing: border-box;', + }, + [chatInput, sendBtn], + ); + + const modalWrapper = E( + 'div', + { style: 'width: 100%; max-width: 680px; box-sizing: border-box;' }, + [quickPromptsBar, messageListContainer, inputToolbar], + ); + + const modalContent = E( + 'div', + { style: 'width: 100%; max-width: 680px; box-sizing: border-box;' }, + [ + modalWrapper, + E( + 'div', + { + style: + 'margin-top: 12px; display: flex; justify-content: flex-end; border-top: 1px solid var(--border-color, rgba(255,255,255,0.15)); padding-top: 10px;', + }, + [ + renderButton({ + text: _('Close'), + onClick: () => ui.hideModal(), + }), + ], + ), + ], + ); + + ui.showModal(_('AI Chat & Tachyon Assistant'), modalContent); +} diff --git a/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts b/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts index 6622e090..b38e6c8c 100644 --- a/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts +++ b/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts @@ -28,6 +28,7 @@ interface IRenderAvailableActionsProps { globalCheck: ActionProps; doctor: ActionProps; aiDoctor: ActionProps; + aiChat?: ActionProps; viewLogs: ActionProps; showSingBoxConfig: ActionProps; generateBugReport: ActionProps; @@ -43,6 +44,7 @@ export function renderAvailableActions({ globalCheck, doctor, aiDoctor, + aiChat, viewLogs, showSingBoxConfig, generateBugReport, @@ -128,9 +130,19 @@ export function renderAvailableActions({ disabled: aiDoctor.disabled, }), ]), + ...insertIf(!!aiChat?.visible, [ + renderButton({ + classNames: ['cbi-button-action'], + onClick: aiChat!.onClick, + icon: renderCircleCheckBigIcon24, + text: _('AI Chat Assistant'), + loading: aiChat!.loading, + disabled: aiChat!.disabled, + }), + ]), ...insertIf(checkServices.visible, [ renderButton({ - classNames: ['cbi-button-apply'], + classNames: ['cbi-button-action'], onClick: checkServices.onClick, icon: renderSquareChartGanttIcon24, text: _('Check Services'), diff --git a/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts b/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts index 75be1b2d..b700147b 100644 --- a/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts +++ b/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts @@ -1,10 +1,14 @@ import { callBaseMethod } from '../../../methods/shell/callBaseMethod'; import { renderButton } from '../../../../partials'; +import { Tachyon } from '../../../types'; -interface ServiceCheckResult { +interface ServiceCheckTarget { section: string; route_type: string; domain: string; +} + +interface ServiceCheckResult extends ServiceCheckTarget { ip: string; dns_ms: number; tcp_ms: number; @@ -15,152 +19,776 @@ interface ServiceCheckResult { } export function renderServiceCheckModal() { - const container = E('div', { class: 'tachyon-service-check-modal' }, [ - E('p', {}, _('Fetching service status, please wait...')), - E('div', { class: 'spinning' }, '...'), - ]); + let currentTargetMode: 'active' | 'all' = 'active'; - ui.showModal(_('Service Health Check'), E('div', {}, [ + const container = E( + 'div', + { + class: 'tachyon-service-check-modal-wrapper', + style: 'width: 100%; max-width: 820px; box-sizing: border-box;', + }, + [ + E( + 'p', + { style: 'text-align: center; margin-top: 20px;' }, + _('Fetching service targets...'), + ), + E( + 'div', + { + class: 'spinning', + style: + 'text-align: center; font-size: 24px; color: var(--border-color, #007bff);', + }, + '⚡', + ), + ], + ); + + const modalContent = E( + 'div', + { style: 'width: 100%; max-width: 820px; box-sizing: border-box;' }, + [ container, - E('div', { style: 'margin-top: 15px; text-align: right;' }, [ + E( + 'div', + { + id: 'tachyon-service-check-footer', + style: + 'margin-top: 15px; display: flex; justify-content: space-between; align-items: center; gap: 10px; border-top: 1px solid var(--border-color, rgba(255,255,255,0.15)); padding-top: 12px; flex-wrap: wrap;', + }, + [ renderButton({ - text: _('Close'), - onClick: () => ui.hideModal() - }) - ]) - ])); + text: _('Close'), + onClick: () => ui.hideModal(), + }), + ], + ), + ], + ); - callBaseMethod('diagnostics/status.uc' as any, [ - 'service-health-check', - ]) - .then((res: any) => { - container.innerHTML = ''; - if (!res.success) { - container.appendChild(E('p', {}, _('Failed to execute service check.'))); - return; - } + ui.showModal(_('Service Health Check'), modalContent); - let results: ServiceCheckResult[] = []; - try { - if (typeof res.data === 'string') { - results = JSON.parse(res.data); + const loadTargets = (targetMode: 'active' | 'all') => { + currentTargetMode = targetMode; + container.innerHTML = ''; + container.appendChild( + E( + 'p', + { style: 'text-align: center; margin-top: 20px;' }, + _('Fetching service targets...'), + ), + ); + + const args = + targetMode === 'all' ? ['get-targets', 'all'] : ['get-targets']; + + callBaseMethod(Tachyon.AvailableMethods.SERVICE_HEALTH_CHECK, args) + .then((res: unknown) => { + const response = res as { + success?: boolean; + data?: string | ServiceCheckTarget[]; + }; + container.innerHTML = ''; + if (!response || !response.success) { + container.appendChild( + E( + 'p', + { style: 'color: #dc3545;' }, + _('Failed to run service check.'), + ), + ); + return; } - } catch (e) { - container.appendChild(E('p', {}, _('Failed to parse service check results.'))); - return; - } - if (results.length === 0) { - container.appendChild(E('p', {}, _('No domains found to check.'))); - } + let targets: ServiceCheckTarget[] = []; + try { + if (typeof response.data === 'string') { + targets = JSON.parse(response.data); + } else if (Array.isArray(response.data)) { + targets = response.data; + } + } catch (_e) { + container.appendChild( + E( + 'p', + { style: 'color: #dc3545;' }, + _('Failed to parse target list.'), + ), + ); + return; + } - const table = E('table', { class: 'table cbi-section-table' }, [ - E('tr', { class: 'tr cbi-section-table-titles' }, [ - E('th', { class: 'th' }, _('Section / Domain')), - E('th', { class: 'th' }, _('Outbound')), - E('th', { class: 'th' }, _('IP / DNS')), - E('th', { class: 'th' }, _('TCP (ms)')), - E('th', { class: 'th' }, _('TLS (ms)')), - E('th', { class: 'th' }, _('HTTP (ms)')), - E('th', { class: 'th' }, _('Verdict')), - ]), - ]); + if (targets.length === 0) { + container.appendChild( + E('p', {}, _('No targets found in section configs.')), + ); + return; + } - results.forEach((item) => { - const badgeColor = item.success - ? '#28a745' - : item.status_class.includes('Timeout') || item.status_class.includes('HTTP') || item.status_class.includes('Reset') - ? '#dc3545' - : '#ffc107'; + // Mode Switcher Toolbar + const activeSectionsBtn = renderButton({ + text: _('Active Sections'), + classNames: [ + targetMode === 'active' + ? 'cbi-button-action' + : 'cbi-button-neutral', + ], + onClick: () => loadTargets('active'), + }); + activeSectionsBtn.style.fontSize = '12px'; + activeSectionsBtn.style.padding = '3px 12px'; - const badge = E( - 'span', + const allProfilesBtn = renderButton({ + text: _('All Profiles'), + classNames: [ + targetMode === 'all' ? 'cbi-button-action' : 'cbi-button-neutral', + ], + onClick: () => loadTargets('all'), + }); + allProfilesBtn.style.fontSize = '12px'; + allProfilesBtn.style.padding = '3px 12px'; + + const modeSwitcherBar = E( + 'div', { - style: `display: inline-block; padding: 2px 6px; border-radius: 4px; color: white; font-weight: bold; font-size: 11px; background: ${badgeColor};`, + style: + 'display: flex; gap: 8px; align-items: center; margin-bottom: 12px; border-bottom: 1px solid var(--border-color, rgba(255,255,255,0.1)); padding-bottom: 8px;', }, - item.status_class, + [ + E( + 'span', + { style: 'font-weight: 600; font-size: 12px; opacity: 0.8;' }, + _('Check Mode:'), + ), + activeSectionsBtn, + allProfilesBtn, + ], ); - table.appendChild( - E('tr', { class: 'tr cbi-rowstyle-1' }, [ - E('td', { class: 'td' }, [ - E('strong', {}, item.section), + // Extract unique sections for filter tabs + const sectionNames = Array.from(new Set(targets.map((t) => t.section))); + let activeFilter = 'ALL'; + let searchQuery = ''; + + // Summary Stats Elements + const totalStatEl = E( + 'div', + { + class: 'stat-val', + style: 'font-size: 18px; font-weight: bold; margin-top: 2px;', + }, + `${targets.length}`, + ); + const passedStatEl = E( + 'div', + { + class: 'stat-val', + style: + 'font-size: 18px; font-weight: bold; color: #28a745; margin-top: 2px;', + }, + '0', + ); + const failedStatEl = E( + 'div', + { + class: 'stat-val', + style: + 'font-size: 18px; font-weight: bold; color: #dc3545; margin-top: 2px;', + }, + '0', + ); + const latencyStatEl = E( + 'div', + { + class: 'stat-val', + style: + 'font-size: 18px; font-weight: bold; color: #17a2b8; margin-top: 2px;', + }, + '-', + ); + + const statsBar = E( + 'div', + { + style: + 'display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; width: 100%; box-sizing: border-box;', + }, + [ + E( + 'div', + { + style: + 'flex: 1 1 120px; min-width: 110px; background: var(--background-color-secondary, rgba(255,255,255,0.05)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; padding: 6px 10px; text-align: center; box-sizing: border-box;', + }, + [ + E( + 'small', + { style: 'display: block; font-size: 11px; opacity: 0.75;' }, + _('Total Targets'), + ), + totalStatEl, + ], + ), + E( + 'div', + { + style: + 'flex: 1 1 120px; min-width: 110px; background: var(--background-color-secondary, rgba(255,255,255,0.05)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; padding: 6px 10px; text-align: center; box-sizing: border-box;', + }, + [ + E( + 'small', + { style: 'display: block; font-size: 11px; opacity: 0.75;' }, + _('Passed'), + ), + passedStatEl, + ], + ), + E( + 'div', + { + style: + 'flex: 1 1 120px; min-width: 110px; background: var(--background-color-secondary, rgba(255,255,255,0.05)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; padding: 6px 10px; text-align: center; box-sizing: border-box;', + }, + [ + E( + 'small', + { style: 'display: block; font-size: 11px; opacity: 0.75;' }, + _('Failed'), + ), + failedStatEl, + ], + ), + E( + 'div', + { + style: + 'flex: 1 1 120px; min-width: 110px; background: var(--background-color-secondary, rgba(255,255,255,0.05)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; padding: 6px 10px; text-align: center; box-sizing: border-box;', + }, + [ + E( + 'small', + { style: 'display: block; font-size: 11px; opacity: 0.75;' }, + _('Avg Latency'), + ), + latencyStatEl, + ], + ), + ], + ); + + // Progress Bar Container + const progressBarInner = E('div', { + style: + 'width: 0%; height: 100%; background: #28a745; transition: width 0.2s ease;', + }); + const progressBarContainer = E( + 'div', + { + style: + 'width: 100%; height: 6px; background: rgba(255,255,255,0.1); border-radius: 3px; overflow: hidden; margin-bottom: 12px; display: none;', + }, + [progressBarInner], + ); + + // Filter Tabs Toolbar + const createFilterTab = (label: string, sectionKey: string) => { + const isActive = activeFilter === sectionKey; + const btn = E( + 'button', + { + type: 'button', + class: `cbi-button ${isActive ? 'cbi-button-action' : 'cbi-button-neutral'}`, + style: 'padding: 3px 10px; font-size: 12px; border-radius: 12px;', + }, + label, + ); + btn.onclick = () => { + activeFilter = sectionKey; + updateFilterTabs(); + applyTableFilter(); + }; + return btn; + }; + + const filterTabsContainer = E('div', { + style: + 'display: flex; gap: 6px; flex-wrap: wrap; align-items: center;', + }); + + const updateFilterTabs = () => { + filterTabsContainer.innerHTML = ''; + filterTabsContainer.appendChild(createFilterTab(_('All'), 'ALL')); + sectionNames.forEach((sec) => { + filterTabsContainer.appendChild(createFilterTab(sec, sec)); + }); + }; + updateFilterTabs(); + + // Search Box + const searchInput = E('input', { + type: 'text', + placeholder: _('Search domain...'), + class: 'cbi-input-text', + style: + 'width: 180px; padding: 4px 8px; font-size: 12px; border-radius: 4px;', + }); + searchInput.oninput = (e: Event) => { + const targetInput = e.target as HTMLInputElement; + searchQuery = (targetInput?.value || '').toLowerCase().trim(); + applyTableFilter(); + }; + + const toolbar = E( + 'div', + { + style: + 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; gap: 10px; flex-wrap: wrap;', + }, + [filterTabsContainer, searchInput], + ); + + // Table Container + const tableHead = E('tr', { class: 'tr cbi-section-table-titles' }, [ + E( + 'th', + { class: 'th', style: 'width: 28%; padding: 6px 8px;' }, + _('Section / Target'), + ), + E( + 'th', + { class: 'th', style: 'width: 17%; padding: 6px 8px;' }, + _('Outbound Route'), + ), + E( + 'th', + { class: 'th', style: 'width: 20%; padding: 6px 8px;' }, + _('Resolved IP / DNS'), + ), + E( + 'th', + { + class: 'th', + style: 'text-align: right; width: 7%; padding: 6px 4px;', + }, + _('TCP'), + ), + E( + 'th', + { + class: 'th', + style: 'text-align: right; width: 7%; padding: 6px 4px;', + }, + _('TLS'), + ), + E( + 'th', + { + class: 'th', + style: 'text-align: right; width: 7%; padding: 6px 4px;', + }, + _('HTTP'), + ), + E( + 'th', + { + class: 'th', + style: 'text-align: center; width: 14%; padding: 6px 6px;', + }, + _('Verdict'), + ), + ]); + + const tableBody = E('tbody', {}); + const table = E( + 'table', + { + class: 'table cbi-section-table', + style: + 'width: 100%; margin: 0; table-layout: fixed; box-sizing: border-box;', + }, + [ + E( + 'thead', + { + style: + 'position: sticky; top: 0; background: var(--background-color-primary, #1e1e1e); z-index: 2;', + }, + [tableHead], + ), + tableBody, + ], + ); + + const tableScrollWrapper = E( + 'div', + { + style: + 'max-height: 380px; overflow-y: auto; overflow-x: hidden; border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; width: 100%; box-sizing: border-box;', + }, + [table], + ); + + const rowMap: { + target: ServiceCheckTarget; + tr: HTMLElement; + result?: ServiceCheckResult; + }[] = []; + + targets.forEach((item) => { + const badge = E( + 'span', + { + style: + 'display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: #6c757d; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;', + }, + _('Pending'), + ); + + const tr = E('tr', { class: 'tr cbi-rowstyle-1' }, [ + E('td', { class: 'td', style: 'word-break: break-all;' }, [ + E( + 'span', + { style: 'font-weight: 600; font-size: 12px;' }, + item.section, + ), E('br'), - E('small', {}, item.domain), + E('small', { style: 'opacity: 0.8;' }, item.domain), ]), - E('td', { class: 'td' }, item.route_type), - E('td', { class: 'td' }, [ - item.ip || '?', + E('td', { class: 'td', style: 'font-size: 11px;' }, [ + E( + 'code', + { + style: + 'background: rgba(255,255,255,0.06); padding: 2px 4px; border-radius: 3px;', + }, + item.route_type, + ), + ]), + E('td', { class: 'td', style: 'font-size: 11px;' }, [ + E('span', {}, '?'), E('br'), - E('small', {}, `${item.dns_ms}ms`), + E('small', { style: 'opacity: 0.6;' }, `-`), ]), - E('td', { class: 'td' }, item.tcp_ms > 0 ? `${item.tcp_ms}` : '-'), - E('td', { class: 'td' }, item.tls_ms > 0 ? `${item.tls_ms}` : '-'), - E('td', { class: 'td' }, item.http_ms > 0 ? `${item.http_ms}` : '-'), - E('td', { class: 'td' }, badge), - ]), + E( + 'td', + { class: 'td', style: 'text-align: right; font-size: 12px;' }, + '-', + ), + E( + 'td', + { class: 'td', style: 'text-align: right; font-size: 12px;' }, + '-', + ), + E( + 'td', + { class: 'td', style: 'text-align: right; font-size: 12px;' }, + '-', + ), + E('td', { class: 'td', style: 'text-align: center;' }, badge), + ]); + + rowMap.push({ target: item, tr }); + tableBody.appendChild(tr); + }); + + const applyTableFilter = () => { + rowMap.forEach(({ target, tr }) => { + const matchesSection = + activeFilter === 'ALL' || target.section === activeFilter; + const matchesSearch = + !searchQuery || + target.domain.toLowerCase().includes(searchQuery) || + target.section.toLowerCase().includes(searchQuery); + tr.style.display = matchesSection && matchesSearch ? '' : 'none'; + }); + }; + + const updateSummaryStats = () => { + let passed = 0; + let failed = 0; + let totalLat = 0; + let countLat = 0; + + rowMap.forEach(({ result }) => { + if (result) { + if (result.success) passed++; + else failed++; + + const lat = result.http_ms || result.tls_ms || result.tcp_ms || 0; + if (lat > 0) { + totalLat += lat; + countLat++; + } + } + }); + + passedStatEl.textContent = `${passed}`; + failedStatEl.textContent = `${failed}`; + latencyStatEl.textContent = + countLat > 0 ? `${Math.round(totalLat / countLat)} ms` : '-'; + }; + + container.appendChild(modeSwitcherBar); + container.appendChild(statsBar); + container.appendChild(progressBarContainer); + container.appendChild(toolbar); + container.appendChild(tableScrollWrapper); + + // Custom domain input & Check Buttons + const footer = document.getElementById('tachyon-service-check-footer'); + if (footer) { + footer.innerHTML = ''; + + const customDomainInput = E('input', { + type: 'text', + id: 'custom-domain-input', + placeholder: _('Check domain or IP (e.g. example.com)...'), + class: 'cbi-input-text', + style: 'width: 260px; font-size: 12px;', + }); + + const customBtn = renderButton({ + text: _('Check Custom'), + classNames: ['cbi-button-neutral'], + onClick: async () => { + const domain = customDomainInput.value.trim(); + if (!domain) return; + + customBtn.disabled = true; + customBtn.textContent = '...'; + + try { + const cRes = (await callBaseMethod( + Tachyon.AvailableMethods.SERVICE_HEALTH_CHECK, + ['check-custom', domain], + )) as { + success?: boolean; + data?: string | ServiceCheckResult[]; + }; + + if (cRes && cRes.success) { + const cResults: ServiceCheckResult[] = + typeof cRes.data === 'string' + ? JSON.parse(cRes.data) + : cRes.data || []; + + if (cResults && cResults.length > 0) { + const cItem: ServiceCheckResult = cResults[0]; + const cBadgeColor = cItem.success ? '#28a745' : '#dc3545'; + const cBadge = E( + 'span', + { + style: `display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: ${cBadgeColor}; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;`, + }, + cItem.status_class, + ); + + const customTr = E('tr', { class: 'tr cbi-rowstyle-2' }, [ + E( + 'td', + { class: 'td', style: 'word-break: break-all;' }, + [ + E( + 'span', + { style: 'font-weight:600;' }, + cItem.section, + ), + E('br'), + E('small', {}, cItem.domain), + ], + ), + E('td', { class: 'td', style: 'font-size: 11px;' }, [ + E('code', {}, cItem.route_type), + ]), + E('td', { class: 'td', style: 'font-size: 11px;' }, [ + cItem.ip || '?', + E('br'), + E('small', {}, `${cItem.dns_ms}ms`), + ]), + E( + 'td', + { class: 'td', style: 'text-align: right;' }, + cItem.tcp_ms > 0 ? `${cItem.tcp_ms}` : '-', + ), + E( + 'td', + { class: 'td', style: 'text-align: right;' }, + cItem.tls_ms > 0 ? `${cItem.tls_ms}` : '-', + ), + E( + 'td', + { class: 'td', style: 'text-align: right;' }, + cItem.http_ms > 0 ? `${cItem.http_ms}` : '-', + ), + E( + 'td', + { class: 'td', style: 'text-align: center;' }, + cBadge, + ), + ]); + + tableBody.insertBefore(customTr, tableBody.firstChild); + rowMap.unshift({ + target: { + section: 'Custom', + route_type: 'auto', + domain: cItem.domain, + }, + tr: customTr, + result: cItem, + }); + updateSummaryStats(); + customDomainInput.value = ''; + } + } + } catch (_e) { + // Ignore custom check errors + } finally { + customBtn.disabled = false; + customBtn.textContent = _('Check Custom'); + } + }, + }); + + const leftWrap = E( + 'div', + { + style: + 'display: flex; gap: 8px; align-items: center; flex-wrap: wrap;', + }, + [customDomainInput, customBtn], + ); + + const checkAllBtn = renderButton({ + text: _('Check All'), + classNames: ['cbi-button-action'], + onClick: async () => { + checkAllBtn.disabled = true; + checkAllBtn.textContent = _('Checking...'); + + progressBarContainer.style.display = 'block'; + progressBarInner.style.width = '0%'; + + for (let i = 0; i < rowMap.length; i++) { + const itemObj = rowMap[i]; + const { target, tr } = itemObj; + + progressBarInner.style.width = `${Math.round(((i + 1) / rowMap.length) * 100)}%`; + + const badgeCell = tr.childNodes[6] as HTMLElement; + badgeCell.innerHTML = ''; + badgeCell.appendChild( + E( + 'span', + { + style: + 'display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: #007bff; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;', + }, + _('Testing...'), + ), + ); + + try { + const cRes = (await callBaseMethod( + Tachyon.AvailableMethods.SERVICE_HEALTH_CHECK, + ['check-domain', JSON.stringify(target)], + )) as { + success?: boolean; + data?: string | ServiceCheckResult[]; + }; + + if (cRes && cRes.success) { + const cResults: ServiceCheckResult[] = + typeof cRes.data === 'string' + ? JSON.parse(cRes.data) + : cRes.data || []; + + if (cResults && cResults.length > 0) { + const cItem: ServiceCheckResult = cResults[0]; + itemObj.result = cItem; + + const cBadgeColor = cItem.success ? '#28a745' : '#dc3545'; + const cBadge = E( + 'span', + { + style: `display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: ${cBadgeColor}; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;`, + }, + cItem.status_class, + ); + + (tr.childNodes[2] as HTMLElement).innerHTML = ''; + (tr.childNodes[2] as HTMLElement).appendChild( + document.createTextNode(cItem.ip || '?'), + ); + (tr.childNodes[2] as HTMLElement).appendChild(E('br')); + (tr.childNodes[2] as HTMLElement).appendChild( + E( + 'small', + { style: 'opacity: 0.6;' }, + `${cItem.dns_ms}ms`, + ), + ); + + (tr.childNodes[3] as HTMLElement).textContent = + cItem.tcp_ms > 0 ? `${cItem.tcp_ms}` : '-'; + (tr.childNodes[4] as HTMLElement).textContent = + cItem.tls_ms > 0 ? `${cItem.tls_ms}` : '-'; + (tr.childNodes[5] as HTMLElement).textContent = + cItem.http_ms > 0 ? `${cItem.http_ms}` : '-'; + + badgeCell.innerHTML = ''; + badgeCell.appendChild(cBadge); + } + } + } catch (_e) { + badgeCell.innerHTML = ''; + badgeCell.appendChild( + E( + 'span', + { + style: + 'display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: #dc3545; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;', + }, + _('Failed'), + ), + ); + } + + updateSummaryStats(); + } + + checkAllBtn.textContent = _('Check Again'); + checkAllBtn.disabled = false; + }, + }); + + const closeBtn = renderButton({ + text: _('Close'), + onClick: () => ui.hideModal(), + }); + + const rightWrap = E('div', { style: 'display: flex; gap: 8px;' }, [ + checkAllBtn, + closeBtn, + ]); + + footer.appendChild(leftWrap); + footer.appendChild(rightWrap); + } + }) + .catch(() => { + container.innerHTML = ''; + container.appendChild( + E( + 'p', + { style: 'color: #dc3545;' }, + _('Failed to run service check.'), + ), ); }); + }; - if (results.length > 0) { - container.appendChild(table); - } - - const customDomainWrap = E('div', { style: 'margin-top: 15px; display: flex; gap: 10px;' }, [ - E('input', { type: 'text', id: 'custom-domain-check-input', placeholder: _('Custom domain (e.g. google.com)') }) - ]); - - let customBtn: HTMLButtonElement; - customBtn = renderButton({ - text: _('Check Custom Domain'), - classNames: ['cbi-button-action'], - onClick: () => { - const input = document.getElementById('custom-domain-check-input') as HTMLInputElement; - if (!input || !input.value) return; - const domain = input.value.trim(); - - if (customBtn) { - customBtn.disabled = true; - customBtn.textContent = '...'; - } - - callBaseMethod('diagnostics/status.uc' as any, ['service-health-check', 'check-custom', domain]).then((cRes: any) => { - if (customBtn) { - customBtn.disabled = false; - customBtn.textContent = _('Check Custom Domain'); - } - if (cRes && cRes.success) { - try { - const cResults = JSON.parse(cRes.data); - if (cResults.length > 0) { - const cItem = cResults[0]; - const cBadgeColor = cItem.success ? '#28a745' : '#dc3545'; - const cBadge = E('span', { style: `display: inline-block; padding: 2px 6px; border-radius: 4px; color: white; font-weight: bold; font-size: 11px; background: ${cBadgeColor};` }, cItem.status_class); - - if (results.length === 0 && !document.body.contains(table)) { - container.insertBefore(table, customDomainWrap); - } - - table.appendChild(E('tr', { class: 'tr cbi-rowstyle-2' }, [ - E('td', { class: 'td' }, [E('strong', {}, cItem.section), E('br'), E('small', {}, cItem.domain)]), - E('td', { class: 'td' }, cItem.route_type), - E('td', { class: 'td' }, [cItem.ip || '?', E('br'), E('small', {}, `${cItem.dns_ms}ms`)]), - E('td', { class: 'td' }, cItem.tcp_ms > 0 ? `${cItem.tcp_ms}` : '-'), - E('td', { class: 'td' }, cItem.tls_ms > 0 ? `${cItem.tls_ms}` : '-'), - E('td', { class: 'td' }, cItem.http_ms > 0 ? `${cItem.http_ms}` : '-'), - E('td', { class: 'td' }, cBadge), - ])); - } - } catch(e) {} - } - }); - } - }); - customDomainWrap.appendChild(customBtn); - container.appendChild(customDomainWrap); - }) - .catch(() => { - container.innerHTML = ''; - container.appendChild(E('p', {}, _('An error occurred while checking services.'))); - }); + loadTargets('active'); } diff --git a/fe-app-tachyon/src/tachyon/types.ts b/fe-app-tachyon/src/tachyon/types.ts index 5a7d5847..5d643701 100644 --- a/fe-app-tachyon/src/tachyon/types.ts +++ b/fe-app-tachyon/src/tachyon/types.ts @@ -93,6 +93,7 @@ export namespace Tachyon { COMPONENT_UPDATE_CHECK_CACHE = 'component_update_check_cache', SUBSCRIPTION_UPDATE_ASYNC = 'subscription_update_async', SUBSCRIPTION_UPDATE_STATUS = 'subscription_update_status', + SERVICE_HEALTH_CHECK = 'service_health_check', } export enum AvailableClashAPIMethods { diff --git a/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js b/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js index 88e92f89..6d70e3f7 100644 --- a/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js +++ b/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js @@ -3056,6 +3056,7 @@ var Tachyon; AvailableMethods2["COMPONENT_UPDATE_CHECK_CACHE"] = "component_update_check_cache"; AvailableMethods2["SUBSCRIPTION_UPDATE_ASYNC"] = "subscription_update_async"; AvailableMethods2["SUBSCRIPTION_UPDATE_STATUS"] = "subscription_update_status"; + AvailableMethods2["SERVICE_HEALTH_CHECK"] = "service_health_check"; })(AvailableMethods = Tachyon2.AvailableMethods || (Tachyon2.AvailableMethods = {})); let AvailableClashAPIMethods; ((AvailableClashAPIMethods2) => { @@ -9721,6 +9722,7 @@ function renderAvailableActions({ globalCheck, doctor, aiDoctor, + aiChat, viewLogs, showSingBoxConfig, generateBugReport, @@ -9806,9 +9808,19 @@ function renderAvailableActions({ disabled: aiDoctor.disabled }) ]), + ...insertIf(!!aiChat?.visible, [ + renderButton({ + classNames: ["cbi-button-action"], + onClick: aiChat.onClick, + icon: renderCircleCheckBigIcon24, + text: _("AI Chat Assistant"), + loading: aiChat.loading, + disabled: aiChat.disabled + }) + ]), ...insertIf(checkServices.visible, [ renderButton({ - classNames: ["cbi-button-apply"], + classNames: ["cbi-button-action"], onClick: checkServices.onClick, icon: renderSquareChartGanttIcon24, text: _("Check Services"), @@ -10025,134 +10037,833 @@ function renderRunAction({ // src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts function renderServiceCheckModal() { - const container = E("div", { class: "tachyon-service-check-modal" }, [ - E("p", {}, _("Fetching service status, please wait...")), - E("div", { class: "spinning" }, "...") - ]); - ui.showModal(_("Service Health Check"), E("div", {}, [ - container, - E("div", { style: "margin-top: 15px; text-align: right;" }, [ - renderButton({ - text: _("Close"), - onClick: () => ui.hideModal() - }) - ]) - ])); - callBaseMethod("diagnostics/status.uc", [ - "service-health-check" - ]).then((res) => { - container.innerHTML = ""; - if (!res.success) { - container.appendChild(E("p", {}, _("Failed to execute service check."))); - return; - } - let results = []; - try { - if (typeof res.data === "string") { - results = JSON.parse(res.data); - } - } catch (e) { - container.appendChild(E("p", {}, _("Failed to parse service check results."))); - return; - } - if (results.length === 0) { - container.appendChild(E("p", {}, _("No domains found to check."))); - } - const table = E("table", { class: "table cbi-section-table" }, [ - E("tr", { class: "tr cbi-section-table-titles" }, [ - E("th", { class: "th" }, _("Section / Domain")), - E("th", { class: "th" }, _("Outbound")), - E("th", { class: "th" }, _("IP / DNS")), - E("th", { class: "th" }, _("TCP (ms)")), - E("th", { class: "th" }, _("TLS (ms)")), - E("th", { class: "th" }, _("HTTP (ms)")), - E("th", { class: "th" }, _("Verdict")) - ]) - ]); - results.forEach((item) => { - const badgeColor = item.success ? "#28a745" : item.status_class.includes("Timeout") || item.status_class.includes("HTTP") || item.status_class.includes("Reset") ? "#dc3545" : "#ffc107"; - const badge = E( - "span", + let currentTargetMode = "active"; + const container = E( + "div", + { + class: "tachyon-service-check-modal-wrapper", + style: "width: 100%; max-width: 820px; box-sizing: border-box;" + }, + [ + E( + "p", + { style: "text-align: center; margin-top: 20px;" }, + _("Fetching service targets...") + ), + E( + "div", { - style: `display: inline-block; padding: 2px 6px; border-radius: 4px; color: white; font-weight: bold; font-size: 11px; background: ${badgeColor};` + class: "spinning", + style: "text-align: center; font-size: 24px; color: var(--border-color, #007bff);" }, - item.status_class - ); - table.appendChild( - E("tr", { class: "tr cbi-rowstyle-1" }, [ - E("td", { class: "td" }, [ - E("strong", {}, item.section), - E("br"), - E("small", {}, item.domain) - ]), - E("td", { class: "td" }, item.route_type), - E("td", { class: "td" }, [ - item.ip || "?", - E("br"), - E("small", {}, `${item.dns_ms}ms`) - ]), - E("td", { class: "td" }, item.tcp_ms > 0 ? `${item.tcp_ms}` : "-"), - E("td", { class: "td" }, item.tls_ms > 0 ? `${item.tls_ms}` : "-"), - E("td", { class: "td" }, item.http_ms > 0 ? `${item.http_ms}` : "-"), - E("td", { class: "td" }, badge) - ]) - ); - }); - if (results.length > 0) { - container.appendChild(table); - } - const customDomainWrap = E("div", { style: "margin-top: 15px; display: flex; gap: 10px;" }, [ - E("input", { type: "text", id: "custom-domain-check-input", placeholder: _("Custom domain (e.g. google.com)") }) - ]); - let customBtn; - customBtn = renderButton({ - text: _("Check Custom Domain"), - classNames: ["cbi-button-action"], - onClick: () => { - const input = document.getElementById("custom-domain-check-input"); - if (!input || !input.value) return; - const domain = input.value.trim(); - if (customBtn) { - customBtn.disabled = true; - customBtn.textContent = "..."; + "\u26A1" + ) + ] + ); + const modalContent = E( + "div", + { style: "width: 100%; max-width: 820px; box-sizing: border-box;" }, + [ + container, + E( + "div", + { + id: "tachyon-service-check-footer", + style: "margin-top: 15px; display: flex; justify-content: space-between; align-items: center; gap: 10px; border-top: 1px solid var(--border-color, rgba(255,255,255,0.15)); padding-top: 12px; flex-wrap: wrap;" + }, + [ + renderButton({ + text: _("Close"), + onClick: () => ui.hideModal() + }) + ] + ) + ] + ); + ui.showModal(_("Service Health Check"), modalContent); + const loadTargets = (targetMode) => { + currentTargetMode = targetMode; + container.innerHTML = ""; + container.appendChild( + E( + "p", + { style: "text-align: center; margin-top: 20px;" }, + _("Fetching service targets...") + ) + ); + const args = targetMode === "all" ? ["get-targets", "all"] : ["get-targets"]; + callBaseMethod(Tachyon.AvailableMethods.SERVICE_HEALTH_CHECK, args).then((res) => { + const response = res; + container.innerHTML = ""; + if (!response || !response.success) { + container.appendChild( + E( + "p", + { style: "color: #dc3545;" }, + _("Failed to run service check.") + ) + ); + return; + } + let targets = []; + try { + if (typeof response.data === "string") { + targets = JSON.parse(response.data); + } else if (Array.isArray(response.data)) { + targets = response.data; } - callBaseMethod("diagnostics/status.uc", ["service-health-check", "check-custom", domain]).then((cRes) => { - if (customBtn) { - customBtn.disabled = false; - customBtn.textContent = _("Check Custom Domain"); - } - if (cRes && cRes.success) { - try { - const cResults = JSON.parse(cRes.data); - if (cResults.length > 0) { - const cItem = cResults[0]; - const cBadgeColor = cItem.success ? "#28a745" : "#dc3545"; - const cBadge = E("span", { style: `display: inline-block; padding: 2px 6px; border-radius: 4px; color: white; font-weight: bold; font-size: 11px; background: ${cBadgeColor};` }, cItem.status_class); - if (results.length === 0 && !document.body.contains(table)) { - container.insertBefore(table, customDomainWrap); - } - table.appendChild(E("tr", { class: "tr cbi-rowstyle-2" }, [ - E("td", { class: "td" }, [E("strong", {}, cItem.section), E("br"), E("small", {}, cItem.domain)]), - E("td", { class: "td" }, cItem.route_type), - E("td", { class: "td" }, [cItem.ip || "?", E("br"), E("small", {}, `${cItem.dns_ms}ms`)]), - E("td", { class: "td" }, cItem.tcp_ms > 0 ? `${cItem.tcp_ms}` : "-"), - E("td", { class: "td" }, cItem.tls_ms > 0 ? `${cItem.tls_ms}` : "-"), - E("td", { class: "td" }, cItem.http_ms > 0 ? `${cItem.http_ms}` : "-"), - E("td", { class: "td" }, cBadge) - ])); - } - } catch (e) { + } catch (_e) { + container.appendChild( + E( + "p", + { style: "color: #dc3545;" }, + _("Failed to parse target list.") + ) + ); + return; + } + if (targets.length === 0) { + container.appendChild( + E("p", {}, _("No targets found in section configs.")) + ); + return; + } + const activeSectionsBtn = renderButton({ + text: _("Active Sections"), + classNames: [ + targetMode === "active" ? "cbi-button-action" : "cbi-button-neutral" + ], + onClick: () => loadTargets("active") + }); + activeSectionsBtn.style.fontSize = "12px"; + activeSectionsBtn.style.padding = "3px 12px"; + const allProfilesBtn = renderButton({ + text: _("All Profiles"), + classNames: [ + targetMode === "all" ? "cbi-button-action" : "cbi-button-neutral" + ], + onClick: () => loadTargets("all") + }); + allProfilesBtn.style.fontSize = "12px"; + allProfilesBtn.style.padding = "3px 12px"; + const modeSwitcherBar = E( + "div", + { + style: "display: flex; gap: 8px; align-items: center; margin-bottom: 12px; border-bottom: 1px solid var(--border-color, rgba(255,255,255,0.1)); padding-bottom: 8px;" + }, + [ + E( + "span", + { style: "font-weight: 600; font-size: 12px; opacity: 0.8;" }, + _("Check Mode:") + ), + activeSectionsBtn, + allProfilesBtn + ] + ); + const sectionNames = Array.from(new Set(targets.map((t) => t.section))); + let activeFilter = "ALL"; + let searchQuery2 = ""; + const totalStatEl = E( + "div", + { + class: "stat-val", + style: "font-size: 18px; font-weight: bold; margin-top: 2px;" + }, + `${targets.length}` + ); + const passedStatEl = E( + "div", + { + class: "stat-val", + style: "font-size: 18px; font-weight: bold; color: #28a745; margin-top: 2px;" + }, + "0" + ); + const failedStatEl = E( + "div", + { + class: "stat-val", + style: "font-size: 18px; font-weight: bold; color: #dc3545; margin-top: 2px;" + }, + "0" + ); + const latencyStatEl = E( + "div", + { + class: "stat-val", + style: "font-size: 18px; font-weight: bold; color: #17a2b8; margin-top: 2px;" + }, + "-" + ); + const statsBar = E( + "div", + { + style: "display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; width: 100%; box-sizing: border-box;" + }, + [ + E( + "div", + { + style: "flex: 1 1 120px; min-width: 110px; background: var(--background-color-secondary, rgba(255,255,255,0.05)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; padding: 6px 10px; text-align: center; box-sizing: border-box;" + }, + [ + E( + "small", + { style: "display: block; font-size: 11px; opacity: 0.75;" }, + _("Total Targets") + ), + totalStatEl + ] + ), + E( + "div", + { + style: "flex: 1 1 120px; min-width: 110px; background: var(--background-color-secondary, rgba(255,255,255,0.05)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; padding: 6px 10px; text-align: center; box-sizing: border-box;" + }, + [ + E( + "small", + { style: "display: block; font-size: 11px; opacity: 0.75;" }, + _("Passed") + ), + passedStatEl + ] + ), + E( + "div", + { + style: "flex: 1 1 120px; min-width: 110px; background: var(--background-color-secondary, rgba(255,255,255,0.05)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; padding: 6px 10px; text-align: center; box-sizing: border-box;" + }, + [ + E( + "small", + { style: "display: block; font-size: 11px; opacity: 0.75;" }, + _("Failed") + ), + failedStatEl + ] + ), + E( + "div", + { + style: "flex: 1 1 120px; min-width: 110px; background: var(--background-color-secondary, rgba(255,255,255,0.05)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; padding: 6px 10px; text-align: center; box-sizing: border-box;" + }, + [ + E( + "small", + { style: "display: block; font-size: 11px; opacity: 0.75;" }, + _("Avg Latency") + ), + latencyStatEl + ] + ) + ] + ); + const progressBarInner = E("div", { + style: "width: 0%; height: 100%; background: #28a745; transition: width 0.2s ease;" + }); + const progressBarContainer = E( + "div", + { + style: "width: 100%; height: 6px; background: rgba(255,255,255,0.1); border-radius: 3px; overflow: hidden; margin-bottom: 12px; display: none;" + }, + [progressBarInner] + ); + const createFilterTab = (label, sectionKey) => { + const isActive = activeFilter === sectionKey; + const btn = E( + "button", + { + type: "button", + class: `cbi-button ${isActive ? "cbi-button-action" : "cbi-button-neutral"}`, + style: "padding: 3px 10px; font-size: 12px; border-radius: 12px;" + }, + label + ); + btn.onclick = () => { + activeFilter = sectionKey; + updateFilterTabs(); + applyTableFilter(); + }; + return btn; + }; + const filterTabsContainer = E("div", { + style: "display: flex; gap: 6px; flex-wrap: wrap; align-items: center;" + }); + const updateFilterTabs = () => { + filterTabsContainer.innerHTML = ""; + filterTabsContainer.appendChild(createFilterTab(_("All"), "ALL")); + sectionNames.forEach((sec) => { + filterTabsContainer.appendChild(createFilterTab(sec, sec)); + }); + }; + updateFilterTabs(); + const searchInput = E("input", { + type: "text", + placeholder: _("Search domain..."), + class: "cbi-input-text", + style: "width: 180px; padding: 4px 8px; font-size: 12px; border-radius: 4px;" + }); + searchInput.oninput = (e) => { + const targetInput = e.target; + searchQuery2 = (targetInput?.value || "").toLowerCase().trim(); + applyTableFilter(); + }; + const toolbar = E( + "div", + { + style: "display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; gap: 10px; flex-wrap: wrap;" + }, + [filterTabsContainer, searchInput] + ); + const tableHead = E("tr", { class: "tr cbi-section-table-titles" }, [ + E( + "th", + { class: "th", style: "width: 28%; padding: 6px 8px;" }, + _("Section / Target") + ), + E( + "th", + { class: "th", style: "width: 17%; padding: 6px 8px;" }, + _("Outbound Route") + ), + E( + "th", + { class: "th", style: "width: 20%; padding: 6px 8px;" }, + _("Resolved IP / DNS") + ), + E( + "th", + { + class: "th", + style: "text-align: right; width: 7%; padding: 6px 4px;" + }, + _("TCP") + ), + E( + "th", + { + class: "th", + style: "text-align: right; width: 7%; padding: 6px 4px;" + }, + _("TLS") + ), + E( + "th", + { + class: "th", + style: "text-align: right; width: 7%; padding: 6px 4px;" + }, + _("HTTP") + ), + E( + "th", + { + class: "th", + style: "text-align: center; width: 14%; padding: 6px 6px;" + }, + _("Verdict") + ) + ]); + const tableBody = E("tbody", {}); + const table = E( + "table", + { + class: "table cbi-section-table", + style: "width: 100%; margin: 0; table-layout: fixed; box-sizing: border-box;" + }, + [ + E( + "thead", + { + style: "position: sticky; top: 0; background: var(--background-color-primary, #1e1e1e); z-index: 2;" + }, + [tableHead] + ), + tableBody + ] + ); + const tableScrollWrapper = E( + "div", + { + style: "max-height: 380px; overflow-y: auto; overflow-x: hidden; border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 6px; width: 100%; box-sizing: border-box;" + }, + [table] + ); + const rowMap = []; + targets.forEach((item) => { + const badge = E( + "span", + { + style: "display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: #6c757d; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;" + }, + _("Pending") + ); + const tr = E("tr", { class: "tr cbi-rowstyle-1" }, [ + E("td", { class: "td", style: "word-break: break-all;" }, [ + E( + "span", + { style: "font-weight: 600; font-size: 12px;" }, + item.section + ), + E("br"), + E("small", { style: "opacity: 0.8;" }, item.domain) + ]), + E("td", { class: "td", style: "font-size: 11px;" }, [ + E( + "code", + { + style: "background: rgba(255,255,255,0.06); padding: 2px 4px; border-radius: 3px;" + }, + item.route_type + ) + ]), + E("td", { class: "td", style: "font-size: 11px;" }, [ + E("span", {}, "?"), + E("br"), + E("small", { style: "opacity: 0.6;" }, `-`) + ]), + E( + "td", + { class: "td", style: "text-align: right; font-size: 12px;" }, + "-" + ), + E( + "td", + { class: "td", style: "text-align: right; font-size: 12px;" }, + "-" + ), + E( + "td", + { class: "td", style: "text-align: right; font-size: 12px;" }, + "-" + ), + E("td", { class: "td", style: "text-align: center;" }, badge) + ]); + rowMap.push({ target: item, tr }); + tableBody.appendChild(tr); + }); + const applyTableFilter = () => { + rowMap.forEach(({ target, tr }) => { + const matchesSection = activeFilter === "ALL" || target.section === activeFilter; + const matchesSearch = !searchQuery2 || target.domain.toLowerCase().includes(searchQuery2) || target.section.toLowerCase().includes(searchQuery2); + tr.style.display = matchesSection && matchesSearch ? "" : "none"; + }); + }; + const updateSummaryStats = () => { + let passed = 0; + let failed2 = 0; + let totalLat = 0; + let countLat = 0; + rowMap.forEach(({ result }) => { + if (result) { + if (result.success) passed++; + else failed2++; + const lat = result.http_ms || result.tls_ms || result.tcp_ms || 0; + if (lat > 0) { + totalLat += lat; + countLat++; } } }); + passedStatEl.textContent = `${passed}`; + failedStatEl.textContent = `${failed2}`; + latencyStatEl.textContent = countLat > 0 ? `${Math.round(totalLat / countLat)} ms` : "-"; + }; + container.appendChild(modeSwitcherBar); + container.appendChild(statsBar); + container.appendChild(progressBarContainer); + container.appendChild(toolbar); + container.appendChild(tableScrollWrapper); + const footer = document.getElementById("tachyon-service-check-footer"); + if (footer) { + footer.innerHTML = ""; + const customDomainInput = E("input", { + type: "text", + id: "custom-domain-input", + placeholder: _("Check domain or IP (e.g. example.com)..."), + class: "cbi-input-text", + style: "width: 260px; font-size: 12px;" + }); + const customBtn = renderButton({ + text: _("Check Custom"), + classNames: ["cbi-button-neutral"], + onClick: async () => { + const domain = customDomainInput.value.trim(); + if (!domain) return; + customBtn.disabled = true; + customBtn.textContent = "..."; + try { + const cRes = await callBaseMethod( + Tachyon.AvailableMethods.SERVICE_HEALTH_CHECK, + ["check-custom", domain] + ); + if (cRes && cRes.success) { + const cResults = typeof cRes.data === "string" ? JSON.parse(cRes.data) : cRes.data || []; + if (cResults && cResults.length > 0) { + const cItem = cResults[0]; + const cBadgeColor = cItem.success ? "#28a745" : "#dc3545"; + const cBadge = E( + "span", + { + style: `display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: ${cBadgeColor}; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;` + }, + cItem.status_class + ); + const customTr = E("tr", { class: "tr cbi-rowstyle-2" }, [ + E( + "td", + { class: "td", style: "word-break: break-all;" }, + [ + E( + "span", + { style: "font-weight:600;" }, + cItem.section + ), + E("br"), + E("small", {}, cItem.domain) + ] + ), + E("td", { class: "td", style: "font-size: 11px;" }, [ + E("code", {}, cItem.route_type) + ]), + E("td", { class: "td", style: "font-size: 11px;" }, [ + cItem.ip || "?", + E("br"), + E("small", {}, `${cItem.dns_ms}ms`) + ]), + E( + "td", + { class: "td", style: "text-align: right;" }, + cItem.tcp_ms > 0 ? `${cItem.tcp_ms}` : "-" + ), + E( + "td", + { class: "td", style: "text-align: right;" }, + cItem.tls_ms > 0 ? `${cItem.tls_ms}` : "-" + ), + E( + "td", + { class: "td", style: "text-align: right;" }, + cItem.http_ms > 0 ? `${cItem.http_ms}` : "-" + ), + E( + "td", + { class: "td", style: "text-align: center;" }, + cBadge + ) + ]); + tableBody.insertBefore(customTr, tableBody.firstChild); + rowMap.unshift({ + target: { + section: "Custom", + route_type: "auto", + domain: cItem.domain + }, + tr: customTr, + result: cItem + }); + updateSummaryStats(); + customDomainInput.value = ""; + } + } + } catch (_e) { + } finally { + customBtn.disabled = false; + customBtn.textContent = _("Check Custom"); + } + } + }); + const leftWrap = E( + "div", + { + style: "display: flex; gap: 8px; align-items: center; flex-wrap: wrap;" + }, + [customDomainInput, customBtn] + ); + const checkAllBtn = renderButton({ + text: _("Check All"), + classNames: ["cbi-button-action"], + onClick: async () => { + checkAllBtn.disabled = true; + checkAllBtn.textContent = _("Checking..."); + progressBarContainer.style.display = "block"; + progressBarInner.style.width = "0%"; + for (let i = 0; i < rowMap.length; i++) { + const itemObj = rowMap[i]; + const { target, tr } = itemObj; + progressBarInner.style.width = `${Math.round((i + 1) / rowMap.length * 100)}%`; + const badgeCell = tr.childNodes[6]; + badgeCell.innerHTML = ""; + badgeCell.appendChild( + E( + "span", + { + style: "display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: #007bff; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;" + }, + _("Testing...") + ) + ); + try { + const cRes = await callBaseMethod( + Tachyon.AvailableMethods.SERVICE_HEALTH_CHECK, + ["check-domain", JSON.stringify(target)] + ); + if (cRes && cRes.success) { + const cResults = typeof cRes.data === "string" ? JSON.parse(cRes.data) : cRes.data || []; + if (cResults && cResults.length > 0) { + const cItem = cResults[0]; + itemObj.result = cItem; + const cBadgeColor = cItem.success ? "#28a745" : "#dc3545"; + const cBadge = E( + "span", + { + style: `display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: ${cBadgeColor}; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;` + }, + cItem.status_class + ); + tr.childNodes[2].innerHTML = ""; + tr.childNodes[2].appendChild( + document.createTextNode(cItem.ip || "?") + ); + tr.childNodes[2].appendChild(E("br")); + tr.childNodes[2].appendChild( + E( + "small", + { style: "opacity: 0.6;" }, + `${cItem.dns_ms}ms` + ) + ); + tr.childNodes[3].textContent = cItem.tcp_ms > 0 ? `${cItem.tcp_ms}` : "-"; + tr.childNodes[4].textContent = cItem.tls_ms > 0 ? `${cItem.tls_ms}` : "-"; + tr.childNodes[5].textContent = cItem.http_ms > 0 ? `${cItem.http_ms}` : "-"; + badgeCell.innerHTML = ""; + badgeCell.appendChild(cBadge); + } + } + } catch (_e) { + badgeCell.innerHTML = ""; + badgeCell.appendChild( + E( + "span", + { + style: "display: inline-block; padding: 2px 6px; border-radius: 8px; color: #fff; font-size: 10px; font-weight: 500; background: #dc3545; text-align: center; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;" + }, + _("Failed") + ) + ); + } + updateSummaryStats(); + } + checkAllBtn.textContent = _("Check Again"); + checkAllBtn.disabled = false; + } + }); + const closeBtn = renderButton({ + text: _("Close"), + onClick: () => ui.hideModal() + }); + const rightWrap = E("div", { style: "display: flex; gap: 8px;" }, [ + checkAllBtn, + closeBtn + ]); + footer.appendChild(leftWrap); + footer.appendChild(rightWrap); } + }).catch(() => { + container.innerHTML = ""; + container.appendChild( + E( + "p", + { style: "color: #dc3545;" }, + _("Failed to run service check.") + ) + ); }); - customDomainWrap.appendChild(customBtn); - container.appendChild(customDomainWrap); - }).catch(() => { - container.innerHTML = ""; - container.appendChild(E("p", {}, _("An error occurred while checking services."))); + }; + loadTargets("active"); +} + +// src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts +var chatHistory = [ + { + sender: "assistant", + text: _( + "Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings." + ), + timestamp: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit" + }) + } +]; +function renderAiChatModal() { + const messageListContainer = E("div", { + style: "height: 360px; overflow-y: auto; padding: 12px; background: var(--background-color-secondary, rgba(0,0,0,0.2)); border: 1px solid var(--border-color, rgba(255,255,255,0.15)); border-radius: 8px; display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; width: 100%; box-sizing: border-box;" }); + const renderMessages = () => { + messageListContainer.innerHTML = ""; + chatHistory.forEach((msg) => { + const isUser = msg.sender === "user"; + const bubble = E( + "div", + { + style: `max-width: 82%; align-self: ${isUser ? "flex-end" : "flex-start"}; background: ${isUser ? "#007bff" : "var(--background-color-primary, #2a2a2a)"}; color: #fff; padding: 8px 12px; border-radius: 12px; font-size: 13px; border: 1px solid ${isUser ? "#0056b3" : "var(--border-color, rgba(255,255,255,0.15))"}; line-height: 1.4; word-break: break-word;` + }, + [ + E("div", {}, msg.text), + E( + "small", + { + style: "display: block; opacity: 0.65; text-align: right; font-size: 10px; margin-top: 4px;" + }, + msg.timestamp + ) + ] + ); + messageListContainer.appendChild(bubble); + }); + messageListContainer.scrollTop = messageListContainer.scrollHeight; + }; + renderMessages(); + const chatInput = E("input", { + type: "text", + placeholder: _("Ask Tachyon AI Assistant a question..."), + class: "cbi-input-text", + style: "flex: 1 1 auto; min-width: 0; font-size: 13px; padding: 6px 10px; border-radius: 6px; box-sizing: border-box;" + }); + const sendBtn = renderButton({ + text: _("Send"), + classNames: ["cbi-button-action"], + onClick: () => handleSend() + }); + const handleSend = async (queryText) => { + const text = (queryText || chatInput.value).trim(); + if (!text) return; + const userMsg = { + sender: "user", + text, + timestamp: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit" + }) + }; + chatHistory.push(userMsg); + chatInput.value = ""; + renderMessages(); + const typingMsg = { + sender: "assistant", + text: "\u{1F916} " + _("Thinking..."), + timestamp: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit" + }) + }; + chatHistory.push(typingMsg); + renderMessages(); + try { + const res = await callBaseMethod( + Tachyon.AvailableMethods.AI_DOCTOR + ); + chatHistory.pop(); + let answerText = _("Failed to receive response from AI service."); + if (res && res.success) { + if (typeof res.data === "string") { + try { + const parsed = JSON.parse(res.data); + answerText = parsed.summary || parsed.message || parsed.raw || res.data; + } catch (_e) { + answerText = res.data; + } + } else if (typeof res.data === "object" && res.data !== null && "message" in res.data) { + answerText = String(res.data.message); + } + } + chatHistory.push({ + sender: "assistant", + text: answerText, + timestamp: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit" + }) + }); + } catch (e) { + chatHistory.pop(); + const errMsg = e instanceof Error ? e.message : _("Server unavailable"); + chatHistory.push({ + sender: "assistant", + text: "\u274C " + _("AI service error") + ": " + errMsg, + timestamp: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit" + }) + }); + } + renderMessages(); + }; + chatInput.onkeydown = (e) => { + if (e.key === "Enter") handleSend(); + }; + const quickPrompts = [ + { label: "\u{1FA7A} " + _("Check YouTube"), query: "Check YouTube availability" }, + { label: "\u{1F50D} " + _("Why Discord fails?"), query: "Why Discord fails?" }, + { + label: "\u{1F6E0}\uFE0F " + _("Full System Diagnostic"), + query: "Run full system diagnostic" + } + ]; + const quickPromptsBar = E( + "div", + { + style: "display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; width: 100%; box-sizing: border-box;" + }, + quickPrompts.map((qp) => { + const btn = E( + "button", + { + type: "button", + class: "cbi-button cbi-button-neutral", + style: "font-size: 11px; padding: 2px 8px; border-radius: 10px;" + }, + qp.label + ); + btn.onclick = () => handleSend(qp.query); + return btn; + }) + ); + const inputToolbar = E( + "div", + { + style: "display: flex; gap: 8px; align-items: center; width: 100%; box-sizing: border-box;" + }, + [chatInput, sendBtn] + ); + const modalWrapper = E( + "div", + { style: "width: 100%; max-width: 680px; box-sizing: border-box;" }, + [quickPromptsBar, messageListContainer, inputToolbar] + ); + const modalContent = E( + "div", + { style: "width: 100%; max-width: 680px; box-sizing: border-box;" }, + [ + modalWrapper, + E( + "div", + { + style: "margin-top: 12px; display: flex; justify-content: flex-end; border-top: 1px solid var(--border-color, rgba(255,255,255,0.15)); padding-top: 10px;" + }, + [ + renderButton({ + text: _("Close"), + onClick: () => ui.hideModal() + }) + ] + ) + ] + ); + ui.showModal(_("AI Chat & Tachyon Assistant"), modalContent); } // src/tachyon/tabs/diagnostic/partials/renderSystemInfo.ts @@ -11288,345 +11999,6 @@ function saveAiDoctorHistory(entry) { } catch (e) { } } -async function handleRunAiDoctor() { - setDiagnosticActionLoading("aiDoctor", true); - let activeTab2 = "diagnosis"; - let historyEntries = getAiDoctorHistory(); - const stepperSteps = [ - _("Checking WAN interfaces & network routing"), - _("Checking sing-box service & DNSmasq"), - _("Checking nftables filtering tables"), - _("Analyzing system log (logread & errors)"), - _("Checking Zapret & ByeDPI rules") - ]; - const modalBody = E("div", { class: "tachyon-partial-modal__body" }, [ - E( - "div", - { - style: "padding: 18px; background: rgba(0,0,0,0.02); border-radius: 8px; border: 1px solid rgba(0,0,0,0.06); text-align: center;" - }, - [ - E( - "div", - { - style: "font-weight: 600; font-size: 15px; margin-bottom: 15px; color: #1976d2;" - }, - "\u26A1 " + _("AI Doctor Diagnostic Scan in Progress...") - ), - E( - "div", - { - id: "tachyon_ai_stepper", - style: "display: flex; flex-direction: column; gap: 10px; text-align: left; max-width: 480px; margin: 0 auto;" - }, - stepperSteps.map( - (step, idx) => E( - "div", - { - id: `tachyon_step_${idx}`, - style: "display: flex; align-items: center; gap: 10px; font-size: 13px; color: #666;" - }, - [ - E("span", { class: "step-icon" }, "\u23F3"), - E("span", { class: "step-text" }, step) - ] - ) - ) - ) - ] - ) - ]); - ui.showModal(_("AI Doctor Diagnosis"), modalBody); - const updateStep = (idx, icon, color) => { - const el = document.getElementById(`tachyon_step_${idx}`); - if (el) { - const iconEl = el.querySelector(".step-icon"); - if (iconEl) iconEl.textContent = icon; - el.style.color = color; - el.style.fontWeight = icon === "\u2705" ? "500" : "normal"; - } - }; - for (let i = 0; i < stepperSteps.length; i++) { - updateStep(i, "\u{1F504}", "#1976d2"); - await new Promise((r) => setTimeout(r, 120)); - updateStep(i, "\u2705", "#2e7d32"); - } - try { - const aiRes = await TachyonShellMethods.aiDoctor(); - if (!aiRes || typeof aiRes !== "object") { - showToast(_("AI Doctor failed") + ": " + _("Unknown error"), "error"); - ui.hideModal(); - return; - } - const rawData = aiRes.data; - const data = typeof rawData === "object" && rawData !== null ? rawData : null; - if (aiRes.success || data && data.success) { - const report = data ? String(data.report ?? "") : String(rawData ?? ""); - const quickFixes = Array.isArray(data?.quick_fixes) ? data.quick_fixes : String(data?.quick_fix ?? "").split(",").map((s) => s.trim()).filter(Boolean); - const nowStr = (/* @__PURE__ */ new Date()).toLocaleTimeString(); - saveAiDoctorHistory({ timestamp: nowStr, report, quickFixes }); - historyEntries = getAiDoctorHistory(); - const repLower = report.toLowerCase(); - const nodes = [ - { - name: "WAN", - status: repLower.includes("wan interface down") ? "FAIL" : "OK" - }, - { - name: "DNS", - status: repLower.includes("dnsmasq") || repLower.includes("dns") ? repLower.includes("dns failed") || repLower.includes("dnsmasq failed") ? "FAIL" : "OK" : "OK" - }, - { - name: "sing-box", - status: repLower.includes("sing-box") && (repLower.includes("stopped") || repLower.includes("error")) ? "FAIL" : "OK" - }, - { - name: "nftables", - status: repLower.includes("nftables") || repLower.includes("rules") ? repLower.includes("damaged") || repLower.includes("corrupted") ? "WARN" : "OK" : "OK" - } - ]; - const renderRootCauseBanner = () => { - return E( - "div", - { - style: "display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; padding: 10px 14px; background: rgba(0,0,0,0.03); border-radius: 6px; margin-bottom: 14px; border: 1px solid rgba(0,0,0,0.06); font-size: 12px; font-weight: 500;" - }, - nodes.flatMap((node, idx) => { - const badgeBg = node.status === "OK" ? "#e8f5e9" : node.status === "WARN" ? "#fff3e0" : "#ffebee"; - const badgeFg = node.status === "OK" ? "#2e7d32" : node.status === "WARN" ? "#e65100" : "#c62828"; - const badgeIcon = node.status === "OK" ? "\u2713" : node.status === "WARN" ? "\u26A0\uFE0F" : "\u274C"; - const itemEl = E( - "span", - { - style: `padding: 4px 8px; border-radius: 4px; background: ${badgeBg}; color: ${badgeFg}; display: inline-flex; align-items: center; gap: 4px;` - }, - `${node.name} [${badgeIcon} ${node.status}]` - ); - return idx < nodes.length - 1 ? [ - itemEl, - E( - "span", - { style: "color: #999; font-weight: bold;" }, - "\u2794" - ) - ] : [itemEl]; - }) - ); - }; - const renderDiagnosisTabContent = () => { - return E("div", {}, [ - renderRootCauseBanner(), - E( - "pre", - { - class: "tachyon-partial-modal__content", - style: "white-space: pre-wrap; font-family: inherit; font-size: 13px; line-height: 1.5; max-height: 360px; overflow-y: auto; background: #fafafa; padding: 12px; border-radius: 6px; border: 1px solid #eee;" - }, - E("code", {}, report) - ), - quickFixes.length > 0 ? E( - "div", - { - style: "margin-top: 14px; padding: 12px; background: rgba(0,0,0,0.02); border-radius: 6px; border: 1px solid rgba(0,0,0,0.08);" - }, - [ - E( - "b", - { style: "font-size: 13px;" }, - _("Recommended Smart Quick Fixes:") - ), - E( - "div", - { - style: "display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px;" - }, - [ - ...quickFixes.map((code) => { - let applied = false; - const btn = renderButton({ - classNames: ["cbi-button-apply"], - text: `\u26A1 ${code}`, - onClick: async () => { - if (applied) return; - showToast( - _("Applying fix") + ": " + code + "...", - "success" - ); - const fixRes = await TachyonShellMethods.applyQuickFix(code); - if (fixRes && typeof fixRes === "object" && fixRes.success) { - applied = true; - btn.textContent = `\u2713 ${code} (${_("Fixed")})`; - btn.classList.remove("cbi-button-apply"); - btn.classList.add("cbi-button-neutral"); - showToast( - _("Fix applied") + ": " + code, - "success" - ); - } else { - showToast( - _("Failed to apply fix") + ": " + code, - "error" - ); - } - } - }); - return btn; - }), - quickFixes.length > 1 ? renderButton({ - classNames: ["cbi-button-action"], - text: `\u26A1 ${_("Fix All")}`, - onClick: async () => { - showToast(_("Applying all fixes..."), "success"); - const fixRes = await TachyonShellMethods.applyQuickFix( - quickFixes.join(",") - ); - if (fixRes && typeof fixRes === "object" && fixRes.success) { - showToast( - _("All fixes applied successfully"), - "success" - ); - } else { - showToast(_("Some fixes failed"), "error"); - } - } - }) : E("span", {}) - ] - ) - ] - ) : E( - "div", - { - style: "margin-top: 12px; color: #2e7d32; font-weight: 500; font-size: 13px;" - }, - "\u2705 " + _("No quick fix required") - ) - ]); - }; - const renderHistoryTabContent = () => { - if (historyEntries.length === 0) { - return E( - "div", - { style: "padding: 20px; text-align: center; color: #777;" }, - _("No diagnostic history available yet.") - ); - } - return E( - "div", - { - style: "display: flex; flex-direction: column; gap: 10px; max-height: 400px; overflow-y: auto;" - }, - historyEntries.map( - (h, i) => E( - "div", - { - style: "padding: 10px 14px; background: #fafafa; border: 1px solid #eee; border-radius: 6px;" - }, - [ - E( - "div", - { - style: "display: flex; justify-content: space-between; font-weight: 600; font-size: 12px; color: #333; margin-bottom: 6px;" - }, - [ - E("span", {}, `Run #${historyEntries.length - i}`), - E("span", { style: "color: #888;" }, h.timestamp) - ] - ), - E( - "pre", - { - style: "margin: 0; white-space: pre-wrap; font-size: 11px; max-height: 120px; overflow-y: auto; color: #555;" - }, - h.report - ) - ] - ) - ) - ); - }; - const mainContainer = E( - "div", - { class: "tachyon-partial-modal__body" }, - [] - ); - const renderModalLayout = () => { - mainContainer.replaceChildren( - E("div", {}, [ - E( - "div", - { - style: "display: flex; gap: 10px; margin-bottom: 14px; border-bottom: 1px solid #eee; padding-bottom: 8px;" - }, - [ - renderButton({ - classNames: [ - activeTab2 === "diagnosis" ? "cbi-button-action" : "cbi-button-neutral" - ], - text: `\u{1F4CB} ${_("Current Diagnosis")}`, - onClick: () => { - activeTab2 = "diagnosis"; - renderModalLayout(); - } - }), - renderButton({ - classNames: [ - activeTab2 === "history" ? "cbi-button-action" : "cbi-button-neutral" - ], - text: `\u{1F552} ${_("Run History")} (${historyEntries.length})`, - onClick: () => { - activeTab2 = "history"; - renderModalLayout(); - } - }) - ] - ), - activeTab2 === "diagnosis" ? renderDiagnosisTabContent() : renderHistoryTabContent(), - E( - "div", - { - class: "tachyon-partial-modal__footer", - style: "margin-top: 15px;" - }, - [ - renderButton({ - classNames: ["cbi-button-apply"], - text: _("Copy"), - onClick: () => copyToClipboard(`\`\`\` -${report} -\`\`\``) - }), - renderButton({ - classNames: ["cbi-button-remove"], - text: _("Close"), - onClick: () => { - ui.hideModal(); - } - }) - ] - ) - ]) - ); - }; - renderModalLayout(); - ui.showModal(_("AI Doctor Diagnosis"), mainContainer); - } else { - const errorMsg = typeof aiRes.error === "string" ? aiRes.error : _("Unknown error"); - showToast(_("AI Doctor failed") + ": " + errorMsg, "error"); - ui.hideModal(); - } - } catch (e) { - logger.error( - "[DIAGNOSTIC]", - "handleRunAiDoctor - e", - e instanceof Error ? e.message : String(e) - ); - showToast(_("AI Doctor failed"), "error"); - ui.hideModal(); - } finally { - setDiagnosticActionLoading("aiDoctor", false); - runChecks(); - } -} async function handleViewLogs() { setDiagnosticActionLoading("viewLogs", true); try { @@ -11658,6 +12030,256 @@ async function handleViewLogs() { setDiagnosticActionLoading("viewLogs", false); } } +async function handleRunAiDoctor() { + setDiagnosticActionLoading("aiDoctor", true); + try { + const aiRes = await TachyonShellMethods.aiDoctor(); + if (!aiRes || typeof aiRes !== "object") { + showToast(_("AI Doctor failed") + ": " + _("Unknown error"), "error"); + return; + } + const rawData = aiRes.data; + const data = typeof rawData === "object" && rawData !== null ? rawData : null; + if (aiRes.success || data && data.success !== false) { + const report = data ? String(data.report ?? data.summary ?? rawData ?? "") : String(rawData ?? ""); + const quickFixes = Array.isArray(data?.quick_fixes) ? data.quick_fixes : String(data?.quick_fix ?? "").split(",").map((s) => s.trim()).filter(Boolean); + const nowStr = (/* @__PURE__ */ new Date()).toLocaleTimeString(); + saveAiDoctorHistory({ timestamp: nowStr, report, quickFixes }); + let historyEntries = getAiDoctorHistory(); + let activeTab2 = "diagnosis"; + const repLower = report.toLowerCase(); + const nodes = [ + { + name: "WAN", + status: repLower.includes("wan interface down") ? "FAIL" : "OK" + }, + { + name: "DNS", + status: repLower.includes("dnsmasq") || repLower.includes("dns") ? repLower.includes("dns failed") || repLower.includes("dnsmasq failed") ? "FAIL" : "OK" : "OK" + }, + { + name: "sing-box", + status: repLower.includes("sing-box") && (repLower.includes("stopped") || repLower.includes("error")) ? "FAIL" : "OK" + }, + { + name: "nftables", + status: repLower.includes("nftables") || repLower.includes("rules") ? repLower.includes("damaged") || repLower.includes("corrupted") ? "WARN" : "OK" : "OK" + } + ]; + const renderRootCauseBanner = () => { + return E( + "div", + { + style: "display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; padding: 10px 14px; background: rgba(255,255,255,0.03); border-radius: 8px; margin-bottom: 14px; border: 1px solid var(--border-color, rgba(255,255,255,0.1)); font-size: 12px; font-weight: 500; width: 100%; box-sizing: border-box;" + }, + nodes.flatMap((node, idx) => { + const badgeBg = node.status === "OK" ? "rgba(40, 167, 69, 0.18)" : node.status === "WARN" ? "rgba(255, 193, 7, 0.18)" : "rgba(220, 53, 69, 0.18)"; + const badgeBorder = node.status === "OK" ? "rgba(40, 167, 69, 0.4)" : node.status === "WARN" ? "rgba(255, 193, 7, 0.4)" : "rgba(220, 53, 69, 0.4)"; + const badgeFg = node.status === "OK" ? "#28a745" : node.status === "WARN" ? "#ffc107" : "#dc3545"; + const badgeIcon = node.status === "OK" ? "\u2713" : node.status === "WARN" ? "\u26A0\uFE0F" : "\u274C"; + const itemEl = E( + "span", + { + style: `padding: 4px 10px; border-radius: 12px; background: ${badgeBg}; border: 1px solid ${badgeBorder}; color: ${badgeFg}; display: inline-flex; align-items: center; gap: 4px; font-weight: 600;` + }, + `${node.name} [${badgeIcon} ${node.status}]` + ); + return idx < nodes.length - 1 ? [ + itemEl, + E("span", { style: "opacity: 0.5; font-weight: bold;" }, "\u2794") + ] : [itemEl]; + }) + ); + }; + const renderDiagnosisTabContent = () => { + return E("div", { style: "width: 100%; box-sizing: border-box;" }, [ + renderRootCauseBanner(), + E( + "pre", + { + class: "tachyon-partial-modal__content", + style: "white-space: pre-wrap; font-family: inherit; font-size: 13px; line-height: 1.5; max-height: 360px; overflow-y: auto; overflow-x: hidden; background: rgba(0, 0, 0, 0.25); padding: 12px; border-radius: 8px; border: 1px solid var(--border-color, rgba(255, 255, 255, 0.15)); color: inherit; width: 100%; box-sizing: border-box;" + }, + E("code", {}, report) + ), + quickFixes.length > 0 ? E( + "div", + { + style: "margin-top: 14px; padding: 12px; background: rgba(40, 167, 69, 0.08); border-radius: 8px; border: 1px solid rgba(40, 167, 69, 0.3); width: 100%; box-sizing: border-box;" + }, + [ + E( + "b", + { style: "font-size: 13px; color: #28a745;" }, + "\u{1F6E0}\uFE0F " + _("Recommended Quick Fixes:") + ), + E( + "div", + { + style: "display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px;" + }, + quickFixes.map((code) => { + let applied = false; + const btn = renderButton({ + classNames: ["cbi-button-apply"], + text: `\u26A1 ${code}`, + onClick: async () => { + if (applied) return; + showToast( + _("Applying fix") + ": " + code + "...", + "success" + ); + const fixRes = await TachyonShellMethods.applyQuickFix(code); + if (fixRes && typeof fixRes === "object" && fixRes.success) { + applied = true; + btn.textContent = `\u2713 ${code} (${_("Fixed")})`; + btn.classList.remove("cbi-button-apply"); + btn.classList.add("cbi-button-neutral"); + showToast( + _("Fix applied") + ": " + code, + "success" + ); + } else { + showToast( + _("Failed to apply fix") + ": " + code, + "error" + ); + } + } + }); + return btn; + }) + ) + ] + ) : E( + "div", + { + style: "margin-top: 12px; color: #28a745; font-weight: 500; font-size: 13px;" + }, + "\u2705 " + _("No quick fix required") + ) + ]); + }; + const renderHistoryTabContent = () => { + if (historyEntries.length === 0) { + return E( + "div", + { style: "padding: 20px; text-align: center; opacity: 0.6;" }, + _("No diagnostic history available yet.") + ); + } + return E( + "div", + { + style: "display: flex; flex-direction: column; gap: 10px; max-height: 400px; overflow-y: auto; width: 100%; box-sizing: border-box;" + }, + historyEntries.map( + (h, i) => E( + "div", + { + style: "padding: 12px; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--border-color, rgba(255, 255, 255, 0.12)); border-radius: 8px; width: 100%; box-sizing: border-box;" + }, + [ + E( + "div", + { + style: "display: flex; justify-content: space-between; font-weight: 600; font-size: 12px; margin-bottom: 8px;" + }, + [ + E("span", {}, `#${historyEntries.length - i}`), + E("span", { style: "opacity: 0.65;" }, h.timestamp) + ] + ), + E( + "pre", + { + style: "margin: 0; white-space: pre-wrap; font-size: 12px; max-height: 140px; overflow-y: auto; overflow-x: hidden; background: rgba(0, 0, 0, 0.25); padding: 10px; border-radius: 6px; border: 1px solid var(--border-color, rgba(255, 255, 255, 0.1)); color: inherit; width: 100%; box-sizing: border-box;" + }, + h.report + ) + ] + ) + ) + ); + }; + const mainContainer = E( + "div", + { + class: "tachyon-partial-modal__body", + style: "width: 100%; max-width: 680px; box-sizing: border-box;" + }, + [] + ); + const renderModalLayout = () => { + mainContainer.replaceChildren( + E("div", {}, [ + E( + "div", + { + style: "display: flex; gap: 10px; margin-bottom: 14px; border-bottom: 1px solid var(--border-color, #eee); padding-bottom: 8px;" + }, + [ + renderButton({ + classNames: [ + activeTab2 === "diagnosis" ? "cbi-button-action" : "cbi-button-neutral" + ], + text: _("Current Diagnosis"), + onClick: () => { + activeTab2 = "diagnosis"; + renderModalLayout(); + } + }), + renderButton({ + classNames: [ + activeTab2 === "history" ? "cbi-button-action" : "cbi-button-neutral" + ], + text: `${_("History")} (${historyEntries.length})`, + onClick: () => { + historyEntries = getAiDoctorHistory(); + activeTab2 = "history"; + renderModalLayout(); + } + }) + ] + ), + activeTab2 === "diagnosis" ? renderDiagnosisTabContent() : renderHistoryTabContent(), + E( + "div", + { + class: "tachyon-partial-modal__footer", + style: "margin-top: 15px; display: flex; justify-content: flex-end; gap: 8px;" + }, + [ + renderButton({ + classNames: ["cbi-button-neutral"], + text: _("Close"), + onClick: () => ui.hideModal() + }) + ] + ) + ]) + ); + }; + renderModalLayout(); + ui.showModal(_("AI Doctor Diagnosis"), mainContainer); + } else { + const errorMsg = typeof aiRes.error === "string" ? aiRes.error : _("Unknown error"); + showToast(_("AI Doctor failed") + ": " + errorMsg, "error"); + } + } catch (e) { + logger.error( + "[DIAGNOSTIC]", + "handleRunAiDoctor - e", + e instanceof Error ? e.message : String(e) + ); + showToast(_("AI Doctor failed"), "error"); + } finally { + setDiagnosticActionLoading("aiDoctor", false); + } +} +function handleOpenAiChat() { + renderAiChatModal(); +} async function handleShowSingBoxConfig() { setDiagnosticActionLoading("showSingBoxConfig", true); try { @@ -11835,6 +12457,12 @@ function renderDiagnosticAvailableActionsWidget() { onClick: handleRunAiDoctor, disabled: diagnosticsActions.aiDoctor.loading }, + aiChat: { + loading: false, + visible: true, + onClick: handleOpenAiChat, + disabled: false + }, checkServices: { visible: true, loading: diagnosticsActions.checkServices.loading, diff --git a/luci-app-tachyon/po/ru/tachyon.po b/luci-app-tachyon/po/ru/tachyon.po index fa4ef976..6e6139d0 100644 --- a/luci-app-tachyon/po/ru/tachyon.po +++ b/luci-app-tachyon/po/ru/tachyon.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: TACHYON\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-12 10:20+0300\n" -"PO-Revision-Date: 2026-08-12 10:20+0300\n" +"POT-Creation-Date: 2026-08-12 12:15+0300\n" +"PO-Revision-Date: 2026-08-12 12:15+0300\n" "Last-Translator: Dushnilin\n" "Language-Team: none\n" "Language: ru\n" @@ -17,27 +17,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -msgid "-- Select --" -msgstr "-- Выбрать --" - -msgid ".lst Lists" -msgstr ".lst списки" - -msgid "(provider default)" -msgstr "" - -msgid "+ Add JSON outbound" -msgstr "+ Добавить JSON outbound" - -msgid "+ Add level" -msgstr "+ Добавить уровень" - -msgid "+ Add priority" -msgstr "+ Добавить приоритет" - -msgid "+ Add URLTest" -msgstr "+ Добавить URLTest" - msgid "⏹ Stop" msgstr "⏹ Стоп" @@ -47,12 +26,6 @@ msgstr "▶ Старт" msgid "⚙ Advanced Settings" msgstr "⚙ Настройки" -msgid "⚠️ If all Bootstrap DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss." -msgstr "⚠️ Если все Bootstrap DNS недоступны 3 раза, запросы будут отправлены через DNS провайдера в открытом виде. Используйте только как крайнюю меру." - -msgid "⚠️ If all Main DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss." -msgstr "⚠️ Если все Main DNS недоступны 3 раза, запросы будут отправлены через DNS провайдера в открытом виде. Используйте только как крайнюю меру." - msgid "✔ Running" msgstr "✔ Работает" @@ -62,15 +35,6 @@ msgstr "✘ Остановлено" msgid "🔑 Generate" msgstr "🔑 Сгенерировать" -msgid "Accept external proxy connections and route them with sing-box." -msgstr "Принимает внешние прокси-подключения и маршрутизирует их через sing-box." - -msgid "Accept routes" -msgstr "Принимать маршруты" - -msgid "Action" -msgstr "Действие" - msgid "Active" msgstr "Активные" @@ -86,90 +50,33 @@ msgstr "Активные соединения" msgid "Active Main DNS" msgstr "Активный основной DNS" -msgid "Add a section" -msgstr "Добавить секцию" - -msgid "Add a server inbound" -msgstr "Добавить серверный inbound" - -msgid "Add at least one DNS server" -msgstr "Добавьте хотя бы один DNS-сервер" - -msgid "Add prefix to nodes" -msgstr "Добавить префикс к узлам" - -msgid "Add URLs or local paths to .lst lists containing domains and subnets." -msgstr "Добавьте URL или локальные пути к .lst спискам с доменами и подсетями." - -msgid "Add URLs or local paths to .lst lists containing domains. IP entries are ignored." -msgstr "Добавьте URL или локальные пути к .lst спискам с доменами. IP-адреса игнорируются." - -msgid "Add URLs or local paths to .srs / .json lists. Only domain rules are supported." -msgstr "Добавьте URL или локальные пути к .srs / .json спискам. Поддерживаются только доменные правила." - -msgid "Add URLs or local paths to .srs / .json lists. Subnets are ignored by default." -msgstr "Добавьте URL или локальные пути к .srs / .json спискам. Подсети по умолчанию игнорируются." - -msgid "Add URLTest / Priority group" -msgstr "Добавить URLTest / группу приоритетов" +msgid "Active Sections" +msgstr "Активные секции" msgid "Additional marking rules found" msgstr "Найдены дополнительные правила маркировки" -msgid "Additionally exclude servers by protocol, transport, and security. Exclude only servers matching the specified parameters." -msgstr "Дополнительно исключить серверы по протоколу, транспорту и безопасности. Исключаются только серверы, соответствующие указанным параметрам." - -msgid "Additionally filter servers by protocol, transport, and security. Add only servers matching the specified parameters." -msgstr "Дополнительно фильтровать серверы по протоколу, транспорту и безопасности. Добавляются только серверы, соответствующие указанным параметрам." - -msgid "Additionally hide servers by protocol, transport, and security. Hide servers matching the specified parameters." -msgstr "Дополнительно скрыть серверы по протоколу, транспорту и безопасности. Скрываются серверы, соответствующие указанным параметрам." - -msgid "Additionally show servers by protocol, transport, and security. Add only servers matching the specified parameters." -msgstr "Дополнительно показать серверы по протоколу, транспорту и безопасности. Добавляются только серверы, соответствующие указанным параметрам." - -msgid "Address" -msgstr "Адрес" - -msgid "Administrator Chat IDs" -msgstr "Telegram ID администраторов" - msgid "Advanced self-healing features. Requires Watchdog to be enabled." msgstr "Расширенные функции самовосстановления. Требуется включённый Watchdog." -msgid "Advanced System" -msgstr "" - -msgid "Advertise exit node" -msgstr "Анонсировать exit node" - -msgid "Advertise routes" -msgstr "Анонсировать маршруты" - -msgid "AEAD Method" -msgstr "Метод AEAD" - -msgid "AI & Watchdog" -msgstr "" - msgid "AI Agent REST API (12 Endpoints)" msgstr "HTTP REST API ИИ-агента (12 эндпоинтов)" -msgid "AI Agent REST API Bearer Token" -msgstr "Токен авторизации AI Agent REST API" - msgid "AI API Key" msgstr "API-ключ ИИ" +msgid "AI Chat & Tachyon Assistant" +msgstr "ИИ Чат & Ассистент Tachyon" + +msgid "AI Chat Assistant" +msgstr "" + msgid "AI Doctor (ChatGPT / DeepSeek API)" msgstr "AI Doctor (ChatGPT / DeepSeek API)" msgid "AI Doctor Diagnosis" msgstr "" -msgid "AI Doctor Diagnostic Scan in Progress..." -msgstr "" - msgid "AI Doctor failed" msgstr "" @@ -182,6 +89,9 @@ msgstr "" msgid "AI Provider" msgstr "Провайдер ИИ" +msgid "AI service error" +msgstr "Ошибка ИИ-сервиса" + msgid "AI Watchdog" msgstr "ИИ Watchdog" @@ -191,159 +101,39 @@ msgstr "Настройки AI Watchdog сохранены. Перезапуст msgid "All" msgstr "Все" -msgid "All except selected" -msgstr "Все кроме выбранных" - -msgid "All fixes applied successfully" -msgstr "" - -msgid "All remaining except selected" -msgstr "Все оставшиеся кроме выбранных" - -msgid "All remaining servers" -msgstr "Все оставшиеся серверы" - -msgid "All remaining servers means every server not already assigned to a higher-priority level." -msgstr "Все оставшиеся серверы — это все серверы, не назначенные на уровень с более высоким приоритетом." +msgid "All Profiles" +msgstr "Все сервисы и профили" msgid "All Routes" msgstr "Все маршруты" -msgid "All servers" -msgstr "Все серверы" - -msgid "All traffic from these IP addresses will be routed through the section unconditionally, ignoring all other conditions." -msgstr "Весь трафик с этих IP-адресов будет направляться через секцию безусловно, игнорируя все остальные условия." - -msgid "Allow Insecure TLS" -msgstr "Разрешить небезопасный TLS" - -msgid "Allowed domain prefixes are full:, keyword:, and regex:" -msgstr "Допустимые префиксы доменов: full:, keyword: и regex:" - -msgid "Allows access to YACD from the WAN. Make sure to open the appropriate port in your firewall." -msgstr "Обеспечивает доступ к YACD из WAN. Убедитесь, что в брандмауэре открыт соответствующий порт." - -msgid "Allows limiting the list of servers for URLTest" -msgstr "Позволяет ограничить список серверов для URLTest" - -msgid "Allows Tachyon to send diagnostic snapshots to ChatGPT or DeepSeek API for intelligent root-cause analysis and auto-repair recommendations." -msgstr "Позволяет Tachyon отправлять снимки диагностики в ChatGPT или DeepSeek API для интеллектуального анализа причин неисправностей и рекомендаций по авто-ремонту." - -msgid "ALPN" -msgstr "ALPN" - -msgid "Alter ID" -msgstr "Alter ID" - -msgid "AmneziaWG config loaded successfully!" -msgstr "Конфиг AmneziaWG успешно загружен!" - -msgid "AmneziaWG Generator" -msgstr "Генератор AmneziaWG" - -msgid "An error occurred while checking services." -msgstr "" - -msgid "Analyzing system log (logread & errors)" -msgstr "" - -msgid "API Key for OpenAI (sk-...) or DeepSeek (optional for Ollama / LM Studio)" -msgstr "" - -msgid "Apply rules of this section only to selected protocols." -msgstr "Применять правила этой секции только к выбранным протоколам." - -msgid "Apply section rules only to the specified local IP addresses" -msgstr "Применять правила секции только к указанным локальным IP-адресам" - -msgid "Applying all fixes..." -msgstr "" - msgid "Applying fix" msgstr "" -msgid "At least one Admin Chat ID is required" -msgstr "Требуется хотя бы один Admin Chat ID" - -msgid "At least one valid domain must be specified." -msgstr "Необходимо указать хотя бы один корректный домен." - -msgid "At least one valid IP or subnet must be specified." -msgstr "Необходимо указать хотя бы один корректный IP или подсеть." - -msgid "Auth Digest" -msgstr "Алгоритм аутентификации" +msgid "Ask Tachyon AI Assistant a question..." +msgstr "Задайте вопрос ИИ-ассистенту..." msgid "Auto refresh" msgstr "Автообновление" -msgid "Auto update" -msgstr "Автообновление" - -msgid "Auto-detected domains" -msgstr "Авто-добавленные домены" - -msgid "Auto-detected Domains" -msgstr "Авто-добавленные домены" - msgid "Auto-detects blocked domains from logs and adds them to the first section where they work via proxy." msgstr "Автоматически определяет заблокированные домены из логов и добавляет их в первую секцию, где они работают через прокси." -msgid "Auto-generate HWID" -msgstr "Автогенерация HWID" - -msgid "Auto-update Hosts Lists" -msgstr "Автообновление списков хостов" - -msgid "Automatic component update checks" -msgstr "Автоматическая проверка обновлений компонентов" - -msgid "Automatic User-Agent selection" -msgstr "Автоматический выбор User-Agent" - -msgid "Automatically add text to the name of each server from this subscription for convenient filtering." -msgstr "Автоматически добавлять текст к имени каждого сервера из этой подписки для удобной фильтрации." - -msgid "Automatically check installed components for new versions" -msgstr "Автоматически проверять наличие новых версий установленных компонентов" - -msgid "Automatically generate a Cloudflare WARP account and configure all AmneziaWG settings." -msgstr "Автоматически сгенерировать аккаунт Cloudflare WARP и настроить все параметры AmneziaWG." - -msgid "Automatically increase check intervals when healthy (to 5 min) and decrease on problems (to 120s)." -msgstr "Автоматически увеличивает интервалы при стабильности (до 5 мин) и уменьшает при проблемах (до 120с)." - msgid "Automatically select the fastest node in the current level" msgstr "Автовыбор самого быстрого узла уровня" -msgid "Automatically update remote hosts lists on schedule" -msgstr "Автоматически обновлять удалённые списки хостов по расписанию" - msgid "Available actions" msgstr "Доступные действия" -msgid "Backend validation failed: %s" -msgstr "Ошибка валидации на бэкенде: %s" +msgid "Avg Latency" +msgstr "Ср. задержка" msgid "Bearer Auth Token" msgstr "Токен авторизации (Bearer)" -msgid "Belarus (by)" -msgstr "Беларусь (by)" - -msgid "BitTorrent / P2P" -msgstr "BitTorrent / P2P Торренты" - msgid "Bootstrap DNS" msgstr "Bootstrap DNS" -msgid "Bootstrap DNS Servers" -msgstr "Bootstrap DNS-серверы" - -msgid "Bot Status" -msgstr "Статус бота" - msgid "Browser FakeIP check could not be completed" msgstr "Не удалось выполнить проверку FakeIP в браузере" @@ -356,24 +146,6 @@ msgstr "Браузер использует FakeIP" msgid "Bug report downloaded" msgstr "Отчёт об ошибке загружен" -msgid "Built-in rule sets" -msgstr "Встроенные наборы правил" - -msgid "By flag emoji from name" -msgstr "По эмодзи флага из имени" - -msgid "ByeDPI listen address and port are assigned by Tachyon and must not be set in the strategy." -msgstr "Адрес и порт прослушивания ByeDPI назначаются Tachyon и не должны указываться в стратегии." - -msgid "ByeDPI option does not accept a compact value: %s" -msgstr "Опция ByeDPI не принимает компактное значение: %s" - -msgid "ByeDPI option does not accept a value: %s" -msgstr "Опция ByeDPI не принимает значение: %s" - -msgid "ByeDPI option requires a value: %s" -msgstr "Опция ByeDPI требует значение: %s" - msgid "ByeDPI package is installed" msgstr "Пакет ByeDPI установлен" @@ -392,93 +164,51 @@ msgstr "Outbound ByeDPI в sing-box настроен" msgid "ByeDPI sing-box outbound is not configured" msgstr "Outbound ByeDPI в sing-box не настроен" -msgid "ByeDPI Strategy" -msgstr "Стратегия ByeDPI" - -msgid "ByeDPI strategy cannot be empty" -msgstr "Стратегия ByeDPI не может быть пустой" - -msgid "Bypasses UDP traffic for selected game consoles (PS5/Xbox) to achieve NAT Type 1 / 2 (Full Cone NAT) for P2P matchmaking, while keeping TCP (PSN/Auth) routed through the proxy." -msgstr "Направляет UDP трафик выбранных консолей (PS5/Xbox) в обход прокси напрямую (Full Cone NAT) для идеального P2P матчмейкинга, оставляя TCP трафик (PSN/Auth) под защитой прокси." - -msgid "CA Certificate" -msgstr "CA сертификат" - -msgid "Cache all built-in lists and databases even if they are not currently selected in any section. Recommended if you have plenty of storage space or USB drive." -msgstr "Кешировать все встроенные списки и базы (даже если они не выбраны ни в одной секции). Рекомендуется при наличии свободного места или USB-накопителя." - -msgid "Cache File Path" -msgstr "Путь к файлу кэша" - -msgid "Cache file path cannot be empty" -msgstr "Путь к файлу кэша не может быть пустым" - -msgid "Cancel" -msgstr "Отмена" - msgid "Cannot receive checks result" msgstr "Не удалось получить результаты проверки" -msgid "Cannot save server" -msgstr "Не удалось сохранить сервер" +msgid "Check Again" +msgstr "Проверить снова" -msgid "Cannot save settings" -msgstr "Не удалось сохранить настройки" - -msgid "Cascade connection" -msgstr "Каскадное подключение" - -msgid "Certificate path" -msgstr "Путь к сертификату" - -msgid "Certificate pin is unavailable. Apply or restart the server to generate the default certificate, then open this dialog again." -msgstr "Пин сертификата недоступен. Примените или перезапустите сервер, чтобы сгенерировать дефолтный сертификат, затем откройте это окно снова." +msgid "Check All" +msgstr "Проверить все" msgid "Check Connection" msgstr "Проверить подключение" -msgid "Check Custom Domain" -msgstr "" +msgid "Check Custom" +msgstr "Проверить свой" + +msgid "Check domain or IP (e.g. example.com)..." +msgstr "Проверить домен или IP (напр. example.com)..." msgid "Check interval" msgstr "Интервал проверки" +msgid "Check Mode:" +msgstr "Режим проверки:" + msgid "Check Services" msgstr "" -msgid "Check timeout after which the server is considered dead" -msgstr "Таймаут проверки, после которого сервер считается недоступным" - msgid "Check update" msgstr "Проверить обновление" msgid "Check URL" msgstr "URL проверки" +msgid "Check YouTube" +msgstr "Проверить YouTube" + msgid "Checking Connection..." msgstr "Проверка соединения..." -msgid "Checking nftables filtering tables" -msgstr "" - -msgid "Checking sing-box service & DNSmasq" -msgstr "" - -msgid "Checking WAN interfaces & network routing" -msgstr "" - -msgid "Checking Zapret & ByeDPI rules" -msgstr "" - msgid "Checking, please wait" msgstr "Проверяем, пожалуйста подождите" msgid "Checking..." msgstr "Проверка..." -msgid "Checking…" -msgstr "Проверка…" - msgid "checks" msgstr "проверки" @@ -491,45 +221,9 @@ msgstr "Проверки пройдены" msgid "Checks passed with manual DHCP" msgstr "Проверки пройдены с ручным DHCP" -msgid "China (cn)" -msgstr "Китай (cn)" - -msgid "Choose Hosts File..." -msgstr "Выбрать hosts-файл..." - -msgid "Choose whether to route traffic to all destinations except selected countries (Exclude) or only to selected countries (Include)." -msgstr "Выберите, направлять ли трафик во все назначения кроме выбранных стран (Исключить) или только в выбранные страны (Включить)." - msgid "CIDR must be between 0 and 32 for IPv4 or 0 and 128 for IPv6" msgstr "CIDR должен быть от 0 до 32 для IPv4 или от 0 до 128 для IPv6" -msgid "Cipher" -msgstr "Шифрование" - -msgid "Clean Comments" -msgstr "Очистить комментарии" - -msgid "Clear" -msgstr "Сбросить" - -msgid "Client Certificate" -msgstr "Сертификат клиента" - -msgid "Client fingerprint" -msgstr "Отпечаток клиента" - -msgid "Client Key" -msgstr "Ключ клиента" - -msgid "Client link" -msgstr "Ссылка клиента" - -msgid "Client link is not available yet" -msgstr "Ссылка клиента пока недоступна" - -msgid "Client link QR code" -msgstr "QR-код клиентской ссылки" - msgid "Close" msgstr "Закрыть" @@ -542,66 +236,21 @@ msgstr "Закрыть подключение" msgid "Closed" msgstr "Закрытые" -msgid "Cloudflare account / device ID" -msgstr "ID аккаунта / устройства Cloudflare" - -msgid "Cloudflare API access token" -msgstr "Токен доступа Cloudflare API" - -msgid "Cloudflare WARP account / device ID" -msgstr "ID аккаунта / устройства Cloudflare WARP" - -msgid "Cloudflare WARP API access token" -msgstr "Токен доступа к API Cloudflare WARP" - -msgid "Comma-separated list of Telegram user IDs authorized to control the bot." -msgstr "Список ID пользователей Telegram через запятую, которым разрешено управлять ботом." - -msgid "Community Lists" -msgstr "Списки сообщества (Community Lists)" - msgid "Component update available" msgstr "Доступно обновление компонента" -msgid "Component update check interval" -msgstr "Период проверки обновлений" - -msgid "Components" -msgstr "Компоненты" - msgid "compressed" msgstr "compressed" -msgid "Concurrency" -msgstr "Параллелизм" - -msgid "Conditions" -msgstr "Условия" - -msgid "Config File Path" -msgstr "Путь к файлу конфигурации" - -msgid "Configuration for Tachyon service" -msgstr "Настройки сервиса Tachyon" - -msgid "Configure User-Agent in the item settings" -msgstr "Настройте User-Agent в настройках элемента" - msgid "Conflict" msgstr "Конфликт" msgid "Connect ChatGPT, DeepSeek or local LLM to get automated diagnostic reports and intelligent root-cause analysis." msgstr "Подключите ChatGPT, DeepSeek или локальную модель LLM для получения автоматических диагностических отчётов и умного анализа сетевых проблем." -msgid "Connect through" -msgstr "Подключаться через" - msgid "Connected" msgstr "Подключено" -msgid "Connection URL" -msgstr "URL подключения" - msgid "Connections are unavailable" msgstr "Подключения недоступны" @@ -620,84 +269,27 @@ msgstr "Скопировать ссылку прокси" msgid "Could not compare FakeIP and control public IPs" msgstr "Не удалось сравнить публичные IP FakeIP и контрольной проверки" -msgid "Country code (e.g. ru, us, de)" -msgstr "Код страны (например, ru, us, de)" - msgid "Current Diagnosis" msgstr "" -msgid "Current section cannot be used as its own transit section" -msgstr "Текущая секция не может быть транзитной для самой себя" - -msgid "Current section cannot download its own subscription" -msgstr "Текущая секция не может скачивать собственную подписку" - msgid "Currently unavailable" msgstr "Временно недоступно" msgid "Custom API Endpoint URL" msgstr "Пользовательский URL эндпоинта API" -msgid "Custom device headers" -msgstr "Кастомные заголовки устройства" - -msgid "Custom DNS Records (Hosts)" -msgstr "Пользовательские записи DNS (Hosts)" - -msgid "Custom domain (e.g. google.com)" -msgstr "" - -msgid "Custom OpenAI-Compatible API (OpenRouter)" -msgstr "" - -msgid "Custom OpenAI-compatible API endpoint URL (e.g. http://192.168.1.100:11434/v1/chat/completions)" -msgstr "" - -msgid "Custom outbound configurations in JSON format" -msgstr "Пользовательские конфигурации outbound в формате JSON" - -msgid "Dashboard" -msgstr "Дашборд" - msgid "Dashboard currently unavailable" msgstr "Дашборд сейчас недоступен" -msgid "Default (auto)" -msgstr "По умолчанию (авто)" - -msgid "Default address for checking server availability and latency. URLTest uses its own address." -msgstr "Адрес по умолчанию для проверки доступности и задержки серверов. Для URLTest используется собственный адрес." - -msgid "Delay in milliseconds before reloading Tachyon after interface UP" -msgstr "Задержка в миллисекундах перед перезапуском Tachyon после поднятия интерфейса" - -msgid "Delay value cannot be empty" -msgstr "Значение задержки не может быть пустым" - -msgid "Delete" -msgstr "Удалить" - -msgid "Detect server country" -msgstr "Определять страну сервера" - -msgid "Detects and drops STUN/TURN packets in nftables to prevent real IP leaks via WebRTC." -msgstr "Детектирует и отбрасывает пакеты STUN/TURN в nftables для предотвращения утечек реального IP-адреса через WebRTC." - msgid "detour must be a non-empty string" msgstr "detour должен быть непустой строкой" -msgid "Device filter" -msgstr "Фильтр устройств" - msgid "Device IPs (one per line):" msgstr "IP устройств (по одному на строку):" msgid "Device IPs saved" msgstr "IP устройств сохранены" -msgid "Device or IP" -msgstr "Устройство или IP" - msgid "Devices listed here are always routed through the assigned section, regardless of global rules." msgstr "Устройства из этого списка всегда маршрутизируются через назначенную секцию, независимо от глобальных правил." @@ -707,132 +299,24 @@ msgstr "DHCP содержит DNS сервер" msgid "DHCP is managed manually" msgstr "DHCP управляется вручную" -msgid "Diagnostics" -msgstr "Диагностика" - -msgid "Direct" -msgstr "Напрямую" - -msgid "Direct (Default)" -msgstr "Напрямую (по умолчанию)" - -msgid "Direct connection" -msgstr "Прямое подключение" - msgid "Disable autostart" msgstr "Отключить автостарт" -msgid "Disable QUIC" -msgstr "Отключить QUIC" - -msgid "Disable the QUIC protocol to improve compatibility or fix issues with video streaming" -msgstr "Отключить QUIC протокол для улучшения совместимости или исправления видео стриминга" - -msgid "Disabling interception is incompatible with action=zapret2 because Tachyon sends matched traffic through NFQUEUE." -msgstr "Отключение перехвата несовместимо с action=zapret2, так как Tachyon направляет совпадающий трафик через NFQUEUE." - -msgid "Display name" -msgstr "Отображаемое имя" - -msgid "DNS" -msgstr "DNS" - -msgid "DNS Check Interval" -msgstr "Период проверки DNS" - -msgid "DNS Check Interval (s)" -msgstr "Интервал проверки DNS (с)" - -msgid "DNS Failures Before Switching" -msgstr "Ошибок DNS перед переключением" - msgid "DNS on router" msgstr "DNS на роутере" -msgid "DNS over HTTPS (DoH)" -msgstr "DNS через HTTPS (DoH)" - -msgid "DNS over QUIC (DoQ)" -msgstr "DNS over QUIC (DoQ)" - -msgid "DNS over TLS (DoT)" -msgstr "DNS через TLS (DoT)" - -msgid "DNS protocol" -msgstr "DNS протокол" - -msgid "DNS Protocol Type" -msgstr "Тип протокола DNS" - -msgid "DNS protocol used by the resolver" -msgstr "Протокол DNS, используемый резолвером" - -msgid "DNS requests through section" -msgstr "DNS-запросы через секцию" - -msgid "DNS Rewrite TTL" -msgstr "Перезапись TTL для DNS" - -msgid "DNS server" -msgstr "DNS сервер" - msgid "DNS server address cannot be empty" msgstr "Адрес DNS-сервера не может быть пустым" -msgid "DNS server used by the resolver" -msgstr "DNS сервер, используемый резолвером" - -msgid "DNS server used to obtain IP addresses for upstream DNS and proxies. If multiple servers are selected, a timeout switches to a backup." -msgstr "DNS-сервер для получения IP вышестоящих DNS и прокси. Если выбрать несколько, то при таймауте произойдёт переключение на резервный." - -msgid "DNS Servers" -msgstr "DNS-серверы" - -msgid "DNS Settings" -msgstr "" - -msgid "DNS Strategy" -msgstr "Стратегия DNS" - -msgid "DNS Successful Checks Before Recovery" -msgstr "Успешных проверок DNS перед восстановлением" - -msgid "DNS through proxy" -msgstr "DNS через прокси" - -msgid "DNS through section" -msgstr "DNS через секцию" - msgid "DNS Turbo Cache" msgstr "Быстрый DNS-кэш" msgid "DNS Turbo Cache saved" msgstr "DNS Turbo Cache сохранён" -msgid "DNS Unavailability Timeout" -msgstr "Таймаут недоступности DNS" - msgid "Do not panic, everything can be fixed, just..." msgstr "Не паникуйте, всё можно исправить, просто..." -msgid "Do not test servers from these countries." -msgstr "Не тестировать серверы из этих стран." - -msgid "Do not test servers whose names match the expression." -msgstr "Не тестировать серверы, имена которых совпадают с выражением." - -msgid "Do not test servers with one of the selected protocols." -msgstr "Не тестировать серверы с одним из выбранных протоколов." - -msgid "Do not test servers with one of the selected security types." -msgstr "Не тестировать серверы с одним из выбранных типов безопасности." - -msgid "Do not test servers with one of the selected transports." -msgstr "Не тестировать серверы с одним из выбранных транспортов." - -msgid "Do not test specified servers." -msgstr "Не тестировать указанные серверы." - msgid "Doctor failed" msgstr "Доктор завершился с ошибкой" @@ -842,260 +326,35 @@ msgstr "Исправление доктором" msgid "Does not resolve" msgstr "Не резолвится" -msgid "Domain and IP lists" -msgstr "Списки доменов и IP" - -msgid "Domain lists" -msgstr "Списки доменов" - -msgid "Domain Resolver" -msgstr "Резолвер доменов" - -msgid "Domain test sections" -msgstr "Секции тестирования доменов" - -msgid "Domains" -msgstr "Домены (Domains)" - -msgid "Domains automatically detected by Smart Detect or added via Telegram bot. You can manually edit or remove them here." -msgstr "Домены, автоматически обнаруженные Smart Detect или добавленные через Telegram-бота. Вы можете вручную изменить или удалить их здесь." - -msgid "Done" -msgstr "Готово" - -msgid "Dont Touch My DHCP!" -msgstr "Отключить управление DHCP" - msgid "Downlink" msgstr "Входящий" msgid "Download" msgstr "Скачать" -msgid "Download component packages via the selected section" -msgstr "Скачивать пакеты компонентов через выбранную секцию" - -msgid "Download components through" -msgstr "Скачивать компоненты через" - -msgid "Download components through a section" -msgstr "Скачивать компоненты через секцию" - -msgid "Download lists through" -msgstr "Скачивать списки через" - -msgid "Download lists through a section" -msgstr "Скачивать списки через секцию" - -msgid "Download remote lists and rule sets via the selected section" -msgstr "Скачивать удаленные списки и наборы правил через выбранную секцию" - -msgid "Download subscription through a section" -msgstr "Скачивать подписку через секцию" - -msgid "Download subscriptions via the selected section" -msgstr "Скачивать подписки через выбранную секцию" - -msgid "Download through" -msgstr "Скачивать через" - msgid "Downloaded" msgstr "Загружено" -msgid "Drag rows to change priority. The rule at the top is checked first." -msgstr "Перетаскивайте строки, чтобы изменить приоритет. Правило сверху проверяется первым." - -msgid "DSCP marks (QoS)" -msgstr "DSCP-метки (QoS)" - msgid "Duplicate JSON outbound tag" msgstr "Такой тег JSON outbound уже используется" -msgid "Duplicate value" -msgstr "Дублирующееся значение" - -msgid "e.g. AES-256-GCM — leave empty for default" -msgstr "например AES-256-GCM — оставьте пустым для значения по умолчанию" - -msgid "e.g. google.com, 1.1.1.1, 443" -msgstr "например: google.com, 1.1.1.1, 443" - -msgid "e.g. SHA256 — leave empty for default" -msgstr "например SHA256 — оставьте пустым для значения по умолчанию" - -msgid "Edit rule action" -msgstr "Изменить" - -msgid "Enable" -msgstr "Включить" - -msgid "Enable Adaptive Intervals" -msgstr "Адаптивные интервалы" - -msgid "Enable AI Doctor (ChatGPT / LLM Analysis)" -msgstr "Включить AI Doctor (анализ через ChatGPT / LLM)" - msgid "Enable AI Doctor (LLM Integration)" msgstr "Включить AI Doctor (интеграция с LLM)" -msgid "Enable Anomaly Detection" -msgstr "Обнаружение аномалий" - -msgid "Enable authentication" -msgstr "Включить авторизацию" - -msgid "Enable automatic updates for remote lists and rule sets" -msgstr "Включить автоматическое обновление удалённых списков и наборов правил" - msgid "Enable autostart" msgstr "Включить автостарт" -msgid "Enable built-in DNS resolver for domains handled by this section" -msgstr "Включить встроенный DNS резолвер для доменов, обрабатываемых этой секцией" - -msgid "Enable Config Validation" -msgstr "Валидация конфига" - -msgid "Enable DNS Continuous Check" -msgstr "Непрерывная проверка DNS" - msgid "Enable DNS Turbo Cache" msgstr "Включить быстрый DNS-кэш" -msgid "Enable Firewall Reload Dedup" -msgstr "Дедупликация перезагрузки файрвола" - -msgid "Enable Graceful Degradation" -msgstr "Graceful Degradation" - -msgid "Enable Health Metrics" -msgstr "Метрики здоровья" - -msgid "Enable list updates" -msgstr "Включить обновление списков" - -msgid "Enable Mixed Proxy" -msgstr "Включить смешанный прокси" - -msgid "Enable Mixed Proxy Authentication" -msgstr "Включить аутентификацию смешанного прокси" - -msgid "Enable Output Network Interface" -msgstr "Включить выходной сетевой интерфейс" - -msgid "Enable Proxy Health Monitor" -msgstr "Мониторинг здоровья прокси" - -msgid "Enable Smart Cooldowns" -msgstr "Smart Cooldowns" - msgid "Enable Smart Detect" msgstr "Включить Smart Detect" -msgid "Enable Telegram Bot" -msgstr "Включить Telegram-бота" - -msgid "Enable WAN DNS Fallback for Bootstrap DNS" -msgstr "Разрешить резервный WAN DNS для Bootstrap DNS" - -msgid "Enable WAN DNS Fallback for Main DNS" -msgstr "Разрешить резервный WAN DNS для Main DNS" - -msgid "Enable Watchdog" -msgstr "Включить сторожевой таймер (Watchdog)" - -msgid "Enable YACD" -msgstr "Включить YACD" - -msgid "Enable YACD WAN Access" -msgstr "Включить доступ YACD WAN" - -msgid "Enables the background daemon that polls Telegram for commands and sends notifications." -msgstr "Включает фоновый процесс, который опрашивает Telegram на наличие команд и отправляет уведомления." - -msgid "Enables the background watchdog process to monitor services and auto-recover on failures." -msgstr "Включает фоновый процесс watchdog для мониторинга служб и автоматического восстановления при сбоях." - -msgid "Enter a complete sing-box inbound object" -msgstr "Введите полный объект inbound sing-box" - -msgid "Enter a complete sing-box outbound object" -msgstr "Введите полный объект outbound для sing-box" - -msgid "Enter a display name" -msgstr "Введите отображаемое имя" - -msgid "Enter a level name" -msgstr "Введите название уровня" - -msgid "Enter HWID" -msgstr "Введите HWID" - -msgid "Enter the API token obtained from @BotFather." -msgstr "Введите токен API, полученный от @BotFather." - -msgid "Enter the HWID sent with subscription requests" -msgstr "Введите HWID, отправляемый с запросами подписки" - -msgid "Enter the subscription URL" -msgstr "Введите URL подписки" - -msgid "Error" -msgstr "Ошибка" - -msgid "Error running generator:" -msgstr "Ошибка запуска генератора:" - -msgid "Error running trace:" -msgstr "Ошибка при выполнении трассировки:" - -msgid "Exclude by proxy parameters" -msgstr "Исключить по параметрам прокси" - -msgid "Exclude by regular expression" -msgstr "Исключить по регулярному выражению" - -msgid "Exclude countries" -msgstr "Исключить страны" - -msgid "Exclude selected countries" -msgstr "Исключить выбранные страны" - -msgid "Exclude servers" -msgstr "Исключить серверы" - -msgid "Exclude servers with one of the selected protocols from this level." -msgstr "Исключить с этого уровня серверы с одним из выбранных протоколов." - -msgid "Exclude servers with one of the selected security types from this level." -msgstr "Исключить с этого уровня серверы с одним из выбранных типов безопасности." - -msgid "Exclude servers with one of the selected transports from this level." -msgstr "Исключить с этого уровня серверы с одним из выбранных транспортов." - -msgid "Exclude traffic types" -msgstr "Исключать типы трафика" - -msgid "Exclude URLTest / Priority group" -msgstr "Исключить URLTest / группу приоритетов" - -msgid "Excluded devices" -msgstr "Исключённые устройства" - -msgid "Expecting: %s" -msgstr "Ожидается: %s" - msgid "Expires" msgstr "Истекает" -msgid "Expose this section as a local HTTP+SOCKS proxy" -msgstr "Предоставить эту секцию как локальный HTTP+SOCKS прокси" - -msgid "External nfqws config files bypass Tachyon queue management and explicit validation." -msgstr "Внешние файлы конфигурации nfqws обходят управление очередями Tachyon и явную валидацию." - -msgid "External nfqws2 config files bypass Tachyon queue management and explicit validation." -msgstr "Внешние файлы конфигурации nfqws2 обходят управление очередями Tachyon и явную валидацию." +msgid "Failed" +msgstr "Ошибки" msgid "Failed to apply fix" msgstr "" @@ -1112,23 +371,17 @@ msgstr "Не удалось скопировать!" msgid "Failed to execute" msgstr "Не удалось выполнить" -msgid "Failed to execute service check." -msgstr "" - msgid "Failed to generate bug report" msgstr "Не удалось создать отчёт об ошибке" -msgid "Failed to generate WARP config:" -msgstr "Не удалось создать конфиг WARP:" +msgid "Failed to parse target list." +msgstr "Ошибка обработки списка целей." -msgid "Failed to parse file:" -msgstr "Не удалось разобрать файл:" +msgid "Failed to receive response from AI service." +msgstr "Не удалось получить ответ от ИИ-сервиса." -msgid "Failed to parse service check results." -msgstr "" - -msgid "Failed to parse WARP config:" -msgstr "Не удалось разобрать конфиг WARP:" +msgid "Failed to run service check." +msgstr "Не удалось выполнить проверку сервисов." msgid "Failed to save AI Watchdog settings" msgstr "Ошибка сохранения настроек AI Watchdog" @@ -1142,18 +395,6 @@ msgstr "Не удалось сохранить DNS Turbo Cache" msgid "Failed to save Smart Detect settings" msgstr "Ошибка сохранения настроек Smart Detect" -msgid "Failed to start bot" -msgstr "Ошибка запуска бота" - -msgid "Failed to start watchdog" -msgstr "Ошибка запуска watchdog" - -msgid "Failed to stop bot" -msgstr "Ошибка остановки бота" - -msgid "Failed to stop watchdog" -msgstr "Ошибка остановки watchdog" - msgid "Failed to update subscriptions" msgstr "Не удалось обновить подписки" @@ -1166,108 +407,33 @@ msgstr "FakeIP и контрольная проверка используют msgid "FakeIP works; public IP comparison is inconclusive" msgstr "FakeIP работает; сравнение публичных IP не дает однозначного результата" -msgid "FakeTLS host" -msgstr "FakeTLS-хост" - -msgid "Fallback on unknown DC" -msgstr "Fallback для неизвестного DC" - -msgid "Faster DNS health monitoring than the default cycle. Switches bootstrap DNS on failure." -msgstr "Быстрый мониторинг DNS по умолчанию. Переключает bootstrap DNS при сбое." - msgid "Faster server search interval" msgstr "Интервал поиска более быстрого сервера" msgid "Fastest" msgstr "Самый быстрый" -msgid "Fetching service status, please wait..." -msgstr "" - -msgid "Filter the servers that will be displayed on the dashboard." -msgstr "Фильтровать серверы, отображаемые на дашборде." - -msgid "Finland (fi)" -msgstr "Финляндия (fi)" +msgid "Fetching service targets..." +msgstr "Получение списка сервисов..." msgid "Firewall WAN port" msgstr "Порт в firewall для WAN" -msgid "Fix All" -msgstr "" - msgid "Fix applied" msgstr "" -msgid "Fix the highlighted fields and save again." -msgstr "Исправьте подсвеченные поля и сохраните снова." - msgid "Fixed" msgstr "Исправлено" -msgid "Forced device routing" -msgstr "Принудительная маршрутизация устройств" - -msgid "Forces sing-box to tunnel DNS requests via DoQ with Encrypted Client Hello (ECH) for SNI hiding." -msgstr "Принудительно направляет DNS-запросы через DoQ с Encrypted Client Hello (ECH) для скрытия SNI." - -msgid "France (fr)" -msgstr "Франция (fr)" - -msgid "Fronting IP" -msgstr "IP фронтинга" - -msgid "Fronting port" -msgstr "Порт фронтинга" - -msgid "Fronting proxy protocol" -msgstr "Proxy protocol для фронтинга" - -msgid "Fuzzing is not supported here because Tachyon needs deterministic runtime validation." -msgstr "Фаззинг здесь не поддерживается, так как Tachyon требует детерминированной валидации во время выполнения." - -msgid "Game Console IPs" -msgstr "IP-адреса игровых консолей" - -msgid "Game Console Optimizer (NAT Type 1)" -msgstr "Оптимизатор игровых консолей (NAT Type 1)" - -msgid "Generate a random 16-character hexadecimal HWID" -msgstr "Сгенерировать случайный 16-символьный шестнадцатеричный HWID" +msgid "Full System Diagnostic" +msgstr "Полная диагностика" msgid "Generate bug report" msgstr "Сгенерировать баг-репорт" -msgid "Generate HWID" -msgstr "Сгенерировать HWID" - -msgid "Generate HWID from router hardware information for this subscription" -msgstr "Генерировать HWID из аппаратной информации роутера для этой подписки" - -msgid "Generate WARP Config" -msgstr "Сгенерировать конфиг WARP" - msgid "Generated inbound" msgstr "Созданный inbound" -msgid "Generated!" -msgstr "Сгенерировано!" - -msgid "Generating…" -msgstr "Генерация…" - -msgid "GeoIP Countries" -msgstr "Страны для фильтрации GeoIP" - -msgid "GeoIP Mode" -msgstr "Режим фильтрации GeoIP" - -msgid "GeoSite / GeoIP" -msgstr "GeoSite / GeoIP" - -msgid "Germany (de)" -msgstr "Германия (de)" - msgid "GET endpoints are open on LAN. POST endpoints require Authorization: Bearer ." msgstr "GET-эндпоинты открыты в локальной сети. POST-эндпоинты требуют Authorization: Bearer ." @@ -1277,47 +443,11 @@ msgstr "Получить глобальную проверку" msgid "Global check" msgstr "Глобальная проверка" -msgid "gRPC service" -msgstr "gRPC-сервис" - -msgid "Handshake timeout" -msgstr "Таймаут рукопожатия" - msgid "Health Checks" msgstr "Проверки здоровья" -msgid "Hide cascade connection nodes" -msgstr "Скрыть узлы каскадных подключений" - -msgid "Hide individual nodes that are already included in imported subscription URLTest groups" -msgstr "Скрыть отдельные узлы, уже включённые в импортированные группы URLTest подписки" - -msgid "Hide intermediate nodes used as detours by other subscription nodes" -msgstr "Скрыть промежуточные узлы, используемые как транзиты другими узлами подписки" - -msgid "Hide selected servers." -msgstr "Скрыть выбранные серверы." - -msgid "Hide servers from selected groups without repeating their filtering criteria." -msgstr "Скрыть серверы из выбранных групп без повторения их критериев фильтрации." - -msgid "Hide servers from the specified countries." -msgstr "Скрыть серверы из указанных стран." - -msgid "Hide servers whose names match the expression." -msgstr "Скрыть серверы, имена которых совпадают с выражением." - -msgid "Hide servers with one of the selected protocols." -msgstr "Скрыть серверы с одним из выбранных протоколов." - -msgid "Hide servers with one of the selected security types." -msgstr "Скрыть серверы с одним из выбранных типов безопасности." - -msgid "Hide servers with one of the selected transports." -msgstr "Скрыть серверы с одним из выбранных транспортов." - -msgid "Hide URLTest group nodes" -msgstr "Скрыть узлы группы URLTest" +msgid "Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings." +msgstr "Привет! Я ИИ-ассистент Tachyon. Чем могу помочь? Задайте вопрос о блокировках, диагностике или настройках роутера." msgid "Hide values" msgstr "Скрывать значения" @@ -1325,135 +455,24 @@ msgstr "Скрывать значения" msgid "Higher-level check interval" msgstr "Интервал проверки высших уровней" -msgid "Higher-priority DNS Check" -msgstr "Проверка верхних DNS" +msgid "History" +msgstr "" msgid "Host" msgstr "Хост" -msgid "Hosts" -msgstr "Хосты" - -msgid "Hosts Lists Update Interval" -msgstr "Интервал обновления списков хостов" - -msgid "How many hours of metrics to keep (default 24)." -msgstr "Сколько часов хранить метрики (по умолчанию 24)." - -msgid "How often higher priority levels are checked while a lower level is active" -msgstr "Как часто проверяются уровни с более высоким приоритетом, пока активен уровень с более низким" - -msgid "How often the currently selected server is checked" -msgstr "Как часто проверяется текущий выбранный сервер" - -msgid "How often to check DNS health in seconds (default 60)." -msgstr "Как часто проверять DNS в секундах (по умолчанию 60)." - -msgid "How often to check proxy health in seconds (fast tier, default 30)." -msgstr "Как часто проверять прокси в секундах (быстрый тир, по умолчанию 30)." - -msgid "How often to check Telegram for new messages (default: 5)." -msgstr "Как часто проверять Telegram на наличие новых сообщений (по умолчанию: 5)." - -msgid "How often to check the active DNS servers." -msgstr "Как часто проверять активные DNS-серверы." - -msgid "How often to check whether a higher-priority DNS server has recovered." -msgstr "Как часто проверять, восстановился ли DNS-сервер с более высоким приоритетом." - msgid "HTTP" msgstr "HTTP" -msgid "HTTP (ms)" -msgstr "" - msgid "HTTP error" msgstr "Ошибка HTTP" -msgid "HTTP hosts" -msgstr "HTTP-хосты" - msgid "HTTP REST API for external AI agents (Claude, GPT, Open-WebUI) served at /cgi-bin/tachyon-agent/" msgstr "HTTP REST API для внешних ИИ-агентов (Claude, GPT, Open-WebUI), доступен по адресу /cgi-bin/tachyon-agent/" -msgid "HWID" -msgstr "HWID" - msgid "Idle timeout" msgstr "Таймаут простоя" -msgid "If one health check fails with an error, continue running other checks instead of stopping." -msgstr "Если одна проверка падает с ошибкой, продолжает другие проверки вместо остановки." - -msgid "Import" -msgstr "Импортировать" - -msgid "Import (%d records)" -msgstr "Импортировать (%d записей)" - -msgid "Import AmneziaWG settings from .conf file" -msgstr "Импортировать настройки AmneziaWG из файла .conf" - -msgid "Import Hosts File" -msgstr "Импортировать hosts-файл" - -msgid "Import subscription URLTest groups" -msgstr "Импортировать группы URLTest подписки" - -msgid "Import URLTest groups returned by this subscription provider" -msgstr "Импортировать группы URLTest, возвращаемые этим провайдером подписок" - -msgid "Inbound JSON" -msgstr "Inbound JSON" - -msgid "Inbound JSON cannot be empty" -msgstr "Inbound JSON не может быть пустым" - -msgid "Inbound JSON must be an object with a type field" -msgstr "Inbound JSON должен быть объектом с полем type" - -msgid "Include by proxy parameters" -msgstr "Включить по параметрам прокси" - -msgid "Include by regular expression" -msgstr "Включить по регулярному выражению" - -msgid "Include countries" -msgstr "Включить страны" - -msgid "Include IP addresses and subnets" -msgstr "Включить IP-адреса и подсети" - -msgid "Include selected countries" -msgstr "Включить выбранные страны" - -msgid "Include servers" -msgstr "Включить серверы" - -msgid "Information" -msgstr "Информация" - -msgid "Init Packet Magic Header (S1)" -msgstr "Magic Header: Инициализация (S1)" - -msgid "Init Packet Magic Header (S3)" -msgstr "Magic Header: Инициализация (S3)" - -msgid "Init Packet Payload (I1)" -msgstr "Payload: Инициализация (I1)" - -msgid "Init Packet Payload (I2)" -msgstr "Payload: Инициализация (I2)" - -msgid "Init Packet Payload (I3)" -msgstr "Payload: Инициализация (I3)" - -msgid "Init Packet Payload (I4)" -msgstr "Payload: Инициализация (I4)" - -msgid "Init Packet Payload (I5)" -msgstr "Payload: Инициализация (I5)" - msgid "Install" msgstr "Установить" @@ -1466,30 +485,12 @@ msgstr "Установленная сборка → Доступная сбор msgid "Installed version is newer than release" msgstr "Установлена версия новее релиза" -msgid "Interface Monitoring" -msgstr "Мониторинг интерфейса" - -msgid "Interface Monitoring Delay" -msgstr "Задержка при мониторинге интерфейсов" - -msgid "Interface monitoring for Bad WAN" -msgstr "Мониторинг интерфейса для Bad WAN" - msgid "Interrupt connections" msgstr "Прерывать соединения" -msgid "Interrupt connections when priority failover switches server" -msgstr "Прерывать соединения при переключении сервера в режиме приоритета" - -msgid "Interrupt connections when URLTest switches the selected server" -msgstr "Прерывать соединения при переключении URLTest на другой сервер" - msgid "Interval" msgstr "Интервал" -msgid "Invalid ByeDPI strategy" -msgstr "Некорректная стратегия ByeDPI" - msgid "Invalid CIDR prefix" msgstr "Неверный префикс CIDR" @@ -1553,21 +554,12 @@ msgstr "Неверный IP-адрес" msgid "Invalid JSON format" msgstr "Неверный формат JSON" -msgid "Invalid line: \"%s\". Use: domain ip or ip domain" -msgstr "Неверная строка: \"%s\". Формат: домен ip или ip домен" - msgid "Invalid path format. Path must start with \"/\" and contain valid characters" msgstr "Неверный формат пути. Должен начинаться с \"/\" и содержать допустимые символы" msgid "Invalid port number. Must be between 1 and 65535" msgstr "Неверный номер порта. Допустимо от 1 до 65535" -msgid "Invalid port or range. Use 80 or 1000-2000" -msgstr "Некорректный порт или диапазон. Используйте 80 или 1000-2000" - -msgid "Invalid regular expression" -msgstr "Некорректное регулярное выражение" - msgid "Invalid Shadowsocks URL: decoded credentials must contain method:password" msgstr "Неверный URL Shadowsocks: декодированные данные должны содержать method:password" @@ -1691,36 +683,12 @@ msgstr "Неверный URL VLESS: ошибка разбора" msgid "Invalid VMess URL: parsing failed" msgstr "Некорректный VMess URL: ошибка разбора" -msgid "IP / DNS" -msgstr "" - -msgid "IP Addresses (IP CIDR)" -msgstr "IP-адреса и подсети (IP CIDR)" - -msgid "IPs" -msgstr "IP-адреса" - -msgid "IPv4 only" -msgstr "Только IPv4" - -msgid "IPv6 only" -msgstr "Только IPv6" - -msgid "Isolate BitTorrent traffic and force it direct to prevent VPN bans" -msgstr "Изолировать BitTorrent-трафик и направлять напрямую во избежание банов VPN" - msgid "Issues" msgstr "Проблемы" msgid "Issues detected" msgstr "Обнаружены проблемы" -msgid "Japan (jp)" -msgstr "Япония (jp)" - -msgid "JSON outbound" -msgstr "JSON outbound" - msgid "JSON outbound cannot be empty" msgstr "JSON outbound не может быть пустым" @@ -1733,102 +701,27 @@ msgstr "JSON outbound должен содержать непустое поле msgid "JSON outbound must contain a non-empty type field" msgstr "JSON outbound должен содержать непустое поле type" -msgid "JSON outbound settings" -msgstr "Настройки JSON outbound" - -msgid "Junk Max Size (Jmax)" -msgstr "Макс. размер Junk (Jmax)" - -msgid "Junk Min Size (Jmin)" -msgstr "Мин. размер Junk (Jmin)" - -msgid "Junk Packet Count (Jc)" -msgstr "Количество Junk-пакетов (Jc)" - -msgid "Kazakhstan (kz)" -msgstr "Казахстан (kz)" - -msgid "Keep Priority before latency-sorted servers" -msgstr "Держать Priority перед серверами, отсортированными по задержке" - -msgid "Keep URLTest before latency-sorted servers" -msgstr "Держать URLTest перед серверами, отсортированными по задержке" - msgid "Keeps FakeIP cache persistent across reboots and pre-resolves popular blocked domains on startup so first-visit latency is 0 ms." msgstr "Сохраняет FakeIP-кэш между перезагрузками и заранее резолвит популярные заблокированные домены при старте — задержка при первом визите 0 мс." -msgid "Key" -msgstr "Ключ" - -msgid "Key path" -msgstr "Путь к ключу" - -msgid "Keyword must not contain spaces or commas" -msgstr "Ключевое слово не должно содержать пробелы или запятые" - -msgid "Language for AI Doctor diagnosis responses" -msgstr "" - msgid "Latency test failed" msgstr "Проверка задержки не удалась" -msgid "Latency test URL" -msgstr "URL для проверки задержки" - msgid "Latest version is installed" msgstr "Установлена последняя версия" msgid "Latest version:" msgstr "Последняя версия:" -msgid "Leave empty to omit this header" -msgstr "Оставьте пустым, чтобы опустить этот заголовок" - msgid "Level" msgstr "Уровень" -msgid "Level name" -msgstr "Название уровня" - -msgid "List must be an HTTP(S) URL or a local .lst path" -msgstr "Список должен быть HTTP(S) URL или локальным путём .lst" - -msgid "List of domains automatically detected and the section they were added to. To edit or remove them, open the routing rules of the respective section." -msgstr "Список автоматически обнаруженных доменов и секций, в которые они были добавлены. Чтобы изменить или удалить их, откройте правила маршрутизации соответствующей секции." - -msgid "List Update Frequency" -msgstr "Частота обновления списков" - -msgid "Listen address" -msgstr "Адрес прослушивания" - -msgid "Listen port" -msgstr "Порт прослушивания" - msgid "Listening port" msgstr "Слушающий порт" msgid "LM Studio (Local PC / Server)" msgstr "" -msgid "Load .conf" -msgstr "Загрузить .conf" - -msgid "Load .conf config" -msgstr "Загрузить конфиг .conf" - -msgid "Load Current Records" -msgstr "Загрузить текущие записи" - -msgid "Loaded %d current record(s)" -msgstr "Загружено %d текущих записей" - -msgid "Loaded!" -msgstr "Загружено!" - -msgid "Loading client link..." -msgstr "Загрузка клиентской ссылки..." - msgid "Loading connections" msgstr "Загрузка подключений" @@ -1838,120 +731,24 @@ msgstr "Загрузка..." msgid "Loading…" msgstr "Загрузка…" -msgid "Local Address" -msgstr "Локальный адрес" - -msgid "Log Level" -msgstr "Уровень логов" - msgid "lx" msgstr "lx" msgid "Main DNS" msgstr "Основной DNS" -msgid "Main DNS server. If multiple servers are selected, a timeout switches to a backup." -msgstr "Основной DNS-сервер. Если выбрать несколько, то при таймауте произойдёт переключение на резервный." - -msgid "MASQUE Access Token" -msgstr "Токен доступа MASQUE" - -msgid "MASQUE Account ID" -msgstr "ID аккаунта MASQUE" - -msgid "MASQUE Private Key" -msgstr "Приватный ключ MASQUE" - -msgid "Match destination IPs or subnets" -msgstr "Совпадение по IP или подсети назначения" - -msgid "Match destination ports. Use a single port or a range" -msgstr "Совпадение по портам назначения. Используйте один порт или диапазон" - -msgid "Match Found" -msgstr "Совпадение найдено" - -msgid "Match traffic by packet DSCP mark (assigned in Windows via Policy-Based QoS). Examples: 46 (EF), 0x2e, 34 (AF41)" -msgstr "Сопоставление трафика по DSCP-метке пакета (назначается в Windows через Policy-Based QoS). Примеры: 46 (EF), 0x2e, 34 (AF41)" - -msgid "Max reconnects per hour before alert (default 10)." -msgstr "Макс. переподключений в час перед алертом (по умолчанию 10)." - -msgid "Maximum time to wait for example.com to resolve during a DNS health check." -msgstr "Максимальное время ожидания разрешения example.com при проверке доступности DNS." - msgid "Memory Usage" msgstr "Использование памяти" -msgid "Method" -msgstr "Метод" - -msgid "Metrics Retention (hours)" -msgstr "Хранение метрик (часов)" - -msgid "Minimum latency difference in milliseconds that triggers switching to a faster server." -msgstr "Минимальная разница в задержке (мс), при которой происходит переключение на более быстрый сервер." - -msgid "Mixed Proxy Password" -msgstr "Пароль смешанного прокси" - -msgid "Mixed Proxy Port" -msgstr "Порт смешанного прокси" - -msgid "Mixed Proxy Username" -msgstr "Имя пользователя смешанного прокси" - -msgid "Model name to use. Leave empty to use default (gpt-4o-mini / claude-3-5-haiku / deepseek-chat / llama3:latest)." -msgstr "" - -msgid "Monitored Interfaces" -msgstr "Наблюдаемые интерфейсы" - -msgid "Monitoring" -msgstr "Мониторинг" - msgid "Monitoring & Analytics" msgstr "Мониторинг и аналитика" -msgid "Monitors sing-box reconnect frequency. Alerts if too many reconnects per hour." -msgstr "Мониторит частоту переподключений sing-box. Уведомляет при превышении лимита." - msgid "Move down" msgstr "Вниз" msgid "Move up" msgstr "Вверх" -msgid "MTU" -msgstr "MTU" - -msgid "Must be a comma-separated list of numeric IDs" -msgstr "Должен быть список числовых ID через запятую" - -msgid "Must be a number in the range of 0 - 10000" -msgstr "Должно быть числом в диапазоне от 0 до 10000" - -msgid "Name displayed on the dashboard" -msgstr "Имя, отображаемое на дашборде" - -msgid "Name shown in the priority level list" -msgstr "Имя, отображаемое в списке уровней приоритета" - -msgid "Netherlands (nl)" -msgstr "Нидерланды (nl)" - -msgid "Network & Interfaces" -msgstr "" - -msgid "Network Interface" -msgstr "Сетевой интерфейс" - -msgid "Network interface settings" -msgstr "Настройки сетевого интерфейса" - -msgid "New domains:" -msgstr "Новых доменов:" - msgid "New version %s is available for %s" msgstr "Доступна новая версия %s для %s" @@ -1961,18 +758,6 @@ msgstr "Диапазон NFQUEUE свободен" msgid "NFQUEUE range overlaps with another rule" msgstr "Диапазон NFQUEUE пересекается с другим правилом" -msgid "NFQWS Strategy" -msgstr "Стратегия NFQWS" - -msgid "NFQWS strategy cannot be empty" -msgstr "Стратегия NFQWS не может быть пустой" - -msgid "NFQWS2 Strategy" -msgstr "Стратегия NFQWS2" - -msgid "NFQWS2 strategy cannot be empty" -msgstr "Стратегия NFQWS2 не может быть пустой" - msgid "No" msgstr "Нет" @@ -1991,24 +776,12 @@ msgstr "Нет закрытых подключений" msgid "No conflict detected" msgstr "Конфликт не обнаружен" -msgid "No Custom Rules Matched" -msgstr "Пользовательские правила не совпали" - msgid "No diagnostic history available yet." msgstr "" -msgid "No domains detected yet" -msgstr "Домены пока не обнаружены" - -msgid "No domains found to check." -msgstr "" - msgid "No enabled server inbounds configured" msgstr "Включённые серверные inbounds не настроены" -msgid "No file selected" -msgstr "Файл не выбран" - msgid "No issues found" msgstr "Проблем не обнаружено" @@ -2030,15 +803,15 @@ msgstr "Нет правил, использующих Zapret" msgid "No rules use Zapret2" msgstr "Нет правил, использующих Zapret2" +msgid "No targets found in section configs." +msgstr "Цели в конфигурациях секций не найдены." + msgid "Node list is empty" msgstr "Список узлов пуст" msgid "Nodes" msgstr "Узлы" -msgid "None" -msgstr "Нет" - msgid "Not configured" msgstr "Не настроено" @@ -2066,78 +839,12 @@ msgstr "Не отвечает" msgid "Not running" msgstr "Не запущено" -msgid "Not set" -msgstr "Не заданы" - -msgid "Notify on Certificate Warnings" -msgstr "Уведомлять о предупреждениях сертификатов" - -msgid "Notify on Core Crashes" -msgstr "Уведомлять о сбоях ядра" - -msgid "Notify on DNS Leaks" -msgstr "Уведомлять об утечках DNS" - -msgid "Notify on Server Switches" -msgstr "Уведомлять о переключениях серверов" - -msgid "Notify on Service Restarts" -msgstr "Уведомлять о перезапусках службы" - -msgid "Notify on Subscription Updates" -msgstr "Уведомлять об обновлениях подписок" - -msgid "Number of consecutive failed checks required before switching DNS servers." -msgstr "Количество последовательных неудачных проверок, необходимое для переключения DNS-сервера." - -msgid "Number of consecutive failures before restarting (default 3)." -msgstr "Количество последовательных сбоев перед перезапуском (по умолчанию 3)." - -msgid "Number of consecutive successful checks required before returning to a higher-priority DNS server." -msgstr "Количество последовательных успешных проверок, необходимое для возврата к DNS-серверу с более высоким приоритетом." - -msgid "Obfuscation" -msgstr "Обфускация" - -msgid "Obfuscation password" -msgstr "Пароль обфускации" - msgid "Ollama (Local PC / Server)" msgstr "" -msgid "One record per line: example.com 192.168.1.100 or 192.168.1.100 example.com. Lines starting with # are ignored." -msgstr "По одной записи на строку: example.com 192.168.1.100 или 192.168.1.100 example.com. Строки, начинающиеся с #, игнорируются." - -msgid "Only from the specified countries." -msgstr "Только из указанных стран." - -msgid "Only selected" -msgstr "Только выбранные" - -msgid "Only selected except exclusions" -msgstr "Только выбранные, кроме исключений" - -msgid "Only servers whose names match the expression." -msgstr "Только серверы, имена которых совпадают с выражением." - -msgid "Only servers with one of the selected protocols." -msgstr "Только серверы с одним из выбранных протоколов." - -msgid "Only servers with one of the selected security types." -msgstr "Только серверы с одним из выбранных типов безопасности." - -msgid "Only servers with one of the selected transports." -msgstr "Только серверы с одним из выбранных транспортов." - -msgid "Only the specified servers." -msgstr "Только указанные серверы." - msgid "Open" msgstr "Открыть" -msgid "Open priority settings and enter a display name" -msgstr "Откройте настройки приоритета и введите отображаемое имя" - msgid "Open Project Page" msgstr "Открыть страницу проекта" @@ -2147,308 +854,65 @@ msgstr "Время ожидания истекло" msgid "Optimization" msgstr "Оптимизация" -msgid "Option \"%s\" contains an invalid input value." -msgstr "Параметр \"%s\" содержит недопустимое значение." - -msgid "Optional — leave empty for default" -msgstr "Опционально — оставьте пустым для значения по умолчанию" - msgid "Optional for local LLM" msgstr "" -msgid "Optional tls-auth or tls-crypt key" -msgstr "Опциональный ключ tls-auth или tls-crypt" - -msgid "Optional values must be attached with '=' here; a separate token would be ignored by nfqws." -msgstr "Опциональные значения должны быть указаны через '=' здесь; отдельный токен будет проигнорирован nfqws." - -msgid "Optional values must be attached with '=' here; a separate token would be ignored by nfqws2." -msgstr "Опциональные значения должны быть указаны через '=' здесь; отдельный токен будет проигнорирован nfqws2." - -msgid "Or paste hosts file content:" -msgstr "Или вставьте содержимое hosts-файла:" - -msgid "Outbound" -msgstr "" +msgid "Outbound Route" +msgstr "Маршрут" msgid "outbounds must be a non-empty array of strings" msgstr "outbounds должен быть непустым массивом строк" -msgid "Output Network Interface" -msgstr "Выходной сетевой интерфейс" - -msgid "Override the default OpenWrt device headers for this subscription" -msgstr "Переопределить стандартные заголовки OpenWrt для этой подписки" - -msgid "Overwrite existing records (if unchecked, merge with existing records)" -msgstr "Перезаписать существующие записи (если сброшено — объединить)" - -msgid "P2P Leak Protection" -msgstr "Изоляция торрент-трафика (P2P)" - -msgid "Padding" -msgstr "Padding" - -msgid "Parsed records:" -msgstr "Распознано записей:" - -msgid "Password" -msgstr "Пароль" - -msgid "Password cannot be empty" -msgstr "Пароль не может быть пустым" - -msgid "Paste content or upload a file to preview imported DNS records." -msgstr "Вставьте содержимое или загрузите файл для предварительного просмотра." +msgid "Passed" +msgstr "Успешно" msgid "Path cannot be empty" msgstr "Путь не может быть пустым" -msgid "Path must be absolute (start with /)" -msgstr "Путь должен быть абсолютным (начинаться с /)" - -msgid "Path must contain at least one directory (like /tmp/cache.db)" -msgstr "Путь должен содержать хотя бы одну директорию (например /tmp/cache.db)" - -msgid "Path must end with cache.db" -msgstr "Путь должен заканчиваться на cache.db" - msgid "Pause updates" msgstr "Приостановить обновление" -msgid "Peer Public Key" -msgstr "Публичный ключ пира" - -msgid "PEM-encoded CA certificate" -msgstr "CA сертификат в формате PEM" - -msgid "PEM-encoded client certificate" -msgstr "Клиентский сертификат в формате PEM" - -msgid "PEM-encoded client private key" -msgstr "Приватный ключ клиента в формате PEM" - msgid "Pending" msgstr "Ожидает запуска" msgid "Per-Device Routing" msgstr "Маршрутизация по устройствам" -msgid "Periodically check the current level and switch to a faster server even when the current one works." -msgstr "Периодически проверять текущий уровень и переключаться на более быстрый сервер, даже если текущий работает." - -msgid "Periodically checks if the proxy is responding. Restarts Tachyon after consecutive failures." -msgstr "Периодически проверяет работоспособность прокси. Перезапускает Tachyon после последовательных сбоев." - -msgid "Persistent Keepalive" -msgstr "Persistent Keepalive" - -msgid "Persistent Smart Detect" -msgstr "Persistent Smart Detect" - -msgid "Pin on dashboard" -msgstr "Закрепить на дашборде" - -msgid "Polling Interval (seconds)" -msgstr "Интервал опроса (секунды)" - -msgid "Polling interval must be at least 1 second" -msgstr "Интервал опроса должен быть не менее 1 секунды" - -msgid "Port cannot be empty" -msgstr "Порт не может быть пустым" - msgid "Port conflict" msgstr "Конфликт порта" -msgid "Port for the local mixed proxy of this section" -msgstr "Порт локального смешанного прокси этой секции" - -msgid "Port must be between 1 and 65535" -msgstr "Порт должен быть от 1 до 65535" - -msgid "Port range start must be less than or equal to end" -msgstr "Начало диапазона портов должно быть меньше или равно концу" - -msgid "Ports" -msgstr "Порты" - -msgid "Pre-download all preset lists" -msgstr "Скачивать все предустановленные списки" - -msgid "Pre-shared key" -msgstr "Предварительно распределённый ключ" - -msgid "Prefer IPv4" -msgstr "Предпочитать IPv4" - -msgid "Prefer IPv6" -msgstr "Предпочитать IPv6" - -msgid "Preferred IP" -msgstr "Предпочитаемый IP" - -msgid "Prefix text" -msgstr "Текст префикса" - -msgid "Preshared Key" -msgstr "Общий ключ" - -msgid "Prevents multiple reload_firewall calls within 120 seconds to avoid connection drops." -msgstr "Предотвращает множественные вызовы reload_firewall в течение 120 секунд для избежания обрывов." - -msgid "Priority" -msgstr "Приоритет" - msgid "Priority details" msgstr "Детали Priority" msgid "Priority details are unavailable" msgstr "Детали Priority недоступны" -msgid "Priority level settings" -msgstr "Настройки уровня приоритета" - -msgid "Priority levels" -msgstr "Уровни приоритета" - -msgid "Priority settings" -msgstr "Настройки приоритета" - -msgid "Private Key" -msgstr "Приватный ключ" - msgid "Protection" msgstr "Защита" -msgid "Protocol" -msgstr "Протокол" - -msgid "Proxy Fail Threshold" -msgstr "Порог ошибок прокси" - -msgid "Proxy Health Check Interval (s)" -msgstr "Интервал проверки прокси (с)" - -msgid "Proxy Health Check URL" -msgstr "URL проверки прокси" - msgid "Proxy link is unavailable" msgstr "Ссылка прокси недоступна" -msgid "Proxy Section for Bot" -msgstr "Секция прокси для бота" - -msgid "Proxy to use for WARP API registration (api.cloudflareclient.com)" -msgstr "Прокси для регистрации WARP API (api.cloudflareclient.com)" - -msgid "PSK" -msgstr "PSK" - msgid "Public host" msgstr "Публичный хост" -msgid "QR code is too large" -msgstr "QR-код слишком большой" - -msgid "QUIC (HTTP/3)" -msgstr "QUIC (HTTP/3)" - -msgid "RDP" -msgstr "RDP" - -msgid "Read error" -msgstr "Ошибка чтения" - -msgid "Reality fake site" -msgstr "Fake-сайт Reality" - -msgid "Reality fake site port" -msgstr "Порт fake-сайта Reality" - -msgid "Reality max time difference" -msgstr "Максимальная разница времени Reality" - -msgid "Reality private key" -msgstr "Приватный ключ Reality" - -msgid "Reality public key" -msgstr "Публичный ключ Reality" - -msgid "Reality short ID" -msgstr "Reality short ID" - -msgid "Reality short ID must contain 1-8 hex digits" -msgstr "Reality short ID должен содержать 1-8 hex-символов" - msgid "Rebuilt release" msgstr "Пересобранный релиз" -msgid "Recommended Smart Quick Fixes:" +msgid "Recommended Quick Fixes:" msgstr "" -msgid "Reconnect Threshold" -msgstr "Порог переподключений" - -msgid "Records proxy/DNS latency and health status in hourly buckets for analysis." -msgstr "Записывает латентность прокси/DNS и статус здоровья в часовые интервалы для анализа." - -msgid "Records: %d" -msgstr "Записей: %d" - msgid "Refill" msgstr "Сброс" -msgid "Registration Detour" -msgstr "Обходной путь регистрации" - -msgid "Regular expression must not contain spaces or commas" -msgstr "Регулярное выражение не должно содержать пробелы или запятые" - msgid "Reinstall" msgstr "Переустановить" -msgid "Remote Hosts Lists" -msgstr "Удалённые списки хостов" - msgid "Remove" msgstr "Удалить" -msgid "Remove servers from the specified countries from this level." -msgstr "Удалить серверы из указанных стран с этого уровня." - -msgid "Remove servers whose names match the expression from this level." -msgstr "Удалить с этого уровня серверы, имена которых совпадают с выражением." - -msgid "Remove the specified servers from this level." -msgstr "Удалить указанные серверы с этого уровня." - -msgid "Require a username and password for the local mixed proxy" -msgstr "Требовать имя пользователя и пароль для локального смешанного прокси" - -msgid "Resolve domain names before routing so sing-box can use real destination IPs." -msgstr "Разрешать доменные имена до маршрутизации, чтобы sing-box мог использовать реальные IP назначения." - -msgid "Resolve real IP for routing" -msgstr "Определять реальный IP для маршрутизации" - -msgid "Resource selection by hostname inside nfqws is not supported here; sing-box selects resources before NFQUEUE." -msgstr "Выбор ресурсов по имени хоста внутри nfqws не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE." - -msgid "Resource selection by hostname inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE." -msgstr "Выбор ресурсов по имени хоста внутри nfqws2 не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE." - -msgid "Resource selection by IP or CIDR inside nfqws is not supported here; sing-box selects resources before NFQUEUE." -msgstr "Выбор ресурсов по IP или CIDR внутри nfqws не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE." - -msgid "Resource selection by IP or CIDR inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE." -msgstr "Выбор ресурсов по IP или CIDR внутри nfqws2 не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE." - -msgid "Response Packet Magic Header (S2)" -msgstr "Magic Header: Ответ (S2)" - -msgid "Response Packet Magic Header (S4)" -msgstr "Magic Header: Ответ (S4)" +msgid "Resolved IP / DNS" +msgstr "IP / DNS" msgid "Restart Tachyon" msgstr "Перезапустить Tachyon" @@ -2462,45 +926,9 @@ msgstr "Продолжить обновление" msgid "Route" msgstr "Маршрут" -msgid "Route bot API requests through this section. Leave empty to use the default mixed proxy." -msgstr "Направлять запросы бота к Telegram API через эту секцию. Оставьте пустым для использования стандартного прокси." - -msgid "Route main DNS requests through the selected section." -msgstr "Маршрутизировать основные DNS-запросы через выбранную секцию." - -msgid "Route requests to this DNS server through another section." -msgstr "Маршрутизировать запросы к этому DNS серверу через другую секцию." - -msgid "Routing mode" -msgstr "Режим маршрутизации" - -msgid "Routing Rule Tracer" -msgstr "Трассировщик правил маршрутизации" - msgid "Routing rules" msgstr "Правила маршрутизации" -msgid "Routing section" -msgstr "Секция маршрутизации" - -msgid "Rule" -msgstr "Правило" - -msgid "Rule set must be an HTTP(S) URL or a local .srs / .json path" -msgstr "Набор правил должен быть HTTP(S) URL или локальным путём .srs / .json" - -msgid "Rule set settings" -msgstr "Настройки набора правил" - -msgid "Rule sets" -msgstr "Наборы правил" - -msgid "Rule Sets (.srs / .json)" -msgstr "Наборы правил (.srs / .json)" - -msgid "Rules" -msgstr "Правила" - msgid "Rules mangle counters" msgstr "Счётчики правил mangle" @@ -2528,15 +956,9 @@ msgstr "Запустить диагностику" msgid "Run doctor repair" msgstr "Запустить восстановление" -msgid "Run History" -msgstr "" - msgid "Running" msgstr "Запущен" -msgid "Russia (ru)" -msgstr "Россия (ru)" - msgid "Save" msgstr "Сохранить" @@ -2552,167 +974,29 @@ msgstr "Сохранение…" msgid "Search" msgstr "Поиск" -msgid "Secret" -msgstr "Секрет" - -msgid "Secret key for authenticating remote access to YACD when WAN access is enabled." -msgstr "Секретный ключ для аутентификации удаленного доступа к YACD при включенном доступе через WAN." - -msgid "Secret token for authorizing WRITE operations (POST/PUT) on /cgi-bin/tachyon-agent/. Leave empty if auth is not required." -msgstr "Секретный токен для авторизации WRITE-операций (POST/PUT) по адресу /cgi-bin/tachyon-agent/. Оставьте пустым, если авторизация не требуется." +msgid "Search domain..." +msgstr "Поиск домена..." msgid "Secret token for WRITE requests" msgstr "Секретный токен для POST/PUT запросов" -msgid "Section" -msgstr "Секция" - -msgid "Section / Domain" -msgstr "" - -msgid "Section action" -msgstr "Действие секции" - -msgid "Section name" -msgstr "Название секции" - -msgid "Section Rules Content" -msgstr "Содержимое правил секции" +msgid "Section / Target" +msgstr "Секция / Цель" msgid "Section test order (checked = active, drag rows with △▽):" msgstr "Порядок проверки секций (галочка = активна, перетаскивайте △▽):" -msgid "Sections" -msgstr "Секции" - -msgid "Security" -msgstr "Защита" - -msgid "Select a common client profile or enter a custom User-Agent" -msgstr "Выберите стандартный профиль клиента или введите пользовательский User-Agent" - -msgid "Select a file with .conf extension" -msgstr "Выберите файл с расширением .conf" - -msgid "Select a network interface" -msgstr "Выберите сетевой интерфейс" - -msgid "Select a predefined domain list" -msgstr "Выберите предопределённый список доменов" - -msgid "Select a section" -msgstr "Выберите секцию" - -msgid "Select a section for downloading this subscription" -msgstr "Выберите секцию для скачивания этой подписки" - -msgid "Select a transit section" -msgstr "Выберите транзитную секцию" - -msgid "Select AI LLM provider for diagnostics" -msgstr "Выберите провайдера LLM для диагностики" - -msgid "Select an existing network interface" -msgstr "Выберите существующий сетевой интерфейс" - -msgid "Select an existing URLTest or Priority group" -msgstr "Выберите существующий URLTest или группу приоритетов" - -msgid "Select an intermediate section" -msgstr "Выберите промежуточную секцию" - -msgid "Select and order the sections through which blocked domains are tested. Checked sections are tried top-to-bottom." -msgstr "Выберите и упорядочьте секции для тестирования заблокированных доменов. Отмеченные секции проверяются сверху вниз." - -msgid "Select DNS protocol to use" -msgstr "Выберите протокол DNS" - -msgid "Select network interface for VPN connection" -msgstr "Выберите сетевой интерфейс для VPN соединения" - -msgid "Select one or more country ISO codes (e.g. ru, us, de, nl, fr, fi, se, tr, cn, jp, sg, by, kz, ua)." -msgstr "Выберите одну или несколько стран по двухбуквенному коду ISO (например: ru, us, de, nl, fr, fi, se, tr, cn, jp, sg, by, kz, ua)." - -msgid "Select or enter a User-Agent" -msgstr "Выберите или введите User-Agent" - -msgid "Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing" -msgstr "Выберите или введите путь к файлу кеша sing-box. Изменяйте это, ТОЛЬКО если вы знаете, что делаете" - -msgid "Select or enter the IP addresses of your game consoles." -msgstr "Выберите или введите IP-адреса ваших игровых приставок." - -msgid "Select path for sing-box config file. Change this ONLY if you know what you are doing" -msgstr "Выберите путь к файлу конфигурации sing-box. Изменяйте это, ТОЛЬКО если вы знаете, что делаете" - msgid "Select the fastest node" msgstr "Выбирать самый быстрый узел" -msgid "Select the log level for sing-box" -msgstr "Выберите уровень логов для sing-box" - -msgid "Select the network interface from which the traffic will originate" -msgstr "Выберите сетевой интерфейс, с которого будет исходить трафик" - -msgid "Select the network interface to which the traffic will originate" -msgstr "Выберите сетевой интерфейс, на который будет поступать трафик." - -msgid "Select the WAN interfaces to be monitored" -msgstr "Выберите WAN интерфейсы для мониторинга" - msgid "Selected" msgstr "Выбран" -msgid "Selected section" -msgstr "Выбранная секция" - msgid "Selector and URLTest outbounds must contain a non-empty outbounds array" msgstr "Selector и URLTest outbound должны содержать непустой массив outbounds" -msgid "Send a Telegram notification if a potential DNS leak is detected." -msgstr "Отправлять уведомление в Telegram при обнаружении возможной утечки DNS." - -msgid "Send a Telegram notification if sing-box or nftables rules crash and get auto-restored." -msgstr "Отправлять уведомление в Telegram, если правила sing-box или nftables упали и были автоматически восстановлены." - -msgid "Send a Telegram notification if SSL/TLS certificates are close to expiration." -msgstr "Отправлять уведомление в Telegram, если срок действия SSL/TLS-сертификатов близок к истечению." - -msgid "Send a Telegram notification if the Tachyon service is restarted by the watchdog." -msgstr "Отправлять уведомление в Telegram при перезапуске службы Tachyon сторожевым таймером." - -msgid "Send a Telegram notification when a URLTest group switches to a new server." -msgstr "Отправлять уведомление в Telegram при переключении группы URLTest на новый сервер." - -msgid "Send a Telegram notification when proxy subscriptions are successfully updated." -msgstr "Отправлять уведомление в Telegram при успешном обновлении подписок прокси." - -msgid "Server" -msgstr "Сервер" - -msgid "Server Address" -msgstr "Адрес сервера" - -msgid "Server filtering" -msgstr "Фильтрация серверов" - -msgid "Server group for automatic lowest-latency selection" -msgstr "Группа серверов для автоматического выбора с наименьшей задержкой" - -msgid "Server group for priority failover" -msgstr "Группа серверов для резервного переключения по приоритету" - -msgid "Server information" -msgstr "Информация о сервере" - -msgid "Server name" -msgstr "Имя сервера" - -msgid "Server name / SNI" -msgstr "Имя сервера / SNI" - -msgid "Server Name Indication — leave empty to use server address" -msgstr "Server Name Indication — оставьте пустым для использования адреса сервера" +msgid "Send" +msgstr "Отправить" msgid "Server outbound must contain a non-empty server field" msgstr "Серверный outbound должен содержать непустое поле server" @@ -2720,66 +1004,24 @@ msgstr "Серверный outbound должен содержать непуст msgid "Server outbound must contain a numeric server_port from 1 to 65535" msgstr "Серверный outbound должен содержать числовой server_port от 1 до 65535" -msgid "Server Port" -msgstr "Порт сервера" +msgid "Server unavailable" +msgstr "Сервер недоступен" msgid "server_port must be a number from 1 to 65535" msgstr "server_port должен быть числом от 1 до 65535" -msgid "Servers" -msgstr "Серверы" - -msgid "Servers on dashboard" -msgstr "Серверы на дашборде" - msgid "Service action failed" msgstr "Действие сервиса не выполнено" msgid "Service Health Check" -msgstr "" - -msgid "Service list" -msgstr "Список сервисов" - -msgid "Services & Access" -msgstr "" +msgstr "Проверка доступности сервисов" msgid "Services info" msgstr "Информация о сервисах" -msgid "Settings" -msgstr "Настройки" - -msgid "Show metadata on dashboard" -msgstr "Показывать метаданные на дашборде" - -msgid "Show only selected servers." -msgstr "Показывать только выбранные серверы." - -msgid "Show only servers with one of the selected protocols." -msgstr "Показывать только серверы с одним из выбранных протоколов." - -msgid "Show only servers with one of the selected security types." -msgstr "Показывать только серверы с одним из выбранных типов безопасности." - -msgid "Show only servers with one of the selected transports." -msgstr "Показывать только серверы с одним из выбранных транспортов." - -msgid "Show servers from selected groups without repeating their filtering criteria." -msgstr "Показывать серверы из выбранных групп без повторения их критериев фильтрации." - -msgid "Show servers only from the specified countries." -msgstr "Показывать серверы только из указанных стран." - -msgid "Show servers whose names match the expression." -msgstr "Показывать серверы, имена которых совпадают с выражением." - msgid "Show sing-box config" msgstr "Показать sing-box конфигурацию" -msgid "Show subscription metadata for this source on the dashboard" -msgstr "Показывать метаданные подписки для этого источника на дашборде" - msgid "Sing-box autostart disabled" msgstr "Автостарт sing-box отключен" @@ -2804,60 +1046,15 @@ msgstr "Сервис sing-box существует" msgid "Sing-box version is compatible (newer than 1.12.4)" msgstr "Версия Sing-box совместима (новее 1.12.4)" -msgid "Singapore (sg)" -msgstr "Сингапур (sg)" - -msgid "Skip loopback & local entries (127.0.0.1, ::1, 0.0.0.0, localhost)" -msgstr "Пропускать локальные и loopback-записи (127.0.0.1, ::1, 0.0.0.0, localhost)" - -msgid "Skip TLS certificate verification (not recommended)" -msgstr "Пропустить проверку TLS-сертификата (не рекомендуется)" - -msgid "Skipped comments/invalid:" -msgstr "Пропущено комментариев/невалидных:" - -msgid "Skipped loopback:" -msgstr "Пропущено loopback:" - msgid "Smart Detect" msgstr "Smart Detect" msgid "Smart Detect settings saved" msgstr "Настройки Smart Detect сохранены" -msgid "Snell Version" -msgstr "Версия Snell" - -msgid "Some fixes failed" -msgstr "" - -msgid "Sort Alphabetically" -msgstr "Сортировать по алфавиту" - -msgid "Sort by latency" -msgstr "Сортировка по задержке" - -msgid "Sorts servers in this section by lowest latency in the dashboard." -msgstr "Сортирует серверы в этой секции по наименьшей задержке на дашборде." - msgid "Source" msgstr "Источник" -msgid "Source Devices" -msgstr "Устройства-источники" - -msgid "Source Network Interface" -msgstr "Сетевой интерфейс источника" - -msgid "Specify a file path" -msgstr "Укажите путь к файлу" - -msgid "Specify different files" -msgstr "Укажите разные файлы" - -msgid "SSH" -msgstr "SSH" - msgid "Standalone ByeDPI autostart is enabled" msgstr "Автозапуск отдельной службы ByeDPI включен" @@ -2891,84 +1088,30 @@ msgstr "Отдельная служба Zapret2 активна" msgid "Standalone Zapret2 service is inactive" msgstr "Отдельная служба Zapret2 неактивна" -msgid "Start" -msgstr "Запустить" - -msgid "Start bot" -msgstr "Запустить бота" - msgid "Start Tachyon" msgstr "Запустить Tachyon" msgid "Start Watchdog first" msgstr "Сначала запустите Watchdog" -msgid "Starting…" -msgstr "Запуск…" - msgid "Status" msgstr "Статус" -msgid "Stop" -msgstr "Остановить" - -msgid "Stop bot" -msgstr "Остановить бота" - -msgid "Stop checking when URLTest group is not used. Use sing-box duration format like 1d, 12h or 30m." -msgstr "Прекратить проверку, когда группа URLTest не используется. Используйте формат длительности sing-box, например 1d, 12h или 30m." - msgid "Stop Tachyon" msgstr "Остановить Tachyon" msgid "Stopped" msgstr "Остановлен" -msgid "Stopping…" -msgstr "Остановка…" - -msgid "Store auto-detected domains in /etc instead of /tmp to survive reboots." -msgstr "Хранить авто-обнаруженные домены в /etc вместо /tmp для сохранения после перезагрузок." - -msgid "Strict ECH + DoQ DNS Enforcer" -msgstr "Strict ECH Enforcer" - -msgid "STUN (P2P Calls)" -msgstr "STUN (P2P Звонки)" - -msgid "Subnets from the list will be extracted and added to nftables" -msgstr "Подсети из списка будут извлечены и добавлены в nftables" - -msgid "Subscription auto update" -msgstr "Автообновление подписки" - msgid "Subscription info:" msgstr "Информация о подписке:" msgid "Subscription update failed" msgstr "Обновление подписки завершилось ошибкой" -msgid "Subscription update interval" -msgstr "Интервал обновления подписки" - -msgid "Subscription URL" -msgstr "URL подписки" - -msgid "Subscription URL settings" -msgstr "Настройки URL подписки" - msgid "Subscriptions updated" msgstr "Подписки обновлены" -msgid "Success" -msgstr "Успешно" - -msgid "Successfully imported %d DNS record(s)" -msgstr "Успешно импортировано %d DNS-записей" - -msgid "Sweden (se)" -msgstr "Швеция (se)" - msgid "System info" msgstr "Системная информация" @@ -2981,30 +1124,12 @@ msgstr "Таблица существует" msgid "Tachyon Error" msgstr "Ошибка Tachyon" -msgid "Tachyon manages ciadpi pid files itself, so pidfile options are not allowed here." -msgstr "Tachyon самостоятельно управляет pid файлами ciadpi, поэтому параметры pidfile недопустимы здесь." - -msgid "Tachyon manages the ciadpi process lifecycle itself, so daemon mode is not allowed here." -msgstr "Tachyon самостоятельно управляет жизненным циклом процесса ciadpi, поэтому режим демона недопустим здесь." - -msgid "Tachyon manages the nfqws process lifecycle itself, so daemon mode is not allowed here." -msgstr "Tachyon самостоятельно управляет жизненным циклом процесса nfqws, поэтому режим демона недопустим здесь." - -msgid "Tachyon manages the nfqws2 process lifecycle itself, so daemon mode is not allowed here." -msgstr "Tachyon самостоятельно управляет жизненным циклом процесса nfqws2, поэтому режим демона недопустим здесь." - msgid "Tachyon service is stopped. Start the service to display connections." msgstr "Служба Tachyon остановлена. Запустите сервис для отображения подключений." msgid "Tachyon service is stopped. Start the service to display the dashboard." msgstr "Служба Tachyon остановлена. Запустите сервис для отображения дашборда." -msgid "Tachyon Settings" -msgstr "Настройки Tachyon" - -msgid "Tachyon will not modify your DHCP configuration" -msgstr "Tachyon не будет изменять вашу конфигурацию DHCP" - msgid "Tachyon-managed ciadpi runtime has restarted" msgstr "ciadpi Tachyon перезапускался" @@ -3035,59 +1160,20 @@ msgstr "NFQWS2 Tachyon не запущен" msgid "Tachyon-managed nfqws2 runtime is ready" msgstr "NFQWS2 Tachyon готов" -msgid "Tailscale auth key" -msgstr "Ключ авторизации Tailscale" - -msgid "Tailscale control URL" -msgstr "URL control plane Tailscale" - msgid "Tailscale endpoint" msgstr "Tailscale endpoint" -msgid "Tailscale hostname" -msgstr "Hostname Tailscale" - -msgid "TCP (ms)" +msgid "TCP" msgstr "" -msgid "Telegram Bot" -msgstr "Telegram-бот" - -msgid "Telegram Bot Token" -msgstr "Токен Telegram-бота" - msgid "Test latency" msgstr "Тестирование задержки" -msgid "Test only selected servers." -msgstr "Тестировать только выбранные серверы." - -msgid "Test only servers with one of the selected protocols." -msgstr "Тестировать только серверы с одним из выбранных протоколов." - -msgid "Test only servers with one of the selected security types." -msgstr "Тестировать только серверы с одним из выбранных типов безопасности." - -msgid "Test only servers with one of the selected transports." -msgstr "Тестировать только серверы с одним из выбранных транспортов." - -msgid "Test servers only from the specified countries." -msgstr "Тестировать серверы только из указанных стран." - -msgid "Test servers whose names match the expression." -msgstr "Тестировать серверы, имена которых совпадают с выражением." - msgid "Testing URL" msgstr "URL проверки" -msgid "The desync fwmark is managed by Tachyon for loop prevention and must not be overridden here." -msgstr "Метка fwmark для десинхронизации управляется Tachyon для предотвращения петель и не должна переопределяться здесь." - -msgid "The NFQUEUE number is assigned by Tachyon for each rule and must not be overridden here." -msgstr "Номер NFQUEUE назначается Tachyon для каждого правила и не должен переопределяться здесь." - -msgid "The rule applies to the domain and all its subdomains. Use full:, keyword:, or regex: prefixes for exact match, keyword match, or regular expression." -msgstr "Правило применяется к домену и всем его поддоменам. Используйте префиксы full:, keyword: или regex: для точного совпадения, совпадения по ключевому слову или регулярного выражения." +msgid "Testing..." +msgstr "Тестирование..." msgid "There are rules using ByeDPI" msgstr "Есть правила, использующие ByeDPI" @@ -3098,162 +1184,39 @@ msgstr "Есть правила использующие Zapret" msgid "There are rules using Zapret2" msgstr "Есть правила, использующие Zapret2" -msgid "This field is required" -msgstr "Заполните это поле" - -msgid "This field must start a working ciadpi strategy; help/version options exit immediately and are not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии ciadpi; опции help/version немедленно завершаются и недопустимы здесь." - -msgid "This field must start a working nfqws strategy; --dry-run exits immediately and is not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии nfqws; --dry-run немедленно завершается и недопустим здесь." - -msgid "This field must start a working nfqws strategy; --version exits immediately and is not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии nfqws; --version немедленно завершается и недопустим здесь." - -msgid "This field must start a working nfqws2 strategy; --dry-run exits immediately and is not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии nfqws2; --dry-run немедленно завершается и недопустим здесь." - -msgid "This field must start a working nfqws2 strategy; --version exits immediately and is not allowed here." -msgstr "Это поле должно начинаться с рабочей стратегии nfqws2; --version немедленно завершается и недопустим здесь." - -msgid "This flag does not accept a value." -msgstr "Этот флаг не принимает значение." - -msgid "This option requires a value." -msgstr "Эта опция требует значение." +msgid "Thinking..." +msgstr "Думаю..." msgid "Time" msgstr "Время" -msgid "Time in seconds for DNS record caching (default: 60)" -msgstr "Время в секундах для кэширования DNS записей (по умолчанию: 60)" - -msgid "Time skew tolerance" -msgstr "Допуск расхождения времени" - msgid "tiny" msgstr "tiny" -msgid "TLS (ms)" +msgid "TLS" msgstr "" -msgid "TLS / HTTPS" -msgstr "TLS / HTTPS" - -msgid "TLS Auth/Crypt Key" -msgstr "Ключ TLS Auth/Crypt" - -msgid "TLS SNI" -msgstr "TLS SNI" - -msgid "Token is required when the bot is enabled" -msgstr "Токен обязателен при включённом боте" - msgid "Tolerance" msgstr "Допуск" -msgid "Top level has the highest priority; lower levels are used as fallback" -msgstr "Верхний уровень имеет наивысший приоритет; нижние уровни используются как резерв" - -msgid "Total lines:" -msgstr "Всего строк:" - -msgid "Trace" -msgstr "Проверить" - -msgid "Tracing routing rules..." -msgstr "Выполняется трассировка..." +msgid "Total Targets" +msgstr "Всего целей" msgid "Traffic" msgstr "Трафик" -msgid "Traffic for this level goes directly." -msgstr "Трафик для этого уровня проходит напрямую." - -msgid "Traffic from these IP addresses will never be routed through this section, even if other conditions match." -msgstr "Трафик с этих IP-адресов никогда не будет направляться через эту секцию, даже если другие условия совпадают." - -msgid "Traffic of specified protocols (e.g. BitTorrent, QUIC, STUN) will bypass this section." -msgstr "Трафик указанных протоколов (например, BitTorrent, QUIC, STUN) будет идти в обход этой секции." - msgid "Traffic Total" msgstr "Всего трафика" -msgid "Traffic type filter" -msgstr "Фильтр по типам трафика" - -msgid "Traffic will go through the default route (Direct/Default)." -msgstr "Трафик пройдёт через маршрут по умолчанию (Напрямую/По умолчанию)." - -msgid "Transparent proxy mode is incompatible with action=byedpi because Tachyon connects to ciadpi through SOCKS." -msgstr "Режим прозрачного прокси несовместим с action=byedpi, так как Tachyon подключается к ciadpi через SOCKS." - -msgid "Transport" -msgstr "Транспорт" - -msgid "Transport host" -msgstr "Хост транспорта" - -msgid "Transport path" -msgstr "Путь транспорта" - -msgid "Transport path must start with /" -msgstr "Путь транспорта должен начинаться с /" - msgid "Troubleshooting" msgstr "Устранение неполадок" -msgid "Try compatible User-Agent profiles automatically when downloading this subscription" -msgstr "Автоматически пробовать совместимые профили User-Agent при скачивании этой подписки" - -msgid "TTL must be a positive number" -msgstr "TTL должно быть положительным числом" - -msgid "TTL value cannot be empty" -msgstr "Значение TTL не может быть пустым" - -msgid "Turkey (tr)" -msgstr "Турция (tr)" - msgid "Type" msgstr "Тип" -msgid "UDP (Unprotected DNS)" -msgstr "UDP (Незащищённый DNS)" - -msgid "Ukraine (ua)" -msgstr "Украина (ua)" - -msgid "Unable to validate the ByeDPI strategy through the backend parser." -msgstr "Не удалось валидировать стратегию ByeDPI через парсер бэкенда." - -msgid "Unable to validate the NFQWS strategy through the backend parser." -msgstr "Не удалось валидировать стратегию NFQWS через парсер бэкенда." - -msgid "Unable to validate the NFQWS2 strategy through the backend parser." -msgstr "Не удалось валидировать стратегию NFQWS2 через парсер бэкенда." - msgid "Unavailability timeout" msgstr "Таймаут недоступности" -msgid "Underload Packet Magic Header (H1)" -msgstr "Magic Header: Underload (H1)" - -msgid "Underload Packet Magic Header (H2)" -msgstr "Magic Header: Underload (H2)" - -msgid "Underload Packet Magic Header (H3)" -msgstr "Magic Header: Underload (H3)" - -msgid "Underload Packet Magic Header (H4)" -msgstr "Magic Header: Underload (H4)" - -msgid "Unexpected ByeDPI strategy argument: %s" -msgstr "Неожиданный аргумент стратегии ByeDPI: %s" - -msgid "Unexpected standalone token. Use explicit flags such as --name or --name=value." -msgstr "Неожиданный отдельный токен. Используйте явные флаги, например --name или --name=value." - msgid "Unexpected Tachyon-managed ciadpi runtime is running" msgstr "Обнаружен лишний ciadpi Tachyon" @@ -3263,45 +1226,21 @@ msgstr "Обнаружен лишний NFQWS Tachyon" msgid "Unexpected Tachyon-managed nfqws2 runtime is running" msgstr "Обнаружен лишний NFQWS2 Tachyon" -msgid "unique UCI identifier" -msgstr "уникальный идентификатор UCI" - -msgid "United Kingdom (gb)" -msgstr "Великобритания (gb)" - -msgid "United States (us)" -msgstr "США (us)" - msgid "unknown" msgstr "неизвестно" msgid "Unknown" msgstr "Неизвестно" -msgid "Unknown ByeDPI option: %s" -msgstr "Неизвестная опция ByeDPI: %s" - -msgid "Unknown country" -msgstr "Неизвестная страна" - msgid "Unknown error" msgstr "Неизвестная ошибка" -msgid "Unknown NFQWS flag." -msgstr "Неизвестный флаг NFQWS." - -msgid "Unknown NFQWS2 flag." -msgstr "Неизвестный флаг NFQWS2." - msgid "Unspecified IP address is not allowed" msgstr "Неуказанный IP-адрес не разрешён" msgid "Unstable" msgstr "Нестабильно" -msgid "Unsupported security mode for this protocol" -msgstr "Этот протокол не поддерживает выбранный режим защиты" - msgid "Update" msgstr "Обновить" @@ -3317,15 +1256,6 @@ msgstr "Доступна новая версия:" msgid "Update subscriptions" msgstr "Обновить подписки" -msgid "Update this subscription automatically" -msgstr "Автоматически обновлять эту подписку" - -msgid "Updated/duplicates:" -msgstr "Обновлено/дубликатов:" - -msgid "Updates & Downloads" -msgstr "" - msgid "Uplink" msgstr "Исходящий" @@ -3338,177 +1268,39 @@ msgstr "URL должен начинаться с vless://, vmess://, ss://, troj msgid "URL must use one of the following protocols:" msgstr "URL должен использовать один из следующих протоколов:" -msgid "URL to test through the proxy (default: Cloudflare 204)." -msgstr "URL для теста через прокси (по умолчанию: Cloudflare 204)." - -msgid "URL used to check whether a server is alive" -msgstr "URL для проверки доступности сервера" - -msgid "URL used to test server latency" -msgstr "URL для тестирования задержки сервера" - -msgid "URLs of remote hosts files to download and apply. Supports standard hosts format: IP domain." -msgstr "URL удалённых файлов hosts для загрузки и применения. Поддерживается стандартный формат hosts: IP domain." - -msgid "URLTest" -msgstr "URLTest" - msgid "URLTest details" msgstr "Детали URLTest" msgid "URLTest details are unavailable" msgstr "Детали URLTest недоступны" -msgid "URLTest settings" -msgstr "Настройки URLTest" - -msgid "Use 3-tier check intervals: fast (15s), normal (120s), slow (300s) instead of a single interval." -msgstr "3-уровневые интервалы проверок: быстрый (15с), нормальный (120с), медленный (300с)." - -msgid "Use 32 hex characters" -msgstr "Укажите 32 hex-символа" - -msgid "Use a domain name or IP address" -msgstr "Используйте доменное имя или IP-адрес" - -msgid "Use a duration like 30s, 5m, or 1h30m" -msgstr "Укажите длительность в формате 30s, 5m или 1h30m" - -msgid "Use a non-negative integer" -msgstr "Используйте неотрицательное целое число" - -msgid "Use a non-zero secret" -msgstr "Укажите ненулевой секрет" - -msgid "Use an HTTP or HTTPS URL" -msgstr "Укажите HTTP или HTTPS URL" - -msgid "Use an IP address" -msgstr "Используйте IP-адрес" - -msgid "Use an IP listen address" -msgstr "Используйте IP-адрес для прослушивания" - -msgid "Use another section as an intermediate hop to connect to servers in this section. Does not apply to network interfaces or JSON outbounds." -msgstr "Использовать другую секцию как промежуточный узел для подключения к серверам этой секции. Не применяется к сетевым интерфейсам и JSON outbound." - -msgid "Use CIDR prefixes like 192.168.1.0/24 or 2001:db8::/32" -msgstr "Используйте CIDR-префиксы, например 192.168.1.0/24 или 2001:db8::/32" - -msgid "Use CIDR prefixes or IP addresses like 192.168.1.0/24, 192.168.1.10, or 2001:db8::1" -msgstr "Используйте CIDR-префиксы или IP-адреса, например 192.168.1.0/24, 192.168.1.10 или 2001:db8::1" - -msgid "Use letters, digits, dots, underscores, or hyphens" -msgstr "Используйте буквы, цифры, точки, подчёркивания или дефисы" - -msgid "Use sing-box duration format like 10s, 1m or 2m30s" -msgstr "Используйте формат длительности sing-box, например 10s, 1m или 2m30s" - -msgid "Use sing-box duration format like 1d, 12h or 30m" -msgstr "Используйте формат длительности sing-box, например 1d, 12h или 30m" - -msgid "Use sing-box duration format like 1d, 12h or 6h" -msgstr "Используйте формат длительности sing-box: 1d, 12h или 6h" - msgid "Used by" msgstr "Используется" -msgid "User-Agent" -msgstr "User-Agent" - -msgid "Username" -msgstr "Имя пользователя" - -msgid "Username cannot be empty" -msgstr "Имя пользователя не может быть пустым" - msgid "Valid" msgstr "Валидно" -msgid "Validates sing-box config before restart to prevent boot loops on broken configs." -msgstr "Проверяет конфиг sing-box перед перезапуском для предотвращения boot loop на сломанных конфигах." - -msgid "Validation errors:" -msgstr "Ошибки валидации:" - -msgid "Value cannot be empty" -msgstr "Значение не может быть пустым" - -msgid "Value must not contain control characters" -msgstr "Значение не должно содержать управляющие символы" - msgid "Verdict" -msgstr "" - -msgid "Via country.is" -msgstr "Через country.is" +msgstr "Статус" msgid "View logs" msgstr "Посмотреть логи" -msgid "Visible name of this section" -msgstr "Видимое имя этой секции" - -msgid "VLESS flow" -msgstr "VLESS flow" - -msgid "vless://, vmess://, ss://, trojan://, socks4/5://, hy2/hysteria2:// links" -msgstr "ссылки vless://, vmess://, ss://, trojan://, socks4/5://, hy2/hysteria2://" - msgid "WAN" msgstr "WAN" msgid "WAN public IP" msgstr "Публичный WAN IP" -msgid "WARP Access Token" -msgstr "Токен доступа WARP" - -msgid "WARP Account ID" -msgstr "ID аккаунта WARP" - -msgid "WARP Configuration generated and loaded successfully!" -msgstr "Конфигурация WARP успешно сгенерирована и загружена!" - -msgid "WARP Private Key" -msgstr "Приватный ключ WARP" - msgid "Watchdog" msgstr "Сторожевой таймер" -msgid "Watchdog Status" -msgstr "Статус watchdog" - -msgid "WebRTC Leak Protection" -msgstr "Защита от утечек WebRTC" - -msgid "What Tachyon should do when this section matches" -msgstr "Что должен делать Tachyon, когда эта секция совпадает" - -msgid "When switching to another level, test every server and select the fastest instead of the first working one." -msgstr "При переключении на другой уровень проверить каждый сервер и выбрать самый быстрый, а не первый рабочий." - -msgid "WireGuard private key from your Cloudflare account" -msgstr "WireGuard приватный ключ из вашего аккаунта Cloudflare" - -msgid "WireGuard private key from your Cloudflare WARP account" -msgstr "Приватный ключ WireGuard от вашего аккаунта Cloudflare WARP" - -msgid "XHTTP mode" -msgstr "Режим XHTTP" - -msgid "YACD Secret Key" -msgstr "Секретный ключ YACD" +msgid "Why Discord fails?" +msgstr "Почему не работает Discord?" msgid "Yes" msgstr "Да" -msgid "You can select Output Network Interface, by default autodetect" -msgstr "Вы можете выбрать выходной сетевой интерфейс, по умолчанию он определяется автоматически." - -msgid "Zapret hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS strategies." -msgstr "Шаблоны списков хостов Zapret не поддерживаются здесь, так как Tachyon не разворачивает их для поправильных стратегий NFQWS." - msgid "Zapret package is installed" msgstr "Пакет Zapret установлен" @@ -3527,9 +1319,6 @@ msgstr "sing-box outbound для Zapret настроен" msgid "Zapret sing-box outbound is not configured" msgstr "sing-box outbound для Zapret не настроен" -msgid "Zapret2 hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS2 strategies." -msgstr "Шаблоны списков хостов Zapret2 не поддерживаются здесь, так как Tachyon не разворачивает их для поправильных стратегий NFQWS2." - msgid "Zapret2 package is installed" msgstr "Пакет Zapret2 установлен" diff --git a/luci-app-tachyon/po/templates/tachyon.pot b/luci-app-tachyon/po/templates/tachyon.pot index 6eed4a3a..ef056583 100644 --- a/luci-app-tachyon/po/templates/tachyon.pot +++ b/luci-app-tachyon/po/templates/tachyon.pot @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: TACHYON\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-12 07:20+0300\n" -"PO-Revision-Date: 2026-08-12 07:20+0300\n" +"POT-Creation-Date: 2026-08-12 09:15+0300\n" +"PO-Revision-Date: 2026-08-12 09:15+0300\n" "Last-Translator: Dushnilin \n" "Language-Team: LANGUAGE \n" "Language: \n" @@ -16,42 +16,6 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2062 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2439 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2818 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2833 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3031 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3046 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3282 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3434 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3444 -msgid "-- Select --" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10205 -msgid ".lst Lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1285 -msgid "(provider default)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8865 -msgid "+ Add JSON outbound" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3198 -msgid "+ Add level" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8951 -msgid "+ Add priority" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8892 -msgid "+ Add URLTest" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:467 msgid "⏹ Stop" msgstr "" @@ -64,14 +28,6 @@ msgstr "" msgid "⚙ Advanced Settings" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:592 -msgid "⚠️ If all Bootstrap DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:583 -msgid "⚠️ If all Main DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss." -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1670 #: src/tachyon/tabs/dashboard/initController.ts:1679 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:457 @@ -88,19 +44,6 @@ msgstr "" msgid "🔑 Generate" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:444 -msgid "Accept external proxy connections and route them with sing-box." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3132 -msgid "Accept routes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7236 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7266 -msgid "Action" -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:713 #: src/tachyon/tabs/monitoring/render.ts:20 msgid "Active" @@ -123,145 +66,64 @@ msgstr "" msgid "Active Main DNS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:433 -msgid "Add a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:450 -msgid "Add a server inbound" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1843 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:122 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:166 -msgid "Add at least one DNS server" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2529 -msgid "Add prefix to nodes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9429 -msgid "Add URLs or local paths to .lst lists containing domains and subnets." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9455 -msgid "Add URLs or local paths to .lst lists containing domains. IP entries are ignored." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9404 -msgid "Add URLs or local paths to .srs / .json lists. Only domain rules are supported." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9375 -msgid "Add URLs or local paths to .srs / .json lists. Subnets are ignored by default." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3456 -msgid "Add URLTest / Priority group" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:130 +msgid "Active Sections" msgstr "" #: src/tachyon/tabs/diagnostic/checks/runNftCheck.ts:106 msgid "Additional marking rules found" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2748 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2958 -msgid "Additionally exclude servers by protocol, transport, and security. Exclude only servers matching the specified parameters." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2731 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2940 -msgid "Additionally filter servers by protocol, transport, and security. Add only servers matching the specified parameters." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3356 -msgid "Additionally hide servers by protocol, transport, and security. Hide servers matching the specified parameters." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3336 -msgid "Additionally show servers by protocol, transport, and security. Add only servers matching the specified parameters." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1652 -msgid "Address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1691 -msgid "Administrator Chat IDs" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:579 msgid "Advanced self-healing features. Requires Watchdog to be enabled." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:508 -msgid "Advanced System" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3115 -msgid "Advertise exit node" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3125 -msgid "Advertise routes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8603 -msgid "AEAD Method" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:507 -msgid "AI & Watchdog" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:684 msgid "AI Agent REST API (12 Endpoints)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1237 -msgid "AI Agent REST API Bearer Token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1304 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:893 msgid "AI API Key" msgstr "" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:220 +msgid "AI Chat & Tachyon Assistant" +msgstr "" + +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:138 +msgid "AI Chat Assistant" +msgstr "" + #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:740 msgid "AI Doctor (ChatGPT / DeepSeek API)" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:855 -#: src/tachyon/tabs/diagnostic/initController.ts:1211 +#: src/tachyon/tabs/diagnostic/initController.ts:1154 msgid "AI Doctor Diagnosis" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:827 -msgid "AI Doctor Diagnostic Scan in Progress..." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:878 -#: src/tachyon/tabs/diagnostic/initController.ts:1217 -#: src/tachyon/tabs/diagnostic/initController.ts:1226 +#: src/tachyon/tabs/diagnostic/initController.ts:843 +#: src/tachyon/tabs/diagnostic/initController.ts:1160 +#: src/tachyon/tabs/diagnostic/initController.ts:1168 msgid "AI Doctor failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1291 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:860 msgid "AI Doctor Language" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1278 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:836 msgid "AI Model" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1262 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:766 msgid "AI Provider" msgstr "" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:138 +msgid "AI service error" +msgstr "" + #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:574 msgid "AI Watchdog" msgstr "" @@ -272,27 +134,12 @@ msgstr "" #: src/tachyon/tabs/monitoring/initController.ts:672 #: src/tachyon/tabs/monitoring/render.ts:40 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:318 msgid "All" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1959 -msgid "All except selected" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1068 -msgid "All fixes applied successfully" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1969 -msgid "All remaining except selected" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1967 -msgid "All remaining servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2914 -msgid "All remaining servers means every server not already assigned to a higher-priority level." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:140 +msgid "All Profiles" msgstr "" #: src/tachyon/tabs/monitoring/initController.ts:635 @@ -300,191 +147,42 @@ msgstr "" msgid "All Routes" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1958 -msgid "All servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9487 -msgid "All traffic from these IP addresses will be routed through the section unconditionally, ignoring all other conditions." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8505 -msgid "Allow Insecure TLS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5323 -msgid "Allowed domain prefixes are full:, keyword:, and regex:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:883 -msgid "Allows access to YACD from the WAN. Make sure to open the appropriate port in your firewall." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2708 -msgid "Allows limiting the list of servers for URLTest" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1251 -msgid "Allows Tachyon to send diagnostic snapshots to ChatGPT or DeepSeek API for intelligent root-cause analysis and auto-repair recommendations." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2644 -msgid "ALPN" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2878 -msgid "Alter ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8292 -msgid "AmneziaWG config loaded successfully!" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8005 -msgid "AmneziaWG Generator" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:165 -msgid "An error occurred while checking services." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:809 -msgid "Analyzing system log (logread & errors)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1305 -msgid "API Key for OpenAI (sk-...) or DeepSeek (optional for Ollama / LM Studio)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9543 -msgid "Apply rules of this section only to selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9478 -msgid "Apply section rules only to the specified local IP addresses" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1057 -msgid "Applying all fixes..." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1024 +#: src/tachyon/tabs/diagnostic/initController.ts:995 msgid "Applying fix" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1702 -msgid "At least one Admin Chat ID is required" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5354 -msgid "At least one valid domain must be specified." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5436 -msgid "At least one valid IP or subnet must be specified." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8686 -msgid "Auth Digest" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:60 +msgid "Ask Tachyon AI Assistant a question..." msgstr "" #: src/partials/modal/renderModal.ts:286 msgid "Auto refresh" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3035 -msgid "Auto update" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1494 -msgid "Auto-detected domains" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9300 -msgid "Auto-detected Domains" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1454 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1053 msgid "Auto-detects blocked domains from logs and adds them to the first section where they work via proxy." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2455 -msgid "Auto-generate HWID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7978 -msgid "Auto-update Hosts Lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1018 -msgid "Automatic component update checks" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2424 -msgid "Automatic User-Agent selection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2530 -msgid "Automatically add text to the name of each server from this subscription for convenient filtering." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1019 -msgid "Automatically check installed components for new versions" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8006 -msgid "Automatically generate a Cloudflare WARP account and configure all AmneziaWG settings." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1428 -msgid "Automatically increase check intervals when healthy (to 5 min) and decrease on problems (to 120s)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3148 #: src/tachyon/tabs/dashboard/initController.ts:1243 msgid "Automatically select the fastest node in the current level" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7979 -msgid "Automatically update remote hosts lists on schedule" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:52 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:54 msgid "Available actions" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5569 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6014 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6426 -msgid "Backend validation failed: %s" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:270 +msgid "Avg Latency" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:694 msgid "Bearer Auth Token" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9249 -msgid "Belarus (by)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9526 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9545 -msgid "BitTorrent / P2P" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:57 msgid "Bootstrap DNS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:546 -msgid "Bootstrap DNS Servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1653 -msgid "Bot Status" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:51 #: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:79 msgid "Browser FakeIP check could not be completed" @@ -498,37 +196,10 @@ msgstr "" msgid "Browser is using FakeIP correctly" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1351 +#: src/tachyon/tabs/diagnostic/initController.ts:1258 msgid "Bug report downloaded" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9321 -msgid "Built-in rule sets" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1976 -msgid "By flag emoji from name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6495 -msgid "ByeDPI listen address and port are assigned by Tachyon and must not be set in the strategy." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6672 -msgid "ByeDPI option does not accept a compact value: %s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6601 -msgid "ByeDPI option does not accept a value: %s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6593 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6619 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6653 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6662 -msgid "ByeDPI option requires a value: %s" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:71 msgid "ByeDPI package is installed" msgstr "" @@ -553,38 +224,6 @@ msgstr "" msgid "ByeDPI sing-box outbound is not configured" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7435 -msgid "ByeDPI Strategy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6698 -msgid "ByeDPI strategy cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:932 -msgid "Bypasses UDP traffic for selected game consoles (PS5/Xbox) to achieve NAT Type 1 / 2 (Full Cone NAT) for P2P matchmaking, while keeping TCP (PSN/Auth) routed through the proxy." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8697 -msgid "CA Certificate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1006 -msgid "Cache all built-in lists and databases even if they are not currently selected in any section. Recommended if you have plenty of storage space or USB drive." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1149 -msgid "Cache File Path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1163 -msgid "Cache file path cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7712 -msgid "Cancel" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:26 #: src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:27 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:172 @@ -596,24 +235,12 @@ msgstr "" msgid "Cannot receive checks result" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2240 -msgid "Cannot save server" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:760 +msgid "Check Again" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3584 -msgid "Cannot save settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8984 -msgid "Cascade connection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2654 -msgid "Certificate path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1597 -msgid "Certificate pin is unavailable. Apply or restart the server to generate the default certificate, then open this dialog again." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:661 +msgid "Check All" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderSections.ts:426 @@ -621,56 +248,44 @@ msgstr "" msgid "Check Connection" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:115 -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:131 -msgid "Check Custom Domain" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:549 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:646 +msgid "Check Custom" +msgstr "" + +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:543 +msgid "Check domain or IP (e.g. example.com)..." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2636 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3099 #: src/tachyon/tabs/dashboard/initController.ts:1230 msgid "Check interval" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:136 -msgid "Check Services" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:159 +msgid "Check Mode:" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3112 -msgid "Check timeout after which the server is considered dead" +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:148 +msgid "Check Services" msgstr "" #: src/tachyon/tabs/updates/initController.ts:795 msgid "Check update" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2662 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3086 #: src/tachyon/tabs/dashboard/initController.ts:1228 msgid "Check URL" msgstr "" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:155 +msgid "Check YouTube" +msgstr "" + #: src/tachyon/tabs/dashboard/initController.ts:1404 msgid "Checking Connection..." msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:808 -msgid "Checking nftables filtering tables" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:807 -msgid "Checking sing-box service & DNSmasq" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:806 -msgid "Checking WAN interfaces & network routing" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:810 -msgid "Checking Zapret & ByeDPI rules" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1639 +#: src/tachyon/tabs/diagnostic/initController.ts:1552 #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:14 #: src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:15 #: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:15 @@ -687,26 +302,22 @@ msgstr "" #: src/tachyon/tabs/dashboard/partials/renderSections.ts:420 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:775 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:849 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:665 msgid "Checking..." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:275 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1545 -msgid "Checking…" -msgstr "" - #: src/tachyon/tabs/diagnostic/helpers/getCheckTitle.ts:2 msgid "checks" msgstr "" -#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:26 #: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:10 +#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:26 msgid "Checks failed" msgstr "" -#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:13 #: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:23 #: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:43 +#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:13 msgid "Checks passed" msgstr "" @@ -714,67 +325,18 @@ msgstr "" msgid "Checks passed with manual DHCP" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9246 -msgid "China (cn)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7531 -msgid "Choose Hosts File..." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9215 -msgid "Choose whether to route traffic to all destinations except selected countries (Exclude) or only to selected countries (Include)." -msgstr "" - #: src/validators/validateSubnet.ts:35 msgid "CIDR must be between 0 and 32 for IPv4 or 0 and 128 for IPv6" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8675 -msgid "Cipher" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7815 -msgid "Clean Comments" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10013 -msgid "Clear" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8709 -msgid "Client Certificate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2752 -msgid "Client fingerprint" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8721 -msgid "Client Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1669 -msgid "Client link" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1577 -msgid "Client link is not available yet" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1610 -msgid "Client link QR code" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3651 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10221 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1717 #: src/partials/modal/renderModal.ts:263 #: src/tachyon/tabs/dashboard/initController.ts:1085 -#: src/tachyon/tabs/diagnostic/initController.ts:1199 #: src/tachyon/tabs/monitoring/initController.ts:884 #: src/tachyon/tabs/monitoring/initController.ts:934 -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:28 +#: src/tachyon/tabs/diagnostic/initController.ts:1144 +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:212 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:62 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:766 msgid "Close" msgstr "" @@ -793,66 +355,14 @@ msgstr "" msgid "Closed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8629 -msgid "Cloudflare account / device ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8641 -msgid "Cloudflare API access token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8434 -msgid "Cloudflare WARP account / device ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8446 -msgid "Cloudflare WARP API access token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1692 -msgid "Comma-separated list of Telegram user IDs authorized to control the bot." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10201 -msgid "Community Lists" -msgstr "" - #: src/tachyon/services/core.service.ts:43 msgid "Component update available" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1028 -msgid "Component update check interval" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:520 -msgid "Components" -msgstr "" - #: src/tachyon/helpers/singBoxVariant.ts:60 msgid "compressed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2987 -msgid "Concurrency" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7224 -msgid "Conditions" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1135 -msgid "Config File Path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:367 -msgid "Configuration for Tachyon service" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4749 -msgid "Configure User-Agent in the item settings" -msgstr "" - #: src/tachyon/methods/custom/getDashboardSections.ts:1569 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:583 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141 @@ -863,18 +373,10 @@ msgstr "" msgid "Connect ChatGPT, DeepSeek or local LLM to get automated diagnostic reports and intelligent root-cause analysis." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9022 -msgid "Connect through" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderSections.ts:782 msgid "Connected" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8745 -msgid "Connection URL" -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:998 msgid "Connections are unavailable" msgstr "" @@ -883,14 +385,11 @@ msgstr "" msgid "Connectivity probe failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1564 #: src/helpers/copyToClipboard.ts:10 msgid "Copied" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1693 #: src/partials/modal/renderModal.ts:258 -#: src/tachyon/tabs/diagnostic/initController.ts:1194 msgid "Copy" msgstr "" @@ -904,101 +403,26 @@ msgstr "" msgid "Could not compare FakeIP and control public IPs" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9252 -msgid "Country code (e.g. ru, us, de)" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1162 +#: src/tachyon/tabs/diagnostic/initController.ts:1110 msgid "Current Diagnosis" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9039 -msgid "Current section cannot be used as its own transit section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2416 -msgid "Current section cannot download its own subscription" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderWidget.ts:22 msgid "Currently unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1315 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:915 msgid "Custom API Endpoint URL" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2492 -msgid "Custom device headers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7720 -msgid "Custom DNS Records (Hosts)" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:113 -msgid "Custom domain (e.g. google.com)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1271 -msgid "Custom OpenAI-Compatible API (OpenRouter)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1316 -msgid "Custom OpenAI-compatible API endpoint URL (e.g. http://192.168.1.100:11434/v1/chat/completions)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8860 -msgid "Custom outbound configurations in JSON format" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:496 -msgid "Dashboard" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderSections.ts:44 msgid "Dashboard currently unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1818 -msgid "Default (auto)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1065 -msgid "Default address for checking server availability and latency. URLTest uses its own address." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:856 -msgid "Delay in milliseconds before reloading Tachyon after interface UP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:863 -msgid "Delay value cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1744 -msgid "Delete" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2718 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2927 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3323 -msgid "Detect server country" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1205 -msgid "Detects and drops STUN/TURN packets in nftables to prevent real IP leaks via WebRTC." -msgstr "" - #: src/validators/validateOutboundJson.ts:115 msgid "detour must be a non-empty string" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9477 -msgid "Device filter" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1126 msgid "Device IPs (one per line):" msgstr "" @@ -1007,10 +431,6 @@ msgstr "" msgid "Device IPs saved" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6961 -msgid "Device or IP" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1164 msgid "Devices listed here are always routed through the assigned section, regardless of global rules." msgstr "" @@ -1023,145 +443,18 @@ msgstr "" msgid "DHCP is managed manually" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:484 -msgid "Diagnostics" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2562 -msgid "Direct" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8464 -msgid "Direct (Default)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2904 -msgid "Direct connection" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:88 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:90 msgid "Disable autostart" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:907 -msgid "Disable QUIC" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:908 -msgid "Disable the QUIC protocol to improve compatibility or fix issues with video streaming" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6096 -msgid "Disabling interception is incompatible with action=zapret2 because Tachyon sends matched traffic through NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2618 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3075 -msgid "Display name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9529 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9548 -msgid "DNS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:601 -msgid "DNS Check Interval" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1372 -msgid "DNS Check Interval (s)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:630 -msgid "DNS Failures Before Switching" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runDnsCheck.ts:75 msgid "DNS on router" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1814 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:519 -msgid "DNS over HTTPS (DoH)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1816 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:521 -msgid "DNS over QUIC (DoQ)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1815 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:520 -msgid "DNS over TLS (DoT)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2585 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7294 -msgid "DNS protocol" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:516 -msgid "DNS Protocol Type" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2586 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7295 -msgid "DNS protocol used by the resolver" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7357 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:711 -msgid "DNS requests through section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:658 -msgid "DNS Rewrite TTL" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2595 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7308 -msgid "DNS server" -msgstr "" - #: src/validators/validateDns.ts:8 msgid "DNS server address cannot be empty" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2596 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7309 -msgid "DNS server used by the resolver" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:547 -msgid "DNS server used to obtain IP addresses for upstream DNS and proxies. If multiple servers are selected, a timeout switches to a backup." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:532 -msgid "DNS Servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:503 -msgid "DNS Settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:690 -msgid "DNS Strategy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:644 -msgid "DNS Successful Checks Before Recovery" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:702 -msgid "DNS through proxy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7345 -msgid "DNS through section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:680 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:479 msgid "DNS Turbo Cache" msgstr "" @@ -1170,46 +463,18 @@ msgstr "" msgid "DNS Turbo Cache saved" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:619 -msgid "DNS Unavailability Timeout" -msgstr "" - #: src/tachyon/tabs/diagnostic/partials/renderWikiDisclaimer.ts:26 msgid "Do not panic, everything can be fixed, just..." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2791 -msgid "Do not test servers from these countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2807 -msgid "Do not test servers whose names match the expression." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2752 -msgid "Do not test servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2758 -msgid "Do not test servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2755 -msgid "Do not test servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2799 -msgid "Do not test specified servers." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:720 -#: src/tachyon/tabs/diagnostic/initController.ts:758 -#: src/tachyon/tabs/diagnostic/initController.ts:766 +#: src/tachyon/tabs/diagnostic/initController.ts:721 +#: src/tachyon/tabs/diagnostic/initController.ts:759 +#: src/tachyon/tabs/diagnostic/initController.ts:767 msgid "Doctor failed" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:736 -#: src/tachyon/tabs/diagnostic/initController.ts:745 +#: src/tachyon/tabs/diagnostic/initController.ts:737 +#: src/tachyon/tabs/diagnostic/initController.ts:746 msgid "Doctor repair" msgstr "" @@ -1217,39 +482,6 @@ msgstr "" msgid "Does not resolve" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9428 -msgid "Domain and IP lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9454 -msgid "Domain lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2576 -msgid "Domain Resolver" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1466 -msgid "Domain test sections" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9271 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10202 -msgid "Domains" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9301 -msgid "Domains automatically detected by Smart Detect or added via Telegram bot. You can manually edit or remove them here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8292 -msgid "Done" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1125 -msgid "Dont Touch My DHCP!" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1630 #: src/tachyon/tabs/dashboard/initController.ts:1643 msgid "Downlink" @@ -1259,334 +491,41 @@ msgstr "" msgid "Download" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1104 -msgid "Download component packages via the selected section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1112 -msgid "Download components through" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1103 -msgid "Download components through a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1090 -msgid "Download lists through" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1081 -msgid "Download lists through a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1082 -msgid "Download remote lists and rule sets via the selected section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2390 -msgid "Download subscription through a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2391 -msgid "Download subscriptions via the selected section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2399 -msgid "Download through" -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:877 #: src/tachyon/tabs/monitoring/initController.ts:931 msgid "Downloaded" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:427 -msgid "Drag rows to change priority. The rule at the top is checked first." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9514 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10209 -msgid "DSCP marks (QoS)" -msgstr "" - #: src/validators/validateOutboundJson.ts:75 msgid "Duplicate JSON outbound tag" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4795 -msgid "Duplicate value" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8676 -msgid "e.g. AES-256-GCM — leave empty for default" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10011 -msgid "e.g. google.com, 1.1.1.1, 443" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8687 -msgid "e.g. SHA256 — leave empty for default" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1737 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:68 -msgid "Edit rule action" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7226 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2479 -msgid "Enable" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1427 -msgid "Enable Adaptive Intervals" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1250 -msgid "Enable AI Doctor (ChatGPT / LLM Analysis)" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:760 msgid "Enable AI Doctor (LLM Integration)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1434 -msgid "Enable Anomaly Detection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2839 -msgid "Enable authentication" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:959 -msgid "Enable automatic updates for remote lists and rule sets" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:98 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:100 msgid "Enable autostart" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2577 -msgid "Enable built-in DNS resolver for domains handled by this section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1406 -msgid "Enable Config Validation" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1366 -msgid "Enable DNS Continuous Check" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:498 msgid "Enable DNS Turbo Cache" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1379 -msgid "Enable Firewall Reload Dedup" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1413 -msgid "Enable Graceful Degradation" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1386 -msgid "Enable Health Metrics" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:958 -msgid "Enable list updates" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9060 -msgid "Enable Mixed Proxy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9101 -msgid "Enable Mixed Proxy Authentication" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:758 -msgid "Enable Output Network Interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1342 -msgid "Enable Proxy Health Monitor" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1399 -msgid "Enable Smart Cooldowns" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1453 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1070 msgid "Enable Smart Detect" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1663 -msgid "Enable Telegram Bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:591 -msgid "Enable WAN DNS Fallback for Bootstrap DNS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:582 -msgid "Enable WAN DNS Fallback for Main DNS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1224 -msgid "Enable Watchdog" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:872 -msgid "Enable YACD" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:882 -msgid "Enable YACD WAN Access" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1664 -msgid "Enables the background daemon that polls Telegram for commands and sends notifications." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1225 -msgid "Enables the background watchdog process to monitor services and auto-recover on failures." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2585 -msgid "Enter a complete sing-box inbound object" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4001 -msgid "Enter a complete sing-box outbound object" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2630 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3080 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3956 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3972 -msgid "Enter a display name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2877 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2898 -msgid "Enter a level name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2473 -msgid "Enter HWID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1675 -msgid "Enter the API token obtained from @BotFather." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2465 -msgid "Enter the HWID sent with subscription requests" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8771 -msgid "Enter the subscription URL" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8083 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8085 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8092 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8094 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8146 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8148 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8152 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8154 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8233 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8244 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8246 -msgid "Error" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8154 -msgid "Error running generator:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10124 -msgid "Error running trace:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2747 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2957 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3355 -msgid "Exclude by proxy parameters" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2806 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3019 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3415 -msgid "Exclude by regular expression" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2790 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3003 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3399 -msgid "Exclude countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9219 -msgid "Exclude selected countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2798 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3011 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3407 -msgid "Exclude servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2965 -msgid "Exclude servers with one of the selected protocols from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2971 -msgid "Exclude servers with one of the selected security types from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2968 -msgid "Exclude servers with one of the selected transports from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9523 -msgid "Exclude traffic types" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3470 -msgid "Exclude URLTest / Priority group" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9497 -msgid "Excluded devices" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:54 -msgid "Expecting: %s" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderSections.ts:131 msgid "Expires" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9061 -msgid "Expose this section as a local HTTP+SOCKS proxy" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:255 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:752 +msgid "Failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5630 -msgid "External nfqws config files bypass Tachyon queue management and explicit validation." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6075 -msgid "External nfqws2 config files bypass Tachyon queue management and explicit validation." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1044 +#: src/tachyon/tabs/diagnostic/initController.ts:1015 msgid "Failed to apply fix" msgstr "" @@ -1600,7 +539,6 @@ msgstr "" msgid "Failed to close connections" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1566 #: src/helpers/copyToClipboard.ts:12 msgid "Failed to copy!" msgstr "" @@ -1614,29 +552,21 @@ msgstr "" msgid "Failed to execute" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:44 -msgid "Failed to execute service check." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1354 +#: src/tachyon/tabs/diagnostic/initController.ts:1261 msgid "Failed to generate bug report" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8085 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8094 -msgid "Failed to generate WARP config:" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:115 +msgid "Failed to parse target list." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8246 -msgid "Failed to parse file:" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:106 +msgid "Failed to receive response from AI service." msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:52 -msgid "Failed to parse service check results." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8148 -msgid "Failed to parse WARP config:" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:97 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:785 +msgid "Failed to run service check." msgstr "" #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:405 @@ -1655,22 +585,6 @@ msgstr "" msgid "Failed to save Smart Detect settings" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1609 -msgid "Failed to start bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:341 -msgid "Failed to start watchdog" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1623 -msgid "Failed to stop bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:355 -msgid "Failed to stop watchdog" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:309 #: src/tachyon/tabs/dashboard/initController.ts:310 #: src/tachyon/tabs/dashboard/initController.ts:329 @@ -1693,19 +607,6 @@ msgstr "" msgid "FakeIP works; public IP comparison is inconclusive" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2962 -msgid "FakeTLS host" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3044 -msgid "Fallback on unknown DC" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1367 -msgid "Faster DNS health monitoring than the default cycle. Switches bootstrap DNS on failure." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3159 #: src/tachyon/tabs/dashboard/initController.ts:1249 msgid "Faster server search interval" msgstr "" @@ -1714,206 +615,66 @@ msgstr "" msgid "Fastest" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:19 -msgid "Fetching service status, please wait..." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3312 -msgid "Filter the servers that will be displayed on the dashboard." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9243 -msgid "Finland (fi)" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:34 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:79 +msgid "Fetching service targets..." msgstr "" #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:136 msgid "Firewall WAN port" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1055 -msgid "Fix All" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1039 +#: src/tachyon/tabs/diagnostic/initController.ts:1010 msgid "Fix applied" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3585 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2241 -msgid "Fix the highlighted fields and save again." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:742 -#: src/tachyon/tabs/diagnostic/initController.ts:1035 +#: src/tachyon/tabs/diagnostic/initController.ts:743 +#: src/tachyon/tabs/diagnostic/initController.ts:1006 msgid "Fixed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9486 -msgid "Forced device routing" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:158 +msgid "Full System Diagnostic" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1215 -msgid "Forces sing-box to tunnel DNS requests via DoQ with Encrypted Client Hello (ECH) for SNI hiding." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9242 -msgid "France (fr)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3007 -msgid "Fronting IP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2996 -msgid "Fronting port" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3017 -msgid "Fronting proxy protocol" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6093 -msgid "Fuzzing is not supported here because Tachyon needs deterministic runtime validation." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:941 -msgid "Game Console IPs" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:931 -msgid "Game Console Optimizer (NAT Type 1)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2480 -msgid "Generate a random 16-character hexadecimal HWID" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:163 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:175 msgid "Generate bug report" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2479 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2484 -msgid "Generate HWID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2456 -msgid "Generate HWID from router hardware information for this subscription" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8009 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8047 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8063 -msgid "Generate WARP Config" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:89 msgid "Generated inbound" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8142 -msgid "Generated!" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8078 -msgid "Generating…" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9232 -msgid "GeoIP Countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9214 -msgid "GeoIP Mode" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10206 -msgid "GeoSite / GeoIP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9239 -msgid "Germany (de)" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:729 msgid "GET endpoints are open on LAN. POST endpoints require Authorization: Bearer ." msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:107 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:109 msgid "Get global check" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:696 +#: src/tachyon/tabs/diagnostic/initController.ts:697 msgid "Global check" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2819 -msgid "gRPC service" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3072 -msgid "Handshake timeout" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:584 msgid "Health Checks" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2565 -msgid "Hide cascade connection nodes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2554 -msgid "Hide individual nodes that are already included in imported subscription URLTest groups" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2566 -msgid "Hide intermediate nodes used as detours by other subscription nodes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3408 -msgid "Hide selected servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3471 -msgid "Hide servers from selected groups without repeating their filtering criteria." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3400 -msgid "Hide servers from the specified countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3416 -msgid "Hide servers whose names match the expression." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3363 -msgid "Hide servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3367 -msgid "Hide servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3364 -msgid "Hide servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2553 -msgid "Hide URLTest group nodes" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:14 +msgid "Hello! I am Tachyon AI Assistant. How can I help you today? Ask me about domain blocks, diagnostics, or router settings." msgstr "" #: src/partials/modal/renderModal.ts:310 msgid "Hide values" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3123 #: src/tachyon/tabs/dashboard/initController.ts:1235 msgid "Higher-level check interval" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:610 -msgid "Higher-priority DNS Check" +#: src/tachyon/tabs/diagnostic/initController.ts:1122 +msgid "History" msgstr "" #: src/tachyon/tabs/monitoring/initController.ts:867 @@ -1921,184 +682,22 @@ msgstr "" msgid "Host" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4264 -msgid "Hosts" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7985 -msgid "Hosts Lists Update Interval" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1393 -msgid "How many hours of metrics to keep (default 24)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3124 -msgid "How often higher priority levels are checked while a lower level is active" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3100 -msgid "How often the currently selected server is checked" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1373 -msgid "How often to check DNS health in seconds (default 60)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1349 -msgid "How often to check proxy health in seconds (fast tier, default 30)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1715 -msgid "How often to check Telegram for new messages (default: 5)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:602 -msgid "How often to check the active DNS servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:611 -msgid "How often to check whether a higher-priority DNS server has recovered." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9530 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9549 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:387 msgid "HTTP" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:67 -msgid "HTTP (ms)" -msgstr "" - #: src/tachyon/api.ts:27 msgid "HTTP error" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2812 -msgid "HTTP hosts" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:689 msgid "HTTP REST API for external AI agents (Claude, GPT, Open-WebUI) served at /cgi-bin/tachyon-agent/" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2464 -msgid "HWID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2675 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3062 #: src/tachyon/tabs/dashboard/initController.ts:1110 msgid "Idle timeout" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1414 -msgid "If one health check fails with an error, continue running other checks instead of stopping." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7577 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7590 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7640 -msgid "Import" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7637 -msgid "Import (%d records)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8164 -msgid "Import AmneziaWG settings from .conf file" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7691 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7824 -msgid "Import Hosts File" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2544 -msgid "Import subscription URLTest groups" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2545 -msgid "Import URLTest groups returned by this subscription provider" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2584 -msgid "Inbound JSON" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1970 -msgid "Inbound JSON cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1981 -msgid "Inbound JSON must be an object with a type field" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2730 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2939 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3335 -msgid "Include by proxy parameters" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2782 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2995 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3391 -msgid "Include by regular expression" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2766 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2979 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3375 -msgid "Include countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4076 -msgid "Include IP addresses and subnets" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9220 -msgid "Include selected countries" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2774 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2987 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3383 -msgid "Include servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1745 -msgid "Information" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8401 -msgid "Init Packet Magic Header (S1)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8403 -msgid "Init Packet Magic Header (S3)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8409 -msgid "Init Packet Payload (I1)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8410 -msgid "Init Packet Payload (I2)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8411 -msgid "Init Packet Payload (I3)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8412 -msgid "Init Packet Payload (I4)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8413 -msgid "Init Packet Payload (I5)" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:809 msgid "Install" msgstr "" @@ -2116,41 +715,15 @@ msgstr "" msgid "Installed version is newer than release" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:821 -msgid "Interface Monitoring" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:855 -msgid "Interface Monitoring Delay" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:822 -msgid "Interface monitoring for Bad WAN" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2689 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3175 #: src/tachyon/tabs/dashboard/initController.ts:1112 #: src/tachyon/tabs/dashboard/initController.ts:1255 msgid "Interrupt connections" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3176 -msgid "Interrupt connections when priority failover switches server" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2690 -msgid "Interrupt connections when URLTest switches the selected server" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1108 msgid "Interval" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7456 -msgid "Invalid ByeDPI strategy" -msgstr "" - #: src/validators/validateSubnet.ts:25 msgid "Invalid CIDR prefix" msgstr "" @@ -2163,7 +736,6 @@ msgstr "" msgid "Invalid DNS server port" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5303 #: src/validators/validateDomain.ts:67 #: src/validators/validateDomain.ts:73 msgid "Invalid domain address" @@ -2234,32 +806,18 @@ msgstr "" msgid "Invalid IP address" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1983 #: src/validators/validateOutboundJson.ts:58 msgid "Invalid JSON format" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7754 -msgid "Invalid line: \"%s\". Use: domain ip or ip domain" -msgstr "" - #: src/validators/validatePath.ts:22 msgid "Invalid path format. Path must start with \"/\" and contain valid characters" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9094 #: src/validators/validateShadowsocksUrl.ts:91 msgid "Invalid port number. Must be between 1 and 65535" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5452 -msgid "Invalid port or range. Use 80 or 1000-2000" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4678 -msgid "Invalid regular expression" -msgstr "" - #: src/validators/validateShadowsocksUrl.ts:38 msgid "Invalid Shadowsocks URL: decoded credentials must contain method:password" msgstr "" @@ -2427,50 +985,15 @@ msgstr "" msgid "Invalid VMess URL: parsing failed" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:64 -msgid "IP / DNS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10203 -msgid "IP Addresses (IP CIDR)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9311 -msgid "IPs" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:692 -msgid "IPv4 only" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:694 -msgid "IPv6 only" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:920 -msgid "Isolate BitTorrent traffic and force it direct to prevent VPN bans" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:738 +#: src/tachyon/tabs/diagnostic/initController.ts:739 msgid "Issues" msgstr "" -#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:20 #: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:17 +#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:20 msgid "Issues detected" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9247 -msgid "Japan (jp)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1082 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4000 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4266 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8859 -msgid "JSON outbound" -msgstr "" - #: src/validators/validateOutboundJson.ts:50 msgid "JSON outbound cannot be empty" msgstr "" @@ -2487,64 +1010,15 @@ msgstr "" msgid "JSON outbound must contain a non-empty type field" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4024 -msgid "JSON outbound settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8400 -msgid "Junk Max Size (Jmax)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8399 -msgid "Junk Min Size (Jmin)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8398 -msgid "Junk Packet Count (Jc)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9250 -msgid "Kazakhstan (kz)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3185 -msgid "Keep Priority before latency-sorted servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2699 -msgid "Keep URLTest before latency-sorted servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:681 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:484 msgid "Keeps FakeIP cache persistent across reboots and pre-resolves popular blocked domains on startup so first-visit latency is 0 ms." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8592 -msgid "Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2669 -msgid "Key path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4688 -msgid "Keyword must not contain spaces or commas" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1292 -msgid "Language for AI Doctor diagnosis responses" -msgstr "" - #: src/tachyon/methods/shell/index.ts:480 #: src/tachyon/methods/shell/index.ts:501 msgid "Latency test failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1064 -msgid "Latency test URL" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:302 #: src/tachyon/tabs/updates/initController.ts:1142 msgid "Latest version is installed" @@ -2554,72 +1028,18 @@ msgstr "" msgid "Latest version:" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2510 -msgid "Leave empty to omit this header" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1191 msgid "Level" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2893 -msgid "Level name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7157 -msgid "List must be an HTTP(S) URL or a local .lst path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1495 -msgid "List of domains automatically detected and the section they were added to. To edit or remove them, open the routing rules of the respective section." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:968 -msgid "List Update Frequency" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2534 -msgid "Listen address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2541 -msgid "Listen port" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:125 msgid "Listening port" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1270 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:821 msgid "LM Studio (Local PC / Server)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8215 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8224 -msgid "Load .conf" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8163 -msgid "Load .conf config" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7550 -msgid "Load Current Records" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7547 -msgid "Loaded %d current record(s)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8290 -msgid "Loaded!" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1702 -msgid "Loading client link..." -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:988 #: src/tachyon/tabs/monitoring/render.ts:101 msgid "Loading connections" @@ -2637,14 +1057,6 @@ msgstr "" msgid "Loading…" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8312 -msgid "Local Address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1186 -msgid "Log Level" -msgstr "" - #: src/tachyon/helpers/singBoxVariant.ts:62 msgid "lx" msgstr "" @@ -2653,94 +1065,14 @@ msgstr "" msgid "Main DNS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:533 -msgid "Main DNS server. If multiple servers are selected, a timeout switches to a backup." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8640 -msgid "MASQUE Access Token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8628 -msgid "MASQUE Account ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8616 -msgid "MASQUE Private Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9312 -msgid "Match destination IPs or subnets" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9507 -msgid "Match destination ports. Use a single port or a range" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10064 -msgid "Match Found" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9515 -msgid "Match traffic by packet DSCP mark (assigned in Windows via Policy-Based QoS). Examples: 46 (EF), 0x2e, 34 (AF41)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1441 -msgid "Max reconnects per hour before alert (default 10)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:620 -msgid "Maximum time to wait for example.com to resolve during a DNS health check." -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1656 msgid "Memory Usage" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2826 -msgid "Method" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1392 -msgid "Metrics Retention (hours)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2649 -msgid "Minimum latency difference in milliseconds that triggers switching to a faster server." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9152 -msgid "Mixed Proxy Password" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9075 -msgid "Mixed Proxy Port" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9116 -msgid "Mixed Proxy Username" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1279 -msgid "Model name to use. Leave empty to use default (gpt-4o-mini / claude-3-5-haiku / deepseek-chat / llama3:latest)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:831 -msgid "Monitored Interfaces" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:508 -msgid "Monitoring" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:633 msgid "Monitoring & Analytics" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1435 -msgid "Monitors sing-box reconnect frequency. Alerts if too many reconnects per hour." -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1004 msgid "Move down" msgstr "" @@ -2749,49 +1081,6 @@ msgstr "" msgid "Move up" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8375 -msgid "MTU" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1705 -msgid "Must be a comma-separated list of numeric IDs" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2074 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2089 -msgid "Must be a number in the range of 0 - 10000" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2619 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3076 -msgid "Name displayed on the dashboard" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2894 -msgid "Name shown in the priority level list" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9240 -msgid "Netherlands (nl)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:504 -msgid "Network & Interfaces" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1889 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8818 -msgid "Network Interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3775 -msgid "Network interface settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7631 -msgid "New domains:" -msgstr "" - #: src/tachyon/services/core.service.ts:38 msgid "New version %s is available for %s" msgstr "" @@ -2806,22 +1095,6 @@ msgstr "" msgid "NFQUEUE range overlaps with another rule" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7374 -msgid "NFQWS Strategy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5760 -msgid "NFQWS strategy cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7407 -msgid "NFQWS2 Strategy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6234 -msgid "NFQWS2 strategy cannot be empty" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:812 #: src/tachyon/tabs/dashboard/initController.ts:816 #: src/tachyon/tabs/dashboard/initController.ts:892 @@ -2837,7 +1110,6 @@ msgstr "" msgid "No active connections" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:389 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1112 msgid "No active routing sections found." msgstr "" @@ -2850,31 +1122,15 @@ msgstr "" msgid "No conflict detected" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10113 -msgid "No Custom Rules Matched" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1097 +#: src/tachyon/tabs/diagnostic/initController.ts:1042 msgid "No diagnostic history available yet." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1510 -msgid "No domains detected yet" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:57 -msgid "No domains found to check." -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:187 msgid "No enabled server inbounds configured" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7554 -msgid "No file selected" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:745 +#: src/tachyon/tabs/diagnostic/initController.ts:746 msgid "No issues found" msgstr "" @@ -2886,7 +1142,7 @@ msgstr "" msgid "No public firewall port required" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1087 +#: src/tachyon/tabs/diagnostic/initController.ts:1032 msgid "No quick fix required" msgstr "" @@ -2902,6 +1158,10 @@ msgstr "" msgid "No rules use Zapret2" msgstr "" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:123 +msgid "No targets found in section configs." +msgstr "" + #: src/tachyon/tabs/dashboard/initController.ts:1070 msgid "Node list is empty" msgstr "" @@ -2910,13 +1170,6 @@ msgstr "" msgid "Nodes" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:449 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2599 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2891 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2900 -msgid "None" -msgstr "" - #: src/tachyon/methods/custom/getDashboardSections.ts:1572 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:586 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46 @@ -2961,113 +1214,22 @@ msgid "Not responding" msgstr "" #: src/tachyon/tabs/diagnostic/diagnostic.store.ts:140 -#: src/tachyon/tabs/diagnostic/initController.ts:123 -#: src/tachyon/tabs/diagnostic/initController.ts:353 -#: src/tachyon/tabs/diagnostic/initController.ts:411 -#: src/tachyon/tabs/diagnostic/initController.ts:497 +#: src/tachyon/tabs/diagnostic/initController.ts:124 +#: src/tachyon/tabs/diagnostic/initController.ts:354 +#: src/tachyon/tabs/diagnostic/initController.ts:412 +#: src/tachyon/tabs/diagnostic/initController.ts:498 msgid "Not running" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10179 -msgid "Not set" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1787 -msgid "Notify on Certificate Warnings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1735 -msgid "Notify on Core Crashes" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1800 -msgid "Notify on DNS Leaks" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1761 -msgid "Notify on Server Switches" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1748 -msgid "Notify on Service Restarts" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1774 -msgid "Notify on Subscription Updates" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:631 -msgid "Number of consecutive failed checks required before switching DNS servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1355 -msgid "Number of consecutive failures before restarting (default 3)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:645 -msgid "Number of consecutive successful checks required before returning to a higher-priority DNS server." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2899 -msgid "Obfuscation" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2922 -msgid "Obfuscation password" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1269 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:813 msgid "Ollama (Local PC / Server)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7721 -msgid "One record per line: example.com 192.168.1.100 or 192.168.1.100 example.com. Lines starting with # are ignored." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2980 -msgid "Only from the specified countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1960 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1968 -msgid "Only selected" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1961 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1970 -msgid "Only selected except exclusions" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2996 -msgid "Only servers whose names match the expression." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2947 -msgid "Only servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2951 -msgid "Only servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2948 -msgid "Only servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2988 -msgid "Only the specified servers." -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:1118 #: src/tachyon/tabs/updates/initController.ts:1157 msgid "Open" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3968 -msgid "Open priority settings and enter a display name" -msgstr "" - #: src/tachyon/tabs/diagnostic/partials/renderWikiDisclaimer.ts:31 msgid "Open Project Page" msgstr "" @@ -3082,121 +1244,34 @@ msgstr "" msgid "Optimization" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1399 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6836 -msgid "Option \"%s\" contains an invalid input value." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8604 -msgid "Optional — leave empty for default" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:901 msgid "Optional for local LLM" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8734 -msgid "Optional tls-auth or tls-crypt key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5838 -msgid "Optional values must be attached with '=' here; a separate token would be ignored by nfqws." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6312 -msgid "Optional values must be attached with '=' here; a separate token would be ignored by nfqws2." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7696 -msgid "Or paste hosts file content:" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:63 -msgid "Outbound" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:358 +msgid "Outbound Route" msgstr "" #: src/validators/validateOutboundJson.ts:111 msgid "outbounds must be a non-empty array of strings" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:768 -msgid "Output Network Interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2493 -msgid "Override the default OpenWrt device headers for this subscription" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7705 -msgid "Overwrite existing records (if unchecked, merge with existing records)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:919 -msgid "P2P Leak Protection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2981 -msgid "Padding" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7628 -msgid "Parsed records:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8483 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8571 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2862 -msgid "Password" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9178 -msgid "Password cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7573 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7588 -msgid "Paste content or upload a file to preview imported DNS records." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:240 +msgid "Passed" msgstr "" #: src/validators/validatePath.ts:7 msgid "Path cannot be empty" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1167 -msgid "Path must be absolute (start with /)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1176 -msgid "Path must contain at least one directory (like /tmp/cache.db)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1171 -msgid "Path must end with cache.db" -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:737 #: src/tachyon/tabs/monitoring/render.ts:80 #: src/tachyon/tabs/monitoring/render.ts:81 msgid "Pause updates" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8335 -msgid "Peer Public Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8698 -msgid "PEM-encoded CA certificate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8710 -msgid "PEM-encoded client certificate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8722 -msgid "PEM-encoded client private key" -msgstr "" - #: src/tachyon/tabs/diagnostic/diagnostic.store.ts:63 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:442 msgid "Pending" msgstr "" @@ -3205,98 +1280,10 @@ msgstr "" msgid "Per-Device Routing" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3149 -msgid "Periodically check the current level and switch to a faster server even when the current one works." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1343 -msgid "Periodically checks if the proxy is responding. Restarts Tachyon after consecutive failures." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8382 -msgid "Persistent Keepalive" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1420 -msgid "Persistent Smart Detect" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2698 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3184 -msgid "Pin on dashboard" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1714 -msgid "Polling Interval (seconds)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1727 -msgid "Polling interval must be at least 1 second" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9086 -msgid "Port cannot be empty" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:19 msgid "Port conflict" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9076 -msgid "Port for the local mixed proxy of this section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5459 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1813 -msgid "Port must be between 1 and 65535" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5463 -msgid "Port range start must be less than or equal to end" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9506 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10208 -msgid "Ports" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1005 -msgid "Pre-download all preset lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8526 -msgid "Pre-shared key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:691 -msgid "Prefer IPv4" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:693 -msgid "Prefer IPv6" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3024 -msgid "Preferred IP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2537 -msgid "Prefix text" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8369 -msgid "Preshared Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1380 -msgid "Prevents multiple reload_firewall calls within 120 seconds to avoid connection drops." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8945 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10103 -msgid "Priority" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1274 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:514 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:515 @@ -3307,209 +1294,43 @@ msgstr "" msgid "Priority details are unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3853 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3854 -msgid "Priority level settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3193 -msgid "Priority levels" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3913 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3918 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3919 -msgid "Priority settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8324 -msgid "Private Key" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:613 msgid "Protection" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2030 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8663 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2485 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2519 -msgid "Protocol" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1354 -msgid "Proxy Fail Threshold" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1348 -msgid "Proxy Health Check Interval (s)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1360 -msgid "Proxy Health Check URL" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:807 msgid "Proxy link is unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1811 -msgid "Proxy Section for Bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8457 -msgid "Proxy to use for WARP API registration (api.cloudflareclient.com)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8526 -msgid "PSK" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2548 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:40 msgid "Public host" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1612 -msgid "QR code is too large" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9527 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9546 -msgid "QUIC (HTTP/3)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9533 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9552 -msgid "RDP" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8296 -msgid "Read error" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2687 -msgid "Reality fake site" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2698 -msgid "Reality fake site port" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2741 -msgid "Reality max time difference" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2709 -msgid "Reality private key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2716 -msgid "Reality public key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2722 -msgid "Reality short ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2094 -msgid "Reality short ID must contain 1-8 hex digits" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:1138 msgid "Rebuilt release" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1007 -msgid "Recommended Smart Quick Fixes:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1440 -msgid "Reconnect Threshold" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1387 -msgid "Records proxy/DNS latency and health status in hourly buckets for analysis." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7779 -msgid "Records: %d" +#: src/tachyon/tabs/diagnostic/initController.ts:979 +msgid "Recommended Quick Fixes:" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderSections.ts:132 msgid "Refill" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8456 -msgid "Registration Detour" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5345 -msgid "Regular expression must not contain spaces or commas" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:898 msgid "Reinstall" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7838 -msgid "Remote Hosts Lists" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7918 #: src/tachyon/tabs/updates/initController.ts:854 msgid "Remove" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3004 -msgid "Remove servers from the specified countries from this level." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:363 +msgid "Resolved IP / DNS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3020 -msgid "Remove servers whose names match the expression from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3012 -msgid "Remove the specified servers from this level." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9102 -msgid "Require a username and password for the local mixed proxy" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9189 -msgid "Resolve domain names before routing so sing-box can use real destination IPs." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9188 -msgid "Resolve real IP for routing" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5633 -msgid "Resource selection by hostname inside nfqws is not supported here; sing-box selects resources before NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6078 -msgid "Resource selection by hostname inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5636 -msgid "Resource selection by IP or CIDR inside nfqws is not supported here; sing-box selects resources before NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6081 -msgid "Resource selection by IP or CIDR inside nfqws2 is not supported here; sing-box selects resources before NFQUEUE." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8402 -msgid "Response Packet Magic Header (S2)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8404 -msgid "Response Packet Magic Header (S4)" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:58 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:60 msgid "Restart Tachyon" msgstr "" @@ -3526,63 +1347,12 @@ msgstr "" msgid "Route" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1812 -msgid "Route bot API requests through this section. Leave empty to use the default mixed proxy." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:703 -msgid "Route main DNS requests through the selected section." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7346 -msgid "Route requests to this DNS server through another section." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2560 -msgid "Routing mode" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10008 -msgid "Routing Rule Tracer" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:103 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:114 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:144 msgid "Routing rules" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2569 -msgid "Routing section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10074 -msgid "Rule" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7148 -msgid "Rule set must be an HTTP(S) URL or a local .srs / .json path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4083 -msgid "Rule set settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9374 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9403 -msgid "Rule sets" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10204 -msgid "Rule Sets (.srs / .json)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2561 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:101 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:107 -msgid "Rules" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runNftCheck.ts:79 msgid "Rules mangle counters" msgstr "" @@ -3607,7 +1377,7 @@ msgstr "" msgid "Rules proxy exist" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:126 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:128 msgid "Run AI Doctor" msgstr "" @@ -3615,28 +1385,16 @@ msgstr "" msgid "Run Diagnostic" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:116 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:118 msgid "Run doctor repair" msgstr "" -#: src/tachyon/tabs/diagnostic/initController.ts:1174 -msgid "Run History" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:301 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1573 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1574 #: src/tachyon/methods/custom/getDashboardSections.ts:1567 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:581 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135 msgid "Running" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9237 -msgid "Russia (ru)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3660 #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1151 msgid "Save" msgstr "" @@ -3660,231 +1418,37 @@ msgstr "" msgid "Search" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2938 -msgid "Secret" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:896 -msgid "Secret key for authenticating remote access to YACD when WAN access is enabled." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1238 -msgid "Secret token for authorizing WRITE operations (POST/PUT) on /cgi-bin/tachyon-agent/. Leave empty if auth is not required." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:328 +msgid "Search domain..." msgstr "" #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:700 msgid "Secret token for WRITE requests" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:432 -msgid "Section" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:62 -msgid "Section / Domain" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10198 -msgid "Section action" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7253 -msgid "Section name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10213 -msgid "Section Rules Content" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:353 +msgid "Section / Target" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1078 msgid "Section test order (checked = active, drag rows with △▽):" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:426 -msgid "Sections" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2042 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2596 -msgid "Security" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2436 -msgid "Select a common client profile or enter a custom User-Agent" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8233 -msgid "Select a file with .conf extension" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8824 -msgid "Select a network interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9322 -msgid "Select a predefined domain list" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7367 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:87 -msgid "Select a section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2413 -msgid "Select a section for downloading this subscription" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9023 -msgid "Select a transit section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1263 -msgid "Select AI LLM provider for diagnostics" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1940 -msgid "Select an existing network interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3295 -msgid "Select an existing URLTest or Priority group" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9036 -msgid "Select an intermediate section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1467 -msgid "Select and order the sections through which blocked domains are tested. Checked sections are tried top-to-bottom." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:517 -msgid "Select DNS protocol to use" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8819 -msgid "Select network interface for VPN connection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9233 -msgid "Select one or more country ISO codes (e.g. ru, us, de, nl, fr, fi, se, tr, cn, jp, sg, by, kz, ua)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2449 -msgid "Select or enter a User-Agent" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1150 -msgid "Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:942 -msgid "Select or enter the IP addresses of your game consoles." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1136 -msgid "Select path for sing-box config file. Change this ONLY if you know what you are doing" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3137 #: src/tachyon/tabs/dashboard/initController.ts:1239 msgid "Select the fastest node" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1187 -msgid "Select the log level for sing-box" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:721 -msgid "Select the network interface from which the traffic will originate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:769 -msgid "Select the network interface to which the traffic will originate" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:832 -msgid "Select the WAN interfaces to be monitored" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1104 #: src/tachyon/tabs/dashboard/initController.ts:1225 msgid "Selected" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2563 -msgid "Selected section" -msgstr "" - #: src/validators/validateOutboundJson.ts:85 msgid "Selector and URLTest outbounds must contain a non-empty outbounds array" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1801 -msgid "Send a Telegram notification if a potential DNS leak is detected." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1736 -msgid "Send a Telegram notification if sing-box or nftables rules crash and get auto-restored." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1788 -msgid "Send a Telegram notification if SSL/TLS certificates are close to expiration." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1749 -msgid "Send a Telegram notification if the Tachyon service is restarted by the watchdog." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1762 -msgid "Send a Telegram notification when a URLTest group switches to a new server." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1775 -msgid "Send a Telegram notification when proxy subscriptions are successfully updated." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:449 -msgid "Server" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8346 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8471 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8514 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8545 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8580 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8650 -msgid "Server Address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2707 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2913 -msgid "Server filtering" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8887 -msgid "Server group for automatic lowest-latency selection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8946 -msgid "Server group for priority failover" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1706 -msgid "Server information" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1622 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2496 -msgid "Server name" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2625 -msgid "Server name / SNI" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8495 -msgid "Server Name Indication — leave empty to use server address" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:67 +msgid "Send" msgstr "" #: src/validators/validateOutboundJson.ts:94 @@ -3895,96 +1459,33 @@ msgstr "" msgid "Server outbound must contain a numeric server_port from 1 to 65535" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8357 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8477 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8520 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8551 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8586 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8656 -msgid "Server Port" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:135 +msgid "Server unavailable" msgstr "" #: src/validators/validateOutboundJson.ts:107 msgid "server_port must be a number from 1 to 65535" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:443 -msgid "Servers" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3311 -msgid "Servers on dashboard" -msgstr "" - #: src/tachyon/methods/shell/index.ts:401 #: src/tachyon/methods/shell/index.ts:422 -#: src/tachyon/tabs/diagnostic/initController.ts:604 +#: src/tachyon/tabs/diagnostic/initController.ts:605 msgid "Service action failed" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:24 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:70 msgid "Service Health Check" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9325 -msgid "Service list" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:505 -msgid "Services & Access" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1666 msgid "Services info" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1143 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7223 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:461 -msgid "Settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2520 -msgid "Show metadata on dashboard" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3384 -msgid "Show only selected servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3343 -msgid "Show only servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3349 -msgid "Show only servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3346 -msgid "Show only servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3457 -msgid "Show servers from selected groups without repeating their filtering criteria." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3376 -msgid "Show servers only from the specified countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3392 -msgid "Show servers whose names match the expression." -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1287 -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:154 +#: src/tachyon/tabs/diagnostic/initController.ts:1194 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:166 msgid "Show sing-box config" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2521 -msgid "Show subscription metadata for this source on the dashboard" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runSingBoxCheck.ts:77 msgid "Sing-box autostart disabled" msgstr "" @@ -4017,26 +1518,6 @@ msgstr "" msgid "Sing-box version is compatible (newer than 1.12.4)" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9248 -msgid "Singapore (sg)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7701 -msgid "Skip loopback & local entries (127.0.0.1, ::1, 0.0.0.0, localhost)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8506 -msgid "Skip TLS certificate verification (not recommended)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7630 -msgid "Skipped comments/invalid:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7629 -msgid "Skipped loopback:" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:1048 msgid "Smart Detect" msgstr "" @@ -4045,54 +1526,11 @@ msgstr "" msgid "Smart Detect settings saved" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8533 -msgid "Snell Version" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1072 -msgid "Some fixes failed" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7801 -msgid "Sort Alphabetically" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9048 -msgid "Sort by latency" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9049 -msgid "Sorts servers in this section by lowest latency in the dashboard." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10081 #: src/tachyon/tabs/monitoring/initController.ts:883 #: src/tachyon/tabs/monitoring/initController.ts:933 msgid "Source" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10207 -msgid "Source Devices" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:720 -msgid "Source Network Interface" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1929 -msgid "Specify a file path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1940 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1952 -msgid "Specify different files" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9532 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9551 -msgid "SSH" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:122 msgid "Standalone ByeDPI autostart is enabled" msgstr "" @@ -4137,15 +1575,7 @@ msgstr "" msgid "Standalone Zapret2 service is inactive" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:285 -msgid "Start" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1555 -msgid "Start bot" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:78 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:80 msgid "Start Tachyon" msgstr "" @@ -4153,66 +1583,21 @@ msgstr "" msgid "Start Watchdog first" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:334 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1602 -msgid "Starting…" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:449 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:633 msgid "Status" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:292 -msgid "Stop" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1562 -msgid "Stop bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2676 -msgid "Stop checking when URLTest group is not used. Use sing-box duration format like 1d, 12h or 30m." -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:68 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:70 msgid "Stop Tachyon" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:307 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1579 #: src/tachyon/methods/custom/getDashboardSections.ts:1571 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:585 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147 msgid "Stopped" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:348 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1616 -msgid "Stopping…" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1421 -msgid "Store auto-detected domains in /etc instead of /tmp to survive reboots." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1214 -msgid "Strict ECH + DoQ DNS Enforcer" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9528 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9547 -msgid "STUN (P2P Calls)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4077 -msgid "Subnets from the list will be extracted and added to nftables" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2367 -msgid "Subscription auto update" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderSections.ts:146 msgid "Subscription info:" msgstr "" @@ -4222,34 +1607,10 @@ msgstr "" msgid "Subscription update failed" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2376 -msgid "Subscription update interval" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8770 -msgid "Subscription URL" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3764 -msgid "Subscription URL settings" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:335 msgid "Subscriptions updated" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8144 -msgid "Success" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7688 -msgid "Successfully imported %d DNS record(s)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9244 -msgid "Sweden (se)" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1653 msgid "System info" msgstr "" @@ -4266,22 +1627,6 @@ msgstr "" msgid "Tachyon Error" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6504 -msgid "Tachyon manages ciadpi pid files itself, so pidfile options are not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6501 -msgid "Tachyon manages the ciadpi process lifecycle itself, so daemon mode is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5648 -msgid "Tachyon manages the nfqws process lifecycle itself, so daemon mode is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6099 -msgid "Tachyon manages the nfqws2 process lifecycle itself, so daemon mode is not allowed here." -msgstr "" - #: src/tachyon/tabs/monitoring/initController.ts:977 msgid "Tachyon service is stopped. Start the service to display connections." msgstr "" @@ -4290,14 +1635,6 @@ msgstr "" msgid "Tachyon service is stopped. Start the service to display the dashboard." msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:366 -msgid "Tachyon Settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1126 -msgid "Tachyon will not modify your DHCP configuration" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:91 msgid "Tachyon-managed ciadpi runtime has restarted" msgstr "" @@ -4338,32 +1675,12 @@ msgstr "" msgid "Tachyon-managed nfqws2 runtime is ready" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3080 -msgid "Tailscale auth key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3089 -msgid "Tailscale control URL" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:98 msgid "Tailscale endpoint" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3097 -msgid "Tailscale hostname" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:65 -msgid "TCP (ms)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:473 -msgid "Telegram Bot" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1674 -msgid "Telegram Bot Token" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:371 +msgid "TCP" msgstr "" #: src/tachyon/tabs/dashboard/partials/renderSections.ts:241 @@ -4372,46 +1689,12 @@ msgstr "" msgid "Test latency" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2775 -msgid "Test only selected servers." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2735 -msgid "Test only servers with one of the selected protocols." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2741 -msgid "Test only servers with one of the selected security types." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2738 -msgid "Test only servers with one of the selected transports." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2767 -msgid "Test servers only from the specified countries." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2783 -msgid "Test servers whose names match the expression." -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1107 msgid "Testing URL" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5645 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6090 -msgid "The desync fwmark is managed by Tachyon for loop prevention and must not be overridden here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5642 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6087 -msgid "The NFQUEUE number is assigned by Tachyon for each rule and must not be overridden here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9272 -msgid "The rule applies to the domain and all its subdomains. Use full:, keyword:, or regex: prefixes for exact match, keyword match, or regular expression." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:685 +msgid "Testing..." msgstr "" #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:78 @@ -4426,43 +1709,8 @@ msgstr "" msgid "There are rules using Zapret2" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10265 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1828 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1833 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1923 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2085 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2885 -msgid "This field is required" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6507 -msgid "This field must start a working ciadpi strategy; help/version options exit immediately and are not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5651 -msgid "This field must start a working nfqws strategy; --dry-run exits immediately and is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5654 -msgid "This field must start a working nfqws strategy; --version exits immediately and is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6102 -msgid "This field must start a working nfqws2 strategy; --dry-run exits immediately and is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6105 -msgid "This field must start a working nfqws2 strategy; --version exits immediately and is not allowed here." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5823 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6297 -msgid "This flag does not accept a value." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5854 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6328 -msgid "This option requires a value." +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:91 +msgid "Thinking..." msgstr "" #: src/tachyon/tabs/monitoring/initController.ts:874 @@ -4470,58 +1718,20 @@ msgstr "" msgid "Time" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:659 -msgid "Time in seconds for DNS record caching (default: 60)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:3054 -msgid "Time skew tolerance" -msgstr "" - #: src/tachyon/helpers/singBoxVariant.ts:64 msgid "tiny" msgstr "" -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:66 -msgid "TLS (ms)" +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:379 +msgid "TLS" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9531 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9550 -msgid "TLS / HTTPS" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8733 -msgid "TLS Auth/Crypt Key" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8494 -msgid "TLS SNI" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1683 -msgid "Token is required when the bot is enabled" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2648 #: src/tachyon/tabs/dashboard/initController.ts:1109 msgid "Tolerance" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3194 -msgid "Top level has the highest priority; lower levels are used as fallback" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7627 -msgid "Total lines:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10012 -msgid "Trace" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10049 -msgid "Tracing routing rules..." +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:225 +msgid "Total Targets" msgstr "" #: src/tachyon/tabs/dashboard/initController.ts:1627 @@ -4529,131 +1739,23 @@ msgstr "" msgid "Traffic" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2905 -msgid "Traffic for this level goes directly." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9498 -msgid "Traffic from these IP addresses will never be routed through this section, even if other conditions match." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9524 -msgid "Traffic of specified protocols (e.g. BitTorrent, QUIC, STUN) will bypass this section." -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1640 msgid "Traffic Total" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9542 -msgid "Traffic type filter" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10114 -msgid "Traffic will go through the default route (Direct/Default)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6498 -msgid "Transparent proxy mode is incompatible with action=byedpi because Tachyon connects to ciadpi through SOCKS." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2036 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8557 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2763 -msgid "Transport" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2787 -msgid "Transport host" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2771 -msgid "Transport path" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2006 -msgid "Transport path must start with /" -msgstr "" - #: src/tachyon/tabs/diagnostic/partials/renderWikiDisclaimer.ts:25 msgid "Troubleshooting" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2425 -msgid "Try compatible User-Agent profiles automatically when downloading this subscription" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:670 -msgid "TTL must be a positive number" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:665 -msgid "TTL value cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9245 -msgid "Turkey (tr)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1637 #: src/tachyon/tabs/monitoring/initController.ts:868 #: src/tachyon/tabs/monitoring/initController.ts:928 msgid "Type" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:522 -msgid "UDP (Unprotected DNS)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9251 -msgid "Ukraine (ua)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6422 -msgid "Unable to validate the ByeDPI strategy through the backend parser." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5565 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6900 -msgid "Unable to validate the NFQWS strategy through the backend parser." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6010 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6909 -msgid "Unable to validate the NFQWS2 strategy through the backend parser." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3111 #: src/tachyon/tabs/dashboard/initController.ts:1233 msgid "Unavailability timeout" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8405 -msgid "Underload Packet Magic Header (H1)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8406 -msgid "Underload Packet Magic Header (H2)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8407 -msgid "Underload Packet Magic Header (H3)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8408 -msgid "Underload Packet Magic Header (H4)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6639 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6688 -msgid "Unexpected ByeDPI strategy argument: %s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5803 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6277 -msgid "Unexpected standalone token. Use explicit flags such as --name or --name=value." -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runByedpiCheck.ts:96 msgid "Unexpected Tachyon-managed ciadpi runtime is running" msgstr "" @@ -4666,18 +1768,6 @@ msgstr "" msgid "Unexpected Tachyon-managed nfqws2 runtime is running" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/tachyon.js:54 -msgid "unique UCI identifier" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9241 -msgid "United Kingdom (gb)" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9238 -msgid "United States (us)" -msgstr "" - #: src/tachyon/helpers/singBoxVariant.ts:37 #: src/tachyon/services/systemInfo.service.ts:10 #: src/tachyon/services/systemInfo.service.ts:12 @@ -4693,38 +1783,18 @@ msgstr "" msgid "unknown" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:328 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1596 #: src/tachyon/methods/custom/getDashboardSections.ts:1573 msgid "Unknown" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6608 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6630 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6681 -msgid "Unknown ByeDPI option: %s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:616 -msgid "Unknown country" -msgstr "" - #: src/tachyon/api.ts:40 -#: src/tachyon/tabs/diagnostic/initController.ts:720 -#: src/tachyon/tabs/diagnostic/initController.ts:757 -#: src/tachyon/tabs/diagnostic/initController.ts:878 -#: src/tachyon/tabs/diagnostic/initController.ts:1216 +#: src/tachyon/tabs/diagnostic/initController.ts:721 +#: src/tachyon/tabs/diagnostic/initController.ts:758 +#: src/tachyon/tabs/diagnostic/initController.ts:843 +#: src/tachyon/tabs/diagnostic/initController.ts:1159 msgid "Unknown error" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5814 -msgid "Unknown NFQWS flag." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6288 -msgid "Unknown NFQWS2 flag." -msgstr "" - #: src/validators/validateSubnet.ts:17 msgid "Unspecified IP address is not allowed" msgstr "" @@ -4733,10 +1803,6 @@ msgstr "" msgid "Unstable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2119 -msgid "Unsupported security mode for this protocol" -msgstr "" - #: src/tachyon/tabs/updates/initController.ts:809 msgid "Update" msgstr "" @@ -4759,18 +1825,6 @@ msgstr "" msgid "Update subscriptions" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2368 -msgid "Update this subscription automatically" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7632 -msgid "Updated/duplicates:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:506 -msgid "Updates & Downloads" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1629 #: src/tachyon/tabs/dashboard/initController.ts:1642 msgid "Uplink" @@ -4789,26 +1843,6 @@ msgstr "" msgid "URL must use one of the following protocols:" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1361 -msgid "URL to test through the proxy (default: Cloudflare 204)." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3087 -msgid "URL used to check whether a server is alive" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2663 -msgid "URL used to test server latency" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7839 -msgid "URLs of remote hosts files to download and apply. Supports standard hosts format: IP domain." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8886 -msgid "URLTest" -msgstr "" - #: src/tachyon/tabs/dashboard/initController.ts:1131 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:495 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:496 @@ -4819,109 +1853,10 @@ msgstr "" msgid "URLTest details are unavailable" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3803 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3804 -msgid "URLTest settings" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1400 -msgid "Use 3-tier check intervals: fast (15s), normal (120s), slow (300s) instead of a single interval." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2103 -msgid "Use 32 hex characters" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1893 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1899 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2015 -msgid "Use a domain name or IP address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1994 -msgid "Use a duration like 30s, 5m, or 1h30m" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2000 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2887 -msgid "Use a non-negative integer" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2106 -msgid "Use a non-zero secret" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1962 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1964 -msgid "Use an HTTP or HTTPS URL" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1916 -msgid "Use an IP address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1909 -msgid "Use an IP listen address" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8985 -msgid "Use another section as an intermediate hop to connect to servers in this section. Does not apply to network interfaces or JSON outbounds." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2063 -msgid "Use CIDR prefixes like 192.168.1.0/24 or 2001:db8::/32" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2077 -msgid "Use CIDR prefixes or IP addresses like 192.168.1.0/24, 192.168.1.10, or 2001:db8::1" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2021 -msgid "Use letters, digits, dots, underscores, or hyphens" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:252 -msgid "Use sing-box duration format like 10s, 1m or 2m30s" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2377 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2637 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3160 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4722 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4729 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4736 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:969 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:991 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:998 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1029 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1057 -msgid "Use sing-box duration format like 1d, 12h or 30m" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7986 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7997 -msgid "Use sing-box duration format like 1d, 12h or 6h" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:25 msgid "Used by" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:2435 -msgid "User-Agent" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8565 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2846 -msgid "Username" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9142 -msgid "Username cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5338 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5351 #: src/validators/validateDns.ts:25 #: src/validators/validateDns.ts:29 #: src/validators/validateDomain.ts:57 @@ -4941,48 +1876,15 @@ msgstr "" msgid "Valid" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1407 -msgid "Validates sing-box config before restart to prevent boot loops on broken configs." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:4791 -msgid "Validation errors:" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5328 -msgid "Value cannot be empty" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10268 -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1837 -msgid "Value must not contain control characters" -msgstr "" - -#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:68 +#: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:395 msgid "Verdict" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:1977 -msgid "Via country.is" -msgstr "" - -#: src/tachyon/tabs/diagnostic/initController.ts:1252 -#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:145 +#: src/tachyon/tabs/diagnostic/initController.ts:817 +#: src/tachyon/tabs/diagnostic/partials/renderAvailableActions.ts:157 msgid "View logs" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7254 -msgid "Visible name of this section" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2890 -msgid "VLESS flow" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8746 -msgid "vless://, vmess://, ss://, trojan://, socks4/5://, hy2/hysteria2:// links" -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:70 msgid "WAN" msgstr "" @@ -4991,70 +1893,18 @@ msgstr "" msgid "WAN public IP" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8445 -msgid "WARP Access Token" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8433 -msgid "WARP Account ID" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8144 -msgid "WARP Configuration generated and loaded successfully!" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8421 -msgid "WARP Private Key" -msgstr "" - #: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:446 msgid "Watchdog" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1331 -msgid "Watchdog Status" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1204 -msgid "WebRTC Leak Protection" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7267 -msgid "What Tachyon should do when this section matches" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3138 -msgid "When switching to another level, test every server and select the fastest instead of the first working one." -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8617 -msgid "WireGuard private key from your Cloudflare account" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:8422 -msgid "WireGuard private key from your Cloudflare WARP account" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:2800 -msgid "XHTTP mode" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:895 -msgid "YACD Secret Key" +#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:156 +msgid "Why Discord fails?" msgstr "" #: src/tachyon/tabs/dashboard/initController.ts:812 msgid "Yes" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:759 -msgid "You can select Output Network Interface, by default autodetect" -msgstr "" - -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5639 -msgid "Zapret hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS strategies." -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runZapretCheck.ts:71 msgid "Zapret package is installed" msgstr "" @@ -5079,10 +1929,6 @@ msgstr "" msgid "Zapret sing-box outbound is not configured" msgstr "" -#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6084 -msgid "Zapret2 hostlist templates are not supported here because Tachyon does not expand them for per-rule NFQWS2 strategies." -msgstr "" - #: src/tachyon/tabs/diagnostic/checks/runZapret2Check.ts:74 msgid "Zapret2 package is installed" msgstr "" diff --git a/tachyon/files/usr/bin/tachyon b/tachyon/files/usr/bin/tachyon index 14b8ec7b..78224fd9 100755 --- a/tachyon/files/usr/bin/tachyon +++ b/tachyon/files/usr/bin/tachyon @@ -159,7 +159,7 @@ function command_spec(command) { restart: [ "service/lifecycle.uc", "restart", 0 ], enable: [ "service/lifecycle.uc", "enable", 0 ], disable: [ "service/lifecycle.uc", "disable", 0 ], - uninstall: [ "service/lifecycle.uc", "uninstall", 0 ], + uninstall: [ "service/uninstall.uc", "uninstall", 1 ], dnsmasq_restore: [ "service/lifecycle.uc", "dnsmasq-restore", 0 ], restore_dnsmasq: [ "service/lifecycle.uc", "dnsmasq-restore", 0 ], main: [ "service/lifecycle.uc", "main", 0 ], @@ -217,6 +217,7 @@ function command_spec(command) { extract_ruleset: [ "diagnostics/runtime.uc", "extract-ruleset", 1 ], check_dns_available: [ "diagnostics/runtime.uc", "check-dns-available", 0 ], global_check: [ "diagnostics/runtime.uc", "global-check", 2 ], + service_health_check: [ "diagnostics/runtime.uc", "service-health-check", 2 ], doctor: [ "diagnostics/runtime.uc", "doctor", 1 ], ai_doctor: [ "diagnostics/runtime.uc", "ai-doctor", 0 ], ai_doctor_last: [ "diagnostics/runtime.uc", "ai-doctor-last", 0 ], diff --git a/tachyon/files/usr/lib/diagnostics/runtime.uc b/tachyon/files/usr/lib/diagnostics/runtime.uc index 48de3e5f..1711cb08 100644 --- a/tachyon/files/usr/lib/diagnostics/runtime.uc +++ b/tachyon/files/usr/lib/diagnostics/runtime.uc @@ -3599,6 +3599,13 @@ else if (mode == "ai-doctor-last") exit(ai_doctor_last()); else if (mode == "apply-quick-fix") exit(apply_quick_fix(ARGV[1] || "")); +else if (mode == "service-health-check") { + let args = []; + for (let i = 1; i < length(ARGV); i++) { + push(args, ARGV[i]); + } + exit(module_passthrough(LIB_DIR + "/diagnostics/service_check.uc", args)); +} else if (mode == "validate-nfqws-strategy-json") exit(validate_nfqws_strategy_json(ARGV[1] || "")); else if (mode == "validate-nfqws2-strategy-json") diff --git a/tachyon/files/usr/lib/diagnostics/service_check.uc b/tachyon/files/usr/lib/diagnostics/service_check.uc index bf9aabd4..4f8993d5 100644 --- a/tachyon/files/usr/lib/diagnostics/service_check.uc +++ b/tachyon/files/usr/lib/diagnostics/service_check.uc @@ -1,156 +1,2056 @@ #!/usr/bin/env ucode +// Forkop Service Check - probe engine for Forkop and Podkop. +// +// Проверяет доступность сервисов так, как это делает клиент сети: имя резолвится +// через тот же dnsmasq -> sing-box, а соединение уходит из роутера и попадает в +// цепочку mangle_output -> tproxy, то есть тем же путём, что трафик из LAN. +// В режиме netns трафик реально входит через br-lan из отдельного namespace, +// что дополнительно воспроизводит правила секций, привязанные к source IP. + let fs = require("fs"); -let uci = require("uci"); -let TARGET_DOMAINS = { - youtube: "www.youtube.com", - discord: "discord.com", - telegram: "web.telegram.org", - instagram: "www.instagram.com", - twitter: "twitter.com", - facebook: "www.facebook.com", - rutracker: "rutracker.org", - tiktok: "www.tiktok.com", - google_ai: "gemini.google.com", - openai: "chatgpt.com", - github: "github.com", - netflix: "www.netflix.com", - russia_inside: "www.instagram.com" -}; +const LIB_DIR = getenv("FORKOP_SC_LIB") || "/usr/lib/forkop-servicecheck"; +const ENGINE = LIB_DIR + "/probe.uc"; +const PROFILES_OVERRIDE = "/etc/tachyon/servicecheck_profiles.json"; +const PROFILES_DEFAULT = "/usr/share/tachyon/servicecheck_profiles.json"; +const STATE_DIR = "/var/run/tachyon-servicecheck"; +const FORKOP_BIN = "/usr/bin/tachyon"; +const PODKOP_BIN = "/usr/bin/podkop"; +const DEFAULT_SING_BOX_CONFIG = "/etc/sing-box/config.json"; +const NETNS_NAME = "fkpsc"; +const NETNS_VETH_HOST = "fkpsc0"; +const NETNS_VETH_PEER = "fkpsc1"; +const XHTTP_PATCH = ""; +const ICMP_TPROXY_PATCH = ""; +const CONFIG_DIR = "/etc/tachyon/servicecheck"; +const GEMINI_API_KEY_FILE = CONFIG_DIR + "/gemini_api_key"; -function perform_curl_check(domain) { - let url = "https://" + domain; - let cmd = sprintf("curl -k -s -o /dev/null -w '%%{time_namelookup}|%%{time_connect}|%%{time_appconnect}|%%{time_starttransfer}|%%{time_total}|%%{http_code}|%%{remote_ip}' --connect-timeout 5 --max-time 10 %s", url); - let f = fs.popen(cmd, "r"); - if (!f) return null; - let result_str = f.read("all"); - let exit_code = f.close(); - - // exit_code is shifted by 8 in popen close - exit_code = exit_code / 256; - - let parts = split(result_str, "|"); - if (length(parts) < 7) { - return { success: false, error: "curl_failed", exit_code: exit_code }; +const USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"; +const DNS_TIMEOUT = 3; +const CONNECT_TIMEOUT = 7; +const TOTAL_TIMEOUT = 15; +const SLOW_THRESHOLD_MS = 5000; +const JOB_MAX_AGE = 1800; + +function as_string(value) { + return value == null ? "" : "" + value; +} + +function object_or_empty(value) { + return type(value) == "object" ? value : {}; +} + +function array_or_empty(value) { + return type(value) == "array" ? value : []; +} + +function shell_quote(value) { + return "'" + replace(as_string(value), /'/g, "'\\''") + "'"; +} + +function command_from_args(args) { + let parts = []; + for (let arg in args) + push(parts, shell_quote(arg)); + return join(" ", parts); +} + +function normalize_status(status) { + status = int(status); + if (status < 0) + return 1; + return status > 255 ? int(status / 256) : status; +} + +function now_ms() { + let value = null; + try { + value = clock(true); } - - let time_namelookup = int(1000 * +(parts[0])); - let time_connect = int(1000 * +(parts[1])); - let time_appconnect = int(1000 * +(parts[2])); - let time_starttransfer = int(1000 * +(parts[3])); - let time_total = int(1000 * +(parts[4])); - let http_code = int(parts[5]); - let remote_ip = parts[6]; - - let tcp_ms = time_connect > 0 ? time_connect - time_namelookup : 0; - let tls_ms = time_appconnect > 0 ? time_appconnect - time_connect : 0; - let http_ms = time_starttransfer > 0 ? time_starttransfer - time_appconnect : 0; - - let status_class = "OK"; - - if (exit_code == 6) status_class = "DNS Error"; - else if (exit_code == 7 || exit_code == 28) status_class = "TCP Timeout/Refused"; - else if (exit_code == 35 || (exit_code == 0 && time_appconnect == 0 && time_connect > 0)) status_class = "TLS Reset"; - else if (exit_code != 0) status_class = "Error (" + exit_code + ")"; - else if (http_code == 403 || http_code == 451) status_class = "HTTP " + http_code; - else if (http_code >= 200 && http_code < 400) status_class = "OK"; - else status_class = "HTTP " + http_code; + catch (e) { + value = null; + } + if (type(value) != "array") + value = clock(); + if (type(value) != "array") + return 0; + return value[0] * 1000 + int(value[1] / 1000000); +} + +function now_seconds() { + let value = clock(); + return type(value) == "array" ? int(value[0]) : 0; +} + +function capture(command) { + let pipe = fs.popen(command, "r"); + if (!pipe) + return { status: 1, output: "" }; + let data = pipe.read("all"); + let status = normalize_status(pipe.close()); + return { status, output: data == null ? "" : as_string(data) }; +} + +function capture_args(args, merge_stderr) { + return capture(command_from_args(args) + (merge_stderr ? " 2>&1" : " 2>/dev/null")); +} + +function run_quiet(args) { + return normalize_status(system(command_from_args(args) + " >/dev/null 2>&1")) == 0; +} + +function command_exists(name) { + return run_quiet([ "command", "-v", as_string(name) ]); +} + +function write_json(value) { + print(sprintf("%J", value), "\n"); +} + +function xhttp_patch() { + if (fs.stat(XHTTP_PATCH) == null) { + write_json({ success: false, message: "xHTTP-патч не установлен в пакет" }); + return 1; + } + let result = capture_args([ "sh", XHTTP_PATCH ], true); + write_json({ success: result.status == 0, code: result.status, output: trim(as_string(result.output)) }); + return result.status; +} + +function icmp_tproxy_patch() { + if (fs.stat(ICMP_TPROXY_PATCH) == null) { + write_json({ success: false, message: "ICMP/TProxy-патч не установлен в пакет" }); + return 1; + } + let result = capture_args([ "sh", ICMP_TPROXY_PATCH ], true); + write_json({ success: result.status == 0, code: result.status, output: trim(as_string(result.output)) }); + return result.status; +} + +function available_fixes() { + // Эти исправления меняют внутренние файлы Forkop и не должны предлагаться + // на Podkop, даже если общий диагностический backend работает нормально. + if (fs.stat(FORKOP_BIN) == null) + return []; + + return [ + { + id: "xhttp_import", + title: "Фикс xHTTP импорта подписок", + description: "Исправляет импорт дополнительных полей xHTTP из подписок в parser.uc Forkop.", + risk: "Создаётся резервная копия parser.uc; патч проверяется через ucode до замены." + }, + { + id: "icmp_tproxy", + title: "Фикс ping/ICMP для правил подсетей", + description: "Ограничивает метку TProxy в priority_rules протоколами TCP и UDP, чтобы ICMP не уходил в локальный TProxy-сокет.", + risk: "Создаётся резервная копия nft/apply.uc; патч проверяется через ucode. Работающий Forkop перезапускается, live-правила проверяются, а при ошибке выполняется откат." + } + ]; +} + +function list_fixes() { + write_json({ success: true, fixes: available_fixes() }); + return 0; +} + +function run_fix(id) { + if (fs.stat(FORKOP_BIN) == null) { + write_json({ success: false, message: "фиксы доступны только при установленном Forkop" }); + return 1; + } + + if (as_string(id) == "xhttp_import") + return xhttp_patch(); + if (as_string(id) == "icmp_tproxy") + return icmp_tproxy_patch(); + write_json({ success: false, message: "неизвестный фикс Forkop" }); + return 1; +} + +function parse_json(value) { + try { + return json(as_string(value)); + } + catch (e) { + return null; + } +} + +function read_json_file(path) { + let data = fs.readfile(as_string(path)); + return data == null ? null : parse_json(data); +} + +function trim_newlines(value) { + return replace(as_string(value), /[\r\n]+$/g, ""); +} + +function words(value) { + value = trim(as_string(value)); + return value == "" ? [] : split(value, /[ \t\r\n]+/); +} + +// curl отдаёт тайминги как "0.123". Собирать число по частям нельзя: деление двух +// целых в ucode целочисленное, и дробная часть схлопывается в ноль. Умножение же +// приводит числовую строку к double, поэтому проверяем формат и умножаем. +function number_value(value) { + value = trim(as_string(value)); + if (match(value, /^[0-9]+(\.[0-9]+)?$/) == null) + return 0; + return value * 1; +} + +function temp_path(suffix) { + return sprintf("/tmp/.forkop-sc-%d-%d.%s", now_seconds(), int(now_ms() % 1000000), as_string(suffix)); +} + +function ensure_state_dir() { + run_quiet([ "mkdir", "-p", STATE_DIR ]); +} + +function profiles_file() { + let override = getenv("FORKOP_SC_PROFILES"); + if (as_string(override) != "") + return as_string(override); + if (fs.stat(PROFILES_OVERRIDE) != null) + return PROFILES_OVERRIDE; + return PROFILES_DEFAULT; +} + +// --------------------------------------------------------------------------- +// Сеть: разбор адресов +// --------------------------------------------------------------------------- + +function valid_ipv4(value) { + value = trim(as_string(value)); + let matched = match(value, /^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/); + if (matched == null) + return false; + for (let i = 1; i <= 4; i++) + if (int(matched[i]) > 255) + return false; + return true; +} + +function valid_domain(value) { + value = trim(as_string(value)); + if (length(value) < 1 || length(value) > 253 || index(value, "..") >= 0) + return false; + + for (let label in split(value, ".")) { + if (length(label) < 1 || length(label) > 63 || + match(label, /^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?$/) == null) + return false; + } + + return true; +} + +function valid_custom_host(value) { + value = trim(as_string(value)); + if (valid_ipv4(value)) + return true; + // Не принимаем ошибочный IPv4 вроде 999.1.1.1 за обычное доменное имя. + if (match(value, /^[0-9.]+$/) != null) + return false; + return valid_domain(value); +} + +function ipv4_to_int(value) { + let parts = split(trim(as_string(value)), "."); + if (length(parts) != 4) + return -1; + return int(parts[0]) * 16777216 + int(parts[1]) * 65536 + int(parts[2]) * 256 + int(parts[3]); +} + +function int_to_ipv4(value) { + value = int(value); + let a = int(value / 16777216) % 256; + let b = int(value / 65536) % 256; + let c = int(value / 256) % 256; + let d = value % 256; + return sprintf("%d.%d.%d.%d", a, b, c, d); +} + +function prefix_mask(prefix) { + prefix = int(prefix); + if (prefix <= 0) + return 0; + if (prefix >= 32) + return 4294967295; + return (4294967295 << (32 - prefix)) & 4294967295; +} + +function ipv4_in_cidr(ip, cidr) { + let parts = split(as_string(cidr), "/"); + if (length(parts) != 2 || !valid_ipv4(ip) || !valid_ipv4(parts[0])) + return false; + let mask = prefix_mask(parts[1]); + return (ipv4_to_int(ip) & mask) == (ipv4_to_int(parts[0]) & mask); +} + +function tachyon_get_targets() { + return read_json_file("/etc/tachyon/targets.json") || []; +} + +function tachyon_check_target(target) { + return true; +} + +function ipv4_in_any_cidr(ip, cidrs) { + for (let cidr in array_or_empty(cidrs)) + if (ipv4_in_cidr(ip, cidr)) + return true; + return false; +} + +// --------------------------------------------------------------------------- +// Окружение роутера +// --------------------------------------------------------------------------- + +function uci_get(path) { + let result = capture_args([ "uci", "-q", "get", as_string(path) ]); + return result.status == 0 ? trim_newlines(result.output) : ""; +} + +function backend_id() { + let override = lc(trim(as_string(getenv("FORKOP_SC_BACKEND")))); + if (override == "forkop" || override == "podkop") + return override; + if (fs.stat(FORKOP_BIN) != null) + return "forkop"; + if (fs.stat(PODKOP_BIN) != null) + return "podkop"; + return "none"; +} + +function backend_name(id) { + id = as_string(id); + if (id == "forkop") + return "Forkop"; + if (id == "podkop") + return "Podkop"; + return "Sing-box"; +} + +function sing_box_config_path() { + let overridden = trim(as_string(getenv("FORKOP_SC_SING_BOX_CONFIG"))); + if (overridden != "") + return overridden; + + if (backend_id() == "podkop") { + let configured = trim(uci_get("podkop.settings.config_path")); + if (configured != "") + return configured; + } + + return DEFAULT_SING_BOX_CONFIG; +} + +function lan_interface() { + let namespace = backend_id() == "podkop" ? "podkop" : "forkop"; + let configured = words(uci_get(namespace + ".settings.source_network_interfaces")); + if (length(configured) > 0) + return configured[0]; + return "br-lan"; +} + +function interface_ipv4(interface) { + let output = capture_args([ "ip", "-4", "-o", "addr", "show", "dev", as_string(interface) ], false).output; + for (let line in split(output, "\n")) { + let matched = match(trim(as_string(line)), /inet[ \t]+([0-9.]+)\/([0-9]+)/); + if (matched != null) + return { address: matched[1], prefix: int(matched[2]) }; + } + return null; +} + +function fakeip_ranges() { + let ranges = []; + let config = read_json_file(sing_box_config_path()); + let dns = object_or_empty(object_or_empty(config).dns); + + for (let server in array_or_empty(dns.servers)) { + server = object_or_empty(server); + if (as_string(server.type) == "fakeip") { + if (as_string(server.inet4_range) != "") + push(ranges, as_string(server.inet4_range)); + } + } + + let legacy = object_or_empty(dns.fakeip); + if (as_string(legacy.inet4_range) != "") + push(ranges, as_string(legacy.inet4_range)); + + if (length(ranges) == 0) + push(ranges, "198.18.0.0/15"); + + return ranges; +} + +function forkop_running() { + let backend = backend_id(); + let result; + + if (backend == "forkop") + result = capture_args([ FORKOP_BIN, "get_status" ], false); + else if (backend == "podkop") + result = capture_args([ PODKOP_BIN, "get_sing_box_status" ], false); + else + return false; + + if (result.status != 0) { + if (backend == "podkop") + return run_quiet([ "pgrep", "-f", "sing-box" ]); + return false; + } + let status = object_or_empty(parse_json(result.output)); + if (status.running === true || int(status.running) == 1) + return true; + if (backend == "podkop" && status.running == null) + return run_quiet([ "pgrep", "-f", "sing-box" ]); + return false; +} + +// Сборки busybox сильно разнятся: где-то nc умеет -z и -w, где-то это +// "Usage: nc [IPADDR PORT]" вообще без флагов. Пробуем от лучшего к худшему. +function nc_option_rejected(command) { + let output = lc(as_string(capture(command).output)); + return index(output, "invalid option") >= 0 || index(output, "unrecognized option") >= 0 || + index(output, "usage:") >= 0 || index(output, "bad port") >= 0; +} + +function detect_nc_mode() { + if (!command_exists("nc")) + return "none"; + if (!nc_option_rejected("nc -z -w 1 127.0.0.1 1 2>&1")) + return "zero"; + if (!nc_option_rejected("nc -w 1 127.0.0.1 1 2>&1")) + return "wait"; + return "plain"; +} + +function capabilities() { + let backend = backend_id(); + let running = forkop_running(); + let interface = lan_interface(); + let address = interface_ipv4(interface); + let nc_mode = detect_nc_mode(); return { - success: exit_code == 0 && (http_code >= 200 && http_code < 400), - status_class: status_class, - dns_ms: time_namelookup, - tcp_ms: tcp_ms, - tls_ms: tls_ms, - http_ms: http_ms, - total_ms: time_total, - http_code: http_code, - remote_ip: remote_ip, - exit_code: exit_code + curl: command_exists("curl"), + uclient_fetch: command_exists("uclient-fetch") || command_exists("wget"), + dig: command_exists("dig"), + nslookup: command_exists("nslookup"), + nc: nc_mode != "none", + nc_mode, + timeout_cmd: command_exists("timeout"), + netns: run_quiet([ "ip", "netns", "list" ]) && command_exists("ip"), + lan_interface: interface, + lan_address: address == null ? "" : address.address, + lan_prefix: address == null ? 0 : address.prefix, + fakeip_ranges: fakeip_ranges(), + backend, + backend_name: backend_name(backend), + backend_installed: backend != "none", + backend_running: running, + forkop_installed: fs.stat(FORKOP_BIN) != null, + podkop_installed: fs.stat(PODKOP_BIN) != null, + fixes_available: backend == "forkop" && fs.stat(FORKOP_BIN) != null, + sing_box_config: sing_box_config_path(), + // Старое поле оставлено для совместимости со страницей предыдущих версий. + forkop_running: running, + profiles_version: int(object_or_empty(read_json_file(profiles_file())).version || 0) }; } -function process_sections() { +// --------------------------------------------------------------------------- +// Профили +// --------------------------------------------------------------------------- + +function load_profiles() { + let data = object_or_empty(read_json_file(profiles_file())); + return array_or_empty(data.profiles); +} + +function validate_profiles_config(config) { + if (type(config) != "object" || type(config.profiles) != "array") + return "корневой объект должен содержать массив profiles"; + + let profiles = array_or_empty(config.profiles); + if (length(profiles) == 0) + return "список profiles не может быть пустым"; + if (length(profiles) > 100) + return "допускается не более 100 профилей"; + + let seen = {}; + let allowed_kinds = { https: true, http: true, tcp: true, udp: true, udp_dns: true }; + + for (let profile in profiles) { + profile = object_or_empty(profile); + let id = as_string(profile.id); + let title = trim(as_string(profile.title)); + let targets = array_or_empty(profile.targets); + + if (match(id, /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/) == null) + return "некорректный id профиля: " + id; + if (seen[id]) + return "id профиля повторяется: " + id; + seen[id] = true; + if (title == "") + return "у профиля " + id + " не задан title"; + if (length(targets) == 0 || length(targets) > 50) + return "у профиля " + id + " должно быть от 1 до 50 целей"; + + for (let target in targets) { + target = object_or_empty(target); + let kind = as_string(target.kind || "https"); + let host = trim(as_string(target.host)); + let port = int(target.port || (kind == "http" ? 80 : 443)); + + if (!allowed_kinds[kind]) + return "неподдерживаемый kind в профиле " + id + ": " + kind; + if (host == "" || match(host, /[ \t\r\n\/]/) != null) + return "некорректный host в профиле " + id; + if (port < 1 || port > 65535) + return "некорректный port в профиле " + id; + } + } + + return ""; +} + +function profiles_get() { + let path = profiles_file(); + let config = read_json_file(path); + if (type(config) != "object") { + write_json({ success: false, message: "не удалось прочитать список проверок" }); + return 1; + } + write_json({ success: true, source: path == PROFILES_OVERRIDE ? "custom" : "built-in", config }); + return 0; +} + +function profiles_save(payload) { + payload = as_string(payload); + if (length(payload) == 0 || length(payload) > 131072) { + write_json({ success: false, message: "размер списка должен быть от 1 байта до 128 КиБ" }); + return 1; + } + + let config = parse_json(payload); + let error = validate_profiles_config(config); + if (error != "") { + write_json({ success: false, message: error }); + return 1; + } + + if (!run_quiet([ "mkdir", "-p", "/etc/forkop-servicecheck" ])) { + write_json({ success: false, message: "не удалось создать /etc/forkop-servicecheck" }); + return 1; + } + + let temporary = PROFILES_OVERRIDE + ".tmp"; + if (fs.writefile(temporary, sprintf("%J", config) + "\n") == null || + !run_quiet([ "chmod", "0644", temporary ]) || + !run_quiet([ "mv", "-f", temporary, PROFILES_OVERRIDE ])) { + fs.unlink(temporary); + write_json({ success: false, message: "не удалось сохранить пользовательский список" }); + return 1; + } + + write_json({ success: true, message: "пользовательский список сохранён", profiles: length(config.profiles) }); + return 0; +} + +function profiles_reset() { + if (fs.stat(PROFILES_OVERRIDE) != null && fs.unlink(PROFILES_OVERRIDE) == null) { + write_json({ success: false, message: "не удалось удалить пользовательский список" }); + return 1; + } + write_json({ success: true, message: "восстановлен встроенный список" }); + return 0; +} + +function target_label(target) { + target = object_or_empty(target); + if (as_string(target.label) != "") + return as_string(target.label); + if (as_string(target.kind) == "tcp" || as_string(target.kind) == "udp" || as_string(target.kind) == "udp_dns") + return sprintf("%s:%d", as_string(target.host), int(target.port || 443)); + return as_string(target.host) + as_string(target.path || "/"); +} + +function target_url(target) { + target = object_or_empty(target); + let scheme = as_string(target.kind) == "http" ? "http" : "https"; + let port = int(target.port || 0); + let host = as_string(target.host); + let authority = port > 0 && port != 443 && port != 80 ? host + ":" + as_string(port) : host; + let path = as_string(target.path || "/"); + if (substr(path, 0, 1) != "/") + path = "/" + path; + return scheme + "://" + authority + path; +} + +// --------------------------------------------------------------------------- +// Пробы +// --------------------------------------------------------------------------- + +function prefixed_args(ctx, args) { + let full = []; + for (let arg in array_or_empty(ctx.exec_prefix)) + push(full, arg); + for (let arg in args) + push(full, arg); + return full; +} + +function probe_dns(ctx, host) { + if (valid_ipv4(host)) + return { ok: true, ip: host, fakeip: false, ms: 0, error: "", skipped: true }; + + let started = now_ms(); + let addresses = []; + + if (ctx.tools.dig) { + let result = capture_args(prefixed_args(ctx, [ + "dig", "@" + ctx.resolver, as_string(host), "A", "+short", + "+timeout=" + as_string(DNS_TIMEOUT), "+tries=1" + ]), false); + for (let line in split(result.output, "\n")) { + line = trim(as_string(line)); + if (valid_ipv4(line)) + push(addresses, line); + } + } + else if (ctx.tools.nslookup) { + let result = capture_args(prefixed_args(ctx, [ "nslookup", as_string(host), ctx.resolver ]), true); + // busybox печатает "Address 1: 1.2.3.4 host.example", хвост после адреса игнорируем. + for (let line in split(result.output, "\n")) { + let matched = match(trim(as_string(line)), /^Address[ \t0-9]*:[ \t]+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/); + if (matched != null && valid_ipv4(matched[1]) && matched[1] != ctx.resolver) + push(addresses, matched[1]); + } + } + + let elapsed = now_ms() - started; + + if (length(addresses) == 0) + return { ok: false, ip: "", fakeip: false, ms: elapsed, error: "нет A-записи" }; + + return { + ok: true, + ip: addresses[0], + all: addresses, + fakeip: ipv4_in_any_cidr(addresses[0], ctx.fakeip_ranges), + ms: elapsed, + error: "" + }; +} + +function curl_failure_verdict(status, output) { + output = lc(as_string(output)); + + if (status == 6) + return { verdict: "dns_fail", message: "имя не резолвится" }; + if (status == 7) + return { verdict: "tcp_refused", message: "не удалось установить TCP-соединение" }; + if (status == 28) + return { verdict: "timeout", message: "таймаут соединения" }; + // Три "ошибки TLS" у curl имеют совершенно разные причины, и валить их в одну + // строку - значит прятать диагноз. 35 - хендшейк оборвали (типовая подпись DPI), + // 51 - сертификат отклонён, 60 - сертификат не удалось проверить, а это почти + // всегда сбитые часы роутера (нет RTC) или отсутствующий ca-bundle. + if (status == 35) + return { verdict: "tls_handshake", message: "TLS-хендшейк оборван — похоже на DPI или несовместимый TLS" }; + if (status == 51) + return { verdict: "tls_cert_rejected", message: "сертификат сервера отклонён" }; + if (status == 60) + return { verdict: "tls_cert_untrusted", message: "сертификат не проверен — проверьте часы роутера и наличие ca-bundle" }; + if (status == 52) + return { verdict: "tls_reset", message: "сервер закрыл соединение без ответа" }; + if (status == 56) + return { verdict: "tls_reset", message: "соединение сброшено при передаче данных" }; + if (status == 47) + return { verdict: "redirect_loop", message: "сервис отвечает, но перенаправляет по кругу" }; + if (index(output, "connection reset") >= 0) + return { verdict: "tls_reset", message: "соединение сброшено" }; + + return { verdict: "failed", message: trim(as_string(output)) != "" ? trim(as_string(output)) : sprintf("curl завершился с кодом %d", status) }; +} + +function http_probe_curl(ctx, target) { + let url = target_url(target); + let format = "%{http_code}|%{time_namelookup}|%{time_connect}|%{time_appconnect}|%{time_starttransfer}|%{time_total}|%{remote_ip}"; + let args = prefixed_args(ctx, [ + "curl", "-sS", "-o", "/dev/null", "-L", "--max-redirs", "5", + "--connect-timeout", as_string(CONNECT_TIMEOUT), + "--max-time", as_string(TOTAL_TIMEOUT), + "-A", USER_AGENT, + "-w", format, + url + ]); + let error_file = temp_path("curl-err"); + let result = capture(command_from_args(args) + " 2>" + shell_quote(error_file)); + let stderr = as_string(fs.readfile(error_file) || ""); + fs.unlink(error_file); + + if (result.status != 0) { + let failure = curl_failure_verdict(result.status, stderr); + return { + reached: false, + code: 0, + remote_ip: "", + tcp_ms: 0, + tls_ms: 0, + total_ms: 0, + verdict: failure.verdict, + message: failure.message + }; + } + + let fields = split(trim(as_string(result.output)), "|"); + if (length(fields) < 7) + return { reached: false, code: 0, remote_ip: "", tcp_ms: 0, tls_ms: 0, total_ms: 0, verdict: "failed", message: "не удалось разобрать ответ curl" }; + + let namelookup = number_value(fields[1]) * 1000; + let connect = number_value(fields[2]) * 1000; + let appconnect = number_value(fields[3]) * 1000; + let total = number_value(fields[5]) * 1000; + + return { + reached: true, + code: int(fields[0]), + remote_ip: as_string(fields[6]), + dns_ms: int(namelookup), + tcp_ms: int(connect > namelookup ? connect - namelookup : connect), + tls_ms: int(appconnect > connect ? appconnect - connect : 0), + total_ms: int(total), + verdict: "", + message: "" + }; +} + +function uclient_failure_verdict(output) { + output = lc(as_string(output)); + + if (index(output, "download completed") >= 0) + return null; + if (index(output, "failed to resolve") >= 0 || index(output, "name or service not known") >= 0) + return { verdict: "dns_fail", message: "имя не резолвится" }; + if (index(output, "connection refused") >= 0) + return { verdict: "tcp_refused", message: "соединение отклонено" }; + if (index(output, "timed out") >= 0 || index(output, "timeout") >= 0) + return { verdict: "timeout", message: "таймаут соединения" }; + if (index(output, "connection reset") >= 0) + return { verdict: "tls_reset", message: "соединение сброшено" }; + if (index(output, "ssl") >= 0 || index(output, "tls") >= 0) + return { verdict: "tls_error", message: "ошибка TLS" }; + if (index(output, "failed to establish connection") >= 0) + return { verdict: "timeout", message: "не удалось установить соединение" }; + + return { verdict: "failed", message: trim(as_string(output)) }; +} + +function http_probe_uclient(ctx, target) { + let url = target_url(target); + let binary = command_exists("uclient-fetch") ? "uclient-fetch" : "wget"; + let started = now_ms(); + // Без -q: именно в stderr uclient-fetch и busybox wget пишут причину отказа, + // а -T понимают обе реализации, в отличие от --timeout=. + let result = capture_args(prefixed_args(ctx, [ + binary, "-T", as_string(CONNECT_TIMEOUT), "-O", "/dev/null", url + ]), true); + let elapsed = now_ms() - started; + let output = as_string(result.output); + + let code_match = match(output, /HTTP error ([0-9]{3})/); + if (code_match != null) + return { + reached: true, + code: int(code_match[1]), + remote_ip: "", + tcp_ms: 0, + tls_ms: 0, + total_ms: elapsed, + verdict: "", + message: "" + }; + + if (result.status == 0) + return { + reached: true, + code: 200, + remote_ip: "", + tcp_ms: 0, + tls_ms: 0, + total_ms: elapsed, + verdict: "", + message: "код ответа определён приблизительно (нет curl)" + }; + + let failure = uclient_failure_verdict(output); + if (failure == null) + return { reached: true, code: 200, remote_ip: "", tcp_ms: 0, tls_ms: 0, total_ms: elapsed, verdict: "", message: "" }; + + return { + reached: false, + code: 0, + remote_ip: "", + tcp_ms: 0, + tls_ms: 0, + total_ms: elapsed, + verdict: failure.verdict, + message: failure.message + }; +} + +// Проверка чистого TCP через curl. Протокол на порту нам безразличен: важно лишь, +// дошло ли дело до установленного соединения. curl это и говорит кодом выхода - +// 7 и 28 означают, что соединиться не удалось, а ошибки TLS уровнем выше (35, 52, +// 56) означают, что TCP как раз поднялся. Так обходимся без nc, флаги которого +// в busybox-сборках непредсказуемы. +function tcp_probe_curl(ctx, target) { + let host = as_string(target.host); + let port = int(target.port || 443); + let url = "https://" + host + ":" + as_string(port) + "/"; + let args = prefixed_args(ctx, [ + "curl", "-sS", "-o", "/dev/null", + "--connect-timeout", as_string(CONNECT_TIMEOUT), + "--max-time", as_string(CONNECT_TIMEOUT + 2), + "-w", "%{time_connect}|%{remote_ip}", + url + ]); + let started = now_ms(); + let result = capture(command_from_args(args) + " 2>/dev/null"); + let elapsed = now_ms() - started; + let status = result.status; + + let fields = split(trim(as_string(result.output)), "|"); + let connect_ms = length(fields) > 0 ? int(number_value(fields[0]) * 1000) : 0; + let remote_ip = length(fields) > 1 ? as_string(fields[1]) : ""; + + if (status == 6) + return { reached: false, code: 0, remote_ip: "", tcp_ms: 0, tls_ms: 0, total_ms: elapsed, verdict: "dns_fail", message: "имя не резолвится" }; + + if (status == 7) + return { reached: false, code: 0, remote_ip: "", tcp_ms: 0, tls_ms: 0, total_ms: elapsed, verdict: "tcp_refused", message: "не удалось установить TCP-соединение" }; + + // curl can time out after the TCP handshake while it waits for an HTTPS + // response. Raw TCP services can accept connections on port 443 without + // speaking TLS/HTTP. In that case time_connect/remote_ip + // prove that the TCP target is reachable, which is all this probe tests. + if (status == 28 && connect_ms <= 0 && remote_ip == "") + return { reached: false, code: 0, remote_ip: "", tcp_ms: 0, tls_ms: 0, total_ms: elapsed, verdict: "timeout", message: "таймаут TCP-соединения" }; + + let measured = connect_ms > 0 ? connect_ms : elapsed; + return { reached: true, code: 0, remote_ip, tcp_ms: measured, tls_ms: 0, total_ms: measured, verdict: "", message: "" }; +} + +function tcp_probe_nc(ctx, target) { + let host = as_string(target.host); + let port = as_string(int(target.port || 443)); + let mode = as_string(ctx.tools.nc_mode); + let args = []; + + if (mode == "zero") + args = [ "nc", "-z", "-w", as_string(CONNECT_TIMEOUT), host, port ]; + else if (mode == "wait") + args = [ "nc", "-w", as_string(CONNECT_TIMEOUT), host, port ]; + else if (ctx.tools.timeout_cmd) + args = [ "timeout", as_string(CONNECT_TIMEOUT), "nc", host, port ]; + else + return { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "skipped", message: "nc без поддержки таймаута, а curl не установлен" }; + + let started = now_ms(); + let status = normalize_status(system(command_from_args(prefixed_args(ctx, args)) + " /dev/null 2>&1")); + let elapsed = now_ms() - started; + + if (status == 0) + return { reached: true, code: 0, remote_ip: "", tcp_ms: elapsed, tls_ms: 0, total_ms: elapsed, verdict: "", message: "" }; + + let timed_out = elapsed >= CONNECT_TIMEOUT * 1000 - 500; + return { + reached: false, + code: 0, + remote_ip: "", + tcp_ms: 0, + tls_ms: 0, + total_ms: elapsed, + verdict: timed_out ? "timeout" : "tcp_refused", + message: timed_out ? "таймаут TCP-соединения" : "TCP-соединение отклонено" + }; +} + +function tcp_probe(ctx, target) { + if (ctx.tools.curl) + return tcp_probe_curl(ctx, target); + return tcp_probe_nc(ctx, target); +} + +// Google возвращает отдельный FAILED_PRECONDITION для регионов, в которых +// Gemini API недоступен. Обычная HTTPS-проверка этого не отличает от рабочего +// API с ошибкой авторизации, поэтому для профиля Gemini разбираем JSON-ответ. +function read_gemini_api_key() { + return trim(as_string(fs.readfile(GEMINI_API_KEY_FILE) || "")); +} + +function probe_gemini_geo(ctx, target) { + let api_key = read_gemini_api_key(); + if (api_key == "") + return { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "skipped", message: "укажите API-ключ Gemini в настройках карточки" }; + + let url = "https://" + as_string(target.host) + as_string(target.path); + let body_file = temp_path("gemini-body"); + let error_file = temp_path("gemini-err"); + let config_file = temp_path("gemini-curl"); + + // Ключ не передаётся в argv curl и не виден в списке процессов. Временный + // config доступен только root и удаляется сразу после завершения запроса. + if (fs.writefile(config_file, "header = \"x-goog-api-key: " + api_key + "\"\n") == null) + return { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "gemini_geo_error", message: "не удалось подготовить запрос Gemini API" }; + run_quiet([ "chmod", "600", config_file ]); + + let started = now_ms(); + let format = "%{http_code}|%{remote_ip}|%{time_total}"; + let args = prefixed_args(ctx, [ + "curl", "--config", config_file, "-sS", + "-o", body_file, + "--connect-timeout", as_string(CONNECT_TIMEOUT), + "--max-time", as_string(TOTAL_TIMEOUT), + "-A", USER_AGENT, + "-w", format, + url + ]); + let result = capture(command_from_args(args) + " 2>" + shell_quote(error_file)); + let stderr = as_string(fs.readfile(error_file) || ""); + let body_raw = as_string(fs.readfile(body_file) || ""); + fs.unlink(config_file); + fs.unlink(error_file); + fs.unlink(body_file); + + let elapsed = now_ms() - started; + if (result.status != 0) { + let failure = curl_failure_verdict(result.status, stderr); + return { + reached: false, + code: 0, + remote_ip: "", + tcp_ms: 0, + tls_ms: 0, + total_ms: int(elapsed), + verdict: failure.verdict, + message: failure.message + }; + } + + let fields = split(trim(as_string(result.output)), "|"); + let http_code = int(fields[0]); + let remote_ip = as_string(fields[1]); + let total_ms = int(number_value(fields[2]) * 1000); + let body = parse_json(body_raw); + body = type(body) == "object" ? body : {}; + let error_obj = object_or_empty(body.error); + let error_status = as_string(error_obj.status); + let error_message = as_string(error_obj.message); + let error_lc = lc(error_message); + let verdict = "gemini_geo_error"; + let message = ""; + + if (http_code == 200) { + verdict = "gemini_geo_ok"; + message = "Gemini API доступен в этом регионе"; + } + else if (error_status == "FAILED_PRECONDITION" || index(error_lc, "user location is not supported") >= 0) { + verdict = "gemini_geo_blocked"; + message = "регион VPN-сервера недоступен для Gemini — смените сервер на другой регион"; + } + else if (error_status == "INVALID_ARGUMENT" || index(error_lc, "api key not valid") >= 0) { + verdict = "gemini_api_key_invalid"; + message = "API-ключ Gemini невалиден — обновите его в настройках карточки"; + } + else if (http_code == 401 || http_code == 403) { + if (index(error_lc, "location") >= 0 || index(error_lc, "supported") >= 0) { + verdict = "gemini_geo_blocked"; + message = "регион недоступен для Gemini API — смените VPN-сервер"; + } + else { + verdict = "gemini_api_key_invalid"; + message = error_message != "" ? error_message : "Google отклонил API-ключ Gemini"; + } + } + else { + message = error_message != "" + ? sprintf("неожиданный ответ Gemini API: HTTP %d — %s", http_code, error_message) + : sprintf("неожиданный ответ Gemini API: HTTP %d", http_code); + } + + return { + reached: true, + code: http_code, + remote_ip, + tcp_ms: 0, + tls_ms: 0, + total_ms: total_ms > 0 ? total_ms : int(elapsed), + verdict, + message + }; +} + +function udp_probe(ctx, target) { + if (!ctx.tools.nc) + return { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "skipped", message: "нет nc для UDP-проверки" }; + + let started = now_ms(); + let args = [ "nc", "-u" ]; + if (ctx.tools.nc_mode == "zero") + push(args, "-z"); + if (ctx.tools.nc_mode != "plain") + push(args, "-w", "2"); + push(args, as_string(target.host), as_string(int(target.port || 0))); + let status = normalize_status(system(command_from_args(prefixed_args(ctx, args)) + " /dev/null 2>&1")); + let elapsed = now_ms() - started; + + // UDP не подтверждает доставку без ответа приложения. Это best-effort: + // успешная отправка означает, что маршрут и локальный сокет доступны. + if (status == 0) + return { reached: true, code: 0, remote_ip: "", tcp_ms: elapsed, tls_ms: 0, total_ms: elapsed, verdict: "udp_unconfirmed", message: "UDP-пакет отправлен, но протокол не подтвердил доставку" }; + return { reached: true, code: 0, remote_ip: "", tcp_ms: elapsed, tls_ms: 0, total_ms: elapsed, verdict: "udp_unconfirmed", message: "UDP-ответ не получен; это не доказывает блокировку трафика" }; +} + +function udp_dns_probe(ctx, target) { + if (!ctx.tools.nslookup) + return { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "skipped", message: "нет nslookup для двусторонней UDP-проверки" }; + + let query = as_string(target.query || "example.com"); + let started = now_ms(); + let result = capture_args(prefixed_args(ctx, [ "nslookup", query, as_string(target.host) ]), true); + let elapsed = now_ms() - started; + let output = lc(as_string(result.output)); + let ok = result.status == 0 && index(output, "address") >= 0; + return { + reached: ok, + code: 0, + remote_ip: as_string(target.host), + tcp_ms: elapsed, + tls_ms: 0, + total_ms: elapsed, + verdict: ok ? "" : "timeout", + message: ok ? "получен ответ DNS по UDP" : "нет ответа DNS по UDP" + }; +} + +function connection_probe(ctx, target) { + if (as_string(target.kind) == "gemini_geo") { + if (!ctx.tools.curl) + return { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "skipped", message: "для геопроверки Gemini нужен curl" }; + return probe_gemini_geo(ctx, target); + } + if (as_string(target.kind) == "udp_dns") + return udp_dns_probe(ctx, target); + if (as_string(target.kind) == "udp") + return udp_probe(ctx, target); + if (as_string(target.kind) == "tcp") { + if (!ctx.tools.curl && !ctx.tools.nc) + return { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "skipped", message: "нет ни curl, ни nc" }; + return tcp_probe(ctx, target); + } + + if (ctx.tools.curl) + return http_probe_curl(ctx, target); + if (ctx.tools.uclient_fetch) + return http_probe_uclient(ctx, target); + + return { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "skipped", message: "нет ни curl, ни uclient-fetch" }; +} + +// --------------------------------------------------------------------------- +// Определение маршрута через Clash API +// --------------------------------------------------------------------------- + +function clash_connections() { + let backend = backend_id(); + let result; + + if (backend == "forkop") { + result = capture_args([ FORKOP_BIN, "clash_api", "get_connections" ], false); + } + else if (backend == "podkop") { + let config = object_or_empty(read_json_file(sing_box_config_path())); + let clash = object_or_empty(object_or_empty(config.experimental).clash_api); + let controller = trim(as_string(clash.external_controller)); + let secret = as_string(clash.secret); + + if (controller == "") + controller = "127.0.0.1:9090"; + if (match(controller, /^0\.0\.0\.0:/) != null) + controller = replace(controller, /^0\.0\.0\.0:/, "127.0.0.1:"); + if (index(controller, "http://") != 0 && index(controller, "https://") != 0) + controller = "http://" + controller; + + let args = [ "curl", "-sS", "--connect-timeout", "2", "--max-time", "4" ]; + if (secret == "") + secret = uci_get("podkop.settings.yacd_secret_key"); + if (secret != "") { + push(args, "-H"); + push(args, "Authorization: Bearer " + secret); + } + push(args, controller + "/connections"); + result = capture_args(args, false); + } + else { + return []; + } + + if (result.status != 0) + return []; + + let parsed = parse_json(result.output); + if (type(parsed) == "array") + return parsed; + + return array_or_empty(object_or_empty(parsed).connections); +} + +function route_for(connections, host, remote_ip, port) { + host = lc(as_string(host)); + remote_ip = as_string(remote_ip); + port = int(port || 0); + + for (let connection in connections) { + connection = object_or_empty(connection); + let metadata = object_or_empty(connection.metadata); + let connection_host = lc(as_string(metadata.host)); + let destination = as_string(metadata.destinationIP); + let destination_port = int(metadata.destinationPort || 0); + + if ((connection_host != "" && connection_host == host) || + (remote_ip != "" && destination == remote_ip)) { + if (port > 0 && destination_port > 0 && destination_port != port) + continue; + let chains = array_or_empty(connection.chains); + return { + seen: true, + outbound: length(chains) > 0 ? join(" ← ", chains) : "" + }; + } + } + + return { seen: false, outbound: "" }; +} + +function outbound_for(connections, host, remote_ip) { + return route_for(connections, host, remote_ip, 0).outbound; +} + +// Держим отдельное TCP-соединение открытым несколько секунд и в это время +// опрашиваем Clash API. Так маршрут определяется заметно надёжнее, чем после +// короткого HTTP-запроса, который часто успевает закрыться до get_connections. +function detect_live_route(ctx, host, port, remote_ip) { + let unknown = { attempted: false, seen: false, outbound: "" }; + if (!ctx.backend_running) + return unknown; + + let command = ""; + let nc_mode = as_string(ctx.tools.nc_mode); + if (ctx.tools.nc && (nc_mode == "zero" || nc_mode == "wait")) { + let args = prefixed_args(ctx, [ "nc", "-w", "6", as_string(host), as_string(port) ]); + command = "( sleep 5 ) | " + command_from_args(args); + } + else if (ctx.tools.curl) { + let url = "https://" + as_string(host) + ":" + as_string(port) + "/"; + let args = prefixed_args(ctx, [ + "curl", "-k", "-sS", "-L", "--connect-timeout", "4", "--max-time", "6", + "--limit-rate", "1", "-o", "/dev/null", url + ]); + command = command_from_args(args); + } + else { + return unknown; + } + + let launched = normalize_status(system("( " + command + " ) >/dev/null 2>&1 &")) == 0; + if (!launched) + return unknown; + + for (let attempt = 0; attempt < 6; attempt++) { + run_quiet([ "sleep", "1" ]); + let route = route_for(clash_connections(), host, remote_ip, port); + if (route.seen) + return { attempted: true, seen: true, outbound: route.outbound }; + } + + return { attempted: true, seen: false, outbound: "" }; +} + +// --------------------------------------------------------------------------- +// Вердикты +// --------------------------------------------------------------------------- + +function expected_codes(target) { + let expect = array_or_empty(object_or_empty(target).expect); + return length(expect) > 0 ? expect : [ 200 ]; +} + +function code_expected(code, target) { + code = int(code); + for (let value in expected_codes(target)) + if (int(value) == code) + return true; + return false; +} + +function target_verdict(target, dns, connection) { + if (as_string(connection.verdict) == "skipped") + return { state: "skipped", verdict: "skipped", message: as_string(connection.message) }; + + if (as_string(connection.verdict) == "udp_unconfirmed") + return { state: "warning", verdict: "udp_unconfirmed", message: as_string(connection.message) }; + + if (!dns.ok && !valid_ipv4(as_string(target.host))) + return { state: "error", verdict: "dns_fail", message: "DNS не отдал адрес: " + as_string(dns.error) }; + + if (!connection.reached) { + let verdict = as_string(connection.verdict); + // Круг редиректов означает, что сервис отвечает: сеть до него рабочая, + // поэтому это замечание, а не отказ. + if (verdict == "redirect_loop") + return { state: "warning", verdict, message: as_string(connection.message) }; + return { state: "error", verdict: verdict != "" ? verdict : "failed", message: as_string(connection.message) }; + } + + if (as_string(target.kind) == "gemini_geo") { + if (connection.verdict == "gemini_geo_ok") + return { state: "success", verdict: "ok", message: as_string(connection.message) }; + if (connection.verdict == "gemini_geo_blocked") + return { state: "warning", verdict: "geo_blocked", message: as_string(connection.message) }; + if (connection.verdict == "gemini_api_key_invalid") + return { state: "warning", verdict: "gemini_api_key_invalid", message: as_string(connection.message) }; + return { state: "error", verdict: as_string(connection.verdict) != "" ? as_string(connection.verdict) : "failed", message: as_string(connection.message) }; + } + + if (as_string(target.kind) == "tcp" || as_string(target.kind) == "udp" || as_string(target.kind) == "udp_dns") + return int(connection.total_ms) > SLOW_THRESHOLD_MS + ? { state: "warning", verdict: "slow", message: "соединение установлено, но медленно" } + : { state: "success", verdict: "ok", message: "" }; + + let code = int(connection.code); + let expected = code_expected(code, target); + + // Мы проверяем достижимость, а не семантику API: раз пришёл любой HTTP-ответ, + // значит DNS, TCP, TLS и HTTP отработали и путь до сервиса живой. Коды вроде + // 404 на голом корне CDN - это норма, а не проблема сети. Особые случаи ниже. + if (code >= 500) + return { state: "warning", verdict: "http_server_error", message: sprintf("сервис отвечает ошибкой %d", code) }; + + if (!expected && (code == 403 || code == 451)) + return { state: "warning", verdict: "geo_blocked", message: sprintf("ответ %d — похоже на блокировку по IP или региону", code) }; + + if (int(connection.total_ms) > SLOW_THRESHOLD_MS) + return { state: "warning", verdict: "slow", message: sprintf("работает, но медленно: %d мс", int(connection.total_ms)) }; + + if (!expected) + return { state: "success", verdict: "ok", message: sprintf("ответ %d — нетипичный, но соединение проходит", code) }; + + return { state: "success", verdict: "ok", message: "" }; +} + +function service_state(items) { + let required_total = 0; + let required_ok = 0; + let has_warning = false; + + for (let item in items) { + if (item.optional || item.state == "skipped") + continue; + + required_total++; + if (item.state == "success") + required_ok++; + else if (item.state == "warning") { + required_ok++; + has_warning = true; + } + } + + if (required_total == 0) + return { state: "warning", description: "проверить не удалось" }; + if (required_ok == 0) + return { state: "error", description: "не работает" }; + if (required_ok < required_total) + return { state: "warning", description: sprintf("работает частично (%d из %d)", required_ok, required_total) }; + if (has_warning) + return { state: "warning", description: "работает с замечаниями" }; + + return { state: "success", description: "работает" }; +} + +// --------------------------------------------------------------------------- +// Запуск проверки +// --------------------------------------------------------------------------- + +// ВАЖНО: в ucode нет подъёма объявлений - функция, объявленная ниже по файлу, +// не видна объявленной выше (вызов компилируется как обращение к глобали и падает +// в рантайме). Поэтому порядок объявлений здесь значим: сначала зависимости. + +function netns_teardown() { + run_quiet([ "ip", "netns", "del", NETNS_NAME ]); + run_quiet([ "ip", "link", "del", NETNS_VETH_HOST ]); + run_quiet([ "rm", "-rf", "/etc/netns/" + NETNS_NAME ]); +} + +function leased_addresses() { + let leases = {}; + let data = fs.readfile("/tmp/dhcp.leases"); + if (data == null) + return leases; + + for (let line in split(as_string(data), "\n")) { + let fields = words(line); + if (length(fields) >= 3 && valid_ipv4(fields[2])) + leases[fields[2]] = true; + } + + return leases; +} + +function address_free(candidate, leases) { + if (leases[candidate]) + return false; + // Не используем ICMP: некоторые провайдеры и сетевые фильтры реагируют на + // массовые echo-запросы. Проверяем только ARP/маршрут через HTTPS. + if (command_exists("curl")) { + let result = capture_args([ "curl", "-k", "-sS", "-o", "/dev/null", + "--connect-timeout", "1", "--max-time", "2", "https://" + candidate + "/" ], false); + // Любой ответ HTTPS означает занятый адрес; ошибки маршрута/таймаута + // оставляют возможность использовать кандидат. + return result.status == 6 || result.status == 7 || result.status == 28; + } + return true; +} + +function pick_client_ip(caps, requested) { + requested = as_string(requested); + if (valid_ipv4(requested)) + return requested; + + let prefix = int(caps.lan_prefix); + if (!valid_ipv4(caps.lan_address) || prefix < 16 || prefix > 30) + return ""; + + let mask = prefix_mask(prefix); + let router_value = ipv4_to_int(caps.lan_address); + let network = router_value & mask; + let size = 1 << (32 - prefix); + let broadcast = network + size - 1; + let leases = leased_addresses(); + + // Берём адреса с верхнего края подсети - там DHCP-пул OpenWrt заканчивается раньше. + for (let offset = 1; offset <= 8; offset++) { + let candidate_value = broadcast - offset; + if (candidate_value <= network || candidate_value == router_value) + continue; + let candidate = int_to_ipv4(candidate_value); + if (address_free(candidate, leases)) + return candidate; + } + + return ""; +} + +function netns_setup(caps, requested_ip) { + if (!caps.netns) + return { ok: false, error: "режим клиента недоступен: нет поддержки ip netns" }; + + netns_teardown(); + + let client_ip = pick_client_ip(caps, requested_ip); + if (client_ip == "") + return { ok: false, error: "не удалось подобрать свободный IP в LAN" }; + + let prefix = as_string(int(caps.lan_prefix)); + let steps = [ + [ "ip", "netns", "add", NETNS_NAME ], + [ "ip", "link", "add", NETNS_VETH_HOST, "type", "veth", "peer", "name", NETNS_VETH_PEER ], + [ "ip", "link", "set", NETNS_VETH_PEER, "netns", NETNS_NAME ], + [ "ip", "link", "set", NETNS_VETH_HOST, "master", caps.lan_interface ], + [ "ip", "link", "set", NETNS_VETH_HOST, "up" ], + [ "ip", "netns", "exec", NETNS_NAME, "ip", "link", "set", "lo", "up" ], + [ "ip", "netns", "exec", NETNS_NAME, "ip", "addr", "add", client_ip + "/" + prefix, "dev", NETNS_VETH_PEER ], + [ "ip", "netns", "exec", NETNS_NAME, "ip", "link", "set", NETNS_VETH_PEER, "up" ], + [ "ip", "netns", "exec", NETNS_NAME, "ip", "route", "add", "default", "via", caps.lan_address ] + ]; + + for (let step in steps) { + if (!run_quiet(step)) { + netns_teardown(); + return { ok: false, error: "не удалось выполнить: " + join(" ", step) }; + } + } + + run_quiet([ "mkdir", "-p", "/etc/netns/" + NETNS_NAME ]); + if (fs.writefile("/etc/netns/" + NETNS_NAME + "/resolv.conf", "nameserver " + caps.lan_address + "\n") == null) { + netns_teardown(); + return { ok: false, error: "не удалось записать resolv.conf для namespace" }; + } + + return { ok: true, client_ip, error: "" }; +} + +function build_context(mode, client_ip) { + let caps = capabilities(); + let ctx = { + tools: { + curl: caps.curl, + uclient_fetch: caps.uclient_fetch, + dig: caps.dig, + nslookup: caps.nslookup, + nc: caps.nc, + nc_mode: caps.nc_mode, + timeout_cmd: caps.timeout_cmd + }, + fakeip_ranges: caps.fakeip_ranges, + resolver: "127.0.0.1", + exec_prefix: [], + mode: as_string(mode) == "netns" ? "netns" : "router", + lan_interface: caps.lan_interface, + lan_address: caps.lan_address, + backend: caps.backend, + backend_name: caps.backend_name, + backend_running: caps.backend_running, + forkop_running: caps.forkop_running, + client_ip: "", + netns_error: "" + }; + + if (ctx.mode != "netns") + return ctx; + + let netns = netns_setup(caps, client_ip); + if (!netns.ok) { + ctx.mode = "router"; + ctx.netns_error = netns.error; + return ctx; + } + + ctx.exec_prefix = [ "ip", "netns", "exec", NETNS_NAME ]; + ctx.resolver = caps.lan_address != "" ? caps.lan_address : "127.0.0.1"; + ctx.client_ip = netns.client_ip; + ctx.netns_active = true; + return ctx; +} + +function probe_target(ctx, target) { + target = object_or_empty(target); + let host = as_string(target.host); + let dns = probe_dns(ctx, host); + let connection = { reached: false, code: 0, tcp_ms: 0, tls_ms: 0, total_ms: 0, remote_ip: "", verdict: "", message: "" }; + + if (dns.ok) + connection = connection_probe(ctx, target); + else + connection.verdict = "dns_fail"; + + let verdict = target_verdict(target, dns, connection); + + return { + label: target_label(target), + kind: as_string(target.kind || "https"), + host, + port: int(target.port || (as_string(target.kind) == "http" ? 80 : 443)), + url: as_string(target.kind) == "tcp" ? "" : target_url(target), + optional: target.optional === true, + dns_ok: dns.ok, + dns_ip: as_string(dns.ip), + dns_fakeip: dns.fakeip === true, + dns_ms: int(dns.ms), + remote_ip: as_string(connection.remote_ip), + http_code: int(connection.code), + tcp_ms: int(connection.tcp_ms), + tls_ms: int(connection.tls_ms), + total_ms: int(connection.total_ms), + outbound: "", + state: verdict.state, + verdict: verdict.verdict, + message: verdict.message + }; +} + +function probe_service(ctx, profile) { + profile = object_or_empty(profile); + let items = []; + + for (let target in array_or_empty(profile.targets)) + push(items, probe_target(ctx, target)); + + // Атрибуция маршрута - best effort: Clash API отдаёт только живые соединения, + // а короткие HTTP-запросы к моменту опроса часто уже закрыты. Поэтому один + // запрос на сервис, а не на каждую цель, и пустой результат не считается ошибкой. + if (ctx.backend_running) { + let connections = clash_connections(); + if (length(connections) > 0) { + for (let item in items) { + if (!item.state || item.state == "skipped") + continue; + item.outbound = outbound_for(connections, item.host, item.remote_ip); + } + } + } + + let summary = service_state(items); + + return { + id: as_string(profile.id), + title: as_string(profile.title), + group: as_string(profile.group), + description: as_string(profile.description), + state: summary.state, + description_result: summary.description, + items + }; +} + +function custom_check(host, port, mode, client_ip) { + host = lc(trim(as_string(host))); + if (length(host) > 0 && substr(host, length(host) - 1, 1) == ".") + host = substr(host, 0, length(host) - 1); + + port = int(port || 443); + if (!valid_custom_host(host)) + return { success: false, message: "Введите корректный IPv4-адрес или домен без протокола и пути" }; + if (port < 1 || port > 65535) + return { success: false, message: "TCP-порт должен быть от 1 до 65535" }; + + let ctx = build_context(mode, client_ip); + let dns = probe_dns(ctx, host); + let remote_ip = dns.ok ? as_string(dns.ip) : (valid_ipv4(host) ? host : ""); + let live_route = detect_live_route(ctx, host, port, remote_ip); + let item = probe_target(ctx, { + kind: "tcp", + host, + port, + label: host + ":" + as_string(port) + }); + + let through_sing_box = null; + let route_status = "unknown"; + let route_message = "Маршрут не удалось подтвердить через Clash API."; + let evidence = ""; + + if (!ctx.backend_running) { + through_sing_box = false; + route_status = "direct"; + evidence = "backend_stopped"; + route_message = ctx.backend_name + " остановлен: соединение не проходит через sing-box."; + } + else if (live_route.seen) { + through_sing_box = true; + route_status = "sing-box"; + evidence = "clash_api"; + item.outbound = live_route.outbound; + route_message = live_route.outbound != "" + ? "Соединение найдено в sing-box; outbound: " + live_route.outbound + : "Соединение найдено среди активных соединений sing-box."; + } + else if (item.dns_fakeip) { + through_sing_box = true; + route_status = "sing-box"; + evidence = "fakeip"; + route_message = "Домен получил FakeIP, который обслуживается sing-box."; + } + else if (live_route.attempted && item.state != "error" && item.state != "skipped") { + through_sing_box = false; + route_status = "direct"; + evidence = "clash_api_absent"; + route_message = "Соединение доступно, но за время теста не появилось в Clash API: маршрут идёт мимо sing-box."; + } + else if (item.state == "error") { + route_message = "Соединение не установлено, поэтому определить маршрут нельзя."; + } + + if (ctx.netns_active) + netns_teardown(); + + return { + success: true, + target: host, + port, + mode: ctx.mode, + requested_mode: as_string(mode) == "netns" ? "netns" : "router", + client_ip: as_string(ctx.client_ip), + netns_error: as_string(ctx.netns_error), + backend: ctx.backend, + backend_name: ctx.backend_name, + backend_running: ctx.backend_running, + forkop_running: ctx.forkop_running, + route: { + status: route_status, + through_sing_box, + outbound: as_string(item.outbound), + evidence, + message: route_message + }, + item + }; +} + +function selected_profiles(ids) { + ids = trim(as_string(ids)); + let all = load_profiles(); + + if (ids == "" || ids == "all") + return all; + + let wanted = {}; + for (let id in split(ids, ",")) + wanted[trim(as_string(id))] = true; + + let result = []; + for (let profile in all) + if (wanted[as_string(object_or_empty(profile).id)]) + push(result, profile); + + return result; +} + +// Состояние фоновых заданий. Объявлено до run_check, потому что тот пишет в него +// прогресс по ходу проверки, а forward-ссылок ucode не прощает. + +function job_id_valid(value) { + value = as_string(value); + return value != "" && match(value, /^[A-Za-z0-9_-]+$/) != null; +} + +function job_path(job_id) { + return job_id_valid(job_id) ? STATE_DIR + "/" + as_string(job_id) + ".json" : ""; +} + +function write_state(path, value) { + ensure_state_dir(); + return fs.writefile(as_string(path), sprintf("%J", value) + "\n") != null; +} + +function update_progress(path, done, total, services) { + let state = object_or_empty(read_json_file(path)); + if (!state.running) + return; + state.progress = { done: int(done), total: int(total) }; + state.services = services; + write_state(path, state); +} + +function run_check(ids, mode, client_ip, progress_path) { + let profiles = selected_profiles(ids); + let ctx = build_context(mode, client_ip); + let services = []; + let total = 0; + + for (let profile in profiles) + total += length(array_or_empty(object_or_empty(profile).targets)); + + let done = 0; + + for (let profile in profiles) { + let result = probe_service(ctx, profile); + push(services, result); + done += length(result.items); + if (as_string(progress_path) != "") + update_progress(progress_path, done, total, services); + } + + if (ctx.netns_active) + netns_teardown(); + + return { + generated_at: now_seconds(), + mode: ctx.mode, + requested_mode: as_string(mode) == "netns" ? "netns" : "router", + netns_error: as_string(ctx.netns_error), + client_ip: as_string(ctx.client_ip), + resolver: ctx.resolver, + backend: ctx.backend, + backend_name: ctx.backend_name, + backend_running: ctx.backend_running, + forkop_running: ctx.forkop_running, + tools: ctx.tools, + fakeip_ranges: ctx.fakeip_ranges, + progress: { done, total }, + services + }; +} + +// --------------------------------------------------------------------------- +// Фоновые задания +// --------------------------------------------------------------------------- + +function cleanup_jobs() { + ensure_state_dir(); + let now = now_seconds(); + for (let path in fs.glob(STATE_DIR + "/*.json")) { + let state = object_or_empty(read_json_file(path)); + let started = int(state.started_at || 0); + if (started > 0 && now - started > JOB_MAX_AGE) + fs.unlink(path); + } +} + +function start_job(ids, mode, client_ip) { + ensure_state_dir(); + cleanup_jobs(); + + let job_id = sprintf("sc-%d-%d", now_seconds(), int(now_ms() % 100000)); + let path = job_path(job_id); + if (path == "") { + write_json({ success: false, message: "не удалось создать задание" }); + return 1; + } + + let profiles = selected_profiles(ids); + let total = 0; + for (let profile in profiles) + total += length(array_or_empty(object_or_empty(profile).targets)); + + if (length(profiles) == 0) { + write_json({ success: false, message: "не выбран ни один сервис" }); + return 1; + } + + let state = { + kind: "service_check", + job_id, + running: true, + success: false, + started_at: now_seconds(), + finished_at: 0, + mode: as_string(mode) == "netns" ? "netns" : "router", + ids: as_string(ids), + progress: { done: 0, total }, + services: [] + }; + + if (!write_state(path, state)) { + write_json({ success: false, message: "не удалось записать состояние задания" }); + return 1; + } + + let worker = command_from_args([ + "ucode", "-L", LIB_DIR, ENGINE, "worker", path, as_string(ids), as_string(mode), as_string(client_ip) + ]); + system("(" + worker + " >/dev/null 2>&1 &)"); + + write_json({ success: true, job_id, progress: state.progress }); + return 0; +} + +function worker(path, ids, mode, client_ip) { + let result = run_check(ids, mode, client_ip, path); + let state = object_or_empty(read_json_file(path)); + + state.running = false; + state.success = true; + state.finished_at = now_seconds(); + state.services = result.services; + state.resolver = result.resolver; + state.tools = result.tools; + state.fakeip_ranges = result.fakeip_ranges; + state.progress = result.progress; + state.mode = result.mode; + state.netns_error = result.netns_error; + state.client_ip = result.client_ip; + state.backend = result.backend; + state.backend_name = result.backend_name; + state.backend_running = result.backend_running; + state.forkop_running = result.forkop_running; + + write_state(path, state); + return 0; +} + +function job_status(job_id) { + let path = job_path(job_id); + if (path == "" || fs.stat(path) == null) { + write_json({ success: false, running: false, message: "задание не найдено" }); + return 1; + } + + let state = object_or_empty(read_json_file(path)); + if (length(keys(state)) == 0) { + write_json({ success: false, running: false, message: "не удалось прочитать состояние задания" }); + return 1; + } + + write_json(state); + return 0; +} + +function list_profiles() { + let data = object_or_empty(read_json_file(profiles_file())); + let profiles = []; + + for (let profile in array_or_empty(data.profiles)) { + profile = object_or_empty(profile); + push(profiles, { + id: as_string(profile.id), + title: as_string(profile.title), + group: as_string(profile.group), + description: as_string(profile.description), + targets: length(array_or_empty(profile.targets)) + }); + } + + write_json({ version: int(data.version || 0), updated: as_string(data.updated), profiles }); + return 0; +} + +function gemini_key_set(value) { + let key = trim(as_string(value)); + if (match(key, /^[A-Za-z0-9_-]{20,200}$/) == null) { + write_json({ success: false, message: "ключ имеет недопустимый формат" }); + return 1; + } + + run_quiet([ "mkdir", "-p", CONFIG_DIR ]); + if (fs.writefile(GEMINI_API_KEY_FILE, key + "\n") == null) { + write_json({ success: false, message: "не удалось сохранить ключ" }); + return 1; + } + + run_quiet([ "chmod", "600", GEMINI_API_KEY_FILE ]); + write_json({ success: true, configured: true, message: "ключ сохранён" }); + return 0; +} + +function gemini_key_reset() { + fs.unlink(GEMINI_API_KEY_FILE); + write_json({ success: true, configured: false, message: "ключ удалён" }); + return 0; +} + +function gemini_key_status() { + let configured = read_gemini_api_key() != ""; + write_json({ success: true, configured, message: configured ? "используется пользовательский ключ" : "ключ не задан" }); + return 0; +} + +// --------------------------------------------------------------------------- + +function tachyon_get_targets(all_mode) { + let uci = require("uci"); let cursor = uci.cursor(); cursor.load("tachyon"); - let results = []; - + let all_profiles_json = fs.readfile(PROFILES_OVERRIDE) || fs.readfile(PROFILES_DEFAULT); + let all_profiles = json(all_profiles_json) || { profiles: [] }; + let profiles_map = {}; + for (let i = 0; i < length(all_profiles.profiles); i++) { + let p = all_profiles.profiles[i]; + profiles_map[p.id] = p; + } + + let targets = []; + let seen_domains = {}; + + if (all_mode == "all") { + // 1. Include ALL Community Profiles + for (let i = 0; i < length(all_profiles.profiles); i++) { + let profile = all_profiles.profiles[i]; + let profile_title = profile.title || profile.name || profile.id; + for (let j = 0; j < length(profile.targets); j++) { + let t = profile.targets[j]; + let host = t.host || t.query || ""; + if (!host || seen_domains[host]) continue; + seen_domains[host] = true; + + push(targets, { + section: profile_title, + route_type: "auto", + domain: host, + port: t.port || (t.kind == "https" ? 443 : 80), + kind: t.kind, + path: t.path || "/", + expect: t.expect || [200, 301, 302], + target_label: t.label || host + }); + } + } + + // 2. Include custom user domains from all UCI sections + cursor.foreach("tachyon", "section", function(s) { + let label = s.label || s['.name']; + let route_type = s.action || "direct"; + if (s.action == "zapret" && s.zapret_strategy) route_type = "zapret (" + s.zapret_strategy + ")"; + else if (s.action == "zapret2" && s.zapret2_strategy) route_type = "zapret2 (" + s.zapret2_strategy + ")"; + else if (s.action == "byedpi" && s.byedpi_strategy) route_type = "byedpi (" + s.byedpi_strategy + ")"; + + let custom_domains = []; + let lists = type(s.user_domains) == "array" ? s.user_domains : [ s.user_domains ]; + for (let d in lists) { + if (!d) continue; + for (let line in split(as_string(d), /[\n\r,]+/)) { + let domain_str = trim(replace(line, /^\*?\./, "")); + if (domain_str != "" && substr(domain_str, 0, 1) != "#") + push(custom_domains, domain_str); + } + } + + if (s.user_domains_text) { + for (let line in split(as_string(s.user_domains_text), /[\n\r,]+/)) { + let domain_str = trim(replace(line, /^\*?\./, "")); + if (domain_str != "" && substr(domain_str, 0, 1) != "#") + push(custom_domains, domain_str); + } + } + + for (let cd in custom_domains) { + if (seen_domains[cd]) continue; + seen_domains[cd] = true; + push(targets, { + section: label, + route_type: route_type, + domain: cd, + port: 443, + kind: "https", + path: "/", + expect: [200, 301, 302, 307, 400, 403, 404, 405, 426], + target_label: cd + }); + } + }); + + write_json(targets); + return; + } + + // Active mode (default): Check targets in active enabled UCI sections cursor.foreach("tachyon", "section", function(s) { if (s.enabled != "1") return; - let domains_to_check = []; + let profiles_to_check = []; if (type(s.community_lists) == "array") { for (let i = 0; i < length(s.community_lists); i++) { - let list_name = s.community_lists[i]; - if (TARGET_DOMAINS[list_name]) { - push(domains_to_check, TARGET_DOMAINS[list_name]); + if (profiles_map[s.community_lists[i]]) { + push(profiles_to_check, profiles_map[s.community_lists[i]]); } } } else if (type(s.community_lists) == "string") { - if (TARGET_DOMAINS[s.community_lists]) { - push(domains_to_check, TARGET_DOMAINS[s.community_lists]); + if (profiles_map[s.community_lists]) { + push(profiles_to_check, profiles_map[s.community_lists]); } } - let unique_domains = {}; - for (let i = 0; i < length(domains_to_check); i++) { - unique_domains[domains_to_check[i]] = true; - } + let label = s.label || s['.name']; + let route_type = s.action || "direct"; - for (let domain in keys(unique_domains)) { - let label = s.label || s['.name']; - let route_type = s.action || "direct"; - - if (s.action == "zapret" && s.zapret_strategy) { - route_type = "zapret (" + s.zapret_strategy + ")"; - } else if (s.action == "zapret2" && s.zapret2_strategy) { - route_type = "zapret2 (" + s.zapret2_strategy + ")"; - } else if (s.action == "byedpi" && s.byedpi_strategy) { - route_type = "byedpi (" + s.byedpi_strategy + ")"; + if (s.action == "zapret" && s.zapret_strategy) route_type = "zapret (" + s.zapret_strategy + ")"; + else if (s.action == "zapret2" && s.zapret2_strategy) route_type = "zapret2 (" + s.zapret2_strategy + ")"; + else if (s.action == "byedpi" && s.byedpi_strategy) route_type = "byedpi (" + s.byedpi_strategy + ")"; + + for (let i = 0; i < length(profiles_to_check); i++) { + let profile = profiles_to_check[i]; + for (let j = 0; j < length(profile.targets); j++) { + let t = profile.targets[j]; + let host = t.host || t.query || ""; + if (!host) continue; + + push(targets, { + section: label, + route_type: route_type, + domain: host, + port: t.port || (t.kind == "https" ? 443 : 80), + kind: t.kind, + path: t.path || "/", + expect: t.expect || [200, 301, 302], + target_label: t.label || host + }); } - - let res = perform_curl_check(domain); - let check_result = { + } + + let custom_domains = []; + let lists = type(s.user_domains) == "array" ? s.user_domains : [ s.user_domains ]; + for (let d in lists) { + if (!d) continue; + for (let line in split(as_string(d), /[\n\r,]+/)) { + let domain_str = trim(replace(line, /^\*?\./, "")); + if (domain_str != "" && substr(domain_str, 0, 1) != "#") + push(custom_domains, domain_str); + } + } + + if (s.user_domains_text) { + for (let line in split(as_string(s.user_domains_text), /[\n\r,]+/)) { + let domain_str = trim(replace(line, /^\*?\./, "")); + if (domain_str != "" && substr(domain_str, 0, 1) != "#") + push(custom_domains, domain_str); + } + } + + for (let cd in custom_domains) { + push(targets, { section: label, route_type: route_type, - domain: domain, - ip: res ? res.remote_ip : "", - dns_ms: res ? res.dns_ms : 0, - tcp_ms: res ? res.tcp_ms : 0, - tls_ms: res ? res.tls_ms : 0, - http_ms: res ? res.http_ms : 0, - status_class: res ? res.status_class : "Error", - success: res ? res.success : false - }; - push(results, check_result); + domain: cd, + port: 443, + kind: "https", + path: "/", + expect: [200, 301, 302, 307, 400, 403, 404, 405, 426], + target_label: cd + }); } }); - print(sprintf("%J", results), "\n"); + write_json(targets); } -function process_custom_domain(domain) { - let res = perform_curl_check(domain); - let results = [{ - section: "Custom", - route_type: "auto", - domain: domain, - ip: res ? res.remote_ip : "", - dns_ms: res ? res.dns_ms : 0, - tcp_ms: res ? res.tcp_ms : 0, - tls_ms: res ? res.tls_ms : 0, - http_ms: res ? res.http_ms : 0, - status_class: res ? res.status_class : "Error", - success: res ? res.success : false +function tachyon_check_target(target_json_str) { + let t = json(target_json_str); + if (!t) { + write_json([{ success: false, status_class: "Error parsing target" }]); + return; + } + + if (!t.host && t.domain) t.host = t.domain; + + let ctx = build_context("router", ""); + let item = probe_target(ctx, t); + + let http_time = item.total_ms - item.tcp_ms - item.tls_ms; + if (http_time < 0) http_time = 0; + + let result = [{ + section: t.section || "Custom", + route_type: t.route_type || "auto", + domain: t.target_label || t.host, + ip: item.remote_ip || item.dns_ip || "", + dns_ms: item.dns_ms || 0, + tcp_ms: item.tcp_ms || 0, + tls_ms: item.tls_ms || 0, + http_ms: http_time || 0, + status_class: item.state == "success" ? "OK" : (item.message || item.verdict || "Error"), + success: item.state == "success" }]; - print(sprintf("%J", results), "\n"); + write_json(result); } -if (ARGV[0] == "check-custom" && ARGV[1]) { - process_custom_domain(ARGV[1]); +let mode = as_string(ARGV[0]); + +if (mode == "get-targets") { + tachyon_get_targets(ARGV[1]); +} else if (mode == "check-domain" && ARGV[1]) { + tachyon_check_target(ARGV[1]); +} else if (mode == "check-custom" && ARGV[1]) { + let custom_target = { + kind: "https", + host: ARGV[1], + port: 443, + path: "/", + expect: [200, 301, 302, 307, 400, 403, 404, 405, 426] + }; + tachyon_check_target(sprintf("%J", custom_target)); } else { - process_sections(); + warn("Unknown mode: ", mode, "\n"); + exit(1); } diff --git a/tachyon/files/usr/lib/diagnostics/status.uc b/tachyon/files/usr/lib/diagnostics/status.uc index 70bf6f22..c4d78b99 100644 --- a/tachyon/files/usr/lib/diagnostics/status.uc +++ b/tachyon/files/usr/lib/diagnostics/status.uc @@ -2031,8 +2031,6 @@ else if (mode == "clash-proxy-latencies-result") clash_proxy_latencies_result(ARGV[1], ARGV[2]); else if (mode == "clash-unknown-action") clash_unknown_action(); -else if (mode == "service-health-check") - system("ucode /usr/lib/tachyon/diagnostics/service_check.uc " + (ARGV[1] || "")); else { warn("Usage: diagnostics/status.uc ...\n"); exit(1); diff --git a/tachyon/files/usr/lib/subscription/parser.uc b/tachyon/files/usr/lib/subscription/parser.uc index 16eb1a38..3a7159c8 100644 --- a/tachyon/files/usr/lib/subscription/parser.uc +++ b/tachyon/files/usr/lib/subscription/parser.uc @@ -1737,12 +1737,58 @@ function metadata_trim_text(value) { return trim(as_string(value)); } +function hex_val(ch) { + let code = ord(ch); + if (code >= 48 && code <= 57) return code - 48; + if (code >= 65 && code <= 70) return code - 55; + if (code >= 97 && code <= 102) return code - 87; + return 0; +} + +function hex_to_int(str) { + if (length(str) < 2) return 0; + return (hex_val(substr(str, 0, 1)) << 4) | hex_val(substr(str, 1, 1)); +} + +function decode_url_component(str) { + str = as_string(str); + str = replace(str, /\+/g, " "); + return replace(str, /%([0-9A-Fa-f]{2})/g, function(match, hex) { + return chr(hex_to_int(hex)); + }); +} + +function decode_rfc2047(val) { + val = as_string(val); + let m = match(val, /^=\?([^?]+)\?([BbQq])\?([^?]+)\?=$/); + if (m) { + let encoding = lc(m[2]); + let data = m[3]; + if (encoding == "b") { + let decoded = base64_decode(data); + if (decoded != null) return decoded; + } else if (encoding == "q") { + let qdecoded = replace(data, /_/g, " "); + qdecoded = replace(qdecoded, /=([0-9A-Fa-f]{2})/g, function(full, hex) { + return chr(hex_to_int(hex)); + }); + return qdecoded; + } + } + return val; +} + function metadata_clean_text(value, max, decode_base64) { value = as_string(value); + if (starts_with(value, "=?")) + value = decode_rfc2047(value); if (decode_base64 && lc(substr(value, 0, 7)) == "base64:") { let decoded = base64_decode(substr(value, 7)); value = decoded == null ? "" : decoded; } + if (index(value, "%") >= 0) { + value = decode_url_component(value); + } let cleaned = trim(replace(replace(value, regexp('[\\x00-\\x1f\\x7f]', 'g'), " "), regexp(' +', 'g'), " ")); if (cleaned == "") @@ -1777,28 +1823,47 @@ function metadata_replace_path_separators(value) { function metadata_content_disposition_filename(value) { value = as_string(value); let filename = null; - let quoted_marker = "filename=\""; - let quoted_pos = index(value, quoted_marker); - if (quoted_pos >= 0) { - let rest = substr(value, quoted_pos + length(quoted_marker)); - let quote_end = index(rest, "\""); - filename = quote_end >= 0 ? substr(rest, 0, quote_end) : rest; - } - else { - let marker = "filename="; - let pos = index(value, marker); - if (pos < 0) - return null; - let rest = substr(value, pos + length(marker)); + let pos_ext = index(value, "filename*="); + if (pos_ext >= 0) { + let rest = substr(value, pos_ext + 10); let semicolon = index(rest, ";"); - filename = semicolon >= 0 ? substr(rest, 0, semicolon) : rest; - if (length(filename) > 0 && substr(filename, 0, 1) == "\"") - filename = substr(filename, 1); - if (length(filename) > 0 && substr(filename, length(filename) - 1) == "\"") - filename = substr(filename, 0, length(filename) - 1); + let ext_val = semicolon >= 0 ? substr(rest, 0, semicolon) : rest; + ext_val = trim(ext_val); + let quote = index(ext_val, "''"); + if (quote >= 0) { + filename = decode_url_component(substr(ext_val, quote + 2)); + } else { + filename = decode_url_component(ext_val); + } } + if (filename == null) { + let quoted_marker = "filename=\""; + let quoted_pos = index(value, quoted_marker); + if (quoted_pos >= 0) { + let rest = substr(value, quoted_pos + length(quoted_marker)); + let quote_end = index(rest, "\""); + filename = quote_end >= 0 ? substr(rest, 0, quote_end) : rest; + } + else { + let marker = "filename="; + let pos = index(value, marker); + if (pos >= 0) { + let rest = substr(value, pos + length(marker)); + let semicolon = index(rest, ";"); + filename = semicolon >= 0 ? substr(rest, 0, semicolon) : rest; + if (length(filename) > 0 && substr(filename, 0, 1) == "\"") + filename = substr(filename, 1); + if (length(filename) > 0 && substr(filename, length(filename) - 1) == "\"") + filename = substr(filename, 0, length(filename) - 1); + } + } + } + + if (filename == null) + return null; + filename = metadata_clean_text(filename, 120, false); if (filename == null) return null; diff --git a/tachyon/files/usr/lib/tachyon/service/uninstall.uc b/tachyon/files/usr/lib/tachyon/service/uninstall.uc new file mode 100644 index 00000000..708e0248 --- /dev/null +++ b/tachyon/files/usr/lib/tachyon/service/uninstall.uc @@ -0,0 +1,82 @@ +#!/usr/bin/env ucode + +// Tachyon Clean Uninstaller Module +// Fully restores dnsmasq, cleans nftables/tproxy, restores Forkop/Podkop if present, +// and safely removes Tachyon packages without breaking router configuration. + +let fs = require("fs"); + +function as_string(value) { + return value == null ? "" : "" + value; +} + +function run_cmd(args) { + let parts = []; + for (let arg in args) + push(parts, "'" + replace(as_string(arg), /'/g, "'\\''") + "'"); + return system(join(" ", parts) + " >/dev/null 2>&1"); +} + +function log_step(msg) { + print("[Tachyon Uninstall] ", msg, "\n"); +} + +function uninstall_tachyon(purge_config) { + log_step("Stopping and disabling Tachyon service..."); + run_cmd(["/etc/init.d/tachyon", "stop"]); + run_cmd(["/etc/init.d/tachyon", "disable"]); + + log_step("Cleaning up firewall and nftables rules..."); + run_cmd(["nft", "delete", "table", "inet", "tachyon"]); + run_cmd(["nft", "delete", "table", "ip", "tachyon"]); + run_cmd(["nft", "delete", "table", "ip6", "tachyon"]); + run_cmd(["ip", "rule", "del", "fwmark", "0x1/0x1"]); + run_cmd(["ip", "rule", "del", "fwmark", "0x2/0x2"]); + run_cmd(["ip", "route", "flush", "table", "100"]); + + log_step("Restoring dnsmasq configuration..."); + run_cmd(["rm", "-f", "/etc/dnsmasq.d/tachyon.conf"]); + run_cmd(["rm", "-f", "/tmp/dnsmasq.d/tachyon.conf"]); + run_cmd(["rm", "-rf", "/tmp/dnsmasq.d/tachyon-*.conf"]); + + if (fs.stat("/etc/config/dnsmasq.tachyon-bak") != null) { + run_cmd(["cp", "-f", "/etc/config/dnsmasq.tachyon-bak", "/etc/config/dnsmasq"]); + log_step("Restored original dnsmasq config from backup."); + } + + run_cmd(["/etc/init.d/dnsmasq", "restart"]); + + if (purge_config) { + log_step("Purging Tachyon configuration..."); + run_cmd(["rm", "-rf", "/etc/config/tachyon"]); + run_cmd(["rm", "-rf", "/etc/tachyon"]); + } else { + log_step("Backing up Tachyon configuration to /etc/config/tachyon.bak..."); + run_cmd(["cp", "-af", "/etc/config/tachyon", "/etc/config/tachyon.bak"]); + } + + // Check if Forkop or Podkop was installed prior and re-enable it + if (fs.stat("/etc/init.d/forkop") != null) { + log_step("Forkop detected! Restoring Forkop service..."); + run_cmd(["/etc/init.d/forkop", "enable"]); + run_cmd(["/etc/init.d/forkop", "restart"]); + } else if (fs.stat("/etc/init.d/podkop") != null) { + log_step("Podkop detected! Restoring Podkop service..."); + run_cmd(["/etc/init.d/podkop", "enable"]); + run_cmd(["/etc/init.d/podkop", "restart"]); + } + + log_step("Removing Tachyon packages..."); + if (fs.stat("/bin/opkg") != null || fs.stat("/usr/bin/opkg") != null) { + run_cmd(["opkg", "remove", "luci-app-tachyon", "tachyon"]); + } else if (fs.stat("/sbin/apk") != null) { + run_cmd(["apk", "del", "luci-app-tachyon", "tachyon"]); + } + + log_step("Tachyon has been successfully uninstalled."); + return 0; +} + +let mode = as_string(ARGV[0]); +let purge = mode == "--purge" || as_string(ARGV[1]) == "--purge"; +exit(uninstall_tachyon(purge)); diff --git a/tachyon/files/usr/share/tachyon/servicecheck_profiles.json b/tachyon/files/usr/share/tachyon/servicecheck_profiles.json new file mode 100644 index 00000000..fa68981f --- /dev/null +++ b/tachyon/files/usr/share/tachyon/servicecheck_profiles.json @@ -0,0 +1,220 @@ +{ + "version": 2, + "updated": "2026-08-12", + "profiles": [ + { + "id": "baseline", + "title": "Базовая связность", + "group": "system", + "description": "Проверяет, что интернет и TLS вообще работают. Если этот профиль красный — остальные результаты бессмысленны.", + "targets": [ + { "kind": "https", "host": "cp.cloudflare.com", "path": "/generate_204", "expect": [204], "label": "Cloudflare generate_204" }, + { "kind": "https", "host": "www.gstatic.com", "path": "/generate_204", "expect": [204], "label": "Google generate_204" }, + { "kind": "tcp", "host": "1.1.1.1", "port": 443, "label": "TCP 1.1.1.1:443" } + ] + }, + { + "id": "telegram", + "title": "Telegram", + "group": "messenger", + "description": "Веб-версия, Bot API и основные домены Telegram.", + "targets": [ + { "kind": "https", "host": "web.telegram.org", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "api.telegram.org", "path": "/", "expect": [200, 302, 404] }, + { "kind": "https", "host": "core.telegram.org", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "t.me", "path": "/", "expect": [200, 301, 302] } + ] + }, + { + "id": "instagram", + "title": "Instagram", + "group": "social", + "description": "Веб-фронт, приватное API приложения и CDN с картинками и видео.", + "targets": [ + { "kind": "https", "host": "www.instagram.com", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "i.instagram.com", "path": "/", "expect": [200, 301, 302, 400, 403, 404] }, + { "kind": "https", "host": "graph.instagram.com", "path": "/", "expect": [200, 400, 401, 403, 404] }, + { "kind": "https", "host": "scontent.cdninstagram.com", "path": "/", "expect": [200, 204, 400, 403, 404], "label": "CDN scontent.cdninstagram.com" }, + { "kind": "https", "host": "static.cdninstagram.com", "path": "/", "expect": [200, 400, 403, 404], "optional": true } + ] + }, + { + "id": "youtube", + "title": "YouTube", + "group": "video", + "description": "Сайт, API плеера, превью и раздача самого видео с googlevideo.", + "targets": [ + { "kind": "https", "host": "www.youtube.com", "path": "/generate_204", "expect": [204] }, + { "kind": "https", "host": "www.youtube.com", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "youtubei.googleapis.com", "path": "/", "expect": [200, 400, 403, 404, 405], "label": "API плеера" }, + { "kind": "https", "host": "i.ytimg.com", "path": "/", "expect": [200, 400, 403, 404], "label": "Превью i.ytimg.com" }, + { "kind": "https", "host": "redirector.googlevideo.com", "path": "/", "expect": [200, 204, 400, 403, 404], "optional": true, "label": "Раздача видео googlevideo" } + ] + }, + { + "id": "tiktok", + "title": "TikTok", + "group": "video", + "description": "Веб-версия, API приложения и CDN с видео и превью.", + "targets": [ + { "kind": "https", "host": "www.tiktok.com", "path": "/", "expect": [200, 301, 302, 403] }, + { "kind": "https", "host": "api16-normal-c-useast1a.tiktokv.com", "path": "/", "expect": [200, 400, 403, 404], "label": "API приложения" }, + { "kind": "https", "host": "p16-sign-va.tiktokcdn.com", "path": "/", "expect": [200, 400, 403, 404], "label": "CDN превью" }, + { "kind": "https", "host": "v16-webapp-prime.tiktok.com", "path": "/", "expect": [200, 400, 403, 404], "optional": true, "label": "Раздача видео" }, + { "kind": "https", "host": "webcast.tiktok.com", "path": "/", "expect": [200, 400, 403, 404], "optional": true, "label": "Прямые эфиры" } + ] + }, + { + "id": "chatgpt", + "title": "ChatGPT / OpenAI", + "group": "ai", + "description": "Веб-интерфейс, API и статика. Требует, чтобы выходной IP не был в бане OpenAI.", + "targets": [ + { "kind": "https", "host": "chatgpt.com", "path": "/", "expect": [200, 301, 302, 307, 403] }, + { "kind": "https", "host": "api.openai.com", "path": "/v1/models", "expect": [401, 403], "label": "api.openai.com (ожидается 401)" }, + { "kind": "https", "host": "ab.chatgpt.com", "path": "/", "expect": [200, 400, 403, 404], "optional": true }, + { "kind": "https", "host": "cdn.oaistatic.com", "path": "/", "expect": [200, 400, 403, 404], "optional": true } + ] + }, + { + "id": "gemini", + "title": "Gemini / Google AI", + "group": "ai", + "description": "Веб-интерфейс Gemini, AI Studio и API. Геодоступность API проверяется отдельно по ответу Google; для неё укажите свой API-ключ в настройках карточки.", + "targets": [ + { "kind": "https", "host": "gemini.google.com", "path": "/", "expect": [200, 301, 302, 307], "label": "gemini.google.com" }, + { "kind": "https", "host": "aistudio.google.com", "path": "/", "expect": [200, 301, 302, 307, 403], "label": "aistudio.google.com" }, + { "kind": "gemini_geo", "host": "generativelanguage.googleapis.com", "path": "/v1beta/models", "label": "Геодоступность Gemini API" }, + { "kind": "https", "host": "ai.google.dev", "path": "/", "expect": [200, 301, 302, 404], "optional": true, "label": "Документация ai.google.dev" }, + { "kind": "https", "host": "notebooklm.google.com", "path": "/", "expect": [200, 301, 302, 307, 403], "optional": true, "label": "NotebookLM" } + ] + }, + { + "id": "discord", + "title": "Discord", + "group": "messenger", + "description": "Сайт, WebSocket-шлюз и CDN. Голосовой UDP-трафик этой проверкой не покрывается.", + "targets": [ + { "kind": "https", "host": "discord.com", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "gateway.discord.gg", "path": "/", "expect": [200, 400, 404, 426], "label": "WebSocket-шлюз" }, + { "kind": "https", "host": "cdn.discordapp.com", "path": "/", "expect": [200, 400, 403, 404] }, + { "kind": "https", "host": "media.discordapp.net", "path": "/", "expect": [200, 400, 401, 403, 404], "optional": true } + ] + }, + { + "id": "x", + "title": "X (Twitter)", + "group": "social", + "description": "Сайт, API и медиа-CDN.", + "targets": [ + { "kind": "https", "host": "x.com", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "api.x.com", "path": "/", "expect": [200, 400, 403, 404] }, + { "kind": "https", "host": "abs.twimg.com", "path": "/", "expect": [200, 400, 403, 404] }, + { "kind": "https", "host": "video.twimg.com", "path": "/", "expect": [200, 400, 403, 404], "optional": true } + ] + }, + { + "id": "facebook", + "title": "Facebook", + "group": "social", + "description": "Веб-фронт, Graph API и CDN.", + "targets": [ + { "kind": "https", "host": "www.facebook.com", "path": "/", "expect": [200, 301, 302, 400] }, + { "kind": "https", "host": "graph.facebook.com", "path": "/", "expect": [200, 400, 403] }, + { "kind": "https", "host": "scontent.xx.fbcdn.net", "path": "/", "expect": [200, 204, 400, 403, 404], "optional": true } + ] + }, + { + "id": "whatsapp", + "title": "WhatsApp", + "group": "messenger", + "description": "Веб-версия, медиа-серверы и XMPP-порт клиента.", + "targets": [ + { "kind": "https", "host": "web.whatsapp.com", "path": "/", "expect": [200, 301, 302, 400] }, + { "kind": "https", "host": "mmg.whatsapp.net", "path": "/", "expect": [200, 400, 403, 404] }, + { "kind": "tcp", "host": "g.whatsapp.net", "port": 5222, "label": "XMPP g.whatsapp.net:5222" }, + { "kind": "tcp", "host": "g.whatsapp.net", "port": 443, "optional": true } + ] + }, + { + "id": "netflix", + "title": "Netflix", + "group": "video", + "description": "Сайт, публичная статика и раздающая инфраструктура Netflix. Проверка показывает доступность сети без входа в аккаунт.", + "targets": [ + { "kind": "https", "host": "www.netflix.com", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "assets.nflxext.com", "path": "/", "expect": [200, 301, 302, 403, 404], "label": "Публичная статика nflxext.com" }, + { "kind": "https", "host": "occ-0-1360-1361.1.nflxso.net", "path": "/", "expect": [200, 400, 403, 404, 422], "optional": true, "label": "CDN nflxso.net" } + ] + }, + { + "id": "spotify", + "title": "Spotify", + "group": "music", + "description": "Веб-плеер, API и раздача аудио.", + "targets": [ + { "kind": "https", "host": "open.spotify.com", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "api.spotify.com", "path": "/v1/me", "expect": [400, 401, 403] }, + { "kind": "https", "host": "i.scdn.co", "path": "/", "expect": [200, 400, 403, 404], "optional": true } + ] + }, + { + "id": "twitch", + "title": "Twitch", + "group": "video", + "description": "Сайт, GraphQL API и выдача плейлистов стримов.", + "targets": [ + { "kind": "https", "host": "www.twitch.tv", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "gql.twitch.tv", "path": "/", "expect": [200, 400, 403, 405] }, + { "kind": "https", "host": "usher.ttvnw.net", "path": "/", "expect": [200, 400, 403, 404], "optional": true } + ] + }, + { + "id": "steam", + "title": "Steam", + "group": "games", + "description": "Магазин, API и CDN с контентом игр.", + "targets": [ + { "kind": "https", "host": "store.steampowered.com", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "api.steampowered.com", "path": "/", "expect": [200, 400, 403, 404] }, + { "kind": "https", "host": "cdn.cloudflare.steamstatic.com", "path": "/", "expect": [200, 400, 403, 404], "optional": true } + ] + }, + { + "id": "github", + "title": "GitHub", + "group": "dev", + "description": "Сайт, API и раздача файлов — важно для обновлений Forkop/Podkop и списков правил.", + "targets": [ + { "kind": "https", "host": "github.com", "path": "/", "expect": [200, 301, 302] }, + { "kind": "https", "host": "api.github.com", "path": "/", "expect": [200] }, + { "kind": "https", "host": "raw.githubusercontent.com", "path": "/", "expect": [200, 400, 403, 404] }, + { "kind": "https", "host": "objects.githubusercontent.com", "path": "/", "expect": [200, 400, 403, 404], "optional": true } + ] + }, + { + "id": "blocked_ru", + "title": "Заблокированные в РФ", + "group": "bypass", + "description": "Сайты, недоступные без обхода. Зелёный результат — прямое доказательство, что обход работает.", + "targets": [ + { "kind": "https", "host": "rutracker.org", "path": "/forum/index.php", "expect": [200, 301, 302] }, + { "kind": "https", "host": "www.linkedin.com", "path": "/", "expect": [200, 301, 302, 403, 999] }, + { "kind": "https", "host": "medium.com", "path": "/", "expect": [200, 301, 302, 403] } + ] + }, + { + "id": "udp_common", + "title": "UDP / QUIC", + "group": "network", + "description": "Двусторонняя проверка UDP через DNS-ответы и best-effort отправка QUIC.", + "targets": [ + { "kind": "udp_dns", "host": "1.1.1.1", "port": 53, "query": "example.com", "label": "Cloudflare DNS UDP :53" }, + { "kind": "udp_dns", "host": "8.8.8.8", "port": 53, "query": "example.com", "label": "Google DNS UDP :53", "optional": true }, + { "kind": "udp", "host": "cloudflare.com", "port": 443, "label": "Cloudflare QUIC :443" }, + { "kind": "udp", "host": "google.com", "port": 443, "label": "Google QUIC :443" }, + { "kind": "udp", "host": "g.whatsapp.net", "port": 443, "label": "WhatsApp UDP :443", "optional": true } + ] + } + ] +}