frontend-auto-cms 1.0.12 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime/dashboard.js +233 -191
- package/package.json +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
const
|
|
2
|
-
function
|
|
3
|
-
localStorage.setItem(
|
|
1
|
+
const ve = "cms-export.patch.json", we = "frontend-auto-cms::content", oe = "frontend-auto-cms::locales";
|
|
2
|
+
function re(e) {
|
|
3
|
+
localStorage.setItem(we, JSON.stringify(e));
|
|
4
4
|
}
|
|
5
|
-
function
|
|
5
|
+
function se() {
|
|
6
6
|
try {
|
|
7
|
-
const e = localStorage.getItem(
|
|
7
|
+
const e = localStorage.getItem(oe);
|
|
8
8
|
return e ? JSON.parse(e) : {};
|
|
9
9
|
} catch {
|
|
10
10
|
return {};
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
function I(e) {
|
|
14
|
-
localStorage.setItem(
|
|
14
|
+
localStorage.setItem(oe, JSON.stringify(e));
|
|
15
15
|
}
|
|
16
16
|
async function ke() {
|
|
17
17
|
try {
|
|
@@ -24,7 +24,7 @@ async function ke() {
|
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
async function
|
|
27
|
+
async function ie() {
|
|
28
28
|
try {
|
|
29
29
|
const e = await fetch("/cms-locales.json", { cache: "no-store" });
|
|
30
30
|
if (!e.ok)
|
|
@@ -35,7 +35,7 @@ async function oe() {
|
|
|
35
35
|
return {};
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
async function
|
|
38
|
+
async function Le() {
|
|
39
39
|
try {
|
|
40
40
|
const e = await fetch("/cms-route-map.json", { cache: "no-store" });
|
|
41
41
|
if (!e.ok)
|
|
@@ -46,9 +46,9 @@ async function we() {
|
|
|
46
46
|
return {};
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function $e(e) {
|
|
50
50
|
const t = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), a = URL.createObjectURL(t), o = document.createElement("a");
|
|
51
|
-
o.href = a, o.download =
|
|
51
|
+
o.href = a, o.download = ve, o.click(), URL.revokeObjectURL(a);
|
|
52
52
|
}
|
|
53
53
|
function A(e) {
|
|
54
54
|
return e.replace(/[^\w]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
@@ -60,15 +60,15 @@ function v(e) {
|
|
|
60
60
|
const a = (e.getAttribute("class") ?? "").split(/\s+/).filter(Boolean)[0];
|
|
61
61
|
return a ? `${e.tagName.toLowerCase()}.${a}` : e.tagName.toLowerCase();
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function le(e) {
|
|
64
64
|
return ["SCRIPT", "STYLE", "NOSCRIPT", "IFRAME"].includes(e.tagName);
|
|
65
65
|
}
|
|
66
66
|
function N(e) {
|
|
67
67
|
return (e ?? "").replace(/\s+/g, " ").trim();
|
|
68
68
|
}
|
|
69
|
-
function
|
|
69
|
+
function Se(e, t, a) {
|
|
70
70
|
const o = t.parentElement;
|
|
71
|
-
if (!o ||
|
|
71
|
+
if (!o || le(o))
|
|
72
72
|
return null;
|
|
73
73
|
if (Array.from(o.childNodes).filter(
|
|
74
74
|
(s) => s.nodeType === Node.TEXT_NODE && N(s.nodeValue).length > 0
|
|
@@ -95,22 +95,22 @@ function S(e = document, t) {
|
|
|
95
95
|
if (m.length < 2)
|
|
96
96
|
continue;
|
|
97
97
|
o += 1;
|
|
98
|
-
const
|
|
99
|
-
if (!
|
|
98
|
+
const J = `${A(i || "index")}.text.${o}`, O = Se(e, b, J);
|
|
99
|
+
if (!O)
|
|
100
100
|
continue;
|
|
101
101
|
a.push({
|
|
102
102
|
id: `dom_txt_${o}`,
|
|
103
|
-
key:
|
|
103
|
+
key: J,
|
|
104
104
|
type: "text",
|
|
105
|
-
label: v(
|
|
105
|
+
label: v(O),
|
|
106
106
|
value: m,
|
|
107
|
-
selector: v(
|
|
107
|
+
selector: v(O),
|
|
108
108
|
sourceRefs: [{ file: i, original: m }]
|
|
109
109
|
});
|
|
110
110
|
continue;
|
|
111
111
|
}
|
|
112
112
|
const l = d;
|
|
113
|
-
if (
|
|
113
|
+
if (le(l))
|
|
114
114
|
continue;
|
|
115
115
|
const p = l.tagName.toLowerCase();
|
|
116
116
|
if (p === "img" || p === "video") {
|
|
@@ -172,7 +172,7 @@ function S(e = document, t) {
|
|
|
172
172
|
nodes: a
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
|
-
function
|
|
175
|
+
function B(e, t = document) {
|
|
176
176
|
if (!e.key)
|
|
177
177
|
return;
|
|
178
178
|
const a = t.querySelector(`[data-cms-key="${CSS.escape(e.key)}"]`);
|
|
@@ -191,7 +191,7 @@ function P(e, t = document) {
|
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
|
-
const
|
|
194
|
+
const P = [
|
|
195
195
|
{ code: "af", label: "Afrikaans", nllb: "afr_Latn" },
|
|
196
196
|
{ code: "ar", label: "Arabic", nllb: "arb_Arab" },
|
|
197
197
|
{ code: "az", label: "Azerbaijani", nllb: "azj_Latn" },
|
|
@@ -256,24 +256,24 @@ const B = [
|
|
|
256
256
|
{ code: "uz", label: "Uzbek", nllb: "uzn_Latn" },
|
|
257
257
|
{ code: "vi", label: "Vietnamese", nllb: "vie_Latn" },
|
|
258
258
|
{ code: "zh", label: "Chinese (Simplified)", nllb: "zho_Hans" }
|
|
259
|
-
],
|
|
260
|
-
|
|
261
|
-
),
|
|
262
|
-
function
|
|
259
|
+
], W = Object.fromEntries(
|
|
260
|
+
P.map((e) => [e.nllb.slice(0, 3).toLowerCase(), e.code])
|
|
261
|
+
), Ee = "https://api.mymemory.translated.net/get";
|
|
262
|
+
function Y(e) {
|
|
263
263
|
const t = e.trim().toLowerCase().split(/[-_]/)[0];
|
|
264
264
|
if (/^[a-z]{2}$/i.test(t))
|
|
265
265
|
return t;
|
|
266
|
-
if (/^[a-z]{3}$/i.test(t) &&
|
|
267
|
-
return
|
|
266
|
+
if (/^[a-z]{3}$/i.test(t) && W[t])
|
|
267
|
+
return W[t];
|
|
268
268
|
throw new Error(`Unsupported language code "${e}" for MyMemory translation.`);
|
|
269
269
|
}
|
|
270
|
-
async function
|
|
270
|
+
async function _e(e, t, a) {
|
|
271
271
|
if (!e.trim())
|
|
272
272
|
return e;
|
|
273
273
|
const o = new URLSearchParams({
|
|
274
274
|
q: e,
|
|
275
275
|
langpair: `${t}|${a}`
|
|
276
|
-
}), n = await fetch(`${
|
|
276
|
+
}), n = await fetch(`${Ee}?${o.toString()}`, { method: "GET" });
|
|
277
277
|
if (!n.ok)
|
|
278
278
|
throw new Error(`MyMemory request failed (${n.status})`);
|
|
279
279
|
const r = await n.json();
|
|
@@ -282,8 +282,8 @@ async function Ee(e, t, a) {
|
|
|
282
282
|
const s = r.responseData?.translatedText;
|
|
283
283
|
return typeof s == "string" && s.trim() ? s : e;
|
|
284
284
|
}
|
|
285
|
-
async function
|
|
286
|
-
const n =
|
|
285
|
+
async function Ae(e, t, a = "en", o) {
|
|
286
|
+
const n = Y(a), r = Y(t), s = /* @__PURE__ */ new Map(), i = {}, c = Object.entries(e), u = c.length;
|
|
287
287
|
let d = 0;
|
|
288
288
|
for (const [l, p] of c) {
|
|
289
289
|
if (s.has(p)) {
|
|
@@ -291,7 +291,7 @@ async function _e(e, t, a = "en", o) {
|
|
|
291
291
|
continue;
|
|
292
292
|
}
|
|
293
293
|
try {
|
|
294
|
-
const g = await
|
|
294
|
+
const g = await _e(p, n, r);
|
|
295
295
|
s.set(p, g), i[l] = g;
|
|
296
296
|
} catch {
|
|
297
297
|
i[l] = p;
|
|
@@ -300,13 +300,13 @@ async function _e(e, t, a = "en", o) {
|
|
|
300
300
|
}
|
|
301
301
|
return i;
|
|
302
302
|
}
|
|
303
|
-
function
|
|
303
|
+
function ce(e) {
|
|
304
304
|
return /^[^/\s]+\/[^/\s]+$/.test(e);
|
|
305
305
|
}
|
|
306
|
-
function
|
|
306
|
+
function de(e) {
|
|
307
307
|
return /^([^/\s]+\/)+[^/\s]+$/.test(e);
|
|
308
308
|
}
|
|
309
|
-
async function
|
|
309
|
+
async function Te(e, t, a) {
|
|
310
310
|
return (await fetch(
|
|
311
311
|
`https://gitlab.com/api/v4/projects/${encodeURIComponent(e.repository)}/repository/files/${encodeURIComponent(a)}?ref=${encodeURIComponent(e.branch)}`,
|
|
312
312
|
{
|
|
@@ -315,7 +315,7 @@ async function Ae(e, t, a) {
|
|
|
315
315
|
}
|
|
316
316
|
)).ok;
|
|
317
317
|
}
|
|
318
|
-
async function
|
|
318
|
+
async function Ie() {
|
|
319
319
|
try {
|
|
320
320
|
const e = await fetch("/cms-hosting.json", { cache: "no-store" });
|
|
321
321
|
if (!e.ok)
|
|
@@ -324,7 +324,7 @@ async function Te() {
|
|
|
324
324
|
if (!t || !t.provider || t.provider === "none" || t.provider !== "github" && t.provider !== "gitlab" || typeof t.repository != "string" || !t.repository.trim())
|
|
325
325
|
return null;
|
|
326
326
|
const a = t.repository.trim();
|
|
327
|
-
return t.provider === "github" && !
|
|
327
|
+
return t.provider === "github" && !ce(a) || t.provider === "gitlab" && !de(a) || typeof t.branch != "string" || !t.branch.trim() ? null : { ...t, repository: a, branch: t.branch.trim() };
|
|
328
328
|
} catch {
|
|
329
329
|
return null;
|
|
330
330
|
}
|
|
@@ -352,7 +352,29 @@ async function $(e, t, a, o, n) {
|
|
|
352
352
|
})).ok)
|
|
353
353
|
throw new Error(`GitHub publish failed for ${a}`);
|
|
354
354
|
}
|
|
355
|
-
function
|
|
355
|
+
async function V(e, t, a) {
|
|
356
|
+
return (await fetch(`https://api.github.com/repos/${e.repository}/branches/${encodeURIComponent(a)}`, {
|
|
357
|
+
headers: { Authorization: `Bearer ${t}` }
|
|
358
|
+
})).ok;
|
|
359
|
+
}
|
|
360
|
+
async function Ce(e, t) {
|
|
361
|
+
const a = await fetch(`https://api.github.com/repos/${e.repository}`, {
|
|
362
|
+
headers: { Authorization: `Bearer ${t}` }
|
|
363
|
+
});
|
|
364
|
+
return a.ok && (await a.json()).default_branch?.trim() || null;
|
|
365
|
+
}
|
|
366
|
+
async function je(e, t) {
|
|
367
|
+
const a = e.branch.trim();
|
|
368
|
+
if (await V(e, t, a))
|
|
369
|
+
return { ...e, branch: a };
|
|
370
|
+
const o = await Ce(e, t);
|
|
371
|
+
if (!o)
|
|
372
|
+
throw new Error(`Configured branch "${a}" was not found and repo default branch could not be resolved.`);
|
|
373
|
+
if (!await V(e, t, o))
|
|
374
|
+
throw new Error(`Configured branch "${a}" was not found. Resolved default branch "${o}" is also unavailable.`);
|
|
375
|
+
return { ...e, branch: o };
|
|
376
|
+
}
|
|
377
|
+
function Oe(e, t, a, o = 1) {
|
|
356
378
|
if (!t || o < 1)
|
|
357
379
|
return e;
|
|
358
380
|
let n = -1, r = 0;
|
|
@@ -363,15 +385,15 @@ function Ie(e, t, a, o = 1) {
|
|
|
363
385
|
}
|
|
364
386
|
return `${e.slice(0, n)}${a}${e.slice(n + t.length)}`;
|
|
365
387
|
}
|
|
366
|
-
function
|
|
388
|
+
function ze(e) {
|
|
367
389
|
const t = (e ?? "").trim().replace(/\\/g, "/").replace(/^\/+/, "");
|
|
368
390
|
return !t || t.includes("..") ? null : t;
|
|
369
391
|
}
|
|
370
|
-
function
|
|
392
|
+
function Ne(e) {
|
|
371
393
|
const t = atob(e.replace(/\s+/g, "")), a = Uint8Array.from(t, (o) => o.charCodeAt(0));
|
|
372
394
|
return new TextDecoder().decode(a);
|
|
373
395
|
}
|
|
374
|
-
async function
|
|
396
|
+
async function Me(e, t, a) {
|
|
375
397
|
const o = `https://api.github.com/repos/${e.repository}/contents/${encodeURIComponent(a).replace(/%2F/g, "/")}`, n = await fetch(`${o}?ref=${encodeURIComponent(e.branch)}`, {
|
|
376
398
|
headers: { Authorization: `Bearer ${t}` }
|
|
377
399
|
});
|
|
@@ -380,15 +402,15 @@ async function je(e, t, a) {
|
|
|
380
402
|
const r = await n.json();
|
|
381
403
|
return !r.sha || !r.content || r.encoding !== "base64" ? null : {
|
|
382
404
|
sha: r.sha,
|
|
383
|
-
content:
|
|
405
|
+
content: Ne(r.content)
|
|
384
406
|
};
|
|
385
407
|
}
|
|
386
|
-
async function
|
|
408
|
+
async function Re(e, t, a, o) {
|
|
387
409
|
const n = /* @__PURE__ */ new Map();
|
|
388
410
|
let r = 0;
|
|
389
411
|
a.forEach((i) => {
|
|
390
412
|
i.find !== i.replace && (r += 1);
|
|
391
|
-
const c =
|
|
413
|
+
const c = ze(i.file);
|
|
392
414
|
if (!c)
|
|
393
415
|
return;
|
|
394
416
|
const u = n.get(c) ?? [];
|
|
@@ -396,36 +418,36 @@ async function ze(e, t, a, o) {
|
|
|
396
418
|
});
|
|
397
419
|
let s = 0;
|
|
398
420
|
for (const [i, c] of n.entries()) {
|
|
399
|
-
const u = await
|
|
421
|
+
const u = await Me(e, t, i);
|
|
400
422
|
if (!u)
|
|
401
423
|
continue;
|
|
402
424
|
let d = u.content;
|
|
403
425
|
c.forEach((l) => {
|
|
404
|
-
d =
|
|
426
|
+
d = Oe(d, l.find, l.replace, l.occurrence ?? 1);
|
|
405
427
|
}), d !== u.content && (await $(e, t, i, d, o), s += 1);
|
|
406
428
|
}
|
|
407
429
|
return { updatedFiles: s, attemptedFiles: n.size, actionableOperations: r };
|
|
408
430
|
}
|
|
409
|
-
async function
|
|
410
|
-
const o = `chore(cms): publish content updates ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
411
|
-
if (
|
|
431
|
+
async function Be(e, t, a) {
|
|
432
|
+
const o = await je(e, t), n = `chore(cms): publish content updates ${(/* @__PURE__ */ new Date()).toISOString()}`, r = await Re(o, t, a.operations ?? [], n);
|
|
433
|
+
if (r.actionableOperations > 0 && r.updatedFiles === 0)
|
|
412
434
|
throw new Error(
|
|
413
|
-
`No source files were updated (${
|
|
435
|
+
`No source files were updated (${r.attemptedFiles} candidate files checked). Run setup again to refresh cms-route-map.json and retry.`
|
|
414
436
|
);
|
|
415
|
-
if (await $(
|
|
416
|
-
for (const [
|
|
417
|
-
await $(
|
|
437
|
+
if (await $(o, t, "cms-content.json", JSON.stringify(a.content, null, 2), n), a.locales) {
|
|
438
|
+
for (const [s, i] of Object.entries(a.locales))
|
|
439
|
+
await $(o, t, `locales/${s}.json`, JSON.stringify(i, null, 2), n);
|
|
418
440
|
await $(
|
|
419
|
-
|
|
441
|
+
o,
|
|
420
442
|
t,
|
|
421
443
|
"cms-locales.json",
|
|
422
444
|
JSON.stringify({ version: 1, locales: a.locales }, null, 2),
|
|
423
|
-
|
|
445
|
+
n
|
|
424
446
|
);
|
|
425
447
|
}
|
|
426
|
-
await $(
|
|
448
|
+
await $(o, t, "cms-export.patch.json", JSON.stringify(a, null, 2), n);
|
|
427
449
|
}
|
|
428
|
-
async function
|
|
450
|
+
async function Pe(e, t, a) {
|
|
429
451
|
const o = [
|
|
430
452
|
{ filePath: "cms-content.json", content: JSON.stringify(a.content, null, 2) },
|
|
431
453
|
{ filePath: "cms-export.patch.json", content: JSON.stringify(a, null, 2) }
|
|
@@ -437,7 +459,7 @@ async function Me(e, t, a) {
|
|
|
437
459
|
}
|
|
438
460
|
const n = [];
|
|
439
461
|
for (const s of o) {
|
|
440
|
-
const i = await
|
|
462
|
+
const i = await Te(e, t, s.filePath);
|
|
441
463
|
n.push({
|
|
442
464
|
action: i ? "update" : "create",
|
|
443
465
|
file_path: s.filePath,
|
|
@@ -458,18 +480,18 @@ async function Me(e, t, a) {
|
|
|
458
480
|
})).ok)
|
|
459
481
|
throw new Error("GitLab publish failed.");
|
|
460
482
|
}
|
|
461
|
-
async function
|
|
483
|
+
async function De(e, t, a) {
|
|
462
484
|
if (!a || !t.trim())
|
|
463
485
|
return !1;
|
|
464
|
-
if (a.provider === "github" && !
|
|
486
|
+
if (a.provider === "github" && !ce(a.repository))
|
|
465
487
|
throw new Error('Invalid GitHub repository format. Use "owner/repo".');
|
|
466
|
-
if (a.provider === "gitlab" && !
|
|
488
|
+
if (a.provider === "gitlab" && !de(a.repository))
|
|
467
489
|
throw new Error('Invalid GitLab repository format. Use "group/project".');
|
|
468
|
-
return a.provider === "github" ? (await
|
|
490
|
+
return a.provider === "github" ? (await Be(a, t.trim(), e), !0) : a.provider === "gitlab" ? (await Pe(a, t.trim(), e), !0) : !1;
|
|
469
491
|
}
|
|
470
|
-
const
|
|
471
|
-
let D = !1,
|
|
472
|
-
function
|
|
492
|
+
const X = "facms-auth-modal", M = "facms-auth-missing", Z = "facms-token-modal", Q = "facms-language-modal", Ue = "frontend-auto-cms::theme", ue = "frontend-auto-cms::main-language", fe = "frontend-auto-cms::language-labels";
|
|
493
|
+
let D = !1, w = null, ee = !1, x = null, f = "dark", U = {};
|
|
494
|
+
function pe() {
|
|
473
495
|
if (document.getElementById("facms-dashboard-css"))
|
|
474
496
|
return;
|
|
475
497
|
const e = document.createElement("style");
|
|
@@ -708,24 +730,24 @@ function ue() {
|
|
|
708
730
|
}
|
|
709
731
|
`, document.head.appendChild(e);
|
|
710
732
|
}
|
|
711
|
-
function
|
|
733
|
+
function ge(e) {
|
|
712
734
|
f = e;
|
|
713
735
|
const t = e === "dark";
|
|
714
|
-
document.documentElement.classList.toggle("dark", t), document.body.classList.toggle("dark", t), document.documentElement.style.background = t ? "#020617" : "#f1f5f9", document.body.style.background = t ? "#020617" : "#f1f5f9", document.documentElement.setAttribute("data-facms-theme", e), document.getElementById("facms-app")?.classList.toggle("dark", t), localStorage.setItem(
|
|
736
|
+
document.documentElement.classList.toggle("dark", t), document.body.classList.toggle("dark", t), document.documentElement.style.background = t ? "#020617" : "#f1f5f9", document.body.style.background = t ? "#020617" : "#f1f5f9", document.documentElement.setAttribute("data-facms-theme", e), document.getElementById("facms-app")?.classList.toggle("dark", t), localStorage.setItem(Ue, e);
|
|
715
737
|
const o = document.getElementById("facms-theme-toggle");
|
|
716
738
|
o && (o.textContent = e === "dark" ? "Switch to light" : "Switch to dark");
|
|
717
739
|
}
|
|
718
|
-
function
|
|
719
|
-
f = "dark",
|
|
740
|
+
function be() {
|
|
741
|
+
f = "dark", ge("dark");
|
|
720
742
|
}
|
|
721
|
-
function
|
|
743
|
+
function Ge(e) {
|
|
722
744
|
return Array.from(new Uint8Array(e)).map((t) => t.toString(16).padStart(2, "0")).join("");
|
|
723
745
|
}
|
|
724
|
-
async function
|
|
746
|
+
async function He(e) {
|
|
725
747
|
const t = new TextEncoder().encode(e), a = await crypto.subtle.digest("SHA-256", t);
|
|
726
|
-
return
|
|
748
|
+
return Ge(a);
|
|
727
749
|
}
|
|
728
|
-
async function
|
|
750
|
+
async function me() {
|
|
729
751
|
if (x)
|
|
730
752
|
return x;
|
|
731
753
|
try {
|
|
@@ -734,7 +756,7 @@ async function ge() {
|
|
|
734
756
|
const t = await e.json();
|
|
735
757
|
return x = {
|
|
736
758
|
dashboardPath: t.dashboardPath || "/dashboard",
|
|
737
|
-
pages: (t.pages?.length ? t.pages : ["/"]).map((a) =>
|
|
759
|
+
pages: (t.pages?.length ? t.pages : ["/"]).map((a) => H(a)),
|
|
738
760
|
showFloatingButton: t.showFloatingButton ?? !1,
|
|
739
761
|
autoTranslateEnabled: t.autoTranslateEnabled ?? !0
|
|
740
762
|
}, x;
|
|
@@ -743,24 +765,24 @@ async function ge() {
|
|
|
743
765
|
}
|
|
744
766
|
return x = { dashboardPath: "/dashboard", pages: ["/"], showFloatingButton: !1, autoTranslateEnabled: !0 }, x;
|
|
745
767
|
}
|
|
746
|
-
async function
|
|
747
|
-
if (!
|
|
748
|
-
|
|
768
|
+
async function G() {
|
|
769
|
+
if (!ee) {
|
|
770
|
+
ee = !0;
|
|
749
771
|
try {
|
|
750
772
|
const e = await fetch("/cms-runtime-auth.json", { cache: "no-store" });
|
|
751
773
|
if (!e.ok) return;
|
|
752
774
|
const t = await e.json();
|
|
753
|
-
t.algorithm === "sha256" && typeof t.salt == "string" && typeof t.passcodeHash == "string" && (
|
|
775
|
+
t.algorithm === "sha256" && typeof t.salt == "string" && typeof t.passcodeHash == "string" && (w = { algorithm: "sha256", salt: t.salt, passcodeHash: t.passcodeHash });
|
|
754
776
|
} catch {
|
|
755
|
-
|
|
777
|
+
w = null;
|
|
756
778
|
}
|
|
757
779
|
}
|
|
758
780
|
}
|
|
759
|
-
async function
|
|
781
|
+
async function qe(e) {
|
|
760
782
|
const t = e.trim();
|
|
761
|
-
return !t || (await
|
|
783
|
+
return !t || (await G(), !w) ? !1 : await He(`${w.salt}:${t}`) === w.passcodeHash;
|
|
762
784
|
}
|
|
763
|
-
function
|
|
785
|
+
function Ke() {
|
|
764
786
|
let e = document.getElementById(M);
|
|
765
787
|
e || (e = document.createElement("div"), e.id = M, e.style.position = "fixed", e.style.inset = "0", e.style.zIndex = "2147483647", e.style.background = "rgba(2, 6, 23, 0.88)", e.style.display = "grid", e.style.placeItems = "center", e.innerHTML = `
|
|
766
788
|
<div style="width:min(560px,92vw);background:#0f172a;color:#e2e8f0;border:1px solid #334155;border-radius:16px;padding:16px;box-shadow:0 20px 55px rgba(2,6,23,.45);font-family:Inter,system-ui,sans-serif;">
|
|
@@ -770,20 +792,20 @@ function Ge() {
|
|
|
770
792
|
</div>
|
|
771
793
|
`, document.body.appendChild(e));
|
|
772
794
|
}
|
|
773
|
-
function
|
|
795
|
+
function Fe() {
|
|
774
796
|
document.getElementById(M)?.remove();
|
|
775
797
|
}
|
|
776
|
-
async function
|
|
777
|
-
return await
|
|
798
|
+
async function he() {
|
|
799
|
+
return await G(), w ? (Fe(), !0) : (Ke(), !1);
|
|
778
800
|
}
|
|
779
|
-
function
|
|
780
|
-
const t = document.getElementById(
|
|
801
|
+
function ye(e) {
|
|
802
|
+
const t = document.getElementById(X);
|
|
781
803
|
if (t) {
|
|
782
804
|
t.style.display = "grid";
|
|
783
805
|
return;
|
|
784
806
|
}
|
|
785
807
|
const a = document.createElement("div");
|
|
786
|
-
a.id =
|
|
808
|
+
a.id = X, a.style.position = "fixed", a.style.inset = "0", a.style.zIndex = "2147483647", a.style.background = "rgba(2, 6, 23, 0.45)", a.style.display = "grid", a.style.placeItems = "center", a.innerHTML = `
|
|
787
809
|
<div style="width: min(420px, 92vw); background: ${f === "dark" ? "#0f172a" : "#ffffff"}; color: ${f === "dark" ? "#e2e8f0" : "#0f172a"}; border: 1px solid ${f === "dark" ? "#334155" : "#e2e8f0"}; border-radius: 16px; padding: 16px; box-shadow: 0 20px 55px rgba(2,6,23,0.45); font-family: Inter, system-ui, sans-serif;">
|
|
788
810
|
<h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Unlock CMS</h3>
|
|
789
811
|
<p style="margin: 0 0 12px 0; font-size: 12px; color: ${f === "dark" ? "#94a3b8" : "#475569"};">Enter your passcode to edit content.</p>
|
|
@@ -796,11 +818,11 @@ function me(e) {
|
|
|
796
818
|
</div>
|
|
797
819
|
`;
|
|
798
820
|
const o = a.querySelector("#facms-passcode-input"), n = a.querySelector("#facms-passcode-error"), r = () => a.style.display = "none", s = async () => {
|
|
799
|
-
if (await
|
|
821
|
+
if (await G(), !w) {
|
|
800
822
|
n && (n.textContent = "CMS auth is not configured. Run setup to generate runtime auth files.", n.style.display = "block");
|
|
801
823
|
return;
|
|
802
824
|
}
|
|
803
|
-
if (!await
|
|
825
|
+
if (!await qe(o?.value ?? "")) {
|
|
804
826
|
n && (n.textContent = "Incorrect passcode.", n.style.display = "block");
|
|
805
827
|
return;
|
|
806
828
|
}
|
|
@@ -808,11 +830,11 @@ function me(e) {
|
|
|
808
830
|
};
|
|
809
831
|
a.querySelector("#facms-passcode-cancel")?.addEventListener("click", r), a.querySelector("#facms-passcode-submit")?.addEventListener("click", s), o?.addEventListener("keydown", (i) => i.key === "Enter" && void s()), document.body.appendChild(a), o?.focus();
|
|
810
832
|
}
|
|
811
|
-
function
|
|
812
|
-
const a = document.getElementById(
|
|
833
|
+
function Je(e, t) {
|
|
834
|
+
const a = document.getElementById(Z);
|
|
813
835
|
a && a.remove();
|
|
814
836
|
const o = document.createElement("div");
|
|
815
|
-
o.id =
|
|
837
|
+
o.id = Z, o.style.position = "fixed", o.style.inset = "0", o.style.zIndex = "2147483647", o.style.background = "rgba(2, 6, 23, 0.45)", o.style.display = "grid", o.style.placeItems = "center", o.innerHTML = `
|
|
816
838
|
<div style="width: min(520px, 92vw); background: ${f === "dark" ? "#0f172a" : "#ffffff"}; color: ${f === "dark" ? "#e2e8f0" : "#0f172a"}; border: 1px solid ${f === "dark" ? "#334155" : "#e2e8f0"}; border-radius: 16px; padding: 16px; box-shadow: 0 20px 55px rgba(2,6,23,0.45); font-family: Inter, system-ui, sans-serif;">
|
|
817
839
|
<h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Publish token required</h3>
|
|
818
840
|
<p style="margin: 0 0 12px 0; font-size: 12px; color: ${f === "dark" ? "#94a3b8" : "#475569"};">Enter your ${e} token for this publish only. It is not stored.</p>
|
|
@@ -834,17 +856,17 @@ function qe(e, t) {
|
|
|
834
856
|
};
|
|
835
857
|
o.querySelector("#facms-token-cancel")?.addEventListener("click", s), o.querySelector("#facms-token-submit")?.addEventListener("click", i), n?.addEventListener("keydown", (c) => c.key === "Enter" && i()), document.body.appendChild(o), n?.focus();
|
|
836
858
|
}
|
|
837
|
-
function
|
|
838
|
-
const o = document.getElementById(
|
|
859
|
+
function We(e, t, a) {
|
|
860
|
+
const o = document.getElementById(Q);
|
|
839
861
|
o && o.remove();
|
|
840
862
|
const n = document.createElement("div");
|
|
841
|
-
n.id =
|
|
863
|
+
n.id = Q, n.style.position = "fixed", n.style.inset = "0", n.style.zIndex = "2147483647", n.style.background = "rgba(2, 6, 23, 0.45)", n.style.display = "grid", n.style.placeItems = "center", n.innerHTML = `
|
|
842
864
|
<div style="width: min(520px, 92vw); background: ${f === "dark" ? "#0f172a" : "#ffffff"}; color: ${f === "dark" ? "#e2e8f0" : "#0f172a"}; border: 1px solid ${f === "dark" ? "#334155" : "#e2e8f0"}; border-radius: 16px; padding: 16px; box-shadow: 0 20px 55px rgba(2,6,23,0.45); font-family: Inter, system-ui, sans-serif;">
|
|
843
865
|
<h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Add translation</h3>
|
|
844
866
|
<p style="margin: 0 0 8px 0; font-size: 12px; color: ${f === "dark" ? "#94a3b8" : "#475569"};">Pick a supported language or define a custom one for manual translation.</p>
|
|
845
867
|
<select id="facms-language-select" style="width: 100%; border: 1px solid ${f === "dark" ? "#475569" : "#cbd5e1"}; background: ${f === "dark" ? "#1e293b" : "#ffffff"}; color: ${f === "dark" ? "#f1f5f9" : "#0f172a"}; border-radius: 10px; padding: 10px 12px; font-size: 14px; box-sizing: border-box; margin-bottom: 8px;">
|
|
846
868
|
<option value="">Select supported language</option>
|
|
847
|
-
${
|
|
869
|
+
${P.filter((d) => !e.includes(d.code)).map((d) => `<option value="${d.code}">${d.label} (${d.code})</option>`).join("")}
|
|
848
870
|
<option value="__custom__">Custom language (manual)</option>
|
|
849
871
|
</select>
|
|
850
872
|
<input id="facms-language-name" type="text" placeholder="Custom language name (e.g. Klingon)" style="width: 100%; border: 1px solid ${f === "dark" ? "#475569" : "#cbd5e1"}; background: ${f === "dark" ? "#1e293b" : "#ffffff"}; color: ${f === "dark" ? "#f1f5f9" : "#0f172a"}; border-radius: 10px; padding: 10px 12px; font-size: 14px; box-sizing: border-box; margin-bottom: 8px; display:none;" />
|
|
@@ -891,17 +913,17 @@ function z(e, t) {
|
|
|
891
913
|
function C(e) {
|
|
892
914
|
return e.trim().toLowerCase();
|
|
893
915
|
}
|
|
894
|
-
function
|
|
916
|
+
function H(e) {
|
|
895
917
|
const t = e.trim() || "/";
|
|
896
918
|
return t === "/" ? "/" : (t.startsWith("/") ? t : `/${t}`).toLowerCase();
|
|
897
919
|
}
|
|
898
920
|
function E(e) {
|
|
899
|
-
const t = C(e), a =
|
|
921
|
+
const t = C(e), a = P.find((o) => o.code === t);
|
|
900
922
|
return a ? a.label : t.toUpperCase();
|
|
901
923
|
}
|
|
902
|
-
function
|
|
924
|
+
function Ye() {
|
|
903
925
|
try {
|
|
904
|
-
const e = localStorage.getItem(
|
|
926
|
+
const e = localStorage.getItem(fe);
|
|
905
927
|
if (!e)
|
|
906
928
|
return {};
|
|
907
929
|
const t = JSON.parse(e);
|
|
@@ -910,15 +932,15 @@ function Fe() {
|
|
|
910
932
|
return {};
|
|
911
933
|
}
|
|
912
934
|
}
|
|
913
|
-
function
|
|
914
|
-
localStorage.setItem(
|
|
935
|
+
function q(e) {
|
|
936
|
+
localStorage.setItem(fe, JSON.stringify(e));
|
|
915
937
|
}
|
|
916
|
-
function
|
|
917
|
-
const t = localStorage.getItem(
|
|
938
|
+
function j(e) {
|
|
939
|
+
const t = localStorage.getItem(ue);
|
|
918
940
|
return t && e[t] ? t : e.en ? "en" : Object.keys(e)[0] ?? "en";
|
|
919
941
|
}
|
|
920
|
-
function
|
|
921
|
-
localStorage.setItem(
|
|
942
|
+
function te(e) {
|
|
943
|
+
localStorage.setItem(ue, e);
|
|
922
944
|
}
|
|
923
945
|
function h(e) {
|
|
924
946
|
return e.replace(/[&<>'"]/g, (t) => ({ "&": "&", "<": "<", ">": ">", "'": "'", '"': """ })[t]);
|
|
@@ -927,10 +949,10 @@ function T(e, t = 72) {
|
|
|
927
949
|
const a = e.replace(/\s+/g, " ").trim();
|
|
928
950
|
return a.length <= t ? a : `${a.slice(0, t)}...`;
|
|
929
951
|
}
|
|
930
|
-
function
|
|
952
|
+
function Ve(e) {
|
|
931
953
|
return e.type === "section" ? T((e.sectionItems ?? []).join(" | ")) : e.type === "property" ? T(JSON.stringify(e.attrs ?? {})) : T(e.value);
|
|
932
954
|
}
|
|
933
|
-
function
|
|
955
|
+
function Xe(e) {
|
|
934
956
|
const t = [];
|
|
935
957
|
return e.forEach((a, o) => {
|
|
936
958
|
const n = (a.selector ?? "").trim(), r = t[t.length - 1];
|
|
@@ -945,7 +967,7 @@ function We(e) {
|
|
|
945
967
|
});
|
|
946
968
|
}), t;
|
|
947
969
|
}
|
|
948
|
-
function
|
|
970
|
+
function Ze(e) {
|
|
949
971
|
const t = (a) => {
|
|
950
972
|
if (Array.isArray(a))
|
|
951
973
|
return a.map(t);
|
|
@@ -957,43 +979,56 @@ function Ye(e) {
|
|
|
957
979
|
};
|
|
958
980
|
return JSON.stringify(t(e));
|
|
959
981
|
}
|
|
960
|
-
async function
|
|
982
|
+
async function Qe(e) {
|
|
961
983
|
const t = new TextEncoder().encode(e), a = await crypto.subtle.digest("SHA-256", t);
|
|
962
984
|
return Array.from(new Uint8Array(a)).map((o) => o.toString(16).padStart(2, "0")).join("");
|
|
963
985
|
}
|
|
964
|
-
function
|
|
986
|
+
function et(e) {
|
|
965
987
|
const t = (e ?? "").trim();
|
|
966
988
|
if (!t)
|
|
967
989
|
return t;
|
|
968
990
|
if (t.startsWith("/")) {
|
|
969
|
-
const a =
|
|
970
|
-
return
|
|
991
|
+
const a = H(t);
|
|
992
|
+
return U[a] ?? t;
|
|
971
993
|
}
|
|
972
994
|
return t.replace(/^\.?\//, "");
|
|
973
995
|
}
|
|
974
|
-
async function
|
|
975
|
-
const o = e.nodes.flatMap(
|
|
976
|
-
(
|
|
977
|
-
file:
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
996
|
+
async function tt(e, t, a) {
|
|
997
|
+
const o = /* @__PURE__ */ new Set(), n = e.nodes.flatMap(
|
|
998
|
+
(i) => i.sourceRefs.map((c) => ({
|
|
999
|
+
file: (() => {
|
|
1000
|
+
const u = (c.file ?? "").trim();
|
|
1001
|
+
if (u.startsWith("/")) {
|
|
1002
|
+
const d = H(u);
|
|
1003
|
+
if (!U[d])
|
|
1004
|
+
return o.add(d), u;
|
|
1005
|
+
}
|
|
1006
|
+
return et(u);
|
|
1007
|
+
})(),
|
|
1008
|
+
find: c.original,
|
|
1009
|
+
replace: i.type === "property" ? JSON.stringify(i.attrs ?? {}) : i.type === "section" ? (i.sectionItems ?? []).join(" ") : (i.type === "text", i.value),
|
|
1010
|
+
occurrence: c.occurrence ?? 1
|
|
981
1011
|
}))
|
|
982
|
-
)
|
|
1012
|
+
);
|
|
1013
|
+
if (o.size)
|
|
1014
|
+
throw new Error(
|
|
1015
|
+
`Missing route mappings for: ${Array.from(o).join(", ")}. Run setup again and commit public/cms-route-map.json.`
|
|
1016
|
+
);
|
|
1017
|
+
const r = {
|
|
983
1018
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
984
1019
|
content: { ...e, updatedAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
985
|
-
operations:
|
|
1020
|
+
operations: n,
|
|
986
1021
|
locales: t
|
|
987
|
-
},
|
|
1022
|
+
}, s = await Qe(Ze(r));
|
|
988
1023
|
return {
|
|
989
|
-
...
|
|
1024
|
+
...r,
|
|
990
1025
|
integrity: {
|
|
991
1026
|
algorithm: "sha256",
|
|
992
|
-
value:
|
|
1027
|
+
value: s
|
|
993
1028
|
}
|
|
994
1029
|
};
|
|
995
1030
|
}
|
|
996
|
-
function
|
|
1031
|
+
function at(e, t) {
|
|
997
1032
|
const a = `${e.type.toUpperCase()} • ${h(e.label || e.selector || "")}`, o = `<div class="text-xs text-slate-500 dark:text-slate-400 mb-2">#${t + 1} ${a}</div>`;
|
|
998
1033
|
if (e.type === "text")
|
|
999
1034
|
return `<div class="rounded-lg p-2 bg-slate-50/60 dark:bg-slate-900/40">${o}<textarea data-cms-id="${e.id}" data-cms-field="value" class="w-full border border-slate-300 dark:border-slate-800 bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100 rounded-lg p-2 text-sm h-24 focus:outline-none focus:ring-2 focus:ring-indigo-500/40">${h(e.value)}</textarea></div>`;
|
|
@@ -1008,15 +1043,15 @@ function Qe(e, t) {
|
|
|
1008
1043
|
}
|
|
1009
1044
|
function _(e, t, a, o) {
|
|
1010
1045
|
e.nodes.forEach((n) => {
|
|
1011
|
-
n.type === "text" && (n.value = t[n.key] ?? o[n.key] ?? n.value,
|
|
1046
|
+
n.type === "text" && (n.value = t[n.key] ?? o[n.key] ?? n.value, B(n, a));
|
|
1012
1047
|
});
|
|
1013
1048
|
}
|
|
1014
|
-
function
|
|
1049
|
+
function nt(e, t) {
|
|
1015
1050
|
e.activeLanguage = t;
|
|
1016
1051
|
const a = e.locales[t] ?? e.locales[e.mainLanguage] ?? e.baseTextByKey;
|
|
1017
1052
|
_(e.content, a, e.workingDocument, e.baseTextByKey);
|
|
1018
1053
|
}
|
|
1019
|
-
function
|
|
1054
|
+
function ot(e, t) {
|
|
1020
1055
|
const a = e.querySelector("#facms-language-tabs");
|
|
1021
1056
|
if (!a)
|
|
1022
1057
|
return;
|
|
@@ -1031,13 +1066,13 @@ function tt(e, t) {
|
|
|
1031
1066
|
}).join(""), a.querySelectorAll("[data-lang]").forEach((n) => {
|
|
1032
1067
|
n.addEventListener("click", () => {
|
|
1033
1068
|
const r = n.dataset.lang;
|
|
1034
|
-
r && (
|
|
1069
|
+
r && (nt(t, r), L(e, t));
|
|
1035
1070
|
});
|
|
1036
1071
|
}), a.querySelectorAll("[data-main-lang]").forEach((n) => {
|
|
1037
1072
|
n.addEventListener("click", (r) => {
|
|
1038
1073
|
r.stopPropagation();
|
|
1039
1074
|
const s = n.dataset.mainLang;
|
|
1040
|
-
!s || !t.locales[s] || (t.mainLanguage = s,
|
|
1075
|
+
!s || !t.locales[s] || (t.mainLanguage = s, te(s), t.baseTextByKey = { ...t.locales[s] }, L(e, t));
|
|
1041
1076
|
});
|
|
1042
1077
|
}), a.querySelectorAll("[data-remove-lang]").forEach((n) => {
|
|
1043
1078
|
n.addEventListener("click", (r) => {
|
|
@@ -1048,12 +1083,12 @@ function tt(e, t) {
|
|
|
1048
1083
|
alert("You must keep at least one language.");
|
|
1049
1084
|
return;
|
|
1050
1085
|
}
|
|
1051
|
-
delete t.locales[s], delete t.languageLabels[s],
|
|
1086
|
+
delete t.locales[s], delete t.languageLabels[s], q(t.languageLabels), I(t.locales), t.mainLanguage === s && (t.mainLanguage = j(t.locales), te(t.mainLanguage), t.baseTextByKey = { ...t.locales[t.mainLanguage] ?? {} }), t.activeLanguage === s && (t.activeLanguage = K(t.locales, t.mainLanguage)), xe(t), L(e, t);
|
|
1052
1087
|
}
|
|
1053
1088
|
});
|
|
1054
1089
|
});
|
|
1055
1090
|
}
|
|
1056
|
-
function
|
|
1091
|
+
function rt(e, t) {
|
|
1057
1092
|
e.querySelectorAll("[data-cms-id]").forEach((a) => {
|
|
1058
1093
|
const o = a.dataset.cmsId, n = a.dataset.cmsField;
|
|
1059
1094
|
!o || !n || a.addEventListener("input", () => {
|
|
@@ -1073,12 +1108,12 @@ function at(e, t) {
|
|
|
1073
1108
|
} catch {
|
|
1074
1109
|
return;
|
|
1075
1110
|
}
|
|
1076
|
-
|
|
1111
|
+
B(r, t.workingDocument), re(t.content);
|
|
1077
1112
|
}
|
|
1078
1113
|
});
|
|
1079
1114
|
});
|
|
1080
1115
|
}
|
|
1081
|
-
function
|
|
1116
|
+
function k(e, t, a) {
|
|
1082
1117
|
const o = e.querySelector("#facms-i18n-status"), n = e.querySelector("#facms-translate-loader"), r = e.querySelector("#facms-add-language");
|
|
1083
1118
|
R(a, t), o && (o.textContent = t), n && (n.style.display = a ? "inline-flex" : "none"), r && (r.disabled = a);
|
|
1084
1119
|
}
|
|
@@ -1087,8 +1122,8 @@ function R(e, t) {
|
|
|
1087
1122
|
a && (a.style.display = e ? "flex" : "none"), o && (o.textContent = e ? t : "Loading");
|
|
1088
1123
|
}
|
|
1089
1124
|
function L(e, t) {
|
|
1090
|
-
const a =
|
|
1091
|
-
const r = n.items[0], s = n.items[n.items.length - 1], i = r.index === s.index ? `#${r.index + 1}` : `#${r.index + 1} - #${s.index + 1}`, c = n.items.map((l) =>
|
|
1125
|
+
const a = Xe(t.content.nodes), o = a.length ? a.map((n) => {
|
|
1126
|
+
const r = n.items[0], s = n.items[n.items.length - 1], i = r.index === s.index ? `#${r.index + 1}` : `#${r.index + 1} - #${s.index + 1}`, c = n.items.map((l) => Ve(l.node)).filter(Boolean).join(" • "), u = n.items.length > 1 ? `${i} ${h(n.selector || "Grouped fields")} (${n.items.length} fields)` : `${i} ${h(r.node.type.toUpperCase())} • ${h(r.node.label || r.node.selector || "")}`, d = n.items.map((l) => at(l.node, l.index)).join("");
|
|
1092
1127
|
return `
|
|
1093
1128
|
<details class="rounded-xl p-2 border border-slate-200 dark:border-transparent bg-white dark:bg-slate-900/60 shadow-sm">
|
|
1094
1129
|
<summary class="list-none cursor-pointer flex items-center justify-between gap-2 p-3 rounded-lg bg-slate-50 dark:bg-slate-800/70 border border-slate-200 dark:border-slate-800">
|
|
@@ -1120,17 +1155,24 @@ function L(e, t) {
|
|
|
1120
1155
|
<p id="facms-i18n-status" class="text-xs text-slate-500 dark:text-slate-400"></p>
|
|
1121
1156
|
</div>
|
|
1122
1157
|
</div>
|
|
1123
|
-
`,
|
|
1124
|
-
|
|
1158
|
+
`, ot(e, t), e.querySelector("#facms-save")?.addEventListener("click", async () => {
|
|
1159
|
+
let n, r;
|
|
1160
|
+
try {
|
|
1161
|
+
n = await tt(t.content, t.locales, t.baseTextByKey), r = await Ie();
|
|
1162
|
+
} catch (i) {
|
|
1163
|
+
const c = i instanceof Error ? i.message : String(i);
|
|
1164
|
+
alert(`Could not prepare publish payload: ${c}`);
|
|
1165
|
+
return;
|
|
1166
|
+
}
|
|
1125
1167
|
if (!r || r.provider === "none") {
|
|
1126
|
-
|
|
1168
|
+
$e(n), alert("Patch downloaded. Configure hosting in setup for one-click publish.");
|
|
1127
1169
|
return;
|
|
1128
1170
|
}
|
|
1129
1171
|
const s = r.provider;
|
|
1130
|
-
|
|
1172
|
+
Je(s, async (i) => {
|
|
1131
1173
|
let c = !1, u = "Publishing failed. Please verify token permissions and repository settings.";
|
|
1132
1174
|
try {
|
|
1133
|
-
c = await
|
|
1175
|
+
c = await De(n, i, r);
|
|
1134
1176
|
} catch (d) {
|
|
1135
1177
|
const l = d instanceof Error ? d.message : String(d);
|
|
1136
1178
|
l && (u = `Publishing failed: ${l}`), c = !1;
|
|
@@ -1142,7 +1184,7 @@ function L(e, t) {
|
|
|
1142
1184
|
alert("Changes published successfully.");
|
|
1143
1185
|
});
|
|
1144
1186
|
}), e.querySelector("#facms-add-language")?.addEventListener("click", () => {
|
|
1145
|
-
|
|
1187
|
+
We(Object.keys(t.locales), x?.autoTranslateEnabled ?? !0, async (n, r) => {
|
|
1146
1188
|
const [s, i] = n.split("::"), c = C(s ?? ""), u = (i ?? "").trim() || E(c);
|
|
1147
1189
|
if (!c)
|
|
1148
1190
|
return;
|
|
@@ -1153,69 +1195,69 @@ function L(e, t) {
|
|
|
1153
1195
|
sourceKeys: Object.keys(l).length,
|
|
1154
1196
|
browserLanguage: navigator.language,
|
|
1155
1197
|
browserLanguages: navigator.languages
|
|
1156
|
-
}), t.locales[c] = p, t.languageLabels[c] = u,
|
|
1157
|
-
r === "auto" && !(x?.autoTranslateEnabled ?? !0) &&
|
|
1198
|
+
}), t.locales[c] = p, t.languageLabels[c] = u, q(t.languageLabels), t.activeLanguage = c, I(t.locales), _(t.content, t.locales[c], t.workingDocument, t.baseTextByKey), L(e, t), z("Manual language tab created", { lang: c }), k(e, `Added ${u} tab prefilled with source text for manual translation.`, !1), r !== "auto" || !(x?.autoTranslateEnabled ?? !0)) {
|
|
1199
|
+
r === "auto" && !(x?.autoTranslateEnabled ?? !0) && k(e, `Privacy mode is on. Added ${u} tab for manual translation only.`, !1);
|
|
1158
1200
|
return;
|
|
1159
1201
|
}
|
|
1160
1202
|
try {
|
|
1161
1203
|
const g = Object.keys(l).length;
|
|
1162
|
-
|
|
1163
|
-
const y = await
|
|
1164
|
-
|
|
1204
|
+
k(e, `Auto-filling ${u} translation... (0/${g})`, !0);
|
|
1205
|
+
const y = await Ae(l, c, t.mainLanguage, (F, b) => {
|
|
1206
|
+
k(e, `Auto-filling ${u} translation... (${F}/${b})`, !0);
|
|
1165
1207
|
});
|
|
1166
1208
|
t.locales[c] = y, I(t.locales), t.activeLanguage = c, _(t.content, y, t.workingDocument, t.baseTextByKey), L(e, t), z("Automatic translation succeeded", {
|
|
1167
1209
|
lang: c,
|
|
1168
1210
|
translatedKeys: Object.keys(y).length,
|
|
1169
1211
|
ms: Math.round(performance.now() - d)
|
|
1170
|
-
}),
|
|
1212
|
+
}), k(e, `Added ${u} with auto-filled translation. Review and edit as needed.`, !1);
|
|
1171
1213
|
} catch (g) {
|
|
1172
1214
|
console.error("[frontend-auto-cms:dashboard] Automatic translation failed", {
|
|
1173
1215
|
lang: c,
|
|
1174
1216
|
message: g instanceof Error ? g.message : String(g),
|
|
1175
1217
|
stack: g instanceof Error ? g.stack : void 0,
|
|
1176
1218
|
ms: Math.round(performance.now() - d)
|
|
1177
|
-
}),
|
|
1219
|
+
}), k(e, `Auto-fill failed. ${u} stays prefilled with source text for manual editing.`, !1);
|
|
1178
1220
|
}
|
|
1179
1221
|
});
|
|
1180
|
-
}),
|
|
1222
|
+
}), rt(e, t);
|
|
1181
1223
|
}
|
|
1182
|
-
function
|
|
1183
|
-
const a = Object.keys(e), o = t && e[t] ? t :
|
|
1224
|
+
function K(e, t) {
|
|
1225
|
+
const a = Object.keys(e), o = t && e[t] ? t : j(e), n = [...navigator.languages ?? [], navigator.language].map((r) => r.toLowerCase().split("-")[0]);
|
|
1184
1226
|
for (const r of n)
|
|
1185
1227
|
if (a.includes(r))
|
|
1186
1228
|
return r;
|
|
1187
1229
|
return a.includes(o) ? o : a[0] ?? "en";
|
|
1188
1230
|
}
|
|
1189
|
-
function
|
|
1231
|
+
function xe(e) {
|
|
1190
1232
|
const t = e.locales[e.activeLanguage] ?? e.locales.en ?? e.baseTextByKey;
|
|
1191
1233
|
_(e.content, t, e.workingDocument, e.baseTextByKey);
|
|
1192
1234
|
}
|
|
1193
|
-
function
|
|
1235
|
+
function st(e) {
|
|
1194
1236
|
return new Promise((t) => window.setTimeout(t, e));
|
|
1195
1237
|
}
|
|
1196
|
-
async function
|
|
1238
|
+
async function ae(e, t) {
|
|
1197
1239
|
const a = [0, 120, 280, 600, 1100, 1800, 2600];
|
|
1198
1240
|
let o = S(e, t);
|
|
1199
1241
|
if (o.nodes.length > 0)
|
|
1200
1242
|
return o;
|
|
1201
1243
|
for (const n of a.slice(1))
|
|
1202
|
-
if (await
|
|
1244
|
+
if (await st(n), o = S(e, t), o.nodes.length > 0)
|
|
1203
1245
|
return o;
|
|
1204
1246
|
return o;
|
|
1205
1247
|
}
|
|
1206
|
-
function
|
|
1207
|
-
const o =
|
|
1248
|
+
function it(e, t, a) {
|
|
1249
|
+
const o = se(), n = {
|
|
1208
1250
|
...a,
|
|
1209
1251
|
...o
|
|
1210
|
-
}, r =
|
|
1252
|
+
}, r = Ye(), s = Object.fromEntries(e.nodes.filter((l) => l.type === "text").map((l) => [l.key, l.value])), i = j(n), c = {
|
|
1211
1253
|
...n,
|
|
1212
1254
|
[i]: { ...n[i] ?? {}, ...s }
|
|
1213
1255
|
};
|
|
1214
1256
|
!c.en && i === "en" && (c.en = Object.assign({}, c.en ?? {}, s));
|
|
1215
|
-
const u =
|
|
1257
|
+
const u = K(c, i), d = { ...r };
|
|
1216
1258
|
return Object.keys(c).forEach((l) => {
|
|
1217
1259
|
d[l] || (d[l] = E(l));
|
|
1218
|
-
}),
|
|
1260
|
+
}), q(d), {
|
|
1219
1261
|
content: e,
|
|
1220
1262
|
locales: c,
|
|
1221
1263
|
workingDocument: t,
|
|
@@ -1225,7 +1267,7 @@ function ot(e, t, a) {
|
|
|
1225
1267
|
languageLabels: d
|
|
1226
1268
|
};
|
|
1227
1269
|
}
|
|
1228
|
-
async function
|
|
1270
|
+
async function lt() {
|
|
1229
1271
|
const e = await ke();
|
|
1230
1272
|
if (!e?.nodes?.length)
|
|
1231
1273
|
return;
|
|
@@ -1235,18 +1277,18 @@ async function rt() {
|
|
|
1235
1277
|
const a = new Map(e.nodes.map((o) => [o.key, o]));
|
|
1236
1278
|
t.nodes.forEach((o) => {
|
|
1237
1279
|
const n = a.get(o.key);
|
|
1238
|
-
!n || n.type !== o.type || (o.value = n.value, n.attrs && (o.attrs = { ...n.attrs }), n.sectionItems && (o.sectionItems = [...n.sectionItems]),
|
|
1280
|
+
!n || n.type !== o.type || (o.value = n.value, n.attrs && (o.attrs = { ...n.attrs }), n.sectionItems && (o.sectionItems = [...n.sectionItems]), B(o, document));
|
|
1239
1281
|
});
|
|
1240
1282
|
}
|
|
1241
|
-
async function
|
|
1242
|
-
await
|
|
1283
|
+
async function ct() {
|
|
1284
|
+
await lt();
|
|
1243
1285
|
const t = {
|
|
1244
|
-
...await
|
|
1245
|
-
...
|
|
1286
|
+
...await ie(),
|
|
1287
|
+
...se()
|
|
1246
1288
|
};
|
|
1247
1289
|
if (!Object.keys(t).length)
|
|
1248
1290
|
return;
|
|
1249
|
-
const a =
|
|
1291
|
+
const a = j(t), o = K(t, a);
|
|
1250
1292
|
if (!o || o === a)
|
|
1251
1293
|
return;
|
|
1252
1294
|
const n = S(document, location.pathname), r = t[o];
|
|
@@ -1255,7 +1297,7 @@ async function st() {
|
|
|
1255
1297
|
const s = Object.fromEntries(n.nodes.filter((i) => i.type === "text").map((i) => [i.key, i.value]));
|
|
1256
1298
|
_(n, r, document, s);
|
|
1257
1299
|
}
|
|
1258
|
-
function
|
|
1300
|
+
function dt(e) {
|
|
1259
1301
|
const t = e.pages.length ? e.pages : ["/"];
|
|
1260
1302
|
document.documentElement.style.margin = "0", document.documentElement.style.padding = "0", document.documentElement.style.background = f === "dark" ? "#020617" : "#f1f5f9", document.body.style.margin = "0", document.body.style.padding = "0", document.body.style.background = f === "dark" ? "#020617" : "#f1f5f9", document.body.innerHTML = `
|
|
1261
1303
|
<div id="facms-app" class="h-screen w-screen grid grid-cols-1 lg:grid-cols-[760px_1fr] bg-slate-100 dark:bg-slate-950 text-slate-900 dark:text-slate-100">
|
|
@@ -1296,7 +1338,7 @@ function it(e) {
|
|
|
1296
1338
|
});
|
|
1297
1339
|
});
|
|
1298
1340
|
};
|
|
1299
|
-
|
|
1341
|
+
ge(f), a.addEventListener("load", async () => {
|
|
1300
1342
|
const u = a.contentDocument;
|
|
1301
1343
|
if (u) {
|
|
1302
1344
|
R(!0, `Scanning page content for ${s}...`);
|
|
@@ -1304,48 +1346,48 @@ function it(e) {
|
|
|
1304
1346
|
let d = r.get(s);
|
|
1305
1347
|
if (d) {
|
|
1306
1348
|
d.workingDocument = u;
|
|
1307
|
-
const l = d.content.nodes.length ? S(u, s) : await
|
|
1349
|
+
const l = d.content.nodes.length ? S(u, s) : await ae(u, s);
|
|
1308
1350
|
l.nodes.length && !d.content.nodes.length && (d.content = l);
|
|
1309
1351
|
} else {
|
|
1310
|
-
const l = await
|
|
1311
|
-
d =
|
|
1352
|
+
const l = await ae(u, s);
|
|
1353
|
+
d = it(l, u, i), r.set(s, d);
|
|
1312
1354
|
}
|
|
1313
|
-
|
|
1355
|
+
xe(d), re(d.content), L(o, d);
|
|
1314
1356
|
} finally {
|
|
1315
1357
|
R(!1, "Loading");
|
|
1316
1358
|
}
|
|
1317
1359
|
}
|
|
1318
|
-
}), c(), Promise.all([
|
|
1319
|
-
i = u,
|
|
1360
|
+
}), c(), Promise.all([ie(), Le()]).then(([u, d]) => {
|
|
1361
|
+
i = u, U = d, a.src = s;
|
|
1320
1362
|
});
|
|
1321
1363
|
}
|
|
1322
|
-
async function
|
|
1323
|
-
if (
|
|
1364
|
+
async function ne() {
|
|
1365
|
+
if (pe(), be(), !await he())
|
|
1324
1366
|
return;
|
|
1325
|
-
const e = await
|
|
1367
|
+
const e = await me(), t = () => dt(e);
|
|
1326
1368
|
if (!D) {
|
|
1327
|
-
|
|
1369
|
+
ye(t);
|
|
1328
1370
|
return;
|
|
1329
1371
|
}
|
|
1330
1372
|
t();
|
|
1331
1373
|
}
|
|
1332
|
-
async function
|
|
1333
|
-
const e = await
|
|
1374
|
+
async function ut() {
|
|
1375
|
+
const e = await me(), a = new URLSearchParams(location.search).get("__facms") === "1";
|
|
1334
1376
|
if (location.pathname !== e.dashboardPath && !a) {
|
|
1335
|
-
|
|
1377
|
+
ct();
|
|
1336
1378
|
return;
|
|
1337
1379
|
}
|
|
1338
|
-
if (
|
|
1380
|
+
if (pe(), be(), !!await he()) {
|
|
1339
1381
|
if (!D) {
|
|
1340
|
-
|
|
1341
|
-
|
|
1382
|
+
ye(() => {
|
|
1383
|
+
ne();
|
|
1342
1384
|
});
|
|
1343
1385
|
return;
|
|
1344
1386
|
}
|
|
1345
|
-
|
|
1387
|
+
ne();
|
|
1346
1388
|
}
|
|
1347
1389
|
}
|
|
1348
1390
|
export {
|
|
1349
|
-
|
|
1350
|
-
|
|
1391
|
+
ne as launchDashboard,
|
|
1392
|
+
ut as registerCmsLauncher
|
|
1351
1393
|
};
|