fix(i18n): complexity tier names are translated everywhere they're shown
low/medium/high leaked as raw English into the bands legend, the tier badges on the Routing page, the pair complexity selects, the benchmark's tier column and the Playground decision panel. New trTier() helper renders the human name (ru: лёгкий/средний/сложный, de: leicht/mittel/schwer, fr/es/zh/tr likewise); custom tier names pass through untouched, badge colors stay keyed by the raw tier. Verified in the browser in Russian and German.
This commit is contained in:
Vendored
+5
@@ -48,6 +48,11 @@ export function onLangChange(fn) {
|
||||
return () => listeners.delete(fn);
|
||||
}
|
||||
|
||||
// Human name for a complexity tier; custom tier names pass through as-is.
|
||||
export function trTier(tier) {
|
||||
return ["low", "medium", "high"].includes(tier) ? t("tier." + tier) : tier;
|
||||
}
|
||||
|
||||
export function t(key, vars) {
|
||||
const d = DICTS[lang] || en;
|
||||
let s = d[key] ?? en[key] ?? key;
|
||||
|
||||
Vendored
+3
@@ -631,4 +631,7 @@ export default {
|
||||
"routing.tasks.addModel": "Modell",
|
||||
"routing.bands.enable": "Eigene Komplexitätsgrenzen",
|
||||
"routing.bands.hint": "Ziehen Sie die Griffe: wo low endet und high beginnt — die Griffe schieben einander, die Zahlen aktualisieren sich live. Der kontinuierliche Router-Score wird mit IHREN Grenzen neu eingeteilt; ohne Häkchen gelten die Grenzen des Routers.",
|
||||
"tier.low": "leicht",
|
||||
"tier.medium": "mittel",
|
||||
"tier.high": "schwer",
|
||||
};
|
||||
|
||||
Vendored
+3
@@ -624,4 +624,7 @@ export default {
|
||||
"routing.tasks.addModel": "model",
|
||||
"routing.bands.enable": "My complexity boundaries",
|
||||
"routing.bands.hint": "Drag the handles to set where low ends and where high begins — the handles push each other, the numbers update live. The router's continuous score is re-mapped with YOUR boundaries; unchecked = the router's own bands.",
|
||||
"tier.low": "low",
|
||||
"tier.medium": "medium",
|
||||
"tier.high": "high",
|
||||
};
|
||||
|
||||
Vendored
+3
@@ -631,4 +631,7 @@ export default {
|
||||
"routing.tasks.addModel": "modelo",
|
||||
"routing.bands.enable": "Mis límites de complejidad",
|
||||
"routing.bands.hint": "Arrastra los tiradores: dónde termina low y dónde empieza high — se empujan entre sí y las cifras se actualizan en vivo. La puntuación continua del router se re-mapea con TUS límites; sin marcar = las bandas del propio router.",
|
||||
"tier.low": "fácil",
|
||||
"tier.medium": "medio",
|
||||
"tier.high": "difícil",
|
||||
};
|
||||
|
||||
Vendored
+3
@@ -631,4 +631,7 @@ export default {
|
||||
"routing.tasks.addModel": "modèle",
|
||||
"routing.bands.enable": "Mes limites de complexité",
|
||||
"routing.bands.hint": "Faites glisser les poignées : où finit low et où commence high — elles se poussent l'une l'autre, les chiffres se mettent à jour en direct. Le score continu du routeur est re-découpé avec VOS limites ; décoché = les bandes du routeur.",
|
||||
"tier.low": "facile",
|
||||
"tier.medium": "moyen",
|
||||
"tier.high": "difficile",
|
||||
};
|
||||
|
||||
Vendored
+3
@@ -623,4 +623,7 @@ export default {
|
||||
"routing.tasks.addModel": "модель",
|
||||
"routing.bands.enable": "Мои границы сложности",
|
||||
"routing.bands.hint": "Тяните ручки: где кончается low и где начинается high — ручки толкают друг друга, цифры обновляются на лету. Непрерывный score роутера пересчитывается ВАШИМИ границами; галочка снята — действуют пороги самого роутера.",
|
||||
"tier.low": "лёгкий",
|
||||
"tier.medium": "средний",
|
||||
"tier.high": "сложный",
|
||||
};
|
||||
|
||||
Vendored
+3
@@ -631,4 +631,7 @@ export default {
|
||||
"routing.tasks.addModel": "model",
|
||||
"routing.bands.enable": "Kendi karmaşıklık sınırlarım",
|
||||
"routing.bands.hint": "Tutamaçları sürükleyin: low nerede biter, high nerede başlar — tutamaçlar birbirini iter, sayılar anlık güncellenir. Yönlendiricinin sürekli puanı SİZİN sınırlarınızla yeniden bölümlenir; işaret kaldırılırsa yönlendiricinin kendi bantları geçerli.",
|
||||
"tier.low": "kolay",
|
||||
"tier.medium": "orta",
|
||||
"tier.high": "zor",
|
||||
};
|
||||
|
||||
Vendored
+3
@@ -631,4 +631,7 @@ export default {
|
||||
"routing.tasks.addModel": "模型",
|
||||
"routing.bands.enable": "自定义复杂度边界",
|
||||
"routing.bands.hint": "拖动手柄设定 low 到哪里结束、high 从哪里开始 — 手柄会相互推动,数字实时更新。路由器的连续得分将按你的边界重新划分;取消勾选则使用路由器自身的边界。",
|
||||
"tier.low": "简单",
|
||||
"tier.medium": "中等",
|
||||
"tier.high": "困难",
|
||||
};
|
||||
|
||||
Vendored
+2
-2
@@ -8,7 +8,7 @@
|
||||
// (keyword checks with | synonyms, think-tag stripping, anti-loop detection,
|
||||
// pass/partial/fail), now embedded, localized and CDN-free.
|
||||
import { h, mount, toast, ms, money, moneyEl } from "../ui.js";
|
||||
import { t } from "../i18n.js";
|
||||
import { t, trTier } from "../i18n.js";
|
||||
import { api, testStream } from "../api.js";
|
||||
|
||||
// ── built-in suite ──────────────────────────────────────────────────────────
|
||||
@@ -402,7 +402,7 @@ export async function renderBenchmark() {
|
||||
: h("span", { class: r.taskOk ? "" : "err" },
|
||||
(r.taskOk ? "✓ " : "✗ ") + r.task,
|
||||
r.taskOk ? "" : h("div", { class: "muted small" }, t("bm.expectedLbl") + " " + (r.expected || []).join("/")))),
|
||||
h("td", {}, r.tier ? h("span", { class: "badge tier-" + r.tier }, r.tier) : "—"),
|
||||
h("td", {}, r.tier ? h("span", { class: "badge tier-" + r.tier }, trTier(r.tier)) : "—"),
|
||||
h("td", {},
|
||||
h("span", { class: "mono small" }, r.chosen || "—"),
|
||||
r.cost > 0 ? h("div", { class: "muted small" }, moneyEl(r.cost)) : null,
|
||||
|
||||
Vendored
+2
-2
@@ -5,7 +5,7 @@
|
||||
// Media results are decoded in the browser (PPM → canvas, MJPEG AVI → canvas
|
||||
// player synced to the wav) — the same no-ffmpeg stance as the engine itself.
|
||||
import { h, mount, toast, money, moneyEl, ms } from "../ui.js";
|
||||
import { t } from "../i18n.js";
|
||||
import { t, trTier } from "../i18n.js";
|
||||
import { api, testStream, mediaFileUrl, mediaFileBytes } from "../api.js";
|
||||
import { appState } from "../app.js";
|
||||
import { ppmToCanvas, fileToPpmB64, aviJpegFrames, mjpegPlayer } from "../media-utils.js";
|
||||
@@ -206,7 +206,7 @@ export async function renderPlayground() {
|
||||
decision,
|
||||
h("div", { class: "card-head" }, h("h3", {}, t("pg.decision"))),
|
||||
kv(t("pg.task"), c.task_label || "—"),
|
||||
kv(t("pg.tier"), c.complexity?.tier ? h("span", { class: "badge tier-" + c.complexity.tier }, c.complexity.tier) : "—"),
|
||||
kv(t("pg.tier"), c.complexity?.tier ? h("span", { class: "badge tier-" + c.complexity.tier }, trTier(c.complexity.tier)) : "—"),
|
||||
h(
|
||||
"div",
|
||||
{ class: "kv", style: "display:block" },
|
||||
|
||||
Vendored
+6
-6
@@ -1,6 +1,6 @@
|
||||
// Routing — tier editor (ordered model chips), default model, and policy.
|
||||
import { h, mount, toast } from "../ui.js";
|
||||
import { t } from "../i18n.js";
|
||||
import { t, trTier } from "../i18n.js";
|
||||
import { api } from "../api.js";
|
||||
import { appState } from "../app.js";
|
||||
|
||||
@@ -153,9 +153,9 @@ export async function renderRouting() {
|
||||
// подписи не наезжают, когда ручки рядом
|
||||
hMed.querySelector(".bands-val").classList.toggle("raised", me - lo < 0.09);
|
||||
mount(legend,
|
||||
h("span", { class: "badge tier-low" }, `low ≤ ${lo.toFixed(2)}`),
|
||||
h("span", { class: "badge tier-medium" }, `medium ≤ ${me.toFixed(2)}`),
|
||||
h("span", { class: "badge tier-high" }, `high > ${me.toFixed(2)}`));
|
||||
h("span", { class: "badge tier-low" }, `${trTier("low")} ≤ ${lo.toFixed(2)}`),
|
||||
h("span", { class: "badge tier-medium" }, `${trTier("medium")} ≤ ${me.toFixed(2)}`),
|
||||
h("span", { class: "badge tier-high" }, `${trTier("high")} > ${me.toFixed(2)}`));
|
||||
track.classList.toggle("disabled", !st.bands);
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ export async function renderRouting() {
|
||||
return h(
|
||||
"div",
|
||||
{ class: "tierrow" },
|
||||
h("div", { class: "tname" }, h("span", { class: "badge tier-" + tier }, tier)),
|
||||
h("div", { class: "tname" }, h("span", { class: "badge tier-" + tier }, trTier(tier))),
|
||||
chipEditor(st.tiers, tier)
|
||||
);
|
||||
}
|
||||
@@ -254,7 +254,7 @@ export async function renderRouting() {
|
||||
"select",
|
||||
{ class: "pair-tier", title: t("routing.tasks.tierHint") },
|
||||
h("option", { value: "any" }, t("routing.tasks.tierAny")),
|
||||
...Object.keys(st.tiers).map((tr) => h("option", { value: tr }, tr))
|
||||
...Object.keys(st.tiers).map((tr) => h("option", { value: tr }, trTier(tr)))
|
||||
);
|
||||
tierSel.value = p.tier;
|
||||
tierSel.addEventListener("change", () => { p.tier = tierSel.value; });
|
||||
|
||||
Reference in New Issue
Block a user