refactor(web): decompose i18n module into smaller focused files
Split the monolithic i18n.ts (~1700 lines) into separate modules: - types.ts: type definitions - languages.ts: language options and helpers - translate.ts: locale get/set and translation logic - locales/: one file per locale - index.ts: re-exports for backward-compatible imports Update LanguageSelector to use option.label directly and remove unused getLanguageOptionLabel import and id attribute. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
149165fa45
commit
ac63a4d16a
@ -2,7 +2,6 @@ import { Check, ChevronDown } from 'lucide-react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
getLanguageOption,
|
||||
getLanguageOptionLabel,
|
||||
getLocaleDirection,
|
||||
LANGUAGE_OPTIONS,
|
||||
type Locale,
|
||||
@ -58,7 +57,6 @@ export default function LanguageSelector({
|
||||
return (
|
||||
<div ref={containerRef} className="relative" dir={localeDirection}>
|
||||
<button
|
||||
id="locale-selector-trigger"
|
||||
type="button"
|
||||
data-testid="locale-select"
|
||||
aria-label={ariaLabel}
|
||||
@ -75,7 +73,7 @@ export default function LanguageSelector({
|
||||
>
|
||||
{activeLanguage.flag}
|
||||
</span>
|
||||
<span dir={localeDirection} className="min-w-0 truncate text-start">{getLanguageOptionLabel(activeLanguage)}</span>
|
||||
<span dir={localeDirection} className="min-w-0 truncate text-start">{activeLanguage.label}</span>
|
||||
<ChevronDown className={`h-4 w-4 shrink-0 transition ${open ? 'rotate-180' : ''}`} />
|
||||
</button>
|
||||
|
||||
@ -115,7 +113,7 @@ export default function LanguageSelector({
|
||||
{option.flag}
|
||||
</span>
|
||||
<span dir={option.direction} className="min-w-0 flex-1 truncate text-start">
|
||||
{getLanguageOptionLabel(option)}
|
||||
{option.label}
|
||||
</span>
|
||||
{selected ? <Check className="h-4 w-4 shrink-0 text-[#8cc2ff]" /> : null}
|
||||
</button>
|
||||
|
||||
1702
web/src/lib/i18n.ts
1702
web/src/lib/i18n.ts
File diff suppressed because it is too large
Load Diff
@ -3,11 +3,10 @@ import {
|
||||
applyLocaleToDocument,
|
||||
coerceLocale,
|
||||
getLanguageOption,
|
||||
getLanguageOptionLabel,
|
||||
getLocaleDirection,
|
||||
LANGUAGE_OPTIONS,
|
||||
LANGUAGE_SWITCH_ORDER,
|
||||
} from './i18n';
|
||||
} from '.';
|
||||
|
||||
describe('language metadata', () => {
|
||||
it('keeps language options aligned with switch order', () => {
|
||||
@ -18,7 +17,7 @@ describe('language metadata', () => {
|
||||
it('provides a flag-backed label for every locale', () => {
|
||||
for (const option of LANGUAGE_OPTIONS) {
|
||||
expect(getLanguageOption(option.value)).toEqual(option);
|
||||
expect(getLanguageOptionLabel(option)).toBe(option.label);
|
||||
expect(option.label.length).toBeGreaterThan(0);
|
||||
expect(option.flag.length).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
4
web/src/lib/i18n/index.ts
Normal file
4
web/src/lib/i18n/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export type { Locale, LocaleDirection, LanguageOption, LocaleDocumentTarget } from './types';
|
||||
export { LANGUAGE_OPTIONS, LANGUAGE_SWITCH_ORDER, getLocaleDirection, getLanguageOption } from './languages';
|
||||
export { coerceLocale, getLocale, setLocale, t, tLocale, applyLocaleToDocument } from './translate';
|
||||
export { translations } from './locales';
|
||||
58
web/src/lib/i18n/languages.ts
Normal file
58
web/src/lib/i18n/languages.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import type { LanguageOption, Locale, LocaleDirection } from './types';
|
||||
|
||||
export const LANGUAGE_OPTIONS: ReadonlyArray<LanguageOption> = [
|
||||
{ value: 'en', label: 'English', flag: '🇺🇸', direction: 'ltr' },
|
||||
{ value: 'zh-CN', label: '简体中文', flag: '🇨🇳', direction: 'ltr' },
|
||||
{ value: 'ja', label: '日本語', flag: '🇯🇵', direction: 'ltr' },
|
||||
{ value: 'ko', label: '한국어', flag: '🇰🇷', direction: 'ltr' },
|
||||
{ value: 'vi', label: 'Tiếng Việt', flag: '🇻🇳', direction: 'ltr' },
|
||||
{ value: 'tl', label: 'Tagalog', flag: '🇵🇭', direction: 'ltr' },
|
||||
{ value: 'es', label: 'Español', flag: '🇪🇸', direction: 'ltr' },
|
||||
{ value: 'pt', label: 'Português', flag: '🇵🇹', direction: 'ltr' },
|
||||
{ value: 'it', label: 'Italiano', flag: '🇮🇹', direction: 'ltr' },
|
||||
{ value: 'de', label: 'Deutsch', flag: '🇩🇪', direction: 'ltr' },
|
||||
{ value: 'fr', label: 'Français', flag: '🇫🇷', direction: 'ltr' },
|
||||
{ value: 'ar', label: 'العربية', flag: '🇸🇦', direction: 'rtl' },
|
||||
{ value: 'hi', label: 'हिन्दी', flag: '🇮🇳', direction: 'ltr' },
|
||||
{ value: 'ru', label: 'Русский', flag: '🇷🇺', direction: 'ltr' },
|
||||
{ value: 'bn', label: 'বাংলা', flag: '🇧🇩', direction: 'ltr' },
|
||||
{ value: 'he', label: 'עברית', flag: '🇮🇱', direction: 'rtl' },
|
||||
{ value: 'pl', label: 'Polski', flag: '🇵🇱', direction: 'ltr' },
|
||||
{ value: 'cs', label: 'Čeština', flag: '🇨🇿', direction: 'ltr' },
|
||||
{ value: 'nl', label: 'Nederlands', flag: '🇳🇱', direction: 'ltr' },
|
||||
{ value: 'tr', label: 'Türkçe', flag: '🇹🇷', direction: 'ltr' },
|
||||
{ value: 'uk', label: 'Українська', flag: '🇺🇦', direction: 'ltr' },
|
||||
{ value: 'id', label: 'Bahasa Indonesia', flag: '🇮🇩', direction: 'ltr' },
|
||||
{ value: 'th', label: 'ไทย', flag: '🇹🇭', direction: 'ltr' },
|
||||
{ value: 'ur', label: 'اردو', flag: '🇵🇰', direction: 'rtl' },
|
||||
{ value: 'ro', label: 'Română', flag: '🇷🇴', direction: 'ltr' },
|
||||
{ value: 'sv', label: 'Svenska', flag: '🇸🇪', direction: 'ltr' },
|
||||
{ value: 'el', label: 'Ελληνικά', flag: '🇬🇷', direction: 'ltr' },
|
||||
{ value: 'hu', label: 'Magyar', flag: '🇭🇺', direction: 'ltr' },
|
||||
{ value: 'fi', label: 'Suomi', flag: '🇫🇮', direction: 'ltr' },
|
||||
{ value: 'da', label: 'Dansk', flag: '🇩🇰', direction: 'ltr' },
|
||||
{ value: 'nb', label: 'Norsk Bokmål', flag: '🇳🇴', direction: 'ltr' },
|
||||
];
|
||||
|
||||
export const LANGUAGE_SWITCH_ORDER: ReadonlyArray<Locale> =
|
||||
LANGUAGE_OPTIONS.map((option) => option.value);
|
||||
|
||||
const RTL_LOCALES = new Set<Locale>(['ar', 'he', 'ur']);
|
||||
|
||||
export function getLocaleDirection(locale: Locale): LocaleDirection {
|
||||
return RTL_LOCALES.has(locale) ? 'rtl' : 'ltr';
|
||||
}
|
||||
|
||||
export function getLanguageOption(locale: Locale): LanguageOption {
|
||||
const matched = LANGUAGE_OPTIONS.find((option) => option.value === locale);
|
||||
if (matched) {
|
||||
return matched;
|
||||
}
|
||||
|
||||
const fallback = LANGUAGE_OPTIONS.find((option) => option.value === 'en');
|
||||
if (!fallback) {
|
||||
throw new Error('English locale metadata is missing.');
|
||||
}
|
||||
|
||||
return fallback;
|
||||
}
|
||||
33
web/src/lib/i18n/locales/ar.ts
Normal file
33
web/src/lib/i18n/locales/ar.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const ar: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'لوحة التحكم',
|
||||
'nav.agent': 'الوكيل',
|
||||
'nav.tools': 'الأدوات',
|
||||
'nav.cron': 'المهام المجدولة',
|
||||
'nav.integrations': 'التكاملات',
|
||||
'nav.memory': 'الذاكرة',
|
||||
'nav.config': 'الإعدادات',
|
||||
'nav.cost': 'تتبع التكلفة',
|
||||
'nav.logs': 'السجلات',
|
||||
'nav.doctor': 'التشخيص',
|
||||
'dashboard.hero_title': 'لوحة تشغيل كهربائية',
|
||||
'agent.placeholder': 'اكتب رسالة…',
|
||||
'tools.search': 'ابحث في الأدوات…',
|
||||
'cron.add': 'إضافة مهمة',
|
||||
'memory.add_memory': 'إضافة ذاكرة',
|
||||
'config.save': 'حفظ',
|
||||
'cost.token_statistics': 'إحصاءات الرموز',
|
||||
'logs.title': 'السجلات المباشرة',
|
||||
'doctor.title': 'تشخيص النظام',
|
||||
'auth.pair_button': 'اقتران',
|
||||
'auth.enter_code': 'أدخل رمز الاقتران لمرة واحدة من الطرفية',
|
||||
'auth.code_placeholder': 'رمز من 6 أرقام',
|
||||
'auth.pairing_progress': 'جارٍ الاقتران…',
|
||||
'auth.logout': 'تسجيل الخروج',
|
||||
'common.languages': 'اللغات',
|
||||
'common.select_language': 'اختر اللغة',
|
||||
'header.dashboard_tagline': 'لوحة ZeroClaw',
|
||||
};
|
||||
|
||||
export default ar;
|
||||
33
web/src/lib/i18n/locales/bn.ts
Normal file
33
web/src/lib/i18n/locales/bn.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const bn: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'ড্যাশবোর্ড',
|
||||
'nav.agent': 'এজেন্ট',
|
||||
'nav.tools': 'টুলস',
|
||||
'nav.cron': 'নির্ধারিত কাজ',
|
||||
'nav.integrations': 'ইন্টিগ্রেশন',
|
||||
'nav.memory': 'মেমরি',
|
||||
'nav.config': 'কনফিগারেশন',
|
||||
'nav.cost': 'খরচ ট্র্যাকার',
|
||||
'nav.logs': 'লগ',
|
||||
'nav.doctor': 'ডায়াগনস্টিক',
|
||||
'dashboard.hero_title': 'ইলেকট্রিক রানটাইম ড্যাশবোর্ড',
|
||||
'agent.placeholder': 'একটি বার্তা লিখুন…',
|
||||
'tools.search': 'টুল খুঁজুন…',
|
||||
'cron.add': 'কাজ যোগ করুন',
|
||||
'memory.add_memory': 'মেমরি যোগ করুন',
|
||||
'config.save': 'সংরক্ষণ করুন',
|
||||
'cost.token_statistics': 'টোকেন পরিসংখ্যান',
|
||||
'logs.title': 'লাইভ লগ',
|
||||
'doctor.title': 'সিস্টেম ডায়াগনস্টিক',
|
||||
'auth.pair_button': 'পেয়ার করুন',
|
||||
'auth.enter_code': 'টার্মিনাল থেকে একবারের পেয়ারিং কোড লিখুন',
|
||||
'auth.code_placeholder': '৬-সংখ্যার কোড',
|
||||
'auth.pairing_progress': 'পেয়ার করা হচ্ছে…',
|
||||
'auth.logout': 'লগ আউট',
|
||||
'common.languages': 'ভাষাসমূহ',
|
||||
'common.select_language': 'ভাষা বেছে নিন',
|
||||
'header.dashboard_tagline': 'ZeroClaw ড্যাশবোর্ড',
|
||||
};
|
||||
|
||||
export default bn;
|
||||
33
web/src/lib/i18n/locales/cs.ts
Normal file
33
web/src/lib/i18n/locales/cs.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const cs: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Nástěnka',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Nástroje',
|
||||
'nav.cron': 'Plánované úlohy',
|
||||
'nav.integrations': 'Integrace',
|
||||
'nav.memory': 'Paměť',
|
||||
'nav.config': 'Konfigurace',
|
||||
'nav.cost': 'Náklady',
|
||||
'nav.logs': 'Logy',
|
||||
'nav.doctor': 'Diagnostika',
|
||||
'dashboard.hero_title': 'Elektrický runtime panel',
|
||||
'agent.placeholder': 'Napište zprávu…',
|
||||
'tools.search': 'Hledat nástroje…',
|
||||
'cron.add': 'Přidat úlohu',
|
||||
'memory.add_memory': 'Přidat paměť',
|
||||
'config.save': 'Uložit',
|
||||
'cost.token_statistics': 'Statistiky tokenů',
|
||||
'logs.title': 'Živé logy',
|
||||
'doctor.title': 'Diagnostika systému',
|
||||
'auth.pair_button': 'Spárovat',
|
||||
'auth.enter_code': 'Zadejte jednorázový párovací kód z terminálu',
|
||||
'auth.code_placeholder': '6místný kód',
|
||||
'auth.pairing_progress': 'Párování…',
|
||||
'auth.logout': 'Odhlásit se',
|
||||
'common.languages': 'Jazyky',
|
||||
'common.select_language': 'Vyberte jazyk',
|
||||
'header.dashboard_tagline': 'Panel ZeroClaw',
|
||||
};
|
||||
|
||||
export default cs;
|
||||
33
web/src/lib/i18n/locales/da.ts
Normal file
33
web/src/lib/i18n/locales/da.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const da: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Kontrolpanel',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Værktøjer',
|
||||
'nav.cron': 'Planlagte job',
|
||||
'nav.integrations': 'Integrationer',
|
||||
'nav.memory': 'Hukommelse',
|
||||
'nav.config': 'Konfiguration',
|
||||
'nav.cost': 'Omkostninger',
|
||||
'nav.logs': 'Logge',
|
||||
'nav.doctor': 'Diagnostik',
|
||||
'dashboard.hero_title': 'Elektrisk runtime-kontrolpanel',
|
||||
'agent.placeholder': 'Skriv en besked…',
|
||||
'tools.search': 'Søg værktøjer…',
|
||||
'cron.add': 'Tilføj job',
|
||||
'memory.add_memory': 'Tilføj hukommelse',
|
||||
'config.save': 'Gem',
|
||||
'cost.token_statistics': 'Tokenstatistik',
|
||||
'logs.title': 'Live-logge',
|
||||
'doctor.title': 'Systemdiagnostik',
|
||||
'auth.pair_button': 'Par',
|
||||
'auth.enter_code': 'Indtast engangskoden fra terminalen',
|
||||
'auth.code_placeholder': '6-cifret kode',
|
||||
'auth.pairing_progress': 'Parrer…',
|
||||
'auth.logout': 'Log ud',
|
||||
'common.languages': 'Sprog',
|
||||
'common.select_language': 'Vælg sprog',
|
||||
'header.dashboard_tagline': 'ZeroClaw-kontrolpanel',
|
||||
};
|
||||
|
||||
export default da;
|
||||
33
web/src/lib/i18n/locales/de.ts
Normal file
33
web/src/lib/i18n/locales/de.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const de: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Dashboard',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Werkzeuge',
|
||||
'nav.cron': 'Geplante Aufgaben',
|
||||
'nav.integrations': 'Integrationen',
|
||||
'nav.memory': 'Speicher',
|
||||
'nav.config': 'Konfiguration',
|
||||
'nav.cost': 'Kosten',
|
||||
'nav.logs': 'Protokolle',
|
||||
'nav.doctor': 'Diagnose',
|
||||
'dashboard.hero_title': 'Elektrisches Runtime-Dashboard',
|
||||
'agent.placeholder': 'Nachricht eingeben…',
|
||||
'tools.search': 'Werkzeuge suchen…',
|
||||
'cron.add': 'Aufgabe hinzufügen',
|
||||
'memory.add_memory': 'Speicher hinzufügen',
|
||||
'config.save': 'Speichern',
|
||||
'cost.token_statistics': 'Token-Statistiken',
|
||||
'logs.title': 'Live-Protokolle',
|
||||
'doctor.title': 'Systemdiagnose',
|
||||
'auth.pair_button': 'Koppeln',
|
||||
'auth.enter_code': 'Geben Sie den einmaligen Kopplungscode aus dem Terminal ein',
|
||||
'auth.code_placeholder': '6-stelliger Code',
|
||||
'auth.pairing_progress': 'Kopplung…',
|
||||
'auth.logout': 'Abmelden',
|
||||
'common.languages': 'Sprachen',
|
||||
'common.select_language': 'Sprache auswählen',
|
||||
'header.dashboard_tagline': 'ZeroClaw-Dashboard',
|
||||
};
|
||||
|
||||
export default de;
|
||||
33
web/src/lib/i18n/locales/el.ts
Normal file
33
web/src/lib/i18n/locales/el.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const el: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Πίνακας ελέγχου',
|
||||
'nav.agent': 'Πράκτορας',
|
||||
'nav.tools': 'Εργαλεία',
|
||||
'nav.cron': 'Προγραμματισμένες εργασίες',
|
||||
'nav.integrations': 'Ενσωματώσεις',
|
||||
'nav.memory': 'Μνήμη',
|
||||
'nav.config': 'Ρυθμίσεις',
|
||||
'nav.cost': 'Κόστος',
|
||||
'nav.logs': 'Αρχεία καταγραφής',
|
||||
'nav.doctor': 'Διάγνωση',
|
||||
'dashboard.hero_title': 'Ηλεκτρικός πίνακας runtime',
|
||||
'agent.placeholder': 'Πληκτρολογήστε μήνυμα…',
|
||||
'tools.search': 'Αναζήτηση εργαλείων…',
|
||||
'cron.add': 'Προσθήκη εργασίας',
|
||||
'memory.add_memory': 'Προσθήκη μνήμης',
|
||||
'config.save': 'Αποθήκευση',
|
||||
'cost.token_statistics': 'Στατιστικά token',
|
||||
'logs.title': 'Ζωντανά αρχεία καταγραφής',
|
||||
'doctor.title': 'Διάγνωση συστήματος',
|
||||
'auth.pair_button': 'Σύζευξη',
|
||||
'auth.enter_code': 'Εισαγάγετε τον εφάπαξ κωδικό σύζευξης από το terminal',
|
||||
'auth.code_placeholder': '6ψήφιος κωδικός',
|
||||
'auth.pairing_progress': 'Σύζευξη…',
|
||||
'auth.logout': 'Αποσύνδεση',
|
||||
'common.languages': 'Γλώσσες',
|
||||
'common.select_language': 'Επιλέξτε γλώσσα',
|
||||
'header.dashboard_tagline': 'Πίνακας ZeroClaw',
|
||||
};
|
||||
|
||||
export default el;
|
||||
273
web/src/lib/i18n/locales/en.ts
Normal file
273
web/src/lib/i18n/locales/en.ts
Normal file
@ -0,0 +1,273 @@
|
||||
const en = {
|
||||
'nav.dashboard': 'Dashboard',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Tools',
|
||||
'nav.cron': 'Scheduled Jobs',
|
||||
'nav.integrations': 'Integrations',
|
||||
'nav.memory': 'Memory',
|
||||
'nav.config': 'Configuration',
|
||||
'nav.cost': 'Cost Tracker',
|
||||
'nav.logs': 'Logs',
|
||||
'nav.doctor': 'Doctor',
|
||||
|
||||
'dashboard.title': 'Dashboard',
|
||||
'dashboard.provider': 'Provider',
|
||||
'dashboard.model': 'Model',
|
||||
'dashboard.uptime': 'Uptime',
|
||||
'dashboard.temperature': 'Temperature',
|
||||
'dashboard.gateway_port': 'Gateway Port',
|
||||
'dashboard.locale': 'Locale',
|
||||
'dashboard.memory_backend': 'Memory Backend',
|
||||
'dashboard.paired': 'Paired',
|
||||
'dashboard.channels': 'Channels',
|
||||
'dashboard.health': 'Health',
|
||||
'dashboard.status': 'Status',
|
||||
'dashboard.overview': 'Overview',
|
||||
'dashboard.system_info': 'System Information',
|
||||
'dashboard.quick_actions': 'Quick Actions',
|
||||
'dashboard.load_failed': 'Dashboard load failed',
|
||||
'dashboard.load_unknown_error': 'Unknown dashboard load error',
|
||||
'dashboard.hero_eyebrow': 'ZeroClaw Command Deck',
|
||||
'dashboard.hero_title': 'Electric Runtime Dashboard',
|
||||
'dashboard.hero_subtitle': 'Real-time telemetry, cost pulse, and operations status in a single collapsible surface.',
|
||||
'dashboard.live_gateway': 'Live Gateway',
|
||||
'dashboard.unpaired': 'Unpaired',
|
||||
'dashboard.provider_model': 'Provider / Model',
|
||||
'dashboard.since_last_restart': 'Since last restart',
|
||||
'dashboard.pairing_active': 'Pairing active',
|
||||
'dashboard.no_paired_devices': 'No paired devices',
|
||||
'dashboard.cost_pulse': 'Cost Pulse',
|
||||
'dashboard.cost_subtitle': 'Session, daily, and monthly runtime spend',
|
||||
'dashboard.session': 'Session',
|
||||
'dashboard.daily': 'Daily',
|
||||
'dashboard.monthly': 'Monthly',
|
||||
'dashboard.channel_activity': 'Channel Activity',
|
||||
'dashboard.channel_subtitle': 'Live integrations and route connectivity',
|
||||
'dashboard.no_channels': 'No channels configured.',
|
||||
'dashboard.active': 'Active',
|
||||
'dashboard.inactive': 'Inactive',
|
||||
'dashboard.component_health': 'Component Health',
|
||||
'dashboard.component_subtitle': 'Runtime heartbeat and restart awareness',
|
||||
'dashboard.no_component_health': 'No component health is currently available.',
|
||||
'dashboard.restarts': 'Restarts',
|
||||
'dashboard.unknown_provider': 'Unknown',
|
||||
|
||||
'agent.title': 'Agent Chat',
|
||||
'agent.send': 'Send',
|
||||
'agent.placeholder': 'Type a message...',
|
||||
'agent.connecting': 'Connecting...',
|
||||
'agent.connected': 'Connected',
|
||||
'agent.disconnected': 'Disconnected',
|
||||
'agent.reconnecting': 'Reconnecting...',
|
||||
'agent.thinking': 'Thinking...',
|
||||
'agent.tool_call': 'Tool Call',
|
||||
'agent.tool_result': 'Tool Result',
|
||||
'agent.connection_error': 'Connection error. Attempting to reconnect...',
|
||||
'agent.failed_send': 'Failed to send message. Please try again.',
|
||||
'agent.empty_title': 'ZeroClaw Agent',
|
||||
'agent.empty_subtitle': 'Send a message to start the conversation',
|
||||
'agent.unknown_error': 'Unknown error',
|
||||
|
||||
'tools.title': 'Available Tools',
|
||||
'tools.name': 'Name',
|
||||
'tools.description': 'Description',
|
||||
'tools.parameters': 'Parameters',
|
||||
'tools.search': 'Search tools...',
|
||||
'tools.empty': 'No tools available.',
|
||||
'tools.count': 'Total tools',
|
||||
'tools.agent_tools': 'Agent Tools',
|
||||
'tools.cli_tools': 'CLI Tools',
|
||||
'tools.no_search_results': 'No tools match your search.',
|
||||
'tools.parameter_schema': 'Parameter Schema',
|
||||
'tools.path': 'Path',
|
||||
'tools.version': 'Version',
|
||||
'tools.load_failed': 'Failed to load tools',
|
||||
|
||||
'cron.title': 'Scheduled Jobs',
|
||||
'cron.add': 'Add Job',
|
||||
'cron.delete': 'Delete',
|
||||
'cron.enable': 'Enable',
|
||||
'cron.disable': 'Disable',
|
||||
'cron.name': 'Name',
|
||||
'cron.command': 'Command',
|
||||
'cron.schedule': 'Schedule',
|
||||
'cron.next_run': 'Next Run',
|
||||
'cron.last_run': 'Last Run',
|
||||
'cron.last_status': 'Last Status',
|
||||
'cron.enabled': 'Enabled',
|
||||
'cron.empty': 'No scheduled jobs.',
|
||||
'cron.confirm_delete': 'Are you sure you want to delete this job?',
|
||||
'cron.scheduled_tasks': 'Scheduled Tasks',
|
||||
'cron.add_cron_job': 'Add Cron Job',
|
||||
'cron.name_optional': 'Name (optional)',
|
||||
'cron.schedule_required_command_required': 'Schedule and command are required.',
|
||||
'cron.adding': 'Adding...',
|
||||
'cron.no_tasks_configured': 'No scheduled tasks configured.',
|
||||
'cron.load_failed': 'Failed to load cron jobs',
|
||||
'cron.failed_add': 'Failed to add job',
|
||||
'cron.failed_delete': 'Failed to delete job',
|
||||
'cron.delete_prompt': 'Delete?',
|
||||
'cron.id': 'ID',
|
||||
'cron.disabled': 'Disabled',
|
||||
|
||||
'integrations.title': 'Integrations',
|
||||
'integrations.available': 'Available',
|
||||
'integrations.active': 'Active',
|
||||
'integrations.coming_soon': 'Coming Soon',
|
||||
'integrations.category': 'Category',
|
||||
'integrations.status': 'Status',
|
||||
'integrations.search': 'Search integrations...',
|
||||
'integrations.empty': 'No integrations found.',
|
||||
'integrations.activate': 'Activate',
|
||||
'integrations.deactivate': 'Deactivate',
|
||||
'integrations.load_failed': 'Failed to load integrations',
|
||||
'integrations.all': 'all',
|
||||
|
||||
'memory.title': 'Memory Store',
|
||||
'memory.search': 'Search memory...',
|
||||
'memory.add': 'Store Memory',
|
||||
'memory.delete': 'Delete',
|
||||
'memory.key': 'Key',
|
||||
'memory.content': 'Content',
|
||||
'memory.category': 'Category',
|
||||
'memory.timestamp': 'Timestamp',
|
||||
'memory.session': 'Session',
|
||||
'memory.score': 'Score',
|
||||
'memory.empty': 'No memory entries found.',
|
||||
'memory.confirm_delete': 'Are you sure you want to delete this memory entry?',
|
||||
'memory.all_categories': 'All Categories',
|
||||
'memory.add_memory': 'Add Memory',
|
||||
'memory.search_entries': 'Search memory entries...',
|
||||
'memory.load_failed': 'Failed to load memory',
|
||||
'memory.key_content_required': 'Key and content are required.',
|
||||
'memory.failed_store': 'Failed to store memory',
|
||||
'memory.failed_delete': 'Failed to delete memory',
|
||||
'memory.category_optional': 'Category (optional)',
|
||||
'memory.key_placeholder': 'e.g. user_preferences',
|
||||
'memory.content_placeholder': 'Memory content...',
|
||||
'memory.category_placeholder': 'e.g. preferences, context, facts',
|
||||
'memory.search_button': 'Search',
|
||||
'memory.saving': 'Saving...',
|
||||
'memory.delete_prompt': 'Delete?',
|
||||
|
||||
'config.title': 'Configuration',
|
||||
'config.save': 'Save',
|
||||
'config.reset': 'Reset',
|
||||
'config.saved': 'Configuration saved successfully.',
|
||||
'config.error': 'Failed to save configuration.',
|
||||
'config.loading': 'Loading configuration...',
|
||||
'config.editor_placeholder': 'TOML configuration...',
|
||||
'config.saving': 'Saving...',
|
||||
'config.masked_title': 'Sensitive fields are masked',
|
||||
'config.masked_description': 'API keys, tokens, and passwords are hidden for security. To update a masked field, replace the entire masked value with your new value.',
|
||||
'config.toml_configuration': 'TOML Configuration',
|
||||
'config.lines': 'lines',
|
||||
|
||||
'cost.title': 'Cost Tracker',
|
||||
'cost.session': 'Session Cost',
|
||||
'cost.daily': 'Daily Cost',
|
||||
'cost.monthly': 'Monthly Cost',
|
||||
'cost.total_tokens': 'Total Tokens',
|
||||
'cost.request_count': 'Requests',
|
||||
'cost.by_model': 'Cost by Model',
|
||||
'cost.model': 'Model',
|
||||
'cost.tokens': 'Tokens',
|
||||
'cost.requests': 'Requests',
|
||||
'cost.usd': 'Cost (USD)',
|
||||
'cost.total_requests': 'Total Requests',
|
||||
'cost.token_statistics': 'Token Statistics',
|
||||
'cost.avg_tokens_per_request': 'Avg Tokens / Request',
|
||||
'cost.cost_per_1k_tokens': 'Cost per 1K Tokens',
|
||||
'cost.model_breakdown': 'Model Breakdown',
|
||||
'cost.no_model_data': 'No model data available.',
|
||||
'cost.share': 'Share',
|
||||
'cost.load_failed': 'Failed to load cost data',
|
||||
|
||||
'logs.title': 'Live Logs',
|
||||
'logs.clear': 'Clear',
|
||||
'logs.pause': 'Pause',
|
||||
'logs.resume': 'Resume',
|
||||
'logs.filter': 'Filter logs...',
|
||||
'logs.empty': 'No log entries.',
|
||||
'logs.connected': 'Connected to event stream.',
|
||||
'logs.disconnected': 'Disconnected from event stream.',
|
||||
'logs.events': 'events',
|
||||
'logs.jump_to_bottom': 'Jump to bottom',
|
||||
'logs.filter_label': 'Filter:',
|
||||
'logs.paused_stream': 'Log streaming is paused.',
|
||||
'logs.waiting_for_events': 'Waiting for events...',
|
||||
|
||||
'doctor.title': 'System Diagnostics',
|
||||
'doctor.run': 'Run Diagnostics',
|
||||
'doctor.running': 'Running diagnostics...',
|
||||
'doctor.ok': 'OK',
|
||||
'doctor.warn': 'Warning',
|
||||
'doctor.error': 'Error',
|
||||
'doctor.severity': 'Severity',
|
||||
'doctor.category': 'Category',
|
||||
'doctor.message': 'Message',
|
||||
'doctor.empty': 'No diagnostics have been run yet.',
|
||||
'doctor.summary': 'Diagnostic Summary',
|
||||
'doctor.running_short': 'Running...',
|
||||
'doctor.running_hint': 'This may take a few seconds.',
|
||||
'doctor.issues_found': 'Issues Found',
|
||||
'doctor.warnings': 'Warnings',
|
||||
'doctor.all_clear': 'All Clear',
|
||||
'doctor.instructions': 'Click "Run Diagnostics" to check your ZeroClaw installation.',
|
||||
|
||||
'auth.pair': 'Pair Device',
|
||||
'auth.pairing_code': 'Pairing Code',
|
||||
'auth.pair_button': 'Pair',
|
||||
'auth.logout': 'Logout',
|
||||
'auth.pairing_success': 'Pairing successful!',
|
||||
'auth.pairing_failed': 'Pairing failed. Please try again.',
|
||||
'auth.enter_code': 'Enter the one-time pairing code from your terminal',
|
||||
'auth.code_placeholder': '6-digit code',
|
||||
'auth.pairing_progress': 'Pairing...',
|
||||
|
||||
'common.loading': 'Loading...',
|
||||
'common.error': 'An error occurred.',
|
||||
'common.retry': 'Retry',
|
||||
'common.cancel': 'Cancel',
|
||||
'common.confirm': 'Confirm',
|
||||
'common.save': 'Save',
|
||||
'common.delete': 'Delete',
|
||||
'common.edit': 'Edit',
|
||||
'common.close': 'Close',
|
||||
'common.yes': 'Yes',
|
||||
'common.no': 'No',
|
||||
'common.search': 'Search...',
|
||||
'common.no_data': 'No data available.',
|
||||
'common.refresh': 'Refresh',
|
||||
'common.back': 'Back',
|
||||
'common.actions': 'Actions',
|
||||
'common.name': 'Name',
|
||||
'common.description': 'Description',
|
||||
'common.status': 'Status',
|
||||
'common.created': 'Created',
|
||||
'common.updated': 'Updated',
|
||||
'common.languages': 'Languages',
|
||||
'common.select_language': 'Select language',
|
||||
'common.connecting': 'Connecting...',
|
||||
|
||||
'health.title': 'System Health',
|
||||
'health.component': 'Component',
|
||||
'health.status': 'Status',
|
||||
'health.last_ok': 'Last OK',
|
||||
'health.last_error': 'Last Error',
|
||||
'health.restart_count': 'Restart Count',
|
||||
'health.pid': 'Process ID',
|
||||
'health.uptime': 'Uptime',
|
||||
'health.updated_at': 'Updated At',
|
||||
|
||||
'header.dashboard_tagline': 'ZeroClaw dashboard',
|
||||
'sidebar.gateway_dashboard': 'Gateway + Dashboard',
|
||||
'sidebar.runtime_mode': 'Runtime Mode',
|
||||
'navigation.open': 'Open navigation',
|
||||
'navigation.close': 'Close navigation',
|
||||
'navigation.expand': 'Expand navigation',
|
||||
'navigation.collapse': 'Collapse navigation',
|
||||
} satisfies Record<string, string>;
|
||||
|
||||
export type TranslationKeys = typeof en;
|
||||
export default en;
|
||||
33
web/src/lib/i18n/locales/es.ts
Normal file
33
web/src/lib/i18n/locales/es.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const es: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Panel',
|
||||
'nav.agent': 'Agente',
|
||||
'nav.tools': 'Herramientas',
|
||||
'nav.cron': 'Tareas programadas',
|
||||
'nav.integrations': 'Integraciones',
|
||||
'nav.memory': 'Memoria',
|
||||
'nav.config': 'Configuración',
|
||||
'nav.cost': 'Costos',
|
||||
'nav.logs': 'Registros',
|
||||
'nav.doctor': 'Diagnóstico',
|
||||
'dashboard.hero_title': 'Panel eléctrico del runtime',
|
||||
'agent.placeholder': 'Escribe un mensaje…',
|
||||
'tools.search': 'Buscar herramientas…',
|
||||
'cron.add': 'Agregar tarea',
|
||||
'memory.add_memory': 'Agregar memoria',
|
||||
'config.save': 'Guardar',
|
||||
'cost.token_statistics': 'Estadísticas de tokens',
|
||||
'logs.title': 'Registros en vivo',
|
||||
'doctor.title': 'Diagnóstico del sistema',
|
||||
'auth.pair_button': 'Vincular',
|
||||
'auth.enter_code': 'Introduce el código de vinculación de un solo uso del terminal',
|
||||
'auth.code_placeholder': 'Código de 6 dígitos',
|
||||
'auth.pairing_progress': 'Vinculando…',
|
||||
'auth.logout': 'Cerrar sesión',
|
||||
'common.languages': 'Idiomas',
|
||||
'common.select_language': 'Elegir idioma',
|
||||
'header.dashboard_tagline': 'Panel de ZeroClaw',
|
||||
};
|
||||
|
||||
export default es;
|
||||
33
web/src/lib/i18n/locales/fi.ts
Normal file
33
web/src/lib/i18n/locales/fi.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const fi: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Hallintapaneeli',
|
||||
'nav.agent': 'Agentti',
|
||||
'nav.tools': 'Työkalut',
|
||||
'nav.cron': 'Ajastetut tehtävät',
|
||||
'nav.integrations': 'Integraatiot',
|
||||
'nav.memory': 'Muisti',
|
||||
'nav.config': 'Asetukset',
|
||||
'nav.cost': 'Kustannukset',
|
||||
'nav.logs': 'Lokit',
|
||||
'nav.doctor': 'Diagnostiikka',
|
||||
'dashboard.hero_title': 'Sähköinen runtime-hallintapaneeli',
|
||||
'agent.placeholder': 'Kirjoita viesti…',
|
||||
'tools.search': 'Etsi työkaluja…',
|
||||
'cron.add': 'Lisää tehtävä',
|
||||
'memory.add_memory': 'Lisää muisti',
|
||||
'config.save': 'Tallenna',
|
||||
'cost.token_statistics': 'Token-tilastot',
|
||||
'logs.title': 'Live-lokit',
|
||||
'doctor.title': 'Järjestelmädiagnostiikka',
|
||||
'auth.pair_button': 'Yhdistä',
|
||||
'auth.enter_code': 'Syötä terminaalin kertakäyttöinen parituskoodi',
|
||||
'auth.code_placeholder': '6-numeroinen koodi',
|
||||
'auth.pairing_progress': 'Yhdistetään…',
|
||||
'auth.logout': 'Kirjaudu ulos',
|
||||
'common.languages': 'Kielet',
|
||||
'common.select_language': 'Valitse kieli',
|
||||
'header.dashboard_tagline': 'ZeroClaw-hallintapaneeli',
|
||||
};
|
||||
|
||||
export default fi;
|
||||
51
web/src/lib/i18n/locales/fr.ts
Normal file
51
web/src/lib/i18n/locales/fr.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const fr: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Tableau de bord',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Outils',
|
||||
'nav.cron': 'Tâches planifiées',
|
||||
'nav.integrations': 'Intégrations',
|
||||
'nav.memory': 'Mémoire',
|
||||
'nav.config': 'Configuration',
|
||||
'nav.cost': 'Coûts',
|
||||
'nav.logs': 'Journaux',
|
||||
'nav.doctor': 'Diagnostic',
|
||||
'dashboard.hero_title': 'Tableau de bord runtime électrique',
|
||||
'dashboard.live_gateway': 'Passerelle active',
|
||||
'dashboard.unpaired': 'Non appairé',
|
||||
'agent.title': 'Chat agent',
|
||||
'agent.placeholder': 'Saisissez un message…',
|
||||
'agent.connecting': 'Connexion…',
|
||||
'agent.connected': 'Connecté',
|
||||
'agent.disconnected': 'Déconnecté',
|
||||
'tools.search': 'Rechercher des outils…',
|
||||
'tools.agent_tools': 'Outils agent',
|
||||
'tools.cli_tools': 'Outils CLI',
|
||||
'cron.add': 'Ajouter une tâche',
|
||||
'cron.scheduled_tasks': 'Tâches planifiées',
|
||||
'integrations.title': 'Intégrations',
|
||||
'memory.add_memory': 'Ajouter une mémoire',
|
||||
'memory.search_entries': 'Rechercher dans la mémoire…',
|
||||
'config.save': 'Enregistrer',
|
||||
'config.saving': 'Enregistrement…',
|
||||
'cost.session': 'Coût de session',
|
||||
'cost.daily': 'Coût journalier',
|
||||
'cost.monthly': 'Coût mensuel',
|
||||
'logs.title': 'Journaux en direct',
|
||||
'logs.pause': 'Pause',
|
||||
'logs.resume': 'Reprendre',
|
||||
'doctor.title': 'Diagnostic système',
|
||||
'doctor.run': 'Lancer le diagnostic',
|
||||
'doctor.running_short': 'Exécution…',
|
||||
'auth.pair_button': 'Associer',
|
||||
'auth.enter_code': 'Entrez le code d\u2019appairage à usage unique affiché dans le terminal',
|
||||
'auth.code_placeholder': 'Code à 6 chiffres',
|
||||
'auth.pairing_progress': 'Appairage…',
|
||||
'auth.logout': 'Déconnexion',
|
||||
'common.languages': 'Langues',
|
||||
'common.select_language': 'Choisir la langue',
|
||||
'header.dashboard_tagline': 'Tableau de bord ZeroClaw',
|
||||
};
|
||||
|
||||
export default fr;
|
||||
33
web/src/lib/i18n/locales/he.ts
Normal file
33
web/src/lib/i18n/locales/he.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const he: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'לוח מחוונים',
|
||||
'nav.agent': 'סוכן',
|
||||
'nav.tools': 'כלים',
|
||||
'nav.cron': 'משימות מתוזמנות',
|
||||
'nav.integrations': 'אינטגרציות',
|
||||
'nav.memory': 'זיכרון',
|
||||
'nav.config': 'תצורה',
|
||||
'nav.cost': 'מעקב עלויות',
|
||||
'nav.logs': 'יומנים',
|
||||
'nav.doctor': 'אבחון',
|
||||
'dashboard.hero_title': 'לוח מחוונים חשמלי של זמן הריצה',
|
||||
'agent.placeholder': 'הקלד הודעה…',
|
||||
'tools.search': 'חפש כלים…',
|
||||
'cron.add': 'הוסף משימה',
|
||||
'memory.add_memory': 'הוסף זיכרון',
|
||||
'config.save': 'שמור',
|
||||
'cost.token_statistics': 'סטטיסטיקות אסימונים',
|
||||
'logs.title': 'יומנים חיים',
|
||||
'doctor.title': 'אבחון מערכת',
|
||||
'auth.pair_button': 'התאמה',
|
||||
'auth.enter_code': 'הזן את קוד ההתאמה החד-פעמי מהמסוף',
|
||||
'auth.code_placeholder': 'קוד בן 6 ספרות',
|
||||
'auth.pairing_progress': 'מתבצעת התאמה…',
|
||||
'auth.logout': 'התנתק',
|
||||
'common.languages': 'שפות',
|
||||
'common.select_language': 'בחר שפה',
|
||||
'header.dashboard_tagline': 'לוח המחוונים של ZeroClaw',
|
||||
};
|
||||
|
||||
export default he;
|
||||
33
web/src/lib/i18n/locales/hi.ts
Normal file
33
web/src/lib/i18n/locales/hi.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const hi: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'डैशबोर्ड',
|
||||
'nav.agent': 'एजेंट',
|
||||
'nav.tools': 'टूल्स',
|
||||
'nav.cron': 'निर्धारित कार्य',
|
||||
'nav.integrations': 'इंटीग्रेशन',
|
||||
'nav.memory': 'मेमोरी',
|
||||
'nav.config': 'कॉन्फ़िगरेशन',
|
||||
'nav.cost': 'लागत ट्रैकर',
|
||||
'nav.logs': 'लॉग्स',
|
||||
'nav.doctor': 'जाँच',
|
||||
'dashboard.hero_title': 'इलेक्ट्रिक रनटाइम डैशबोर्ड',
|
||||
'agent.placeholder': 'संदेश लिखें…',
|
||||
'tools.search': 'टूल खोजें…',
|
||||
'cron.add': 'कार्य जोड़ें',
|
||||
'memory.add_memory': 'मेमोरी जोड़ें',
|
||||
'config.save': 'सहेजें',
|
||||
'cost.token_statistics': 'टोकन आँकड़े',
|
||||
'logs.title': 'लाइव लॉग्स',
|
||||
'doctor.title': 'सिस्टम जाँच',
|
||||
'auth.pair_button': 'पेयर करें',
|
||||
'auth.enter_code': 'टर्मिनल से एक-बार वाला पेयरिंग कोड दर्ज करें',
|
||||
'auth.code_placeholder': '6-अंकों का कोड',
|
||||
'auth.pairing_progress': 'पेयर किया जा रहा है…',
|
||||
'auth.logout': 'लॉग आउट',
|
||||
'common.languages': 'भाषाएँ',
|
||||
'common.select_language': 'भाषा चुनें',
|
||||
'header.dashboard_tagline': 'ZeroClaw डैशबोर्ड',
|
||||
};
|
||||
|
||||
export default hi;
|
||||
33
web/src/lib/i18n/locales/hu.ts
Normal file
33
web/src/lib/i18n/locales/hu.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const hu: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Irányítópult',
|
||||
'nav.agent': 'Ügynök',
|
||||
'nav.tools': 'Eszközök',
|
||||
'nav.cron': 'Ütemezett feladatok',
|
||||
'nav.integrations': 'Integrációk',
|
||||
'nav.memory': 'Memória',
|
||||
'nav.config': 'Konfiguráció',
|
||||
'nav.cost': 'Költségek',
|
||||
'nav.logs': 'Naplók',
|
||||
'nav.doctor': 'Diagnosztika',
|
||||
'dashboard.hero_title': 'Elektromos runtime irányítópult',
|
||||
'agent.placeholder': 'Írjon üzenetet…',
|
||||
'tools.search': 'Eszközök keresése…',
|
||||
'cron.add': 'Feladat hozzáadása',
|
||||
'memory.add_memory': 'Memória hozzáadása',
|
||||
'config.save': 'Mentés',
|
||||
'cost.token_statistics': 'Tokenstatisztika',
|
||||
'logs.title': 'Élő naplók',
|
||||
'doctor.title': 'Rendszerdiagnosztika',
|
||||
'auth.pair_button': 'Párosítás',
|
||||
'auth.enter_code': 'Adja meg a terminál egyszer használatos párosítási kódját',
|
||||
'auth.code_placeholder': '6 számjegyű kód',
|
||||
'auth.pairing_progress': 'Párosítás…',
|
||||
'auth.logout': 'Kijelentkezés',
|
||||
'common.languages': 'Nyelvek',
|
||||
'common.select_language': 'Nyelv kiválasztása',
|
||||
'header.dashboard_tagline': 'ZeroClaw irányítópult',
|
||||
};
|
||||
|
||||
export default hu;
|
||||
33
web/src/lib/i18n/locales/id.ts
Normal file
33
web/src/lib/i18n/locales/id.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const id: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Dasbor',
|
||||
'nav.agent': 'Agen',
|
||||
'nav.tools': 'Alat',
|
||||
'nav.cron': 'Tugas terjadwal',
|
||||
'nav.integrations': 'Integrasi',
|
||||
'nav.memory': 'Memori',
|
||||
'nav.config': 'Konfigurasi',
|
||||
'nav.cost': 'Biaya',
|
||||
'nav.logs': 'Log',
|
||||
'nav.doctor': 'Diagnosis',
|
||||
'dashboard.hero_title': 'Dasbor runtime elektrik',
|
||||
'agent.placeholder': 'Tulis pesan…',
|
||||
'tools.search': 'Cari alat…',
|
||||
'cron.add': 'Tambah tugas',
|
||||
'memory.add_memory': 'Tambah memori',
|
||||
'config.save': 'Simpan',
|
||||
'cost.token_statistics': 'Statistik token',
|
||||
'logs.title': 'Log langsung',
|
||||
'doctor.title': 'Diagnosis sistem',
|
||||
'auth.pair_button': 'Pasangkan',
|
||||
'auth.enter_code': 'Masukkan kode pairing sekali pakai dari terminal',
|
||||
'auth.code_placeholder': 'Kode 6 digit',
|
||||
'auth.pairing_progress': 'Sedang memasangkan…',
|
||||
'auth.logout': 'Keluar',
|
||||
'common.languages': 'Bahasa',
|
||||
'common.select_language': 'Pilih bahasa',
|
||||
'header.dashboard_tagline': 'Dasbor ZeroClaw',
|
||||
};
|
||||
|
||||
export default id;
|
||||
70
web/src/lib/i18n/locales/index.ts
Normal file
70
web/src/lib/i18n/locales/index.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import type { Locale } from '../types';
|
||||
import en from './en';
|
||||
import zhCN from './zh-CN';
|
||||
import ja from './ja';
|
||||
import ko from './ko';
|
||||
import vi from './vi';
|
||||
import tl from './tl';
|
||||
import es from './es';
|
||||
import pt from './pt';
|
||||
import it from './it';
|
||||
import de from './de';
|
||||
import fr from './fr';
|
||||
import ar from './ar';
|
||||
import hi from './hi';
|
||||
import ru from './ru';
|
||||
import bn from './bn';
|
||||
import he from './he';
|
||||
import pl from './pl';
|
||||
import cs from './cs';
|
||||
import nl from './nl';
|
||||
import tr from './tr';
|
||||
import uk from './uk';
|
||||
import id from './id';
|
||||
import th from './th';
|
||||
import ur from './ur';
|
||||
import ro from './ro';
|
||||
import sv from './sv';
|
||||
import el from './el';
|
||||
import hu from './hu';
|
||||
import fi from './fi';
|
||||
import da from './da';
|
||||
import nb from './nb';
|
||||
|
||||
function merge(overrides: Partial<typeof en>): Record<string, string> {
|
||||
return { ...en, ...overrides };
|
||||
}
|
||||
|
||||
export const translations: Record<Locale, Record<string, string>> = {
|
||||
en,
|
||||
'zh-CN': merge(zhCN),
|
||||
ja: merge(ja),
|
||||
ko: merge(ko),
|
||||
vi: merge(vi),
|
||||
tl: merge(tl),
|
||||
es: merge(es),
|
||||
pt: merge(pt),
|
||||
it: merge(it),
|
||||
de: merge(de),
|
||||
fr: merge(fr),
|
||||
ar: merge(ar),
|
||||
hi: merge(hi),
|
||||
ru: merge(ru),
|
||||
bn: merge(bn),
|
||||
he: merge(he),
|
||||
pl: merge(pl),
|
||||
cs: merge(cs),
|
||||
nl: merge(nl),
|
||||
tr: merge(tr),
|
||||
uk: merge(uk),
|
||||
id: merge(id),
|
||||
th: merge(th),
|
||||
ur: merge(ur),
|
||||
ro: merge(ro),
|
||||
sv: merge(sv),
|
||||
el: merge(el),
|
||||
hu: merge(hu),
|
||||
fi: merge(fi),
|
||||
da: merge(da),
|
||||
nb: merge(nb),
|
||||
};
|
||||
33
web/src/lib/i18n/locales/it.ts
Normal file
33
web/src/lib/i18n/locales/it.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const it: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Dashboard',
|
||||
'nav.agent': 'Agente',
|
||||
'nav.tools': 'Strumenti',
|
||||
'nav.cron': 'Attività pianificate',
|
||||
'nav.integrations': 'Integrazioni',
|
||||
'nav.memory': 'Memoria',
|
||||
'nav.config': 'Configurazione',
|
||||
'nav.cost': 'Costi',
|
||||
'nav.logs': 'Log',
|
||||
'nav.doctor': 'Diagnostica',
|
||||
'dashboard.hero_title': 'Dashboard runtime elettrica',
|
||||
'agent.placeholder': 'Scrivi un messaggio…',
|
||||
'tools.search': 'Cerca strumenti…',
|
||||
'cron.add': 'Aggiungi attività',
|
||||
'memory.add_memory': 'Aggiungi memoria',
|
||||
'config.save': 'Salva',
|
||||
'cost.token_statistics': 'Statistiche token',
|
||||
'logs.title': 'Log in tempo reale',
|
||||
'doctor.title': 'Diagnostica di sistema',
|
||||
'auth.pair_button': 'Associa',
|
||||
'auth.enter_code': 'Inserisci il codice di associazione monouso dal terminale',
|
||||
'auth.code_placeholder': 'Codice a 6 cifre',
|
||||
'auth.pairing_progress': 'Associazione…',
|
||||
'auth.logout': 'Disconnetti',
|
||||
'common.languages': 'Lingue',
|
||||
'common.select_language': 'Scegli lingua',
|
||||
'header.dashboard_tagline': 'Dashboard di ZeroClaw',
|
||||
};
|
||||
|
||||
export default it;
|
||||
51
web/src/lib/i18n/locales/ja.ts
Normal file
51
web/src/lib/i18n/locales/ja.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const ja: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'ダッシュボード',
|
||||
'nav.agent': 'エージェント',
|
||||
'nav.tools': 'ツール',
|
||||
'nav.cron': 'スケジュール',
|
||||
'nav.integrations': '連携',
|
||||
'nav.memory': 'メモリ',
|
||||
'nav.config': '設定',
|
||||
'nav.cost': 'コスト',
|
||||
'nav.logs': 'ログ',
|
||||
'nav.doctor': '診断',
|
||||
'dashboard.hero_title': 'エレクトリック・ランタイム・ダッシュボード',
|
||||
'dashboard.live_gateway': 'ライブゲートウェイ',
|
||||
'dashboard.unpaired': '未ペア',
|
||||
'agent.title': 'エージェントチャット',
|
||||
'agent.placeholder': 'メッセージを入力…',
|
||||
'agent.connecting': '接続中…',
|
||||
'agent.connected': '接続済み',
|
||||
'agent.disconnected': '切断済み',
|
||||
'tools.search': 'ツールを検索…',
|
||||
'tools.agent_tools': 'エージェントツール',
|
||||
'tools.cli_tools': 'CLI ツール',
|
||||
'cron.add': 'ジョブを追加',
|
||||
'cron.scheduled_tasks': 'スケジュールされたジョブ',
|
||||
'integrations.title': '連携',
|
||||
'memory.add_memory': 'メモリを追加',
|
||||
'memory.search_entries': 'メモリエントリを検索…',
|
||||
'config.save': '保存',
|
||||
'config.saving': '保存中…',
|
||||
'cost.session': 'セッションコスト',
|
||||
'cost.daily': '日次コスト',
|
||||
'cost.monthly': '月次コスト',
|
||||
'logs.title': 'ライブログ',
|
||||
'logs.pause': '一時停止',
|
||||
'logs.resume': '再開',
|
||||
'doctor.title': 'システム診断',
|
||||
'doctor.run': '診断を実行',
|
||||
'doctor.running_short': '実行中…',
|
||||
'auth.pair_button': 'ペアリング',
|
||||
'auth.enter_code': '端末のワンタイムペアリングコードを入力してください',
|
||||
'auth.code_placeholder': '6桁のコード',
|
||||
'auth.pairing_progress': 'ペアリング中…',
|
||||
'auth.logout': 'ログアウト',
|
||||
'common.languages': '言語',
|
||||
'common.select_language': '言語を選択',
|
||||
'header.dashboard_tagline': 'ZeroClaw ダッシュボード',
|
||||
};
|
||||
|
||||
export default ja;
|
||||
33
web/src/lib/i18n/locales/ko.ts
Normal file
33
web/src/lib/i18n/locales/ko.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const ko: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': '대시보드',
|
||||
'nav.agent': '에이전트',
|
||||
'nav.tools': '도구',
|
||||
'nav.cron': '예약 작업',
|
||||
'nav.integrations': '통합',
|
||||
'nav.memory': '메모리',
|
||||
'nav.config': '설정',
|
||||
'nav.cost': '비용 추적',
|
||||
'nav.logs': '로그',
|
||||
'nav.doctor': '진단',
|
||||
'dashboard.hero_title': '전기 런타임 대시보드',
|
||||
'agent.placeholder': '메시지를 입력하세요…',
|
||||
'tools.search': '도구 검색…',
|
||||
'cron.add': '작업 추가',
|
||||
'memory.add_memory': '메모리 추가',
|
||||
'config.save': '저장',
|
||||
'cost.token_statistics': '토큰 통계',
|
||||
'logs.title': '실시간 로그',
|
||||
'doctor.title': '시스템 진단',
|
||||
'auth.pair_button': '페어링',
|
||||
'auth.enter_code': '터미널에 표시된 일회용 페어링 코드를 입력하세요',
|
||||
'auth.code_placeholder': '6자리 코드',
|
||||
'auth.pairing_progress': '페어링 중…',
|
||||
'auth.logout': '로그아웃',
|
||||
'common.languages': '언어',
|
||||
'common.select_language': '언어 선택',
|
||||
'header.dashboard_tagline': 'ZeroClaw 대시보드',
|
||||
};
|
||||
|
||||
export default ko;
|
||||
33
web/src/lib/i18n/locales/nb.ts
Normal file
33
web/src/lib/i18n/locales/nb.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const nb: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Kontrollpanel',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Verktøy',
|
||||
'nav.cron': 'Planlagte jobber',
|
||||
'nav.integrations': 'Integrasjoner',
|
||||
'nav.memory': 'Minne',
|
||||
'nav.config': 'Konfigurasjon',
|
||||
'nav.cost': 'Kostnader',
|
||||
'nav.logs': 'Logger',
|
||||
'nav.doctor': 'Diagnostikk',
|
||||
'dashboard.hero_title': 'Elektrisk runtime-kontrollpanel',
|
||||
'agent.placeholder': 'Skriv en melding…',
|
||||
'tools.search': 'Søk etter verktøy…',
|
||||
'cron.add': 'Legg til jobb',
|
||||
'memory.add_memory': 'Legg til minne',
|
||||
'config.save': 'Lagre',
|
||||
'cost.token_statistics': 'Tokenstatistikk',
|
||||
'logs.title': 'Live-logger',
|
||||
'doctor.title': 'Systemdiagnostikk',
|
||||
'auth.pair_button': 'Koble til',
|
||||
'auth.enter_code': 'Skriv inn engangskoden fra terminalen',
|
||||
'auth.code_placeholder': '6-sifret kode',
|
||||
'auth.pairing_progress': 'Kobler til…',
|
||||
'auth.logout': 'Logg ut',
|
||||
'common.languages': 'Språk',
|
||||
'common.select_language': 'Velg språk',
|
||||
'header.dashboard_tagline': 'ZeroClaw-kontrollpanel',
|
||||
};
|
||||
|
||||
export default nb;
|
||||
33
web/src/lib/i18n/locales/nl.ts
Normal file
33
web/src/lib/i18n/locales/nl.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const nl: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Dashboard',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Tools',
|
||||
'nav.cron': 'Geplande taken',
|
||||
'nav.integrations': 'Integraties',
|
||||
'nav.memory': 'Geheugen',
|
||||
'nav.config': 'Configuratie',
|
||||
'nav.cost': 'Kosten',
|
||||
'nav.logs': 'Logs',
|
||||
'nav.doctor': 'Diagnose',
|
||||
'dashboard.hero_title': 'Elektrisch runtime-dashboard',
|
||||
'agent.placeholder': 'Typ een bericht…',
|
||||
'tools.search': 'Tools zoeken…',
|
||||
'cron.add': 'Taak toevoegen',
|
||||
'memory.add_memory': 'Geheugen toevoegen',
|
||||
'config.save': 'Opslaan',
|
||||
'cost.token_statistics': 'Tokenstatistieken',
|
||||
'logs.title': 'Live-logs',
|
||||
'doctor.title': 'Systeemdiagnose',
|
||||
'auth.pair_button': 'Koppelen',
|
||||
'auth.enter_code': 'Voer de eenmalige koppelcode uit de terminal in',
|
||||
'auth.code_placeholder': '6-cijferige code',
|
||||
'auth.pairing_progress': 'Koppelen…',
|
||||
'auth.logout': 'Afmelden',
|
||||
'common.languages': 'Talen',
|
||||
'common.select_language': 'Kies taal',
|
||||
'header.dashboard_tagline': 'ZeroClaw-dashboard',
|
||||
};
|
||||
|
||||
export default nl;
|
||||
33
web/src/lib/i18n/locales/pl.ts
Normal file
33
web/src/lib/i18n/locales/pl.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const pl: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Pulpit',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Narzędzia',
|
||||
'nav.cron': 'Zaplanowane zadania',
|
||||
'nav.integrations': 'Integracje',
|
||||
'nav.memory': 'Pamięć',
|
||||
'nav.config': 'Konfiguracja',
|
||||
'nav.cost': 'Koszty',
|
||||
'nav.logs': 'Logi',
|
||||
'nav.doctor': 'Diagnostyka',
|
||||
'dashboard.hero_title': 'Elektryczny pulpit runtime',
|
||||
'agent.placeholder': 'Wpisz wiadomość…',
|
||||
'tools.search': 'Szukaj narzędzi…',
|
||||
'cron.add': 'Dodaj zadanie',
|
||||
'memory.add_memory': 'Dodaj pamięć',
|
||||
'config.save': 'Zapisz',
|
||||
'cost.token_statistics': 'Statystyki tokenów',
|
||||
'logs.title': 'Logi na żywo',
|
||||
'doctor.title': 'Diagnostyka systemu',
|
||||
'auth.pair_button': 'Sparuj',
|
||||
'auth.enter_code': 'Wprowadź jednorazowy kod parowania z terminala',
|
||||
'auth.code_placeholder': '6-cyfrowy kod',
|
||||
'auth.pairing_progress': 'Parowanie…',
|
||||
'auth.logout': 'Wyloguj',
|
||||
'common.languages': 'Języki',
|
||||
'common.select_language': 'Wybierz język',
|
||||
'header.dashboard_tagline': 'Pulpit ZeroClaw',
|
||||
};
|
||||
|
||||
export default pl;
|
||||
33
web/src/lib/i18n/locales/pt.ts
Normal file
33
web/src/lib/i18n/locales/pt.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const pt: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Painel',
|
||||
'nav.agent': 'Agente',
|
||||
'nav.tools': 'Ferramentas',
|
||||
'nav.cron': 'Tarefas agendadas',
|
||||
'nav.integrations': 'Integrações',
|
||||
'nav.memory': 'Memória',
|
||||
'nav.config': 'Configuração',
|
||||
'nav.cost': 'Custos',
|
||||
'nav.logs': 'Logs',
|
||||
'nav.doctor': 'Diagnóstico',
|
||||
'dashboard.hero_title': 'Painel elétrico do runtime',
|
||||
'agent.placeholder': 'Digite uma mensagem…',
|
||||
'tools.search': 'Buscar ferramentas…',
|
||||
'cron.add': 'Adicionar tarefa',
|
||||
'memory.add_memory': 'Adicionar memória',
|
||||
'config.save': 'Salvar',
|
||||
'cost.token_statistics': 'Estatísticas de tokens',
|
||||
'logs.title': 'Logs ao vivo',
|
||||
'doctor.title': 'Diagnóstico do sistema',
|
||||
'auth.pair_button': 'Parear',
|
||||
'auth.enter_code': 'Digite o código único de pareamento mostrado no terminal',
|
||||
'auth.code_placeholder': 'Código de 6 dígitos',
|
||||
'auth.pairing_progress': 'Pareando…',
|
||||
'auth.logout': 'Sair',
|
||||
'common.languages': 'Idiomas',
|
||||
'common.select_language': 'Escolher idioma',
|
||||
'header.dashboard_tagline': 'Painel do ZeroClaw',
|
||||
};
|
||||
|
||||
export default pt;
|
||||
33
web/src/lib/i18n/locales/ro.ts
Normal file
33
web/src/lib/i18n/locales/ro.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const ro: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Tablou de bord',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Unelte',
|
||||
'nav.cron': 'Sarcini programate',
|
||||
'nav.integrations': 'Integrări',
|
||||
'nav.memory': 'Memorie',
|
||||
'nav.config': 'Configurație',
|
||||
'nav.cost': 'Costuri',
|
||||
'nav.logs': 'Jurnale',
|
||||
'nav.doctor': 'Diagnostic',
|
||||
'dashboard.hero_title': 'Tablou de bord runtime electric',
|
||||
'agent.placeholder': 'Scrie un mesaj…',
|
||||
'tools.search': 'Caută unelte…',
|
||||
'cron.add': 'Adaugă sarcină',
|
||||
'memory.add_memory': 'Adaugă memorie',
|
||||
'config.save': 'Salvează',
|
||||
'cost.token_statistics': 'Statistici tokenuri',
|
||||
'logs.title': 'Jurnale live',
|
||||
'doctor.title': 'Diagnostic sistem',
|
||||
'auth.pair_button': 'Asociază',
|
||||
'auth.enter_code': 'Introdu codul unic de asociere din terminal',
|
||||
'auth.code_placeholder': 'Cod din 6 cifre',
|
||||
'auth.pairing_progress': 'Asociere…',
|
||||
'auth.logout': 'Deconectare',
|
||||
'common.languages': 'Limbi',
|
||||
'common.select_language': 'Alege limba',
|
||||
'header.dashboard_tagline': 'Tabloul ZeroClaw',
|
||||
};
|
||||
|
||||
export default ro;
|
||||
51
web/src/lib/i18n/locales/ru.ts
Normal file
51
web/src/lib/i18n/locales/ru.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const ru: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Панель',
|
||||
'nav.agent': 'Агент',
|
||||
'nav.tools': 'Инструменты',
|
||||
'nav.cron': 'Задания',
|
||||
'nav.integrations': 'Интеграции',
|
||||
'nav.memory': 'Память',
|
||||
'nav.config': 'Конфигурация',
|
||||
'nav.cost': 'Расходы',
|
||||
'nav.logs': 'Логи',
|
||||
'nav.doctor': 'Диагностика',
|
||||
'dashboard.hero_title': 'Панель электрического рантайма',
|
||||
'dashboard.live_gateway': 'Живой шлюз',
|
||||
'dashboard.unpaired': 'Не сопряжено',
|
||||
'agent.title': 'Чат агента',
|
||||
'agent.placeholder': 'Введите сообщение…',
|
||||
'agent.connecting': 'Подключение…',
|
||||
'agent.connected': 'Подключено',
|
||||
'agent.disconnected': 'Отключено',
|
||||
'tools.search': 'Поиск инструментов…',
|
||||
'tools.agent_tools': 'Инструменты агента',
|
||||
'tools.cli_tools': 'CLI-инструменты',
|
||||
'cron.add': 'Добавить задачу',
|
||||
'cron.scheduled_tasks': 'Запланированные задания',
|
||||
'integrations.title': 'Интеграции',
|
||||
'memory.add_memory': 'Добавить память',
|
||||
'memory.search_entries': 'Искать записи памяти…',
|
||||
'config.save': 'Сохранить',
|
||||
'config.saving': 'Сохранение…',
|
||||
'cost.session': 'Стоимость сессии',
|
||||
'cost.daily': 'Стоимость за день',
|
||||
'cost.monthly': 'Стоимость за месяц',
|
||||
'logs.title': 'Живые логи',
|
||||
'logs.pause': 'Пауза',
|
||||
'logs.resume': 'Продолжить',
|
||||
'doctor.title': 'Диагностика системы',
|
||||
'doctor.run': 'Запустить диагностику',
|
||||
'doctor.running_short': 'Выполняется…',
|
||||
'auth.pair_button': 'Сопрячь',
|
||||
'auth.enter_code': 'Введите одноразовый код сопряжения из терминала',
|
||||
'auth.code_placeholder': '6-значный код',
|
||||
'auth.pairing_progress': 'Сопряжение…',
|
||||
'auth.logout': 'Выйти',
|
||||
'common.languages': 'Языки',
|
||||
'common.select_language': 'Выберите язык',
|
||||
'header.dashboard_tagline': 'Панель ZeroClaw',
|
||||
};
|
||||
|
||||
export default ru;
|
||||
33
web/src/lib/i18n/locales/sv.ts
Normal file
33
web/src/lib/i18n/locales/sv.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const sv: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Instrumentpanel',
|
||||
'nav.agent': 'Agent',
|
||||
'nav.tools': 'Verktyg',
|
||||
'nav.cron': 'Schemalagda jobb',
|
||||
'nav.integrations': 'Integrationer',
|
||||
'nav.memory': 'Minne',
|
||||
'nav.config': 'Konfiguration',
|
||||
'nav.cost': 'Kostnader',
|
||||
'nav.logs': 'Loggar',
|
||||
'nav.doctor': 'Diagnostik',
|
||||
'dashboard.hero_title': 'Elektrisk runtimepanel',
|
||||
'agent.placeholder': 'Skriv ett meddelande…',
|
||||
'tools.search': 'Sök verktyg…',
|
||||
'cron.add': 'Lägg till jobb',
|
||||
'memory.add_memory': 'Lägg till minne',
|
||||
'config.save': 'Spara',
|
||||
'cost.token_statistics': 'Tokenstatistik',
|
||||
'logs.title': 'Live-loggar',
|
||||
'doctor.title': 'Systemdiagnostik',
|
||||
'auth.pair_button': 'Para',
|
||||
'auth.enter_code': 'Ange engångskoden från terminalen',
|
||||
'auth.code_placeholder': '6-siffrig kod',
|
||||
'auth.pairing_progress': 'Parar…',
|
||||
'auth.logout': 'Logga ut',
|
||||
'common.languages': 'Språk',
|
||||
'common.select_language': 'Välj språk',
|
||||
'header.dashboard_tagline': 'ZeroClaw-panel',
|
||||
};
|
||||
|
||||
export default sv;
|
||||
33
web/src/lib/i18n/locales/th.ts
Normal file
33
web/src/lib/i18n/locales/th.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const th: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'แดชบอร์ด',
|
||||
'nav.agent': 'เอเจนต์',
|
||||
'nav.tools': 'เครื่องมือ',
|
||||
'nav.cron': 'งานที่ตั้งเวลา',
|
||||
'nav.integrations': 'การเชื่อมต่อ',
|
||||
'nav.memory': 'หน่วยความจำ',
|
||||
'nav.config': 'การกำหนดค่า',
|
||||
'nav.cost': 'ต้นทุน',
|
||||
'nav.logs': 'บันทึก',
|
||||
'nav.doctor': 'วินิจฉัย',
|
||||
'dashboard.hero_title': 'แดชบอร์ดรันไทม์ไฟฟ้า',
|
||||
'agent.placeholder': 'พิมพ์ข้อความ…',
|
||||
'tools.search': 'ค้นหาเครื่องมือ…',
|
||||
'cron.add': 'เพิ่มงาน',
|
||||
'memory.add_memory': 'เพิ่มหน่วยความจำ',
|
||||
'config.save': 'บันทึก',
|
||||
'cost.token_statistics': 'สถิติโทเค็น',
|
||||
'logs.title': 'บันทึกสด',
|
||||
'doctor.title': 'วินิจฉัยระบบ',
|
||||
'auth.pair_button': 'จับคู่',
|
||||
'auth.enter_code': 'ป้อนรหัสจับคู่แบบใช้ครั้งเดียวจากเทอร์มินัล',
|
||||
'auth.code_placeholder': 'รหัส 6 หลัก',
|
||||
'auth.pairing_progress': 'กำลังจับคู่…',
|
||||
'auth.logout': 'ออกจากระบบ',
|
||||
'common.languages': 'ภาษา',
|
||||
'common.select_language': 'เลือกภาษา',
|
||||
'header.dashboard_tagline': 'แดชบอร์ด ZeroClaw',
|
||||
};
|
||||
|
||||
export default th;
|
||||
33
web/src/lib/i18n/locales/tl.ts
Normal file
33
web/src/lib/i18n/locales/tl.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const tl: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Dashboard',
|
||||
'nav.agent': 'Ahente',
|
||||
'nav.tools': 'Mga Tool',
|
||||
'nav.cron': 'Naka-iskedyul na Trabaho',
|
||||
'nav.integrations': 'Mga Integrasyon',
|
||||
'nav.memory': 'Alaala',
|
||||
'nav.config': 'Konpigurasyon',
|
||||
'nav.cost': 'Pagsubaybay sa Gastos',
|
||||
'nav.logs': 'Mga Log',
|
||||
'nav.doctor': 'Diyagnostiko',
|
||||
'dashboard.hero_title': 'Elektrikong Dashboard ng Runtime',
|
||||
'agent.placeholder': 'Mag-type ng mensahe…',
|
||||
'tools.search': 'Maghanap ng tool…',
|
||||
'cron.add': 'Magdagdag ng gawain',
|
||||
'memory.add_memory': 'Magdagdag ng alaala',
|
||||
'config.save': 'I-save',
|
||||
'cost.token_statistics': 'Estadistika ng Token',
|
||||
'logs.title': 'Mga Live Log',
|
||||
'doctor.title': 'Diyagnostiko ng System',
|
||||
'auth.pair_button': 'Ipares',
|
||||
'auth.enter_code': 'Ilagay ang isang beses na pairing code mula sa terminal',
|
||||
'auth.code_placeholder': '6-digit na code',
|
||||
'auth.pairing_progress': 'Pinapares…',
|
||||
'auth.logout': 'Mag-logout',
|
||||
'common.languages': 'Mga Wika',
|
||||
'common.select_language': 'Piliin ang wika',
|
||||
'header.dashboard_tagline': 'Dashboard ng ZeroClaw',
|
||||
};
|
||||
|
||||
export default tl;
|
||||
157
web/src/lib/i18n/locales/tr.ts
Normal file
157
web/src/lib/i18n/locales/tr.ts
Normal file
@ -0,0 +1,157 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const tr: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Kontrol Paneli',
|
||||
'nav.agent': 'Ajan',
|
||||
'nav.tools': 'Araçlar',
|
||||
'nav.cron': 'Zamanlanmış Görevler',
|
||||
'nav.integrations': 'Entegrasyonlar',
|
||||
'nav.memory': 'Hafıza',
|
||||
'nav.config': 'Yapılandırma',
|
||||
'nav.cost': 'Maliyet Takibi',
|
||||
'nav.logs': 'Kayıtlar',
|
||||
'nav.doctor': 'Doktor',
|
||||
'agent.title': 'Ajan Sohbeti',
|
||||
'agent.send': 'Gönder',
|
||||
'agent.placeholder': 'Bir mesaj yazın...',
|
||||
'agent.connecting': 'Bağlanıyor...',
|
||||
'agent.connected': 'Bağlı',
|
||||
'agent.disconnected': 'Bağlantı Kesildi',
|
||||
'agent.reconnecting': 'Yeniden bağlanıyor...',
|
||||
'agent.thinking': 'Düşünüyor...',
|
||||
'agent.tool_call': 'Araç Çağrısı',
|
||||
'agent.tool_result': 'Araç Sonucu',
|
||||
'agent.connection_error': 'Bağlantı hatası. Yeniden bağlanmaya çalışılıyor...',
|
||||
'agent.failed_send': 'Mesaj gönderilemedi. Lütfen tekrar deneyin.',
|
||||
'agent.empty_title': 'ZeroClaw Ajanı',
|
||||
'agent.empty_subtitle': 'Konuşmayı başlatmak için bir mesaj gönderin',
|
||||
'dashboard.title': 'Kontrol Paneli',
|
||||
'dashboard.provider': 'Sağlayıcı',
|
||||
'dashboard.model': 'Model',
|
||||
'dashboard.uptime': 'Çalışma Süresi',
|
||||
'dashboard.temperature': 'Sıcaklık',
|
||||
'dashboard.gateway_port': 'Ağ Geçidi Portu',
|
||||
'dashboard.locale': 'Yerel Ayar',
|
||||
'dashboard.memory_backend': 'Hafıza Arka Ucu',
|
||||
'dashboard.hero_eyebrow': 'ZeroClaw Komuta Güvertesi',
|
||||
'dashboard.hero_title': 'Elektrik Çalışma Zamanı Paneli',
|
||||
'dashboard.hero_subtitle': 'Gerçek zamanlı telemetri, maliyet akışı ve operasyon durumunu tek bir daraltılabilir yüzeyde görün.',
|
||||
'dashboard.live_gateway': 'Canlı Ağ Geçidi',
|
||||
'dashboard.unpaired': 'Eşleşmemiş',
|
||||
'dashboard.provider_model': 'Sağlayıcı / Model',
|
||||
'dashboard.since_last_restart': 'Son yeniden başlatmadan beri',
|
||||
'dashboard.pairing_active': 'Eşleştirme etkin',
|
||||
'dashboard.no_paired_devices': 'Eşleşmiş cihaz yok',
|
||||
'dashboard.cost_pulse': 'Maliyet Nabzı',
|
||||
'dashboard.cost_subtitle': 'Oturum, günlük ve aylık çalışma zamanı harcaması',
|
||||
'dashboard.session': 'Oturum',
|
||||
'dashboard.daily': 'Günlük',
|
||||
'dashboard.monthly': 'Aylık',
|
||||
'dashboard.channel_activity': 'Kanal Etkinliği',
|
||||
'dashboard.channel_subtitle': 'Canlı entegrasyonlar ve rota bağlantısı',
|
||||
'dashboard.no_channels': 'Hiç kanal yapılandırılmamış.',
|
||||
'dashboard.active': 'Aktif',
|
||||
'dashboard.inactive': 'Pasif',
|
||||
'dashboard.component_health': 'Bileşen Sağlığı',
|
||||
'dashboard.component_subtitle': 'Çalışma zamanı nabzı ve yeniden başlatma farkındalığı',
|
||||
'dashboard.no_component_health': 'Şu anda bileşen sağlığı bilgisi yok.',
|
||||
'dashboard.restarts': 'Yeniden Başlatmalar',
|
||||
'tools.title': 'Mevcut Araçlar',
|
||||
'tools.search': 'Araç ara...',
|
||||
'tools.agent_tools': 'Ajan Araçları',
|
||||
'tools.cli_tools': 'CLI Araçları',
|
||||
'tools.no_search_results': 'Aramanızla eşleşen araç yok.',
|
||||
'tools.parameter_schema': 'Parametre Şeması',
|
||||
'tools.path': 'Yol',
|
||||
'tools.version': 'Sürüm',
|
||||
'cron.title': 'Zamanlanmış Görevler',
|
||||
'cron.add': 'Görev Ekle',
|
||||
'cron.scheduled_tasks': 'Zamanlanmış Görevler',
|
||||
'cron.add_cron_job': 'Cron Görevi Ekle',
|
||||
'cron.name_optional': 'Ad (isteğe bağlı)',
|
||||
'cron.schedule_required_command_required': 'Zamanlama ve komut gereklidir.',
|
||||
'cron.adding': 'Ekleniyor...',
|
||||
'cron.no_tasks_configured': 'Zamanlanmış görev yapılandırılmamış.',
|
||||
'cron.load_failed': 'Cron görevleri yüklenemedi',
|
||||
'cron.failed_add': 'Görev eklenemedi',
|
||||
'cron.failed_delete': 'Görev silinemedi',
|
||||
'cron.delete_prompt': 'Silinsin mi?',
|
||||
'cron.disabled': 'Devre Dışı',
|
||||
'integrations.title': 'Entegrasyonlar',
|
||||
'integrations.available': 'Mevcut',
|
||||
'integrations.active': 'Aktif',
|
||||
'integrations.coming_soon': 'Yakında',
|
||||
'integrations.empty': 'Entegrasyon bulunamadı.',
|
||||
'integrations.load_failed': 'Entegrasyonlar yüklenemedi',
|
||||
'memory.title': 'Hafıza Deposu',
|
||||
'memory.add_memory': 'Hafıza Ekle',
|
||||
'memory.search_entries': 'Hafıza girdilerinde ara...',
|
||||
'memory.all_categories': 'Tüm Kategoriler',
|
||||
'memory.search_button': 'Ara',
|
||||
'memory.load_failed': 'Hafıza yüklenemedi',
|
||||
'memory.key_content_required': 'Anahtar ve içerik gereklidir.',
|
||||
'memory.failed_store': 'Hafıza kaydedilemedi',
|
||||
'memory.failed_delete': 'Hafıza silinemedi',
|
||||
'memory.category_optional': 'Kategori (isteğe bağlı)',
|
||||
'memory.key_placeholder': 'örn. kullanici_tercihleri',
|
||||
'memory.content_placeholder': 'Hafıza içeriği...',
|
||||
'memory.category_placeholder': 'örn. tercihler, bağlam, gerçekler',
|
||||
'memory.saving': 'Kaydediliyor...',
|
||||
'memory.delete_prompt': 'Silinsin mi?',
|
||||
'config.title': 'Yapılandırma',
|
||||
'config.save': 'Kaydet',
|
||||
'config.saved': 'Yapılandırma başarıyla kaydedildi.',
|
||||
'config.saving': 'Kaydediliyor...',
|
||||
'config.masked_title': 'Hassas alanlar maskelendi',
|
||||
'config.masked_description': 'Güvenlik için API anahtarları, belirteçler ve parolalar gizlenir. Maskelenmiş bir alanı güncellemek için tüm maskeli değeri yeni değerinizle değiştirin.',
|
||||
'config.toml_configuration': 'TOML Yapılandırması',
|
||||
'config.lines': 'satır',
|
||||
'cost.title': 'Maliyet Takibi',
|
||||
'cost.session': 'Oturum Maliyeti',
|
||||
'cost.daily': 'Günlük Maliyet',
|
||||
'cost.monthly': 'Aylık Maliyet',
|
||||
'cost.total_requests': 'Toplam İstek',
|
||||
'cost.token_statistics': 'Belirteç İstatistikleri',
|
||||
'cost.avg_tokens_per_request': 'İstek Başına Ort. Belirteç',
|
||||
'cost.cost_per_1k_tokens': '1K Belirteç Başına Maliyet',
|
||||
'cost.model_breakdown': 'Model Dağılımı',
|
||||
'cost.no_model_data': 'Model verisi yok.',
|
||||
'cost.share': 'Pay',
|
||||
'cost.load_failed': 'Maliyet verisi yüklenemedi',
|
||||
'logs.title': 'Canlı Kayıtlar',
|
||||
'logs.pause': 'Duraklat',
|
||||
'logs.resume': 'Sürdür',
|
||||
'logs.events': 'olay',
|
||||
'logs.jump_to_bottom': 'Alta git',
|
||||
'logs.filter_label': 'Filtre:',
|
||||
'logs.paused_stream': 'Kayıt akışı duraklatıldı.',
|
||||
'logs.waiting_for_events': 'Olaylar bekleniyor...',
|
||||
'doctor.title': 'Sistem Teşhisleri',
|
||||
'doctor.run': 'Teşhisleri Çalıştır',
|
||||
'doctor.running': 'Teşhisler çalıştırılıyor...',
|
||||
'doctor.running_short': 'Çalışıyor...',
|
||||
'doctor.running_hint': 'Bu birkaç saniye sürebilir.',
|
||||
'doctor.warn': 'Uyarı',
|
||||
'doctor.issues_found': 'Sorunlar Bulundu',
|
||||
'doctor.warnings': 'Uyarılar',
|
||||
'doctor.all_clear': 'Temiz',
|
||||
'doctor.instructions': 'ZeroClaw kurulumunuzu kontrol etmek için "Teşhisleri Çalıştır" düğmesine tıklayın.',
|
||||
'auth.pair': 'Cihazı Eşle',
|
||||
'auth.pair_button': 'Eşle',
|
||||
'auth.logout': 'Çıkış Yap',
|
||||
'auth.enter_code': 'Terminalinizdeki tek kullanımlık eşleştirme kodunu girin',
|
||||
'auth.code_placeholder': '6 haneli kod',
|
||||
'auth.pairing_progress': 'Eşleştiriliyor...',
|
||||
'common.languages': 'Diller',
|
||||
'common.select_language': 'Dil seçin',
|
||||
'common.connecting': 'Bağlanıyor...',
|
||||
'header.dashboard_tagline': 'ZeroClaw paneli',
|
||||
'sidebar.gateway_dashboard': 'Ağ Geçidi + Panel',
|
||||
'sidebar.runtime_mode': 'Çalışma Modu',
|
||||
'navigation.open': 'Gezinmeyi aç',
|
||||
'navigation.close': 'Gezinmeyi kapat',
|
||||
'navigation.expand': 'Gezinmeyi genişlet',
|
||||
'navigation.collapse': 'Gezinmeyi daralt',
|
||||
};
|
||||
|
||||
export default tr;
|
||||
33
web/src/lib/i18n/locales/uk.ts
Normal file
33
web/src/lib/i18n/locales/uk.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const uk: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Панель',
|
||||
'nav.agent': 'Агент',
|
||||
'nav.tools': 'Інструменти',
|
||||
'nav.cron': 'Заплановані завдання',
|
||||
'nav.integrations': 'Інтеграції',
|
||||
'nav.memory': 'Пам\u2019ять',
|
||||
'nav.config': 'Конфігурація',
|
||||
'nav.cost': 'Витрати',
|
||||
'nav.logs': 'Журнали',
|
||||
'nav.doctor': 'Діагностика',
|
||||
'dashboard.hero_title': 'Електрична панель runtime',
|
||||
'agent.placeholder': 'Введіть повідомлення…',
|
||||
'tools.search': 'Пошук інструментів…',
|
||||
'cron.add': 'Додати завдання',
|
||||
'memory.add_memory': 'Додати пам\u2019ять',
|
||||
'config.save': 'Зберегти',
|
||||
'cost.token_statistics': 'Статистика токенів',
|
||||
'logs.title': 'Живі журнали',
|
||||
'doctor.title': 'Діагностика системи',
|
||||
'auth.pair_button': 'З\u2019єднати',
|
||||
'auth.enter_code': 'Введіть одноразовий код з\u2019єднання з термінала',
|
||||
'auth.code_placeholder': '6-значний код',
|
||||
'auth.pairing_progress': 'З\u2019єднання…',
|
||||
'auth.logout': 'Вийти',
|
||||
'common.languages': 'Мови',
|
||||
'common.select_language': 'Оберіть мову',
|
||||
'header.dashboard_tagline': 'Панель ZeroClaw',
|
||||
};
|
||||
|
||||
export default uk;
|
||||
33
web/src/lib/i18n/locales/ur.ts
Normal file
33
web/src/lib/i18n/locales/ur.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const ur: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'ڈیش بورڈ',
|
||||
'nav.agent': 'ایجنٹ',
|
||||
'nav.tools': 'ٹولز',
|
||||
'nav.cron': 'شیڈول شدہ کام',
|
||||
'nav.integrations': 'انضمامات',
|
||||
'nav.memory': 'میموری',
|
||||
'nav.config': 'ترتیبات',
|
||||
'nav.cost': 'لاگت',
|
||||
'nav.logs': 'لاگز',
|
||||
'nav.doctor': 'تشخیص',
|
||||
'dashboard.hero_title': 'الیکٹرک رن ٹائم ڈیش بورڈ',
|
||||
'agent.placeholder': 'پیغام لکھیں…',
|
||||
'tools.search': 'ٹولز تلاش کریں…',
|
||||
'cron.add': 'کام شامل کریں',
|
||||
'memory.add_memory': 'میموری شامل کریں',
|
||||
'config.save': 'محفوظ کریں',
|
||||
'cost.token_statistics': 'ٹوکن کے اعدادوشمار',
|
||||
'logs.title': 'لائیو لاگز',
|
||||
'doctor.title': 'سسٹم تشخیص',
|
||||
'auth.pair_button': 'جوڑیں',
|
||||
'auth.enter_code': 'ٹرمینل سے ایک بار استعمال ہونے والا پیئرنگ کوڈ درج کریں',
|
||||
'auth.code_placeholder': '6 ہندسوں کا کوڈ',
|
||||
'auth.pairing_progress': 'جوڑا جا رہا ہے…',
|
||||
'auth.logout': 'لاگ آؤٹ',
|
||||
'common.languages': 'زبانیں',
|
||||
'common.select_language': 'زبان منتخب کریں',
|
||||
'header.dashboard_tagline': 'ZeroClaw ڈیش بورڈ',
|
||||
};
|
||||
|
||||
export default ur;
|
||||
51
web/src/lib/i18n/locales/vi.ts
Normal file
51
web/src/lib/i18n/locales/vi.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const vi: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': 'Bảng điều khiển',
|
||||
'nav.agent': 'Tác tử',
|
||||
'nav.tools': 'Công cụ',
|
||||
'nav.cron': 'Lịch tác vụ',
|
||||
'nav.integrations': 'Tích hợp',
|
||||
'nav.memory': 'Bộ nhớ',
|
||||
'nav.config': 'Cấu hình',
|
||||
'nav.cost': 'Chi phí',
|
||||
'nav.logs': 'Nhật ký',
|
||||
'nav.doctor': 'Chẩn đoán',
|
||||
'dashboard.hero_title': 'Bảng điều khiển runtime điện xanh',
|
||||
'dashboard.live_gateway': 'Cổng hoạt động',
|
||||
'dashboard.unpaired': 'Chưa ghép đôi',
|
||||
'agent.title': 'Trò chuyện với tác tử',
|
||||
'agent.placeholder': 'Nhập tin nhắn…',
|
||||
'agent.connecting': 'Đang kết nối…',
|
||||
'agent.connected': 'Đã kết nối',
|
||||
'agent.disconnected': 'Đã ngắt kết nối',
|
||||
'tools.search': 'Tìm công cụ…',
|
||||
'tools.agent_tools': 'Công cụ tác tử',
|
||||
'tools.cli_tools': 'Công cụ CLI',
|
||||
'cron.add': 'Thêm tác vụ',
|
||||
'cron.scheduled_tasks': 'Tác vụ đã lên lịch',
|
||||
'integrations.title': 'Tích hợp',
|
||||
'memory.add_memory': 'Thêm bộ nhớ',
|
||||
'memory.search_entries': 'Tìm trong bộ nhớ…',
|
||||
'config.save': 'Lưu',
|
||||
'config.saving': 'Đang lưu…',
|
||||
'cost.session': 'Chi phí phiên',
|
||||
'cost.daily': 'Chi phí ngày',
|
||||
'cost.monthly': 'Chi phí tháng',
|
||||
'logs.title': 'Nhật ký trực tiếp',
|
||||
'logs.pause': 'Tạm dừng',
|
||||
'logs.resume': 'Tiếp tục',
|
||||
'doctor.title': 'Chẩn đoán hệ thống',
|
||||
'doctor.run': 'Chạy chẩn đoán',
|
||||
'doctor.running_short': 'Đang chạy…',
|
||||
'auth.pair_button': 'Ghép đôi',
|
||||
'auth.enter_code': 'Nhập mã ghép đôi một lần từ terminal',
|
||||
'auth.code_placeholder': 'Mã 6 chữ số',
|
||||
'auth.pairing_progress': 'Đang ghép đôi…',
|
||||
'auth.logout': 'Đăng xuất',
|
||||
'common.languages': 'Ngôn ngữ',
|
||||
'common.select_language': 'Chọn ngôn ngữ',
|
||||
'header.dashboard_tagline': 'Bảng điều khiển ZeroClaw',
|
||||
};
|
||||
|
||||
export default vi;
|
||||
51
web/src/lib/i18n/locales/zh-CN.ts
Normal file
51
web/src/lib/i18n/locales/zh-CN.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import type { TranslationKeys } from './en';
|
||||
|
||||
const zhCN: Partial<TranslationKeys> = {
|
||||
'nav.dashboard': '仪表盘',
|
||||
'nav.agent': '代理',
|
||||
'nav.tools': '工具',
|
||||
'nav.cron': '定时任务',
|
||||
'nav.integrations': '集成',
|
||||
'nav.memory': '记忆',
|
||||
'nav.config': '配置',
|
||||
'nav.cost': '成本跟踪',
|
||||
'nav.logs': '日志',
|
||||
'nav.doctor': '诊断',
|
||||
'dashboard.hero_title': '电光运行仪表盘',
|
||||
'dashboard.live_gateway': '在线网关',
|
||||
'dashboard.unpaired': '未配对',
|
||||
'agent.title': '代理聊天',
|
||||
'agent.placeholder': '输入消息…',
|
||||
'agent.connecting': '正在连接…',
|
||||
'agent.connected': '已连接',
|
||||
'agent.disconnected': '已断开',
|
||||
'tools.search': '搜索工具…',
|
||||
'tools.agent_tools': '代理工具',
|
||||
'tools.cli_tools': 'CLI 工具',
|
||||
'cron.add': '添加任务',
|
||||
'cron.scheduled_tasks': '定时任务',
|
||||
'integrations.title': '集成',
|
||||
'memory.add_memory': '添加记忆',
|
||||
'memory.search_entries': '搜索记忆条目…',
|
||||
'config.save': '保存',
|
||||
'config.saving': '正在保存…',
|
||||
'cost.session': '会话成本',
|
||||
'cost.daily': '每日成本',
|
||||
'cost.monthly': '每月成本',
|
||||
'logs.title': '实时日志',
|
||||
'logs.pause': '暂停',
|
||||
'logs.resume': '继续',
|
||||
'doctor.title': '系统诊断',
|
||||
'doctor.run': '运行诊断',
|
||||
'doctor.running_short': '运行中…',
|
||||
'auth.pair_button': '配对',
|
||||
'auth.enter_code': '输入终端中的一次性配对码',
|
||||
'auth.code_placeholder': '6 位代码',
|
||||
'auth.pairing_progress': '正在配对…',
|
||||
'auth.logout': '退出',
|
||||
'common.languages': '语言',
|
||||
'common.select_language': '选择语言',
|
||||
'header.dashboard_tagline': 'ZeroClaw 仪表盘',
|
||||
};
|
||||
|
||||
export default zhCN;
|
||||
75
web/src/lib/i18n/translate.ts
Normal file
75
web/src/lib/i18n/translate.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import type { Locale, LocaleDocumentTarget } from './types';
|
||||
import { getLocaleDirection } from './languages';
|
||||
import { translations } from './locales';
|
||||
|
||||
const LOCALE_PREFIX_MAP = new Map<string, Locale>([
|
||||
['zh', 'zh-CN'],
|
||||
['ja', 'ja'],
|
||||
['ko', 'ko'],
|
||||
['vi', 'vi'],
|
||||
['tl', 'tl'],
|
||||
['es', 'es'],
|
||||
['pt', 'pt'],
|
||||
['it', 'it'],
|
||||
['de', 'de'],
|
||||
['fr', 'fr'],
|
||||
['ar', 'ar'],
|
||||
['hi', 'hi'],
|
||||
['ru', 'ru'],
|
||||
['bn', 'bn'],
|
||||
['iw', 'he'],
|
||||
['he', 'he'],
|
||||
['pl', 'pl'],
|
||||
['cs', 'cs'],
|
||||
['nl', 'nl'],
|
||||
['tr', 'tr'],
|
||||
['uk', 'uk'],
|
||||
['id', 'id'],
|
||||
['th', 'th'],
|
||||
['ur', 'ur'],
|
||||
['ro', 'ro'],
|
||||
['sv', 'sv'],
|
||||
['el', 'el'],
|
||||
['hu', 'hu'],
|
||||
['fi', 'fi'],
|
||||
['da', 'da'],
|
||||
['nb', 'nb'],
|
||||
['no', 'nb'],
|
||||
]);
|
||||
|
||||
export function coerceLocale(locale: string | undefined): Locale {
|
||||
if (!locale) return 'en';
|
||||
const prefix = locale.toLowerCase().split(/[-_]/)[0];
|
||||
return LOCALE_PREFIX_MAP.get(prefix) ?? 'en';
|
||||
}
|
||||
|
||||
let currentLocale: Locale = 'en';
|
||||
|
||||
export function getLocale(): Locale {
|
||||
return currentLocale;
|
||||
}
|
||||
|
||||
export function setLocale(locale: Locale): void {
|
||||
currentLocale = locale;
|
||||
}
|
||||
|
||||
export function t(key: string): string {
|
||||
return translations[currentLocale]?.[key] ?? translations.en[key] ?? key;
|
||||
}
|
||||
|
||||
export function tLocale(key: string, locale: Locale): string {
|
||||
return translations[locale]?.[key] ?? translations.en[key] ?? key;
|
||||
}
|
||||
|
||||
export function applyLocaleToDocument(locale: Locale, target: LocaleDocumentTarget): void {
|
||||
const direction = getLocaleDirection(locale);
|
||||
|
||||
if (target.documentElement) {
|
||||
target.documentElement.lang = locale;
|
||||
target.documentElement.dir = direction;
|
||||
}
|
||||
|
||||
if (target.body) {
|
||||
target.body.dir = direction;
|
||||
}
|
||||
}
|
||||
46
web/src/lib/i18n/types.ts
Normal file
46
web/src/lib/i18n/types.ts
Normal file
@ -0,0 +1,46 @@
|
||||
export type Locale =
|
||||
| 'en'
|
||||
| 'zh-CN'
|
||||
| 'ja'
|
||||
| 'ko'
|
||||
| 'vi'
|
||||
| 'tl'
|
||||
| 'es'
|
||||
| 'pt'
|
||||
| 'it'
|
||||
| 'de'
|
||||
| 'fr'
|
||||
| 'ar'
|
||||
| 'hi'
|
||||
| 'ru'
|
||||
| 'bn'
|
||||
| 'he'
|
||||
| 'pl'
|
||||
| 'cs'
|
||||
| 'nl'
|
||||
| 'tr'
|
||||
| 'uk'
|
||||
| 'id'
|
||||
| 'th'
|
||||
| 'ur'
|
||||
| 'ro'
|
||||
| 'sv'
|
||||
| 'el'
|
||||
| 'hu'
|
||||
| 'fi'
|
||||
| 'da'
|
||||
| 'nb';
|
||||
|
||||
export type LocaleDirection = 'ltr' | 'rtl';
|
||||
|
||||
export interface LanguageOption {
|
||||
value: Locale;
|
||||
label: string;
|
||||
flag: string;
|
||||
direction: LocaleDirection;
|
||||
}
|
||||
|
||||
export interface LocaleDocumentTarget {
|
||||
documentElement?: { lang?: string; dir?: string };
|
||||
body?: { dir?: string } | null;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user