frontend-auto-cms 1.0.13 → 1.0.15

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.
@@ -1,17 +1,17 @@
1
- const xe = "cms-export.patch.json", ve = "frontend-auto-cms::content", ne = "frontend-auto-cms::locales";
1
+ const ve = "cms-export.patch.json", we = "frontend-auto-cms::content", re = "frontend-auto-cms::locales";
2
2
  function oe(e) {
3
- localStorage.setItem(ve, JSON.stringify(e));
3
+ localStorage.setItem(we, JSON.stringify(e));
4
4
  }
5
- function re() {
5
+ function se() {
6
6
  try {
7
- const e = localStorage.getItem(ne);
7
+ const e = localStorage.getItem(re);
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(ne, JSON.stringify(e));
14
+ localStorage.setItem(re, 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 se() {
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 se() {
35
35
  return {};
36
36
  }
37
37
  }
38
- async function we() {
38
+ async function $e() {
39
39
  try {
40
40
  const e = await fetch("/cms-route-map.json", { cache: "no-store" });
41
41
  if (!e.ok)
@@ -47,8 +47,8 @@ async function we() {
47
47
  }
48
48
  }
49
49
  function Le(e) {
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 = xe, o.click(), URL.revokeObjectURL(a);
50
+ const t = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), a = URL.createObjectURL(t), r = document.createElement("a");
51
+ r.href = a, r.download = ve, r.click(), URL.revokeObjectURL(a);
52
52
  }
53
53
  function A(e) {
54
54
  return e.replace(/[^\w]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
@@ -60,46 +60,46 @@ 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 ie(e) {
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 $e(e, t, a) {
70
- const o = t.parentElement;
71
- if (!o || ie(o))
69
+ function Se(e, t, a) {
70
+ const r = t.parentElement;
71
+ if (!r || le(r))
72
72
  return null;
73
- if (Array.from(o.childNodes).filter(
73
+ if (Array.from(r.childNodes).filter(
74
74
  (s) => s.nodeType === Node.TEXT_NODE && N(s.nodeValue).length > 0
75
- ).length === 1 && o.children.length === 0)
76
- return o.setAttribute("data-cms-key", a), o;
77
- const r = e.createElement("span");
78
- return r.textContent = t.nodeValue ?? "", r.setAttribute("data-cms-key", a), t.parentNode?.replaceChild(r, t), r;
75
+ ).length === 1 && r.children.length === 0)
76
+ return r.setAttribute("data-cms-key", a), r;
77
+ const o = e.createElement("span");
78
+ return o.textContent = t.nodeValue ?? "", o.setAttribute("data-cms-key", a), t.parentNode?.replaceChild(o, t), o;
79
79
  }
80
80
  function S(e = document, t) {
81
81
  const a = [];
82
- let o = 0, n = 0, r = 0, s = 0;
83
- const i = t ?? e.location?.pathname ?? location.pathname, c = e.body;
84
- if (!c)
82
+ let r = 0, n = 0, o = 0, s = 0;
83
+ const i = t ?? e.location?.pathname ?? location.pathname, l = e.body;
84
+ if (!l)
85
85
  return {
86
86
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
87
87
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
88
88
  nodes: a
89
89
  };
90
- const u = e.createTreeWalker(c, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
90
+ const u = e.createTreeWalker(l, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
91
91
  for (; u.nextNode(); ) {
92
92
  const d = u.currentNode;
93
93
  if (d.nodeType === Node.TEXT_NODE) {
94
94
  const b = d, m = N(b.nodeValue);
95
95
  if (m.length < 2)
96
96
  continue;
97
- o += 1;
98
- const J = `${A(i || "index")}.text.${o}`, O = $e(e, b, J);
97
+ r += 1;
98
+ const J = `${A(i || "index")}.text.${r}`, O = Se(e, b, J);
99
99
  if (!O)
100
100
  continue;
101
101
  a.push({
102
- id: `dom_txt_${o}`,
102
+ id: `dom_txt_${r}`,
103
103
  key: J,
104
104
  type: "text",
105
105
  label: v(O),
@@ -109,47 +109,47 @@ function S(e = document, t) {
109
109
  });
110
110
  continue;
111
111
  }
112
- const l = d;
113
- if (ie(l))
112
+ const c = d;
113
+ if (le(c))
114
114
  continue;
115
- const p = l.tagName.toLowerCase();
115
+ const p = c.tagName.toLowerCase();
116
116
  if (p === "img" || p === "video") {
117
- const b = l.getAttribute("src") ?? "";
117
+ const b = c.getAttribute("src") ?? "";
118
118
  if (b) {
119
119
  n += 1;
120
120
  const m = `${A(i || "index")}.${p}.${n}`;
121
- l.setAttribute("data-cms-key", m), a.push({
121
+ c.setAttribute("data-cms-key", m), a.push({
122
122
  id: `dom_media_${n}`,
123
123
  key: m,
124
124
  type: p === "img" ? "image" : "video",
125
- label: v(l),
125
+ label: v(c),
126
126
  value: b,
127
- selector: v(l),
128
- attrs: { src: b, alt: l.getAttribute("alt") ?? "" },
127
+ selector: v(c),
128
+ attrs: { src: b, alt: c.getAttribute("alt") ?? "" },
129
129
  sourceRefs: [{ file: i, original: b }]
130
130
  });
131
131
  }
132
132
  }
133
- if (["section", "ul", "ol"].includes(p) || l.hasAttribute("data-repeatable")) {
134
- const b = Array.from(l.children).map((m) => N(m.textContent)).filter(Boolean);
133
+ if (["section", "ul", "ol"].includes(p) || c.hasAttribute("data-repeatable")) {
134
+ const b = Array.from(c.children).map((m) => N(m.textContent)).filter(Boolean);
135
135
  if (b.length >= 2) {
136
- r += 1;
137
- const m = `${A(i || "index")}.section.${r}`;
138
- l.setAttribute("data-cms-key", m), a.push({
139
- id: `dom_sec_${r}`,
136
+ o += 1;
137
+ const m = `${A(i || "index")}.section.${o}`;
138
+ c.setAttribute("data-cms-key", m), a.push({
139
+ id: `dom_sec_${o}`,
140
140
  key: m,
141
141
  type: "section",
142
- label: v(l),
142
+ label: v(c),
143
143
  value: b.join(" | "),
144
- selector: v(l),
144
+ selector: v(c),
145
145
  sectionItems: b,
146
- sourceRefs: [{ file: i, original: l.innerHTML }]
146
+ sourceRefs: [{ file: i, original: c.innerHTML }]
147
147
  });
148
148
  }
149
149
  }
150
150
  const g = {};
151
151
  if (["alt", "href", "src", "aria-label", "title"].forEach((b) => {
152
- const m = l.getAttribute(b);
152
+ const m = c.getAttribute(b);
153
153
  m != null && m.trim() && (g[b] = m);
154
154
  }), Object.keys(g).length > 0 && !(p === "img" || p === "video")) {
155
155
  s += 1;
@@ -158,9 +158,9 @@ function S(e = document, t) {
158
158
  id: `dom_prop_${s}`,
159
159
  key: b,
160
160
  type: "property",
161
- label: v(l),
161
+ label: v(c),
162
162
  value: JSON.stringify(g),
163
- selector: v(l),
163
+ selector: v(c),
164
164
  attrs: g,
165
165
  sourceRefs: [{ file: i, original: JSON.stringify(g) }]
166
166
  });
@@ -172,7 +172,7 @@ function S(e = document, t) {
172
172
  nodes: a
173
173
  };
174
174
  }
175
- function P(e, t = document) {
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)}"]`);
@@ -182,16 +182,16 @@ function P(e, t = document) {
182
182
  else if (e.type === "image" || e.type === "video")
183
183
  a.src = e.value, e.attrs?.alt != null && a.setAttribute("alt", e.attrs.alt);
184
184
  else if (e.type === "property" && e.attrs)
185
- Object.entries(e.attrs).forEach(([o, n]) => a.setAttribute(o, n));
185
+ Object.entries(e.attrs).forEach(([r, n]) => a.setAttribute(r, n));
186
186
  else if (e.type === "section" && e.sectionItems) {
187
- const o = Array.from(a.children);
188
- e.sectionItems.forEach((n, r) => {
189
- o[r] && (o[r].textContent = n);
187
+ const r = Array.from(a.children);
188
+ e.sectionItems.forEach((n, o) => {
189
+ r[o] && (r[o].textContent = n);
190
190
  });
191
191
  }
192
192
  }
193
193
  }
194
- const B = [
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" },
@@ -257,8 +257,8 @@ const B = [
257
257
  { code: "vi", label: "Vietnamese", nllb: "vie_Latn" },
258
258
  { code: "zh", label: "Chinese (Simplified)", nllb: "zho_Hans" }
259
259
  ], W = Object.fromEntries(
260
- B.map((e) => [e.nllb.slice(0, 3).toLowerCase(), e.code])
261
- ), Se = "https://api.mymemory.translated.net/get";
260
+ P.map((e) => [e.nllb.slice(0, 3).toLowerCase(), e.code])
261
+ ), Ee = "https://api.mymemory.translated.net/get";
262
262
  function Y(e) {
263
263
  const t = e.trim().toLowerCase().split(/[-_]/)[0];
264
264
  if (/^[a-z]{2}$/i.test(t))
@@ -267,46 +267,46 @@ function Y(e) {
267
267
  return W[t];
268
268
  throw new Error(`Unsupported language code "${e}" for MyMemory translation.`);
269
269
  }
270
- async function Ee(e, t, a) {
270
+ async function _e(e, t, a) {
271
271
  if (!e.trim())
272
272
  return e;
273
- const o = new URLSearchParams({
273
+ const r = new URLSearchParams({
274
274
  q: e,
275
275
  langpair: `${t}|${a}`
276
- }), n = await fetch(`${Se}?${o.toString()}`, { method: "GET" });
276
+ }), n = await fetch(`${Ee}?${r.toString()}`, { method: "GET" });
277
277
  if (!n.ok)
278
278
  throw new Error(`MyMemory request failed (${n.status})`);
279
- const r = await n.json();
280
- if (r.responseStatus && r.responseStatus !== 200)
281
- throw new Error(`MyMemory translation failed with status ${r.responseStatus}`);
282
- const s = r.responseData?.translatedText;
279
+ const o = await n.json();
280
+ if (o.responseStatus && o.responseStatus !== 200)
281
+ throw new Error(`MyMemory translation failed with status ${o.responseStatus}`);
282
+ const s = o.responseData?.translatedText;
283
283
  return typeof s == "string" && s.trim() ? s : e;
284
284
  }
285
- async function _e(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;
285
+ async function Ae(e, t, a = "en", r) {
286
+ const n = Y(a), o = Y(t), s = /* @__PURE__ */ new Map(), i = {}, l = Object.entries(e), u = l.length;
287
287
  let d = 0;
288
- for (const [l, p] of c) {
288
+ for (const [c, p] of l) {
289
289
  if (s.has(p)) {
290
- i[l] = s.get(p), d += 1, o?.(d, u);
290
+ i[c] = s.get(p), d += 1, r?.(d, u);
291
291
  continue;
292
292
  }
293
293
  try {
294
- const g = await Ee(p, n, r);
295
- s.set(p, g), i[l] = g;
294
+ const g = await _e(p, n, o);
295
+ s.set(p, g), i[c] = g;
296
296
  } catch {
297
- i[l] = p;
297
+ i[c] = p;
298
298
  }
299
- d += 1, o?.(d, u);
299
+ d += 1, r?.(d, u);
300
300
  }
301
301
  return i;
302
302
  }
303
- function le(e) {
303
+ function ce(e) {
304
304
  return /^[^/\s]+\/[^/\s]+$/.test(e);
305
305
  }
306
- function ce(e) {
306
+ function de(e) {
307
307
  return /^([^/\s]+\/)+[^/\s]+$/.test(e);
308
308
  }
309
- async function Ae(e, t, a) {
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 Te() {
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,120 +324,175 @@ 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" && !le(a) || t.provider === "gitlab" && !ce(a) || typeof t.branch != "string" || !t.branch.trim() ? null : { ...t, repository: a, branch: t.branch.trim() };
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
  }
331
331
  }
332
- async function $(e, t, a, o, n) {
333
- const r = `https://api.github.com/repos/${e.repository}/contents/${encodeURIComponent(a).replace(/%2F/g, "/")}`;
332
+ async function L(e, t, a, r, n) {
333
+ const o = `https://api.github.com/repos/${e.repository}/contents/${encodeURIComponent(a).replace(/%2F/g, "/")}`;
334
334
  let s;
335
- const i = await fetch(`${r}?ref=${encodeURIComponent(e.branch)}`, {
335
+ const i = await fetch(`${o}?ref=${encodeURIComponent(e.branch)}`, {
336
336
  headers: { Authorization: `Bearer ${t}` }
337
337
  });
338
338
  i.ok && (s = (await i.json()).sha);
339
- const c = {
339
+ const l = {
340
340
  message: n,
341
- content: btoa(unescape(encodeURIComponent(o))),
341
+ content: btoa(unescape(encodeURIComponent(r))),
342
342
  branch: e.branch,
343
343
  sha: s
344
344
  };
345
- if (!(await fetch(r, {
345
+ if (!(await fetch(o, {
346
346
  method: "PUT",
347
347
  headers: {
348
348
  Authorization: `Bearer ${t}`,
349
349
  "Content-Type": "application/json"
350
350
  },
351
- body: JSON.stringify(c)
351
+ body: JSON.stringify(l)
352
352
  })).ok)
353
353
  throw new Error(`GitHub publish failed for ${a}`);
354
354
  }
355
- function Ie(e, t, a, o = 1) {
356
- if (!t || o < 1)
357
- return e;
358
- let n = -1, r = 0;
359
- for (let s = 0; s < o; s += 1) {
360
- if (n = e.indexOf(t, r), n < 0)
361
- return e;
362
- r = n + t.length;
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 r = await Ce(e, t);
371
+ if (!r)
372
+ throw new Error(`Configured branch "${a}" was not found and repo default branch could not be resolved.`);
373
+ if (!await V(e, t, r))
374
+ throw new Error(`Configured branch "${a}" was not found. Resolved default branch "${r}" is also unavailable.`);
375
+ return { ...e, branch: r };
376
+ }
377
+ function Oe(e) {
378
+ return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
379
+ }
380
+ function ze(e, t, a, r = 1) {
381
+ if (!t || r < 1)
382
+ return { content: e, replaced: !1 };
383
+ let n = -1, o = 0;
384
+ for (let s = 0; s < r; s += 1) {
385
+ if (n = e.indexOf(t, o), n < 0)
386
+ return { content: e, replaced: !1 };
387
+ o = n + t.length;
363
388
  }
364
- return `${e.slice(0, n)}${a}${e.slice(n + t.length)}`;
389
+ return {
390
+ content: `${e.slice(0, n)}${a}${e.slice(n + t.length)}`,
391
+ replaced: !0
392
+ };
365
393
  }
366
- function Ce(e) {
394
+ function Ne(e, t, a, r = 1) {
395
+ if (!t || r < 1)
396
+ return { content: e, replaced: !1 };
397
+ const n = t.trim().split(/\s+/).filter(Boolean);
398
+ if (!n.length)
399
+ return { content: e, replaced: !1 };
400
+ const o = n.map((u) => Oe(u)).join("\\s+"), s = new RegExp(o, "g");
401
+ let i = null, l = 0;
402
+ for (; (i = s.exec(e)) !== null; ) {
403
+ if (l += 1, l !== r)
404
+ continue;
405
+ const u = i.index, d = u + i[0].length;
406
+ return {
407
+ content: `${e.slice(0, u)}${a}${e.slice(d)}`,
408
+ replaced: !0
409
+ };
410
+ }
411
+ return { content: e, replaced: !1 };
412
+ }
413
+ function Me(e) {
367
414
  const t = (e ?? "").trim().replace(/\\/g, "/").replace(/^\/+/, "");
368
415
  return !t || t.includes("..") ? null : t;
369
416
  }
370
- function je(e) {
371
- const t = atob(e.replace(/\s+/g, "")), a = Uint8Array.from(t, (o) => o.charCodeAt(0));
417
+ function Re(e) {
418
+ const t = atob(e.replace(/\s+/g, "")), a = Uint8Array.from(t, (r) => r.charCodeAt(0));
372
419
  return new TextDecoder().decode(a);
373
420
  }
374
- async function Oe(e, t, a) {
375
- const o = `https://api.github.com/repos/${e.repository}/contents/${encodeURIComponent(a).replace(/%2F/g, "/")}`, n = await fetch(`${o}?ref=${encodeURIComponent(e.branch)}`, {
421
+ async function Be(e, t, a) {
422
+ const r = `https://api.github.com/repos/${e.repository}/contents/${encodeURIComponent(a).replace(/%2F/g, "/")}`, n = await fetch(`${r}?ref=${encodeURIComponent(e.branch)}`, {
376
423
  headers: { Authorization: `Bearer ${t}` }
377
424
  });
378
425
  if (!n.ok)
379
426
  return null;
380
- const r = await n.json();
381
- return !r.sha || !r.content || r.encoding !== "base64" ? null : {
382
- sha: r.sha,
383
- content: je(r.content)
427
+ const o = await n.json();
428
+ return !o.sha || !o.content || o.encoding !== "base64" ? null : {
429
+ sha: o.sha,
430
+ content: Re(o.content)
384
431
  };
385
432
  }
386
- async function ze(e, t, a, o) {
433
+ async function Pe(e, t, a, r) {
387
434
  const n = /* @__PURE__ */ new Map();
388
- let r = 0;
389
- a.forEach((i) => {
390
- i.find !== i.replace && (r += 1);
391
- const c = Ce(i.file);
392
- if (!c)
435
+ let o = 0;
436
+ a.forEach((l) => {
437
+ l.find !== l.replace && (o += 1);
438
+ const u = Me(l.file);
439
+ if (!u)
393
440
  return;
394
- const u = n.get(c) ?? [];
395
- u.push({ ...i, file: c }), n.set(c, u);
441
+ const d = n.get(u) ?? [];
442
+ d.push({ ...l, file: u }), n.set(u, d);
396
443
  });
397
- let s = 0;
398
- for (const [i, c] of n.entries()) {
399
- const u = await Oe(e, t, i);
400
- if (!u)
444
+ let s = 0, i = 0;
445
+ for (const [l, u] of n.entries()) {
446
+ const d = await Be(e, t, l);
447
+ if (!d)
401
448
  continue;
402
- let d = u.content;
403
- c.forEach((l) => {
404
- d = Ie(d, l.find, l.replace, l.occurrence ?? 1);
405
- }), d !== u.content && (await $(e, t, i, d, o), s += 1);
449
+ let c = d.content;
450
+ u.forEach((p) => {
451
+ if (!p.find || p.find === p.replace)
452
+ return;
453
+ const g = ze(c, p.find, p.replace, p.occurrence ?? 1);
454
+ if (g.replaced) {
455
+ c = g.content, i += 1;
456
+ return;
457
+ }
458
+ const h = Ne(c, p.find, p.replace, p.occurrence ?? 1);
459
+ h.replaced && (c = h.content, i += 1);
460
+ }), c !== d.content && (await L(e, t, l, c, r), s += 1);
406
461
  }
407
- return { updatedFiles: s, attemptedFiles: n.size, actionableOperations: r };
462
+ return { updatedFiles: s, attemptedFiles: n.size, actionableOperations: o, appliedOperations: i };
408
463
  }
409
- async function Ne(e, t, a) {
410
- const o = `chore(cms): publish content updates ${(/* @__PURE__ */ new Date()).toISOString()}`, n = await ze(e, t, a.operations ?? [], o);
411
- if (n.actionableOperations > 0 && n.updatedFiles === 0)
464
+ async function De(e, t, a) {
465
+ const r = await je(e, t), n = `chore(cms): publish content updates ${(/* @__PURE__ */ new Date()).toISOString()}`, o = await Pe(r, t, a.operations ?? [], n);
466
+ if (o.actionableOperations > 0 && o.appliedOperations === 0)
412
467
  throw new Error(
413
- `No source files were updated (${n.attemptedFiles} candidate files checked). Run setup again to refresh cms-route-map.json and retry.`
468
+ `No source files were updated (${o.attemptedFiles} candidate files checked). Run setup again to refresh cms-route-map.json and retry.`
414
469
  );
415
- if (await $(e, t, "cms-content.json", JSON.stringify(a.content, null, 2), o), a.locales) {
416
- for (const [r, s] of Object.entries(a.locales))
417
- await $(e, t, `locales/${r}.json`, JSON.stringify(s, null, 2), o);
418
- await $(
419
- e,
470
+ if (await L(r, t, "cms-content.json", JSON.stringify(a.content, null, 2), n), a.locales) {
471
+ for (const [s, i] of Object.entries(a.locales))
472
+ await L(r, t, `locales/${s}.json`, JSON.stringify(i, null, 2), n);
473
+ await L(
474
+ r,
420
475
  t,
421
476
  "cms-locales.json",
422
477
  JSON.stringify({ version: 1, locales: a.locales }, null, 2),
423
- o
478
+ n
424
479
  );
425
480
  }
426
- await $(e, t, "cms-export.patch.json", JSON.stringify(a, null, 2), o);
481
+ await L(r, t, "cms-export.patch.json", JSON.stringify(a, null, 2), n);
427
482
  }
428
- async function Me(e, t, a) {
429
- const o = [
483
+ async function Ue(e, t, a) {
484
+ const r = [
430
485
  { filePath: "cms-content.json", content: JSON.stringify(a.content, null, 2) },
431
486
  { filePath: "cms-export.patch.json", content: JSON.stringify(a, null, 2) }
432
487
  ];
433
488
  if (a.locales) {
434
489
  for (const [s, i] of Object.entries(a.locales))
435
- o.push({ filePath: `locales/${s}.json`, content: JSON.stringify(i, null, 2) });
436
- o.push({ filePath: "cms-locales.json", content: JSON.stringify({ version: 1, locales: a.locales }, null, 2) });
490
+ r.push({ filePath: `locales/${s}.json`, content: JSON.stringify(i, null, 2) });
491
+ r.push({ filePath: "cms-locales.json", content: JSON.stringify({ version: 1, locales: a.locales }, null, 2) });
437
492
  }
438
493
  const n = [];
439
- for (const s of o) {
440
- const i = await Ae(e, t, s.filePath);
494
+ for (const s of r) {
495
+ const i = await Te(e, t, s.filePath);
441
496
  n.push({
442
497
  action: i ? "update" : "create",
443
498
  file_path: s.filePath,
@@ -458,18 +513,18 @@ async function Me(e, t, a) {
458
513
  })).ok)
459
514
  throw new Error("GitLab publish failed.");
460
515
  }
461
- async function Re(e, t, a) {
516
+ async function Ge(e, t, a) {
462
517
  if (!a || !t.trim())
463
518
  return !1;
464
- if (a.provider === "github" && !le(a.repository))
519
+ if (a.provider === "github" && !ce(a.repository))
465
520
  throw new Error('Invalid GitHub repository format. Use "owner/repo".');
466
- if (a.provider === "gitlab" && !ce(a.repository))
521
+ if (a.provider === "gitlab" && !de(a.repository))
467
522
  throw new Error('Invalid GitLab repository format. Use "group/project".');
468
- return a.provider === "github" ? (await Ne(a, t.trim(), e), !0) : a.provider === "gitlab" ? (await Me(a, t.trim(), e), !0) : !1;
523
+ return a.provider === "github" ? (await De(a, t.trim(), e), !0) : a.provider === "gitlab" ? (await Ue(a, t.trim(), e), !0) : !1;
469
524
  }
470
- const V = "facms-auth-modal", M = "facms-auth-missing", X = "facms-token-modal", Z = "facms-language-modal", Pe = "frontend-auto-cms::theme", de = "frontend-auto-cms::main-language", ue = "frontend-auto-cms::language-labels";
471
- let D = !1, k = null, Q = !1, x = null, f = "dark", U = {};
472
- function fe() {
525
+ const X = "facms-auth-modal", M = "facms-auth-missing", Z = "facms-token-modal", Q = "facms-language-modal", He = "frontend-auto-cms::theme", ue = "frontend-auto-cms::main-language", fe = "frontend-auto-cms::language-labels";
526
+ let D = !1, w = null, ee = !1, x = null, f = "dark", U = {};
527
+ function pe() {
473
528
  if (document.getElementById("facms-dashboard-css"))
474
529
  return;
475
530
  const e = document.createElement("style");
@@ -708,24 +763,24 @@ function fe() {
708
763
  }
709
764
  `, document.head.appendChild(e);
710
765
  }
711
- function pe(e) {
766
+ function ge(e) {
712
767
  f = e;
713
768
  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(Pe, e);
715
- const o = document.getElementById("facms-theme-toggle");
716
- o && (o.textContent = e === "dark" ? "Switch to light" : "Switch to dark");
769
+ 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(He, e);
770
+ const r = document.getElementById("facms-theme-toggle");
771
+ r && (r.textContent = e === "dark" ? "Switch to light" : "Switch to dark");
717
772
  }
718
- function ge() {
719
- f = "dark", pe("dark");
773
+ function be() {
774
+ f = "dark", ge("dark");
720
775
  }
721
- function Be(e) {
776
+ function qe(e) {
722
777
  return Array.from(new Uint8Array(e)).map((t) => t.toString(16).padStart(2, "0")).join("");
723
778
  }
724
- async function De(e) {
779
+ async function Ke(e) {
725
780
  const t = new TextEncoder().encode(e), a = await crypto.subtle.digest("SHA-256", t);
726
- return Be(a);
781
+ return qe(a);
727
782
  }
728
- async function be() {
783
+ async function me() {
729
784
  if (x)
730
785
  return x;
731
786
  try {
@@ -744,23 +799,23 @@ async function be() {
744
799
  return x = { dashboardPath: "/dashboard", pages: ["/"], showFloatingButton: !1, autoTranslateEnabled: !0 }, x;
745
800
  }
746
801
  async function G() {
747
- if (!Q) {
748
- Q = !0;
802
+ if (!ee) {
803
+ ee = !0;
749
804
  try {
750
805
  const e = await fetch("/cms-runtime-auth.json", { cache: "no-store" });
751
806
  if (!e.ok) return;
752
807
  const t = await e.json();
753
- t.algorithm === "sha256" && typeof t.salt == "string" && typeof t.passcodeHash == "string" && (k = { algorithm: "sha256", salt: t.salt, passcodeHash: t.passcodeHash });
808
+ t.algorithm === "sha256" && typeof t.salt == "string" && typeof t.passcodeHash == "string" && (w = { algorithm: "sha256", salt: t.salt, passcodeHash: t.passcodeHash });
754
809
  } catch {
755
- k = null;
810
+ w = null;
756
811
  }
757
812
  }
758
813
  }
759
- async function Ue(e) {
814
+ async function Fe(e) {
760
815
  const t = e.trim();
761
- return !t || (await G(), !k) ? !1 : await De(`${k.salt}:${t}`) === k.passcodeHash;
816
+ return !t || (await G(), !w) ? !1 : await Ke(`${w.salt}:${t}`) === w.passcodeHash;
762
817
  }
763
- function Ge() {
818
+ function Je() {
764
819
  let e = document.getElementById(M);
765
820
  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
821
  <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 +825,20 @@ function Ge() {
770
825
  </div>
771
826
  `, document.body.appendChild(e));
772
827
  }
773
- function He() {
828
+ function We() {
774
829
  document.getElementById(M)?.remove();
775
830
  }
776
- async function me() {
777
- return await G(), k ? (He(), !0) : (Ge(), !1);
831
+ async function he() {
832
+ return await G(), w ? (We(), !0) : (Je(), !1);
778
833
  }
779
- function he(e) {
780
- const t = document.getElementById(V);
834
+ function ye(e) {
835
+ const t = document.getElementById(X);
781
836
  if (t) {
782
837
  t.style.display = "grid";
783
838
  return;
784
839
  }
785
840
  const a = document.createElement("div");
786
- a.id = V, 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 = `
841
+ 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
842
  <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
843
  <h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Unlock CMS</h3>
789
844
  <p style="margin: 0 0 12px 0; font-size: 12px; color: ${f === "dark" ? "#94a3b8" : "#475569"};">Enter your passcode to edit content.</p>
@@ -795,24 +850,24 @@ function he(e) {
795
850
  </div>
796
851
  </div>
797
852
  `;
798
- const o = a.querySelector("#facms-passcode-input"), n = a.querySelector("#facms-passcode-error"), r = () => a.style.display = "none", s = async () => {
799
- if (await G(), !k) {
853
+ const r = a.querySelector("#facms-passcode-input"), n = a.querySelector("#facms-passcode-error"), o = () => a.style.display = "none", s = async () => {
854
+ if (await G(), !w) {
800
855
  n && (n.textContent = "CMS auth is not configured. Run setup to generate runtime auth files.", n.style.display = "block");
801
856
  return;
802
857
  }
803
- if (!await Ue(o?.value ?? "")) {
858
+ if (!await Fe(r?.value ?? "")) {
804
859
  n && (n.textContent = "Incorrect passcode.", n.style.display = "block");
805
860
  return;
806
861
  }
807
- n && (n.style.display = "none"), D = !0, r(), e();
862
+ n && (n.style.display = "none"), D = !0, o(), e();
808
863
  };
809
- 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();
864
+ a.querySelector("#facms-passcode-cancel")?.addEventListener("click", o), a.querySelector("#facms-passcode-submit")?.addEventListener("click", s), r?.addEventListener("keydown", (i) => i.key === "Enter" && void s()), document.body.appendChild(a), r?.focus();
810
865
  }
811
- function qe(e, t) {
812
- const a = document.getElementById(X);
866
+ function Ye(e, t) {
867
+ const a = document.getElementById(Z);
813
868
  a && a.remove();
814
- const o = document.createElement("div");
815
- o.id = X, 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 = `
869
+ const r = document.createElement("div");
870
+ r.id = Z, r.style.position = "fixed", r.style.inset = "0", r.style.zIndex = "2147483647", r.style.background = "rgba(2, 6, 23, 0.45)", r.style.display = "grid", r.style.placeItems = "center", r.innerHTML = `
816
871
  <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
872
  <h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Publish token required</h3>
818
873
  <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>
@@ -824,27 +879,27 @@ function qe(e, t) {
824
879
  </div>
825
880
  </div>
826
881
  `;
827
- const n = o.querySelector("#facms-token-input"), r = o.querySelector("#facms-token-error"), s = () => o.style.display = "none", i = () => {
828
- const c = (n?.value ?? "").trim();
829
- if (!c) {
830
- r && (r.style.display = "block");
882
+ const n = r.querySelector("#facms-token-input"), o = r.querySelector("#facms-token-error"), s = () => r.style.display = "none", i = () => {
883
+ const l = (n?.value ?? "").trim();
884
+ if (!l) {
885
+ o && (o.style.display = "block");
831
886
  return;
832
887
  }
833
- r && (r.style.display = "none"), s(), t(c);
888
+ o && (o.style.display = "none"), s(), t(l);
834
889
  };
835
- 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();
890
+ r.querySelector("#facms-token-cancel")?.addEventListener("click", s), r.querySelector("#facms-token-submit")?.addEventListener("click", i), n?.addEventListener("keydown", (l) => l.key === "Enter" && i()), document.body.appendChild(r), n?.focus();
836
891
  }
837
- function Ke(e, t, a) {
838
- const o = document.getElementById(Z);
839
- o && o.remove();
892
+ function Ve(e, t, a) {
893
+ const r = document.getElementById(Q);
894
+ r && r.remove();
840
895
  const n = document.createElement("div");
841
- n.id = Z, 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 = `
896
+ 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
897
  <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
898
  <h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Add translation</h3>
844
899
  <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
900
  <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
901
  <option value="">Select supported language</option>
847
- ${B.filter((d) => !e.includes(d.code)).map((d) => `<option value="${d.code}">${d.label} (${d.code})</option>`).join("")}
902
+ ${P.filter((d) => !e.includes(d.code)).map((d) => `<option value="${d.code}">${d.label} (${d.code})</option>`).join("")}
848
903
  <option value="__custom__">Custom language (manual)</option>
849
904
  </select>
850
905
  <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;" />
@@ -857,27 +912,27 @@ function Ke(e, t, a) {
857
912
  </div>
858
913
  </div>
859
914
  `;
860
- const r = () => n.style.display = "none";
861
- n.querySelector("#facms-language-cancel")?.addEventListener("click", r);
862
- const s = n.querySelector("#facms-language-select"), i = n.querySelector("#facms-language-input"), c = n.querySelector("#facms-language-name");
915
+ const o = () => n.style.display = "none";
916
+ n.querySelector("#facms-language-cancel")?.addEventListener("click", o);
917
+ const s = n.querySelector("#facms-language-select"), i = n.querySelector("#facms-language-input"), l = n.querySelector("#facms-language-name");
863
918
  s?.addEventListener("change", () => {
864
919
  const d = s.value === "__custom__";
865
- i && (i.style.display = d ? "block" : "none"), c && (c.style.display = d ? "block" : "none");
920
+ i && (i.style.display = d ? "block" : "none"), l && (l.style.display = d ? "block" : "none");
866
921
  });
867
922
  const u = (d) => {
868
- const l = n.querySelector("#facms-language-error");
923
+ const c = n.querySelector("#facms-language-error");
869
924
  let p = "";
870
925
  const g = s?.value ?? "";
871
- let y = "";
872
- if (g && g !== "__custom__" ? (p = C(g), y = E(p)) : (p = C(i?.value ?? ""), y = (c?.value ?? "").trim()), !p || !/^[a-z]{2,3}([_-][a-z0-9]{2,8})?$|^[a-z]{3}_[A-Za-z]+$/i.test(p)) {
873
- l && (l.textContent = "Enter a valid language code.", l.style.display = "block");
926
+ let h = "";
927
+ if (g && g !== "__custom__" ? (p = C(g), h = E(p)) : (p = C(i?.value ?? ""), h = (l?.value ?? "").trim()), !p || !/^[a-z]{2,3}([_-][a-z0-9]{2,8})?$|^[a-z]{3}_[A-Za-z]+$/i.test(p)) {
928
+ c && (c.textContent = "Enter a valid language code.", c.style.display = "block");
874
929
  return;
875
930
  }
876
- if (y || (y = E(p)), e.includes(p)) {
877
- l && (l.textContent = `Language "${p}" already exists.`, l.style.display = "block");
931
+ if (h || (h = E(p)), e.includes(p)) {
932
+ c && (c.textContent = `Language "${p}" already exists.`, c.style.display = "block");
878
933
  return;
879
934
  }
880
- l && (l.style.display = "none"), r(), a(`${p}::${y}`, d);
935
+ c && (c.style.display = "none"), o(), a(`${p}::${h}`, d);
881
936
  };
882
937
  n.querySelector("#facms-language-manual")?.addEventListener("click", () => u("manual")), t && n.querySelector("#facms-language-autofill")?.addEventListener("click", () => u("auto")), document.body.appendChild(n);
883
938
  }
@@ -896,12 +951,12 @@ function H(e) {
896
951
  return t === "/" ? "/" : (t.startsWith("/") ? t : `/${t}`).toLowerCase();
897
952
  }
898
953
  function E(e) {
899
- const t = C(e), a = B.find((o) => o.code === t);
954
+ const t = C(e), a = P.find((r) => r.code === t);
900
955
  return a ? a.label : t.toUpperCase();
901
956
  }
902
- function Fe() {
957
+ function Xe() {
903
958
  try {
904
- const e = localStorage.getItem(ue);
959
+ const e = localStorage.getItem(fe);
905
960
  if (!e)
906
961
  return {};
907
962
  const t = JSON.parse(e);
@@ -911,57 +966,57 @@ function Fe() {
911
966
  }
912
967
  }
913
968
  function q(e) {
914
- localStorage.setItem(ue, JSON.stringify(e));
969
+ localStorage.setItem(fe, JSON.stringify(e));
915
970
  }
916
971
  function j(e) {
917
- const t = localStorage.getItem(de);
972
+ const t = localStorage.getItem(ue);
918
973
  return t && e[t] ? t : e.en ? "en" : Object.keys(e)[0] ?? "en";
919
974
  }
920
- function ee(e) {
921
- localStorage.setItem(de, e);
975
+ function te(e) {
976
+ localStorage.setItem(ue, e);
922
977
  }
923
- function h(e) {
978
+ function y(e) {
924
979
  return e.replace(/[&<>'"]/g, (t) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", "'": "&#39;", '"': "&quot;" })[t]);
925
980
  }
926
981
  function T(e, t = 72) {
927
982
  const a = e.replace(/\s+/g, " ").trim();
928
983
  return a.length <= t ? a : `${a.slice(0, t)}...`;
929
984
  }
930
- function Je(e) {
985
+ function Ze(e) {
931
986
  return e.type === "section" ? T((e.sectionItems ?? []).join(" | ")) : e.type === "property" ? T(JSON.stringify(e.attrs ?? {})) : T(e.value);
932
987
  }
933
- function We(e) {
988
+ function Qe(e) {
934
989
  const t = [];
935
- return e.forEach((a, o) => {
936
- const n = (a.selector ?? "").trim(), r = t[t.length - 1];
937
- if (!!(r && n && r.selector === n) && r) {
938
- r.items.push({ node: a, index: o });
990
+ return e.forEach((a, r) => {
991
+ const n = (a.selector ?? "").trim(), o = t[t.length - 1];
992
+ if (!!(o && n && o.selector === n) && o) {
993
+ o.items.push({ node: a, index: r });
939
994
  return;
940
995
  }
941
996
  t.push({
942
- key: n || `group_${o}`,
997
+ key: n || `group_${r}`,
943
998
  selector: n,
944
- items: [{ node: a, index: o }]
999
+ items: [{ node: a, index: r }]
945
1000
  });
946
1001
  }), t;
947
1002
  }
948
- function Ye(e) {
1003
+ function et(e) {
949
1004
  const t = (a) => {
950
1005
  if (Array.isArray(a))
951
1006
  return a.map(t);
952
1007
  if (a && typeof a == "object") {
953
- const o = Object.entries(a).sort(([n], [r]) => n.localeCompare(r));
954
- return Object.fromEntries(o.map(([n, r]) => [n, t(r)]));
1008
+ const r = Object.entries(a).sort(([n], [o]) => n.localeCompare(o));
1009
+ return Object.fromEntries(r.map(([n, o]) => [n, t(o)]));
955
1010
  }
956
1011
  return a;
957
1012
  };
958
1013
  return JSON.stringify(t(e));
959
1014
  }
960
- async function Ve(e) {
1015
+ async function tt(e) {
961
1016
  const t = new TextEncoder().encode(e), a = await crypto.subtle.digest("SHA-256", t);
962
- return Array.from(new Uint8Array(a)).map((o) => o.toString(16).padStart(2, "0")).join("");
1017
+ return Array.from(new Uint8Array(a)).map((r) => r.toString(16).padStart(2, "0")).join("");
963
1018
  }
964
- function Xe(e) {
1019
+ function at(e) {
965
1020
  const t = (e ?? "").trim();
966
1021
  if (!t)
967
1022
  return t;
@@ -971,143 +1026,143 @@ function Xe(e) {
971
1026
  }
972
1027
  return t.replace(/^\.?\//, "");
973
1028
  }
974
- async function Ze(e, t, a) {
975
- const o = /* @__PURE__ */ new Set(), n = e.nodes.flatMap(
976
- (i) => i.sourceRefs.map((c) => ({
1029
+ async function nt(e, t, a) {
1030
+ const r = /* @__PURE__ */ new Set(), n = e.nodes.flatMap(
1031
+ (i) => i.sourceRefs.map((l) => ({
977
1032
  file: (() => {
978
- const u = (c.file ?? "").trim();
1033
+ const u = (l.file ?? "").trim();
979
1034
  if (u.startsWith("/")) {
980
1035
  const d = H(u);
981
1036
  if (!U[d])
982
- return o.add(d), u;
1037
+ return r.add(d), u;
983
1038
  }
984
- return Xe(u);
1039
+ return at(u);
985
1040
  })(),
986
- find: c.original,
1041
+ find: l.original,
987
1042
  replace: i.type === "property" ? JSON.stringify(i.attrs ?? {}) : i.type === "section" ? (i.sectionItems ?? []).join(" ") : (i.type === "text", i.value),
988
- occurrence: c.occurrence ?? 1
1043
+ occurrence: l.occurrence ?? 1
989
1044
  }))
990
1045
  );
991
- if (o.size)
1046
+ if (r.size)
992
1047
  throw new Error(
993
- `Missing route mappings for: ${Array.from(o).join(", ")}. Run setup again and commit public/cms-route-map.json.`
1048
+ `Missing route mappings for: ${Array.from(r).join(", ")}. Run setup again and commit public/cms-route-map.json.`
994
1049
  );
995
- const r = {
1050
+ const o = {
996
1051
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
997
1052
  content: { ...e, updatedAt: (/* @__PURE__ */ new Date()).toISOString() },
998
1053
  operations: n,
999
1054
  locales: t
1000
- }, s = await Ve(Ye(r));
1055
+ }, s = await tt(et(o));
1001
1056
  return {
1002
- ...r,
1057
+ ...o,
1003
1058
  integrity: {
1004
1059
  algorithm: "sha256",
1005
1060
  value: s
1006
1061
  }
1007
1062
  };
1008
1063
  }
1009
- function Qe(e, t) {
1010
- 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>`;
1064
+ function rt(e, t) {
1065
+ const a = `${e.type.toUpperCase()} • ${y(e.label || e.selector || "")}`, r = `<div class="text-xs text-slate-500 dark:text-slate-400 mb-2">#${t + 1} ${a}</div>`;
1011
1066
  if (e.type === "text")
1012
- 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>`;
1067
+ return `<div class="rounded-lg p-2 bg-slate-50/60 dark:bg-slate-900/40">${r}<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">${y(e.value)}</textarea></div>`;
1013
1068
  if (e.type === "image" || e.type === "video")
1014
- return `<div class="rounded-lg p-2 bg-slate-50/60 dark:bg-slate-900/40">${o}<label class="text-xs text-slate-500 dark:text-slate-400">Source URL</label><input data-cms-id="${e.id}" data-cms-field="value" value="${h(e.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 mb-2 focus:outline-none focus:ring-2 focus:ring-indigo-500/40" /><label class="text-xs text-slate-500 dark:text-slate-400">Alt text</label><input data-cms-id="${e.id}" data-cms-field="alt" value="${h(e.attrs?.alt ?? "")}" 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 focus:outline-none focus:ring-2 focus:ring-indigo-500/40" /></div>`;
1069
+ return `<div class="rounded-lg p-2 bg-slate-50/60 dark:bg-slate-900/40">${r}<label class="text-xs text-slate-500 dark:text-slate-400">Source URL</label><input data-cms-id="${e.id}" data-cms-field="value" value="${y(e.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 mb-2 focus:outline-none focus:ring-2 focus:ring-indigo-500/40" /><label class="text-xs text-slate-500 dark:text-slate-400">Alt text</label><input data-cms-id="${e.id}" data-cms-field="alt" value="${y(e.attrs?.alt ?? "")}" 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 focus:outline-none focus:ring-2 focus:ring-indigo-500/40" /></div>`;
1015
1070
  if (e.type === "section") {
1016
1071
  const n = (e.sectionItems ?? []).join(`
1017
1072
  `);
1018
- 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="sectionItems" 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-28 focus:outline-none focus:ring-2 focus:ring-indigo-500/40">${h(n)}</textarea></div>`;
1073
+ return `<div class="rounded-lg p-2 bg-slate-50/60 dark:bg-slate-900/40">${r}<textarea data-cms-id="${e.id}" data-cms-field="sectionItems" 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-28 focus:outline-none focus:ring-2 focus:ring-indigo-500/40">${y(n)}</textarea></div>`;
1019
1074
  }
1020
- 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="attrs" 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-xs h-28 focus:outline-none focus:ring-2 focus:ring-indigo-500/40">${h(JSON.stringify(e.attrs ?? {}, null, 2))}</textarea></div>`;
1075
+ return `<div class="rounded-lg p-2 bg-slate-50/60 dark:bg-slate-900/40">${r}<textarea data-cms-id="${e.id}" data-cms-field="attrs" 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-xs h-28 focus:outline-none focus:ring-2 focus:ring-indigo-500/40">${y(JSON.stringify(e.attrs ?? {}, null, 2))}</textarea></div>`;
1021
1076
  }
1022
- function _(e, t, a, o) {
1077
+ function _(e, t, a, r) {
1023
1078
  e.nodes.forEach((n) => {
1024
- n.type === "text" && (n.value = t[n.key] ?? o[n.key] ?? n.value, P(n, a));
1079
+ n.type === "text" && (n.value = t[n.key] ?? r[n.key] ?? n.value, B(n, a));
1025
1080
  });
1026
1081
  }
1027
- function et(e, t) {
1082
+ function ot(e, t) {
1028
1083
  e.activeLanguage = t;
1029
1084
  const a = e.locales[t] ?? e.locales[e.mainLanguage] ?? e.baseTextByKey;
1030
1085
  _(e.content, a, e.workingDocument, e.baseTextByKey);
1031
1086
  }
1032
- function tt(e, t) {
1087
+ function st(e, t) {
1033
1088
  const a = e.querySelector("#facms-language-tabs");
1034
1089
  if (!a)
1035
1090
  return;
1036
- const o = Object.keys(t.locales);
1037
- a.innerHTML = o.map((n) => {
1038
- const r = n === t.activeLanguage, s = n === t.mainLanguage, i = t.languageLabels[n] ?? E(n);
1039
- return `<div class="inline-flex items-center rounded-lg overflow-hidden border ${r ? "border-indigo-500" : "border-slate-200 dark:border-slate-700"}">
1040
- <button data-lang="${n}" class="px-2.5 py-1.5 text-xs ${r ? "bg-indigo-600 text-white" : "bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-200"}">${h(i)}</button>
1041
- ${s ? `<span class="px-2 py-1.5 text-[10px] font-semibold ${r ? "bg-indigo-700 text-indigo-100" : "bg-emerald-600 text-white"}">MAIN</span>` : `<button data-main-lang="${n}" title="Set as main language" class="px-2 py-1.5 text-xs ${r ? "bg-indigo-700 text-indigo-100 hover:bg-indigo-800" : "bg-emerald-600 text-white hover:bg-emerald-500"}">★</button>`}
1042
- <button data-remove-lang="${n}" title="Remove language" class="px-2 py-1.5 text-xs ${r ? "bg-indigo-700 text-indigo-100 hover:bg-indigo-800" : "bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-200 hover:bg-slate-300 dark:hover:bg-slate-600"}">×</button>
1091
+ const r = Object.keys(t.locales);
1092
+ a.innerHTML = r.map((n) => {
1093
+ const o = n === t.activeLanguage, s = n === t.mainLanguage, i = t.languageLabels[n] ?? E(n);
1094
+ return `<div class="inline-flex items-center rounded-lg overflow-hidden border ${o ? "border-indigo-500" : "border-slate-200 dark:border-slate-700"}">
1095
+ <button data-lang="${n}" class="px-2.5 py-1.5 text-xs ${o ? "bg-indigo-600 text-white" : "bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-200"}">${y(i)}</button>
1096
+ ${s ? `<span class="px-2 py-1.5 text-[10px] font-semibold ${o ? "bg-indigo-700 text-indigo-100" : "bg-emerald-600 text-white"}">MAIN</span>` : `<button data-main-lang="${n}" title="Set as main language" class="px-2 py-1.5 text-xs ${o ? "bg-indigo-700 text-indigo-100 hover:bg-indigo-800" : "bg-emerald-600 text-white hover:bg-emerald-500"}">★</button>`}
1097
+ <button data-remove-lang="${n}" title="Remove language" class="px-2 py-1.5 text-xs ${o ? "bg-indigo-700 text-indigo-100 hover:bg-indigo-800" : "bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-200 hover:bg-slate-300 dark:hover:bg-slate-600"}">×</button>
1043
1098
  </div>`;
1044
1099
  }).join(""), a.querySelectorAll("[data-lang]").forEach((n) => {
1045
1100
  n.addEventListener("click", () => {
1046
- const r = n.dataset.lang;
1047
- r && (et(t, r), L(e, t));
1101
+ const o = n.dataset.lang;
1102
+ o && (ot(t, o), $(e, t));
1048
1103
  });
1049
1104
  }), a.querySelectorAll("[data-main-lang]").forEach((n) => {
1050
- n.addEventListener("click", (r) => {
1051
- r.stopPropagation();
1105
+ n.addEventListener("click", (o) => {
1106
+ o.stopPropagation();
1052
1107
  const s = n.dataset.mainLang;
1053
- !s || !t.locales[s] || (t.mainLanguage = s, ee(s), t.baseTextByKey = { ...t.locales[s] }, L(e, t));
1108
+ !s || !t.locales[s] || (t.mainLanguage = s, te(s), t.baseTextByKey = { ...t.locales[s] }, $(e, t));
1054
1109
  });
1055
1110
  }), a.querySelectorAll("[data-remove-lang]").forEach((n) => {
1056
- n.addEventListener("click", (r) => {
1057
- r.stopPropagation();
1111
+ n.addEventListener("click", (o) => {
1112
+ o.stopPropagation();
1058
1113
  const s = n.dataset.removeLang;
1059
1114
  if (s) {
1060
1115
  if (Object.keys(t.locales).length <= 1) {
1061
1116
  alert("You must keep at least one language.");
1062
1117
  return;
1063
1118
  }
1064
- delete t.locales[s], delete t.languageLabels[s], q(t.languageLabels), I(t.locales), t.mainLanguage === s && (t.mainLanguage = j(t.locales), ee(t.mainLanguage), t.baseTextByKey = { ...t.locales[t.mainLanguage] ?? {} }), t.activeLanguage === s && (t.activeLanguage = K(t.locales, t.mainLanguage)), ye(t), L(e, t);
1119
+ 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), $(e, t);
1065
1120
  }
1066
1121
  });
1067
1122
  });
1068
1123
  }
1069
- function at(e, t) {
1124
+ function it(e, t) {
1070
1125
  e.querySelectorAll("[data-cms-id]").forEach((a) => {
1071
- const o = a.dataset.cmsId, n = a.dataset.cmsField;
1072
- !o || !n || a.addEventListener("input", () => {
1073
- const r = t.content.nodes.find((s) => s.id === o);
1074
- if (r) {
1126
+ const r = a.dataset.cmsId, n = a.dataset.cmsField;
1127
+ !r || !n || a.addEventListener("input", () => {
1128
+ const o = t.content.nodes.find((s) => s.id === r);
1129
+ if (o) {
1075
1130
  if (n === "value")
1076
- r.value = a.value, r.type === "text" && (t.activeLanguage === t.mainLanguage ? (t.baseTextByKey[r.key] = a.value, t.locales[t.mainLanguage] = { ...t.locales[t.mainLanguage] ?? {}, [r.key]: a.value }) : t.locales[t.activeLanguage] = {
1131
+ o.value = a.value, o.type === "text" && (t.activeLanguage === t.mainLanguage ? (t.baseTextByKey[o.key] = a.value, t.locales[t.mainLanguage] = { ...t.locales[t.mainLanguage] ?? {}, [o.key]: a.value }) : t.locales[t.activeLanguage] = {
1077
1132
  ...t.locales[t.activeLanguage] ?? {},
1078
- [r.key]: a.value
1133
+ [o.key]: a.value
1079
1134
  }, I(t.locales));
1080
- else if (n === "alt") r.attrs = { ...r.attrs ?? {}, alt: a.value };
1081
- else if (n === "sectionItems") r.sectionItems = a.value.split(`
1135
+ else if (n === "alt") o.attrs = { ...o.attrs ?? {}, alt: a.value };
1136
+ else if (n === "sectionItems") o.sectionItems = a.value.split(`
1082
1137
  `).map((s) => s.trim()).filter(Boolean);
1083
1138
  else if (n === "attrs")
1084
1139
  try {
1085
- r.attrs = JSON.parse(a.value);
1140
+ o.attrs = JSON.parse(a.value);
1086
1141
  } catch {
1087
1142
  return;
1088
1143
  }
1089
- P(r, t.workingDocument), oe(t.content);
1144
+ B(o, t.workingDocument), oe(t.content);
1090
1145
  }
1091
1146
  });
1092
1147
  });
1093
1148
  }
1094
- function w(e, t, a) {
1095
- const o = e.querySelector("#facms-i18n-status"), n = e.querySelector("#facms-translate-loader"), r = e.querySelector("#facms-add-language");
1096
- R(a, t), o && (o.textContent = t), n && (n.style.display = a ? "inline-flex" : "none"), r && (r.disabled = a);
1149
+ function k(e, t, a) {
1150
+ const r = e.querySelector("#facms-i18n-status"), n = e.querySelector("#facms-translate-loader"), o = e.querySelector("#facms-add-language");
1151
+ R(a, t), r && (r.textContent = t), n && (n.style.display = a ? "inline-flex" : "none"), o && (o.disabled = a);
1097
1152
  }
1098
1153
  function R(e, t) {
1099
- const a = document.getElementById("facms-global-loader"), o = document.getElementById("facms-global-loader-label");
1100
- a && (a.style.display = e ? "flex" : "none"), o && (o.textContent = e ? t : "Loading");
1154
+ const a = document.getElementById("facms-global-loader"), r = document.getElementById("facms-global-loader-label");
1155
+ a && (a.style.display = e ? "flex" : "none"), r && (r.textContent = e ? t : "Loading");
1101
1156
  }
1102
- function L(e, t) {
1103
- const a = We(t.content.nodes), o = a.length ? a.map((n) => {
1104
- 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) => Je(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) => Qe(l.node, l.index)).join("");
1157
+ function $(e, t) {
1158
+ const a = Qe(t.content.nodes), r = a.length ? a.map((n) => {
1159
+ const o = n.items[0], s = n.items[n.items.length - 1], i = o.index === s.index ? `#${o.index + 1}` : `#${o.index + 1} - #${s.index + 1}`, l = n.items.map((c) => Ze(c.node)).filter(Boolean).join(" • "), u = n.items.length > 1 ? `${i} ${y(n.selector || "Grouped fields")} (${n.items.length} fields)` : `${i} ${y(o.node.type.toUpperCase())} • ${y(o.node.label || o.node.selector || "")}`, d = n.items.map((c) => rt(c.node, c.index)).join("");
1105
1160
  return `
1106
1161
  <details class="rounded-xl p-2 border border-slate-200 dark:border-transparent bg-white dark:bg-slate-900/60 shadow-sm">
1107
1162
  <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">
1108
1163
  <div class="min-w-0">
1109
1164
  <div class="text-xs text-slate-500 dark:text-slate-400">${u}</div>
1110
- <div class="text-sm text-slate-700 dark:text-slate-300 truncate">${h(T(c || "No preview"))}</div>
1165
+ <div class="text-sm text-slate-700 dark:text-slate-300 truncate">${y(T(l || "No preview"))}</div>
1111
1166
  </div>
1112
1167
  <span class="text-xs text-indigo-600 dark:text-indigo-400">Expand</span>
1113
1168
  </summary>
@@ -1124,7 +1179,7 @@ function L(e, t) {
1124
1179
  <div id="facms-language-tabs" class="flex flex-wrap gap-2"></div>
1125
1180
  <button id="facms-add-language" class="px-2.5 py-1.5 rounded-lg text-xs border border-indigo-500 text-indigo-600 dark:text-indigo-300 dark:border-indigo-400 hover:bg-indigo-50 dark:hover:bg-indigo-900/30">+ Add translation</button>
1126
1181
  </div>
1127
- <div class="space-y-3">${o}</div>
1182
+ <div class="space-y-3">${r}</div>
1128
1183
  <div class="mt-4 flex flex-wrap gap-2">
1129
1184
  <button id="facms-save" class="px-3 py-2 bg-emerald-600 text-white rounded-lg text-sm hover:bg-emerald-500 shadow">Save + Publish</button>
1130
1185
  </div>
@@ -1133,149 +1188,149 @@ function L(e, t) {
1133
1188
  <p id="facms-i18n-status" class="text-xs text-slate-500 dark:text-slate-400"></p>
1134
1189
  </div>
1135
1190
  </div>
1136
- `, tt(e, t), e.querySelector("#facms-save")?.addEventListener("click", async () => {
1137
- let n, r;
1191
+ `, st(e, t), e.querySelector("#facms-save")?.addEventListener("click", async () => {
1192
+ let n, o;
1138
1193
  try {
1139
- n = await Ze(t.content, t.locales, t.baseTextByKey), r = await Te();
1194
+ n = await nt(t.content, t.locales, t.baseTextByKey), o = await Ie();
1140
1195
  } catch (i) {
1141
- const c = i instanceof Error ? i.message : String(i);
1142
- alert(`Could not prepare publish payload: ${c}`);
1196
+ const l = i instanceof Error ? i.message : String(i);
1197
+ alert(`Could not prepare publish payload: ${l}`);
1143
1198
  return;
1144
1199
  }
1145
- if (!r || r.provider === "none") {
1200
+ if (!o || o.provider === "none") {
1146
1201
  Le(n), alert("Patch downloaded. Configure hosting in setup for one-click publish.");
1147
1202
  return;
1148
1203
  }
1149
- const s = r.provider;
1150
- qe(s, async (i) => {
1151
- let c = !1, u = "Publishing failed. Please verify token permissions and repository settings.";
1204
+ const s = o.provider;
1205
+ Ye(s, async (i) => {
1206
+ let l = !1, u = "Publishing failed. Please verify token permissions and repository settings.";
1152
1207
  try {
1153
- c = await Re(n, i, r);
1208
+ l = await Ge(n, i, o);
1154
1209
  } catch (d) {
1155
- const l = d instanceof Error ? d.message : String(d);
1156
- l && (u = `Publishing failed: ${l}`), c = !1;
1210
+ const c = d instanceof Error ? d.message : String(d);
1211
+ c && (u = `Publishing failed: ${c}`), l = !1;
1157
1212
  }
1158
- if (!c) {
1213
+ if (!l) {
1159
1214
  alert(u);
1160
1215
  return;
1161
1216
  }
1162
1217
  alert("Changes published successfully.");
1163
1218
  });
1164
1219
  }), e.querySelector("#facms-add-language")?.addEventListener("click", () => {
1165
- Ke(Object.keys(t.locales), x?.autoTranslateEnabled ?? !0, async (n, r) => {
1166
- const [s, i] = n.split("::"), c = C(s ?? ""), u = (i ?? "").trim() || E(c);
1167
- if (!c)
1220
+ Ve(Object.keys(t.locales), x?.autoTranslateEnabled ?? !0, async (n, o) => {
1221
+ const [s, i] = n.split("::"), l = C(s ?? ""), u = (i ?? "").trim() || E(l);
1222
+ if (!l)
1168
1223
  return;
1169
- const d = performance.now(), l = t.locales[t.mainLanguage] ?? t.baseTextByKey, p = { ...l };
1224
+ const d = performance.now(), c = t.locales[t.mainLanguage] ?? t.baseTextByKey, p = { ...c };
1170
1225
  if (z("Add language requested", {
1171
- lang: c,
1172
- mode: r,
1173
- sourceKeys: Object.keys(l).length,
1226
+ lang: l,
1227
+ mode: o,
1228
+ sourceKeys: Object.keys(c).length,
1174
1229
  browserLanguage: navigator.language,
1175
1230
  browserLanguages: navigator.languages
1176
- }), 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 }), w(e, `Added ${u} tab prefilled with source text for manual translation.`, !1), r !== "auto" || !(x?.autoTranslateEnabled ?? !0)) {
1177
- r === "auto" && !(x?.autoTranslateEnabled ?? !0) && w(e, `Privacy mode is on. Added ${u} tab for manual translation only.`, !1);
1231
+ }), t.locales[l] = p, t.languageLabels[l] = u, q(t.languageLabels), t.activeLanguage = l, I(t.locales), _(t.content, t.locales[l], t.workingDocument, t.baseTextByKey), $(e, t), z("Manual language tab created", { lang: l }), k(e, `Added ${u} tab prefilled with source text for manual translation.`, !1), o !== "auto" || !(x?.autoTranslateEnabled ?? !0)) {
1232
+ o === "auto" && !(x?.autoTranslateEnabled ?? !0) && k(e, `Privacy mode is on. Added ${u} tab for manual translation only.`, !1);
1178
1233
  return;
1179
1234
  }
1180
1235
  try {
1181
- const g = Object.keys(l).length;
1182
- w(e, `Auto-filling ${u} translation... (0/${g})`, !0);
1183
- const y = await _e(l, c, t.mainLanguage, (F, b) => {
1184
- w(e, `Auto-filling ${u} translation... (${F}/${b})`, !0);
1236
+ const g = Object.keys(c).length;
1237
+ k(e, `Auto-filling ${u} translation... (0/${g})`, !0);
1238
+ const h = await Ae(c, l, t.mainLanguage, (F, b) => {
1239
+ k(e, `Auto-filling ${u} translation... (${F}/${b})`, !0);
1185
1240
  });
1186
- t.locales[c] = y, I(t.locales), t.activeLanguage = c, _(t.content, y, t.workingDocument, t.baseTextByKey), L(e, t), z("Automatic translation succeeded", {
1187
- lang: c,
1188
- translatedKeys: Object.keys(y).length,
1241
+ t.locales[l] = h, I(t.locales), t.activeLanguage = l, _(t.content, h, t.workingDocument, t.baseTextByKey), $(e, t), z("Automatic translation succeeded", {
1242
+ lang: l,
1243
+ translatedKeys: Object.keys(h).length,
1189
1244
  ms: Math.round(performance.now() - d)
1190
- }), w(e, `Added ${u} with auto-filled translation. Review and edit as needed.`, !1);
1245
+ }), k(e, `Added ${u} with auto-filled translation. Review and edit as needed.`, !1);
1191
1246
  } catch (g) {
1192
1247
  console.error("[frontend-auto-cms:dashboard] Automatic translation failed", {
1193
- lang: c,
1248
+ lang: l,
1194
1249
  message: g instanceof Error ? g.message : String(g),
1195
1250
  stack: g instanceof Error ? g.stack : void 0,
1196
1251
  ms: Math.round(performance.now() - d)
1197
- }), w(e, `Auto-fill failed. ${u} stays prefilled with source text for manual editing.`, !1);
1252
+ }), k(e, `Auto-fill failed. ${u} stays prefilled with source text for manual editing.`, !1);
1198
1253
  }
1199
1254
  });
1200
- }), at(e, t);
1255
+ }), it(e, t);
1201
1256
  }
1202
1257
  function K(e, t) {
1203
- const a = Object.keys(e), o = t && e[t] ? t : j(e), n = [...navigator.languages ?? [], navigator.language].map((r) => r.toLowerCase().split("-")[0]);
1204
- for (const r of n)
1205
- if (a.includes(r))
1206
- return r;
1207
- return a.includes(o) ? o : a[0] ?? "en";
1258
+ const a = Object.keys(e), r = t && e[t] ? t : j(e), n = [...navigator.languages ?? [], navigator.language].map((o) => o.toLowerCase().split("-")[0]);
1259
+ for (const o of n)
1260
+ if (a.includes(o))
1261
+ return o;
1262
+ return a.includes(r) ? r : a[0] ?? "en";
1208
1263
  }
1209
- function ye(e) {
1264
+ function xe(e) {
1210
1265
  const t = e.locales[e.activeLanguage] ?? e.locales.en ?? e.baseTextByKey;
1211
1266
  _(e.content, t, e.workingDocument, e.baseTextByKey);
1212
1267
  }
1213
- function nt(e) {
1268
+ function lt(e) {
1214
1269
  return new Promise((t) => window.setTimeout(t, e));
1215
1270
  }
1216
- async function te(e, t) {
1271
+ async function ae(e, t) {
1217
1272
  const a = [0, 120, 280, 600, 1100, 1800, 2600];
1218
- let o = S(e, t);
1219
- if (o.nodes.length > 0)
1220
- return o;
1273
+ let r = S(e, t);
1274
+ if (r.nodes.length > 0)
1275
+ return r;
1221
1276
  for (const n of a.slice(1))
1222
- if (await nt(n), o = S(e, t), o.nodes.length > 0)
1223
- return o;
1224
- return o;
1277
+ if (await lt(n), r = S(e, t), r.nodes.length > 0)
1278
+ return r;
1279
+ return r;
1225
1280
  }
1226
- function ot(e, t, a) {
1227
- const o = re(), n = {
1281
+ function ct(e, t, a) {
1282
+ const r = se(), n = {
1228
1283
  ...a,
1229
- ...o
1230
- }, r = Fe(), s = Object.fromEntries(e.nodes.filter((l) => l.type === "text").map((l) => [l.key, l.value])), i = j(n), c = {
1284
+ ...r
1285
+ }, o = Xe(), s = Object.fromEntries(e.nodes.filter((c) => c.type === "text").map((c) => [c.key, c.value])), i = j(n), l = {
1231
1286
  ...n,
1232
1287
  [i]: { ...n[i] ?? {}, ...s }
1233
1288
  };
1234
- !c.en && i === "en" && (c.en = Object.assign({}, c.en ?? {}, s));
1235
- const u = K(c, i), d = { ...r };
1236
- return Object.keys(c).forEach((l) => {
1237
- d[l] || (d[l] = E(l));
1289
+ !l.en && i === "en" && (l.en = Object.assign({}, l.en ?? {}, s));
1290
+ const u = K(l, i), d = { ...o };
1291
+ return Object.keys(l).forEach((c) => {
1292
+ d[c] || (d[c] = E(c));
1238
1293
  }), q(d), {
1239
1294
  content: e,
1240
- locales: c,
1295
+ locales: l,
1241
1296
  workingDocument: t,
1242
- baseTextByKey: c[i] ?? s,
1297
+ baseTextByKey: l[i] ?? s,
1243
1298
  activeLanguage: u,
1244
1299
  mainLanguage: i,
1245
1300
  languageLabels: d
1246
1301
  };
1247
1302
  }
1248
- async function rt() {
1303
+ async function dt() {
1249
1304
  const e = await ke();
1250
1305
  if (!e?.nodes?.length)
1251
1306
  return;
1252
1307
  const t = S(document, location.pathname);
1253
1308
  if (!t.nodes.length)
1254
1309
  return;
1255
- const a = new Map(e.nodes.map((o) => [o.key, o]));
1256
- t.nodes.forEach((o) => {
1257
- const n = a.get(o.key);
1258
- !n || n.type !== o.type || (o.value = n.value, n.attrs && (o.attrs = { ...n.attrs }), n.sectionItems && (o.sectionItems = [...n.sectionItems]), P(o, document));
1310
+ const a = new Map(e.nodes.map((r) => [r.key, r]));
1311
+ t.nodes.forEach((r) => {
1312
+ const n = a.get(r.key);
1313
+ !n || n.type !== r.type || (r.value = n.value, n.attrs && (r.attrs = { ...n.attrs }), n.sectionItems && (r.sectionItems = [...n.sectionItems]), B(r, document));
1259
1314
  });
1260
1315
  }
1261
- async function st() {
1262
- await rt();
1316
+ async function ut() {
1317
+ await dt();
1263
1318
  const t = {
1264
- ...await se(),
1265
- ...re()
1319
+ ...await ie(),
1320
+ ...se()
1266
1321
  };
1267
1322
  if (!Object.keys(t).length)
1268
1323
  return;
1269
- const a = j(t), o = K(t, a);
1270
- if (!o || o === a)
1324
+ const a = j(t), r = K(t, a);
1325
+ if (!r || r === a)
1271
1326
  return;
1272
- const n = S(document, location.pathname), r = t[o];
1273
- if (!r)
1327
+ const n = S(document, location.pathname), o = t[r];
1328
+ if (!o)
1274
1329
  return;
1275
1330
  const s = Object.fromEntries(n.nodes.filter((i) => i.type === "text").map((i) => [i.key, i.value]));
1276
- _(n, r, document, s);
1331
+ _(n, o, document, s);
1277
1332
  }
1278
- function it(e) {
1333
+ function ft(e) {
1279
1334
  const t = e.pages.length ? e.pages : ["/"];
1280
1335
  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 = `
1281
1336
  <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">
@@ -1305,67 +1360,67 @@ function it(e) {
1305
1360
  </div>
1306
1361
  </div>
1307
1362
  `;
1308
- const a = document.getElementById("facms-route-preview"), o = document.getElementById("facms-route-editor"), n = document.getElementById("facms-page-tabs"), r = /* @__PURE__ */ new Map();
1363
+ const a = document.getElementById("facms-route-preview"), r = document.getElementById("facms-route-editor"), n = document.getElementById("facms-page-tabs"), o = /* @__PURE__ */ new Map();
1309
1364
  let s = t[0], i = {};
1310
- const c = () => {
1365
+ const l = () => {
1311
1366
  n.innerHTML = t.map(
1312
- (u) => `<button data-page="${u}" class="w-full text-left px-3 py-2 rounded-lg text-sm border ${u === s ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-100 border-slate-200 dark:bg-slate-800 dark:border-slate-700 text-slate-700 dark:text-slate-200 hover:bg-slate-200 dark:hover:bg-slate-700"}">${h(u)}</button>`
1367
+ (u) => `<button data-page="${u}" class="w-full text-left px-3 py-2 rounded-lg text-sm border ${u === s ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-100 border-slate-200 dark:bg-slate-800 dark:border-slate-700 text-slate-700 dark:text-slate-200 hover:bg-slate-200 dark:hover:bg-slate-700"}">${y(u)}</button>`
1313
1368
  ).join(""), n.querySelectorAll("[data-page]").forEach((u) => {
1314
1369
  u.addEventListener("click", () => {
1315
- s = u.dataset.page || "/", c(), a.src = s;
1370
+ s = u.dataset.page || "/", l(), a.src = s;
1316
1371
  });
1317
1372
  });
1318
1373
  };
1319
- pe(f), a.addEventListener("load", async () => {
1374
+ ge(f), a.addEventListener("load", async () => {
1320
1375
  const u = a.contentDocument;
1321
1376
  if (u) {
1322
1377
  R(!0, `Scanning page content for ${s}...`);
1323
1378
  try {
1324
- let d = r.get(s);
1379
+ let d = o.get(s);
1325
1380
  if (d) {
1326
1381
  d.workingDocument = u;
1327
- const l = d.content.nodes.length ? S(u, s) : await te(u, s);
1328
- l.nodes.length && !d.content.nodes.length && (d.content = l);
1382
+ const c = d.content.nodes.length ? S(u, s) : await ae(u, s);
1383
+ c.nodes.length && !d.content.nodes.length && (d.content = c);
1329
1384
  } else {
1330
- const l = await te(u, s);
1331
- d = ot(l, u, i), r.set(s, d);
1385
+ const c = await ae(u, s);
1386
+ d = ct(c, u, i), o.set(s, d);
1332
1387
  }
1333
- ye(d), oe(d.content), L(o, d);
1388
+ xe(d), oe(d.content), $(r, d);
1334
1389
  } finally {
1335
1390
  R(!1, "Loading");
1336
1391
  }
1337
1392
  }
1338
- }), c(), Promise.all([se(), we()]).then(([u, d]) => {
1393
+ }), l(), Promise.all([ie(), $e()]).then(([u, d]) => {
1339
1394
  i = u, U = d, a.src = s;
1340
1395
  });
1341
1396
  }
1342
- async function ae() {
1343
- if (fe(), ge(), !await me())
1397
+ async function ne() {
1398
+ if (pe(), be(), !await he())
1344
1399
  return;
1345
- const e = await be(), t = () => it(e);
1400
+ const e = await me(), t = () => ft(e);
1346
1401
  if (!D) {
1347
- he(t);
1402
+ ye(t);
1348
1403
  return;
1349
1404
  }
1350
1405
  t();
1351
1406
  }
1352
- async function lt() {
1353
- const e = await be(), a = new URLSearchParams(location.search).get("__facms") === "1";
1407
+ async function pt() {
1408
+ const e = await me(), a = new URLSearchParams(location.search).get("__facms") === "1";
1354
1409
  if (location.pathname !== e.dashboardPath && !a) {
1355
- st();
1410
+ ut();
1356
1411
  return;
1357
1412
  }
1358
- if (fe(), ge(), !!await me()) {
1413
+ if (pe(), be(), !!await he()) {
1359
1414
  if (!D) {
1360
- he(() => {
1361
- ae();
1415
+ ye(() => {
1416
+ ne();
1362
1417
  });
1363
1418
  return;
1364
1419
  }
1365
- ae();
1420
+ ne();
1366
1421
  }
1367
1422
  }
1368
1423
  export {
1369
- ae as launchDashboard,
1370
- lt as registerCmsLauncher
1424
+ ne as launchDashboard,
1425
+ pt as registerCmsLauncher
1371
1426
  };