1const HOME_I18N_URL = "/documents/i18n.json"; 2const HOME_ROUTE = "/"; 3 4function getHomeLocale() { 5 const prefix = window.location.pathname.split("/")[1]; 6 return ["zh", "ja"].includes(prefix) ? prefix : "en"; 7} 8 9function localizedHomeValue(entry, locale) { 10 return entry?.[locale] ?? entry?.en ?? ""; 11} 12 13function appendTextWithAiModeFlow(el, value, locale) { 14 const phrase = locale === "zh" ? "AI模å¼" : "AI Mode"; 15 const start = value.indexOf(phrase); 16 17 if (start === -1) { 18 el.append(document.createTextNode(value)); 19 return; 20 } 21 22 const before = value.slice(0, start); 23 const after = value.slice(start + phrase.length); 24 const flowText = document.createElement("span"); 25 26 flowText.className = "ai-mode-flow"; 27 flowText.textContent = phrase; 28 29 if (before) el.append(document.createTextNode(before)); 30 el.append(flowText); 31 if (after) el.append(document.createTextNode(after)); 32} 33 34function appendHeroTitleLine(el, value, locale) { 35 const line = document.createElement("span"); 36 const hasAiMode = value.includes(locale === "zh" ? "AI模å¼" : "AI Mode"); 37 38 line.className = hasAiMode ? "hero-title-line hero-title-nowrap" : "hero-title-line"; 39 appendTextWithAiModeFlow(line, value, locale); 40 el.append(line); 41} 42 43function appendCmsLines(el, values) { 44 el.textContent = ""; 45 const locale = getHomeLocale(); 46 47 values.forEach((value, index) => { 48 if (el.classList.contains("hero-contact-title")) { 49 appendHeroTitleLine(el, value, locale); 50 return; 51 } 52 53 if (index > 0) el.appendChild(document.createElement("br")); 54 appendTextWithAiModeFlow(el, value, locale); 55 }); 56} 57 58function cmsEntriesByKey(page) { 59 return Object.fromEntries((page.strings || []).map((entry) => [entry.key, entry])); 60} 61 62function applyHomeI18n(page, locale) { 63 const entries = cmsEntriesByKey(page); 64 65 document.querySelectorAll("[data-cms]").forEach((el) => { 66 const keys = String(el.dataset.cms || "") 67 .split(",") 68 .map((key) => key.trim()) 69 .filter(Boolean); 70 71 const values = keys 72 .map((key) => localizedHomeValue(entries[key], locale)) 73 .filter((value) => value !== ""); 74 75 if (!values.length) return; 76 77 const attr = el.dataset.cmsAttr; 78 if (attr) { 79 el.setAttribute(attr, values[0]); 80 return; 81 } 82 83 if (keys.length > 1) { 84 appendCmsLines(el, values); 85 return; 86 } 87 88 el.textContent = values[0]; 89 }); 90} 91 92async function initHomeI18n() { 93 const response = await fetch(HOME_I18N_URL); 94 if (!response.ok) throw new Error(`i18n request failed with ${response.status}`); 95 96 const i18n = await response.json(); 97 const page = i18n.pages?.[HOME_ROUTE]; 98 if (!page) return; 99 100 applyHomeI18n(page, getHomeLocale()); 101} 102 103initHomeI18n().catch((error) => { 104 console.error(error); 105});
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.