1import { translations } from "../data/i18n.js"; 2 3const STORAGE_KEY = "cis-uw-language"; 4const supported = ["en", "zh"]; 5 6export function getLanguage() { 7 const saved = localStorage.getItem(STORAGE_KEY); 8 return supported.includes(saved) ? saved : "en"; 9} 10 11export function t(path) { 12 return path.split(".").reduce((value, key) => value?.[key], translations[getLanguage()]) ?? path; 13} 14 15export function localized(value) { 16 if (!value || typeof value !== "object") return value ?? ""; 17 return value[getLanguage()] ?? value.en ?? ""; 18} 19 20export function applyDocumentLanguage() { 21 const language = getLanguage(); 22 document.documentElement.lang = language === "zh" ? "zh-CN" : "en"; 23 document.querySelectorAll("[data-i18n]").forEach((element) => { 24 element.textContent = t(element.dataset.i18n); 25 }); 26 document.querySelectorAll("[data-i18n-aria]").forEach((element) => { 27 element.setAttribute("aria-label", t(element.dataset.i18nAria)); 28 }); 29} 30 31export function toggleLanguage() { 32 const next = getLanguage() === "en" ? "zh" : "en"; 33 localStorage.setItem(STORAGE_KEY, next); 34 applyDocumentLanguage(); 35 window.dispatchEvent(new CustomEvent("languagechange", { detail: { language: next } })); 36}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.