File size: 3,273 Bytes
3d50167
 
 
 
 
 
798bcc6
3d50167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
798bcc6
3d50167
 
 
 
 
 
 
 
 
798bcc6
 
 
 
 
3d50167
798bcc6
 
 
 
 
 
 
 
3d50167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// i18n.js - Utilitaire de traduction pour Kimi APP

class KimiI18nManager {
    constructor() {
        this.translations = {};
        this.currentLang = "en";
        this._reloadAttempted = false;
    }
    async setLanguage(lang) {
        this.currentLang = lang;
        await this.loadTranslations(lang);
        this.applyTranslations();
    }
    async loadTranslations(lang) {
        try {
            const response = await fetch("kimi-locale/" + lang + ".json");
            if (!response.ok) throw new Error("Translation file not found");
            this.translations = await response.json();
            this.currentLang = lang;
        } catch (e) {
            this.translations = {};
            this.currentLang = "en";
        }
    }
    t(key, params) {
        let str = this.translations[key] || key;
        if (params && typeof str === "string") {
            for (const [k, v] of Object.entries(params)) {
                str = str.replace(new RegExp(`{${k}}`, "g"), v);
            }
        }
        return str;
    }
    applyTranslations() {
        const missing = [];
        document.querySelectorAll("[data-i18n]").forEach(el => {
            const key = el.getAttribute("data-i18n");
            let params = undefined;
            const paramsAttr = el.getAttribute("data-i18n-params");
            if (paramsAttr) {
                try {
                    params = JSON.parse(paramsAttr);
                } catch {}
            }
            const val = this.t(key, params);
            if (val === key && this.currentLang !== "en") {
                missing.push(key);
            }
            el.textContent = val;
        });
        // Auto-reload once if new keys were added after initial load
        if (missing.length > 0 && !this._reloadAttempted) {
            this._reloadAttempted = true;
            this.loadTranslations(this.currentLang).then(() => {
                // Re-apply with fresh file
                requestAnimationFrame(() => this.applyTranslations());
            });
        }
        document.querySelectorAll("[data-i18n-title]").forEach(el => {
            const key = el.getAttribute("data-i18n-title");
            el.setAttribute("title", this.t(key));
        });
        document.querySelectorAll("[data-i18n-placeholder]").forEach(el => {
            const key = el.getAttribute("data-i18n-placeholder");
            el.setAttribute("placeholder", this.t(key));
        });
        if (document.title && this.translations["title"]) {
            document.title = this.translations["title"];
        }
    }
    detectLanguage() {
        const nav = (navigator && (navigator.language || (navigator.languages && navigator.languages[0]))) || "en";
        const short = String(nav).slice(0, 2).toLowerCase();
        return ["en", "fr", "es", "de", "it", "ja", "zh"].includes(short) ? short : "en";
    }
}

window.applyTranslations = function () {
    if (window.kimiI18nManager && typeof window.kimiI18nManager.applyTranslations === "function") {
        window.kimiI18nManager.applyTranslations();
    }
};

if (typeof document !== "undefined") {
    if (!window.kimiI18nManager) {
        window.kimiI18nManager = new KimiI18nManager();
    }
}

window.KimiI18nManager = KimiI18nManager;