Compare commits

...

4 Commits

Author SHA1 Message Date
renovate[bot]
4ec7aa142a
chore(deps): update github/gh-aw-actions action to v0.65.1 2026-03-31 16:43:49 +00:00
Tunglies
3714f0c4c8
feat: update clash_verge_service_ipc version to 2.2.0 2026-04-01 00:40:35 +08:00
Nemu-x
4e75c36097
feat: complete Russian localization (#6685) 2026-03-31 14:29:16 +00:00
Tunglies
9bcb79465c
fix: resolve frontend data race conditions in hooks
- use-system-state: convert module-level `disablingTunMode` to useRef
  to isolate state per hook instance, fix no-op clearTimeout, add
  proper effect cleanup
- use-profiles: convert forEach to for..of so selectNodeForGroup is
  properly awaited, remove fire-and-forget setTimeout around mutate
- use-clash: add useLockFn to patchInfo for concurrency safety
2026-03-31 20:26:34 +08:00
9 changed files with 225 additions and 211 deletions

View File

@ -65,7 +65,7 @@ jobs:
title: ${{ steps.sanitized.outputs.title }} title: ${{ steps.sanitized.outputs.title }}
steps: steps:
- name: Setup Scripts - name: Setup Scripts
uses: github/gh-aw-actions/setup@dc2e3faa962b8cd6219ca125f4e3989bf731e535 # v0.64.4 uses: github/gh-aw-actions/setup@d478fe1c5f5e4030bb8a29a64a68aef198507267 # v0.65.1
with: with:
destination: ${{ runner.temp }}/gh-aw/actions destination: ${{ runner.temp }}/gh-aw/actions
- name: Generate agentic run info - name: Generate agentic run info
@ -277,7 +277,7 @@ jobs:
output_types: ${{ steps.collect_output.outputs.output_types }} output_types: ${{ steps.collect_output.outputs.output_types }}
steps: steps:
- name: Setup Scripts - name: Setup Scripts
uses: github/gh-aw-actions/setup@dc2e3faa962b8cd6219ca125f4e3989bf731e535 # v0.64.4 uses: github/gh-aw-actions/setup@d478fe1c5f5e4030bb8a29a64a68aef198507267 # v0.65.1
with: with:
destination: ${{ runner.temp }}/gh-aw/actions destination: ${{ runner.temp }}/gh-aw/actions
- name: Set runtime paths - name: Set runtime paths
@ -800,7 +800,7 @@ jobs:
total_count: ${{ steps.missing_tool.outputs.total_count }} total_count: ${{ steps.missing_tool.outputs.total_count }}
steps: steps:
- name: Setup Scripts - name: Setup Scripts
uses: github/gh-aw-actions/setup@dc2e3faa962b8cd6219ca125f4e3989bf731e535 # v0.64.4 uses: github/gh-aw-actions/setup@d478fe1c5f5e4030bb8a29a64a68aef198507267 # v0.65.1
with: with:
destination: ${{ runner.temp }}/gh-aw/actions destination: ${{ runner.temp }}/gh-aw/actions
- name: Download agent output artifact - name: Download agent output artifact
@ -895,7 +895,7 @@ jobs:
detection_success: ${{ steps.detection_conclusion.outputs.success }} detection_success: ${{ steps.detection_conclusion.outputs.success }}
steps: steps:
- name: Setup Scripts - name: Setup Scripts
uses: github/gh-aw-actions/setup@dc2e3faa962b8cd6219ca125f4e3989bf731e535 # v0.64.4 uses: github/gh-aw-actions/setup@d478fe1c5f5e4030bb8a29a64a68aef198507267 # v0.65.1
with: with:
destination: ${{ runner.temp }}/gh-aw/actions destination: ${{ runner.temp }}/gh-aw/actions
- name: Download agent output artifact - name: Download agent output artifact
@ -1056,7 +1056,7 @@ jobs:
process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
steps: steps:
- name: Setup Scripts - name: Setup Scripts
uses: github/gh-aw-actions/setup@dc2e3faa962b8cd6219ca125f4e3989bf731e535 # v0.64.4 uses: github/gh-aw-actions/setup@d478fe1c5f5e4030bb8a29a64a68aef198507267 # v0.65.1
with: with:
destination: ${{ runner.temp }}/gh-aw/actions destination: ${{ runner.temp }}/gh-aw/actions
- name: Download agent output artifact - name: Download agent output artifact

34
Cargo.lock generated
View File

@ -1242,8 +1242,8 @@ dependencies = [
[[package]] [[package]]
name = "clash_verge_service_ipc" name = "clash_verge_service_ipc"
version = "2.1.3" version = "2.2.0"
source = "git+https://github.com/clash-verge-rev/clash-verge-service-ipc#360f205a12c6c2fe229d09252a41e3253ed6be3e" source = "git+https://github.com/clash-verge-rev/clash-verge-service-ipc#b73568a9ecc9e62577e9ce81a123b554f06a9fb3"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"compact_str", "compact_str",
@ -2074,7 +2074,7 @@ dependencies = [
"libc", "libc",
"option-ext", "option-ext",
"redox_users 0.5.2", "redox_users 0.5.2",
"windows-sys 0.61.2", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -2347,7 +2347,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.61.2", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -3483,7 +3483,7 @@ dependencies = [
"libc", "libc",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"socket2 0.6.3", "socket2 0.5.10",
"system-configuration", "system-configuration",
"tokio", "tokio",
"tower-service", "tower-service",
@ -3808,7 +3808,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
dependencies = [ dependencies = [
"hermit-abi 0.5.2", "hermit-abi 0.5.2",
"libc", "libc",
"windows-sys 0.61.2", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -4576,7 +4576,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -4893,7 +4893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.61.2", "windows-sys 0.45.0",
] ]
[[package]] [[package]]
@ -5687,7 +5687,7 @@ dependencies = [
"quinn-udp", "quinn-udp",
"rustc-hash", "rustc-hash",
"rustls", "rustls",
"socket2 0.6.3", "socket2 0.5.10",
"thiserror 2.0.18", "thiserror 2.0.18",
"tokio", "tokio",
"tracing", "tracing",
@ -5725,7 +5725,7 @@ dependencies = [
"cfg_aliases", "cfg_aliases",
"libc", "libc",
"once_cell", "once_cell",
"socket2 0.6.3", "socket2 0.5.10",
"tracing", "tracing",
"windows-sys 0.60.2", "windows-sys 0.60.2",
] ]
@ -6344,7 +6344,7 @@ dependencies = [
"errno", "errno",
"libc", "libc",
"linux-raw-sys 0.12.1", "linux-raw-sys 0.12.1",
"windows-sys 0.61.2", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -6403,7 +6403,7 @@ dependencies = [
"security-framework", "security-framework",
"security-framework-sys", "security-framework-sys",
"webpki-root-certs", "webpki-root-certs",
"windows-sys 0.61.2", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -7050,7 +7050,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.61.2", "windows-sys 0.60.2",
] ]
[[package]] [[package]]
@ -7955,7 +7955,7 @@ dependencies = [
"getrandom 0.4.2", "getrandom 0.4.2",
"once_cell", "once_cell",
"rustix 1.1.4", "rustix 1.1.4",
"windows-sys 0.61.2", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -8779,7 +8779,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
dependencies = [ dependencies = [
"memoffset", "memoffset",
"tempfile", "tempfile",
"windows-sys 0.61.2", "windows-sys 0.60.2",
] ]
[[package]] [[package]]
@ -9421,7 +9421,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.48.0",
] ]
[[package]] [[package]]
@ -10025,7 +10025,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10" checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"windows-sys 0.61.2", "windows-sys 0.59.0",
] ]
[[package]] [[package]]

View File

@ -98,7 +98,7 @@ tauri-plugin-devtools = { version = "2.0.1" }
tauri-plugin-mihomo = { git = "https://github.com/clash-verge-rev/tauri-plugin-mihomo", branch = "revert" } tauri-plugin-mihomo = { git = "https://github.com/clash-verge-rev/tauri-plugin-mihomo", branch = "revert" }
clash_verge_logger = { git = "https://github.com/clash-verge-rev/clash-verge-logger" } clash_verge_logger = { git = "https://github.com/clash-verge-rev/clash-verge-logger" }
async-trait = "0.1.89" async-trait = "0.1.89"
clash_verge_service_ipc = { version = "2.1.3", features = [ clash_verge_service_ipc = { version = "2.2.0", features = [
"client", "client",
], git = "https://github.com/clash-verge-rev/clash-verge-service-ipc" } ], git = "https://github.com/clash-verge-rev/clash-verge-service-ipc" }
arc-swap = "1.9.0" arc-swap = "1.9.0"

View File

@ -87,7 +87,7 @@ export const useClashInfo = () => {
getClashInfo, getClashInfo,
) )
const patchInfo = async (patch: ClashInfoPatch) => { const patchInfo = useLockFn(async (patch: ClashInfoPatch) => {
if (!hasClashInfoPayload(patch)) return if (!hasClashInfoPayload(patch)) return
validatePorts(patch) validatePorts(patch)
@ -95,7 +95,7 @@ export const useClashInfo = () => {
await patchClashConfig(patch) await patchClashConfig(patch)
mutateInfo() mutateInfo()
mutate('getClashConfig') mutate('getClashConfig')
} })
return { return {
clashInfo, clashInfo,

View File

@ -120,9 +120,9 @@ export const useProfiles = () => {
]) ])
// 处理所有代理组 // 处理所有代理组
;[global, ...groups].forEach((group) => { for (const group of [global, ...groups]) {
if (!group) { if (!group) {
return continue
} }
const { type, name, now } = group const { type, name, now } = group
@ -134,14 +134,14 @@ export const useProfiles = () => {
const preferredProxy = now ? now : savedProxy const preferredProxy = now ? now : savedProxy
newSelected.push({ name, now: preferredProxy }) newSelected.push({ name, now: preferredProxy })
} }
return continue
} }
if (savedProxy == null) { if (savedProxy == null) {
if (now != null) { if (now != null) {
newSelected.push({ name, now }) newSelected.push({ name, now })
} }
return continue
} }
const existsInGroup = availableProxies.some((proxy) => { const existsInGroup = availableProxies.some((proxy) => {
@ -158,7 +158,7 @@ export const useProfiles = () => {
) )
hasChange = true hasChange = true
newSelected.push({ name, now: now ?? savedProxy }) newSelected.push({ name, now: now ?? savedProxy })
return continue
} }
if (savedProxy !== now) { if (savedProxy !== now) {
@ -166,11 +166,18 @@ export const useProfiles = () => {
`[ActivateSelected] 需要切换代理组 ${name}: ${now} -> ${savedProxy}`, `[ActivateSelected] 需要切换代理组 ${name}: ${now} -> ${savedProxy}`,
) )
hasChange = true hasChange = true
selectNodeForGroup(name, savedProxy) try {
await selectNodeForGroup(name, savedProxy)
} catch (error: any) {
console.warn(
`[ActivateSelected] 切换代理组 ${name} 失败:`,
error.message,
)
}
} }
newSelected.push({ name, now: savedProxy }) newSelected.push({ name, now: savedProxy })
}) }
if (!hasChange) { if (!hasChange) {
debugLog('[ActivateSelected] 所有代理选择已经是目标状态,无需更新') debugLog('[ActivateSelected] 所有代理选择已经是目标状态,无需更新')
@ -183,9 +190,7 @@ export const useProfiles = () => {
await patchProfile(profileData.current!, { selected: newSelected }) await patchProfile(profileData.current!, { selected: newSelected })
debugLog('[ActivateSelected] 代理选择配置保存成功') debugLog('[ActivateSelected] 代理选择配置保存成功')
setTimeout(() => { await mutate('getProxies', calcuProxies())
mutate('getProxies', calcuProxies())
}, 100)
} catch (error: any) { } catch (error: any) {
console.error('[ActivateSelected] 保存代理选择配置失败:', error.message) console.error('[ActivateSelected] 保存代理选择配置失败:', error.message)
} }

View File

@ -1,4 +1,4 @@
import { useEffect } from 'react' import { useEffect, useRef } from 'react'
import useSWR from 'swr' import useSWR from 'swr'
import { getRunningMode, isAdmin, isServiceAvailable } from '@/services/cmds' import { getRunningMode, isAdmin, isServiceAvailable } from '@/services/cmds'
@ -18,14 +18,13 @@ const defaultSystemState = {
isServiceOk: false, isServiceOk: false,
} as SystemState } as SystemState
let disablingTunMode = false
/** /**
* hook * hook
* *
*/ */
export function useSystemState() { export function useSystemState() {
const { verge, patchVerge } = useVerge() const { verge, patchVerge } = useVerge()
const disablingTunRef = useRef(false)
const { const {
data: systemState, data: systemState,
@ -53,16 +52,18 @@ export function useSystemState() {
const isTunModeAvailable = systemState.isAdminMode || systemState.isServiceOk const isTunModeAvailable = systemState.isAdminMode || systemState.isServiceOk
const enable_tun_mode = verge?.enable_tun_mode const enable_tun_mode = verge?.enable_tun_mode
const cooldownTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
useEffect(() => { useEffect(() => {
if (enable_tun_mode === undefined) return if (enable_tun_mode === undefined) return
if ( if (
!disablingTunMode && !disablingTunRef.current &&
enable_tun_mode && enable_tun_mode &&
!isTunModeAvailable && !isTunModeAvailable &&
!isLoading !isLoading
) { ) {
disablingTunMode = true disablingTunRef.current = true
patchVerge({ enable_tun_mode: false }) patchVerge({ enable_tun_mode: false })
.then(() => { .then(() => {
showNotice.info( showNotice.info(
@ -76,13 +77,21 @@ export function useSystemState() {
) )
}) })
.finally(() => { .finally(() => {
const tid = setTimeout(() => { // 避免 verge 数据更新不及时导致重复执行关闭 Tun 模式
// 避免 verge 数据更新不及时导致重复执行关闭 Tun 模式 cooldownTimerRef.current = setTimeout(() => {
disablingTunMode = false disablingTunRef.current = false
clearTimeout(tid) cooldownTimerRef.current = null
}, 1000) }, 1000)
}) })
} }
return () => {
if (cooldownTimerRef.current != null) {
clearTimeout(cooldownTimerRef.current)
cooldownTimerRef.current = null
disablingTunRef.current = false
}
}
}, [enable_tun_mode, isTunModeAvailable, patchVerge, isLoading]) }, [enable_tun_mode, isTunModeAvailable, patchVerge, isLoading])
return { return {

View File

@ -13,11 +13,11 @@
"feedback": { "feedback": {
"notifications": { "notifications": {
"provider": { "provider": {
"updateSuccess": "{{name}} updated successfully", "updateSuccess": "{{name}} успешно обновлён",
"updateFailed": "Failed to update {{name}}: {{message}}", "updateFailed": "Не удалось обновить {{name}}: {{message}}",
"genericError": "Update failed: {{message}}", "genericError": "Ошибка обновления: {{message}}",
"none": "No providers available to update", "none": "Нет доступных провайдеров для обновления",
"allUpdated": "All providers updated successfully" "allUpdated": "Все провайдеры успешно обновлены"
} }
} }
}, },
@ -30,7 +30,7 @@
"proxyPolicy": "Политика прокси" "proxyPolicy": "Политика прокси"
}, },
"toggles": { "toggles": {
"noResolve": "Без разрешения" "noResolve": "Без DNS-разрешения"
}, },
"actions": { "actions": {
"prependRule": "Добавить правило в начало", "prependRule": "Добавить правило в начало",

View File

@ -15,7 +15,7 @@
"systemProxy": "Системный прокси" "systemProxy": "Системный прокси"
}, },
"tooltips": { "tooltips": {
"silentStart": "Запускать программу в фоновом режиме без отображения панели" "silentStart": "Запускать программу в фоновом режиме без отображения окна"
}, },
"fields": { "fields": {
"autoLaunch": "Автозапуск", "autoLaunch": "Автозапуск",
@ -23,20 +23,20 @@
}, },
"notifications": { "notifications": {
"tunMode": { "tunMode": {
"autoDisabled": "TUN Mode automatically disabled due to service unavailable", "autoDisabled": "Режим TUN автоматически отключен: служба недоступна",
"autoDisableFailed": "Failed to disable TUN Mode automatically" "autoDisableFailed": "Не удалось автоматически отключить режим TUN"
} }
} }
}, },
"proxyControl": { "proxyControl": {
"tooltips": { "tooltips": {
"systemProxy": "Разрешить изменение настроек прокси-сервера операционной системы. Если разрешение не удастся, измените настройки прокси-сервера операционной системы вручную", "systemProxy": "Разрешить изменение настроек прокси-сервера операционной системы. Если разрешение не удастся, измените настройки прокси-сервера операционной системы вручную",
"tunMode": "Режим Tun: захватывает весь системный трафик, при включении нет необходимости включать системный прокси-сервер.", "tunMode": "Режим TUN перехватывает весь системный трафик. При его включении нет необходимости включать системный прокси-сервер.",
"tunUnavailable": "TUN requires Service Mode or Admin Mode" "tunUnavailable": "Для TUN требуется режим службы или права администратора"
}, },
"actions": { "actions": {
"installService": "Установить службу", "installService": "Установить службу",
"uninstallService": "Uninstall Service" "uninstallService": "Удалить службу"
}, },
"fields": { "fields": {
"systemProxy": "Системный прокси", "systemProxy": "Системный прокси",
@ -66,7 +66,7 @@
} }
}, },
"externalCors": { "externalCors": {
"title": "Конфигурация внешнего CORS", "title": "Настройка внешнего CORS",
"fields": { "fields": {
"allowPrivateNetwork": "Разрешить доступ к частной сети", "allowPrivateNetwork": "Разрешить доступ к частной сети",
"allowedOrigins": "Разрешённые источники" "allowedOrigins": "Разрешённые источники"
@ -85,9 +85,9 @@
} }
}, },
"appearance": { "appearance": {
"light": "Light", "light": "Светлая",
"dark": "Dark", "dark": "Тёмная",
"system": "System" "system": "Системная"
}, },
"clash": { "clash": {
"title": "Настройки Clash", "title": "Настройки Clash",
@ -102,7 +102,7 @@
"external": "Внешний контроллер", "external": "Внешний контроллер",
"webUI": "Веб-интерфейс", "webUI": "Веб-интерфейс",
"clashCore": "Ядро Clash", "clashCore": "Ядро Clash",
"openUwpTool": "Открыть UWP инструмент", "openUwpTool": "Открыть инструмент UWP",
"updateGeoData": "Обновить GeoData", "updateGeoData": "Обновить GeoData",
"tunnels": { "tunnels": {
"title": "Управление туннелями", "title": "Управление туннелями",
@ -131,17 +131,17 @@
}, },
"tooltips": { "tooltips": {
"networkInterface": "Сетевой интерфейс", "networkInterface": "Сетевой интерфейс",
"unifiedDelay": "Когда унифицированная(точная) задержка включена, будут выполнены два теста задержки, чтобы устранить различия в задержке между разными типами узлов, вызванные подтверждением соединения и т. д", "unifiedDelay": "Когда точная задержка включена, выполняются два теста задержки, чтобы устранить различия между разными типами узлов, вызванные подтверждением соединения и другими факторами",
"logLevel": "Это действует только на файлы журнала ядра в служебном файле в каталоге журналов.", "logLevel": "Это влияет только на файлы журнала ядра в служебном файле в каталоге логов.",
"openUwpTool": "С Windows 8 приложения UWP (такие как Microsoft Store) ограничены в прямом доступе к сетевым службам локального хоста, и этот инструмент позволяет обойти это ограничение" "openUwpTool": "С Windows 8 приложения UWP (такие как Microsoft Store) ограничены в прямом доступе к сетевым службам локального хоста, и этот инструмент позволяет обойти это ограничение"
}, },
"options": { "options": {
"logLevel": { "logLevel": {
"debug": "Debug", "debug": "Отладка",
"info": "Info", "info": "Информация",
"warning": "Warn", "warning": "Предупреждение",
"error": "Error", "error": "Ошибка",
"silent": "Silent" "silent": "Без вывода"
} }
} }
} }
@ -175,26 +175,26 @@
"advanced": { "advanced": {
"title": "Расширенные настройки Verge", "title": "Расширенные настройки Verge",
"tooltips": { "tooltips": {
"backupInfo": "Поддерживает файлы конфигурации резервного копирования WebDAV", "backupInfo": "Поддерживается резервное копирование файлов конфигурации через WebDAV",
"openConfDir": "Если программное обеспечение работает неправильно, сделайте резервную копию и удалите все файлы в этой папке, а затем перезапустите ПО", "openConfDir": "Если программа работает неправильно, сделайте резервную копию и удалите все файлы в этой папке, затем перезапустите приложение",
"liteMode": "Режим, в котором работает только ядро Clash, а графический интрефейс закрыт" "liteMode": "Режим, в котором работает только ядро Clash, а графический интерфейс закрыт"
}, },
"actions": { "actions": {
"copyVersion": "Copy Version" "copyVersion": "Копировать версию"
}, },
"notifications": { "notifications": {
"latestVersion": "Обновление не требуется", "latestVersion": "Обновление не требуется",
"versionCopied": "Version copied to clipboard" "versionCopied": "Версия скопирована в буфер обмена"
}, },
"fields": { "fields": {
"backupSetting": "Настройки резервного копирования", "backupSetting": "Настройки резервного копирования",
"runtimeConfig": "Используемый конфиг", "runtimeConfig": "Используемая конфигурация",
"openConfDir": "Открыть папку приложения", "openConfDir": "Открыть папку приложения",
"openCoreDir": "Открыть папку ядра", "openCoreDir": "Открыть папку ядра",
"openLogsDir": "Открыть папку логов", "openLogsDir": "Открыть папку логов",
"checkUpdates": "Проверить обновления", "checkUpdates": "Проверить обновления",
"openDevTools": "Открыть Dev Tools", "openDevTools": "Открыть инструменты разработчика",
"liteModeSettings": "Настройки LightWeight Mode", "liteModeSettings": "Настройки режима LightWeight",
"exit": "Выход", "exit": "Выход",
"exportDiagnostics": "Экспорт диагностической информации", "exportDiagnostics": "Экспорт диагностической информации",
"vergeVersion": "Версия Clash Verge Rev" "vergeVersion": "Версия Clash Verge Rev"
@ -205,8 +205,8 @@
"fields": { "fields": {
"primaryColor": "Основной цвет", "primaryColor": "Основной цвет",
"secondaryColor": "Вторичный цвет", "secondaryColor": "Вторичный цвет",
"primaryText": "Первичный текст", "primaryText": "Основной текст",
"secondaryText": "Вторичный текст", "secondaryText": "Дополнительный текст",
"infoColor": "Информационный цвет", "infoColor": "Информационный цвет",
"warningColor": "Цвет предупреждения", "warningColor": "Цвет предупреждения",
"errorColor": "Цвет ошибки", "errorColor": "Цвет ошибки",
@ -215,27 +215,27 @@
"cssInjection": "Внедрение CSS" "cssInjection": "Внедрение CSS"
}, },
"actions": { "actions": {
"editCss": "Edit CSS" "editCss": "Редактировать CSS"
}, },
"dialogs": { "dialogs": {
"editCssTitle": "Edit CSS" "editCssTitle": "Редактирование CSS"
} }
}, },
"layout": { "layout": {
"title": "Настройки раскладки", "title": "Настройки раскладки",
"fields": { "fields": {
"preferSystemTitlebar": "Prefer System Titlebar", "preferSystemTitlebar": "Использовать системную панель заголовка",
"trafficGraph": "График трафика", "trafficGraph": "График трафика",
"memoryUsage": "Использование памяти", "memoryUsage": "Использование памяти",
"proxyGroupIcon": "Иконка Группы прокси", "proxyGroupIcon": "Значок группы прокси",
"toastPosition": "Расположение уведомлений", "toastPosition": "Расположение уведомлений",
"hoverNavigator": "Hover Jump Navigator", "hoverNavigator": "Навигация по алфавиту при наведении",
"hoverNavigatorDelay": "Hover Jump Navigator Delay", "hoverNavigatorDelay": "Задержка навигации при наведении",
"navIcon": "Иконки навигации", "navIcon": "Иконки навигации",
"collapseNavBar": "Свернуть панель навигации", "collapseNavBar": "Свернуть панель навигации",
"trayIcon": "Иконка в трее", "trayIcon": "Значок в трее",
"proxyGroupsDisplayMode": "Proxy Groups Display Mode", "proxyGroupsDisplayMode": "Режим отображения групп прокси",
"showOutboundModesInline": "Show Outbound Modes Inline", "showOutboundModesInline": "Показывать режимы исходящих соединений в строку",
"commonTrayIcon": "Общий значок в трее", "commonTrayIcon": "Общий значок в трее",
"systemProxyTrayIcon": "Значок системного прокси в трее", "systemProxyTrayIcon": "Значок системного прокси в трее",
"tunTrayIcon": "Значок TUN в трее", "tunTrayIcon": "Значок TUN в трее",
@ -244,8 +244,8 @@
"pauseRenderTrafficStatsOnBlur": "При потере фокуса приостанавливать отрисовку статистики трафика" "pauseRenderTrafficStatsOnBlur": "При потере фокуса приостанавливать отрисовку статистики трафика"
}, },
"tooltips": { "tooltips": {
"hoverNavigator": "Automatically scroll to the corresponding proxy group when hovering over alphabet letters", "hoverNavigator": "Автоматически прокручивает к группе прокси при наведении на буквы",
"hoverNavigatorDelay": "Delay before auto scrolling when hovering, in milliseconds" "hoverNavigatorDelay": "Задержка перед прокруткой при наведении (в миллисекундах)"
}, },
"options": { "options": {
"icon": { "icon": {
@ -260,9 +260,9 @@
"bottomRight": "Снизу справа" "bottomRight": "Снизу справа"
}, },
"proxyGroupsDisplayMode": { "proxyGroupsDisplayMode": {
"default": "Default", "default": "По умолчанию",
"inline": "Inline", "inline": "В строку",
"disable": "Disable" "disable": "Отключено"
} }
} }
} }
@ -273,18 +273,18 @@
"title": "Настройка порта", "title": "Настройка порта",
"fields": { "fields": {
"mixed": "Смешанный прокси-порт", "mixed": "Смешанный прокси-порт",
"socks": "Порт Socks-прокси", "socks": "Порт SOCKS-прокси",
"http": "Порт Http(s)-прокси", "http": "Порт HTTP(S)-прокси",
"redir": "Порт прозрачного прокси Redir", "redir": "Порт прозрачного прокси Redir",
"tproxy": "Порт прозрачного прокси Tproxy" "tproxy": "Порт прозрачного прокси TProxy"
}, },
"actions": { "actions": {
"random": "Случайный порт" "random": "Случайный порт"
}, },
"messages": { "messages": {
"portInUse": "Port {{port}} is already in use", "portInUse": "Порт {{port}} уже используется",
"saved": "Port settings saved", "saved": "Настройки портов сохранены",
"saveFailed": "Failed to save port settings" "saveFailed": "Не удалось сохранить настройки портов"
} }
}, },
"clashCore": { "clashCore": {
@ -294,44 +294,44 @@
} }
}, },
"liteMode": { "liteMode": {
"title": "Настройки LightWeight Mode", "title": "Настройка режима LightWeight",
"actions": { "actions": {
"enterNow": "Войти в LightWeight Mode" "enterNow": "Войти в режим LightWeight"
}, },
"toggles": { "toggles": {
"autoEnter": "Автоматический вход в LightWeight Mode" "autoEnter": "Автоматически входить в режим LightWeight"
}, },
"tooltips": { "tooltips": {
"autoEnter": "Автоматически включать LightWeight Mode, если окно закрыто определенное время" "autoEnter": "Автоматически включать режим LightWeight, если окно закрыто определенное время"
}, },
"fields": { "fields": {
"delay": "Задержка включения LightWeight Mode" "delay": "Задержка включения режима LightWeight"
}, },
"messages": { "messages": {
"autoEnterHint": ри закрытии окна LightWeight Mode будет автоматически активирован через {{n}} минут" "autoEnterHint": осле закрытия окна режим LightWeight будет автоматически активирован через {{n}} минут"
} }
}, },
"backup": { "backup": {
"title": "Настройки резервного копирования", "title": "Настройки резервного копирования",
"tabs": { "tabs": {
"local": "Local backup", "local": "Локальное резервное копирование",
"webdav": "WebDAV backup" "webdav": "Резервное копирование WebDAV"
}, },
"actions": { "actions": {
"selectTarget": "Select backup target", "selectTarget": "Выбрать место сохранения",
"backup": "Резервное копирование", "backup": "Резервное копирование",
"export": "Export", "export": "Экспорт",
"exportBackup": "Export Backup", "exportBackup": "Экспорт резервной копии",
"importBackup": "Import Backup", "importBackup": "Импорт резервной копии",
"deleteBackup": "Удалить резервную копию", "deleteBackup": "Удалить резервную копию",
"restore": "Восстановить", "restore": "Восстановить",
"restoreBackup": "Восстановить резервную копию", "restoreBackup": "Восстановить резервную копию",
"viewHistory": "View history" "viewHistory": "Просмотр истории"
}, },
"fields": { "fields": {
"webdavUrl": "URL-адрес сервера WebDAV http(s)://", "webdavUrl": "URL-адрес сервера WebDAV http(s)://",
"username": "Имя пользователя", "username": "Имя пользователя",
"info": "Backups are stored locally in the application data directory. Use the list below to restore or delete backups." "info": "Резервные копии хранятся локально в каталоге данных приложения. Используйте список ниже, чтобы восстановить или удалить резервные копии."
}, },
"messages": { "messages": {
"webdavUrlRequired": "URL-адрес WebDAV не может быть пустым", "webdavUrlRequired": "URL-адрес WebDAV не может быть пустым",
@ -342,60 +342,60 @@
"webdavConfigSaveFailed": "Не удалось сохранить конфигурацию WebDAV: {{error}}", "webdavConfigSaveFailed": "Не удалось сохранить конфигурацию WebDAV: {{error}}",
"backupCreated": "Резервная копия успешно создана", "backupCreated": "Резервная копия успешно создана",
"backupFailed": "Ошибка резервного копирования: {{error}}", "backupFailed": "Ошибка резервного копирования: {{error}}",
"localBackupCreated": "Local backup created successfully", "localBackupCreated": "Локальная резервная копия создана",
"localBackupFailed": "Local backup failed", "localBackupFailed": "Ошибка создания локальной резервной копии",
"restoreSuccess": "Восстановление успешно выполнено, приложение перезапустится через 1 секунду", "restoreSuccess": "Восстановление успешно выполнено, приложение перезапустится через 1 секунду",
"localBackupExported": "Local backup exported successfully", "localBackupExported": "Локальная резервная копия экспортирована",
"localBackupExportFailed": "Failed to export local backup", "localBackupExportFailed": "Не удалось экспортировать резервную копию",
"localBackupImported": "Local backup imported successfully", "localBackupImported": "Локальная резервная копия импортирована",
"localBackupImportFailed": "Не удалось импортировать локальную резервную копию: {{error}}", "localBackupImportFailed": "Не удалось импортировать локальную резервную копию: {{error}}",
"webdavRefreshSuccess": "WebDAV refresh succeeded", "webdavRefreshSuccess": "Список WebDAV успешно обновлён",
"webdavRefreshFailed": "WebDAV refresh failed: {{error}}", "webdavRefreshFailed": "Не удалось обновить список WebDAV: {{error}}",
"confirmDelete": "Вы уверены, что хотите удалить этот файл резервной копии?", "confirmDelete": "Вы уверены, что хотите удалить этот файл резервной копии?",
"confirmRestore": "Вы уверены, что хотите восстановить этот файл резервной копии?" "confirmRestore": "Вы уверены, что хотите восстановить этот файл резервной копии?"
}, },
"auto": { "auto": {
"title": "Automatic backup", "title": "Автоматическое резервное копирование",
"scheduleLabel": "Enable scheduled backup", "scheduleLabel": "Включить резервное копирование по расписанию",
"scheduleHelper": "Create local backups in the background at the configured interval.", "scheduleHelper": "Создавать локальные резервные копии в фоновом режиме через заданный интервал.",
"intervalLabel": "Backup frequency", "intervalLabel": "Частота резервного копирования",
"changeLabel": "Backup on critical changes", "changeLabel": "Резервное копирование при критических изменениях",
"changeHelper": "Automatically backup when Global Extend Config/Script changes.", "changeHelper": "Автоматически создавать резервную копию при изменении Global Extend Config/Script.",
"options": { "options": {
"hours": "Every {{n}} hours", "hours": "Каждые {{n}} часов",
"days": "Every {{n}} days" "days": "Каждые {{n}} дней"
} }
}, },
"manual": { "manual": {
"title": "Manual backup", "title": "Ручное резервное копирование",
"local": "Creates a snapshot on this device, stored under the app data directory.", "local": "Создаёт снимок на этом устройстве и сохраняет его в каталоге данных приложения.",
"webdav": "Upload a snapshot to your WebDAV server once credentials are set.", "webdav": "Загружает снимок на ваш сервер WebDAV после настройки учётных данных.",
"configureWebdav": "Configure WebDAV" "configureWebdav": "Настроить WebDAV"
}, },
"history": { "history": {
"title": "Backup history", "title": "История резервных копий",
"summary": "{{count}} backups • latest {{recent}}", "summary": "{{count}} резервных копий • последняя: {{recent}}",
"empty": "No backups available", "empty": "Резервные копии отсутствуют",
"unknownPlatform": "неизвестно", "unknownPlatform": "неизвестно",
"unknownTime": "Неизвестное время" "unknownTime": "Неизвестное время"
}, },
"webdav": { "webdav": {
"title": "WebDAV settings" "title": "Настройки WebDAV"
}, },
"table": { "table": {
"filename": "Имя файла", "filename": "Имя файла",
"backupTime": "Время резервного копирования", "backupTime": "Время резервного копирования",
"actions": "Действия", "actions": "Действия",
"noBackups": "Нет доступных резервных копий", "noBackups": "Нет доступных резервных копий",
"rowsPerPage": "Rows per page" "rowsPerPage": "Строк на странице"
} }
}, },
"misc": { "misc": {
"title": "Расширенные настройки", "title": "Расширенные настройки",
"fields": { "fields": {
"appLogLevel": "Уровень журнала приложения", "appLogLevel": "Уровень журнала приложения",
"appLogMaxSize": "App Log Max Size", "appLogMaxSize": "Максимальный размер журнала приложения",
"appLogMaxCount": "App Log Max Count", "appLogMaxCount": "Максимальное количество файлов журнала",
"autoCloseConnections": "Автоматическое закрытие соединений", "autoCloseConnections": "Автоматическое закрытие соединений",
"autoCheckUpdate": "Автоматическая проверка обновлений", "autoCheckUpdate": "Автоматическая проверка обновлений",
"enableBuiltinEnhanced": "Включить встроенные улучшения", "enableBuiltinEnhanced": "Включить встроенные улучшения",
@ -403,34 +403,34 @@
"autoLogClean": "Автоматическая очистка логов", "autoLogClean": "Автоматическая очистка логов",
"autoDelayDetection": "Автоматическое измерение задержки", "autoDelayDetection": "Автоматическое измерение задержки",
"autoDelayDetectionInterval": "Интервал автоматического измерения задержки", "autoDelayDetectionInterval": "Интервал автоматического измерения задержки",
"defaultLatencyTest": "Ссылка на тест задержки", "defaultLatencyTest": "URL для теста задержки",
"defaultLatencyTimeout": "Таймаут задержки по умолчанию" "defaultLatencyTimeout": "Таймаут задержки по умолчанию"
}, },
"tooltips": { "tooltips": {
"autoCloseConnections": "Закрыть установленные соединения при изменении выбора группы прокси или режима прокси", "autoCloseConnections": "Закрывать установленные соединения при изменении выбора группы прокси или режима прокси",
"enableBuiltinEnhanced": "Обработка совместимости для файла конфигурации", "enableBuiltinEnhanced": "Обработка совместимости для файла конфигурации",
"autoDelayDetection": "Периодически проверяет задержку текущего узла в фоновом режиме", "autoDelayDetection": "Периодически проверяет задержку текущего узла в фоновом режиме",
"defaultLatencyTest": "Используется только для тестирования HTTP-запросов клиента и не влияет на файл конфигурации" "defaultLatencyTest": "Используется только для тестирования HTTP-запросов клиента и не влияет на файл конфигурации"
}, },
"options": { "options": {
"proxyLayoutColumns": { "proxyLayoutColumns": {
"auto": "Авто колонки" "auto": "Автоколонки"
}, },
"autoLogClean": { "autoLogClean": {
"never": "Никогда не очищать", "never": "Никогда не очищать",
"retainDays": "Сохранять {{n}} дней" "retainDays": "Хранить {{n}} дней"
} }
} }
}, },
"update": { "update": {
"title": "New Version v{{version}}", "title": "Новая версия v{{version}}",
"actions": { "actions": {
"goToRelease": "Перейти на страницу релизов", "goToRelease": "Перейти на страницу релизов",
"update": "Обновить" "update": "Обновить"
}, },
"messages": { "messages": {
"portableError": "Портативная версия не поддерживает обновление внутри приложения, пожалуйста, скачайте и замените файлы вручную", "portableError": "Портативная версия не поддерживает обновление внутри приложения. Пожалуйста, скачайте и замените файлы вручную.",
"breakChangeError": "Это крупное обновление, которое не поддерживает обновление внутри приложения. Пожалуйста, удалите его и загрузите установочный файл вручную." "breakChangeError": "Это крупное обновление, которое не поддерживает обновление внутри приложения. Пожалуйста, удалите текущую версию и загрузите установочный файл вручную."
} }
}, },
"sysproxy": { "sysproxy": {
@ -439,21 +439,21 @@
"currentStatus": "Текущий системный прокси" "currentStatus": "Текущий системный прокси"
}, },
"fields": { "fields": {
"enableStatus": "Статус включения", "enableStatus": "Статус",
"serverAddr": "Адрес сервера: ", "serverAddr": "Адрес сервера: ",
"pacUrl": "Адрес PAC: ", "pacUrl": "Адрес PAC: ",
"proxyHost": "Хост прокси", "proxyHost": "Хост прокси",
"usePacMode": "Используйте режим PAC", "usePacMode": "Использовать режим PAC",
"proxyGuard": "Proxy Guard", "proxyGuard": "Защита прокси",
"guardDuration": "Период защиты", "guardDuration": "Период защиты",
"alwaysUseDefaultBypass": "Всегда использовать стандартное обходное решение", "alwaysUseDefaultBypass": "Всегда использовать стандартный обход",
"enableBypassCheck": "Проверять формат обхода прокси", "enableBypassCheck": "Проверять формат обхода прокси",
"proxyBypass": "Игнорируемые адреса: ", "proxyBypass": "Игнорируемые адреса: ",
"bypass": "Игнорируемые адреса: ", "bypass": "Игнорируемые адреса: ",
"pacScriptContent": "Содержание сценария PAC" "pacScriptContent": "Содержимое PAC-скрипта"
}, },
"tooltips": { "tooltips": {
"proxyGuard": "Включите эту функцию чтобы предотвратить изменение настроек прокси-сервера операционной системы другим ПО" "proxyGuard": "Включите эту функцию, чтобы предотвратить изменение настроек системного прокси другим ПО"
}, },
"messages": { "messages": {
"durationTooShort": "Продолжительность работы прокси-демона не может быть меньше 1 секунды", "durationTooShort": "Продолжительность работы прокси-демона не может быть меньше 1 секунды",
@ -468,18 +468,18 @@
"title": "Режим TUN", "title": "Режим TUN",
"fields": { "fields": {
"stack": "Стек", "stack": "Стек",
"device": "Device Name", "device": "Имя устройства",
"autoRoute": "Автоматическая маршрутизация", "autoRoute": "Автоматическая маршрутизация",
"routeExcludeAddress": "Адреса исключения маршрута", "routeExcludeAddress": "Адреса, исключённые из маршрутизации",
"strictRoute": "Строгая маршрутизация", "strictRoute": "Строгая маршрутизация",
"autoDetectInterface": "Автоопределение интерфейса", "autoDetectInterface": "Автоопределение интерфейса",
"dnsHijack": "DNS-перехват", "dnsHijack": "Перехват DNS",
"mtu": "MTU", "mtu": "MTU",
"autoRedirect": "Auto Redirect" "autoRedirect": "Автоматическое перенаправление"
}, },
"tooltips": { "tooltips": {
"dnsHijack": "Please use , to separate multiple DNS servers", "dnsHijack": "Используйте запятую для разделения нескольких DNS-серверов",
"autoRedirect": "Automatically configures nftables/iptables TCP redirects" "autoRedirect": "Автоматически настраивает перенаправление TCP через nftables/iptables"
}, },
"messages": { "messages": {
"applied": "Настройки применены", "applied": "Настройки применены",
@ -494,34 +494,34 @@
}, },
"sections": { "sections": {
"general": "Настройки DNS", "general": "Настройки DNS",
"fallbackFilter": "Настройки фильтра Fallback", "fallbackFilter": "Настройки фильтра fallback",
"hosts": "Hosts Settings" "hosts": "Настройки hosts"
}, },
"fields": { "fields": {
"enable": "Включить DNS", "enable": "Включить DNS",
"listen": "Прослушивание DNS", "listen": "Прослушивание DNS",
"enhancedMode": "Enhanced Mode", "enhancedMode": "Расширенный режим",
"fakeIpRange": "Диапазон FakeIP", "fakeIpRange": "Диапазон FakeIP",
"fakeIpFilterMode": "FakeIP Filter Mode", "fakeIpFilterMode": "Режим фильтра FakeIP",
"ipv6": { "ipv6": {
"label": "IPv6", "label": "IPv6",
"description": "Enable IPv6 DNS resolution" "description": "Включить DNS-разрешение IPv6"
}, },
"preferH3": { "preferH3": {
"label": "Предпочитать H3", "label": "Предпочитать H3",
"description": "DNS DOH использует http/3" "description": "Использовать HTTP/3 для DNS DoH"
}, },
"respectRules": { "respectRules": {
"label": "Приоритизировать правила", "label": "Приоритизировать правила",
"description": "Соединения DNS следуют правилам маршрутизации" "description": "Соединения DNS следуют правилам маршрутизации"
}, },
"useHosts": { "useHosts": {
"label": "Использовать файл Hosts", "label": "Использовать файл hosts",
"description": "Включить разрешение хостов через файл Hosts" "description": "Включить разрешение хостов через файл hosts"
}, },
"useSystemHosts": { "useSystemHosts": {
"label": "Использовать системный файл Hosts", "label": "Использовать системный файл hosts",
"description": "Включить разрешение хостов через системный файл Hosts" "description": "Включить разрешение хостов через системный файл hosts"
}, },
"directPolicy": { "directPolicy": {
"label": "Прямой сервер имен следует политике", "label": "Прямой сервер имен следует политике",
@ -537,23 +537,23 @@
}, },
"fallback": { "fallback": {
"label": "Fallback", "label": "Fallback",
"description": "Список резервных DNS-серверов, разделенных запятой" "description": "Список DNS-серверов, разделенных запятой"
}, },
"proxy": { "proxy": {
"label": "Proxy Server Nameserver", "label": "DNS-сервер прокси",
"description": "DNS-серверы для разрешения домена прокси-узлов" "description": "DNS-серверы для разрешения домена прокси-узлов"
}, },
"directNameserver": { "directNameserver": {
"label": "DNS-сервер для прямых соединений", "label": "DNS-сервер для прямых соединений",
"description": "Список DNS-серверов для прямых соединений, разделенных запятой" "description": "Список DNS-серверов для прямых соединений, разделённых запятой"
}, },
"fakeIpFilter": { "fakeIpFilter": {
"label": "Фильтр FakeIP", "label": "Фильтр FakeIP",
"description": "Домены, которые пропускают разрешение FakeIP, разделенные запятой" "description": "Домены, исключаемые из разрешения FakeIP, разделённые запятой"
}, },
"nameserverPolicy": { "nameserverPolicy": {
"label": "Политика серверов имен", "label": "Политика DNS-серверов",
"description": "DNS-сервер, специфичный для домена, несколько серверов разделяются знаком ';'" "description": "DNS-сервер для конкретного домена; несколько серверов разделяются символом ';'"
}, },
"geoipFiltering": { "geoipFiltering": {
"label": "Фильтрация GeoIP", "label": "Фильтрация GeoIP",
@ -562,24 +562,24 @@
"geoipCode": "Код GeoIP", "geoipCode": "Код GeoIP",
"fallbackIpCidr": { "fallbackIpCidr": {
"label": "Fallback IP CIDR", "label": "Fallback IP CIDR",
"description": "Диапазоны IP-адресов, не использующие резервные серверы, разделенные запятой" "description": "Диапазоны IP-адресов, не использующие резервные серверы, разделённые запятой"
}, },
"fallbackDomain": { "fallbackDomain": {
"label": "Fallback домены", "label": "Fallback домены",
"description": "Домены, использующие резервные серверы, разделенные запятой" "description": "Домены, использующие резервные серверы, разделённые запятой"
}, },
"hosts": { "hosts": {
"label": "Hosts", "label": "Hosts",
"description": "Custom domain to IP or domain mapping" "description": "Пользовательское сопоставление доменов с IP-адресами или другими доменами"
} }
}, },
"messages": { "messages": {
"saved": "DNS settings saved", "saved": "Настройки DNS сохранены",
"configError": "DNS configuration error:" "configError": "Ошибка конфигурации DNS:"
}, },
"errors": { "errors": {
"invalid": "Invalid configuration", "invalid": "Неверная конфигурация",
"invalidYaml": "Invalid YAML format" "invalidYaml": "Неверный формат YAML"
} }
}, },
"webUI": { "webUI": {
@ -600,24 +600,24 @@
"functions": { "functions": {
"rule": "Режим правил", "rule": "Режим правил",
"global": "Глобальный режим", "global": "Глобальный режим",
"openOrCloseDashboard": "Открыть/Закрыть панель управления", "openOrCloseDashboard": "Открыть/закрыть панель управления",
"toggleSystemProxy": "Включить/Отключить системный прокси", "toggleSystemProxy": "Включить/отключить системный прокси",
"toggleTunMode": "Включить/Отключить режим TUN", "toggleTunMode": "Включить/отключить режим TUN",
"entryLightweightMode": "Вход в LightWeight Mode", "entryLightweightMode": "Войти в режим LightWeight",
"direct": "Прямой режим", "direct": "Прямой режим",
"reactivateProfiles": "Перезапустить профиль" "reactivateProfiles": "Перезапустить профиль"
} }
}, },
"password": { "password": {
"prompts": { "prompts": {
"enterRoot": "Пожалуйста, введите ваш пароль root" "enterRoot": "Пожалуйста, введите пароль root"
} }
}, },
"networkInterface": { "networkInterface": {
"title": "Сетевой интерфейс", "title": "Сетевой интерфейс",
"fields": { "fields": {
"ipAddress": "IP адрес", "ipAddress": "IP-адрес",
"macAddress": "MAC адрес" "macAddress": "MAC-адрес"
} }
} }
}, },
@ -636,19 +636,19 @@
"uninstallSuccess": "Служба успешно удалена" "uninstallSuccess": "Служба успешно удалена"
}, },
"updater": { "updater": {
"withClashProxySuccess": "Update with Clash proxy successfully", "withClashProxySuccess": "Обновление через Clash proxy выполнено успешно",
"withClashProxyFailed": "Update failed even with Clash proxy" "withClashProxyFailed": "Обновление не удалось даже через Clash proxy"
} }
} }
}, },
"statuses": { "statuses": {
"clash": { "clash": {
"stopping": "Stopping Core...", "stopping": "Остановка ядра...",
"restarting": "Restarting Core..." "restarting": "Перезапуск ядра..."
}, },
"clashService": { "clashService": {
"installing": "Установка службы...", "installing": "Установка службы...",
"uninstalling": "Uninstalling Service..." "uninstalling": "Удаление службы..."
} }
} }
} }

View File

@ -12,18 +12,18 @@
"restart": "Перезапустить", "restart": "Перезапустить",
"resetToDefault": "Сбросить настройки", "resetToDefault": "Сбросить настройки",
"refresh": "Обновить", "refresh": "Обновить",
"retry": "Retry", "retry": "Повторить",
"refreshPage": "Refresh Page", "refreshPage": "Обновить страницу",
"showDetails": "Show Details", "showDetails": "Показать подробности",
"hideDetails": "Hide Details", "hideDetails": "Скрыть подробности",
"listView": "Отображать в виде списка", "listView": "Отображать в виде списка",
"tableView": "Отображать в виде таблицы", "tableView": "Отображать в виде таблицы",
"pause": "Пауза", "pause": "Пауза",
"resume": "Возобновить", "resume": "Возобновить",
"closeAll": "Закрыть всё", "closeAll": "Закрыть всё",
"clear": "Очистить", "clear": "Очистить",
"previous": "Previous", "previous": "Назад",
"next": "Next" "next": "Далее"
}, },
"labels": { "labels": {
"updateAt": "Обновлено в", "updateAt": "Обновлено в",
@ -36,14 +36,14 @@
"usedTotal": "Использовано / Всего", "usedTotal": "Использовано / Всего",
"from": "От", "from": "От",
"password": "Пароль", "password": "Пароль",
"retryAttempts": "Retry attempts", "retryAttempts": "Число попыток",
"downloaded": "Скачано", "downloaded": "Скачано",
"uploaded": "Загружено" "uploaded": "Загружено"
}, },
"statuses": { "statuses": {
"enabled": "Включено", "enabled": "Включено",
"disabled": "Отключено", "disabled": "Отключено",
"saving": "Saving...", "saving": "Сохранение...",
"empty": "Пусто" "empty": "Пусто"
}, },
"units": { "units": {
@ -51,8 +51,8 @@
"seconds": "секунды", "seconds": "секунды",
"minutes": "минуты", "minutes": "минуты",
"hours": "часы", "hours": "часы",
"kilobytes": "KB", "kilobytes": "КБ",
"files": "Files" "files": "Файлы"
}, },
"placeholders": { "placeholders": {
"resetInput": "Очистить поле ввода", "resetInput": "Очистить поле ввода",
@ -62,7 +62,7 @@
"useRegex": "Использовать регулярные выражения" "useRegex": "Использовать регулярные выражения"
}, },
"validation": { "validation": {
"invalidRegex": "Invalid regular expression" "invalidRegex": "Недопустимое регулярное выражение"
}, },
"window": { "window": {
"maximize": "Развернуть", "maximize": "Развернуть",
@ -74,8 +74,8 @@
}, },
"feedback": { "feedback": {
"errors": { "errors": {
"trafficStats": "Traffic Statistics Error", "trafficStats": "Ошибка статистики трафика",
"trafficStatsDescription": "The traffic statistics component encountered an error and has been disabled to prevent crashes." "trafficStatsDescription": "Компонент статистики трафика столкнулся с ошибкой и был отключён во избежание сбоев."
}, },
"notices": { "notices": {
"raw": "{{message}}", "raw": "{{message}}",
@ -84,13 +84,13 @@
"notifications": { "notifications": {
"importSuccess": "Профиль успешно импортирован", "importSuccess": "Профиль успешно импортирован",
"importSubscriptionSuccess": "Подписка успешно импортирована", "importSubscriptionSuccess": "Подписка успешно импортирована",
"importWithClashProxy": "Profile Imported with Clash proxy", "importWithClashProxy": "Профиль импортирован через Clash proxy",
"updateAvailable": "Update Available", "updateAvailable": "Доступно обновление",
"saved": "Saved successfully", "saved": "Успешно сохранено",
"common": { "common": {
"copySuccess": "Скопировано", "copySuccess": "Скопировано",
"saveSuccess": "Configuration saved successfully", "saveSuccess": "Конфигурация успешно сохранена",
"saveFailed": "Failed to save configuration", "saveFailed": "Не удалось сохранить конфигурацию",
"refreshFailed": "Не удалось обновить" "refreshFailed": "Не удалось обновить"
} }
}, },
@ -110,7 +110,7 @@
"yaml": { "yaml": {
"syntaxError": "Ошибка синтаксиса YAML, откат изменений", "syntaxError": "Ошибка синтаксиса YAML, откат изменений",
"readError": "Ошибка чтения YAML, откат изменений", "readError": "Ошибка чтения YAML, откат изменений",
"mappingError": "Ошибка YAML Mapping, откат изменений", "mappingError": "Ошибка сопоставления YAML, откат изменений",
"keyError": "Ошибка ключа YAML, откат изменений", "keyError": "Ошибка ключа YAML, откат изменений",
"generalError": "Ошибка YAML, откат изменений" "generalError": "Ошибка YAML, откат изменений"
}, },