2026-04-13 09:46:02 +03:00
<!DOCTYPE html>
< html lang = "ru" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > AlpineRouter — Прокси< / title >
< link rel = "stylesheet" href = "style.css" >
< / head >
< body >
< header >
< div class = "header-left" >
< svg class = "logo" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" >
< path d = "M12 2L2 7l10 5 10-5-10-5z" / >
< path d = "M2 17l10 5 10-5" / >
< path d = "M2 12l10 5 10-5" / >
< / svg >
< h1 > AlpineRouter< / h1 >
< / div >
< div class = "header-right" >
< span id = "statusBadge" class = "svc-badge stopped" > Остановлен< / span >
< / div >
< / header >
< nav class = "tab-nav" >
< a href = "/" class = "tab-link" >
< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" width = "15" height = "15" >
< path d = "M12 2L2 7l10 5 10-5-10-5z" / >
< path d = "M2 17l10 5 10-5" / >
< path d = "M2 12l10 5 10-5" / >
< / svg >
Интерфейсы
< / a >
< a href = "/dhcp.html" class = "tab-link" >
< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" width = "15" height = "15" >
< path d = "M5 12h14M12 5l7 7-7 7" / >
< / svg >
DHCP сервер
< / a >
< a href = "/clients.html" class = "tab-link" >
< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" width = "15" height = "15" >
< circle cx = "9" cy = "7" r = "4" / > < path d = "M3 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2" / >
< path d = "M16 3.13a4 4 0 0 1 0 7.75M21 21v-2a4 4 0 0 0-3-3.87" / >
< / svg >
Клиенты
< / a >
2026-04-13 12:40:49 +03:00
< a href = "/firewall.html" class = "tab-link" >
2026-04-13 09:46:02 +03:00
< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" width = "15" height = "15" >
< path d = "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" / >
2026-04-13 12:40:49 +03:00
< path d = "M9 12l2 2 4-4" / >
< / svg >
Файрвол
< / a >
< a href = "/proxy.html" class = "tab-link active" >
< svg viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" width = "15" height = "15" >
< circle cx = "12" cy = "12" r = "3" / >
< path d = "M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83" / >
2026-04-13 09:46:02 +03:00
< / svg >
Прокси
< / a >
< / nav >
< main class = "proxy-main" >
< div id = "loading" class = "loading" >
< div class = "spinner" > < / div >
< span > Загрузка...< / span >
< / div >
<!-- Status Bar -->
< div id = "statusBar" class = "dhcp-status-bar hidden" >
< div class = "status-info" >
< span class = "status-label" > Mihomo< / span >
< span id = "statusText" class = "svc-badge stopped" > Остановлен< / span >
< / div >
< div class = "status-actions" >
< button class = "btn btn-success btn-sm" id = "startBtn" > Запустить< / button >
< button class = "btn btn-danger btn-sm" id = "stopBtn" disabled > Остановить< / button >
< button class = "btn btn-ghost btn-sm" id = "restartBtn" disabled > Перезапуск< / button >
< / div >
< / div >
<!-- Core Info -->
< div id = "coreInfo" class = "alert alert-error hidden" style = "margin-top:16px" >
< span id = "coreInfoMsg" > Ядро Mihomo не найдено. Загрузите бинарный файл в раздел «Ядро».< / span >
< / div >
<!-- Tabs inside proxy page -->
< div class = "proxy-tabs" >
< button class = "ptab active" data-tab = "proxies" > Прокси< / button >
< button class = "ptab" data-tab = "groups" > Группы< / button >
< button class = "ptab" data-tab = "rules" > Правила< / button >
< button class = "ptab" data-tab = "settings" > Настройки< / button >
< button class = "ptab" data-tab = "logs" > Логи< / button >
< button class = "ptab" data-tab = "core" > Ядро< / button >
< / div >
<!-- Proxies Tab -->
< div id = "tab-proxies" class = "ptab-content" >
< div class = "section-header" style = "margin-bottom:16px" >
< div style = "display:flex;align-items:center;justify-content:space-between" >
< div >
< h2 > Прокси-ноды< / h2 >
< div class = "section-desc" > Добавьте прокси-серверы для маршрутизации трафика< / div >
< / div >
< button class = "btn btn-primary btn-sm" id = "addProxyBtn" > + Добавить< / button >
< / div >
< / div >
< div id = "proxyList" class = "proxy-list" > < / div >
< div id = "proxyEmpty" class = "empty-state hidden" > Нет прокси-нод. Нажмите «Добавить» для создания.< / div >
< / div >
<!-- Groups Tab -->
< div id = "tab-groups" class = "ptab-content hidden" >
< div class = "section-header" style = "margin-bottom:16px" >
< div style = "display:flex;align-items:center;justify-content:space-between" >
< div >
< h2 > Группы прокси< / h2 >
< div class = "section-desc" > Балансировщики, селекторы и URL-тесты< / div >
< / div >
< button class = "btn btn-primary btn-sm" id = "addGroupBtn" > + Добавить группу< / button >
< / div >
< / div >
< div id = "groupList" class = "proxy-list" > < / div >
< div id = "groupEmpty" class = "empty-state hidden" > Нет групп. Нажмите «Добавить группу» для создания.< / div >
< / div >
<!-- Rules Tab -->
< div id = "tab-rules" class = "ptab-content hidden" >
< div class = "section-header" style = "margin-bottom:16px" >
< h2 > Правила маршрутизации< / h2 >
< div class = "section-desc" > Определите, какой трафик куда направляется. Правила apply сверху вниз.< / div >
< / div >
< div class = "form-row" style = "margin-bottom:12px" >
< button class = "btn btn-primary btn-sm" id = "addRuleBtn" > + Добавить правило< / button >
< button class = "btn btn-ghost btn-sm" id = "addBlockBtn" style = "margin-left:8px" > + Блокировка домена< / button >
< / div >
< div id = "rulesList" class = "rules-list" > < / div >
< / div >
<!-- Settings Tab -->
< div id = "tab-settings" class = "ptab-content hidden" >
< div class = "section-header" style = "margin-bottom:16px" >
< h2 > Настройки Mihomo< / h2 >
< / div >
< form id = "settingsForm" class = "proxy-form" >
< div class = "form-row" >
< label > Режим< / label >
< div class = "segmented" id = "modeSwitch" >
< button type = "button" class = "seg-btn active" data-mode = "rule" > Правила< / button >
< button type = "button" class = "seg-btn" data-mode = "global" > Глобальный< / button >
< button type = "button" class = "seg-btn" data-mode = "direct" > Прямой< / button >
< / div >
< / div >
< div class = "form-row" >
< label for = "mixedPort" > Mixed Port (HTTP+SOCKS)< / label >
< input type = "number" id = "mixedPort" value = "7890" >
< / div >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "allowLan" checked >
< span > Разрешить LAN< / span >
< / label >
< / div >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "ipv6" checked >
< span > IPv6< / span >
< / label >
< / div >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "tcpConcurrent" checked >
< span > TCP Concurrency< / span >
< / label >
< / div >
< div class = "form-divider" > < / div >
< h3 style = "color:var(--text);font-size:.95rem;margin-bottom:12px" > TProxy (прозрачный прокси)< / h3 >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "tproxyEnabled" >
< span > Включить TProxy< / span >
< / label >
< / div >
< div class = "form-row" >
< label for = "tproxyPort" > TProxy порт< / label >
< input type = "number" id = "tproxyPort" value = "7894" >
< / div >
< div class = "form-divider" > < / div >
< h3 style = "color:var(--text);font-size:.95rem;margin-bottom:12px" > DNS< / h3 >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "dnsEnabled" checked >
< span > DNS сервер< / span >
< / label >
< / div >
< div class = "form-row" >
< label for = "dnsListen" > DNS адрес< / label >
< input type = "text" id = "dnsListen" value = "0.0.0.0:1053" >
< / div >
< div class = "form-row" >
< label for = "dnsMode" > DNS режим< / label >
< div class = "segmented" id = "dnsModeSwitch" >
< button type = "button" class = "seg-btn active" data-mode = "redir-host" > redir-host< / button >
< button type = "button" class = "seg-btn" data-mode = "fake-ip" > fake-ip< / button >
< / div >
< / div >
< div class = "form-row" >
< label for = "dnsNameserver" > DNS серверы (по строке)< / label >
< textarea id = "dnsNameserver" rows = "3" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.85rem;font-family:'JetBrains Mono','Fira Code',monospace;width:100%;resize:vertical" > https://doh.pub/dns-query
https://dns.alidns.com/dns-query< / textarea >
< / div >
< div class = "form-row" >
< label for = "dnsFallback" > Fallback DNS (по строке)< / label >
< textarea id = "dnsFallback" rows = "2" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.85rem;font-family:'JetBrains Mono','Fira Code',monospace;width:100%;resize:vertical" > tls://8.8.8.8:853
tls://1.1.1.1:853< / textarea >
< / div >
< div class = "form-divider" > < / div >
< div class = "form-row" >
< label for = "externalController" > External Controller< / label >
< input type = "text" id = "externalController" value = "0.0.0.0:9090" >
< / div >
< div class = "form-row" >
< label for = "secret" > Secret (API ключ)< / label >
< input type = "text" id = "secret" placeholder = "опционально" >
< / div >
< div style = "margin-top:16px;display:flex;gap:8px" >
< button type = "submit" class = "btn btn-primary" > Сохранить настройки< / button >
< button type = "button" class = "btn btn-ghost" id = "saveAndRestartBtn" > Сохранить и перезапустить< / button >
< / div >
< / form >
< div class = "form-divider" style = "margin:20px 0" > < / div >
< h3 style = "color:var(--text);font-size:.95rem;margin-bottom:8px" > config.yaml (только чтение)< / h3 >
< div class = "section-desc" style = "margin-bottom:8px" > Текущий конфиг mihomo. Обновляется автоматически после сохранения настроек.< / div >
< div class = "form-row" >
< textarea id = "yamlPreview" rows = "18" readonly style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text-muted);padding:9px 12px;font-size:.8rem;font-family:'JetBrains Mono','Fira Code',monospace;width:100%;resize:vertical;opacity:.85" > < / textarea >
< / div >
< / div >
<!-- Logs Tab -->
< div id = "tab-logs" class = "ptab-content hidden" >
< div class = "section-header" style = "margin-bottom:16px" >
< div style = "display:flex;align-items:center;justify-content:space-between" >
< div >
< h2 > Логи ядра< / h2 >
< div class = "section-desc" > Вывод процесса mihomo (обновление каждые 500мс )< / div >
< / div >
< button class = "btn btn-ghost btn-sm" id = "clearLogsBtn" > Очистить< / button >
< / div >
< / div >
< div id = "logOutput" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);padding:12px;font-family:'JetBrains Mono','Fira Code',monospace;font-size:.78rem;color:var(--text-muted);min-height:200px;max-height:calc(100vh - 300px);overflow-y:auto;white-space:pre-wrap;word-break:break-all" > < / div >
< / div >
<!-- Core Tab -->
< div id = "tab-core" class = "ptab-content hidden" >
< div class = "section-header" style = "margin-bottom:16px" >
< h2 > Ядро Mihomo< / h2 >
< div class = "section-desc" > Управление бинарным файлом ядра< / div >
< / div >
< div id = "coreStatus" class = "proxy-card" style = "margin-bottom:16px" >
< div class = "card-info" >
< div class = "info-row" > < span class = "info-label" > Путь< / span > < span class = "info-val" id = "corePath" > —< / span > < / div >
< div class = "info-row" > < span class = "info-label" > Наличие< / span > < span class = "info-val" id = "coreExists" > —< / span > < / div >
< div class = "info-row" > < span class = "info-label" > PID< / span > < span class = "info-val" id = "corePid" > —< / span > < / div >
< / div >
< / div >
< div class = "form-divider" style = "margin-bottom:16px" > < / div >
< h3 style = "color:var(--text);font-size:.95rem;margin-bottom:12px" > Загрузить ядро< / h3 >
< div class = "section-desc" style = "margin-bottom:12px" > Загрузите бинарный файл mihomo (например, mihomo-linux-amd64). Файл автоматически определит архитектуру по имени.< / div >
< form id = "uploadCoreForm" >
< div class = "form-row" >
< input type = "file" id = "coreFile" accept = ".gz,.zip,application/octet-stream" style = "color:var(--text)" >
< / div >
< button type = "submit" class = "btn btn-primary btn-sm" style = "margin-top:8px" > Загрузить< / button >
< / form >
< div class = "form-divider" style = "margin:20px 0" > < / div >
< h3 style = "color:var(--text);font-size:.95rem;margin-bottom:12px" > Ручная конфигурация (config.yaml)< / h3 >
< div class = "section-desc" style = "margin-bottom:8px" > Редактировать конфигурационный файл напрямую< / div >
< div class = "form-row" >
< textarea id = "yamlEditor" rows = "20" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.8rem;font-family:'JetBrains Mono','Fira Code',monospace;width:100%;resize:vertical" > < / textarea >
< / div >
< div style = "margin-top:8px;display:flex;gap:8px" >
< button class = "btn btn-primary btn-sm" id = "yamlLoadBtn" > Загрузить< / button >
< button class = "btn btn-success btn-sm" id = "yamlSaveBtn" > Сохранить< / button >
< / div >
< / div >
< / div >
<!-- Proxy Modal -->
< div id = "proxyModal" class = "modal hidden" role = "dialog" aria-modal = "true" >
< div class = "modal-backdrop" id = "proxyModalBackdrop" > < / div >
< div class = "modal-box" style = "width:min(560px,calc(100vw - 40px))" >
< div class = "modal-header" >
< h2 id = "proxyModalTitle" > Добавить прокси< / h2 >
< button class = "btn-icon" id = "closeProxyModal" title = "Закрыть" > ✕< / button >
< / div >
< form id = "proxyForm" autocomplete = "off" style = "max-height:60vh;overflow-y:auto" >
< div class = "form-row" >
< label for = "proxyType" > Тип< / label >
< select id = "proxyType" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.9rem;width:100%" >
< option value = "ss" > Shadowsocks< / option >
< option value = "vmess" > VMess< / option >
< option value = "vless" > VLESS< / option >
< option value = "trojan" > Trojan< / option >
< option value = "hysteria2" > Hysteria2< / option >
< option value = "http" > HTTP< / option >
< option value = "socks5" > SOCKS5< / option >
< option value = "direct" > DIRECT< / option >
< / select >
< / div >
< div class = "form-row" >
< label for = "proxyName" > Имя< / label >
< input type = "text" id = "proxyName" placeholder = "my-proxy" >
< / div >
< div id = "proxyServerFields" >
< div class = "form-row" >
< label for = "proxyServer" > Сервер< / label >
< input type = "text" id = "proxyServer" placeholder = "example.com" >
< / div >
< div class = "form-row" >
< label for = "proxyPort" > Порт< / label >
< input type = "number" id = "proxyPort" placeholder = "443" >
< / div >
< / div >
< div id = "proxyAuthFields" class = "hidden" >
< div class = "form-row" >
< label for = "proxyUsername" > Имя пользователя< / label >
< input type = "text" id = "proxyUsername" placeholder = "username" >
< / div >
< div class = "form-row" >
< label for = "proxyPassword" > Пароль< / label >
< input type = "text" id = "proxyPassword" placeholder = "password" >
< / div >
< / div >
< div id = "proxyCipherField" class = "hidden" >
< div class = "form-row" >
< label for = "proxyCipher" > Шифр< / label >
< select id = "proxyCipher" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.9rem;width:100%" >
< option value = "auto" > auto< / option >
< option value = "aes-128-gcm" > aes-128-gcm< / option >
< option value = "aes-256-gcm" > aes-256-gcm< / option >
< option value = "chacha20-ietf-poly1305" > chacha20-ietf-poly1305< / option >
< option value = "none" > none< / option >
< / select >
< / div >
< / div >
< div id = "proxyUUIDField" class = "hidden" >
< div class = "form-row" >
< label for = "proxyUUID" > UUID< / label >
< input type = "text" id = "proxyUUID" placeholder = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" >
< / div >
< / div >
< div id = "proxyTrojanPassField" class = "hidden" >
< div class = "form-row" >
< label for = "proxyTrojanPass" > Пароль (Trojan)< / label >
< input type = "text" id = "proxyTrojanPass" placeholder = "password" >
< / div >
< / div >
< div id = "proxyHysteria2Fields" class = "hidden" >
< div class = "form-row" >
< label for = "proxyObfs" > Obfs тип< / label >
< input type = "text" id = "proxyObfs" placeholder = "salamander или пусто" >
< / div >
< div class = "form-row" >
< label for = "proxyObfsPass" > Obfs пароль< / label >
< input type = "text" id = "proxyObfsPass" placeholder = "obfs password" >
< / div >
< / div >
< div id = "proxyTLSField" class = "hidden" >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "proxyTLS" >
< span > TLS< / span >
< / label >
< / div >
< div class = "form-row" >
< label for = "proxySNI" > SNI (ServerName)< / label >
< input type = "text" id = "proxySNI" placeholder = "example.com" >
< / div >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "proxySkipCertVerify" >
< span > Пропустить проверку сертификата< / span >
< / label >
< / div >
< / div >
< div id = "proxyVlessFlowField" class = "hidden" >
< div class = "form-row" >
< label for = "proxyFlow" > Flow< / label >
< input type = "text" id = "proxyFlow" placeholder = "xtls-rprx-vision (опционально)" >
< / div >
< / div >
< div id = "proxyNetworkField" class = "hidden" >
< div class = "form-row" >
< label for = "proxyNetwork" > Транспорт< / label >
< select id = "proxyNetwork" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.9rem;width:100%" >
< option value = "" > tcp (по умолчанию)< / option >
< option value = "ws" > WebSocket< / option >
< option value = "grpc" > gRPC< / option >
< option value = "h2" > HTTP/2< / option >
< / select >
< / div >
< / div >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "proxyUDP" checked >
< span > UDP< / span >
< / label >
< / div >
< input type = "hidden" id = "proxyEditName" value = "" >
< / form >
< div class = "modal-footer" >
< button class = "btn btn-ghost" id = "cancelProxyBtn" > Отмена< / button >
< button class = "btn btn-primary" id = "saveProxyBtn" > Сохранить< / button >
< / div >
< / div >
< / div >
<!-- Group Modal -->
< div id = "groupModal" class = "modal hidden" role = "dialog" aria-modal = "true" >
< div class = "modal-backdrop" id = "groupModalBackdrop" > < / div >
< div class = "modal-box" style = "width:min(560px,calc(100vw - 40px))" >
< div class = "modal-header" >
< h2 id = "groupModalTitle" > Добавить группу< / h2 >
< button class = "btn-icon" id = "closeGroupModal" title = "Закрыть" > ✕< / button >
< / div >
< form id = "groupForm" autocomplete = "off" >
< div class = "form-row" >
< label for = "groupName" > Имя группы< / label >
< input type = "text" id = "groupName" placeholder = "proxy" >
< / div >
< div class = "form-row" >
< label for = "groupType" > Тип< / label >
< select id = "groupType" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.9rem;width:100%" >
< option value = "select" > Select (ручной выбор)< / option >
< option value = "url-test" > URL-test (автовыбор по задержке)< / option >
< option value = "fallback" > Fallback (резервный)< / option >
< option value = "load-balance" > Load Balance (балансировка)< / option >
< / select >
< / div >
< div id = "groupURLField" class = "hidden" >
< div class = "form-row" >
< label for = "groupURL" > URL тестирования< / label >
< input type = "text" id = "groupURL" value = "https://www.gstatic.com/generate_204" placeholder = "https://www.gstatic.com/generate_204" >
< / div >
< div class = "form-row" >
< label for = "groupInterval" > Интервал тестирования (сек)< / label >
< input type = "number" id = "groupInterval" value = "300" >
< / div >
< div class = "form-row" >
< label for = "groupTolerance" > Допуск (мс)< / label >
< input type = "number" id = "groupTolerance" value = "50" placeholder = "50" >
< / div >
< / div >
< div id = "groupLBStrategy" class = "hidden" >
< div class = "form-row" >
< label > Стратегия балансировки< / label >
< select id = "groupLBStrategy" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.9rem;width:100%" >
< option value = "round-robin" > Round Robin< / option >
< option value = "consistent-hashing" > Consistent Hashing< / option >
< option value = "sticky-sessions" > Sticky Sessions< / option >
< / select >
< / div >
< / div >
< div class = "form-row" >
< label > Прокси-ноды в группе< / label >
< div id = "groupProxyCheckboxes" style = "max-height:200px;overflow-y:auto;background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px" > < / div >
< / div >
< div class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "groupIncludeAll" >
< span > Включить все прокси автоматически< / span >
< / label >
< / div >
< div class = "form-row" >
< label for = "groupFilter" > Фильтр (regex)< / label >
< input type = "text" id = "groupFilter" placeholder = "напр. (?i)hk|hongkong" >
< / div >
< input type = "hidden" id = "groupEditName" value = "" >
< / form >
< div class = "modal-footer" >
< button class = "btn btn-ghost" id = "cancelGroupBtn" > Отмена< / button >
< button class = "btn btn-primary" id = "saveGroupBtn" > Сохранить< / button >
< / div >
< / div >
< / div >
<!-- Rule Modal -->
< div id = "ruleModal" class = "modal hidden" role = "dialog" aria-modal = "true" >
< div class = "modal-backdrop" id = "ruleModalBackdrop" > < / div >
< div class = "modal-box" style = "width:min(520px,calc(100vw - 40px))" >
< div class = "modal-header" >
< h2 id = "ruleModalTitle" > Добавить правило< / h2 >
< button class = "btn-icon" id = "closeRuleModal" title = "Закрыть" > ✕< / button >
< / div >
< form id = "ruleForm" autocomplete = "off" >
< div class = "form-row" >
< label for = "ruleType" > Тип правила< / label >
< select id = "ruleType" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.9rem;width:100%" >
< option value = "DOMAIN" > DOMAIN (точный домен)< / option >
< option value = "DOMAIN-SUFFIX" > DOMAIN-SUFFIX (домен суффикс)< / option >
< option value = "DOMAIN-KEYWORD" > DOMAIN-KEYWORD (ключевое слово)< / option >
< option value = "GEOSITE" > GEOSITE (геосайт)< / option >
< option value = "GEOIP" > GEOIP (г е о IP)< / option >
< option value = "IP-CIDR" > IP-CIDR (подсеть)< / option >
< option value = "SRC-IP-CIDR" > SRC-IP-CIDR (источник подсеть)< / option >
< option value = "DST-PORT" > DST-PORT (порт назначения)< / option >
< option value = "SRC-PORT" > SRC-PORT (порт источника)< / option >
< option value = "MATCH" > MATCH (всё)< / option >
< option value = "RULE-SET" > RULE-SET (набор правил)< / option >
< / select >
< / div >
< div id = "ruleValueField" class = "form-row" >
< label for = "ruleValue" > Значение< / label >
< input type = "text" id = "ruleValue" placeholder = "напр. google.com или 192.168.0.0/16" >
< / div >
< div class = "form-row" >
< label for = "ruleProxy" > Прокси / Группа< / label >
< select id = "ruleProxy" style = "background:var(--bg-deep);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);padding:9px 12px;font-size:.9rem;width:100%" >
< option value = "DIRECT" > DIRECT< / option >
< option value = "REJECT" > REJECT< / option >
< / select >
< / div >
< div id = "ruleNoResolveDiv" class = "form-row" >
< label class = "checkbox-label" >
< input type = "checkbox" id = "ruleNoResolve" checked >
< span > no-resolve< / span >
< / label >
< / div >
< / form >
< div class = "modal-footer" >
< button class = "btn btn-ghost" id = "cancelRuleBtn" > Отмена< / button >
< button class = "btn btn-primary" id = "saveRuleBtn" > Добавить< / button >
< / div >
< / div >
< / div >
<!-- Notification toast -->
< div id = "toast" class = "toast hidden" > < / div >
< script src = "proxy.js" > < / script >
< / body >
< / html >