feat(i18n): 分流规则页静态标签接单源 + 修 mobile 设置行模式 pill 语言
路由页此前静态标签硬编码中文,EN 模式混语。全部接进 strings.json 单源: - 新增 26 个 routing* 产品 getter(6 语):代理模式/内置规则/国内直连/我的规则/ 添加规则/从文本导入/重置默认/最终/直连·走隧道·拒绝/域名后缀/GeoSite 规则集/返回设置… (复用 smartRoute;seg 三项 EN 取短词 Global/Smart/Direct 适配段宽)。 - app_text.dart +26 抽象声明;重生成 6 份 strings_*.dart;alias.json desktop +24 / mobile +19。 - markup 加 data-i18n;JS pill(直连/走隧道/拒绝、FINAL)统一改从生成的 I18N 单源取(_ri), 与静态 pill 同源。JS-owned 的模式说明 rtModeNote 保留 _t 双语(不加 data-i18n)。 - desktop LAN 行(此前未接)补接 rr.lan/rr.lanSub + 新 routingForcedPill。 - 修 mobile 设置行「Routing rules」的模式 pill:缺 data-i18n → EN 显中文,补 setSmartRoute (en=Smart routing,与 desktop 一致)。 验收:l10n 重生成+analyze 0 issue、原型 0 unresolved、生成器零 diff、244 测试全绿、无红线词。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A79VtQA1BwTuQN1ThpvYpo
This commit is contained in:
@@ -633,4 +633,28 @@ abstract class AppText {
|
||||
String get routingRulesSub; // 自定义直连 / 走隧道 / 拒绝
|
||||
String get routingLanDirect; // 局域网 / 私网直连 / LAN & private direct
|
||||
String get routingLanForced; // 强制,不可关 / Always on
|
||||
String get routingForcedPill; // 🔒 强制 / 🔒 Forced
|
||||
String get routingProxyMode; // 代理模式 / Proxy mode
|
||||
String get routingModeGlobal; // 全局代理 / Global
|
||||
String get routingModeSmart; // 智能分流 / Smart
|
||||
String get routingModeDirect; // 全部直连 / Direct
|
||||
String get routingBuiltin; // 内置规则 / Built-in rules
|
||||
String get routingCnDirect; // 国内直连 / China direct
|
||||
String get routingMyRulesOrdered; // 我的规则 · 有序,首命中生效 / My rules · ordered, first match wins
|
||||
String get routingMyRulesFirst; // 我的规则 · 首命中生效 / My rules · first match wins
|
||||
String get routingFinalLong; // 最终(未命中任何规则) / Final (no rule matched)
|
||||
String get routingFinalShort; // 最终(未命中) / Final (no match)
|
||||
String get routingFinalFallback; // FINAL 兜底 / FINAL fallback
|
||||
String get routingTypeDomainSuffix; // 域名后缀 / Domain suffix
|
||||
String get routingTypeDomainSuffixCi; // 域名后缀 · CI 源 / Domain suffix · CI source
|
||||
String get routingTypeDomainSuffixMirror; // 域名后缀 · 镜像 / Domain suffix · Mirror
|
||||
String get routingTypeGeosite; // GeoSite 规则集 / GeoSite rule-set
|
||||
String get routingActDirect; // 直连 / Direct
|
||||
String get routingActProxy; // 走隧道 / Tunnel
|
||||
String get routingActReject; // 拒绝 / Reject
|
||||
String get routingForcedRow; // ⚠ 该域名由系统强制走隧道,此规则不生效 / ⚠ Forced to tunnel by the system; this rule is inactive
|
||||
String get routingAddRule; // 添加规则 / Add rule
|
||||
String get routingImport; // 从文本导入 / Import from text
|
||||
String get routingReset; // 重置默认 / Reset defaults
|
||||
String get routingBack; // 返回设置 / Back to settings
|
||||
}
|
||||
|
||||
@@ -511,6 +511,54 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get routingLanForced => 'Always on';
|
||||
@override
|
||||
String get routingForcedPill => '🔒 Forced';
|
||||
@override
|
||||
String get routingProxyMode => 'Proxy mode';
|
||||
@override
|
||||
String get routingModeGlobal => 'Global';
|
||||
@override
|
||||
String get routingModeSmart => 'Smart';
|
||||
@override
|
||||
String get routingModeDirect => 'Direct';
|
||||
@override
|
||||
String get routingBuiltin => 'Built-in rules';
|
||||
@override
|
||||
String get routingCnDirect => 'China direct';
|
||||
@override
|
||||
String get routingMyRulesOrdered => 'My rules · ordered, first match wins';
|
||||
@override
|
||||
String get routingMyRulesFirst => 'My rules · first match wins';
|
||||
@override
|
||||
String get routingFinalLong => 'Final (no rule matched)';
|
||||
@override
|
||||
String get routingFinalShort => 'Final (no match)';
|
||||
@override
|
||||
String get routingFinalFallback => 'FINAL fallback';
|
||||
@override
|
||||
String get routingTypeDomainSuffix => 'Domain suffix';
|
||||
@override
|
||||
String get routingTypeDomainSuffixCi => 'Domain suffix · CI source';
|
||||
@override
|
||||
String get routingTypeDomainSuffixMirror => 'Domain suffix · Mirror';
|
||||
@override
|
||||
String get routingTypeGeosite => 'GeoSite rule-set';
|
||||
@override
|
||||
String get routingActDirect => 'Direct';
|
||||
@override
|
||||
String get routingActProxy => 'Tunnel';
|
||||
@override
|
||||
String get routingActReject => 'Reject';
|
||||
@override
|
||||
String get routingForcedRow => '⚠ Forced to tunnel by the system; this rule is inactive';
|
||||
@override
|
||||
String get routingAddRule => 'Add rule';
|
||||
@override
|
||||
String get routingImport => 'Import from text';
|
||||
@override
|
||||
String get routingReset => 'Reset defaults';
|
||||
@override
|
||||
String get routingBack => 'Back to settings';
|
||||
@override
|
||||
List<String> get days7 => const ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
|
||||
@override
|
||||
List<String> get featsFree => const ['1 basic node only', '10 min per day', 'Watch an ad to start', '7-day free trial on sign-up'];
|
||||
|
||||
@@ -511,6 +511,54 @@ class StringsEs extends AppText {
|
||||
@override
|
||||
String get routingLanForced => 'Siempre activo';
|
||||
@override
|
||||
String get routingForcedPill => '🔒 Forzado';
|
||||
@override
|
||||
String get routingProxyMode => 'Modo de proxy';
|
||||
@override
|
||||
String get routingModeGlobal => 'Global';
|
||||
@override
|
||||
String get routingModeSmart => 'Inteligente';
|
||||
@override
|
||||
String get routingModeDirect => 'Directo';
|
||||
@override
|
||||
String get routingBuiltin => 'Reglas integradas';
|
||||
@override
|
||||
String get routingCnDirect => 'Directo nacional';
|
||||
@override
|
||||
String get routingMyRulesOrdered => 'Mis reglas · en orden, gana la primera coincidencia';
|
||||
@override
|
||||
String get routingMyRulesFirst => 'Mis reglas · gana la primera coincidencia';
|
||||
@override
|
||||
String get routingFinalLong => 'Final (ninguna regla coincide)';
|
||||
@override
|
||||
String get routingFinalShort => 'Final (sin coincidencia)';
|
||||
@override
|
||||
String get routingFinalFallback => 'FINAL — reserva';
|
||||
@override
|
||||
String get routingTypeDomainSuffix => 'Sufijo de dominio';
|
||||
@override
|
||||
String get routingTypeDomainSuffixCi => 'Sufijo de dominio · fuente CI';
|
||||
@override
|
||||
String get routingTypeDomainSuffixMirror => 'Sufijo de dominio · espejo';
|
||||
@override
|
||||
String get routingTypeGeosite => 'Conjunto de reglas GeoSite';
|
||||
@override
|
||||
String get routingActDirect => 'Directo';
|
||||
@override
|
||||
String get routingActProxy => 'Túnel';
|
||||
@override
|
||||
String get routingActReject => 'Rechazar';
|
||||
@override
|
||||
String get routingForcedRow => '⚠ El sistema fuerza el túnel para este dominio; esta regla no se aplica';
|
||||
@override
|
||||
String get routingAddRule => 'Añadir regla';
|
||||
@override
|
||||
String get routingImport => 'Importar desde texto';
|
||||
@override
|
||||
String get routingReset => 'Restablecer';
|
||||
@override
|
||||
String get routingBack => 'Volver a ajustes';
|
||||
@override
|
||||
List<String> get days7 => const ['L', 'M', 'X', 'J', 'V', 'S', 'D'];
|
||||
@override
|
||||
List<String> get featsFree => const ['Solo 1 nodo básico', '10 min al día', 'Mira un anuncio para empezar', 'Prueba gratis de 7 días al registrarte'];
|
||||
|
||||
@@ -511,6 +511,54 @@ class StringsJa extends AppText {
|
||||
@override
|
||||
String get routingLanForced => '常時オン';
|
||||
@override
|
||||
String get routingForcedPill => '🔒 強制';
|
||||
@override
|
||||
String get routingProxyMode => 'プロキシモード';
|
||||
@override
|
||||
String get routingModeGlobal => 'グローバル';
|
||||
@override
|
||||
String get routingModeSmart => 'スマート';
|
||||
@override
|
||||
String get routingModeDirect => '直接';
|
||||
@override
|
||||
String get routingBuiltin => '組み込みルール';
|
||||
@override
|
||||
String get routingCnDirect => '国内は直接接続';
|
||||
@override
|
||||
String get routingMyRulesOrdered => 'マイルール · 順序あり、最初の一致が有効';
|
||||
@override
|
||||
String get routingMyRulesFirst => 'マイルール · 最初の一致が有効';
|
||||
@override
|
||||
String get routingFinalLong => '最終(どのルールにも一致しない)';
|
||||
@override
|
||||
String get routingFinalShort => '最終(一致なし)';
|
||||
@override
|
||||
String get routingFinalFallback => 'FINAL フォールバック';
|
||||
@override
|
||||
String get routingTypeDomainSuffix => 'ドメインサフィックス';
|
||||
@override
|
||||
String get routingTypeDomainSuffixCi => 'ドメインサフィックス · CI ソース';
|
||||
@override
|
||||
String get routingTypeDomainSuffixMirror => 'ドメインサフィックス · ミラー';
|
||||
@override
|
||||
String get routingTypeGeosite => 'GeoSite ルールセット';
|
||||
@override
|
||||
String get routingActDirect => '直接接続';
|
||||
@override
|
||||
String get routingActProxy => 'トンネル';
|
||||
@override
|
||||
String get routingActReject => '拒否';
|
||||
@override
|
||||
String get routingForcedRow => '⚠ このドメインはシステムにより強制的にトンネル経由となり、このルールは無効です';
|
||||
@override
|
||||
String get routingAddRule => 'ルールを追加';
|
||||
@override
|
||||
String get routingImport => 'テキストから読み込み';
|
||||
@override
|
||||
String get routingReset => 'デフォルトに戻す';
|
||||
@override
|
||||
String get routingBack => '設定に戻る';
|
||||
@override
|
||||
List<String> get days7 => const ['月', '火', '水', '木', '金', '土', '日'];
|
||||
@override
|
||||
List<String> get featsFree => const ['基本ノード1つのみ', '1日10分', '広告を見て開始', '登録で7日間無料トライアル'];
|
||||
|
||||
@@ -511,6 +511,54 @@ class StringsKo extends AppText {
|
||||
@override
|
||||
String get routingLanForced => '항상 켜짐';
|
||||
@override
|
||||
String get routingForcedPill => '🔒 강제';
|
||||
@override
|
||||
String get routingProxyMode => '프록시 모드';
|
||||
@override
|
||||
String get routingModeGlobal => '전체';
|
||||
@override
|
||||
String get routingModeSmart => '스마트';
|
||||
@override
|
||||
String get routingModeDirect => '직접';
|
||||
@override
|
||||
String get routingBuiltin => '기본 규칙';
|
||||
@override
|
||||
String get routingCnDirect => '국내 직접 연결';
|
||||
@override
|
||||
String get routingMyRulesOrdered => '내 규칙 · 순서대로, 첫 일치 적용';
|
||||
@override
|
||||
String get routingMyRulesFirst => '내 규칙 · 첫 일치 적용';
|
||||
@override
|
||||
String get routingFinalLong => '최종(일치하는 규칙 없음)';
|
||||
@override
|
||||
String get routingFinalShort => '최종(일치 없음)';
|
||||
@override
|
||||
String get routingFinalFallback => 'FINAL 폴백';
|
||||
@override
|
||||
String get routingTypeDomainSuffix => '도메인 접미사';
|
||||
@override
|
||||
String get routingTypeDomainSuffixCi => '도메인 접미사 · CI 소스';
|
||||
@override
|
||||
String get routingTypeDomainSuffixMirror => '도메인 접미사 · 미러';
|
||||
@override
|
||||
String get routingTypeGeosite => 'GeoSite 규칙 세트';
|
||||
@override
|
||||
String get routingActDirect => '직접 연결';
|
||||
@override
|
||||
String get routingActProxy => '터널';
|
||||
@override
|
||||
String get routingActReject => '거부';
|
||||
@override
|
||||
String get routingForcedRow => '⚠ 이 도메인은 시스템에 의해 강제로 터널을 사용하며, 이 규칙은 적용되지 않습니다';
|
||||
@override
|
||||
String get routingAddRule => '규칙 추가';
|
||||
@override
|
||||
String get routingImport => '텍스트에서 가져오기';
|
||||
@override
|
||||
String get routingReset => '기본값 재설정';
|
||||
@override
|
||||
String get routingBack => '설정으로 돌아가기';
|
||||
@override
|
||||
List<String> get days7 => const ['월', '화', '수', '목', '금', '토', '일'];
|
||||
@override
|
||||
List<String> get featsFree => const ['기본 노드 1개', '하루 10분', '광고 시청 후 시작', '가입 시 7일 무료 체험'];
|
||||
|
||||
@@ -511,6 +511,54 @@ class StringsRu extends AppText {
|
||||
@override
|
||||
String get routingLanForced => 'Всегда включено';
|
||||
@override
|
||||
String get routingForcedPill => '🔒 Принудительно';
|
||||
@override
|
||||
String get routingProxyMode => 'Режим прокси';
|
||||
@override
|
||||
String get routingModeGlobal => 'Глобально';
|
||||
@override
|
||||
String get routingModeSmart => 'Умный';
|
||||
@override
|
||||
String get routingModeDirect => 'Напрямую';
|
||||
@override
|
||||
String get routingBuiltin => 'Встроенные правила';
|
||||
@override
|
||||
String get routingCnDirect => 'Прямой доступ внутри страны';
|
||||
@override
|
||||
String get routingMyRulesOrdered => 'Мои правила · по порядку, срабатывает первое совпадение';
|
||||
@override
|
||||
String get routingMyRulesFirst => 'Мои правила · срабатывает первое совпадение';
|
||||
@override
|
||||
String get routingFinalLong => 'Итог (ни одно правило не совпало)';
|
||||
@override
|
||||
String get routingFinalShort => 'Итог (нет совпадений)';
|
||||
@override
|
||||
String get routingFinalFallback => 'FINAL — резерв';
|
||||
@override
|
||||
String get routingTypeDomainSuffix => 'Суффикс домена';
|
||||
@override
|
||||
String get routingTypeDomainSuffixCi => 'Суффикс домена · CI-источник';
|
||||
@override
|
||||
String get routingTypeDomainSuffixMirror => 'Суффикс домена · зеркало';
|
||||
@override
|
||||
String get routingTypeGeosite => 'Набор правил GeoSite';
|
||||
@override
|
||||
String get routingActDirect => 'Напрямую';
|
||||
@override
|
||||
String get routingActProxy => 'Туннель';
|
||||
@override
|
||||
String get routingActReject => 'Отклонить';
|
||||
@override
|
||||
String get routingForcedRow => '⚠ Домен принудительно направлен через туннель системой; правило неактивно';
|
||||
@override
|
||||
String get routingAddRule => 'Добавить правило';
|
||||
@override
|
||||
String get routingImport => 'Импорт из текста';
|
||||
@override
|
||||
String get routingReset => 'Сбросить настройки';
|
||||
@override
|
||||
String get routingBack => 'Назад к настройкам';
|
||||
@override
|
||||
List<String> get days7 => const ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
|
||||
@override
|
||||
List<String> get featsFree => const ['Только 1 базовый узел', '10 минут в день', 'Смотрите рекламу, чтобы начать', '7 дней бесплатно при регистрации'];
|
||||
|
||||
@@ -511,6 +511,54 @@ class StringsZh extends AppText {
|
||||
@override
|
||||
String get routingLanForced => '强制,不可关';
|
||||
@override
|
||||
String get routingForcedPill => '🔒 强制';
|
||||
@override
|
||||
String get routingProxyMode => '代理模式';
|
||||
@override
|
||||
String get routingModeGlobal => '全局代理';
|
||||
@override
|
||||
String get routingModeSmart => '智能分流';
|
||||
@override
|
||||
String get routingModeDirect => '全部直连';
|
||||
@override
|
||||
String get routingBuiltin => '内置规则';
|
||||
@override
|
||||
String get routingCnDirect => '国内直连';
|
||||
@override
|
||||
String get routingMyRulesOrdered => '我的规则 · 有序,首命中生效';
|
||||
@override
|
||||
String get routingMyRulesFirst => '我的规则 · 首命中生效';
|
||||
@override
|
||||
String get routingFinalLong => '最终(未命中任何规则)';
|
||||
@override
|
||||
String get routingFinalShort => '最终(未命中)';
|
||||
@override
|
||||
String get routingFinalFallback => 'FINAL 兜底';
|
||||
@override
|
||||
String get routingTypeDomainSuffix => '域名后缀';
|
||||
@override
|
||||
String get routingTypeDomainSuffixCi => '域名后缀 · CI 源';
|
||||
@override
|
||||
String get routingTypeDomainSuffixMirror => '域名后缀 · 镜像';
|
||||
@override
|
||||
String get routingTypeGeosite => 'GeoSite 规则集';
|
||||
@override
|
||||
String get routingActDirect => '直连';
|
||||
@override
|
||||
String get routingActProxy => '走隧道';
|
||||
@override
|
||||
String get routingActReject => '拒绝';
|
||||
@override
|
||||
String get routingForcedRow => '⚠ 该域名由系统强制走隧道,此规则不生效';
|
||||
@override
|
||||
String get routingAddRule => '添加规则';
|
||||
@override
|
||||
String get routingImport => '从文本导入';
|
||||
@override
|
||||
String get routingReset => '重置默认';
|
||||
@override
|
||||
String get routingBack => '返回设置';
|
||||
@override
|
||||
List<String> get days7 => const ['一', '二', '三', '四', '五', '六', '日'];
|
||||
@override
|
||||
List<String> get featsFree => const ['仅 1 个基础节点', '每日 10 分钟时长', '使用前观看广告', '注册享 7 天免费试用'];
|
||||
|
||||
@@ -2000,6 +2000,198 @@
|
||||
"ko": "항상 켜짐",
|
||||
"ru": "Всегда включено",
|
||||
"es": "Siempre activo"
|
||||
},
|
||||
"routingForcedPill": {
|
||||
"zh": "🔒 强制",
|
||||
"en": "🔒 Forced",
|
||||
"ja": "🔒 強制",
|
||||
"ko": "🔒 강제",
|
||||
"ru": "🔒 Принудительно",
|
||||
"es": "🔒 Forzado"
|
||||
},
|
||||
"routingProxyMode": {
|
||||
"zh": "代理模式",
|
||||
"en": "Proxy mode",
|
||||
"ja": "プロキシモード",
|
||||
"ko": "프록시 모드",
|
||||
"ru": "Режим прокси",
|
||||
"es": "Modo de proxy"
|
||||
},
|
||||
"routingModeGlobal": {
|
||||
"zh": "全局代理",
|
||||
"en": "Global",
|
||||
"ja": "グローバル",
|
||||
"ko": "전체",
|
||||
"ru": "Глобально",
|
||||
"es": "Global"
|
||||
},
|
||||
"routingModeSmart": {
|
||||
"zh": "智能分流",
|
||||
"en": "Smart",
|
||||
"ja": "スマート",
|
||||
"ko": "스마트",
|
||||
"ru": "Умный",
|
||||
"es": "Inteligente"
|
||||
},
|
||||
"routingModeDirect": {
|
||||
"zh": "全部直连",
|
||||
"en": "Direct",
|
||||
"ja": "直接",
|
||||
"ko": "직접",
|
||||
"ru": "Напрямую",
|
||||
"es": "Directo"
|
||||
},
|
||||
"routingBuiltin": {
|
||||
"zh": "内置规则",
|
||||
"en": "Built-in rules",
|
||||
"ja": "組み込みルール",
|
||||
"ko": "기본 규칙",
|
||||
"ru": "Встроенные правила",
|
||||
"es": "Reglas integradas"
|
||||
},
|
||||
"routingCnDirect": {
|
||||
"zh": "国内直连",
|
||||
"en": "China direct",
|
||||
"ja": "国内は直接接続",
|
||||
"ko": "국내 직접 연결",
|
||||
"ru": "Прямой доступ внутри страны",
|
||||
"es": "Directo nacional"
|
||||
},
|
||||
"routingMyRulesOrdered": {
|
||||
"zh": "我的规则 · 有序,首命中生效",
|
||||
"en": "My rules · ordered, first match wins",
|
||||
"ja": "マイルール · 順序あり、最初の一致が有効",
|
||||
"ko": "내 규칙 · 순서대로, 첫 일치 적용",
|
||||
"ru": "Мои правила · по порядку, срабатывает первое совпадение",
|
||||
"es": "Mis reglas · en orden, gana la primera coincidencia"
|
||||
},
|
||||
"routingMyRulesFirst": {
|
||||
"zh": "我的规则 · 首命中生效",
|
||||
"en": "My rules · first match wins",
|
||||
"ja": "マイルール · 最初の一致が有効",
|
||||
"ko": "내 규칙 · 첫 일치 적용",
|
||||
"ru": "Мои правила · срабатывает первое совпадение",
|
||||
"es": "Mis reglas · gana la primera coincidencia"
|
||||
},
|
||||
"routingFinalLong": {
|
||||
"zh": "最终(未命中任何规则)",
|
||||
"en": "Final (no rule matched)",
|
||||
"ja": "最終(どのルールにも一致しない)",
|
||||
"ko": "최종(일치하는 규칙 없음)",
|
||||
"ru": "Итог (ни одно правило не совпало)",
|
||||
"es": "Final (ninguna regla coincide)"
|
||||
},
|
||||
"routingFinalShort": {
|
||||
"zh": "最终(未命中)",
|
||||
"en": "Final (no match)",
|
||||
"ja": "最終(一致なし)",
|
||||
"ko": "최종(일치 없음)",
|
||||
"ru": "Итог (нет совпадений)",
|
||||
"es": "Final (sin coincidencia)"
|
||||
},
|
||||
"routingFinalFallback": {
|
||||
"zh": "FINAL 兜底",
|
||||
"en": "FINAL fallback",
|
||||
"ja": "FINAL フォールバック",
|
||||
"ko": "FINAL 폴백",
|
||||
"ru": "FINAL — резерв",
|
||||
"es": "FINAL — reserva"
|
||||
},
|
||||
"routingTypeDomainSuffix": {
|
||||
"zh": "域名后缀",
|
||||
"en": "Domain suffix",
|
||||
"ja": "ドメインサフィックス",
|
||||
"ko": "도메인 접미사",
|
||||
"ru": "Суффикс домена",
|
||||
"es": "Sufijo de dominio"
|
||||
},
|
||||
"routingTypeDomainSuffixCi": {
|
||||
"zh": "域名后缀 · CI 源",
|
||||
"en": "Domain suffix · CI source",
|
||||
"ja": "ドメインサフィックス · CI ソース",
|
||||
"ko": "도메인 접미사 · CI 소스",
|
||||
"ru": "Суффикс домена · CI-источник",
|
||||
"es": "Sufijo de dominio · fuente CI"
|
||||
},
|
||||
"routingTypeDomainSuffixMirror": {
|
||||
"zh": "域名后缀 · 镜像",
|
||||
"en": "Domain suffix · Mirror",
|
||||
"ja": "ドメインサフィックス · ミラー",
|
||||
"ko": "도메인 접미사 · 미러",
|
||||
"ru": "Суффикс домена · зеркало",
|
||||
"es": "Sufijo de dominio · espejo"
|
||||
},
|
||||
"routingTypeGeosite": {
|
||||
"zh": "GeoSite 规则集",
|
||||
"en": "GeoSite rule-set",
|
||||
"ja": "GeoSite ルールセット",
|
||||
"ko": "GeoSite 규칙 세트",
|
||||
"ru": "Набор правил GeoSite",
|
||||
"es": "Conjunto de reglas GeoSite"
|
||||
},
|
||||
"routingActDirect": {
|
||||
"zh": "直连",
|
||||
"en": "Direct",
|
||||
"ja": "直接接続",
|
||||
"ko": "직접 연결",
|
||||
"ru": "Напрямую",
|
||||
"es": "Directo"
|
||||
},
|
||||
"routingActProxy": {
|
||||
"zh": "走隧道",
|
||||
"en": "Tunnel",
|
||||
"ja": "トンネル",
|
||||
"ko": "터널",
|
||||
"ru": "Туннель",
|
||||
"es": "Túnel"
|
||||
},
|
||||
"routingActReject": {
|
||||
"zh": "拒绝",
|
||||
"en": "Reject",
|
||||
"ja": "拒否",
|
||||
"ko": "거부",
|
||||
"ru": "Отклонить",
|
||||
"es": "Rechazar"
|
||||
},
|
||||
"routingForcedRow": {
|
||||
"zh": "⚠ 该域名由系统强制走隧道,此规则不生效",
|
||||
"en": "⚠ Forced to tunnel by the system; this rule is inactive",
|
||||
"ja": "⚠ このドメインはシステムにより強制的にトンネル経由となり、このルールは無効です",
|
||||
"ko": "⚠ 이 도메인은 시스템에 의해 강제로 터널을 사용하며, 이 규칙은 적용되지 않습니다",
|
||||
"ru": "⚠ Домен принудительно направлен через туннель системой; правило неактивно",
|
||||
"es": "⚠ El sistema fuerza el túnel para este dominio; esta regla no se aplica"
|
||||
},
|
||||
"routingAddRule": {
|
||||
"zh": "添加规则",
|
||||
"en": "Add rule",
|
||||
"ja": "ルールを追加",
|
||||
"ko": "규칙 추가",
|
||||
"ru": "Добавить правило",
|
||||
"es": "Añadir regla"
|
||||
},
|
||||
"routingImport": {
|
||||
"zh": "从文本导入",
|
||||
"en": "Import from text",
|
||||
"ja": "テキストから読み込み",
|
||||
"ko": "텍스트에서 가져오기",
|
||||
"ru": "Импорт из текста",
|
||||
"es": "Importar desde texto"
|
||||
},
|
||||
"routingReset": {
|
||||
"zh": "重置默认",
|
||||
"en": "Reset defaults",
|
||||
"ja": "デフォルトに戻す",
|
||||
"ko": "기본값 재설정",
|
||||
"ru": "Сбросить настройки",
|
||||
"es": "Restablecer"
|
||||
},
|
||||
"routingBack": {
|
||||
"zh": "返回设置",
|
||||
"en": "Back to settings",
|
||||
"ja": "設定に戻る",
|
||||
"ko": "설정으로 돌아가기",
|
||||
"ru": "Назад к настройкам",
|
||||
"es": "Volver a ajustes"
|
||||
}
|
||||
},
|
||||
"lists": {
|
||||
|
||||
@@ -129,7 +129,31 @@
|
||||
"login.signupTitle": "tabRegister",
|
||||
"nav.routing": "routingRulesTitle",
|
||||
"set.routing": "routingRulesTitle",
|
||||
"set.routingSub": "routingRulesSub"
|
||||
"set.routingSub": "routingRulesSub",
|
||||
"rr.back": "routingBack",
|
||||
"rr.proxyMode": "routingProxyMode",
|
||||
"rr.modeGlobal": "routingModeGlobal",
|
||||
"rr.modeSmart": "routingModeSmart",
|
||||
"rr.modeDirect": "routingModeDirect",
|
||||
"rr.builtin": "routingBuiltin",
|
||||
"rr.cnDirect": "routingCnDirect",
|
||||
"rr.lan": "routingLanDirect",
|
||||
"rr.lanSub": "routingLanForced",
|
||||
"rr.forcedPill": "routingForcedPill",
|
||||
"rr.myRulesOrdered": "routingMyRulesOrdered",
|
||||
"rr.finalLong": "routingFinalLong",
|
||||
"rr.finalFallback": "routingFinalFallback",
|
||||
"rr.typeDomainSuffix": "routingTypeDomainSuffix",
|
||||
"rr.typeDomainSuffixCi": "routingTypeDomainSuffixCi",
|
||||
"rr.typeDomainSuffixMirror": "routingTypeDomainSuffixMirror",
|
||||
"rr.typeGeosite": "routingTypeGeosite",
|
||||
"rr.actDirect": "routingActDirect",
|
||||
"rr.actProxy": "routingActProxy",
|
||||
"rr.actReject": "routingActReject",
|
||||
"rr.forcedRow": "routingForcedRow",
|
||||
"rr.addRule": "routingAddRule",
|
||||
"rr.import": "routingImport",
|
||||
"rr.reset": "routingReset"
|
||||
},
|
||||
"mobile": {
|
||||
"brandName": "brand",
|
||||
@@ -274,6 +298,23 @@
|
||||
"redeemBtn": "redeemBtn",
|
||||
"navRouting": "routingRulesTitle",
|
||||
"rr.lan": "routingLanDirect",
|
||||
"rr.lanSub": "routingLanForced"
|
||||
"rr.lanSub": "routingLanForced",
|
||||
"rr.proxyMode": "routingProxyMode",
|
||||
"rr.modeGlobal": "routingModeGlobal",
|
||||
"rr.modeSmart": "routingModeSmart",
|
||||
"rr.modeDirect": "routingModeDirect",
|
||||
"rr.builtin": "routingBuiltin",
|
||||
"rr.cnDirect": "routingCnDirect",
|
||||
"rr.myRulesFirst": "routingMyRulesFirst",
|
||||
"rr.finalShort": "routingFinalShort",
|
||||
"rr.finalFallback": "routingFinalFallback",
|
||||
"rr.typeDomainSuffix": "routingTypeDomainSuffix",
|
||||
"rr.typeGeosite": "routingTypeGeosite",
|
||||
"rr.actDirect": "routingActDirect",
|
||||
"rr.actProxy": "routingActProxy",
|
||||
"rr.actReject": "routingActReject",
|
||||
"rr.addRule": "routingAddRule",
|
||||
"rr.import": "routingImport",
|
||||
"rr.reset": "routingReset"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,36 +745,36 @@
|
||||
<!-- 分流规则子视图(从 设置 → 分流规则 入口进) -->
|
||||
<section class="view" data-view="routing">
|
||||
<div class="view-body settings-view">
|
||||
<button class="pv-back" id="rtBack"><svg><use href="#i-arrow-left"/></svg><span>返回设置</span></button>
|
||||
<div class="sec-label">代理模式</div>
|
||||
<button class="pv-back" id="rtBack"><svg><use href="#i-arrow-left"/></svg><span data-i18n="rr.back">返回设置</span></button>
|
||||
<div class="sec-label" data-i18n="rr.proxyMode">代理模式</div>
|
||||
<div class="segswitch" id="rtModeSeg">
|
||||
<button class="segswitch-opt" data-mode="global"><span>全局代理</span></button>
|
||||
<button class="segswitch-opt is-active" data-mode="smart"><span>智能分流</span></button>
|
||||
<button class="segswitch-opt" data-mode="direct"><span>全部直连</span></button>
|
||||
<button class="segswitch-opt" data-mode="global"><span data-i18n="rr.modeGlobal">全局代理</span></button>
|
||||
<button class="segswitch-opt is-active" data-mode="smart"><span data-i18n="rr.modeSmart">智能分流</span></button>
|
||||
<button class="segswitch-opt" data-mode="direct"><span data-i18n="rr.modeDirect">全部直连</span></button>
|
||||
</div>
|
||||
<p id="rtModeNote" style="font-size:var(--text-caption);color:var(--fg3);margin:var(--space-2) 0 var(--space-5)">下方「我的规则」仅在<b>智能分流</b>模式生效。全局代理 / 全部直连为一刀切模式,忽略自定义规则(系统强制层仍保留)。</p>
|
||||
<div class="sec-label">内置规则</div>
|
||||
<div class="sec-label" data-i18n="rr.builtin">内置规则</div>
|
||||
<div class="card card-flush" style="margin-bottom:var(--space-5)">
|
||||
<div class="setting-row" id="rtCnRow"><span class="icon-box"><svg><use href="#i-globe"/></svg></span><div class="st-body"><div class="st-title">国内直连</div><div class="st-sub">GeoIP / GeoSite CN</div></div><span class="st-trail"><button class="toggle is-on"><i></i></button></span></div>
|
||||
<div class="setting-row"><span class="icon-box"><svg><use href="#i-home"/></svg></span><div class="st-body"><div class="st-title">局域网 / 私网直连</div><div class="st-sub">强制,不可关</div></div><span class="st-trail"><span class="pill is-neutral">🔒 强制</span></span></div>
|
||||
<div class="setting-row" id="rtCnRow"><span class="icon-box"><svg><use href="#i-globe"/></svg></span><div class="st-body"><div class="st-title" data-i18n="rr.cnDirect">国内直连</div><div class="st-sub">GeoIP / GeoSite CN</div></div><span class="st-trail"><button class="toggle is-on"><i></i></button></span></div>
|
||||
<div class="setting-row"><span class="icon-box"><svg><use href="#i-home"/></svg></span><div class="st-body"><div class="st-title" data-i18n="rr.lan">局域网 / 私网直连</div><div class="st-sub" data-i18n="rr.lanSub">强制,不可关</div></div><span class="st-trail"><span class="pill is-neutral" data-i18n="rr.forcedPill">🔒 强制</span></span></div>
|
||||
</div>
|
||||
<div id="rtMyRules">
|
||||
<div class="sec-label" id="rtMyRulesLabel">我的规则 · 有序,首命中生效</div>
|
||||
<div class="sec-label" id="rtMyRulesLabel" data-i18n="rr.myRulesOrdered">我的规则 · 有序,首命中生效</div>
|
||||
<div class="card card-flush" id="rtRulesList" style="margin-bottom:var(--space-4)">
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">git.51yanmei.com</div><div class="st-sub">域名后缀 · CI 源</div></div><span class="st-trail"><span class="pill is-success">直连</span></span></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">aliyun.com</div><div class="st-sub">域名后缀 · 镜像</div></div><span class="st-trail"><span class="pill is-success">直连</span></span></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">github.com</div><div class="st-sub">域名后缀</div></div><span class="st-trail"><span class="pill is-warning">走隧道</span></span></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">category-ads</div><div class="st-sub">GeoSite 规则集</div></div><span class="st-trail"><span class="pill is-danger">拒绝</span></span></div>
|
||||
<div class="setting-row" style="opacity:.5"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">git.yanmeiai.com</div><div class="st-sub" style="color:var(--warning)">⚠ 该域名由系统强制走隧道,此规则不生效</div></div><span class="st-trail"><span class="pill is-success">直连</span></span></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">git.51yanmei.com</div><div class="st-sub" data-i18n="rr.typeDomainSuffixCi">域名后缀 · CI 源</div></div><span class="st-trail"><span class="pill is-success" data-i18n="rr.actDirect">直连</span></span></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">aliyun.com</div><div class="st-sub" data-i18n="rr.typeDomainSuffixMirror">域名后缀 · 镜像</div></div><span class="st-trail"><span class="pill is-success" data-i18n="rr.actDirect">直连</span></span></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">github.com</div><div class="st-sub" data-i18n="rr.typeDomainSuffix">域名后缀</div></div><span class="st-trail"><span class="pill is-warning" data-i18n="rr.actProxy">走隧道</span></span></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">category-ads</div><div class="st-sub" data-i18n="rr.typeGeosite">GeoSite 规则集</div></div><span class="st-trail"><span class="pill is-danger" data-i18n="rr.actReject">拒绝</span></span></div>
|
||||
<div class="setting-row" style="opacity:.5"><span style="color:var(--fg3);opacity:.55;margin-right:var(--space-2)">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">git.yanmeiai.com</div><div class="st-sub" style="color:var(--warning)" data-i18n="rr.forcedRow">⚠ 该域名由系统强制走隧道,此规则不生效</div></div><span class="st-trail"><span class="pill is-success" data-i18n="rr.actDirect">直连</span></span></div>
|
||||
</div>
|
||||
<div style="display:flex;gap:var(--space-3);align-items:center;margin-bottom:var(--space-5)">
|
||||
<button class="btn btn-subtle" id="rtAddBtn"><svg><use href="#i-plus"/></svg>添加规则</button>
|
||||
<button class="btn btn-ghost" id="rtImportBtn">从文本导入</button>
|
||||
<button class="btn btn-ghost" id="rtResetBtn">重置默认</button>
|
||||
<button class="btn btn-subtle" id="rtAddBtn"><svg><use href="#i-plus"/></svg><span data-i18n="rr.addRule">添加规则</span></button>
|
||||
<button class="btn btn-ghost" id="rtImportBtn" data-i18n="rr.import">从文本导入</button>
|
||||
<button class="btn btn-ghost" id="rtResetBtn" data-i18n="rr.reset">重置默认</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sec-label">最终(未命中任何规则)</div>
|
||||
<div class="card card-flush"><div class="setting-row"><div class="st-body"><div class="st-title">FINAL 兜底</div></div><span class="st-trail"><span class="pill is-warning" id="rtFinalPill">走隧道</span></span></div></div>
|
||||
<div class="sec-label" data-i18n="rr.finalLong">最终(未命中任何规则)</div>
|
||||
<div class="card card-flush"><div class="setting-row"><div class="st-body"><div class="st-title" data-i18n="rr.finalFallback">FINAL 兜底</div></div><span class="st-trail"><span class="pill is-warning" id="rtFinalPill">走隧道</span></span></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1381,6 +1381,30 @@ var I18N = {
|
||||
'rd.label':{zh:'兑换码',en:'Redemption code'},
|
||||
'rd.ph':{zh:'输入激活码',en:'Enter activation code'},
|
||||
'rd.title':{zh:'兑换激活码',en:'Redeem a code'},
|
||||
'rr.actDirect':{zh:'直连',en:'Direct'},
|
||||
'rr.actProxy':{zh:'走隧道',en:'Tunnel'},
|
||||
'rr.actReject':{zh:'拒绝',en:'Reject'},
|
||||
'rr.addRule':{zh:'添加规则',en:'Add rule'},
|
||||
'rr.back':{zh:'返回设置',en:'Back to settings'},
|
||||
'rr.builtin':{zh:'内置规则',en:'Built-in rules'},
|
||||
'rr.cnDirect':{zh:'国内直连',en:'China direct'},
|
||||
'rr.finalFallback':{zh:'FINAL 兜底',en:'FINAL fallback'},
|
||||
'rr.finalLong':{zh:'最终(未命中任何规则)',en:'Final (no rule matched)'},
|
||||
'rr.forcedPill':{zh:'🔒 强制',en:'🔒 Forced'},
|
||||
'rr.forcedRow':{zh:'⚠ 该域名由系统强制走隧道,此规则不生效',en:'⚠ Forced to tunnel by the system; this rule is inactive'},
|
||||
'rr.import':{zh:'从文本导入',en:'Import from text'},
|
||||
'rr.lan':{zh:'局域网 / 私网直连',en:'LAN & private direct'},
|
||||
'rr.lanSub':{zh:'强制,不可关',en:'Always on'},
|
||||
'rr.modeDirect':{zh:'全部直连',en:'Direct'},
|
||||
'rr.modeGlobal':{zh:'全局代理',en:'Global'},
|
||||
'rr.modeSmart':{zh:'智能分流',en:'Smart'},
|
||||
'rr.myRulesOrdered':{zh:'我的规则 · 有序,首命中生效',en:'My rules · ordered, first match wins'},
|
||||
'rr.proxyMode':{zh:'代理模式',en:'Proxy mode'},
|
||||
'rr.reset':{zh:'重置默认',en:'Reset defaults'},
|
||||
'rr.typeDomainSuffix':{zh:'域名后缀',en:'Domain suffix'},
|
||||
'rr.typeDomainSuffixCi':{zh:'域名后缀 · CI 源',en:'Domain suffix · CI source'},
|
||||
'rr.typeDomainSuffixMirror':{zh:'域名后缀 · 镜像',en:'Domain suffix · Mirror'},
|
||||
'rr.typeGeosite':{zh:'GeoSite 规则集',en:'GeoSite rule-set'},
|
||||
'set.autoconnect':{zh:'自动连接',en:'Auto-connect'},
|
||||
'set.autoconnectSub':{zh:'启动时自动连接节点',en:'Connect automatically on launch'},
|
||||
'set.autostart':{zh:'开机自启',en:'Launch at startup'},
|
||||
@@ -2026,6 +2050,8 @@ var _rtBack=document.getElementById('rtBack'); if(_rtBack) _rtBack.addEventListe
|
||||
(function(){
|
||||
if(!S.routeMode) S.routeMode='smart';
|
||||
function _t(zh,en){ return S.lang==='zh'?zh:en; }
|
||||
// 从生成的 I18N 单源取值(与静态 data-i18n pill 同源),S.lang 恒为 zh/en
|
||||
function _ri(k){ var o=I18N[k]; return o ? (o[S.lang]||o.en) : ''; }
|
||||
function _esc(s){ return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); }
|
||||
var INP='padding:10px 12px;border-radius:var(--radius-md);border:1px solid var(--border);background:var(--surface);color:var(--fg1);font-size:14px;font-family:inherit;width:100%;box-sizing:border-box';
|
||||
|
||||
@@ -2034,7 +2060,7 @@ var _rtBack=document.getElementById('rtBack'); if(_rtBack) _rtBack.addEventListe
|
||||
document.querySelectorAll('#rtModeSeg button').forEach(function(b){ b.classList.toggle('is-active', b.dataset.mode===mode); });
|
||||
['rtCnRow','rtMyRules'].forEach(function(id){ var el=document.getElementById(id); if(!el) return; el.style.opacity=smart?'':'.4'; el.style.pointerEvents=smart?'':'none'; });
|
||||
var fp=document.getElementById('rtFinalPill');
|
||||
if(fp){ if(mode==='direct'){ fp.textContent=_t('直连','Direct'); fp.className='pill is-success'; } else { fp.textContent=_t('走隧道','Tunnel'); fp.className='pill is-warning'; } }
|
||||
if(fp){ if(mode==='direct'){ fp.textContent=_ri('rr.actDirect'); fp.className='pill is-success'; } else { fp.textContent=_ri('rr.actProxy'); fp.className='pill is-warning'; } }
|
||||
var note=document.getElementById('rtModeNote');
|
||||
if(note){
|
||||
if(smart) note.innerHTML=_t('下方「我的规则」仅在<b>智能分流</b>模式生效。全局代理 / 全部直连为一刀切模式,忽略自定义规则(系统强制层仍保留)。','Rules below apply only in <b>Smart routing</b>. Global / Direct are one-size modes that ignore custom rules (system-forced layer stays).');
|
||||
@@ -2048,9 +2074,9 @@ var _rtBack=document.getElementById('rtBack'); if(_rtBack) _rtBack.addEventListe
|
||||
function closeModal(id){ var m=document.getElementById(id); if(m) m.classList.remove('is-open'); }
|
||||
|
||||
function pillFor(act){
|
||||
if(act==='proxy') return '<span class="pill is-warning">'+_t('走隧道','Tunnel')+'</span>';
|
||||
if(act==='reject') return '<span class="pill is-danger">'+_t('拒绝','Reject')+'</span>';
|
||||
return '<span class="pill is-success">'+_t('直连','Direct')+'</span>';
|
||||
if(act==='proxy') return '<span class="pill is-warning">'+_ri('rr.actProxy')+'</span>';
|
||||
if(act==='reject') return '<span class="pill is-danger">'+_ri('rr.actReject')+'</span>';
|
||||
return '<span class="pill is-success">'+_ri('rr.actDirect')+'</span>';
|
||||
}
|
||||
var TYPE={domain_suffix:['域名后缀','Domain suffix'],domain:['域名','Domain'],ip_cidr:['IP-CIDR','IP-CIDR'],geosite:['GeoSite','GeoSite'],geoip:['GeoIP','GeoIP']};
|
||||
function addRuleRow(type,val,act,prepend){
|
||||
|
||||
@@ -869,7 +869,7 @@
|
||||
<div class="setting-row is-tap" id="rowRouting">
|
||||
<span class="icon-box"><svg><use href="#i-compass"/></svg></span>
|
||||
<div class="st-body"><div class="st-title" data-i18n="navRouting">分流规则</div></div>
|
||||
<div class="st-trail" style="display:flex;align-items:center;gap:var(--space-2)"><span class="pill is-neutral">智能分流</span><svg style="width:18px;height:18px;color:var(--fg3)"><use href="#i-chevron-right"/></svg></div>
|
||||
<div class="st-trail" style="display:flex;align-items:center;gap:var(--space-2)"><span class="pill is-neutral" data-i18n="setSmartRoute">智能分流</span><svg style="width:18px;height:18px;color:var(--fg3)"><use href="#i-chevron-right"/></svg></div>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="icon-box"><svg><use href="#i-shield"/></svg></span>
|
||||
@@ -928,33 +928,33 @@
|
||||
<!-- 联系我们:唯一渠道来源(无「去哪买」引流) -->
|
||||
<section class="sub-screen" data-sub="routing">
|
||||
<div class="sub-scr sub-stack">
|
||||
<div class="sec-label">代理模式</div>
|
||||
<div class="sec-label" data-i18n="rr.proxyMode">代理模式</div>
|
||||
<div class="segswitch" id="rtModeSeg">
|
||||
<button class="segswitch-opt" data-mode="global"><span>全局代理</span></button>
|
||||
<button class="segswitch-opt is-active" data-mode="smart"><span>智能分流</span></button>
|
||||
<button class="segswitch-opt" data-mode="direct"><span>全部直连</span></button>
|
||||
<button class="segswitch-opt" data-mode="global"><span data-i18n="rr.modeGlobal">全局代理</span></button>
|
||||
<button class="segswitch-opt is-active" data-mode="smart"><span data-i18n="rr.modeSmart">智能分流</span></button>
|
||||
<button class="segswitch-opt" data-mode="direct"><span data-i18n="rr.modeDirect">全部直连</span></button>
|
||||
</div>
|
||||
<p class="sub-note" id="rtModeNote" style="text-align:left;margin:0">「我的规则」仅在<b>智能分流</b>模式生效;全局 / 直连为一刀切,忽略自定义规则(系统强制层仍保留)。</p>
|
||||
<div class="sec-label">内置规则</div>
|
||||
<div class="sec-label" data-i18n="rr.builtin">内置规则</div>
|
||||
<div class="card card-flush">
|
||||
<div class="setting-row" id="rtCnRow"><span class="icon-box"><svg><use href="#i-globe"/></svg></span><div class="st-body"><div class="st-title">国内直连</div><div class="st-sub">GeoIP / GeoSite CN</div></div><div class="st-trail"><button class="toggle is-on"><i></i></button></div></div>
|
||||
<div class="setting-row" id="rtCnRow"><span class="icon-box"><svg><use href="#i-globe"/></svg></span><div class="st-body"><div class="st-title" data-i18n="rr.cnDirect">国内直连</div><div class="st-sub">GeoIP / GeoSite CN</div></div><div class="st-trail"><button class="toggle is-on"><i></i></button></div></div>
|
||||
<div class="setting-row"><span class="icon-box"><svg><use href="#i-home"/></svg></span><div class="st-body"><div class="st-title" data-i18n="rr.lan">局域网 / 私网直连</div><div class="st-sub" data-i18n="rr.lanSub">强制,不可关</div></div><div class="st-trail"><span class="pill is-neutral" data-i18n="rr.forced">🔒</span></div></div>
|
||||
</div>
|
||||
<div id="rtMyRules">
|
||||
<div class="sec-label">我的规则 · 首命中生效</div>
|
||||
<div class="sec-label" data-i18n="rr.myRulesFirst">我的规则 · 首命中生效</div>
|
||||
<div class="card card-flush" id="rtRulesList">
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">git.51yanmei.com</div><div class="st-sub">域名后缀</div></div><div class="st-trail"><span class="pill is-success">直连</span></div></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">github.com</div><div class="st-sub">域名后缀</div></div><div class="st-trail"><span class="pill is-warning">走隧道</span></div></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">category-ads</div><div class="st-sub">GeoSite 规则集</div></div><div class="st-trail"><span class="pill is-danger">拒绝</span></div></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">git.51yanmei.com</div><div class="st-sub" data-i18n="rr.typeDomainSuffix">域名后缀</div></div><div class="st-trail"><span class="pill is-success" data-i18n="rr.actDirect">直连</span></div></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">github.com</div><div class="st-sub" data-i18n="rr.typeDomainSuffix">域名后缀</div></div><div class="st-trail"><span class="pill is-warning" data-i18n="rr.actProxy">走隧道</span></div></div>
|
||||
<div class="setting-row"><span style="color:var(--fg3);opacity:.55">≡</span><div class="st-body"><div class="st-title" style="font-family:var(--font-mono);font-size:var(--text-sm)">category-ads</div><div class="st-sub" data-i18n="rr.typeGeosite">GeoSite 规则集</div></div><div class="st-trail"><span class="pill is-danger" data-i18n="rr.actReject">拒绝</span></div></div>
|
||||
</div>
|
||||
<button class="btn btn-subtle btn-block" id="rtAddBtn"><svg><use href="#i-plus"/></svg>添加规则</button>
|
||||
<button class="btn btn-subtle btn-block" id="rtAddBtn"><svg><use href="#i-plus"/></svg><span data-i18n="rr.addRule">添加规则</span></button>
|
||||
<div style="display:flex;gap:var(--space-2)">
|
||||
<button class="btn btn-ghost" id="rtImportBtn" style="flex:1"><svg><use href="#i-download"/></svg>从文本导入</button>
|
||||
<button class="btn btn-ghost" id="rtResetBtn" style="flex:1"><svg><use href="#i-refresh-cw"/></svg>重置默认</button>
|
||||
<button class="btn btn-ghost" id="rtImportBtn" style="flex:1"><svg><use href="#i-download"/></svg><span data-i18n="rr.import">从文本导入</span></button>
|
||||
<button class="btn btn-ghost" id="rtResetBtn" style="flex:1"><svg><use href="#i-refresh-cw"/></svg><span data-i18n="rr.reset">重置默认</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sec-label">最终(未命中)</div>
|
||||
<div class="card card-flush"><div class="setting-row"><div class="st-body"><div class="st-title">FINAL 兜底</div></div><div class="st-trail"><span class="pill is-warning" id="rtFinalPill">走隧道</span></div></div></div>
|
||||
<div class="sec-label" data-i18n="rr.finalShort">最终(未命中)</div>
|
||||
<div class="card card-flush"><div class="setting-row"><div class="st-body"><div class="st-title" data-i18n="rr.finalFallback">FINAL 兜底</div></div><div class="st-trail"><span class="pill is-warning" id="rtFinalPill">走隧道</span></div></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1501,9 +1501,26 @@ const I18N = {
|
||||
relYday:'昨天',
|
||||
renew:'续费 / 升级',
|
||||
rowBuyPlan:'购买套餐',
|
||||
'rr.actDirect':'直连',
|
||||
'rr.actProxy':'走隧道',
|
||||
'rr.actReject':'拒绝',
|
||||
'rr.addRule':'添加规则',
|
||||
'rr.builtin':'内置规则',
|
||||
'rr.cnDirect':'国内直连',
|
||||
'rr.finalFallback':'FINAL 兜底',
|
||||
'rr.finalShort':'最终(未命中)',
|
||||
'rr.forced':'🔒',
|
||||
'rr.import':'从文本导入',
|
||||
'rr.lan':'局域网 / 私网直连',
|
||||
'rr.lanSub':'强制,不可关',
|
||||
'rr.modeDirect':'全部直连',
|
||||
'rr.modeGlobal':'全局代理',
|
||||
'rr.modeSmart':'智能分流',
|
||||
'rr.myRulesFirst':'我的规则 · 首命中生效',
|
||||
'rr.proxyMode':'代理模式',
|
||||
'rr.reset':'重置默认',
|
||||
'rr.typeDomainSuffix':'域名后缀',
|
||||
'rr.typeGeosite':'GeoSite 规则集',
|
||||
searchPh:'搜索国家 / 城市',
|
||||
secAccount:'账户信息',
|
||||
secBilling:'购买 · 订单 · 兑换',
|
||||
@@ -1750,9 +1767,26 @@ const I18N = {
|
||||
relYday:'yesterday',
|
||||
renew:'Renew / Upgrade',
|
||||
rowBuyPlan:'Purchase',
|
||||
'rr.actDirect':'Direct',
|
||||
'rr.actProxy':'Tunnel',
|
||||
'rr.actReject':'Reject',
|
||||
'rr.addRule':'Add rule',
|
||||
'rr.builtin':'Built-in rules',
|
||||
'rr.cnDirect':'China direct',
|
||||
'rr.finalFallback':'FINAL fallback',
|
||||
'rr.finalShort':'Final (no match)',
|
||||
'rr.forced':'🔒',
|
||||
'rr.import':'Import from text',
|
||||
'rr.lan':'LAN & private direct',
|
||||
'rr.lanSub':'Always on',
|
||||
'rr.modeDirect':'Direct',
|
||||
'rr.modeGlobal':'Global',
|
||||
'rr.modeSmart':'Smart',
|
||||
'rr.myRulesFirst':'My rules · first match wins',
|
||||
'rr.proxyMode':'Proxy mode',
|
||||
'rr.reset':'Reset defaults',
|
||||
'rr.typeDomainSuffix':'Domain suffix',
|
||||
'rr.typeGeosite':'GeoSite rule-set',
|
||||
searchPh:'Search country / city',
|
||||
secAccount:'Account info',
|
||||
secBilling:'Buy · Orders · Redeem',
|
||||
@@ -2455,6 +2489,8 @@ $('#rowRouting').addEventListener('click', ()=>{ subOpen('routing'); renderRouti
|
||||
(function(){
|
||||
if(!state.routeMode) state.routeMode='smart';
|
||||
const _t=(zh,en)=>state.lang==='zh'?zh:en;
|
||||
// 从生成的 I18N 单源取值(与静态 data-i18n pill 同源),state.lang 恒为 zh/en
|
||||
const _ri=k=>{ const o=I18N[state.lang]; return o&&o[k]!=null?o[k]:''; };
|
||||
const _esc=s=>String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||||
const INP='padding:10px 12px;border-radius:var(--radius-md);border:1px solid var(--border);background:var(--bg-subtle);color:var(--fg1);font-size:14px;font-family:inherit;width:100%;box-sizing:border-box';
|
||||
|
||||
@@ -2463,7 +2499,7 @@ $('#rowRouting').addEventListener('click', ()=>{ subOpen('routing'); renderRouti
|
||||
document.querySelectorAll('#rtModeSeg button').forEach(b=>b.classList.toggle('is-active', b.dataset.mode===mode));
|
||||
['rtCnRow','rtMyRules'].forEach(id=>{ const el=document.getElementById(id); if(!el) return; el.style.opacity=smart?'':'.4'; el.style.pointerEvents=smart?'':'none'; });
|
||||
const fp=document.getElementById('rtFinalPill');
|
||||
if(fp){ if(mode==='direct'){ fp.textContent=_t('直连','Direct'); fp.className='pill is-success'; } else { fp.textContent=_t('走隧道','Tunnel'); fp.className='pill is-warning'; } }
|
||||
if(fp){ if(mode==='direct'){ fp.textContent=_ri('rr.actDirect'); fp.className='pill is-success'; } else { fp.textContent=_ri('rr.actProxy'); fp.className='pill is-warning'; } }
|
||||
const note=document.getElementById('rtModeNote');
|
||||
if(note){
|
||||
if(smart) note.innerHTML=_t('「我的规则」仅在<b>智能分流</b>模式生效;全局 / 直连为一刀切,忽略自定义规则(系统强制层仍保留)。','Rules apply only in <b>Smart routing</b>; Global / Direct are one-size modes that ignore custom rules (system-forced layer stays).');
|
||||
@@ -2475,7 +2511,7 @@ $('#rowRouting').addEventListener('click', ()=>{ subOpen('routing'); renderRouti
|
||||
|
||||
const openM=id=>{ const m=document.getElementById(id); if(m){ m.classList.add('is-open'); m.onclick=e=>{ if(e.target===m) m.classList.remove('is-open'); }; } };
|
||||
const closeM=id=>{ const m=document.getElementById(id); if(m) m.classList.remove('is-open'); };
|
||||
const pillFor=act=> act==='proxy'?'<span class="pill is-warning">'+_t('走隧道','Tunnel')+'</span>' : act==='reject'?'<span class="pill is-danger">'+_t('拒绝','Reject')+'</span>' : '<span class="pill is-success">'+_t('直连','Direct')+'</span>';
|
||||
const pillFor=act=> act==='proxy'?'<span class="pill is-warning">'+_ri('rr.actProxy')+'</span>' : act==='reject'?'<span class="pill is-danger">'+_ri('rr.actReject')+'</span>' : '<span class="pill is-success">'+_ri('rr.actDirect')+'</span>';
|
||||
const TYPE={domain_suffix:['域名后缀','Domain suffix'],domain:['域名','Domain'],ip_cidr:['IP-CIDR','IP-CIDR'],geosite:['GeoSite','GeoSite'],geoip:['GeoIP','GeoIP']};
|
||||
function addRuleRow(type,val,act,prepend){
|
||||
const list=document.getElementById('rtRulesList'); if(!list) return;
|
||||
|
||||
Reference in New Issue
Block a user