ostp/ostp-gui/src/i18n.js

175 lines
7.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ── OSTP GUI Internationalization ─────────────────────────────────────────────
// Supports: English (en), Russian (ru)
const translations = {
en: {
// Home screen
status_disconnected: 'Disconnected',
status_connecting: 'Connecting...',
status_connected: 'Connected',
hint_tap: 'Tap to protect your traffic',
hint_connecting: 'Establishing secure tunnel...',
hint_connected: 'Your traffic is encrypted',
download: 'Download',
upload: 'Upload',
// Settings
settings_title: 'Configuration',
import_placeholder: 'Paste ostp:// share link here...',
import_btn: 'Import',
label_server: 'Server Address',
label_key: 'Access Key',
ph_key: 'Enter secure access key',
label_socks: 'Local Proxy Address',
label_dns: 'Custom DNS Server',
label_owndns: 'Built-in Server DNS',
owndns_hint: 'Route DNS queries through the VPN server (10.1.0.1)',
label_tun: 'TUN Tunnel Mode',
tun_hint: 'Route all system traffic (Admin req.)',
label_kill_switch: 'Kill Switch',
kill_switch_hint: 'Block non-VPN traffic when tunnel drops',
label_transport: 'Transport Protocol',
label_mtu: 'MTU Size',
label_transport: 'Transport Protocol',
label_sni: 'Stealth SNI (Fake Host)',
label_mtu: 'MTU Size',
label_mux: 'Multiplexing (Mux)',
mux_hint: 'Run multiple streams over one connection',
label_mux_sessions: 'Mux Sessions',
label_debug: 'Debug Logs',
debug_hint: 'Enable verbose internal event outputs',
excl_title: 'Exclusions',
excl_hint: '(one per line)',
excl_domains: 'Bypass Domains',
excl_ips: 'Bypass IPs / CIDR Ranges',
excl_processes: 'Bypass Processes',
save_btn: 'Save & Apply',
toast_saved: 'Configuration saved',
toast_imported: 'Configuration imported',
toast_error: 'Error',
err_server_req: 'Server address is required',
err_key_req: 'Access key is required',
label_autoconnect: 'Auto-connect',
autoconnect_hint: 'Connect automatically on startup',
label_launch_startup: 'Launch at Startup',
launch_startup_hint: 'Start OSTP with Windows',
cancel_btn: 'Cancel',
share_btn: 'Share',
share_title: 'Share configuration',
share_desc: 'Scan the QR or copy the link. The QR is generated locally — the access key never leaves this device.',
copy_btn: 'Copy link',
close_btn: 'Close',
wintun_missing_title: 'Wintun Driver Missing',
wintun_missing_desc: 'TUN mode requires the Wintun network driver (wintun.dll).',
wintun_step1: 'Download wintun.zip from the official site',
wintun_step2: 'Extract amd64\\wintun.dll from the archive',
wintun_step3: 'Place it here:',
wintun_step4: 'Restart the connection',
wintun_open_btn: 'Open wintun.net ↗',
},
ru: {
// Главный экран
status_disconnected: 'Отключено',
status_connecting: 'Подключение...',
status_connected: 'Подключено',
hint_tap: 'Нажмите для защиты трафика',
hint_connecting: 'Установка защищённого туннеля...',
hint_connected: 'Ваш трафик зашифрован',
download: 'Входящий',
upload: 'Исходящий',
// Настройки
settings_title: 'Настройки',
import_placeholder: 'Вставьте ostp:// ссылку...',
import_btn: 'Импорт',
label_server: 'Адрес сервера',
label_key: 'Ключ доступа',
ph_key: 'Введите ключ доступа',
label_socks: 'Адрес локального прокси',
label_dns: 'DNS сервер',
label_owndns: 'Встроенный DNS сервера',
owndns_hint: 'Направлять DNS-запросы через VPN сервер (10.1.0.1)',
label_tun: 'Режим TUN-туннеля',
tun_hint: 'Направить весь трафик (нужны права администратора)',
label_kill_switch: 'Kill Switch',
kill_switch_hint: 'Блокировать трафик вне VPN при обрыве связи',
label_transport: 'Транспортный протокол',
label_mtu: 'Размер MTU',
label_transport: 'Транспортный протокол',
label_sni: 'Маскировочный SNI',
label_mtu: 'Размер MTU',
label_mux: 'Мультиплексирование (Mux)',
mux_hint: 'Несколько потоков через одно соединение',
label_mux_sessions: 'Сессий Mux',
label_debug: 'Журнал отладки',
debug_hint: 'Включить подробный вывод событий',
excl_title: 'Исключения',
excl_hint: '(по одному на строку)',
excl_domains: 'Обход для доменов',
excl_ips: 'Обход для IP / CIDR',
excl_processes: 'Обход для процессов',
save_btn: 'Сохранить',
toast_saved: 'Настройки сохранены',
toast_imported: 'Настройки импортированы',
toast_error: 'Ошибка',
err_server_req: 'Укажите адрес сервера',
err_key_req: 'Укажите ключ доступа',
label_autoconnect: 'Автоподключение',
autoconnect_hint: 'Подключаться автоматически при запуске',
label_launch_startup: 'Запуск вместе с Windows',
launch_startup_hint: 'Автозапуск OSTP при входе в систему',
cancel_btn: 'Отмена',
share_btn: 'Поделиться',
share_title: 'Поделиться конфигурацией',
share_desc: 'Отсканируйте QR или скопируйте ссылку. QR генерируется локально — ключ доступа не покидает устройство.',
copy_btn: 'Копировать ссылку',
close_btn: 'Закрыть',
wintun_missing_title: 'Отсутствует драйвер Wintun',
wintun_missing_desc: 'Режим TUN требует сетевой драйвер Wintun (wintun.dll).',
wintun_step1: 'Скачайте wintun.zip с официального сайта',
wintun_step2: 'Извлеките amd64\\wintun.dll из архива',
wintun_step3: 'Поместите файл сюда:',
wintun_step4: 'Перезапустите подключение',
wintun_open_btn: 'Открыть wintun.net ↗',
},
};
let currentLang = localStorage.getItem('ostp_lang') || 'en';
export function t(key) {
const dict = translations[currentLang] || translations.en;
return dict[key] || translations.en[key] || key;
}
export function getLang() {
return currentLang;
}
export function setLang(lang) {
if (!translations[lang]) return;
currentLang = lang;
localStorage.setItem('ostp_lang', lang);
applyTranslations();
}
export function toggleLang() {
const next = currentLang === 'en' ? 'ru' : 'en';
setLang(next);
return next;
}
export function applyTranslations() {
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.getAttribute('data-i18n');
const value = t(key);
if (value) el.textContent = value;
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
const key = el.getAttribute('data-i18n-placeholder');
const value = t(key);
if (value) el.placeholder = value;
});
const langLabel = document.getElementById('lang-label');
if (langLabel) langLabel.textContent = currentLang.toUpperCase();
}