// Tiny i18n harness — Russian primary, English fallback (BCP-47 prefix // match — any `en` variant). Bootstrap forwards `clientLanguage` from the // host; main.tsx can also call `createT()` without args before bootstrap // completes (falls back to navigator.language, then RU). // // Identical mechanics to apps/widget-telegram/src/i18n/index.ts; the // Discord widget keeps its own dictionary file because the copy differs — // QR-only flow, no SMS, no 2FA password form. import { RU, type StringKey } from './ru'; import { EN } from './en'; const interpolate = (s: string, vars?: Record): string => { if (!vars) return s; return s.replace(/\{(\w+)\}/g, (_, k) => vars[k] ?? `{${k}}`); }; const pickDict = (clientLanguage: string | undefined): Record => { const lang = ( clientLanguage || (typeof navigator !== 'undefined' ? navigator.language : '') || 'ru' ).toLowerCase(); return lang.startsWith('en') ? EN : RU; }; export type T = (key: StringKey, vars?: Record) => string; export const createT = (clientLanguage?: string): T => { const dict = pickDict(clientLanguage); return (key, vars) => interpolate(dict[key], vars); }; export type { StringKey };