@sevenfold/setto-client 0.29.0 → 0.30.1
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/SettoImage.d.ts +22 -0
- package/dist/index.d.ts +7 -1
- package/dist/lib/page-store.d.ts +84 -0
- package/dist/pages/SettoPage.d.ts +63 -0
- package/dist/pages/bundled.d.ts +10 -0
- package/dist/pages/manifest.d.ts +202 -0
- package/dist/provider.d.ts +7 -0
- package/dist/setto-client.js +702 -17
- package/dist/setto-client.js.map +1 -1
- package/dist/types.d.ts +13 -0
- package/package.json +1 -1
package/dist/setto-client.js
CHANGED
|
@@ -20764,10 +20764,10 @@ function shouldShowDeprecationWarning() {
|
|
|
20764
20764
|
return parseInt(versionMatch[1], 10) <= 18;
|
|
20765
20765
|
}
|
|
20766
20766
|
if (shouldShowDeprecationWarning()) console.warn("⚠️ Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
20767
|
-
const cache = /* @__PURE__ */ new WeakMap();
|
|
20767
|
+
const cache$1 = /* @__PURE__ */ new WeakMap();
|
|
20768
20768
|
function getSupabase(config) {
|
|
20769
20769
|
const key = { url: config.url, anonKey: config.anonKey };
|
|
20770
|
-
const hit = cache.get(key);
|
|
20770
|
+
const hit = cache$1.get(key);
|
|
20771
20771
|
if (hit) return hit;
|
|
20772
20772
|
const client = createClient(config.url, config.anonKey, {
|
|
20773
20773
|
auth: {
|
|
@@ -20776,7 +20776,7 @@ function getSupabase(config) {
|
|
|
20776
20776
|
storageKey: `setto-auth-${config.url}`
|
|
20777
20777
|
}
|
|
20778
20778
|
});
|
|
20779
|
-
cache.set(key, client);
|
|
20779
|
+
cache$1.set(key, client);
|
|
20780
20780
|
return client;
|
|
20781
20781
|
}
|
|
20782
20782
|
function createFormsApi(request) {
|
|
@@ -21459,6 +21459,452 @@ class ThemeStore {
|
|
|
21459
21459
|
for (const fn of this.listeners) fn(this.cachedSnapshot);
|
|
21460
21460
|
}
|
|
21461
21461
|
}
|
|
21462
|
+
const PAGES_MANIFEST_VERSION = 1;
|
|
21463
|
+
const PAGES_PATH = "src/content/pages.json";
|
|
21464
|
+
const BUILTIN_SECTION_TYPES = ["text"];
|
|
21465
|
+
const ID = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
21466
|
+
const PATH = /^\/(?:[a-z0-9][a-z0-9-]*(?:\/[a-z0-9][a-z0-9-]*)*)?$/;
|
|
21467
|
+
function isRecord$1(value) {
|
|
21468
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21469
|
+
}
|
|
21470
|
+
function parseManifest(input) {
|
|
21471
|
+
const issues = [];
|
|
21472
|
+
if (!isRecord$1(input)) return { ok: false, issues: [{ at: "$", message: "not an object" }] };
|
|
21473
|
+
if (input.version !== PAGES_MANIFEST_VERSION) {
|
|
21474
|
+
issues.push({ at: "version", message: `expected ${PAGES_MANIFEST_VERSION}` });
|
|
21475
|
+
}
|
|
21476
|
+
const pages = [];
|
|
21477
|
+
const pageIds = /* @__PURE__ */ new Set();
|
|
21478
|
+
const paths = /* @__PURE__ */ new Set();
|
|
21479
|
+
const sectionIds = /* @__PURE__ */ new Set();
|
|
21480
|
+
const rawPages = Array.isArray(input.pages) ? input.pages : null;
|
|
21481
|
+
if (!rawPages) issues.push({ at: "pages", message: "must be a list" });
|
|
21482
|
+
(rawPages ?? []).forEach((raw, i) => {
|
|
21483
|
+
const at = `pages[${i}]`;
|
|
21484
|
+
if (!isRecord$1(raw)) {
|
|
21485
|
+
issues.push({ at, message: "not an object" });
|
|
21486
|
+
return;
|
|
21487
|
+
}
|
|
21488
|
+
const id = String(raw.id ?? "");
|
|
21489
|
+
const path2 = String(raw.path ?? "");
|
|
21490
|
+
const titleKey = String(raw.titleKey ?? "");
|
|
21491
|
+
if (!ID.test(id)) issues.push({ at: `${at}.id`, message: `invalid id "${id}"` });
|
|
21492
|
+
else if (pageIds.has(id)) issues.push({ at: `${at}.id`, message: `duplicate page "${id}"` });
|
|
21493
|
+
pageIds.add(id);
|
|
21494
|
+
if (!PATH.test(path2)) issues.push({ at: `${at}.path`, message: `invalid path "${path2}"` });
|
|
21495
|
+
else if (path2 === "/setto" || path2.startsWith("/setto/")) {
|
|
21496
|
+
issues.push({ at: `${at}.path`, message: "/setto belongs to the editor" });
|
|
21497
|
+
} else if (paths.has(path2)) issues.push({ at: `${at}.path`, message: `duplicate path "${path2}"` });
|
|
21498
|
+
paths.add(path2);
|
|
21499
|
+
if (!titleKey) issues.push({ at: `${at}.titleKey`, message: "required" });
|
|
21500
|
+
const sections = [];
|
|
21501
|
+
const rawSections = Array.isArray(raw.sections) ? raw.sections : null;
|
|
21502
|
+
if (!rawSections) issues.push({ at: `${at}.sections`, message: "must be a list" });
|
|
21503
|
+
(rawSections ?? []).forEach((s, j) => {
|
|
21504
|
+
const sat = `${at}.sections[${j}]`;
|
|
21505
|
+
if (!isRecord$1(s)) {
|
|
21506
|
+
issues.push({ at: sat, message: "not an object" });
|
|
21507
|
+
return;
|
|
21508
|
+
}
|
|
21509
|
+
const sid = String(s.id ?? "");
|
|
21510
|
+
if (!ID.test(sid)) issues.push({ at: `${sat}.id`, message: `invalid id "${sid}"` });
|
|
21511
|
+
else if (sectionIds.has(sid)) issues.push({ at: `${sat}.id`, message: `duplicate section "${sid}"` });
|
|
21512
|
+
sectionIds.add(sid);
|
|
21513
|
+
const type = s.type;
|
|
21514
|
+
if (type !== void 0 && !BUILTIN_SECTION_TYPES.includes(type)) {
|
|
21515
|
+
issues.push({ at: `${sat}.type`, message: `unknown section type "${String(type)}"` });
|
|
21516
|
+
}
|
|
21517
|
+
sections.push({
|
|
21518
|
+
id: sid,
|
|
21519
|
+
...type !== void 0 ? { type } : {},
|
|
21520
|
+
...s.hidden === true ? { hidden: true } : {},
|
|
21521
|
+
...typeof s.label === "string" && s.label.trim() ? { label: s.label.trim() } : {}
|
|
21522
|
+
});
|
|
21523
|
+
});
|
|
21524
|
+
pages.push({
|
|
21525
|
+
id,
|
|
21526
|
+
path: path2,
|
|
21527
|
+
titleKey,
|
|
21528
|
+
...raw.hidden === true ? { hidden: true } : {},
|
|
21529
|
+
sections
|
|
21530
|
+
});
|
|
21531
|
+
});
|
|
21532
|
+
const menu = parseMenu(input.menu, "menu", issues);
|
|
21533
|
+
const footer2 = parseMenu(input.footer, "footer", issues);
|
|
21534
|
+
if (issues.length > 0) return { ok: false, issues };
|
|
21535
|
+
return { ok: true, manifest: { version: PAGES_MANIFEST_VERSION, pages, menu, footer: footer2 } };
|
|
21536
|
+
}
|
|
21537
|
+
function parseMenu(raw, at, issues) {
|
|
21538
|
+
if (raw === void 0) return [];
|
|
21539
|
+
if (!Array.isArray(raw)) {
|
|
21540
|
+
issues.push({ at, message: "must be a list" });
|
|
21541
|
+
return [];
|
|
21542
|
+
}
|
|
21543
|
+
const ids = /* @__PURE__ */ new Set();
|
|
21544
|
+
const items = [];
|
|
21545
|
+
raw.forEach((item, i) => {
|
|
21546
|
+
const iat = `${at}[${i}]`;
|
|
21547
|
+
if (!isRecord$1(item)) {
|
|
21548
|
+
issues.push({ at: iat, message: "not an object" });
|
|
21549
|
+
return;
|
|
21550
|
+
}
|
|
21551
|
+
const id = String(item.id ?? "");
|
|
21552
|
+
const href = String(item.href ?? "");
|
|
21553
|
+
const labelKey = String(item.labelKey ?? "");
|
|
21554
|
+
if (!ID.test(id)) issues.push({ at: `${iat}.id`, message: `invalid id "${id}"` });
|
|
21555
|
+
else if (ids.has(id)) issues.push({ at: `${iat}.id`, message: `duplicate item "${id}"` });
|
|
21556
|
+
ids.add(id);
|
|
21557
|
+
if (!isSafeHref(href)) issues.push({ at: `${iat}.href`, message: `invalid link "${href}"` });
|
|
21558
|
+
if (!labelKey) issues.push({ at: `${iat}.labelKey`, message: "required" });
|
|
21559
|
+
items.push({ id, href, labelKey, ...item.hidden === true ? { hidden: true } : {} });
|
|
21560
|
+
});
|
|
21561
|
+
return items;
|
|
21562
|
+
}
|
|
21563
|
+
function isSafeHref(href) {
|
|
21564
|
+
if (!href) return false;
|
|
21565
|
+
if (href.startsWith("/") && !href.startsWith("//")) return true;
|
|
21566
|
+
if (href.startsWith("#")) return true;
|
|
21567
|
+
return /^(https?:\/\/|mailto:|tel:)/i.test(href);
|
|
21568
|
+
}
|
|
21569
|
+
function normalisePath(path2) {
|
|
21570
|
+
const bare = (path2.split(/[?#]/)[0] ?? "").replace(/\/+$/, "");
|
|
21571
|
+
return bare === "" ? "/" : bare.toLowerCase();
|
|
21572
|
+
}
|
|
21573
|
+
function pageForPath(manifest, path2) {
|
|
21574
|
+
const wanted = normalisePath(path2);
|
|
21575
|
+
return manifest.pages.find((p) => p.path === wanted) ?? null;
|
|
21576
|
+
}
|
|
21577
|
+
function pageById(manifest, id) {
|
|
21578
|
+
return manifest.pages.find((p) => p.id === id) ?? null;
|
|
21579
|
+
}
|
|
21580
|
+
function findSection(manifest, sectionId) {
|
|
21581
|
+
for (const page of manifest.pages) {
|
|
21582
|
+
const index2 = page.sections.findIndex((s) => s.id === sectionId);
|
|
21583
|
+
if (index2 >= 0) return { page, index: index2, section: page.sections[index2] };
|
|
21584
|
+
}
|
|
21585
|
+
return null;
|
|
21586
|
+
}
|
|
21587
|
+
function visibleMenu(manifest, list2) {
|
|
21588
|
+
return manifest[list2].filter((item) => !item.hidden && !leadsNowhere(manifest, item.href));
|
|
21589
|
+
}
|
|
21590
|
+
function leadsNowhere(manifest, href) {
|
|
21591
|
+
if (!href.startsWith("/") && !href.startsWith("#")) return false;
|
|
21592
|
+
const [pathPart, fragment] = href.split("#");
|
|
21593
|
+
const page = pageForPath(manifest, pathPart || "/");
|
|
21594
|
+
if (pathPart && !page) return false;
|
|
21595
|
+
if (page?.hidden) return true;
|
|
21596
|
+
if (!fragment) return false;
|
|
21597
|
+
const target = findSection(manifest, fragment);
|
|
21598
|
+
return target ? Boolean(target.section.hidden || target.page.hidden) : false;
|
|
21599
|
+
}
|
|
21600
|
+
class ManifestError extends Error {
|
|
21601
|
+
constructor(code2, message) {
|
|
21602
|
+
super(message);
|
|
21603
|
+
this.code = code2;
|
|
21604
|
+
this.name = "ManifestError";
|
|
21605
|
+
}
|
|
21606
|
+
code;
|
|
21607
|
+
}
|
|
21608
|
+
function clone(manifest) {
|
|
21609
|
+
return JSON.parse(JSON.stringify(manifest));
|
|
21610
|
+
}
|
|
21611
|
+
function mustPage(manifest, pageId) {
|
|
21612
|
+
const page = pageById(manifest, pageId);
|
|
21613
|
+
if (!page) throw new ManifestError("page_not_found", `no page "${pageId}"`);
|
|
21614
|
+
return page;
|
|
21615
|
+
}
|
|
21616
|
+
function moveSection(manifest, sectionId, delta) {
|
|
21617
|
+
const next = clone(manifest);
|
|
21618
|
+
const found = findSection(next, sectionId);
|
|
21619
|
+
if (!found) throw new ManifestError("section_not_found", `no section "${sectionId}"`);
|
|
21620
|
+
const { page, index: index2 } = found;
|
|
21621
|
+
let target = index2 + delta;
|
|
21622
|
+
while (target >= 0 && target < page.sections.length && page.sections[target].hidden) target += delta;
|
|
21623
|
+
if (target < 0 || target >= page.sections.length) return manifest;
|
|
21624
|
+
const [moved] = page.sections.splice(index2, 1);
|
|
21625
|
+
page.sections.splice(target, 0, moved);
|
|
21626
|
+
return next;
|
|
21627
|
+
}
|
|
21628
|
+
function placeSection(manifest, sectionId, index2) {
|
|
21629
|
+
const next = clone(manifest);
|
|
21630
|
+
const found = findSection(next, sectionId);
|
|
21631
|
+
if (!found) throw new ManifestError("section_not_found", `no section "${sectionId}"`);
|
|
21632
|
+
const [moved] = found.page.sections.splice(found.index, 1);
|
|
21633
|
+
const at = Math.max(0, Math.min(index2, found.page.sections.length));
|
|
21634
|
+
found.page.sections.splice(at, 0, moved);
|
|
21635
|
+
return next;
|
|
21636
|
+
}
|
|
21637
|
+
function setSectionHidden(manifest, sectionId, hidden) {
|
|
21638
|
+
const next = clone(manifest);
|
|
21639
|
+
const found = findSection(next, sectionId);
|
|
21640
|
+
if (!found) throw new ManifestError("section_not_found", `no section "${sectionId}"`);
|
|
21641
|
+
if (hidden) found.section.hidden = true;
|
|
21642
|
+
else delete found.section.hidden;
|
|
21643
|
+
return next;
|
|
21644
|
+
}
|
|
21645
|
+
function addSection(manifest, pageId, section, index2) {
|
|
21646
|
+
if (!ID.test(section.id)) throw new ManifestError("invalid", `invalid section id "${section.id}"`);
|
|
21647
|
+
if (findSection(manifest, section.id)) {
|
|
21648
|
+
throw new ManifestError("duplicate_id", `section "${section.id}" already exists`);
|
|
21649
|
+
}
|
|
21650
|
+
const next = clone(manifest);
|
|
21651
|
+
const page = mustPage(next, pageId);
|
|
21652
|
+
const at = index2 === void 0 ? page.sections.length : Math.max(0, Math.min(index2, page.sections.length));
|
|
21653
|
+
page.sections.splice(at, 0, { ...section });
|
|
21654
|
+
return next;
|
|
21655
|
+
}
|
|
21656
|
+
function addPage(manifest, page) {
|
|
21657
|
+
const path2 = normalisePath(page.path);
|
|
21658
|
+
if (!ID.test(page.id) || !PATH.test(path2) || path2 === "/setto" || path2.startsWith("/setto/")) {
|
|
21659
|
+
throw new ManifestError("invalid", `invalid page "${page.id}" at "${page.path}"`);
|
|
21660
|
+
}
|
|
21661
|
+
if (pageById(manifest, page.id)) throw new ManifestError("duplicate_id", `page "${page.id}" already exists`);
|
|
21662
|
+
if (pageForPath(manifest, path2)) throw new ManifestError("duplicate_path", `a page already lives at ${path2}`);
|
|
21663
|
+
let next = clone(manifest);
|
|
21664
|
+
next.pages.push({ id: page.id, path: path2, titleKey: page.titleKey, sections: [] });
|
|
21665
|
+
for (const section of page.sections) next = addSection(next, page.id, section);
|
|
21666
|
+
return next;
|
|
21667
|
+
}
|
|
21668
|
+
function setPageHidden(manifest, pageId, hidden) {
|
|
21669
|
+
const next = clone(manifest);
|
|
21670
|
+
const page = mustPage(next, pageId);
|
|
21671
|
+
if (page.path === "/" && hidden) throw new ManifestError("invalid", "the front page cannot be hidden");
|
|
21672
|
+
if (hidden) page.hidden = true;
|
|
21673
|
+
else delete page.hidden;
|
|
21674
|
+
return next;
|
|
21675
|
+
}
|
|
21676
|
+
function upsertMenuItem(manifest, list2, item, index2) {
|
|
21677
|
+
if (!ID.test(item.id) || !isSafeHref(item.href) || !item.labelKey) {
|
|
21678
|
+
throw new ManifestError("invalid", `invalid link "${item.id}"`);
|
|
21679
|
+
}
|
|
21680
|
+
const next = clone(manifest);
|
|
21681
|
+
const items = next[list2];
|
|
21682
|
+
const existing = items.findIndex((i) => i.id === item.id);
|
|
21683
|
+
const clean = { id: item.id, href: item.href, labelKey: item.labelKey };
|
|
21684
|
+
if (item.hidden) clean.hidden = true;
|
|
21685
|
+
if (existing >= 0) items[existing] = clean;
|
|
21686
|
+
else items.splice(index2 === void 0 ? items.length : Math.max(0, Math.min(index2, items.length)), 0, clean);
|
|
21687
|
+
return next;
|
|
21688
|
+
}
|
|
21689
|
+
function moveMenuItem(manifest, list2, itemId, delta) {
|
|
21690
|
+
const next = clone(manifest);
|
|
21691
|
+
const items = next[list2];
|
|
21692
|
+
const index2 = items.findIndex((i) => i.id === itemId);
|
|
21693
|
+
if (index2 < 0) throw new ManifestError("item_not_found", `no link "${itemId}" in ${list2}`);
|
|
21694
|
+
const target = index2 + delta;
|
|
21695
|
+
if (target < 0 || target >= items.length) return manifest;
|
|
21696
|
+
const [moved] = items.splice(index2, 1);
|
|
21697
|
+
items.splice(target, 0, moved);
|
|
21698
|
+
return next;
|
|
21699
|
+
}
|
|
21700
|
+
function setMenuItemHidden(manifest, list2, itemId, hidden) {
|
|
21701
|
+
const next = clone(manifest);
|
|
21702
|
+
const item = next[list2].find((i) => i.id === itemId);
|
|
21703
|
+
if (!item) throw new ManifestError("item_not_found", `no link "${itemId}" in ${list2}`);
|
|
21704
|
+
if (hidden) item.hidden = true;
|
|
21705
|
+
else delete item.hidden;
|
|
21706
|
+
return next;
|
|
21707
|
+
}
|
|
21708
|
+
function applyOp(manifest, op) {
|
|
21709
|
+
switch (op.op) {
|
|
21710
|
+
case "move_section":
|
|
21711
|
+
return moveSection(manifest, op.sectionId, op.delta);
|
|
21712
|
+
case "place_section":
|
|
21713
|
+
return placeSection(manifest, op.sectionId, op.index);
|
|
21714
|
+
case "hide_section":
|
|
21715
|
+
return setSectionHidden(manifest, op.sectionId, true);
|
|
21716
|
+
case "show_section":
|
|
21717
|
+
return setSectionHidden(manifest, op.sectionId, false);
|
|
21718
|
+
case "add_section":
|
|
21719
|
+
return addSection(manifest, op.pageId, op.section, op.index);
|
|
21720
|
+
case "add_page":
|
|
21721
|
+
return addPage(manifest, op.page);
|
|
21722
|
+
case "hide_page":
|
|
21723
|
+
return setPageHidden(manifest, op.pageId, true);
|
|
21724
|
+
case "show_page":
|
|
21725
|
+
return setPageHidden(manifest, op.pageId, false);
|
|
21726
|
+
case "upsert_link":
|
|
21727
|
+
return upsertMenuItem(manifest, op.list, op.item, op.index);
|
|
21728
|
+
case "move_link":
|
|
21729
|
+
return moveMenuItem(manifest, op.list, op.itemId, op.delta);
|
|
21730
|
+
case "hide_link":
|
|
21731
|
+
return setMenuItemHidden(manifest, op.list, op.itemId, true);
|
|
21732
|
+
case "show_link":
|
|
21733
|
+
return setMenuItemHidden(manifest, op.list, op.itemId, false);
|
|
21734
|
+
}
|
|
21735
|
+
}
|
|
21736
|
+
function applyOps(manifest, ops) {
|
|
21737
|
+
let next = manifest;
|
|
21738
|
+
for (let i = 0; i < ops.length; i++) {
|
|
21739
|
+
try {
|
|
21740
|
+
next = applyOp(next, ops[i]);
|
|
21741
|
+
} catch (err) {
|
|
21742
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err), at: i };
|
|
21743
|
+
}
|
|
21744
|
+
}
|
|
21745
|
+
return { ok: true, manifest: next };
|
|
21746
|
+
}
|
|
21747
|
+
function builtinKeys(sectionId) {
|
|
21748
|
+
const base = `sections.${sectionId}`;
|
|
21749
|
+
return {
|
|
21750
|
+
heading: `${base}.heading`,
|
|
21751
|
+
intro: `${base}.intro`,
|
|
21752
|
+
items: `${base}.items`,
|
|
21753
|
+
itemHeading: (itemKey) => `${base}.items.${itemKey}.heading`,
|
|
21754
|
+
itemText: (itemKey) => `${base}.items.${itemKey}.text`
|
|
21755
|
+
};
|
|
21756
|
+
}
|
|
21757
|
+
function pageTitleKey(pageId) {
|
|
21758
|
+
return `pages.${pageId}.title`;
|
|
21759
|
+
}
|
|
21760
|
+
function serialiseManifest(manifest) {
|
|
21761
|
+
return JSON.stringify(manifest, null, 2) + "\n";
|
|
21762
|
+
}
|
|
21763
|
+
const EMPTY_PAGE_STORE_SNAPSHOT = {
|
|
21764
|
+
manifest: null,
|
|
21765
|
+
changes: 0,
|
|
21766
|
+
version: 0
|
|
21767
|
+
};
|
|
21768
|
+
class PageStore {
|
|
21769
|
+
data;
|
|
21770
|
+
baseline;
|
|
21771
|
+
version = 0;
|
|
21772
|
+
listeners = /* @__PURE__ */ new Set();
|
|
21773
|
+
cached;
|
|
21774
|
+
constructor(initial) {
|
|
21775
|
+
this.data = initial ? structuredClone(initial) : null;
|
|
21776
|
+
this.baseline = initial ? structuredClone(initial) : null;
|
|
21777
|
+
this.cached = { manifest: this.data, changes: 0, version: 0 };
|
|
21778
|
+
}
|
|
21779
|
+
snapshot() {
|
|
21780
|
+
return this.cached;
|
|
21781
|
+
}
|
|
21782
|
+
subscribe(listener) {
|
|
21783
|
+
this.listeners.add(listener);
|
|
21784
|
+
return () => this.listeners.delete(listener);
|
|
21785
|
+
}
|
|
21786
|
+
get manifest() {
|
|
21787
|
+
return this.data;
|
|
21788
|
+
}
|
|
21789
|
+
/** True once the site has a manifest to edit. */
|
|
21790
|
+
has() {
|
|
21791
|
+
return this.data !== null;
|
|
21792
|
+
}
|
|
21793
|
+
/**
|
|
21794
|
+
* Apply changes as drafts. All of them or none: a list that fails halfway
|
|
21795
|
+
* leaves the page exactly as it was and says which one failed.
|
|
21796
|
+
*/
|
|
21797
|
+
apply(ops) {
|
|
21798
|
+
if (!this.data) return { ok: false, error: "this site has no page manifest", at: 0 };
|
|
21799
|
+
const result = applyOps(this.data, ops);
|
|
21800
|
+
if (!result.ok) return result;
|
|
21801
|
+
this.data = result.manifest;
|
|
21802
|
+
this.bump();
|
|
21803
|
+
return { ok: true };
|
|
21804
|
+
}
|
|
21805
|
+
/**
|
|
21806
|
+
* Put the draft back to an earlier manifest, keeping the baseline.
|
|
21807
|
+
*
|
|
21808
|
+
* What «Angre» on one of Pixel's changes does: the panel remembers the
|
|
21809
|
+
* manifest from before the change and hands it back here. Checked like
|
|
21810
|
+
* anything else, because it has been through a round trip it did not have
|
|
21811
|
+
* to survive.
|
|
21812
|
+
*/
|
|
21813
|
+
restore(manifest) {
|
|
21814
|
+
const parsed = parseManifest(manifest);
|
|
21815
|
+
if (!parsed.ok) return { ok: false, error: parsed.issues[0]?.message ?? "invalid manifest" };
|
|
21816
|
+
this.data = parsed.manifest;
|
|
21817
|
+
this.bump();
|
|
21818
|
+
return { ok: true };
|
|
21819
|
+
}
|
|
21820
|
+
/**
|
|
21821
|
+
* Replace the baseline with what the repository holds, dropping drafts.
|
|
21822
|
+
*
|
|
21823
|
+
* Checked first: the file in the repository can be newer than this bundle,
|
|
21824
|
+
* or hand-edited, and a baseline this store cannot render must not replace
|
|
21825
|
+
* the one it can. Returns whether it was taken.
|
|
21826
|
+
*/
|
|
21827
|
+
loadBaseline(next) {
|
|
21828
|
+
const parsed = parseManifest(next);
|
|
21829
|
+
if (!parsed.ok) {
|
|
21830
|
+
console.warn("[setto] pages.json from the repository is not valid and was ignored", parsed.issues);
|
|
21831
|
+
return false;
|
|
21832
|
+
}
|
|
21833
|
+
this.data = parsed.manifest;
|
|
21834
|
+
this.baseline = structuredClone(parsed.manifest);
|
|
21835
|
+
this.bump();
|
|
21836
|
+
return true;
|
|
21837
|
+
}
|
|
21838
|
+
revertAll() {
|
|
21839
|
+
this.data = this.baseline ? structuredClone(this.baseline) : null;
|
|
21840
|
+
this.bump();
|
|
21841
|
+
}
|
|
21842
|
+
commit() {
|
|
21843
|
+
this.baseline = this.data ? structuredClone(this.data) : null;
|
|
21844
|
+
this.bump();
|
|
21845
|
+
}
|
|
21846
|
+
/** Number of changes, for the toolbar's count. Zero means nothing to publish. */
|
|
21847
|
+
size() {
|
|
21848
|
+
return this.cached.changes;
|
|
21849
|
+
}
|
|
21850
|
+
serialise() {
|
|
21851
|
+
return this.data ? serialiseManifest(this.data) : null;
|
|
21852
|
+
}
|
|
21853
|
+
bump() {
|
|
21854
|
+
this.version += 1;
|
|
21855
|
+
this.cached = {
|
|
21856
|
+
manifest: this.data,
|
|
21857
|
+
changes: countChanges(this.baseline, this.data),
|
|
21858
|
+
version: this.version
|
|
21859
|
+
};
|
|
21860
|
+
for (const fn of this.listeners) fn(this.cached);
|
|
21861
|
+
}
|
|
21862
|
+
}
|
|
21863
|
+
function countChanges(before, after) {
|
|
21864
|
+
if (!before || !after) return before === after ? 0 : 1;
|
|
21865
|
+
let changes = 0;
|
|
21866
|
+
const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
21867
|
+
const beforePages = new Map(before.pages.map((p) => [p.id, p]));
|
|
21868
|
+
for (const page of after.pages) {
|
|
21869
|
+
const was = beforePages.get(page.id);
|
|
21870
|
+
if (!was) {
|
|
21871
|
+
changes += 1;
|
|
21872
|
+
continue;
|
|
21873
|
+
}
|
|
21874
|
+
if (was.path !== page.path || was.titleKey !== page.titleKey || Boolean(was.hidden) !== Boolean(page.hidden)) {
|
|
21875
|
+
changes += 1;
|
|
21876
|
+
}
|
|
21877
|
+
const wasSections = new Map(was.sections.map((s, i) => [s.id, { s, i }]));
|
|
21878
|
+
page.sections.forEach((s, i) => {
|
|
21879
|
+
const prior = wasSections.get(s.id);
|
|
21880
|
+
if (!prior || prior.i !== i || !same(prior.s, s)) changes += 1;
|
|
21881
|
+
});
|
|
21882
|
+
if (was.sections.length > page.sections.length) changes += was.sections.length - page.sections.length;
|
|
21883
|
+
}
|
|
21884
|
+
if (before.pages.length > after.pages.length) changes += before.pages.length - after.pages.length;
|
|
21885
|
+
for (const list2 of ["menu", "footer"]) {
|
|
21886
|
+
const wasItems = new Map(before[list2].map((item, i) => [item.id, { item, i }]));
|
|
21887
|
+
after[list2].forEach((item, i) => {
|
|
21888
|
+
const prior = wasItems.get(item.id);
|
|
21889
|
+
if (!prior || prior.i !== i || !same(prior.item, item)) changes += 1;
|
|
21890
|
+
});
|
|
21891
|
+
if (before[list2].length > after[list2].length) changes += before[list2].length - after[list2].length;
|
|
21892
|
+
}
|
|
21893
|
+
return changes;
|
|
21894
|
+
}
|
|
21895
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
21896
|
+
function bundledManifest(raw) {
|
|
21897
|
+
if (!raw || typeof raw !== "object") return null;
|
|
21898
|
+
const hit = cache.get(raw);
|
|
21899
|
+
if (hit !== void 0) return hit;
|
|
21900
|
+
const parsed = parseManifest(raw);
|
|
21901
|
+
if (!parsed.ok) {
|
|
21902
|
+
console.warn("[setto] pages.json is not valid and was ignored", parsed.issues);
|
|
21903
|
+
}
|
|
21904
|
+
const manifest = parsed.ok ? parsed.manifest : null;
|
|
21905
|
+
cache.set(raw, manifest);
|
|
21906
|
+
return manifest;
|
|
21907
|
+
}
|
|
21462
21908
|
const EMPTY$1 = {
|
|
21463
21909
|
sites: null,
|
|
21464
21910
|
currentSite: null,
|
|
@@ -29898,7 +30344,7 @@ function requireExtend() {
|
|
|
29898
30344
|
return obj[name2];
|
|
29899
30345
|
};
|
|
29900
30346
|
extend$1 = function extend2() {
|
|
29901
|
-
var options, name2, src, copy, copyIsArray,
|
|
30347
|
+
var options, name2, src, copy, copyIsArray, clone2;
|
|
29902
30348
|
var target = arguments[0];
|
|
29903
30349
|
var i = 1;
|
|
29904
30350
|
var length = arguments.length;
|
|
@@ -29921,11 +30367,11 @@ function requireExtend() {
|
|
|
29921
30367
|
if (deep && copy && (isPlainObject2(copy) || (copyIsArray = isArray(copy)))) {
|
|
29922
30368
|
if (copyIsArray) {
|
|
29923
30369
|
copyIsArray = false;
|
|
29924
|
-
|
|
30370
|
+
clone2 = src && isArray(src) ? src : [];
|
|
29925
30371
|
} else {
|
|
29926
|
-
|
|
30372
|
+
clone2 = src && isPlainObject2(src) ? src : {};
|
|
29927
30373
|
}
|
|
29928
|
-
setProperty(target, { name: name2, newValue: extend2(deep,
|
|
30374
|
+
setProperty(target, { name: name2, newValue: extend2(deep, clone2, copy) });
|
|
29929
30375
|
} else if (typeof copy !== "undefined") {
|
|
29930
30376
|
setProperty(target, { name: name2, newValue: copy });
|
|
29931
30377
|
}
|
|
@@ -34616,7 +35062,7 @@ const ACTIVE_CONVERSATION_KEY = "setto-chat-active";
|
|
|
34616
35062
|
const NAVIGATION_KEY = "setto-chat-navigation";
|
|
34617
35063
|
const CLOSE_MS = 210;
|
|
34618
35064
|
const MIN_COMPOSER_HEIGHT = 36;
|
|
34619
|
-
const MAX_COMPOSER_HEIGHT =
|
|
35065
|
+
const MAX_COMPOSER_HEIGHT = 144;
|
|
34620
35066
|
const DESKTOP_POPUP_QUERY = "(min-width: 701px)";
|
|
34621
35067
|
function visitorId() {
|
|
34622
35068
|
try {
|
|
@@ -36059,7 +36505,7 @@ function useChatStyles() {
|
|
|
36059
36505
|
.setto-chat__body{position:relative;display:flex;flex:1 1 auto;min-height:0;height:100%;flex-direction:column}.setto-chat__log{display:flex;flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;flex-direction:column;padding:calc(58px + 1.3rem) .75rem var(--setto-chat-composer-space,8rem);scroll-padding-bottom:var(--setto-chat-composer-space,8rem);scroll-behavior:auto;-webkit-overflow-scrolling:touch}.setto-chat__message-list{display:flex;flex-direction:column}.setto-chat__message{--setto-chat-bubble:color-mix(in srgb,var(--setto-chat-ink) 7%,var(--setto-chat-canvas));display:flex;align-items:flex-end;gap:.55rem;width:100%;margin-bottom:1rem;color:color-mix(in srgb,var(--setto-chat-ink) 92%,transparent);font-size:16px;line-height:1.5;overflow-wrap:anywhere}.setto-chat__message-stack{display:flex;min-width:0;max-width:min(78%,36rem);flex-direction:column;align-items:flex-start}.setto-chat__message-bubble{position:relative;min-width:2.5rem;padding:.58rem .82rem;border-radius:19px 19px 19px 5px;background:var(--setto-chat-bubble);white-space:pre-wrap}.setto-chat__message--assistant .setto-chat__message-bubble::before,.setto-chat__message--human .setto-chat__message-bubble::before{content:"";position:absolute;z-index:0;left:-7px;bottom:0;width:16px;height:17px;border-bottom-right-radius:14px;background:var(--setto-chat-bubble)}.setto-chat__message--assistant .setto-chat__message-bubble::after,.setto-chat__message--human .setto-chat__message-bubble::after{content:"";position:absolute;z-index:1;left:-10px;bottom:0;width:10px;height:18px;border-bottom-right-radius:10px;background:var(--setto-chat-canvas)}.setto-chat__message-copy,.setto-chat__image{position:relative;z-index:2}.setto-chat__message--visitor{--setto-chat-bubble:#0a84ff;justify-content:flex-end;color:#fff}.setto-chat__message--visitor .setto-chat__message-stack{align-items:flex-end}.setto-chat__message--visitor .setto-chat__message-bubble{border-radius:19px 19px 5px 19px}.setto-chat__message--visitor .setto-chat__message-bubble::before{content:"";position:absolute;z-index:0;right:-7px;bottom:0;width:16px;height:17px;border-bottom-left-radius:14px;background:var(--setto-chat-bubble)}.setto-chat__message--visitor .setto-chat__message-bubble::after{content:"";position:absolute;z-index:1;right:-10px;bottom:0;width:10px;height:18px;border-bottom-left-radius:10px;background:var(--setto-chat-canvas)}.setto-chat__message--system{justify-content:center;color:color-mix(in srgb,var(--setto-chat-ink) 55%,transparent);font-size:.78rem;line-height:1.45;text-align:center}.setto-chat__message--system .setto-chat__message-stack{max-width:85%;align-items:center}.setto-chat__message--system .setto-chat__message-bubble{padding:.25rem .6rem;background:transparent}.setto-chat__avatar{position:relative;z-index:3;display:grid;place-items:center;flex:0 0 34px;width:34px;height:34px;margin-bottom:1px;overflow:hidden;border:2px solid var(--setto-chat-canvas);border-radius:50%;background:var(--setto-chat-crema);color:var(--setto-chat-ink);box-shadow:0 2px 8px color-mix(in srgb,var(--setto-chat-ink) 14%,transparent)}.setto-chat__avatar--assistant{background:var(--setto-chat-accent);color:var(--setto-chat-raised)}.setto-chat__avatar img{display:block;width:100%;height:100%;object-fit:cover}.setto-chat__speaker{display:block;margin:0 0 .2rem .4rem;color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent);font-size:.69rem;font-weight:500;line-height:1.2}.setto-chat__typing{display:inline-block;min-width:1.8rem;animation:setto-chat-pulse 1s ease-in-out infinite}.setto-chat__image{display:block;width:max-content;max-width:100%;margin-top:.65rem;overflow:hidden;border-radius:13px}.setto-chat__image img{display:block;width:min(280px,100%);max-height:260px;object-fit:cover}
|
|
36060
36506
|
.setto-chat__message--agent-joined{justify-content:flex-start;align-items:center;gap:.55rem;padding:.1rem .4rem;color:color-mix(in srgb,var(--setto-chat-ink) 62%,transparent);font-size:.8rem;line-height:1.4;text-align:left}.setto-chat__message--agent-joined .setto-chat__message-stack{max-width:calc(100% - 38px);align-items:flex-start}.setto-chat__message--agent-joined .setto-chat__message-bubble{min-width:0;padding:.2rem 0;background:transparent;white-space:normal}.setto-chat__avatar--joined{flex-basis:30px;width:30px;height:30px;margin:0;border-width:1px;box-shadow:0 2px 7px color-mix(in srgb,var(--setto-chat-ink) 12%,transparent)}
|
|
36061
36507
|
.setto-chat__receipt{display:block;margin:.26rem .45rem 0 0;color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent);font-size:.69rem;font-weight:500;line-height:1.2}.setto-chat__message--typing{animation:setto-chat-typing-in 180ms cubic-bezier(.2,.8,.2,1) both}.setto-chat__message--typing .setto-chat__message-bubble{min-width:3.25rem;text-align:center}.setto-chat__message--typing .setto-chat__typing{font-weight:700;letter-spacing:.06em}@keyframes setto-chat-typing-in{from{opacity:0;transform:translateY(4px)}}@media(prefers-reduced-motion:reduce){.setto-chat__message--typing{animation:none}}
|
|
36062
|
-
.setto-chat__composer-shell{position:absolute;left:0;right:0;bottom:0;z-index:25;display:grid;grid-template-columns:minmax(0,1fr);padding:1.5rem .75rem 0;background:transparent;isolation:isolate}.setto-chat__composer-shell::before{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(to bottom,transparent 0%,color-mix(in srgb,var(--setto-chat-canvas) 82%,transparent) 46%,var(--setto-chat-canvas) 66%);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);-webkit-mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.4) 34%,rgba(0,0,0,1) 66%);mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.4) 34%,rgba(0,0,0,1) 66%)}.setto-chat__composer{position:relative;z-index:1;display:flex;flex-direction:column;gap:.15rem;width:100%;min-width:0;margin:0;padding:.35rem .4rem;border:2px solid color-mix(in srgb,var(--setto-chat-ink) 10%,transparent);border-radius:24px;background:var(--setto-chat-canvas);box-shadow:0 8px 24px -16px color-mix(in srgb,var(--setto-chat-ink) 28%,transparent);transition:padding 220ms cubic-bezier(.16,1,.3,1),border-color 200ms ease,box-shadow 360ms cubic-bezier(.16,1,.3,1)}.setto-chat__composer.is-open{padding:.55rem .5rem}.setto-chat__composer:focus-within{border-color:var(--setto-chat-accent)}.setto-chat__composer textarea,.setto-chat__composer textarea:hover,.setto-chat__composer textarea:focus,.setto-chat__composer textarea:focus-visible{width:100%;min-height:36px;max-height:
|
|
36508
|
+
.setto-chat__composer-shell{position:absolute;left:0;right:0;bottom:0;z-index:25;display:grid;grid-template-columns:minmax(0,1fr);padding:1.5rem .75rem 0;background:transparent;isolation:isolate}.setto-chat__composer-shell::before{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(to bottom,transparent 0%,color-mix(in srgb,var(--setto-chat-canvas) 82%,transparent) 46%,var(--setto-chat-canvas) 66%);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);-webkit-mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.4) 34%,rgba(0,0,0,1) 66%);mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.4) 34%,rgba(0,0,0,1) 66%)}.setto-chat__composer{position:relative;z-index:1;display:flex;flex-direction:column;gap:.15rem;width:100%;min-width:0;margin:0;padding:.35rem .4rem;border:2px solid color-mix(in srgb,var(--setto-chat-ink) 10%,transparent);border-radius:24px;background:var(--setto-chat-canvas);box-shadow:0 8px 24px -16px color-mix(in srgb,var(--setto-chat-ink) 28%,transparent);transition:padding 220ms cubic-bezier(.16,1,.3,1),border-color 200ms ease,box-shadow 360ms cubic-bezier(.16,1,.3,1)}.setto-chat__composer.is-open{padding:.55rem .5rem}.setto-chat__composer:focus-within{border-color:var(--setto-chat-accent)}.setto-chat__composer textarea,.setto-chat__composer textarea:hover,.setto-chat__composer textarea:focus,.setto-chat__composer textarea:focus-visible{width:100%;min-height:36px;max-height:${MAX_COMPOSER_HEIGHT}px;overflow-y:auto;padding:.45rem .25rem;resize:none;-webkit-appearance:none!important;appearance:none!important;border:0!important;border-radius:0!important;outline:0!important;box-shadow:none!important;background:transparent!important;color:var(--setto-chat-ink);font-family:"Archivo Variable",Archivo,system-ui,sans-serif;font-size:16px;line-height:1.35;transition:min-height 220ms cubic-bezier(.16,1,.3,1)}.setto-chat__composer.is-open textarea{min-height:40px}.setto-chat__composer textarea::placeholder{color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent)}.setto-chat__composer textarea::-webkit-scrollbar{width:6px}.setto-chat__composer textarea::-webkit-scrollbar-track{background:transparent}.setto-chat__composer textarea::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--setto-chat-ink) 24%,transparent)}.setto-chat__composer textarea::-webkit-scrollbar-button{display:none;height:0}@supports not selector(::-webkit-scrollbar){.setto-chat__composer textarea{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--setto-chat-ink) 24%,transparent) transparent}}.setto-chat__composer-tools{display:flex;align-items:center;gap:.4rem;width:100%;min-width:0}.setto-chat__attach{flex:none;width:34px;height:34px;padding:0;border:0;border-radius:50%;background:transparent;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background 160ms ease,color 160ms ease}.setto-chat__attach:hover:not(:disabled){background:color-mix(in srgb,var(--setto-chat-ink) 6%,transparent);color:var(--setto-chat-ink)}.setto-chat__attach:disabled{opacity:.4;cursor:default}.setto-chat__send{flex:none;width:36px;height:36px;margin-left:auto;padding:0;border:0;border-radius:50%;background:var(--setto-chat-accent);color:var(--setto-chat-raised);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:transform 360ms cubic-bezier(.16,1,.3,1),box-shadow 360ms cubic-bezier(.16,1,.3,1),background 200ms ease,opacity 200ms ease}.setto-chat__send:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 12px 24px -12px color-mix(in srgb,var(--setto-chat-ink) 45%,transparent)}.setto-chat__send:active:not(:disabled){transform:translateY(0);box-shadow:0 4px 10px -8px color-mix(in srgb,var(--setto-chat-ink) 40%,transparent);transition-duration:90ms}.setto-chat__send:disabled{opacity:.35;cursor:default}.setto-chat__send.is-queued{animation:setto-chat-queued 1.1s ease-in-out infinite}.setto-chat__attachments{display:flex;flex-wrap:wrap;gap:.4rem;list-style:none;margin:0;padding:.15rem .15rem 0}.setto-chat__attachments li{position:relative;width:56px;height:56px;border-radius:10px;overflow:hidden;border:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);background:var(--setto-chat-crema)}.setto-chat__attachments img{display:block;width:100%;height:100%;object-fit:cover}.setto-chat__attachments button{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:0;border-radius:50%;background:color-mix(in srgb,var(--setto-chat-ink) 72%,transparent);color:#fff;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.setto-chat__composer-floor{position:relative;z-index:1;width:calc(100% + 1.5rem);height:max(.35rem,env(safe-area-inset-bottom));margin-left:-.75rem;background:var(--setto-chat-canvas)}
|
|
36063
36509
|
.setto-chat__launcher{width:58px;height:58px;padding:3px;border:1px solid rgba(255,255,255,.54);border-radius:50%;background:color-mix(in srgb,var(--setto-chat-raised) 35%,transparent);box-shadow:0 10px 30px color-mix(in srgb,var(--setto-chat-ink) 24%,transparent),inset 0 0 0 1px color-mix(in srgb,var(--setto-chat-ink) 9%,transparent);backdrop-filter:blur(14px) saturate(115%);-webkit-backdrop-filter:blur(14px) saturate(115%);color:var(--setto-chat-ink);display:grid;place-items:center;cursor:pointer;transition:transform 180ms ease,box-shadow 180ms ease}.setto-chat__launcher:hover{transform:translateY(-2px);box-shadow:0 15px 35px color-mix(in srgb,var(--setto-chat-ink) 28%,transparent),inset 0 0 0 1px color-mix(in srgb,var(--setto-chat-ink) 9%,transparent)}.setto-chat__launcher span{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;background:var(--setto-chat-accent);color:var(--setto-chat-raised)}.setto-chat__launcher img{display:block;width:50px;height:50px;border-radius:50%;object-fit:cover}.setto-chat__launcher:focus-visible,.setto-chat button:focus-visible,.setto-chat input:focus-visible{outline:2px solid var(--setto-chat-accent);outline-offset:2px}@keyframes setto-chat-pulse{50%{opacity:.35}}@keyframes setto-chat-queued{50%{opacity:.55}}
|
|
36064
36510
|
@media(max-width:700px){.setto-chat__chats{position:absolute;inset:0 auto 0 0;transform:translateX(-100%);transition:transform 260ms cubic-bezier(.16,1,.3,1);box-shadow:14px 0 35px color-mix(in srgb,var(--setto-chat-ink) 16%,transparent)}.setto-chat__chats--open{transform:none}.setto-chat__main{width:100%;max-width:none;margin:0}.setto-chat__log{padding-left:.75rem;padding-right:.75rem}}@media(min-width:701px){.setto-chat--mounted{top:auto;right:max(18px,env(safe-area-inset-right));bottom:max(18px,env(safe-area-inset-bottom));left:auto;width:min(440px,calc(100vw - 36px));height:min(720px,calc(100dvh - 36px));overflow:visible;background:transparent}.setto-chat__shell{position:relative;top:auto;left:auto;width:100%;height:100%;border:1px solid color-mix(in srgb,var(--setto-chat-ink) 14%,transparent);border-radius:26px;background:var(--setto-chat-canvas);box-shadow:0 28px 80px -24px color-mix(in srgb,var(--setto-chat-ink) 42%,transparent),0 8px 24px -12px color-mix(in srgb,var(--setto-chat-ink) 24%,transparent);transform:translateY(16px) scale(.975);transform-origin:right bottom}.setto-chat--visible .setto-chat__shell{transform:none}.setto-chat__chats{position:absolute;inset:0 auto 0 0;width:min(82%,280px);height:100%;transform:translateX(-100%);transition:transform 260ms cubic-bezier(.16,1,.3,1);box-shadow:14px 0 35px color-mix(in srgb,var(--setto-chat-ink) 16%,transparent)}.setto-chat__chats--open{transform:none}.setto-chat__main{width:100%;max-width:none;margin:0}.setto-chat__header,.setto-chat__log{padding-left:.9rem;padding-right:.9rem}.setto-chat__composer-shell{padding-left:.9rem;padding-right:.9rem}.setto-chat__composer-floor{width:calc(100% + 1.8rem);height:.45rem;margin-left:-.9rem}.setto-chat__message{font-size:15.5px}.setto-chat__message-stack{max-width:82%}}@media(prefers-reduced-motion:reduce){.setto-chat,.setto-chat__shell,.setto-chat__chats,.setto-chat__launcher,.setto-chat__composer,.setto-chat__composer textarea,.setto-chat__send{transition:none!important}.setto-chat__typing,.setto-chat__send.is-queued{animation:none}}
|
|
36065
36511
|
`;
|
|
@@ -36141,14 +36587,16 @@ function SettoProvider({ config, children }) {
|
|
|
36141
36587
|
const storeRef = useRef(null);
|
|
36142
36588
|
const themeStoreRef = useRef(null);
|
|
36143
36589
|
const assetStoreRef = useRef(null);
|
|
36590
|
+
const pageStoreRef = useRef(null);
|
|
36144
36591
|
const [storeReady, setStoreReady] = useState(false);
|
|
36145
36592
|
useEffect(() => {
|
|
36146
36593
|
if (!i18n) return;
|
|
36147
36594
|
storeRef.current = new I18nStore(i18n);
|
|
36148
36595
|
themeStoreRef.current = new ThemeStore(config.theme ?? {});
|
|
36149
36596
|
assetStoreRef.current = new AssetStore();
|
|
36597
|
+
pageStoreRef.current = new PageStore(bundledManifest(config.pages));
|
|
36150
36598
|
setStoreReady(true);
|
|
36151
|
-
}, [i18n, config.theme]);
|
|
36599
|
+
}, [i18n, config.theme, config.pages]);
|
|
36152
36600
|
const editMode = !!session && access.currentSite?.status === "live" && !onAdminRoute && !authLoading && !access.loading;
|
|
36153
36601
|
const [selectedSectionId, setSelectedSectionId] = useState(null);
|
|
36154
36602
|
const selectSection = useCallback((id) => setSelectedSectionId(id), []);
|
|
@@ -36172,6 +36620,7 @@ function SettoProvider({ config, children }) {
|
|
|
36172
36620
|
store: storeReady ? storeRef.current : null,
|
|
36173
36621
|
themeStore: storeReady ? themeStoreRef.current : null,
|
|
36174
36622
|
assetStore: storeReady ? assetStoreRef.current : null,
|
|
36623
|
+
pageStore: storeReady ? pageStoreRef.current : null,
|
|
36175
36624
|
selectedSectionId,
|
|
36176
36625
|
selectSection,
|
|
36177
36626
|
guestEdit,
|
|
@@ -37060,6 +37509,8 @@ function SettoImage({ srcKey, alt, className, style, ...rest }) {
|
|
|
37060
37509
|
const fileRef = useRef(null);
|
|
37061
37510
|
const [hovered, setHovered] = useState(false);
|
|
37062
37511
|
const [uploading, setUploading] = useState(false);
|
|
37512
|
+
const imgRef = useRef(null);
|
|
37513
|
+
const Tools = useSettoChromeSlot("image-tools");
|
|
37063
37514
|
const [, force] = useState(0);
|
|
37064
37515
|
useEffect(() => {
|
|
37065
37516
|
if (!store) return;
|
|
@@ -37083,10 +37534,8 @@ function SettoImage({ srcKey, alt, className, style, ...rest }) {
|
|
|
37083
37534
|
e.preventDefault();
|
|
37084
37535
|
if (!uploading) fileRef.current?.click();
|
|
37085
37536
|
};
|
|
37086
|
-
const
|
|
37087
|
-
|
|
37088
|
-
e.target.value = "";
|
|
37089
|
-
if (!file || !assetStore || !store) return;
|
|
37537
|
+
const applyFile = async (file) => {
|
|
37538
|
+
if (!assetStore || !store) return;
|
|
37090
37539
|
setUploading(true);
|
|
37091
37540
|
try {
|
|
37092
37541
|
const originalPublicPath = store.original(srcKey, i18n.language);
|
|
@@ -37103,6 +37552,18 @@ function SettoImage({ srcKey, alt, className, style, ...rest }) {
|
|
|
37103
37552
|
setUploading(false);
|
|
37104
37553
|
}
|
|
37105
37554
|
};
|
|
37555
|
+
const handleFile = async (e) => {
|
|
37556
|
+
const file = e.target.files?.[0];
|
|
37557
|
+
e.target.value = "";
|
|
37558
|
+
if (file) await applyFile(file);
|
|
37559
|
+
};
|
|
37560
|
+
const revert2 = () => {
|
|
37561
|
+
if (!assetStore || !store) return;
|
|
37562
|
+
const original = assetStore.revert(srcKey);
|
|
37563
|
+
if (original !== null) {
|
|
37564
|
+
setSrcAllLanguages(store, i18n, srcKey, original);
|
|
37565
|
+
}
|
|
37566
|
+
};
|
|
37106
37567
|
const handleRevert = (e) => {
|
|
37107
37568
|
e.stopPropagation();
|
|
37108
37569
|
e.preventDefault();
|
|
@@ -37117,6 +37578,7 @@ function SettoImage({ srcKey, alt, className, style, ...rest }) {
|
|
|
37117
37578
|
"span",
|
|
37118
37579
|
{
|
|
37119
37580
|
"data-setto-image": true,
|
|
37581
|
+
"data-setto-src-key": srcKey,
|
|
37120
37582
|
"data-setto-ui": true,
|
|
37121
37583
|
onMouseEnter: () => setHovered(true),
|
|
37122
37584
|
onMouseLeave: () => setHovered(false),
|
|
@@ -37130,8 +37592,21 @@ function SettoImage({ srcKey, alt, className, style, ...rest }) {
|
|
|
37130
37592
|
borderRadius: 4
|
|
37131
37593
|
},
|
|
37132
37594
|
children: [
|
|
37133
|
-
/* @__PURE__ */ jsx("img", { src, alt, className, style, ...rest }),
|
|
37134
|
-
|
|
37595
|
+
/* @__PURE__ */ jsx("img", { ref: imgRef, src, alt, className, style, ...rest }),
|
|
37596
|
+
Tools ? /* @__PURE__ */ jsx(
|
|
37597
|
+
Tools,
|
|
37598
|
+
{
|
|
37599
|
+
srcKey,
|
|
37600
|
+
alt,
|
|
37601
|
+
hovered,
|
|
37602
|
+
hasDraft: Boolean(previewUrl),
|
|
37603
|
+
busy: uploading,
|
|
37604
|
+
imageEl: imgRef.current,
|
|
37605
|
+
applyFile,
|
|
37606
|
+
revert: revert2
|
|
37607
|
+
}
|
|
37608
|
+
) : null,
|
|
37609
|
+
previewUrl && !hovered && !Tools ? /* @__PURE__ */ jsx(
|
|
37135
37610
|
"span",
|
|
37136
37611
|
{
|
|
37137
37612
|
"aria-hidden": true,
|
|
@@ -37151,7 +37626,7 @@ function SettoImage({ srcKey, alt, className, style, ...rest }) {
|
|
|
37151
37626
|
children: "Nytt bilde"
|
|
37152
37627
|
}
|
|
37153
37628
|
) : null,
|
|
37154
|
-
hovered ? /* @__PURE__ */ jsxs(
|
|
37629
|
+
hovered && !Tools ? /* @__PURE__ */ jsxs(
|
|
37155
37630
|
"span",
|
|
37156
37631
|
{
|
|
37157
37632
|
"data-setto-ui": true,
|
|
@@ -38362,6 +38837,193 @@ const iframeStyle = {
|
|
|
38362
38837
|
height: "100%",
|
|
38363
38838
|
border: 0
|
|
38364
38839
|
};
|
|
38840
|
+
function usePageManifest() {
|
|
38841
|
+
const { pageStore, config } = useSetto();
|
|
38842
|
+
const snap = useSyncExternalStore(
|
|
38843
|
+
(cb) => pageStore?.subscribe(() => cb()) ?? (() => {
|
|
38844
|
+
}),
|
|
38845
|
+
() => pageStore?.snapshot() ?? EMPTY_PAGE_STORE_SNAPSHOT,
|
|
38846
|
+
() => pageStore?.snapshot() ?? EMPTY_PAGE_STORE_SNAPSHOT
|
|
38847
|
+
);
|
|
38848
|
+
return pageStore ? snap.manifest : bundledManifest(config.pages);
|
|
38849
|
+
}
|
|
38850
|
+
function useSettoMenu(list2 = "menu") {
|
|
38851
|
+
const manifest = usePageManifest();
|
|
38852
|
+
return manifest ? visibleMenu(manifest, list2) : null;
|
|
38853
|
+
}
|
|
38854
|
+
function SettoPage({ pageId, path: path2, sections = {}, builtins, fallback = null }) {
|
|
38855
|
+
const manifest = usePageManifest();
|
|
38856
|
+
const { editMode } = useSetto();
|
|
38857
|
+
if (!manifest) {
|
|
38858
|
+
if (!pageId && path2 !== void 0 && path2 !== "/" && path2 !== "") return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
38859
|
+
return /* @__PURE__ */ jsx(Fragment, { children: Object.entries(sections).map(([id, Component]) => /* @__PURE__ */ jsx(Component, {}, id)) });
|
|
38860
|
+
}
|
|
38861
|
+
const page = pageId ? pageById(manifest, pageId) : pageForPath(manifest, path2 ?? "/");
|
|
38862
|
+
if (!page) {
|
|
38863
|
+
if (pageId) {
|
|
38864
|
+
return /* @__PURE__ */ jsx(Fragment, { children: Object.entries(sections).map(([id, Component]) => /* @__PURE__ */ jsx(Component, {}, id)) });
|
|
38865
|
+
}
|
|
38866
|
+
return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
38867
|
+
}
|
|
38868
|
+
if (page.hidden && !editMode) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
38869
|
+
return /* @__PURE__ */ jsx(PageBody, { page, sections, builtins, editMode, manifest });
|
|
38870
|
+
}
|
|
38871
|
+
function PageBody({
|
|
38872
|
+
page,
|
|
38873
|
+
sections,
|
|
38874
|
+
builtins,
|
|
38875
|
+
editMode,
|
|
38876
|
+
manifest
|
|
38877
|
+
}) {
|
|
38878
|
+
usePageTitle(page);
|
|
38879
|
+
const HiddenPageNote = useSettoChromeSlot("hidden-page");
|
|
38880
|
+
const listed = new Set(manifest.pages.flatMap((p) => p.sections.map((s) => s.id)));
|
|
38881
|
+
const unlisted = Object.keys(sections).filter((id) => !listed.has(id));
|
|
38882
|
+
const firstVisible = page.sections.find((s) => !s.hidden && (s.type || sections[s.id]))?.id;
|
|
38883
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38884
|
+
page.hidden && editMode ? HiddenPageNote ? /* @__PURE__ */ jsx(HiddenPageNote, { pageId: page.id }) : /* @__PURE__ */ jsx(HiddenNote, { text: "Denne siden er skjult for besøkende." }) : null,
|
|
38885
|
+
page.sections.map((section) => /* @__PURE__ */ jsx(Fragment$1, { children: renderSection(section, sections, builtins, editMode, section.id === firstVisible) }, section.id)),
|
|
38886
|
+
unlisted.map((id) => {
|
|
38887
|
+
const Component = sections[id];
|
|
38888
|
+
return /* @__PURE__ */ jsx(Component, {}, id);
|
|
38889
|
+
})
|
|
38890
|
+
] });
|
|
38891
|
+
}
|
|
38892
|
+
function renderSection(section, sections, builtins, editMode, first) {
|
|
38893
|
+
if (section.hidden) {
|
|
38894
|
+
return editMode ? /* @__PURE__ */ jsx(HiddenSection, { section }) : null;
|
|
38895
|
+
}
|
|
38896
|
+
if (section.type) {
|
|
38897
|
+
const Builtin = builtins?.[section.type] ?? BUILTIN_RENDERERS[section.type];
|
|
38898
|
+
return /* @__PURE__ */ jsx(Builtin, { sectionId: section.id, first });
|
|
38899
|
+
}
|
|
38900
|
+
const Component = sections[section.id];
|
|
38901
|
+
if (!Component) {
|
|
38902
|
+
warnOnce(section.id);
|
|
38903
|
+
return null;
|
|
38904
|
+
}
|
|
38905
|
+
return /* @__PURE__ */ jsx(Component, {});
|
|
38906
|
+
}
|
|
38907
|
+
const warned = /* @__PURE__ */ new Set();
|
|
38908
|
+
function warnOnce(id) {
|
|
38909
|
+
if (warned.has(id)) return;
|
|
38910
|
+
warned.add(id);
|
|
38911
|
+
console.warn(`[setto] section "${id}" is in pages.json but the page does not provide it`);
|
|
38912
|
+
}
|
|
38913
|
+
function HiddenSection({ section }) {
|
|
38914
|
+
const { pageStore } = useSetto();
|
|
38915
|
+
const Offered = useSettoChromeSlot("hidden-section");
|
|
38916
|
+
const label = section.label ?? section.id;
|
|
38917
|
+
if (Offered) return /* @__PURE__ */ jsx(Offered, { sectionId: section.id, label });
|
|
38918
|
+
return /* @__PURE__ */ jsxs("div", { "data-setto-ui": true, style: hiddenBarStyle, children: [
|
|
38919
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
38920
|
+
"Skjult: ",
|
|
38921
|
+
label
|
|
38922
|
+
] }),
|
|
38923
|
+
pageStore ? /* @__PURE__ */ jsx(
|
|
38924
|
+
"button",
|
|
38925
|
+
{
|
|
38926
|
+
type: "button",
|
|
38927
|
+
"data-setto-ui": true,
|
|
38928
|
+
style: hiddenBtnStyle,
|
|
38929
|
+
onClick: () => pageStore.apply([{ op: "show_section", sectionId: section.id }]),
|
|
38930
|
+
children: "Vis"
|
|
38931
|
+
}
|
|
38932
|
+
) : null
|
|
38933
|
+
] });
|
|
38934
|
+
}
|
|
38935
|
+
function HiddenNote({ text: text2 }) {
|
|
38936
|
+
return /* @__PURE__ */ jsx("div", { "data-setto-ui": true, style: hiddenBarStyle, children: /* @__PURE__ */ jsx("span", { children: text2 }) });
|
|
38937
|
+
}
|
|
38938
|
+
function usePageTitle(page) {
|
|
38939
|
+
const { t } = useTranslation();
|
|
38940
|
+
const original = useRef(null);
|
|
38941
|
+
const title = page.path === "/" ? null : t(page.titleKey);
|
|
38942
|
+
useEffect(() => {
|
|
38943
|
+
if (!title || typeof document === "undefined") return;
|
|
38944
|
+
original.current ??= document.title;
|
|
38945
|
+
const base = original.current;
|
|
38946
|
+
document.title = base ? `${title} · ${base}` : title;
|
|
38947
|
+
return () => {
|
|
38948
|
+
document.title = base;
|
|
38949
|
+
};
|
|
38950
|
+
}, [title]);
|
|
38951
|
+
}
|
|
38952
|
+
function SettoTextSection({ sectionId, first }) {
|
|
38953
|
+
const keys2 = builtinKeys(sectionId);
|
|
38954
|
+
const { i18n } = useTranslation();
|
|
38955
|
+
const { store, editMode } = useSetto();
|
|
38956
|
+
const intro2 = store ? store.get(keys2.intro, i18n.language) : i18n.t(keys2.intro, { defaultValue: "" });
|
|
38957
|
+
const Heading = first ? "h1" : "h2";
|
|
38958
|
+
return /* @__PURE__ */ jsx(SettoSection, { sectionId, style: textSectionStyle, children: /* @__PURE__ */ jsxs("div", { style: textInnerStyle, children: [
|
|
38959
|
+
/* @__PURE__ */ jsx(Heading, { style: first ? textH1Style : textH2Style, children: /* @__PURE__ */ jsx(T, { k: keys2.heading }) }),
|
|
38960
|
+
intro2 || editMode ? /* @__PURE__ */ jsx("p", { style: textIntroStyle, children: /* @__PURE__ */ jsx(T, { k: keys2.intro }) }) : null,
|
|
38961
|
+
/* @__PURE__ */ jsx(
|
|
38962
|
+
SettoRepeater,
|
|
38963
|
+
{
|
|
38964
|
+
itemsKey: keys2.items,
|
|
38965
|
+
defaultItem: { heading: "Overskrift", text: "Tekst" },
|
|
38966
|
+
itemLabel: "avsnitt",
|
|
38967
|
+
children: (itemKey) => /* @__PURE__ */ jsx(TextItem, { sectionId, itemKey })
|
|
38968
|
+
}
|
|
38969
|
+
)
|
|
38970
|
+
] }) });
|
|
38971
|
+
}
|
|
38972
|
+
function TextItem({ sectionId, itemKey }) {
|
|
38973
|
+
const keys2 = builtinKeys(sectionId);
|
|
38974
|
+
const { i18n } = useTranslation();
|
|
38975
|
+
const { store, editMode } = useSetto();
|
|
38976
|
+
const heading2 = store ? store.get(keys2.itemHeading(itemKey), i18n.language) : i18n.t(keys2.itemHeading(itemKey), { defaultValue: "" });
|
|
38977
|
+
return /* @__PURE__ */ jsxs("div", { style: textItemStyle, children: [
|
|
38978
|
+
heading2 || editMode ? /* @__PURE__ */ jsx("h3", { style: textH3Style, children: /* @__PURE__ */ jsx(T, { k: keys2.itemHeading(itemKey) }) }) : null,
|
|
38979
|
+
/* @__PURE__ */ jsx("p", { style: textParagraphStyle, children: /* @__PURE__ */ jsx(T, { k: keys2.itemText(itemKey) }) })
|
|
38980
|
+
] });
|
|
38981
|
+
}
|
|
38982
|
+
const BUILTIN_RENDERERS = {
|
|
38983
|
+
text: SettoTextSection
|
|
38984
|
+
};
|
|
38985
|
+
const textSectionStyle = { padding: "clamp(48px, 8vw, 96px) 16px" };
|
|
38986
|
+
const textInnerStyle = { maxWidth: "68ch", margin: "0 auto" };
|
|
38987
|
+
const textH1Style = {
|
|
38988
|
+
fontFamily: "var(--setto-display-font, inherit)",
|
|
38989
|
+
fontSize: "clamp(2rem, 4vw, 2.75rem)",
|
|
38990
|
+
lineHeight: 1.15,
|
|
38991
|
+
fontWeight: 600,
|
|
38992
|
+
margin: "0 0 0.75em"
|
|
38993
|
+
};
|
|
38994
|
+
const textH2Style = { ...textH1Style, fontSize: "clamp(1.5rem, 3vw, 2rem)" };
|
|
38995
|
+
const textH3Style = {
|
|
38996
|
+
fontFamily: "var(--setto-display-font, inherit)",
|
|
38997
|
+
fontSize: "1.125rem",
|
|
38998
|
+
lineHeight: 1.3,
|
|
38999
|
+
fontWeight: 600,
|
|
39000
|
+
margin: "0 0 0.4em"
|
|
39001
|
+
};
|
|
39002
|
+
const textIntroStyle = { fontSize: "1.125rem", lineHeight: 1.6, opacity: 0.85, margin: "0 0 2em" };
|
|
39003
|
+
const textItemStyle = { margin: "0 0 1.75em" };
|
|
39004
|
+
const textParagraphStyle = { lineHeight: 1.7, margin: 0, whiteSpace: "pre-line" };
|
|
39005
|
+
const hiddenBarStyle = {
|
|
39006
|
+
display: "flex",
|
|
39007
|
+
alignItems: "center",
|
|
39008
|
+
justifyContent: "center",
|
|
39009
|
+
gap: 12,
|
|
39010
|
+
padding: "10px 16px",
|
|
39011
|
+
margin: "4px 0",
|
|
39012
|
+
border: "1px dashed rgba(100, 10, 255, 0.45)",
|
|
39013
|
+
borderRadius: 8,
|
|
39014
|
+
background: "rgba(100, 10, 255, 0.05)",
|
|
39015
|
+
color: "#3b2a66",
|
|
39016
|
+
font: '500 13px system-ui, -apple-system, "Segoe UI", sans-serif'
|
|
39017
|
+
};
|
|
39018
|
+
const hiddenBtnStyle = {
|
|
39019
|
+
border: "none",
|
|
39020
|
+
borderRadius: 999,
|
|
39021
|
+
padding: "4px 12px",
|
|
39022
|
+
background: "#640AFF",
|
|
39023
|
+
color: "#fff",
|
|
39024
|
+
font: '600 12px system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
39025
|
+
cursor: "pointer"
|
|
39026
|
+
};
|
|
38365
39027
|
const DEFAULT_DURATION = {
|
|
38366
39028
|
fadeIn: 600,
|
|
38367
39029
|
slideUp: 700,
|
|
@@ -39324,15 +39986,21 @@ export {
|
|
|
39324
39986
|
AuthGate,
|
|
39325
39987
|
BLOCK_REGISTRY,
|
|
39326
39988
|
BLOCK_TYPES,
|
|
39989
|
+
BUILTIN_SECTION_TYPES,
|
|
39327
39990
|
CHECKOUT_INTENT,
|
|
39328
39991
|
DEFAULT_LANGUAGE,
|
|
39329
39992
|
EMPTY_I18N_STORE_SNAPSHOT,
|
|
39993
|
+
EMPTY_PAGE_STORE_SNAPSHOT,
|
|
39330
39994
|
FAB_INSET,
|
|
39331
39995
|
FAB_SIZE,
|
|
39332
39996
|
FORM_FIELD_TYPES,
|
|
39333
39997
|
FORM_FIELD_TYPE_LABELS,
|
|
39334
39998
|
FloatingPopover,
|
|
39335
39999
|
GuestEditProvider,
|
|
40000
|
+
ManifestError,
|
|
40001
|
+
PAGES_MANIFEST_VERSION,
|
|
40002
|
+
PAGES_PATH,
|
|
40003
|
+
PageStore,
|
|
39336
40004
|
SETTO_BASE,
|
|
39337
40005
|
SETTO_MODULES,
|
|
39338
40006
|
SettoAdminApp,
|
|
@@ -39348,42 +40016,59 @@ export {
|
|
|
39348
40016
|
SettoLanguages,
|
|
39349
40017
|
SettoMap,
|
|
39350
40018
|
SettoMark,
|
|
40019
|
+
SettoPage,
|
|
39351
40020
|
SettoProvider,
|
|
39352
40021
|
SettoRepeater,
|
|
39353
40022
|
SettoSection,
|
|
40023
|
+
SettoTextSection,
|
|
39354
40024
|
SettoVideo,
|
|
39355
40025
|
T,
|
|
39356
40026
|
adminRedirectUrl,
|
|
39357
40027
|
adminViewUrl,
|
|
39358
40028
|
alternateLinks,
|
|
40029
|
+
applyOp,
|
|
40030
|
+
applyOps,
|
|
40031
|
+
builtinKeys,
|
|
39359
40032
|
checkoutIntentUrl,
|
|
40033
|
+
countChanges,
|
|
39360
40034
|
currentAdminView,
|
|
39361
40035
|
extractContentKeys,
|
|
39362
40036
|
fieldTypeHasOptions,
|
|
39363
40037
|
fieldTypeHasPlaceholder,
|
|
40038
|
+
findSection,
|
|
39364
40039
|
formFieldsPrefix,
|
|
39365
40040
|
isAdminDeploymentView,
|
|
39366
40041
|
isAdminPanelView,
|
|
39367
40042
|
isAdminRoute,
|
|
39368
40043
|
isFormFieldType,
|
|
39369
40044
|
isLinkContext,
|
|
40045
|
+
isSafeHref,
|
|
39370
40046
|
languageFromPath,
|
|
39371
40047
|
languageName,
|
|
39372
40048
|
nodeChildren,
|
|
40049
|
+
normalisePath,
|
|
40050
|
+
pageById,
|
|
40051
|
+
pageForPath,
|
|
40052
|
+
pageTitleKey,
|
|
39373
40053
|
parseBlockTree,
|
|
40054
|
+
parseManifest,
|
|
39374
40055
|
pathForLanguage,
|
|
39375
40056
|
pickInitialLanguage,
|
|
39376
40057
|
readLocaleFields,
|
|
39377
40058
|
redirectForVisitor,
|
|
40059
|
+
serialiseManifest,
|
|
39378
40060
|
settoSubmissionUrl,
|
|
39379
40061
|
siteHomeUrl,
|
|
39380
40062
|
siteLanguages,
|
|
39381
40063
|
useCoarsePointer,
|
|
39382
40064
|
useGuestEdit,
|
|
40065
|
+
usePageManifest,
|
|
39383
40066
|
useSectionTheme,
|
|
39384
40067
|
useSetto,
|
|
39385
40068
|
useSettoChromeSlot,
|
|
40069
|
+
useSettoMenu,
|
|
39386
40070
|
validateBlockTree,
|
|
40071
|
+
visibleMenu,
|
|
39387
40072
|
wantsCheckout,
|
|
39388
40073
|
withoutCheckoutIntent
|
|
39389
40074
|
};
|