Files
clawpanel/scripts/gen-patches-6lang.cjs
晴天 985d263dc6 feat: i18n 11 languages + website update + fix #139 #140 #141
i18n:
- Add 9 new locale files (ja/ko/de/es/fr/pt/ru/vi/zh-TW)
- Add multilingual README files for all 11 languages
- Add locale helper, index, and modular translation system
- Add translation generation scripts

Website (docs/index.html):
- Replace 公益AI接口 branding with 晴辰云AI接口
- Remove OpenClaw 独立安装包 promotion block
- Update SEO meta tags (description, keywords, OG, Twitter, JSON-LD)
- Add 11-language README links to footer
- Update 元宝派 link to new URL

Bug fixes:
- fix(cron): delivery format mode:'push' → mode:'announce', remove invalid 'to' field (fixes #141)
- fix(cron): allow single-channel users to select delivery channel
- fix(cron): preserve delivery field in job state for editing
- fix(models): add 'ollama' as recognized API type, prevent overwriting native ollama config (fixes #140)
- fix(models): skip /v1 append for ollama native API baseUrl
- fix(assistant): normalize 'google-generative-ai' consistently, add ollama hints
- fix(version): use CLI path classification for source detection on Windows (fixes #139)
- fix(version): default to 'official' instead of 'chinese' when source unknown
- fix(version): reorder npm global package check based on active CLI
2026-03-24 22:31:11 +08:00

295 lines
82 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.
/**
* Generate translation patch files for vi/es/pt/ru/fr/de
* Writes scripts/translations/{lang}/{module}.json
*/
const fs = require('fs')
const path = require('path')
const OUTDIR = path.resolve(__dirname, 'translations')
function w(lang, mod, data) {
const dir = path.join(OUTDIR, lang)
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
fs.writeFileSync(path.join(dir, mod + '.json'), JSON.stringify(data, null, 2))
}
const LANGS = ['vi', 'es', 'pt', 'ru', 'fr', 'de']
// ── toast ──
const toast = {
vi: { copySuccess: 'Đã sao chép', copyFailed: 'Sao chép thất bại' },
es: { copySuccess: 'Copiado al portapapeles', copyFailed: 'Error al copiar' },
pt: { copySuccess: 'Copiado', copyFailed: 'Falha ao copiar' },
ru: { copySuccess: 'Скопировано', copyFailed: 'Ошибка копирования' },
fr: { copySuccess: 'Copié', copyFailed: 'Échec de la copie' },
de: { copySuccess: 'Kopiert', copyFailed: 'Kopieren fehlgeschlagen' },
}
// ── modal ──
const modal = {
vi: { confirmTitle: 'Xác nhận', confirmOk: 'Đồng ý', confirmCancel: 'Hủy' },
es: { confirmTitle: 'Confirmar', confirmOk: 'Aceptar', confirmCancel: 'Cancelar' },
pt: { confirmTitle: 'Confirmar', confirmOk: 'OK', confirmCancel: 'Cancelar' },
ru: { confirmTitle: 'Подтвердите', confirmOk: 'ОК', confirmCancel: 'Отмена' },
fr: { confirmTitle: 'Confirmer', confirmOk: 'OK', confirmCancel: 'Annuler' },
de: { confirmTitle: 'Bestätigen', confirmOk: 'OK', confirmCancel: 'Abbrechen' },
}
// ── instance ──
const instance = {
vi: { local: 'Cục bộ', remote: 'Từ xa', docker: 'Docker', addInstance: 'Thêm instance', addRemote: 'Thêm instance từ xa', nameLabel: 'Tên', endpointLabel: 'Địa chỉ panel', adding: 'Đang thêm...', current: 'Hiện tại' },
es: { local: 'Local', remote: 'Remoto', docker: 'Docker', addInstance: 'Agregar instancia', addRemote: 'Agregar instancia remota', nameLabel: 'Nombre', endpointLabel: 'Dirección del panel', adding: 'Agregando...', current: 'Actual' },
pt: { local: 'Local', remote: 'Remoto', docker: 'Docker', addInstance: 'Adicionar instância', addRemote: 'Adicionar instância remota', nameLabel: 'Nome', endpointLabel: 'Endereço do painel', adding: 'Adicionando...', current: 'Atual' },
ru: { local: 'Локальный', remote: 'Удалённый', docker: 'Docker', addInstance: 'Добавить экземпляр', addRemote: 'Добавить удалённый', nameLabel: 'Имя', endpointLabel: 'Адрес панели', adding: 'Добавление...', current: 'Текущий' },
fr: { local: 'Local', remote: 'Distant', docker: 'Docker', addInstance: 'Ajouter une instance', addRemote: 'Ajouter une instance distante', nameLabel: 'Nom', endpointLabel: 'Adresse du panneau', adding: 'Ajout...', current: 'Actuel' },
de: { local: 'Lokal', remote: 'Remote', docker: 'Docker', addInstance: 'Instanz hinzufügen', addRemote: 'Remote-Instanz hinzufügen', nameLabel: 'Name', endpointLabel: 'Panel-Adresse', adding: 'Wird hinzugefügt...', current: 'Aktuell' },
}
// ── logs ──
const logs = {
vi: { title: 'Nhật ký', desc: 'Xem nhật ký dịch vụ OpenClaw', tabGateway: 'Gateway', tabGatewayErr: 'Lỗi Gateway', tabGuardian: 'Guardian', tabBackup: 'Sao lưu', tabAudit: 'Kiểm toán', searchPlaceholder: 'Tìm kiếm...', refresh: 'Làm mới', autoScroll: 'Tự động cuộn', loading: 'Đang tải...', empty: 'Không có nhật ký', loadFailed: 'Tải thất bại', noResults: 'Không có kết quả', searchFailed: 'Tìm kiếm thất bại' },
es: { title: 'Registros', desc: 'Ver registros del servicio OpenClaw', tabGateway: 'Gateway', tabGatewayErr: 'Errores Gateway', tabGuardian: 'Guardian', tabBackup: 'Respaldo', tabAudit: 'Auditoría', searchPlaceholder: 'Buscar...', refresh: 'Actualizar', autoScroll: 'Auto-desplazar', loading: 'Cargando...', empty: 'Sin registros', loadFailed: 'Error al cargar', noResults: 'Sin resultados', searchFailed: 'Búsqueda fallida' },
pt: { title: 'Logs', desc: 'Ver logs do serviço OpenClaw', tabGateway: 'Gateway', tabGatewayErr: 'Erros Gateway', tabGuardian: 'Guardian', tabBackup: 'Backup', tabAudit: 'Auditoria', searchPlaceholder: 'Pesquisar...', refresh: 'Atualizar', autoScroll: 'Rolagem auto', loading: 'Carregando...', empty: 'Sem logs', loadFailed: 'Falha ao carregar', noResults: 'Sem resultados', searchFailed: 'Pesquisa falhou' },
ru: { title: 'Журналы', desc: 'Просмотр журналов OpenClaw', tabGateway: 'Gateway', tabGatewayErr: 'Ошибки Gateway', tabGuardian: 'Guardian', tabBackup: 'Резервное копирование', tabAudit: 'Аудит', searchPlaceholder: 'Поиск...', refresh: 'Обновить', autoScroll: 'Автопрокрутка', loading: 'Загрузка...', empty: 'Нет записей', loadFailed: 'Ошибка загрузки', noResults: 'Ничего не найдено', searchFailed: 'Ошибка поиска' },
fr: { title: 'Journaux', desc: 'Voir les journaux OpenClaw', tabGateway: 'Gateway', tabGatewayErr: 'Erreurs Gateway', tabGuardian: 'Guardian', tabBackup: 'Sauvegarde', tabAudit: 'Audit', searchPlaceholder: 'Rechercher...', refresh: 'Actualiser', autoScroll: 'Défilement auto', loading: 'Chargement...', empty: 'Aucun journal', loadFailed: 'Échec du chargement', noResults: 'Aucun résultat', searchFailed: 'Échec de la recherche' },
de: { title: 'Protokolle', desc: 'OpenClaw-Protokolle anzeigen', tabGateway: 'Gateway', tabGatewayErr: 'Gateway-Fehler', tabGuardian: 'Guardian', tabBackup: 'Backup', tabAudit: 'Audit', searchPlaceholder: 'Suchen...', refresh: 'Aktualisieren', autoScroll: 'Auto-Scrollen', loading: 'Laden...', empty: 'Keine Protokolle', loadFailed: 'Laden fehlgeschlagen', noResults: 'Keine Ergebnisse', searchFailed: 'Suche fehlgeschlagen' },
}
// ── sidebar ──
const sidebar = {
vi: { collapse: 'Thu gọn', closeMenu: 'Đóng menu', themeLight: 'Sáng', themeDark: 'Tối', sectionMonitor: 'Giám sát', sectionConfig: 'Cấu hình', sectionData: 'Dữ liệu', sectionExtension: 'Mở rộng', dashboard: 'Bảng điều khiển', assistant: 'Trợ lý', chat: 'Trò chuyện', services: 'Dịch vụ', logs: 'Nhật ký', models: 'Mô hình', agents: 'Agent', gateway: 'Gateway', channels: 'Kênh', communication: 'Truyền thông', security: 'Bảo mật', memory: 'Bộ nhớ', cron: 'Tác vụ định kỳ', usage: 'Sử dụng', skills: 'Skills', settings: 'Cài đặt', chatDebug: 'Chẩn đoán', about: 'Giới thiệu', setup: 'Thiết lập' },
es: { collapse: 'Colapsar', closeMenu: 'Cerrar menú', themeLight: 'Claro', themeDark: 'Oscuro', sectionMonitor: 'Monitoreo', sectionConfig: 'Configuración', sectionData: 'Datos', sectionExtension: 'Extensiones', dashboard: 'Panel', assistant: 'Asistente', chat: 'Chat', services: 'Servicios', logs: 'Registros', models: 'Modelos', agents: 'Agentes', gateway: 'Gateway', channels: 'Canales', communication: 'Comunicación', security: 'Seguridad', memory: 'Memoria', cron: 'Tareas', usage: 'Uso', skills: 'Skills', settings: 'Configuración', chatDebug: 'Diagnóstico', about: 'Acerca de', setup: 'Configuración inicial' },
pt: { collapse: 'Recolher', closeMenu: 'Fechar menu', themeLight: 'Claro', themeDark: 'Escuro', sectionMonitor: 'Monitoramento', sectionConfig: 'Configuração', sectionData: 'Dados', sectionExtension: 'Extensões', dashboard: 'Painel', assistant: 'Assistente', chat: 'Chat', services: 'Serviços', logs: 'Logs', models: 'Modelos', agents: 'Agentes', gateway: 'Gateway', channels: 'Canais', communication: 'Comunicação', security: 'Segurança', memory: 'Memória', cron: 'Tarefas', usage: 'Uso', skills: 'Skills', settings: 'Configurações', chatDebug: 'Diagnóstico', about: 'Sobre', setup: 'Configuração inicial' },
ru: { collapse: 'Свернуть', closeMenu: 'Закрыть меню', themeLight: 'Светлая', themeDark: 'Тёмная', sectionMonitor: 'Мониторинг', sectionConfig: 'Настройки', sectionData: 'Данные', sectionExtension: 'Расширения', dashboard: 'Панель', assistant: 'Ассистент', chat: 'Чат', services: 'Сервисы', logs: 'Журналы', models: 'Модели', agents: 'Агенты', gateway: 'Gateway', channels: 'Каналы', communication: 'Коммуникации', security: 'Безопасность', memory: 'Память', cron: 'Планировщик', usage: 'Использование', skills: 'Skills', settings: 'Настройки', chatDebug: 'Диагностика', about: 'О программе', setup: 'Начальная настройка' },
fr: { collapse: 'Réduire', closeMenu: 'Fermer le menu', themeLight: 'Clair', themeDark: 'Sombre', sectionMonitor: 'Surveillance', sectionConfig: 'Configuration', sectionData: 'Données', sectionExtension: 'Extensions', dashboard: 'Tableau de bord', assistant: 'Assistant', chat: 'Chat', services: 'Services', logs: 'Journaux', models: 'Modèles', agents: 'Agents', gateway: 'Gateway', channels: 'Canaux', communication: 'Communication', security: 'Sécurité', memory: 'Mémoire', cron: 'Tâches planifiées', usage: 'Utilisation', skills: 'Skills', settings: 'Paramètres', chatDebug: 'Diagnostic', about: 'À propos', setup: 'Configuration initiale' },
de: { collapse: 'Einklappen', closeMenu: 'Menü schließen', themeLight: 'Hell', themeDark: 'Dunkel', sectionMonitor: 'Überwachung', sectionConfig: 'Konfiguration', sectionData: 'Daten', sectionExtension: 'Erweiterungen', dashboard: 'Dashboard', assistant: 'Assistent', chat: 'Live-Chat', services: 'Dienste', logs: 'Protokolle', models: 'Modelle', agents: 'Agenten', gateway: 'Gateway', channels: 'Kanäle', communication: 'Kommunikation', security: 'Sicherheit', memory: 'Speicher', cron: 'Geplante Aufgaben', usage: 'Nutzung', skills: 'Skills', settings: 'Einstellungen', chatDebug: 'Diagnose', about: 'Über', setup: 'Ersteinrichtung' },
}
// Write small modules
for (const mod of [
['toast', toast], ['modal', modal], ['instance', instance],
['logs', logs], ['sidebar', sidebar],
]) {
for (const lang of LANGS) {
if (mod[1][lang]) w(lang, mod[0], mod[1][lang])
}
}
console.log('✓ Small modules: toast, modal, instance, logs, sidebar (6 langs)')
// ── dashboard (core keys) ──
const dashboard = {
vi: { title: 'Bảng điều khiển', desc: 'Tổng quan trạng thái OpenClaw', gateway: 'Gateway', notStarted: 'Chưa khởi động', versionLabel: 'Phiên bản', agentFleet: 'Đội Agent', defaultAgent: 'Mặc định', modelPool: 'Nhóm mô hình', baseServices: 'Dịch vụ cơ bản', controlUI: 'Control UI', restartGw: 'Khởi động lại Gateway', checkUpdate: 'Kiểm tra cập nhật', createBackup: 'Tạo bản sao lưu', recentLogs: 'Nhật ký gần đây', cliPath: 'Đường dẫn CLI', retry: 'Thử lại', notSet: 'Chưa đặt', port: 'Cổng', startBtn: 'Khởi động', stopBtn: 'Dừng', restartBtn: 'Khởi động lại', primaryModel: 'Mô hình chính', noLogs: 'Không có nhật ký', starting: 'Đang khởi động...', stopping: 'Đang dừng...', restarting: 'Đang khởi động lại...', checking: 'Đang kiểm tra...', upToDate: 'Đã cập nhật', backingUp: 'Đang sao lưu...', backupFail: 'Sao lưu thất bại' },
es: { title: 'Panel', desc: 'Resumen del estado de OpenClaw', gateway: 'Gateway', notStarted: 'No iniciado', versionLabel: 'Versión', agentFleet: 'Flota de Agentes', defaultAgent: 'Predeterminado', modelPool: 'Pool de modelos', baseServices: 'Servicios base', controlUI: 'Control UI', restartGw: 'Reiniciar Gateway', checkUpdate: 'Buscar actualizaciones', createBackup: 'Crear respaldo', recentLogs: 'Registros recientes', cliPath: 'Ruta CLI', retry: 'Reintentar', notSet: 'No configurado', port: 'Puerto', startBtn: 'Iniciar', stopBtn: 'Detener', restartBtn: 'Reiniciar', primaryModel: 'Modelo principal', noLogs: 'Sin registros', starting: 'Iniciando...', stopping: 'Deteniendo...', restarting: 'Reiniciando...', checking: 'Verificando...', upToDate: 'Actualizado', backingUp: 'Respaldando...', backupFail: 'Respaldo fallido' },
pt: { title: 'Painel', desc: 'Visão geral do estado do OpenClaw', gateway: 'Gateway', notStarted: 'Não iniciado', versionLabel: 'Versão', agentFleet: 'Frota de Agentes', defaultAgent: 'Padrão', modelPool: 'Pool de modelos', baseServices: 'Serviços base', controlUI: 'Control UI', restartGw: 'Reiniciar Gateway', checkUpdate: 'Verificar atualizações', createBackup: 'Criar backup', recentLogs: 'Logs recentes', cliPath: 'Caminho CLI', retry: 'Tentar novamente', notSet: 'Não definido', port: 'Porta', startBtn: 'Iniciar', stopBtn: 'Parar', restartBtn: 'Reiniciar', primaryModel: 'Modelo principal', noLogs: 'Sem logs', starting: 'Iniciando...', stopping: 'Parando...', restarting: 'Reiniciando...', checking: 'Verificando...', upToDate: 'Atualizado', backingUp: 'Fazendo backup...', backupFail: 'Falha no backup' },
ru: { title: 'Панель', desc: 'Обзор состояния OpenClaw', gateway: 'Gateway', notStarted: 'Не запущен', versionLabel: 'Версия', agentFleet: 'Флот агентов', defaultAgent: 'По умолчанию', modelPool: 'Пул моделей', baseServices: 'Базовые сервисы', controlUI: 'Control UI', restartGw: 'Перезапустить Gateway', checkUpdate: 'Проверить обновления', createBackup: 'Создать резервную копию', recentLogs: 'Последние записи', cliPath: 'Путь CLI', retry: 'Повторить', notSet: 'Не задано', port: 'Порт', startBtn: 'Запустить', stopBtn: 'Остановить', restartBtn: 'Перезапустить', primaryModel: 'Основная модель', noLogs: 'Нет записей', starting: 'Запуск...', stopping: 'Остановка...', restarting: 'Перезапуск...', checking: 'Проверка...', upToDate: 'Актуально', backingUp: 'Резервное копирование...', backupFail: 'Ошибка резервного копирования' },
fr: { title: 'Tableau de bord', desc: "Vue d'ensemble de l'état OpenClaw", gateway: 'Gateway', notStarted: 'Non démarré', versionLabel: 'Version', agentFleet: "Flotte d'Agents", defaultAgent: 'Par défaut', modelPool: 'Pool de modèles', baseServices: 'Services de base', controlUI: 'Control UI', restartGw: 'Redémarrer Gateway', checkUpdate: 'Vérifier les mises à jour', createBackup: 'Créer une sauvegarde', recentLogs: 'Journaux récents', cliPath: 'Chemin CLI', retry: 'Réessayer', notSet: 'Non défini', port: 'Port', startBtn: 'Démarrer', stopBtn: 'Arrêter', restartBtn: 'Redémarrer', primaryModel: 'Modèle principal', noLogs: 'Aucun journal', starting: 'Démarrage...', stopping: 'Arrêt...', restarting: 'Redémarrage...', checking: 'Vérification...', upToDate: 'À jour', backingUp: 'Sauvegarde...', backupFail: 'Échec de la sauvegarde' },
de: { title: 'Dashboard', desc: 'OpenClaw-Statusübersicht', gateway: 'Gateway', notStarted: 'Nicht gestartet', versionLabel: 'Version', agentFleet: 'Agent-Flotte', defaultAgent: 'Standard', modelPool: 'Modell-Pool', baseServices: 'Basisdienste', controlUI: 'Control UI', restartGw: 'Gateway neustarten', checkUpdate: 'Updates prüfen', createBackup: 'Backup erstellen', recentLogs: 'Aktuelle Protokolle', cliPath: 'CLI-Pfad', retry: 'Wiederholen', notSet: 'Nicht gesetzt', port: 'Port', startBtn: 'Starten', stopBtn: 'Stoppen', restartBtn: 'Neustarten', primaryModel: 'Primäres Modell', noLogs: 'Keine Protokolle', starting: 'Wird gestartet...', stopping: 'Wird gestoppt...', restarting: 'Wird neugestartet...', checking: 'Wird geprüft...', upToDate: 'Aktuell', backingUp: 'Backup wird erstellt...', backupFail: 'Backup fehlgeschlagen' },
}
// ── services (core keys) ──
const services = {
vi: { title: 'Quản lý dịch vụ', desc: 'Khởi động, dừng và giám sát dịch vụ OpenClaw', gatewayTitle: 'Dịch vụ Gateway', guardianTitle: 'Dịch vụ Guardian', status: 'Trạng thái', pid: 'PID', uptime: 'Thời gian hoạt động', port: 'Cổng', host: 'Máy chủ', start: 'Khởi động', stop: 'Dừng', restart: 'Khởi động lại', forceKill: 'Buộc dừng', viewLogs: 'Xem nhật ký', starting: 'Đang khởi động...', stopping: 'Đang dừng...', restarting: 'Đang khởi động lại...', loadFail: 'Tải trạng thái thất bại', healthCheck: 'Kiểm tra sức khỏe', healthOk: 'Hoạt động bình thường', healthFail: 'Không phản hồi' },
es: { title: 'Gestión de servicios', desc: 'Iniciar, detener y monitorear servicios OpenClaw', gatewayTitle: 'Servicio Gateway', guardianTitle: 'Servicio Guardian', status: 'Estado', pid: 'PID', uptime: 'Tiempo activo', port: 'Puerto', host: 'Host', start: 'Iniciar', stop: 'Detener', restart: 'Reiniciar', forceKill: 'Forzar cierre', viewLogs: 'Ver registros', starting: 'Iniciando...', stopping: 'Deteniendo...', restarting: 'Reiniciando...', loadFail: 'Error al cargar estado', healthCheck: 'Verificación de salud', healthOk: 'Funcionando correctamente', healthFail: 'Sin respuesta' },
pt: { title: 'Gestão de serviços', desc: 'Iniciar, parar e monitorar serviços OpenClaw', gatewayTitle: 'Serviço Gateway', guardianTitle: 'Serviço Guardian', status: 'Status', pid: 'PID', uptime: 'Tempo ativo', port: 'Porta', host: 'Host', start: 'Iniciar', stop: 'Parar', restart: 'Reiniciar', forceKill: 'Forçar encerramento', viewLogs: 'Ver logs', starting: 'Iniciando...', stopping: 'Parando...', restarting: 'Reiniciando...', loadFail: 'Falha ao carregar status', healthCheck: 'Verificação de saúde', healthOk: 'Funcionando normalmente', healthFail: 'Sem resposta' },
ru: { title: 'Управление сервисами', desc: 'Запуск, остановка и мониторинг сервисов OpenClaw', gatewayTitle: 'Сервис Gateway', guardianTitle: 'Сервис Guardian', status: 'Статус', pid: 'PID', uptime: 'Время работы', port: 'Порт', host: 'Хост', start: 'Запустить', stop: 'Остановить', restart: 'Перезапустить', forceKill: 'Принудительное завершение', viewLogs: 'Смотреть журналы', starting: 'Запуск...', stopping: 'Остановка...', restarting: 'Перезапуск...', loadFail: 'Ошибка загрузки статуса', healthCheck: 'Проверка состояния', healthOk: 'Работает нормально', healthFail: 'Нет ответа' },
fr: { title: 'Gestion des services', desc: 'Démarrer, arrêter et surveiller les services OpenClaw', gatewayTitle: 'Service Gateway', guardianTitle: 'Service Guardian', status: 'Statut', pid: 'PID', uptime: 'Temps de fonctionnement', port: 'Port', host: 'Hôte', start: 'Démarrer', stop: 'Arrêter', restart: 'Redémarrer', forceKill: 'Forcer la fermeture', viewLogs: 'Voir les journaux', starting: 'Démarrage...', stopping: 'Arrêt...', restarting: 'Redémarrage...', loadFail: 'Échec du chargement du statut', healthCheck: 'Vérification de santé', healthOk: 'Fonctionne normalement', healthFail: 'Pas de réponse' },
de: { title: 'Dienstverwaltung', desc: 'OpenClaw-Dienste starten, stoppen und überwachen', gatewayTitle: 'Gateway-Dienst', guardianTitle: 'Guardian-Dienst', status: 'Status', pid: 'PID', uptime: 'Betriebszeit', port: 'Port', host: 'Host', start: 'Starten', stop: 'Stoppen', restart: 'Neustarten', forceKill: 'Erzwungen beenden', viewLogs: 'Protokolle ansehen', starting: 'Wird gestartet...', stopping: 'Wird gestoppt...', restarting: 'Wird neugestartet...', loadFail: 'Status laden fehlgeschlagen', healthCheck: 'Zustandsprüfung', healthOk: 'Läuft normal', healthFail: 'Keine Antwort' },
}
// ── settings (core keys) ──
const settings = {
vi: { title: 'Cài đặt panel', desc: 'Quản lý cài đặt mạng, proxy và nguồn tải xuống', networkProxy: 'Proxy mạng', modelProxy: 'Proxy yêu cầu mô hình', npmRegistry: 'npm Registry', language: 'Ngôn ngữ hiển thị', languageHint: 'Chuyển đổi ngôn ngữ giao diện.', testProxy: 'Kiểm tra kết nối', clearProxy: 'Tắt proxy', resetDefault: 'Khôi phục mặc định', restarting: 'Đang khởi động lại...' },
es: { title: 'Configuración del panel', desc: 'Gestionar configuración de red, proxy y fuentes de descarga', networkProxy: 'Proxy de red', modelProxy: 'Proxy de solicitudes de modelo', npmRegistry: 'npm Registry', language: 'Idioma de visualización', languageHint: 'Cambiar el idioma de la interfaz.', testProxy: 'Probar conexión', clearProxy: 'Desactivar proxy', resetDefault: 'Restaurar predeterminado', restarting: 'Reiniciando...' },
pt: { title: 'Configurações do painel', desc: 'Gerenciar configurações de rede, proxy e fontes de download', networkProxy: 'Proxy de rede', modelProxy: 'Proxy de solicitações de modelo', npmRegistry: 'npm Registry', language: 'Idioma de exibição', languageHint: 'Alterar o idioma da interface.', testProxy: 'Testar conexão', clearProxy: 'Desativar proxy', resetDefault: 'Restaurar padrão', restarting: 'Reiniciando...' },
ru: { title: 'Настройки панели', desc: 'Управление сетью, прокси и источниками загрузки', networkProxy: 'Сетевой прокси', modelProxy: 'Прокси для запросов моделей', npmRegistry: 'npm Registry', language: 'Язык интерфейса', languageHint: 'Переключить язык интерфейса.', testProxy: 'Проверить подключение', clearProxy: 'Отключить прокси', resetDefault: 'Восстановить по умолчанию', restarting: 'Перезапуск...' },
fr: { title: 'Paramètres du panneau', desc: 'Gérer les paramètres réseau, proxy et sources de téléchargement', networkProxy: 'Proxy réseau', modelProxy: 'Proxy des requêtes de modèle', npmRegistry: 'npm Registry', language: "Langue d'affichage", languageHint: "Changer la langue de l'interface.", testProxy: 'Tester la connexion', clearProxy: 'Désactiver le proxy', resetDefault: 'Restaurer les paramètres par défaut', restarting: 'Redémarrage...' },
de: { title: 'Panel-Einstellungen', desc: 'Netzwerk-, Proxy- und Download-Einstellungen verwalten', networkProxy: 'Netzwerk-Proxy', modelProxy: 'Modell-Anfrage-Proxy', npmRegistry: 'npm Registry', language: 'Anzeigesprache', languageHint: 'Sprache der Benutzeroberfläche wechseln.', testProxy: 'Verbindung testen', clearProxy: 'Proxy deaktivieren', resetDefault: 'Standard wiederherstellen', restarting: 'Wird neugestartet...' },
}
// ── agents (core keys) ──
const agents = {
vi: { title: 'Quản lý Agent', desc: 'Tạo và quản lý OpenClaw Agent', addAgent: '+ Agent mới', noAgents: 'Không có Agent', loadFailed: 'Tải thất bại', default: 'Mặc định', backup: 'Sao lưu', edit: 'Sửa', delete: 'Xóa', notSet: 'Chưa đặt', addTitle: 'Agent mới', agentId: 'Agent ID', agentName: 'Tên', agentModel: 'Mô hình', created: 'Agent đã tạo', createFailed: 'Tạo thất bại', editTitle: 'Sửa Agent — {id}', updated: 'Đã cập nhật', updateFailed: 'Cập nhật thất bại', deleted: 'Đã xóa', deleteFailed: 'Xóa thất bại' },
es: { title: 'Gestión de Agentes', desc: 'Crear y gestionar OpenClaw Agents', addAgent: '+ Nuevo Agent', noAgents: 'Sin Agentes', loadFailed: 'Error al cargar', default: 'Predeterminado', backup: 'Respaldo', edit: 'Editar', delete: 'Eliminar', notSet: 'No configurado', addTitle: 'Nuevo Agent', agentId: 'Agent ID', agentName: 'Nombre', agentModel: 'Modelo', created: 'Agent creado', createFailed: 'Error al crear', editTitle: 'Editar Agent — {id}', updated: 'Actualizado', updateFailed: 'Error al actualizar', deleted: 'Eliminado', deleteFailed: 'Error al eliminar' },
pt: { title: 'Gestão de Agentes', desc: 'Criar e gerenciar OpenClaw Agents', addAgent: '+ Novo Agent', noAgents: 'Sem Agentes', loadFailed: 'Falha ao carregar', default: 'Padrão', backup: 'Backup', edit: 'Editar', delete: 'Excluir', notSet: 'Não definido', addTitle: 'Novo Agent', agentId: 'Agent ID', agentName: 'Nome', agentModel: 'Modelo', created: 'Agent criado', createFailed: 'Falha ao criar', editTitle: 'Editar Agent — {id}', updated: 'Atualizado', updateFailed: 'Falha ao atualizar', deleted: 'Excluído', deleteFailed: 'Falha ao excluir' },
ru: { title: 'Управление агентами', desc: 'Создание и управление агентами OpenClaw', addAgent: '+ Новый агент', noAgents: 'Нет агентов', loadFailed: 'Ошибка загрузки', default: 'По умолчанию', backup: 'Резервная копия', edit: 'Редактировать', delete: 'Удалить', notSet: 'Не задано', addTitle: 'Новый агент', agentId: 'ID агента', agentName: 'Имя', agentModel: 'Модель', created: 'Агент создан', createFailed: 'Ошибка создания', editTitle: 'Редактировать агента — {id}', updated: 'Обновлено', updateFailed: 'Ошибка обновления', deleted: 'Удалён', deleteFailed: 'Ошибка удаления' },
fr: { title: 'Gestion des Agents', desc: 'Créer et gérer les Agents OpenClaw', addAgent: '+ Nouvel Agent', noAgents: 'Aucun Agent', loadFailed: 'Échec du chargement', default: 'Par défaut', backup: 'Sauvegarde', edit: 'Modifier', delete: 'Supprimer', notSet: 'Non défini', addTitle: 'Nouvel Agent', agentId: 'ID Agent', agentName: 'Nom', agentModel: 'Modèle', created: 'Agent créé', createFailed: 'Échec de la création', editTitle: "Modifier l'Agent — {id}", updated: 'Mis à jour', updateFailed: 'Échec de la mise à jour', deleted: 'Supprimé', deleteFailed: 'Échec de la suppression' },
de: { title: 'Agenten-Verwaltung', desc: 'OpenClaw-Agenten erstellen und verwalten', addAgent: '+ Neuer Agent', noAgents: 'Keine Agenten', loadFailed: 'Laden fehlgeschlagen', default: 'Standard', backup: 'Backup', edit: 'Bearbeiten', delete: 'Löschen', notSet: 'Nicht gesetzt', addTitle: 'Neuer Agent', agentId: 'Agent-ID', agentName: 'Name', agentModel: 'Modell', created: 'Agent erstellt', createFailed: 'Erstellen fehlgeschlagen', editTitle: 'Agent bearbeiten — {id}', updated: 'Aktualisiert', updateFailed: 'Aktualisierung fehlgeschlagen', deleted: 'Gelöscht', deleteFailed: 'Löschen fehlgeschlagen' },
}
// ── gateway (core keys) ──
const gateway = {
vi: { title: 'Gateway', desc: 'Cấu hình và quản lý Gateway', status: 'Trạng thái', running: 'Đang chạy', stopped: 'Đã dừng', port: 'Cổng', saveConfig: 'Lưu cấu hình', saved: 'Đã lưu cấu hình Gateway', saveFailed: 'Lưu thất bại', restartRequired: 'Cần khởi động lại Gateway', restartNow: 'Khởi động lại ngay', configLoadFail: 'Tải cấu hình thất bại', pairingTitle: 'Ghép nối thiết bị', pairedDevices: 'Thiết bị đã ghép nối', noPairedDevices: 'Chưa có thiết bị ghép nối' },
es: { title: 'Gateway', desc: 'Configurar y gestionar Gateway', status: 'Estado', running: 'Ejecutando', stopped: 'Detenido', port: 'Puerto', saveConfig: 'Guardar configuración', saved: 'Configuración de Gateway guardada', saveFailed: 'Error al guardar', restartRequired: 'Se requiere reiniciar Gateway', restartNow: 'Reiniciar ahora', configLoadFail: 'Error al cargar configuración', pairingTitle: 'Emparejamiento de dispositivos', pairedDevices: 'Dispositivos emparejados', noPairedDevices: 'Sin dispositivos emparejados' },
pt: { title: 'Gateway', desc: 'Configurar e gerenciar Gateway', status: 'Status', running: 'Em execução', stopped: 'Parado', port: 'Porta', saveConfig: 'Salvar configuração', saved: 'Configuração do Gateway salva', saveFailed: 'Falha ao salvar', restartRequired: 'É necessário reiniciar o Gateway', restartNow: 'Reiniciar agora', configLoadFail: 'Falha ao carregar configuração', pairingTitle: 'Pareamento de dispositivos', pairedDevices: 'Dispositivos pareados', noPairedDevices: 'Nenhum dispositivo pareado' },
ru: { title: 'Gateway', desc: 'Настройка и управление Gateway', status: 'Статус', running: 'Работает', stopped: 'Остановлен', port: 'Порт', saveConfig: 'Сохранить настройки', saved: 'Настройки Gateway сохранены', saveFailed: 'Ошибка сохранения', restartRequired: 'Требуется перезапуск Gateway', restartNow: 'Перезапустить сейчас', configLoadFail: 'Ошибка загрузки настроек', pairingTitle: 'Сопряжение устройств', pairedDevices: 'Сопряжённые устройства', noPairedDevices: 'Нет сопряжённых устройств' },
fr: { title: 'Gateway', desc: 'Configurer et gérer Gateway', status: 'Statut', running: 'En cours', stopped: 'Arrêté', port: 'Port', saveConfig: 'Enregistrer la configuration', saved: 'Configuration Gateway enregistrée', saveFailed: 'Échec de la sauvegarde', restartRequired: 'Redémarrage de Gateway requis', restartNow: 'Redémarrer maintenant', configLoadFail: 'Échec du chargement de la configuration', pairingTitle: 'Appairage des appareils', pairedDevices: 'Appareils appairés', noPairedDevices: 'Aucun appareil appairé' },
de: { title: 'Gateway', desc: 'Gateway konfigurieren und verwalten', status: 'Status', running: 'Läuft', stopped: 'Gestoppt', port: 'Port', saveConfig: 'Konfiguration speichern', saved: 'Gateway-Konfiguration gespeichert', saveFailed: 'Speichern fehlgeschlagen', restartRequired: 'Gateway-Neustart erforderlich', restartNow: 'Jetzt neustarten', configLoadFail: 'Konfiguration laden fehlgeschlagen', pairingTitle: 'Gerätekopplung', pairedDevices: 'Gekoppelte Geräte', noPairedDevices: 'Keine gekoppelten Geräte' },
}
// ── models (core keys) ──
const models = {
vi: { title: 'Cấu hình mô hình', desc: 'Quản lý nhà cung cấp và mô hình AI', addProvider: '+ Thêm nhà cung cấp', noProviders: 'Không có nhà cung cấp', providerName: 'Tên nhà cung cấp', baseUrl: 'Base URL', apiKey: 'API Key', models: 'Mô hình', addModel: 'Thêm mô hình', saveProvider: 'Lưu', testConnection: 'Kiểm tra kết nối', testing: 'Đang kiểm tra...', testSuccess: 'Kết nối thành công', testFailed: 'Kết nối thất bại', fetchModels: 'Lấy danh sách mô hình', primaryModel: 'Mô hình chính', enabled: 'Đã bật', disabled: 'Đã tắt', loadFailed: 'Tải cấu hình thất bại' },
es: { title: 'Configuración de modelos', desc: 'Gestionar proveedores y modelos de IA', addProvider: '+ Agregar proveedor', noProviders: 'Sin proveedores', providerName: 'Nombre del proveedor', baseUrl: 'Base URL', apiKey: 'API Key', models: 'Modelos', addModel: 'Agregar modelo', saveProvider: 'Guardar', testConnection: 'Probar conexión', testing: 'Probando...', testSuccess: 'Conexión exitosa', testFailed: 'Conexión fallida', fetchModels: 'Obtener lista de modelos', primaryModel: 'Modelo principal', enabled: 'Habilitado', disabled: 'Deshabilitado', loadFailed: 'Error al cargar configuración' },
pt: { title: 'Configuração de modelos', desc: 'Gerenciar provedores e modelos de IA', addProvider: '+ Adicionar provedor', noProviders: 'Sem provedores', providerName: 'Nome do provedor', baseUrl: 'Base URL', apiKey: 'API Key', models: 'Modelos', addModel: 'Adicionar modelo', saveProvider: 'Salvar', testConnection: 'Testar conexão', testing: 'Testando...', testSuccess: 'Conexão bem-sucedida', testFailed: 'Conexão falhou', fetchModels: 'Obter lista de modelos', primaryModel: 'Modelo principal', enabled: 'Ativado', disabled: 'Desativado', loadFailed: 'Falha ao carregar configuração' },
ru: { title: 'Настройка моделей', desc: 'Управление провайдерами и моделями ИИ', addProvider: '+ Добавить провайдера', noProviders: 'Нет провайдеров', providerName: 'Имя провайдера', baseUrl: 'Base URL', apiKey: 'API Key', models: 'Модели', addModel: 'Добавить модель', saveProvider: 'Сохранить', testConnection: 'Проверить подключение', testing: 'Проверка...', testSuccess: 'Подключение успешно', testFailed: 'Ошибка подключения', fetchModels: 'Получить список моделей', primaryModel: 'Основная модель', enabled: 'Включено', disabled: 'Отключено', loadFailed: 'Ошибка загрузки настроек' },
fr: { title: 'Configuration des modèles', desc: 'Gérer les fournisseurs et modèles IA', addProvider: '+ Ajouter un fournisseur', noProviders: 'Aucun fournisseur', providerName: 'Nom du fournisseur', baseUrl: 'Base URL', apiKey: 'API Key', models: 'Modèles', addModel: 'Ajouter un modèle', saveProvider: 'Enregistrer', testConnection: 'Tester la connexion', testing: 'Test en cours...', testSuccess: 'Connexion réussie', testFailed: 'Connexion échouée', fetchModels: 'Obtenir la liste des modèles', primaryModel: 'Modèle principal', enabled: 'Activé', disabled: 'Désactivé', loadFailed: 'Échec du chargement de la configuration' },
de: { title: 'Modell-Konfiguration', desc: 'KI-Anbieter und Modelle verwalten', addProvider: '+ Anbieter hinzufügen', noProviders: 'Keine Anbieter', providerName: 'Anbietername', baseUrl: 'Base URL', apiKey: 'API Key', models: 'Modelle', addModel: 'Modell hinzufügen', saveProvider: 'Speichern', testConnection: 'Verbindung testen', testing: 'Test läuft...', testSuccess: 'Verbindung erfolgreich', testFailed: 'Verbindung fehlgeschlagen', fetchModels: 'Modellliste abrufen', primaryModel: 'Primäres Modell', enabled: 'Aktiviert', disabled: 'Deaktiviert', loadFailed: 'Konfiguration laden fehlgeschlagen' },
}
// ── security ──
const security = {
vi: { title: 'Bảo mật', desc: 'Quản lý cài đặt bảo mật OpenClaw', toolPermissions: 'Quyền công cụ', savePermissions: 'Lưu quyền', permSaved: 'Quyền đã lưu', loadFailed: 'Tải cài đặt thất bại' },
es: { title: 'Seguridad', desc: 'Gestionar configuración de seguridad de OpenClaw', toolPermissions: 'Permisos de herramientas', savePermissions: 'Guardar permisos', permSaved: 'Permisos guardados', loadFailed: 'Error al cargar configuración' },
pt: { title: 'Segurança', desc: 'Gerenciar configurações de segurança do OpenClaw', toolPermissions: 'Permissões de ferramentas', savePermissions: 'Salvar permissões', permSaved: 'Permissões salvas', loadFailed: 'Falha ao carregar configurações' },
ru: { title: 'Безопасность', desc: 'Управление настройками безопасности OpenClaw', toolPermissions: 'Права инструментов', savePermissions: 'Сохранить права', permSaved: 'Права сохранены', loadFailed: 'Ошибка загрузки настроек' },
fr: { title: 'Sécurité', desc: 'Gérer les paramètres de sécurité OpenClaw', toolPermissions: 'Permissions des outils', savePermissions: 'Enregistrer les permissions', permSaved: 'Permissions enregistrées', loadFailed: 'Échec du chargement de la configuration' },
de: { title: 'Sicherheit', desc: 'OpenClaw-Sicherheitseinstellungen verwalten', toolPermissions: 'Werkzeug-Berechtigungen', savePermissions: 'Berechtigungen speichern', permSaved: 'Berechtigungen gespeichert', loadFailed: 'Einstellungen laden fehlgeschlagen' },
}
// ── memory ──
const memory = {
vi: { title: 'Bộ nhớ', desc: 'Quản lý tệp bộ nhớ Agent', noFiles: 'Không có tệp', view: 'Xem', download: 'Tải xuống', delete: 'Xóa', upload: 'Tải lên', uploading: 'Đang tải...', uploaded: 'Đã tải lên', uploadFailed: 'Tải lên thất bại', deleted: 'Đã xóa', deleteFailed: 'Xóa thất bại', loadFailed: 'Tải thất bại', selectAgent: 'Chọn Agent', searchPlaceholder: 'Tìm kiếm...' },
es: { title: 'Memoria', desc: 'Gestionar archivos de memoria del Agent', noFiles: 'Sin archivos', view: 'Ver', download: 'Descargar', delete: 'Eliminar', upload: 'Subir', uploading: 'Subiendo...', uploaded: 'Subido', uploadFailed: 'Error al subir', deleted: 'Eliminado', deleteFailed: 'Error al eliminar', loadFailed: 'Error al cargar', selectAgent: 'Seleccionar Agent', searchPlaceholder: 'Buscar...' },
pt: { title: 'Memória', desc: 'Gerenciar arquivos de memória do Agent', noFiles: 'Sem arquivos', view: 'Ver', download: 'Baixar', delete: 'Excluir', upload: 'Enviar', uploading: 'Enviando...', uploaded: 'Enviado', uploadFailed: 'Falha ao enviar', deleted: 'Excluído', deleteFailed: 'Falha ao excluir', loadFailed: 'Falha ao carregar', selectAgent: 'Selecionar Agent', searchPlaceholder: 'Pesquisar...' },
ru: { title: 'Память', desc: 'Управление файлами памяти агента', noFiles: 'Нет файлов', view: 'Просмотр', download: 'Скачать', delete: 'Удалить', upload: 'Загрузить', uploading: 'Загрузка...', uploaded: 'Загружено', uploadFailed: 'Ошибка загрузки', deleted: 'Удалено', deleteFailed: 'Ошибка удаления', loadFailed: 'Ошибка загрузки', selectAgent: 'Выбрать агента', searchPlaceholder: 'Поиск...' },
fr: { title: 'Mémoire', desc: "Gérer les fichiers mémoire de l'Agent", noFiles: 'Aucun fichier', view: 'Voir', download: 'Télécharger', delete: 'Supprimer', upload: 'Téléverser', uploading: 'Téléversement...', uploaded: 'Téléversé', uploadFailed: 'Échec du téléversement', deleted: 'Supprimé', deleteFailed: 'Échec de la suppression', loadFailed: 'Échec du chargement', selectAgent: 'Sélectionner Agent', searchPlaceholder: 'Rechercher...' },
de: { title: 'Speicher', desc: 'Agent-Speicherdateien verwalten', noFiles: 'Keine Dateien', view: 'Ansehen', download: 'Herunterladen', delete: 'Löschen', upload: 'Hochladen', uploading: 'Wird hochgeladen...', uploaded: 'Hochgeladen', uploadFailed: 'Hochladen fehlgeschlagen', deleted: 'Gelöscht', deleteFailed: 'Löschen fehlgeschlagen', loadFailed: 'Laden fehlgeschlagen', selectAgent: 'Agent auswählen', searchPlaceholder: 'Suchen...' },
}
// ── usage ──
const usage = {
vi: { title: 'Sử dụng', desc: 'Xem thống kê sử dụng mô hình và token', totalTokens: 'Tổng token', totalRequests: 'Tổng yêu cầu', totalCost: 'Tổng chi phí', today: 'Hôm nay', week: 'Tuần này', month: 'Tháng này', all: 'Tất cả', noData: 'Không có dữ liệu', model: 'Mô hình', tokens: 'Token', loadFailed: 'Tải thất bại', chart: 'Biểu đồ', table: 'Bảng' },
es: { title: 'Uso', desc: 'Ver estadísticas de uso de modelos y tokens', totalTokens: 'Tokens totales', totalRequests: 'Solicitudes totales', totalCost: 'Costo total', today: 'Hoy', week: 'Esta semana', month: 'Este mes', all: 'Todo', noData: 'Sin datos', model: 'Modelo', tokens: 'Tokens', loadFailed: 'Error al cargar', chart: 'Gráfico', table: 'Tabla' },
pt: { title: 'Uso', desc: 'Ver estatísticas de uso de modelos e tokens', totalTokens: 'Total de tokens', totalRequests: 'Total de solicitações', totalCost: 'Custo total', today: 'Hoje', week: 'Esta semana', month: 'Este mês', all: 'Todos', noData: 'Sem dados', model: 'Modelo', tokens: 'Tokens', loadFailed: 'Falha ao carregar', chart: 'Gráfico', table: 'Tabela' },
ru: { title: 'Использование', desc: 'Статистика использования моделей и токенов', totalTokens: 'Всего токенов', totalRequests: 'Всего запросов', totalCost: 'Общая стоимость', today: 'Сегодня', week: 'Эта неделя', month: 'Этот месяц', all: 'Все', noData: 'Нет данных', model: 'Модель', tokens: 'Токены', loadFailed: 'Ошибка загрузки', chart: 'График', table: 'Таблица' },
fr: { title: 'Utilisation', desc: "Voir les statistiques d'utilisation des modèles et tokens", totalTokens: 'Tokens totaux', totalRequests: 'Requêtes totales', totalCost: 'Coût total', today: "Aujourd'hui", week: 'Cette semaine', month: 'Ce mois', all: 'Tout', noData: 'Aucune donnée', model: 'Modèle', tokens: 'Tokens', loadFailed: 'Échec du chargement', chart: 'Graphique', table: 'Tableau' },
de: { title: 'Nutzung', desc: 'Modell- und Token-Nutzungsstatistiken anzeigen', totalTokens: 'Gesamte Tokens', totalRequests: 'Gesamte Anfragen', totalCost: 'Gesamtkosten', today: 'Heute', week: 'Diese Woche', month: 'Dieser Monat', all: 'Alle', noData: 'Keine Daten', model: 'Modell', tokens: 'Tokens', loadFailed: 'Laden fehlgeschlagen', chart: 'Diagramm', table: 'Tabelle' },
}
// ── cron ──
const cron = {
vi: { title: 'Tác vụ định kỳ', desc: 'Quản lý tác vụ định kỳ OpenClaw', addTask: '+ Thêm tác vụ', noTasks: 'Không có tác vụ', taskName: 'Tên tác vụ', schedule: 'Lịch trình', status: 'Trạng thái', active: 'Hoạt động', inactive: 'Không hoạt động', edit: 'Sửa', delete: 'Xóa', enable: 'Bật', disable: 'Tắt', runNow: 'Chạy ngay', created: 'Tác vụ đã tạo', deleted: 'Tác vụ đã xóa', loadFailed: 'Tải thất bại' },
es: { title: 'Tareas programadas', desc: 'Gestionar tareas programadas de OpenClaw', addTask: '+ Agregar tarea', noTasks: 'Sin tareas', taskName: 'Nombre de tarea', schedule: 'Programación', status: 'Estado', active: 'Activa', inactive: 'Inactiva', edit: 'Editar', delete: 'Eliminar', enable: 'Habilitar', disable: 'Deshabilitar', runNow: 'Ejecutar ahora', created: 'Tarea creada', deleted: 'Tarea eliminada', loadFailed: 'Error al cargar' },
pt: { title: 'Tarefas agendadas', desc: 'Gerenciar tarefas agendadas do OpenClaw', addTask: '+ Adicionar tarefa', noTasks: 'Sem tarefas', taskName: 'Nome da tarefa', schedule: 'Agendamento', status: 'Status', active: 'Ativa', inactive: 'Inativa', edit: 'Editar', delete: 'Excluir', enable: 'Ativar', disable: 'Desativar', runNow: 'Executar agora', created: 'Tarefa criada', deleted: 'Tarefa excluída', loadFailed: 'Falha ao carregar' },
ru: { title: 'Планировщик', desc: 'Управление периодическими задачами OpenClaw', addTask: '+ Добавить задачу', noTasks: 'Нет задач', taskName: 'Имя задачи', schedule: 'Расписание', status: 'Статус', active: 'Активна', inactive: 'Неактивна', edit: 'Редактировать', delete: 'Удалить', enable: 'Включить', disable: 'Отключить', runNow: 'Запустить сейчас', created: 'Задача создана', deleted: 'Задача удалена', loadFailed: 'Ошибка загрузки' },
fr: { title: 'Tâches planifiées', desc: 'Gérer les tâches planifiées OpenClaw', addTask: '+ Ajouter une tâche', noTasks: 'Aucune tâche', taskName: 'Nom de la tâche', schedule: 'Planification', status: 'Statut', active: 'Active', inactive: 'Inactive', edit: 'Modifier', delete: 'Supprimer', enable: 'Activer', disable: 'Désactiver', runNow: 'Exécuter maintenant', created: 'Tâche créée', deleted: 'Tâche supprimée', loadFailed: 'Échec du chargement' },
de: { title: 'Geplante Aufgaben', desc: 'OpenClaw-Aufgaben verwalten', addTask: '+ Aufgabe hinzufügen', noTasks: 'Keine Aufgaben', taskName: 'Aufgabenname', schedule: 'Zeitplan', status: 'Status', active: 'Aktiv', inactive: 'Inaktiv', edit: 'Bearbeiten', delete: 'Löschen', enable: 'Aktivieren', disable: 'Deaktivieren', runNow: 'Jetzt ausführen', created: 'Aufgabe erstellt', deleted: 'Aufgabe gelöscht', loadFailed: 'Laden fehlgeschlagen' },
}
// ── skills ──
const skills = {
vi: { title: 'Skills', desc: 'Quản lý và cài đặt OpenClaw Skills', installed: 'Đã cài', available: 'Có sẵn', noSkills: 'Không có Skills', install: 'Cài đặt', uninstall: 'Gỡ cài đặt', update: 'Cập nhật', search: 'Tìm kiếm Skills...', installing: 'Đang cài...', installSuccess: 'Đã cài đặt', installFailed: 'Cài đặt thất bại', loadFailed: 'Tải thất bại', noResults: 'Không có kết quả', refreshList: 'Làm mới danh sách', checkUpdates: 'Kiểm tra cập nhật', noUpdates: 'Đã cập nhật' },
es: { title: 'Skills', desc: 'Gestionar e instalar OpenClaw Skills', installed: 'Instalados', available: 'Disponibles', noSkills: 'Sin Skills', install: 'Instalar', uninstall: 'Desinstalar', update: 'Actualizar', search: 'Buscar Skills...', installing: 'Instalando...', installSuccess: 'Instalado', installFailed: 'Error al instalar', loadFailed: 'Error al cargar', noResults: 'Sin resultados', refreshList: 'Actualizar lista', checkUpdates: 'Buscar actualizaciones', noUpdates: 'Todo actualizado' },
pt: { title: 'Skills', desc: 'Gerenciar e instalar OpenClaw Skills', installed: 'Instalados', available: 'Disponíveis', noSkills: 'Sem Skills', install: 'Instalar', uninstall: 'Desinstalar', update: 'Atualizar', search: 'Pesquisar Skills...', installing: 'Instalando...', installSuccess: 'Instalado', installFailed: 'Falha ao instalar', loadFailed: 'Falha ao carregar', noResults: 'Sem resultados', refreshList: 'Atualizar lista', checkUpdates: 'Verificar atualizações', noUpdates: 'Tudo atualizado' },
ru: { title: 'Skills', desc: 'Управление и установка навыков OpenClaw', installed: 'Установленные', available: 'Доступные', noSkills: 'Нет навыков', install: 'Установить', uninstall: 'Удалить', update: 'Обновить', search: 'Поиск Skills...', installing: 'Установка...', installSuccess: 'Установлено', installFailed: 'Ошибка установки', loadFailed: 'Ошибка загрузки', noResults: 'Ничего не найдено', refreshList: 'Обновить список', checkUpdates: 'Проверить обновления', noUpdates: 'Всё обновлено' },
fr: { title: 'Skills', desc: 'Gérer et installer les Skills OpenClaw', installed: 'Installés', available: 'Disponibles', noSkills: 'Aucun Skill', install: 'Installer', uninstall: 'Désinstaller', update: 'Mettre à jour', search: 'Rechercher Skills...', installing: 'Installation...', installSuccess: 'Installé', installFailed: "Échec de l'installation", loadFailed: 'Échec du chargement', noResults: 'Aucun résultat', refreshList: 'Actualiser la liste', checkUpdates: 'Vérifier les mises à jour', noUpdates: 'Tout est à jour' },
de: { title: 'Skills', desc: 'OpenClaw Skills verwalten und installieren', installed: 'Installiert', available: 'Verfügbar', noSkills: 'Keine Skills', install: 'Installieren', uninstall: 'Deinstallieren', update: 'Aktualisieren', search: 'Skills suchen...', installing: 'Wird installiert...', installSuccess: 'Installiert', installFailed: 'Installation fehlgeschlagen', loadFailed: 'Laden fehlgeschlagen', noResults: 'Keine Ergebnisse', refreshList: 'Liste aktualisieren', checkUpdates: 'Nach Updates suchen', noUpdates: 'Alles aktuell' },
}
// ── ext ──
const ext = {
vi: { title: 'Công cụ mở rộng', desc: 'Quản lý cftunnel và ClawApp', cftunnelTitle: 'cftunnel', clawappTitle: 'ClawApp', installBtn: 'Cài đặt nhanh', status: 'Trạng thái', running: 'Đang chạy', stopped: 'Đã dừng', version: 'Phiên bản', startTunnel: 'Bắt đầu tunnel', stopTunnel: 'Dừng tunnel', start: 'Khởi động', stop: 'Dừng', installing: 'Đang cài đặt...', installDone: 'Cài đặt hoàn tất', installFailed: 'Cài đặt thất bại' },
es: { title: 'Herramientas de extensión', desc: 'Gestionar cftunnel y ClawApp', cftunnelTitle: 'cftunnel', clawappTitle: 'ClawApp', installBtn: 'Instalación rápida', status: 'Estado', running: 'Ejecutando', stopped: 'Detenido', version: 'Versión', startTunnel: 'Iniciar túnel', stopTunnel: 'Detener túnel', start: 'Iniciar', stop: 'Detener', installing: 'Instalando...', installDone: 'Instalación completada', installFailed: 'Instalación fallida' },
pt: { title: 'Ferramentas de extensão', desc: 'Gerenciar cftunnel e ClawApp', cftunnelTitle: 'cftunnel', clawappTitle: 'ClawApp', installBtn: 'Instalação rápida', status: 'Status', running: 'Em execução', stopped: 'Parado', version: 'Versão', startTunnel: 'Iniciar túnel', stopTunnel: 'Parar túnel', start: 'Iniciar', stop: 'Parar', installing: 'Instalando...', installDone: 'Instalação concluída', installFailed: 'Instalação falhou' },
ru: { title: 'Расширения', desc: 'Управление cftunnel и ClawApp', cftunnelTitle: 'cftunnel', clawappTitle: 'ClawApp', installBtn: 'Быстрая установка', status: 'Статус', running: 'Работает', stopped: 'Остановлен', version: 'Версия', startTunnel: 'Запустить туннель', stopTunnel: 'Остановить туннель', start: 'Запустить', stop: 'Остановить', installing: 'Установка...', installDone: 'Установка завершена', installFailed: 'Ошибка установки' },
fr: { title: 'Outils additionnels', desc: 'Gérer cftunnel et ClawApp', cftunnelTitle: 'cftunnel', clawappTitle: 'ClawApp', installBtn: 'Installation rapide', status: 'Statut', running: 'En cours', stopped: 'Arrêté', version: 'Version', startTunnel: 'Démarrer le tunnel', stopTunnel: 'Arrêter le tunnel', start: 'Démarrer', stop: 'Arrêter', installing: 'Installation...', installDone: 'Installation terminée', installFailed: "Échec de l'installation" },
de: { title: 'Erweiterungstools', desc: 'cftunnel und ClawApp verwalten', cftunnelTitle: 'cftunnel', clawappTitle: 'ClawApp', installBtn: 'Schnellinstallation', status: 'Status', running: 'Läuft', stopped: 'Gestoppt', version: 'Version', startTunnel: 'Tunnel starten', stopTunnel: 'Tunnel stoppen', start: 'Starten', stop: 'Stoppen', installing: 'Wird installiert...', installDone: 'Installation abgeschlossen', installFailed: 'Installation fehlgeschlagen' },
}
// Write medium modules
for (const mod of [
['dashboard', dashboard], ['services', services], ['settings', settings],
['agents', agents], ['gateway', gateway], ['models', models],
['security', security], ['memory', memory], ['usage', usage],
['cron', cron], ['skills', skills], ['ext', ext],
]) {
for (const lang of LANGS) {
if (mod[1][lang]) w(lang, mod[0], mod[1][lang])
}
}
console.log('✓ Medium modules: dashboard, services, settings, agents, gateway, models, security, memory, usage, cron, skills, ext (6 langs)')
// ── communication ──
const communication = {
vi: { title: 'Truyền thông & Tự động hóa', desc: 'Cấu hình kênh thông báo và quy tắc tự động', notifyTitle: 'Kênh thông báo', automationTitle: 'Quy tắc tự động', addChannel: '+ Thêm kênh', addRule: '+ Thêm quy tắc', noChannels: 'Không có kênh', noRules: 'Không có quy tắc', channelName: 'Tên kênh', enabled: 'Đã bật', disabled: 'Đã tắt', test: 'Gửi thử', testing: 'Đang thử...', testSuccess: 'Gửi thử thành công', testFailed: 'Gửi thử thất bại', save: 'Lưu', saved: 'Đã lưu', saveFailed: 'Lưu thất bại', delete: 'Xóa', deleted: 'Đã xóa', deleteFailed: 'Xóa thất bại', loadFailed: 'Tải thất bại', trigger: 'Kích hoạt', action: 'Hành động', selectAgent: 'Chọn Agent', approve: 'Phê duyệt' },
es: { title: 'Comunicación y Automatización', desc: 'Configurar canales de notificación y reglas de automatización', notifyTitle: 'Canales de notificación', automationTitle: 'Reglas de automatización', addChannel: '+ Agregar canal', addRule: '+ Agregar regla', noChannels: 'Sin canales', noRules: 'Sin reglas', channelName: 'Nombre del canal', enabled: 'Habilitado', disabled: 'Deshabilitado', test: 'Enviar prueba', testing: 'Probando...', testSuccess: 'Prueba exitosa', testFailed: 'Prueba fallida', save: 'Guardar', saved: 'Guardado', saveFailed: 'Error al guardar', delete: 'Eliminar', deleted: 'Eliminado', deleteFailed: 'Error al eliminar', loadFailed: 'Error al cargar', trigger: 'Activador', action: 'Acción', selectAgent: 'Seleccionar Agent', approve: 'Aprobar' },
pt: { title: 'Comunicação e Automação', desc: 'Configurar canais de notificação e regras de automação', notifyTitle: 'Canais de notificação', automationTitle: 'Regras de automação', addChannel: '+ Adicionar canal', addRule: '+ Adicionar regra', noChannels: 'Sem canais', noRules: 'Sem regras', channelName: 'Nome do canal', enabled: 'Ativado', disabled: 'Desativado', test: 'Enviar teste', testing: 'Testando...', testSuccess: 'Teste bem-sucedido', testFailed: 'Teste falhou', save: 'Salvar', saved: 'Salvo', saveFailed: 'Falha ao salvar', delete: 'Excluir', deleted: 'Excluído', deleteFailed: 'Falha ao excluir', loadFailed: 'Falha ao carregar', trigger: 'Gatilho', action: 'Ação', selectAgent: 'Selecionar Agent', approve: 'Aprovar' },
ru: { title: 'Коммуникации и автоматизация', desc: 'Настройка каналов уведомлений и правил автоматизации', notifyTitle: 'Каналы уведомлений', automationTitle: 'Правила автоматизации', addChannel: '+ Добавить канал', addRule: '+ Добавить правило', noChannels: 'Нет каналов', noRules: 'Нет правил', channelName: 'Имя канала', enabled: 'Включено', disabled: 'Отключено', test: 'Тестовая отправка', testing: 'Тестирование...', testSuccess: 'Тест успешен', testFailed: 'Тест не удался', save: 'Сохранить', saved: 'Сохранено', saveFailed: 'Ошибка сохранения', delete: 'Удалить', deleted: 'Удалено', deleteFailed: 'Ошибка удаления', loadFailed: 'Ошибка загрузки', trigger: 'Триггер', action: 'Действие', selectAgent: 'Выбрать агента', approve: 'Одобрить' },
fr: { title: 'Communication et Automatisation', desc: 'Configurer les canaux de notification et les règles d\'automatisation', notifyTitle: 'Canaux de notification', automationTitle: 'Règles d\'automatisation', addChannel: '+ Ajouter un canal', addRule: '+ Ajouter une règle', noChannels: 'Aucun canal', noRules: 'Aucune règle', channelName: 'Nom du canal', enabled: 'Activé', disabled: 'Désactivé', test: 'Envoyer un test', testing: 'Test en cours...', testSuccess: 'Test réussi', testFailed: 'Test échoué', save: 'Enregistrer', saved: 'Enregistré', saveFailed: 'Échec de la sauvegarde', delete: 'Supprimer', deleted: 'Supprimé', deleteFailed: 'Échec de la suppression', loadFailed: 'Échec du chargement', trigger: 'Déclencheur', action: 'Action', selectAgent: 'Sélectionner Agent', approve: 'Approuver' },
de: { title: 'Kommunikation & Automatisierung', desc: 'Benachrichtigungskanäle und Automatisierungsregeln konfigurieren', notifyTitle: 'Benachrichtigungskanäle', automationTitle: 'Automatisierungsregeln', addChannel: '+ Kanal hinzufügen', addRule: '+ Regel hinzufügen', noChannels: 'Keine Kanäle', noRules: 'Keine Regeln', channelName: 'Kanalname', enabled: 'Aktiviert', disabled: 'Deaktiviert', test: 'Test senden', testing: 'Wird getestet...', testSuccess: 'Test erfolgreich', testFailed: 'Test fehlgeschlagen', save: 'Speichern', saved: 'Gespeichert', saveFailed: 'Speichern fehlgeschlagen', delete: 'Löschen', deleted: 'Gelöscht', deleteFailed: 'Löschen fehlgeschlagen', loadFailed: 'Laden fehlgeschlagen', trigger: 'Auslöser', action: 'Aktion', selectAgent: 'Agent auswählen', approve: 'Genehmigen' },
}
// ── channels (core keys) ──
const channels = {
vi: { title: 'Kênh', desc: 'Quản lý kênh tin nhắn và kết nối nền tảng', addChannel: '+ Thêm kênh', noChannels: 'Không có kênh', channelName: 'Tên kênh', platform: 'Nền tảng', status: 'Trạng thái', connected: 'Đã kết nối', disconnected: 'Chưa kết nối', edit: 'Sửa', delete: 'Xóa', save: 'Lưu', saved: 'Đã lưu', saveFailed: 'Lưu thất bại', deleted: 'Đã xóa', loadFailed: 'Tải thất bại', testConnection: 'Kiểm tra kết nối', testing: 'Đang kiểm tra...', testSuccess: 'Kết nối thành công', testFailed: 'Kết nối thất bại', bindAgent: 'Liên kết Agent', selectAgent: 'Chọn Agent', pairingTitle: 'Ghép nối', approve: 'Phê duyệt', configTitle: 'Cấu hình kênh', restartRequired: 'Cần khởi động lại Gateway', installPlugin: 'Cài đặt plugin', installing: 'Đang cài đặt...', installSuccess: 'Cài đặt thành công', installFailed: 'Cài đặt thất bại' },
es: { title: 'Canales', desc: 'Gestionar canales de mensajería y conexiones de plataforma', addChannel: '+ Agregar canal', noChannels: 'Sin canales', channelName: 'Nombre del canal', platform: 'Plataforma', status: 'Estado', connected: 'Conectado', disconnected: 'Desconectado', edit: 'Editar', delete: 'Eliminar', save: 'Guardar', saved: 'Guardado', saveFailed: 'Error al guardar', deleted: 'Eliminado', loadFailed: 'Error al cargar', testConnection: 'Probar conexión', testing: 'Probando...', testSuccess: 'Conexión exitosa', testFailed: 'Conexión fallida', bindAgent: 'Vincular Agent', selectAgent: 'Seleccionar Agent', pairingTitle: 'Emparejamiento', approve: 'Aprobar', configTitle: 'Configuración del canal', restartRequired: 'Se requiere reiniciar Gateway', installPlugin: 'Instalar plugin', installing: 'Instalando...', installSuccess: 'Instalado', installFailed: 'Instalación fallida' },
pt: { title: 'Canais', desc: 'Gerenciar canais de mensagens e conexões de plataforma', addChannel: '+ Adicionar canal', noChannels: 'Sem canais', channelName: 'Nome do canal', platform: 'Plataforma', status: 'Status', connected: 'Conectado', disconnected: 'Desconectado', edit: 'Editar', delete: 'Excluir', save: 'Salvar', saved: 'Salvo', saveFailed: 'Falha ao salvar', deleted: 'Excluído', loadFailed: 'Falha ao carregar', testConnection: 'Testar conexão', testing: 'Testando...', testSuccess: 'Conexão bem-sucedida', testFailed: 'Conexão falhou', bindAgent: 'Vincular Agent', selectAgent: 'Selecionar Agent', pairingTitle: 'Pareamento', approve: 'Aprovar', configTitle: 'Configuração do canal', restartRequired: 'É necessário reiniciar o Gateway', installPlugin: 'Instalar plugin', installing: 'Instalando...', installSuccess: 'Instalado', installFailed: 'Instalação falhou' },
ru: { title: 'Каналы', desc: 'Управление каналами сообщений и подключение платформ', addChannel: '+ Добавить канал', noChannels: 'Нет каналов', channelName: 'Имя канала', platform: 'Платформа', status: 'Статус', connected: 'Подключён', disconnected: 'Отключён', edit: 'Редактировать', delete: 'Удалить', save: 'Сохранить', saved: 'Сохранено', saveFailed: 'Ошибка сохранения', deleted: 'Удалено', loadFailed: 'Ошибка загрузки', testConnection: 'Проверить подключение', testing: 'Проверка...', testSuccess: 'Подключение успешно', testFailed: 'Ошибка подключения', bindAgent: 'Привязать агента', selectAgent: 'Выбрать агента', pairingTitle: 'Сопряжение', approve: 'Одобрить', configTitle: 'Настройка канала', restartRequired: 'Требуется перезапуск Gateway', installPlugin: 'Установить плагин', installing: 'Установка...', installSuccess: 'Установлено', installFailed: 'Ошибка установки' },
fr: { title: 'Canaux', desc: 'Gérer les canaux de messagerie et les connexions de plateforme', addChannel: '+ Ajouter un canal', noChannels: 'Aucun canal', channelName: 'Nom du canal', platform: 'Plateforme', status: 'Statut', connected: 'Connecté', disconnected: 'Déconnecté', edit: 'Modifier', delete: 'Supprimer', save: 'Enregistrer', saved: 'Enregistré', saveFailed: 'Échec de la sauvegarde', deleted: 'Supprimé', loadFailed: 'Échec du chargement', testConnection: 'Tester la connexion', testing: 'Test en cours...', testSuccess: 'Connexion réussie', testFailed: 'Connexion échouée', bindAgent: 'Lier un Agent', selectAgent: 'Sélectionner Agent', pairingTitle: 'Appairage', approve: 'Approuver', configTitle: 'Configuration du canal', restartRequired: 'Redémarrage de Gateway requis', installPlugin: 'Installer le plugin', installing: 'Installation...', installSuccess: 'Installé', installFailed: "Échec de l'installation" },
de: { title: 'Kanäle', desc: 'Nachrichtenkanäle und Plattformverbindungen verwalten', addChannel: '+ Kanal hinzufügen', noChannels: 'Keine Kanäle', channelName: 'Kanalname', platform: 'Plattform', status: 'Status', connected: 'Verbunden', disconnected: 'Getrennt', edit: 'Bearbeiten', delete: 'Löschen', save: 'Speichern', saved: 'Gespeichert', saveFailed: 'Speichern fehlgeschlagen', deleted: 'Gelöscht', loadFailed: 'Laden fehlgeschlagen', testConnection: 'Verbindung testen', testing: 'Wird getestet...', testSuccess: 'Verbindung erfolgreich', testFailed: 'Verbindung fehlgeschlagen', bindAgent: 'Agent verknüpfen', selectAgent: 'Agent auswählen', pairingTitle: 'Kopplung', approve: 'Genehmigen', configTitle: 'Kanalkonfiguration', restartRequired: 'Gateway-Neustart erforderlich', installPlugin: 'Plugin installieren', installing: 'Wird installiert...', installSuccess: 'Installiert', installFailed: 'Installation fehlgeschlagen' },
}
// ── chat (core keys) ──
const chat = {
vi: { title: 'Trò chuyện trực tiếp', desc: 'Trò chuyện với Agent theo thời gian thực', selectAgent: 'Chọn Agent', connecting: 'Đang kết nối...', connected: 'Đã kết nối', disconnected: 'Đã ngắt kết nối', send: 'Gửi', inputPlaceholder: 'Nhập tin nhắn...', noMessages: 'Không có tin nhắn', clearChat: 'Xóa lịch sử', newSession: 'Phiên mới', noSessions: 'Không có phiên', copyMessage: 'Sao chép', thinking: 'Đang suy nghĩ...', generating: 'Đang tạo...', stop: 'Dừng', regenerate: 'Tạo lại', modelSelect: 'Chọn mô hình', gatewayNotRunning: 'Gateway chưa chạy', startGateway: 'Khởi động Gateway' },
es: { title: 'Chat en vivo', desc: 'Chatear con el Agent en tiempo real', selectAgent: 'Seleccionar Agent', connecting: 'Conectando...', connected: 'Conectado', disconnected: 'Desconectado', send: 'Enviar', inputPlaceholder: 'Escribe un mensaje...', noMessages: 'Sin mensajes', clearChat: 'Limpiar historial', newSession: 'Nueva sesión', noSessions: 'Sin sesiones', copyMessage: 'Copiar', thinking: 'Pensando...', generating: 'Generando...', stop: 'Detener', regenerate: 'Regenerar', modelSelect: 'Seleccionar modelo', gatewayNotRunning: 'Gateway no está ejecutando', startGateway: 'Iniciar Gateway' },
pt: { title: 'Chat ao vivo', desc: 'Conversar com o Agent em tempo real', selectAgent: 'Selecionar Agent', connecting: 'Conectando...', connected: 'Conectado', disconnected: 'Desconectado', send: 'Enviar', inputPlaceholder: 'Digite uma mensagem...', noMessages: 'Sem mensagens', clearChat: 'Limpar histórico', newSession: 'Nova sessão', noSessions: 'Sem sessões', copyMessage: 'Copiar', thinking: 'Pensando...', generating: 'Gerando...', stop: 'Parar', regenerate: 'Regenerar', modelSelect: 'Selecionar modelo', gatewayNotRunning: 'Gateway não está em execução', startGateway: 'Iniciar Gateway' },
ru: { title: 'Живой чат', desc: 'Общение с агентом в реальном времени', selectAgent: 'Выбрать агента', connecting: 'Подключение...', connected: 'Подключено', disconnected: 'Отключено', send: 'Отправить', inputPlaceholder: 'Введите сообщение...', noMessages: 'Нет сообщений', clearChat: 'Очистить историю', newSession: 'Новая сессия', noSessions: 'Нет сессий', copyMessage: 'Копировать', thinking: 'Думает...', generating: 'Генерация...', stop: 'Остановить', regenerate: 'Перегенерировать', modelSelect: 'Выбрать модель', gatewayNotRunning: 'Gateway не запущен', startGateway: 'Запустить Gateway' },
fr: { title: 'Chat en direct', desc: "Discuter avec l'Agent en temps réel", selectAgent: 'Sélectionner Agent', connecting: 'Connexion...', connected: 'Connecté', disconnected: 'Déconnecté', send: 'Envoyer', inputPlaceholder: 'Tapez un message...', noMessages: 'Aucun message', clearChat: "Effacer l'historique", newSession: 'Nouvelle session', noSessions: 'Aucune session', copyMessage: 'Copier', thinking: 'Réflexion...', generating: 'Génération...', stop: 'Arrêter', regenerate: 'Régénérer', modelSelect: 'Sélectionner un modèle', gatewayNotRunning: "Gateway n'est pas en cours d'exécution", startGateway: 'Démarrer Gateway' },
de: { title: 'Live-Chat', desc: 'Mit dem Agenten in Echtzeit chatten', selectAgent: 'Agent auswählen', connecting: 'Verbindung wird hergestellt...', connected: 'Verbunden', disconnected: 'Getrennt', send: 'Senden', inputPlaceholder: 'Nachricht eingeben...', noMessages: 'Keine Nachrichten', clearChat: 'Verlauf löschen', newSession: 'Neue Sitzung', noSessions: 'Keine Sitzungen', copyMessage: 'Kopieren', thinking: 'Denkt nach...', generating: 'Wird generiert...', stop: 'Stoppen', regenerate: 'Neu generieren', modelSelect: 'Modell auswählen', gatewayNotRunning: 'Gateway läuft nicht', startGateway: 'Gateway starten' },
}
// ── chatDebug (core keys) ──
const chatDebug = {
vi: { title: 'Chẩn đoán hệ thống', desc: 'Chẩn đoán kết nối WebSocket và gỡ lỗi mạng', wsStatus: 'Trạng thái WebSocket', wsConnect: 'Kết nối', wsDisconnect: 'Ngắt kết nối', wsConnected: 'Đã kết nối', wsDisconnected: 'Chưa kết nối', wsConnecting: 'Đang kết nối...', wsError: 'Lỗi WebSocket', networkLogTitle: 'Nhật ký yêu cầu mạng', noRequests: 'Không có yêu cầu', totalRequests: 'Tổng yêu cầu', fixStarting: 'Bắt đầu sửa chữa...', fixFailed: 'Sửa chữa thất bại' },
es: { title: 'Diagnóstico del sistema', desc: 'Diagnóstico de conexión WebSocket y depuración de red', wsStatus: 'Estado WebSocket', wsConnect: 'Conectar', wsDisconnect: 'Desconectar', wsConnected: 'Conectado', wsDisconnected: 'No conectado', wsConnecting: 'Conectando...', wsError: 'Error WebSocket', networkLogTitle: 'Registro de solicitudes de red', noRequests: 'Sin solicitudes', totalRequests: 'Total de solicitudes', fixStarting: 'Iniciando reparación...', fixFailed: 'Reparación fallida' },
pt: { title: 'Diagnóstico do sistema', desc: 'Diagnóstico de conexão WebSocket e depuração de rede', wsStatus: 'Status WebSocket', wsConnect: 'Conectar', wsDisconnect: 'Desconectar', wsConnected: 'Conectado', wsDisconnected: 'Não conectado', wsConnecting: 'Conectando...', wsError: 'Erro WebSocket', networkLogTitle: 'Log de solicitações de rede', noRequests: 'Sem solicitações', totalRequests: 'Total de solicitações', fixStarting: 'Iniciando reparo...', fixFailed: 'Reparo falhou' },
ru: { title: 'Диагностика системы', desc: 'Диагностика WebSocket и отладка сети', wsStatus: 'Статус WebSocket', wsConnect: 'Подключить', wsDisconnect: 'Отключить', wsConnected: 'Подключено', wsDisconnected: 'Не подключено', wsConnecting: 'Подключение...', wsError: 'Ошибка WebSocket', networkLogTitle: 'Журнал сетевых запросов', noRequests: 'Нет запросов', totalRequests: 'Всего запросов', fixStarting: 'Начинаем исправление...', fixFailed: 'Исправление не удалось' },
fr: { title: 'Diagnostic système', desc: 'Diagnostic de connexion WebSocket et débogage réseau', wsStatus: 'Statut WebSocket', wsConnect: 'Connecter', wsDisconnect: 'Déconnecter', wsConnected: 'Connecté', wsDisconnected: 'Non connecté', wsConnecting: 'Connexion...', wsError: 'Erreur WebSocket', networkLogTitle: 'Journal des requêtes réseau', noRequests: 'Aucune requête', totalRequests: 'Total des requêtes', fixStarting: 'Début de la réparation...', fixFailed: 'Réparation échouée' },
de: { title: 'Systemdiagnose', desc: 'WebSocket-Verbindungsdiagnose und Netzwerk-Debugging', wsStatus: 'WebSocket-Status', wsConnect: 'Verbinden', wsDisconnect: 'Trennen', wsConnected: 'Verbunden', wsDisconnected: 'Nicht verbunden', wsConnecting: 'Verbindung wird hergestellt...', wsError: 'WebSocket-Fehler', networkLogTitle: 'Netzwerkanfrage-Protokoll', noRequests: 'Keine Anfragen', totalRequests: 'Gesamte Anfragen', fixStarting: 'Reparatur wird gestartet...', fixFailed: 'Reparatur fehlgeschlagen' },
}
// ── setup (core keys) ──
const setup = {
vi: { title: 'Thiết lập ban đầu', desc: 'Cài đặt và cấu hình OpenClaw', headerTitle: 'Chào mừng đến ClawPanel', recheck: 'Kiểm tra lại', stepNode: 'Môi trường Node.js', installed: 'Đã cài đặt', downloadNode: 'Tải Node.js', stepGit: 'Git', stepConfig: 'Tệp cấu hình', saveBtn: 'Lưu', resetDefaultBtn: 'Khôi phục mặc định', aiAssistant: 'Trợ lý AI', openAiAssistant: 'Mở trợ lý AI', nextStepsTitle: 'Bước tiếp theo', configModels: 'Cấu hình mô hình', gatewaySetup: 'Cấu hình Gateway', messageChannels: 'Kênh', enterPanel: 'Vào panel', installBtn: 'Cài đặt nhanh', installOpenclaw: 'Cài đặt OpenClaw', installComplete: 'Cài đặt hoàn tất' },
es: { title: 'Configuración inicial', desc: 'Instalar y configurar OpenClaw', headerTitle: 'Bienvenido a ClawPanel', recheck: 'Verificar de nuevo', stepNode: 'Entorno Node.js', installed: 'Instalado', downloadNode: 'Descargar Node.js', stepGit: 'Git', stepConfig: 'Archivo de configuración', saveBtn: 'Guardar', resetDefaultBtn: 'Restaurar predeterminado', aiAssistant: 'Asistente IA', openAiAssistant: 'Abrir asistente IA', nextStepsTitle: 'Próximos pasos', configModels: 'Configurar modelos', gatewaySetup: 'Configurar Gateway', messageChannels: 'Canales', enterPanel: 'Entrar al panel', installBtn: 'Instalación rápida', installOpenclaw: 'Instalar OpenClaw', installComplete: 'Instalación completada' },
pt: { title: 'Configuração inicial', desc: 'Instalar e configurar OpenClaw', headerTitle: 'Bem-vindo ao ClawPanel', recheck: 'Verificar novamente', stepNode: 'Ambiente Node.js', installed: 'Instalado', downloadNode: 'Baixar Node.js', stepGit: 'Git', stepConfig: 'Arquivo de configuração', saveBtn: 'Salvar', resetDefaultBtn: 'Restaurar padrão', aiAssistant: 'Assistente IA', openAiAssistant: 'Abrir assistente IA', nextStepsTitle: 'Próximos passos', configModels: 'Configurar modelos', gatewaySetup: 'Configurar Gateway', messageChannels: 'Canais', enterPanel: 'Entrar no painel', installBtn: 'Instalação rápida', installOpenclaw: 'Instalar OpenClaw', installComplete: 'Instalação concluída' },
ru: { title: 'Начальная настройка', desc: 'Установка и настройка OpenClaw', headerTitle: 'Добро пожаловать в ClawPanel', recheck: 'Проверить снова', stepNode: 'Среда Node.js', installed: 'Установлено', downloadNode: 'Скачать Node.js', stepGit: 'Git', stepConfig: 'Файл конфигурации', saveBtn: 'Сохранить', resetDefaultBtn: 'Восстановить по умолчанию', aiAssistant: 'ИИ-ассистент', openAiAssistant: 'Открыть ИИ-ассистента', nextStepsTitle: 'Следующие шаги', configModels: 'Настроить модели', gatewaySetup: 'Настроить Gateway', messageChannels: 'Каналы', enterPanel: 'Войти в панель', installBtn: 'Быстрая установка', installOpenclaw: 'Установить OpenClaw', installComplete: 'Установка завершена' },
fr: { title: 'Configuration initiale', desc: 'Installer et configurer OpenClaw', headerTitle: 'Bienvenue sur ClawPanel', recheck: 'Revérifier', stepNode: 'Environnement Node.js', installed: 'Installé', downloadNode: 'Télécharger Node.js', stepGit: 'Git', stepConfig: 'Fichier de configuration', saveBtn: 'Enregistrer', resetDefaultBtn: 'Restaurer les paramètres par défaut', aiAssistant: 'Assistant IA', openAiAssistant: "Ouvrir l'assistant IA", nextStepsTitle: 'Étapes suivantes', configModels: 'Configurer les modèles', gatewaySetup: 'Configurer Gateway', messageChannels: 'Canaux', enterPanel: 'Entrer dans le panneau', installBtn: 'Installation rapide', installOpenclaw: 'Installer OpenClaw', installComplete: 'Installation terminée' },
de: { title: 'Ersteinrichtung', desc: 'OpenClaw installieren und konfigurieren', headerTitle: 'Willkommen bei ClawPanel', recheck: 'Erneut prüfen', stepNode: 'Node.js-Umgebung', installed: 'Installiert', downloadNode: 'Node.js herunterladen', stepGit: 'Git', stepConfig: 'Konfigurationsdatei', saveBtn: 'Speichern', resetDefaultBtn: 'Standard wiederherstellen', aiAssistant: 'KI-Assistent', openAiAssistant: 'KI-Assistent öffnen', nextStepsTitle: 'Nächste Schritte', configModels: 'Modelle konfigurieren', gatewaySetup: 'Gateway konfigurieren', messageChannels: 'Kanäle', enterPanel: 'Panel betreten', installBtn: 'Schnellinstallation', installOpenclaw: 'OpenClaw installieren', installComplete: 'Installation abgeschlossen' },
}
// ── about (core keys) ──
const about = {
vi: { title: 'Giới thiệu', desc: 'Thông tin phiên bản và dự án ClawPanel', subtitle: 'Bảng quản lý trực quan OpenClaw', sectionCommunity: 'Cộng đồng', sectionContribute: 'Đóng góp', sectionLinks: 'Liên kết', checkingUpdate: 'Đang kiểm tra cập nhật...', official: 'Chính thức', notInstalled: 'Chưa cài đặt', versionLabel: 'Phiên bản', recommended: 'Khuyến nghị', current: 'Hiện tại', upToDate: 'Đã cập nhật', checkUpdateFailed: 'Kiểm tra cập nhật thất bại', submitIssue: 'Gửi Issue', submitPR: 'Gửi PR', officialWebsite: 'Trang web chính thức', openSourceRepo: 'Kho mã nguồn mở' },
es: { title: 'Acerca de', desc: 'Información de versión y proyecto de ClawPanel', subtitle: 'Panel de gestión visual de OpenClaw', sectionCommunity: 'Comunidad', sectionContribute: 'Contribuir', sectionLinks: 'Enlaces', checkingUpdate: 'Verificando actualizaciones...', official: 'Oficial', notInstalled: 'No instalado', versionLabel: 'Versión', recommended: 'Recomendado', current: 'Actual', upToDate: 'Actualizado', checkUpdateFailed: 'Error al verificar actualizaciones', submitIssue: 'Enviar Issue', submitPR: 'Enviar PR', officialWebsite: 'Sitio web oficial', openSourceRepo: 'Repositorio de código abierto' },
pt: { title: 'Sobre', desc: 'Informações de versão e projeto do ClawPanel', subtitle: 'Painel de gestão visual do OpenClaw', sectionCommunity: 'Comunidade', sectionContribute: 'Contribuir', sectionLinks: 'Links', checkingUpdate: 'Verificando atualizações...', official: 'Oficial', notInstalled: 'Não instalado', versionLabel: 'Versão', recommended: 'Recomendado', current: 'Atual', upToDate: 'Atualizado', checkUpdateFailed: 'Falha ao verificar atualizações', submitIssue: 'Enviar Issue', submitPR: 'Enviar PR', officialWebsite: 'Site oficial', openSourceRepo: 'Repositório de código aberto' },
ru: { title: 'О программе', desc: 'Информация о версии и проекте ClawPanel', subtitle: 'Панель визуального управления OpenClaw', sectionCommunity: 'Сообщество', sectionContribute: 'Вклад', sectionLinks: 'Ссылки', checkingUpdate: 'Проверка обновлений...', official: 'Официальный', notInstalled: 'Не установлен', versionLabel: 'Версия', recommended: 'Рекомендуемый', current: 'Текущий', upToDate: 'Актуально', checkUpdateFailed: 'Ошибка проверки обновлений', submitIssue: 'Создать Issue', submitPR: 'Создать PR', officialWebsite: 'Официальный сайт', openSourceRepo: 'Открытый репозиторий' },
fr: { title: 'À propos', desc: 'Informations de version et de projet ClawPanel', subtitle: 'Panneau de gestion visuelle OpenClaw', sectionCommunity: 'Communauté', sectionContribute: 'Contribuer', sectionLinks: 'Liens', checkingUpdate: 'Vérification des mises à jour...', official: 'Officiel', notInstalled: 'Non installé', versionLabel: 'Version', recommended: 'Recommandé', current: 'Actuel', upToDate: 'À jour', checkUpdateFailed: 'Échec de la vérification des mises à jour', submitIssue: 'Soumettre un Issue', submitPR: 'Soumettre un PR', officialWebsite: 'Site officiel', openSourceRepo: 'Dépôt open source' },
de: { title: 'Über', desc: 'ClawPanel-Version und Projektinformationen', subtitle: 'OpenClaw Visuelles Verwaltungspanel', sectionCommunity: 'Community', sectionContribute: 'Mitwirken', sectionLinks: 'Links', checkingUpdate: 'Suche nach Updates...', official: 'Offiziell', notInstalled: 'Nicht installiert', versionLabel: 'Version', recommended: 'Empfohlen', current: 'Aktuell', upToDate: 'Aktuell', checkUpdateFailed: 'Update-Prüfung fehlgeschlagen', submitIssue: 'Issue einreichen', submitPR: 'PR einreichen', officialWebsite: 'Offizielle Website', openSourceRepo: 'Open-Source-Repository' },
}
// ── assistant (core keys) ──
const assistant = {
vi: { defaultName: 'Trợ lý AI', welcomeText: 'Xin chào! Tôi là trợ lý AI. Tôi có thể giúp gì cho bạn?', loading: 'Đang tải...', settings: 'Cài đặt', settingsTitle: 'Cài đặt trợ lý', settingsSaved: 'Đã lưu cài đặt', model: 'Mô hình', temperature: 'Nhiệt độ', testSuccess: 'Kết nối thành công', testFailed: 'Kết nối thất bại', testing: 'Đang kiểm tra...', testBtn: 'Kiểm tra kết nối', send: 'Gửi', inputPlaceholder: 'Mô tả vấn đề...', stopped: 'Đã dừng', retry: 'Thử lại', copyText: 'Sao chép văn bản', newSession: 'Phiên mới', deleteSession: 'Xóa phiên', noSessions: 'Không có phiên', sessionList: 'Danh sách phiên', aiThinking: 'Đang suy nghĩ...', confirmAllow: 'Cho phép thực thi', toolExecuting: 'Đang thực thi...', toolDone: 'Thực thi hoàn tất' },
es: { defaultName: 'Asistente IA', welcomeText: '¡Hola! Soy el asistente IA. ¿En qué puedo ayudarle?', loading: 'Cargando...', settings: 'Configuración', settingsTitle: 'Configuración del asistente', settingsSaved: 'Configuración guardada', model: 'Modelo', temperature: 'Temperatura', testSuccess: 'Conexión exitosa', testFailed: 'Conexión fallida', testing: 'Probando...', testBtn: 'Probar conexión', send: 'Enviar', inputPlaceholder: 'Describa el problema...', stopped: 'Detenido', retry: 'Reintentar', copyText: 'Copiar texto', newSession: 'Nueva sesión', deleteSession: 'Eliminar sesión', noSessions: 'Sin sesiones', sessionList: 'Lista de sesiones', aiThinking: 'Pensando...', confirmAllow: 'Permitir ejecución', toolExecuting: 'Ejecutando...', toolDone: 'Ejecución completada' },
pt: { defaultName: 'Assistente IA', welcomeText: 'Olá! Sou o assistente IA. Como posso ajudar?', loading: 'Carregando...', settings: 'Configurações', settingsTitle: 'Configurações do assistente', settingsSaved: 'Configurações salvas', model: 'Modelo', temperature: 'Temperatura', testSuccess: 'Conexão bem-sucedida', testFailed: 'Conexão falhou', testing: 'Testando...', testBtn: 'Testar conexão', send: 'Enviar', inputPlaceholder: 'Descreva o problema...', stopped: 'Parado', retry: 'Tentar novamente', copyText: 'Copiar texto', newSession: 'Nova sessão', deleteSession: 'Excluir sessão', noSessions: 'Sem sessões', sessionList: 'Lista de sessões', aiThinking: 'Pensando...', confirmAllow: 'Permitir execução', toolExecuting: 'Executando...', toolDone: 'Execução concluída' },
ru: { defaultName: 'ИИ-ассистент', welcomeText: 'Здравствуйте! Я ИИ-ассистент. Чем могу помочь?', loading: 'Загрузка...', settings: 'Настройки', settingsTitle: 'Настройки ассистента', settingsSaved: 'Настройки сохранены', model: 'Модель', temperature: 'Температура', testSuccess: 'Подключение успешно', testFailed: 'Ошибка подключения', testing: 'Проверка...', testBtn: 'Проверить подключение', send: 'Отправить', inputPlaceholder: 'Опишите проблему...', stopped: 'Остановлено', retry: 'Повторить', copyText: 'Копировать текст', newSession: 'Новая сессия', deleteSession: 'Удалить сессию', noSessions: 'Нет сессий', sessionList: 'Список сессий', aiThinking: 'Думает...', confirmAllow: 'Разрешить выполнение', toolExecuting: 'Выполняется...', toolDone: 'Выполнение завершено' },
fr: { defaultName: 'Assistant IA', welcomeText: 'Bonjour ! Je suis l\'assistant IA. Comment puis-je vous aider ?', loading: 'Chargement...', settings: 'Paramètres', settingsTitle: 'Paramètres de l\'assistant', settingsSaved: 'Paramètres enregistrés', model: 'Modèle', temperature: 'Température', testSuccess: 'Connexion réussie', testFailed: 'Connexion échouée', testing: 'Test en cours...', testBtn: 'Tester la connexion', send: 'Envoyer', inputPlaceholder: 'Décrivez le problème...', stopped: 'Arrêté', retry: 'Réessayer', copyText: 'Copier le texte', newSession: 'Nouvelle session', deleteSession: 'Supprimer la session', noSessions: 'Aucune session', sessionList: 'Liste des sessions', aiThinking: 'Réflexion...', confirmAllow: "Autoriser l'exécution", toolExecuting: 'Exécution...', toolDone: 'Exécution terminée' },
de: { defaultName: 'KI-Assistent', welcomeText: 'Hallo! Ich bin der KI-Assistent. Wie kann ich Ihnen helfen?', loading: 'Laden...', settings: 'Einstellungen', settingsTitle: 'Assistenten-Einstellungen', settingsSaved: 'Einstellungen gespeichert', model: 'Modell', temperature: 'Temperatur', testSuccess: 'Verbindung erfolgreich', testFailed: 'Verbindung fehlgeschlagen', testing: 'Wird getestet...', testBtn: 'Verbindung testen', send: 'Senden', inputPlaceholder: 'Problem beschreiben...', stopped: 'Gestoppt', retry: 'Wiederholen', copyText: 'Text kopieren', newSession: 'Neue Sitzung', deleteSession: 'Sitzung löschen', noSessions: 'Keine Sitzungen', sessionList: 'Sitzungsliste', aiThinking: 'Denkt nach...', confirmAllow: 'Ausführung erlauben', toolExecuting: 'Wird ausgeführt...', toolDone: 'Ausführung abgeschlossen' },
}
// Write large modules
for (const mod of [
['communication', communication], ['channels', channels], ['chat', chat],
['chatDebug', chatDebug], ['setup', setup], ['about', about], ['assistant', assistant],
]) {
for (const lang of LANGS) {
if (mod[1][lang]) w(lang, mod[0], mod[1][lang])
}
}
console.log('✓ Large modules: communication, channels, chat, chatDebug, setup, about, assistant (6 langs)')
console.log('✓ All 18 modules × 6 languages = patch files generated')