Veröffentlichte Quellen
Quellen als ZIP herunterladen
CH-J Tools
Durchsuchen Sie Verzeichnisse und Dateien einer bestimmten Anwendungsausgabe.
CH-J / Server Manager
872 Dateien
core-20261030T220507Z-61e4558d889f
Hinzugefügt: · Erstellt:
1
"use strict";3
// Core UI translations. The texts live in data files (i18n/core/<language>.json) and the4
// list of languages in i18n/languages.json, so a language is added without code changes.5
// The Rust Core injects both into the window before this script runs; Node tests read the files.6
(function exposeI18n(root, factory) {7
const api = factory();8
if (typeof module === "object" && module.exports) module.exports = api;9
else {10
root.CHJ_I18N = api;11
root.chjI18n = api.createI18n(api.defaultLanguage);12
}13
})(typeof globalThis !== "undefined" ? globalThis : this, () => {14
function loadData() {15
const injected = globalThis.__CHJ_I18N__;16
if (injected && injected.catalogs && injected.catalogs.core) return { manifest: injected.manifest, catalogs: injected.catalogs.core };17
if (typeof require === "function" && typeof __dirname === "string") {18
const fs = require("fs"), path = require("path"), dir = path.join(__dirname, "i18n");19
const manifest = JSON.parse(fs.readFileSync(path.join(dir, "languages.json"), "utf8"));20
const catalogs = {};21
for (const language of manifest.languages) {22
const file = path.join(dir, "core", `${language.code}.json`);23
if (fs.existsSync(file)) catalogs[language.code] = JSON.parse(fs.readFileSync(file, "utf8"));24
}25
return { manifest, catalogs };26
}27
return { manifest: { defaultLanguage: "cs", fallbackLanguage: "en", languages: [] }, catalogs: {} };28
}30
const { manifest, catalogs } = loadData();31
const languages = Object.freeze((manifest.languages || []).filter((entry) => catalogs[entry.code]).map((entry) => Object.freeze({ ...entry })));32
const defaultLanguage = catalogs[manifest.defaultLanguage] ? manifest.defaultLanguage : (languages[0]?.code || "cs");33
const sourceLanguage = catalogs.cs ? "cs" : defaultLanguage;34
const localeByLanguage = Object.freeze(Object.fromEntries(languages.map((entry) => [entry.code, entry.locale || entry.code])));35
const supportedLanguages = Object.freeze(languages.map((entry) => entry.code));37
const entryByLanguage = Object.freeze(Object.fromEntries(languages.map((entry) => [entry.code, entry])));39
// Exact code first (zh-tw, de-at), then the base language (fr-CA → fr).40
function normalizeLanguage(value) {41
const language = String(value || "").toLowerCase().replace(/_/g, "-");42
if (supportedLanguages.includes(language)) return language;43
const base = language.split("-")[0];44
return supportedLanguages.includes(base) ? base : defaultLanguage;45
}47
// Lookup order: the language, its parent (regional variants), the fallback language, Czech.48
function lookupChain(language) {49
const parent = entryByLanguage[language]?.parent || (language.includes("-") ? language.split("-")[0] : null);50
return [...new Set([language, parent, manifest.fallbackLanguage, sourceLanguage].filter(Boolean))];51
}53
function direction(language) {54
return entryByLanguage[language]?.dir === "rtl" ? "rtl" : "ltr";55
}57
function interpolate(template, values = {}) {58
return String(template).replace(/\{([A-Za-z0-9_]+)\}/g, (match, key) => (59
Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : match60
));61
}63
function createI18n(initialLanguage = defaultLanguage) {64
let language = normalizeLanguage(initialLanguage);65
const staticText = new WeakMap();66
return Object.freeze({67
apply(rootNode = document) {68
// Text the application has set itself is not the static translation; its renderers refresh it.69
rootNode.querySelectorAll("[data-i18n]").forEach((element) => {70
if (staticText.has(element) && element.textContent !== staticText.get(element)) return;71
const text = this.t(element.dataset.i18n);72
element.textContent = text;73
staticText.set(element, text);74
});75
rootNode.querySelectorAll("[data-i18n-placeholder]").forEach((element) => { element.placeholder = this.t(element.dataset.i18nPlaceholder); });76
rootNode.querySelectorAll("[data-i18n-aria-label]").forEach((element) => { element.setAttribute("aria-label", this.t(element.dataset.i18nAriaLabel)); });77
},78
formatNumber(value, options) { return Number(value).toLocaleString(localeByLanguage[language], options); },79
getLanguage() { return language; },80
getDirection() { return direction(language); },81
getLocale() { return localeByLanguage[language]; },82
setLanguage(value) { language = normalizeLanguage(value); return language; },83
t(key, values) {84
const template = lookupChain(language).map((code) => catalogs[code]?.[key]).find((value) => value !== undefined) ?? key;85
return interpolate(template, values);86
}87
});88
}90
return Object.freeze({ catalogs, createI18n, interpolate, normalizeLanguage, direction, supportedLanguages, languages, defaultLanguage });91
});SHA-256
12b7c32c09497f45ed2e5afe7df6e6fb86e8bf15d268840d818ca70ffa620fd5CH-J Proprietary Software License 1.14 · Die Quellen werden unter der CH-J Proprietary Software License 1.14 bereitgestellt. Ihre Verfügbarkeit ändert die Lizenzbedingungen nicht und gewährt keine zusätzlichen Rechte.
SHA-256 des Archivs
77380d4805485ffa4027fbe7858b5836f197a4aa9d52358a43e2d12d018744df