@panphora/clayjs 1.11.3 → 1.12.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/README.md +3 -1
- package/dist/clay.standalone.js +10417 -7665
- package/entries/clay-data.js +1 -1
- package/entries/sap.js +3 -3
- package/package.json +1 -1
- package/src/core/draft-mode.js +57 -0
- package/src/core/edit-mode.js +7 -2
- package/src/core/host-meta.js +2 -0
- package/src/core/is-edit-mode.js +27 -9
- package/src/core/page-data.js +12 -0
- package/src/core/save-core.js +22 -2
- package/src/core/save.js +2 -2
- package/src/core/unsaved-warning.js +5 -2
- package/src/lib/root-attrs.js +1 -1
- package/src/loader-logic.js +21 -2
- package/src/loader.js +10 -3
- package/src/plugins/visitor-drafts/bottom-ui.js +31 -0
- package/src/plugins/visitor-drafts/intro-style.js +19 -0
- package/src/plugins/visitor-drafts/intro.js +118 -0
- package/src/plugins/visitor-drafts/owner-chip.js +178 -0
- package/src/plugins/visitor-drafts/prompt-style.js +198 -0
- package/src/plugins/visitor-drafts/prompt.js +203 -0
- package/src/plugins/visitor-drafts/source.js +21 -0
- package/src/plugins/visitor-drafts/store.js +342 -0
- package/src/plugins/visitor-drafts/ui-memory.js +14 -0
- package/src/plugins/visitor-drafts.js +111 -0
- package/src/standalone.js +5 -0
- package/src/vendor/hyper-html-api-data.vendor.js +4 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { extractData, applyData, engine } from "../../vendor/hyper-html-api-data.vendor.js";
|
|
2
|
+
import { draftSlot, setDraftStoreFailed } from "../../core/draft-mode.js";
|
|
3
|
+
|
|
4
|
+
export const KEY_PREFIX = "clay:visitor-drafts:";
|
|
5
|
+
export const RECORD_VERSION = 1;
|
|
6
|
+
|
|
7
|
+
export function safeStorage() {
|
|
8
|
+
try { return window.localStorage; } catch { return null; }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const isPlain = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
12
|
+
|
|
13
|
+
function pathParts(label) {
|
|
14
|
+
const parts = [];
|
|
15
|
+
for (const match of label.matchAll(/([^.[\]]+)|\[(\d+)\]/g)) {
|
|
16
|
+
parts.push(match[2] !== undefined ? Number(match[2]) : match[1]);
|
|
17
|
+
}
|
|
18
|
+
return parts;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function dropPath(data, label) {
|
|
22
|
+
const parts = pathParts(label);
|
|
23
|
+
let node = data;
|
|
24
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
25
|
+
node = node?.[parts[i]];
|
|
26
|
+
if (node == null || typeof node !== "object") return;
|
|
27
|
+
}
|
|
28
|
+
if (node && typeof node === "object") delete node[parts[parts.length - 1]];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// True when everything `wanted` says is present in `got`. Extra fields in `got`
|
|
32
|
+
// (a rule the draft predates) and key order do not matter.
|
|
33
|
+
export function fitsInto(wanted, got) {
|
|
34
|
+
if (Array.isArray(wanted)) {
|
|
35
|
+
return Array.isArray(got) && got.length === wanted.length && wanted.every((item, i) => fitsInto(item, got[i]));
|
|
36
|
+
}
|
|
37
|
+
if (isPlain(wanted)) {
|
|
38
|
+
return isPlain(got) && Object.keys(wanted).every((name) => fitsInto(wanted[name], got[name]));
|
|
39
|
+
}
|
|
40
|
+
return wanted === got;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function same(a, b) {
|
|
44
|
+
return fitsInto(a, b) && fitsInto(b, a);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const hasIds = (rows) => Array.isArray(rows)
|
|
48
|
+
&& rows.every((row) => isPlain(row) && (typeof row.id === "string" || typeof row.id === "number"))
|
|
49
|
+
&& new Set(rows.map((row) => row.id)).size === rows.length;
|
|
50
|
+
|
|
51
|
+
// Fields a draft predates take the page's current value, matched by row id, so
|
|
52
|
+
// the engine pairs rows by what the visitor saved rather than by position.
|
|
53
|
+
function complete(draft, page, top = false) {
|
|
54
|
+
if (isPlain(draft) && isPlain(page)) {
|
|
55
|
+
const out = { ...draft };
|
|
56
|
+
for (const name of Object.keys(page)) {
|
|
57
|
+
if (name in draft) out[name] = complete(draft[name], page[name]);
|
|
58
|
+
else if (!top) out[name] = page[name];
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
if (hasIds(draft) && hasIds(page)) {
|
|
63
|
+
const byId = new Map(page.map((row) => [row.id, row]));
|
|
64
|
+
return draft.map((row) => (byId.has(row.id) ? complete(row, byId.get(row.id)) : row));
|
|
65
|
+
}
|
|
66
|
+
return draft;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Three-way merge of this tab's value with another tab's, from the value both
|
|
70
|
+
// started at. Top-level keys and nested objects merge per field. A list both tabs
|
|
71
|
+
// changed is a conflict, since a card moved between lists or a reorder cannot be
|
|
72
|
+
// told apart from a delete and an add: this tab's value wins.
|
|
73
|
+
export function merge3(base, mine, theirs) {
|
|
74
|
+
if (same(mine, theirs) || same(theirs, base)) return { value: mine, conflict: false };
|
|
75
|
+
if (same(mine, base)) return { value: theirs, conflict: false };
|
|
76
|
+
if (isPlain(mine) && isPlain(theirs)) {
|
|
77
|
+
const value = {};
|
|
78
|
+
let conflict = false;
|
|
79
|
+
for (const name of new Set([...Object.keys(mine), ...Object.keys(theirs)])) {
|
|
80
|
+
const part = merge3(isPlain(base) ? base[name] : undefined, mine[name], theirs[name]);
|
|
81
|
+
conflict ||= part.conflict;
|
|
82
|
+
if (part.value !== undefined) value[name] = part.value;
|
|
83
|
+
}
|
|
84
|
+
return { value, conflict };
|
|
85
|
+
}
|
|
86
|
+
return { value: mine, conflict: true };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function storageFailure(doc, error) {
|
|
90
|
+
setDraftStoreFailed(true);
|
|
91
|
+
doc.dispatchEvent(new CustomEvent("clay:drafts-store-failed", { detail: { error } }));
|
|
92
|
+
const failure = new Error("Couldn't save in this browser. Storage is full or turned off.");
|
|
93
|
+
failure.code = "draft-storage";
|
|
94
|
+
return failure;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function createStore({ doc = document, storage = safeStorage(), now = () => new Date() } = {}) {
|
|
98
|
+
const slot = draftSlot(doc);
|
|
99
|
+
const key = KEY_PREFIX + slot;
|
|
100
|
+
const rules = engine.findRulesIn(doc, "api").rules;
|
|
101
|
+
|
|
102
|
+
let lastRaw = null;
|
|
103
|
+
let base = null;
|
|
104
|
+
let unparked = null;
|
|
105
|
+
let stopped = false;
|
|
106
|
+
|
|
107
|
+
function getRaw() {
|
|
108
|
+
try { return storage ? storage.getItem(key) : null; } catch { return null; }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function parse(raw) {
|
|
112
|
+
try {
|
|
113
|
+
const parsed = JSON.parse(raw);
|
|
114
|
+
if (isPlain(parsed) && parsed.v === RECORD_VERSION && isPlain(parsed.data)) return parsed;
|
|
115
|
+
} catch {}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function read() {
|
|
120
|
+
const raw = getRaw();
|
|
121
|
+
if (raw == null) return null;
|
|
122
|
+
return { raw, record: parse(raw) };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function live() {
|
|
126
|
+
return extractData(doc, rules);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// What a save would store right now: persisted controls keep typing in their
|
|
130
|
+
// live value, which only the save capture copies into the markup.
|
|
131
|
+
function captured() {
|
|
132
|
+
const getHTML = window.clay?.getHTML;
|
|
133
|
+
if (typeof getHTML !== "function") return live();
|
|
134
|
+
return extractData(new DOMParser().parseFromString(getHTML.call(window.clay), "text/html"), rules);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function storedKeys() {
|
|
138
|
+
try {
|
|
139
|
+
if (typeof storage.keys === "function") return storage.keys();
|
|
140
|
+
const names = [];
|
|
141
|
+
for (let i = 0; i < storage.length; i++) names.push(storage.key(i));
|
|
142
|
+
return names;
|
|
143
|
+
} catch {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function snapshot() {
|
|
149
|
+
try { return JSON.stringify(captured()); } catch { return null; }
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function park(raw, { keepSlot = false } = {}) {
|
|
153
|
+
const kept = storedKeys().find((name) => name.startsWith(key + ":unreadable:") && storage.getItem(name) === raw);
|
|
154
|
+
if (kept) {
|
|
155
|
+
unparked = null;
|
|
156
|
+
if (!keepSlot) { try { storage.removeItem(key); } catch {} }
|
|
157
|
+
return kept;
|
|
158
|
+
}
|
|
159
|
+
const parkedKey = key + ":unreadable:" + now().toISOString();
|
|
160
|
+
try {
|
|
161
|
+
storage.setItem(parkedKey, raw);
|
|
162
|
+
} catch {
|
|
163
|
+
unparked = raw;
|
|
164
|
+
console.warn("visitor-drafts: this browser's saved copy no longer fits the page, and there is no room to keep it aside; nothing will be saved over it");
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
unparked = null;
|
|
168
|
+
if (!keepSlot) { try { storage.removeItem(key); } catch {} }
|
|
169
|
+
console.warn(keepSlot
|
|
170
|
+
? "visitor-drafts: part of this browser's saved copy no longer fits the page; the original was kept under"
|
|
171
|
+
: "visitor-drafts: this browser's saved copy no longer fits the page; it was kept under", parkedKey);
|
|
172
|
+
return parkedKey;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Applies `data` to a copy of the page first, so a draft that does not fit never
|
|
176
|
+
// touches the live page. Top-level keys that do not read back are dropped.
|
|
177
|
+
function fit(data) {
|
|
178
|
+
const wanted = complete(JSON.parse(JSON.stringify(data)), live(), true);
|
|
179
|
+
const dropped = [];
|
|
180
|
+
for (let attempt = 0; attempt < 4; attempt++) {
|
|
181
|
+
const trial = doc.cloneNode(true);
|
|
182
|
+
try {
|
|
183
|
+
applyData(trial, wanted, rules);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
const unknown = error?.details?.unknownKeys ?? error?.unknownKeys;
|
|
186
|
+
if (Array.isArray(unknown) && unknown.length) {
|
|
187
|
+
for (const label of unknown) dropPath(wanted, label);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const failing = Object.keys(wanted).filter((name) => {
|
|
191
|
+
try { applyData(doc.cloneNode(true), { [name]: wanted[name] }, rules); return false; } catch { return true; }
|
|
192
|
+
});
|
|
193
|
+
if (!failing.length) return null;
|
|
194
|
+
for (const name of failing) delete wanted[name];
|
|
195
|
+
dropped.push(...failing);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const got = extractData(trial, rules);
|
|
199
|
+
const misfits = Object.keys(wanted).filter((name) => !fitsInto(wanted[name], got[name]));
|
|
200
|
+
if (!misfits.length) return { data: wanted, dropped };
|
|
201
|
+
for (const name of misfits) delete wanted[name];
|
|
202
|
+
dropped.push(...misfits);
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function parkedResult(raw) {
|
|
208
|
+
const parkedKey = park(raw);
|
|
209
|
+
if (!parkedKey) lastRaw = raw;
|
|
210
|
+
base = live();
|
|
211
|
+
return parkedKey
|
|
212
|
+
? { restored: false, hadDraft: true, parked: true }
|
|
213
|
+
: { restored: false, hadDraft: true, parked: false, blocked: true };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function restore() {
|
|
217
|
+
const found = read();
|
|
218
|
+
if (!found) {
|
|
219
|
+
base = live();
|
|
220
|
+
return { restored: false, hadDraft: false };
|
|
221
|
+
}
|
|
222
|
+
if (!found.record) return parkedResult(found.raw);
|
|
223
|
+
const fitted = fit(found.record.data);
|
|
224
|
+
if (!fitted || !Object.keys(fitted.data).length) return parkedResult(found.raw);
|
|
225
|
+
applyData(doc, fitted.data, rules);
|
|
226
|
+
lastRaw = found.raw;
|
|
227
|
+
base = live();
|
|
228
|
+
if (fitted.dropped.length) {
|
|
229
|
+
const parkedKey = park(found.raw, { keepSlot: true });
|
|
230
|
+
return { restored: true, hadDraft: true, data: fitted.data, partial: true, parked: Boolean(parkedKey), blocked: !parkedKey };
|
|
231
|
+
}
|
|
232
|
+
return { restored: true, hadDraft: true, data: fitted.data };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// `base` may hold fields this page cannot read (carried from a tab on newer
|
|
236
|
+
// rules), so only what the page captures is compared.
|
|
237
|
+
function changed() {
|
|
238
|
+
if (stopped) return false;
|
|
239
|
+
try { return !fitsInto(captured(), base); } catch { return true; }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// One copy, the latest: a save that would replace another tab's change keeps it
|
|
243
|
+
// here first, and does not save at all when there is no room for it.
|
|
244
|
+
function keepConflict(raw) {
|
|
245
|
+
const conflictKey = key + ":conflict";
|
|
246
|
+
try {
|
|
247
|
+
storage.setItem(conflictKey, raw);
|
|
248
|
+
} catch (error) {
|
|
249
|
+
throw storageFailure(doc, error);
|
|
250
|
+
}
|
|
251
|
+
console.warn("visitor-drafts: another tab changed the same thing; its copy was kept under", conflictKey);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Another tab may have written since this tab last read or wrote: what only it
|
|
255
|
+
// changed is taken. Fields the stored record has and this page's rules lack (a
|
|
256
|
+
// tab opened before the owner added a field) are carried through, at any depth.
|
|
257
|
+
function merge(mine) {
|
|
258
|
+
const current = getRaw();
|
|
259
|
+
const record = current == null ? null : parse(current);
|
|
260
|
+
if (!record) return { data: mine, stored: null };
|
|
261
|
+
let data = mine;
|
|
262
|
+
if (current !== lastRaw) {
|
|
263
|
+
const merged = merge3(base, mine, record.data);
|
|
264
|
+
if (merged.conflict) keepConflict(current);
|
|
265
|
+
data = merged.value;
|
|
266
|
+
}
|
|
267
|
+
data = complete(data, record.data);
|
|
268
|
+
return { data, stored: same(data, record.data) ? current : null };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function adopt(data) {
|
|
272
|
+
const fitted = fit(data);
|
|
273
|
+
if (!fitted || !Object.keys(fitted.data).length) return null;
|
|
274
|
+
applyData(doc, fitted.data, rules);
|
|
275
|
+
try { window.Sap?.refresh?.(); } catch {}
|
|
276
|
+
doc.dispatchEvent(new CustomEvent("clay:drafts-restored", { detail: { restored: true, hadDraft: true, parked: false, external: true } }));
|
|
277
|
+
return fitted.data;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function write(html) {
|
|
281
|
+
if (stopped) return null;
|
|
282
|
+
if (unparked != null && park(unparked, { keepSlot: true }) === null) {
|
|
283
|
+
throw storageFailure(doc, new Error("an earlier saved copy could not be kept aside"));
|
|
284
|
+
}
|
|
285
|
+
const mine = extractData(new DOMParser().parseFromString(html, "text/html"), rules);
|
|
286
|
+
const current = getRaw();
|
|
287
|
+
if (fitsInto(mine, base) && (current === lastRaw || current == null)) {
|
|
288
|
+
setDraftStoreFailed(false);
|
|
289
|
+
doc.dispatchEvent(new CustomEvent("clay:drafts-saved", { detail: { data: mine, unchanged: true } }));
|
|
290
|
+
return mine;
|
|
291
|
+
}
|
|
292
|
+
const { data, stored } = merge(mine);
|
|
293
|
+
const raw = stored ?? JSON.stringify({ v: RECORD_VERSION, savedAt: now().toISOString(), data });
|
|
294
|
+
if (!stored) {
|
|
295
|
+
try {
|
|
296
|
+
if (!storage) throw new Error("no storage");
|
|
297
|
+
storage.setItem(key, raw);
|
|
298
|
+
} catch (error) {
|
|
299
|
+
throw storageFailure(doc, error);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const taken = Object.keys(mine).filter((name) => !fitsInto(mine[name], data[name]));
|
|
303
|
+
if (taken.length) adopt(Object.fromEntries(taken.map((name) => [name, data[name]])));
|
|
304
|
+
lastRaw = raw;
|
|
305
|
+
base = data;
|
|
306
|
+
setDraftStoreFailed(false);
|
|
307
|
+
doc.dispatchEvent(new CustomEvent("clay:drafts-saved", { detail: { data } }));
|
|
308
|
+
return data;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function writeLive() {
|
|
312
|
+
try { write(window.clay.getHTML()); return true; } catch { return false; }
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function flush() {
|
|
316
|
+
if (stopped || !changed()) return true;
|
|
317
|
+
return writeLive();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// A storage event can arrive late, so read the slot itself rather than trusting
|
|
321
|
+
// the event's value. A tab with its own edit merges at its next save instead.
|
|
322
|
+
function adoptExternal() {
|
|
323
|
+
if (stopped) return false;
|
|
324
|
+
const raw = getRaw();
|
|
325
|
+
if (raw == null || raw === lastRaw || changed()) return false;
|
|
326
|
+
const record = parse(raw);
|
|
327
|
+
const adopted = record && adopt(record.data);
|
|
328
|
+
if (!adopted) return false;
|
|
329
|
+
lastRaw = raw;
|
|
330
|
+
base = { ...base, ...adopted };
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function clear() {
|
|
335
|
+
stopped = true;
|
|
336
|
+
unparked = null;
|
|
337
|
+
setDraftStoreFailed(false);
|
|
338
|
+
try { storage.removeItem(key); } catch {}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return { slot, key, rules, read, restore, write, writeLive, flush, changed, adoptExternal, park, clear, snapshot };
|
|
342
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function createUiMemory(slot, storage) {
|
|
2
|
+
const key = `clay:visitor-drafts:${slot}:ui`;
|
|
3
|
+
const blank = () => ({ v: 1, prompt: {}, intro: { done: null }, src: null });
|
|
4
|
+
let mem = blank();
|
|
5
|
+
try {
|
|
6
|
+
const parsed = JSON.parse(storage?.getItem(key) || "null");
|
|
7
|
+
if (parsed && typeof parsed === "object" && parsed.v === 1) mem = { ...blank(), ...parsed };
|
|
8
|
+
} catch {}
|
|
9
|
+
return {
|
|
10
|
+
get: () => mem,
|
|
11
|
+
save() { try { storage?.setItem(key, JSON.stringify(mem)); } catch {} },
|
|
12
|
+
reset() { mem = blank(); try { storage?.removeItem(key); } catch {} },
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { isDraftMode, isEditMode, isOwner } from "../core/is-edit-mode.js";
|
|
2
|
+
import { hasSaveToken } from "../core/host-attrs.js";
|
|
3
|
+
import { draftSlot, setDraftTransport, setDraftFlush } from "../core/draft-mode.js";
|
|
4
|
+
import { createStore, safeStorage } from "./visitor-drafts/store.js";
|
|
5
|
+
import { createUiMemory } from "./visitor-drafts/ui-memory.js";
|
|
6
|
+
import { rememberSource, downloadUrl, signupTag } from "./visitor-drafts/source.js";
|
|
7
|
+
import { mountPrompt } from "./visitor-drafts/prompt.js";
|
|
8
|
+
import { mountIntro } from "./visitor-drafts/intro.js";
|
|
9
|
+
import { mountOwnerChip } from "./visitor-drafts/owner-chip.js";
|
|
10
|
+
|
|
11
|
+
const DOWNLOAD_URL = "/_/download?as=htmlclay";
|
|
12
|
+
|
|
13
|
+
let store = null;
|
|
14
|
+
let restoredDetail = null;
|
|
15
|
+
let downloadLink = DOWNLOAD_URL;
|
|
16
|
+
let source = null;
|
|
17
|
+
|
|
18
|
+
const slot = draftSlot();
|
|
19
|
+
const rulesTag = document.querySelector('script[data-rules-name~="api"]');
|
|
20
|
+
|
|
21
|
+
if (isDraftMode && slot && rulesTag) {
|
|
22
|
+
store = createStore();
|
|
23
|
+
setDraftTransport((html) => store.write(html));
|
|
24
|
+
const result = store.restore();
|
|
25
|
+
restoredDetail = { restored: result.restored, hadDraft: result.hadDraft, parked: Boolean(result.parked), ...(result.partial && { partial: true }), ...(result.blocked && { blocked: true }) };
|
|
26
|
+
document.dispatchEvent(new CustomEvent("clay:drafts-restored", { detail: restoredDetail }));
|
|
27
|
+
const memory = createUiMemory(slot, safeStorage());
|
|
28
|
+
source = rememberSource(memory);
|
|
29
|
+
downloadLink = downloadUrl(source);
|
|
30
|
+
const appName = document.querySelector('meta[name="application-name"]')?.content?.trim() || document.title.split(/:|\s\|\s/)[0].trim() || "This app";
|
|
31
|
+
const template = document.querySelector("template[visitor-intro]");
|
|
32
|
+
const start = () => {
|
|
33
|
+
const prompt = mountPrompt({ memory, appName, link: downloadLink, tag: signupTag(slot, template), source });
|
|
34
|
+
mountIntro({ memory, template, appName, hadDraft: result.hadDraft });
|
|
35
|
+
if (isOwner) mountOwnerChip();
|
|
36
|
+
document.addEventListener("clay:drafts-store-failed", () => prompt.showError());
|
|
37
|
+
document.addEventListener("clay:drafts-saved", () => prompt.clearError());
|
|
38
|
+
};
|
|
39
|
+
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", start, { once: true }) : start();
|
|
40
|
+
setDraftFlush(() => store.flush());
|
|
41
|
+
window.addEventListener("storage", (event) => { if (event.key === store.key) store.adoptExternal(); });
|
|
42
|
+
const flush = () => store.flush();
|
|
43
|
+
document.addEventListener("visibilitychange", () => { if (document.visibilityState === "hidden") flush(); });
|
|
44
|
+
window.addEventListener("pagehide", flush);
|
|
45
|
+
} else if (!slot || !rulesTag) {
|
|
46
|
+
const missing = [];
|
|
47
|
+
if (!slot) missing.push('a visitor-drafts="<slot>" attribute on <html>');
|
|
48
|
+
if (!rulesTag) missing.push('a <script data-rules-name~="api"> rules tag');
|
|
49
|
+
console.warn(`visitor-drafts: this page keeps no draft (missing ${missing.join(" and ")})`);
|
|
50
|
+
} else if (isOwner && isEditMode && !hasSaveToken()) {
|
|
51
|
+
mountOwnerChip();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const ready = Promise.resolve();
|
|
55
|
+
|
|
56
|
+
function editOriginal() {
|
|
57
|
+
const url = new URL(window.location.href);
|
|
58
|
+
url.searchParams.set("editmode", "true");
|
|
59
|
+
window.location.href = url.toString();
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function backToDraft() {
|
|
64
|
+
const url = new URL(window.location.href);
|
|
65
|
+
url.searchParams.delete("editmode");
|
|
66
|
+
window.location.href = url.toString();
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function inertVisitorDrafts() {
|
|
71
|
+
return {
|
|
72
|
+
active: false,
|
|
73
|
+
slot: null,
|
|
74
|
+
key: null,
|
|
75
|
+
hasDraft: () => false,
|
|
76
|
+
restored: () => null,
|
|
77
|
+
saveNow: () => false,
|
|
78
|
+
reset: () => false,
|
|
79
|
+
onRestore: () => false,
|
|
80
|
+
editOriginal,
|
|
81
|
+
backToDraft,
|
|
82
|
+
downloadUrl: () => DOWNLOAD_URL,
|
|
83
|
+
source: null,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const visitorDrafts = store ? {
|
|
88
|
+
active: true,
|
|
89
|
+
slot: store.slot,
|
|
90
|
+
key: store.key,
|
|
91
|
+
hasDraft: () => Boolean(store.read()),
|
|
92
|
+
restored: () => restoredDetail,
|
|
93
|
+
saveNow: () => store.writeLive(),
|
|
94
|
+
reset() {
|
|
95
|
+
store.clear();
|
|
96
|
+
window.location.reload();
|
|
97
|
+
return true;
|
|
98
|
+
},
|
|
99
|
+
onRestore(fn) {
|
|
100
|
+
if (restoredDetail) {
|
|
101
|
+
fn(restoredDetail);
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
document.addEventListener("clay:drafts-restored", (event) => fn(event.detail), { once: true });
|
|
105
|
+
return false;
|
|
106
|
+
},
|
|
107
|
+
editOriginal,
|
|
108
|
+
backToDraft,
|
|
109
|
+
downloadUrl: () => downloadLink,
|
|
110
|
+
source,
|
|
111
|
+
} : inertVisitorDrafts();
|
package/src/standalone.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
shared pieces. */
|
|
10
10
|
import { boot } from "./loader.js";
|
|
11
11
|
import onDomReady from "./lib/dom-ready.js";
|
|
12
|
+
import { noteBootParams } from "./core/draft-mode.js";
|
|
12
13
|
|
|
13
14
|
(function () {
|
|
14
15
|
// Suppress every vendored bundle's window auto-export; the loader assembles
|
|
@@ -39,6 +40,10 @@ import onDomReady from "./lib/dom-ready.js";
|
|
|
39
40
|
var script = document.currentScript;
|
|
40
41
|
var params = script && script.src ? new URL(script.src, location.href).searchParams : new URLSearchParams();
|
|
41
42
|
clay.__booted = true;
|
|
43
|
+
// Before the satellites below: the internals graph reaches core/is-edit-mode.js,
|
|
44
|
+
// which freezes its draft-mode answer as it evaluates. boot() notes the same
|
|
45
|
+
// params again, which is harmless.
|
|
46
|
+
noteBootParams(params);
|
|
42
47
|
|
|
43
48
|
function domReady() {
|
|
44
49
|
return new Promise(function (r) { onDomReady(r); });
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// GENERATED — do not edit. Vendored from
|
|
2
|
+
// hyper-html-api/dist/hyper-html-api.engine.esm.js via hyper-html-api
|
|
3
|
+
// `npm run copy-to-clayjs`. Edit the hyper-html-api source and re-run.
|
|
4
|
+
var Qe=Object.defineProperty;var et=(e,t)=>{for(var n in t)Qe(e,n,{get:t[n],enumerable:!0})};var X=["textContent","innerText","innerHTML","outerHTML","value","checked","selected","disabled","readOnly","type","tagName","nodeName","nodeType","nodeValue","childElementCount","id","className","classList","baseURI","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","dataset","currentSrc","duration","paused","title","documentURI","contentType"],Y=new Set(X),re=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),$=new Set(["tagName","nodeName","nodeType","nodeValue","childElementCount","classList","baseURI","documentURI","contentType","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","currentSrc","duration","paused","dataset"]),Ee=new Set(["checked","selected","disabled","readOnly","paused"]);function ie(e,t){return t==null?Ee.has(e)?!1:"":Ee.has(e)?t==="false"?!1:!!t:t}var R={};et(R,{EmptyListInsert:()=>N,MAX_RULE_DEPTH:()=>L,MaxRuleDepthExceeded:()=>P,NoRulesTag:()=>oe,RuleTargetReadOnly:()=>B,RulesParseError:()=>k,ShapeMismatch:()=>v,UnknownRulesVersion:()=>W,WriteNotRoundTripped:()=>Z,WriteRefused:()=>H,WriteRejected:()=>se});var k=class extends Error{constructor(t,n){super(t),this.name="RulesParseError",this.cause=n}},W=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},L=20,P=class extends Error{constructor(t){super(`rule depth exceeded ${L} at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},v=class extends Error{constructor(t){super(`shape mismatch: ${t.length} field(s) failed validation`),this.name="ShapeMismatch",this.mismatches=t}},N=class extends Error{constructor(t,n){super(n?`cannot add items to empty list at "${t.join(".")}" \u2014 ${n}`:`cannot add items to empty list at "${t.join(".")}" \u2014 no sibling to clone as template. Seed the list with a hidden item first.`),this.name="EmptyListInsert",this.path=t}},B=class extends Error{constructor(t){super(`cannot write to read-only DOM property "${t}"`),this.name="RuleTargetReadOnly",this.target=t}},H=class extends Error{constructor(t){super(`write refused: ${t.length} write(s) broke the content-only policy`),this.name="WriteRefused",this.refusals=t}};function tt(e){return e.reduce((n,r)=>typeof r=="number"?`${n}[${r}]`:n?`${n}.${r}`:String(r),"")||"(root)"}var Z=class extends Error{constructor(t){super(`write did not round-trip at "${tt(t)}"`),this.name="WriteNotRoundTripped",this.path=t}},oe=class extends Error{constructor(t){super(`no <script data-rules-name~="${t}"> rules tag in this document`),this.name="NoRulesTag",this.token=t}},se=class extends Error{constructor(t,n){super(`write rejected: ${t.length} unknown key(s), ${n.length} rule(s) with no matching element`),this.name="WriteRejected",this.unknownKeys=t,this.unmatched=n}};function b(e){let t=0,n=null,r=-1;for(let i=0;i<e.length;i++){let s=e[i];s==="\\"?i++:n?s===n&&(n=null):s==='"'||s==="'"?n=s:s==="["||s==="("?t++:s==="]"||s===")"?t>0&&t--:s==="@"&&t===0&&(r=i)}return r}function le(e){let t=b(e);return t===-1?{selector:e,prop:null}:{selector:e.slice(0,t),prop:e.slice(t+1)||null}}function ce(e){let t=0,n=null,r=-1,i=!1;for(let s=0;s<e.length;s++){let l=e[s];l==="\\"?s++:n?l===n&&(n=null):l==='"'||l==="'"?n=l:l==="["||l==="("?t++:l==="]"||l===")"?t>0&&t--:t===0&&l===">"?r=s:t===0&&l===","&&(i=!0)}return i||r===-1||!nt(e,r+1)?null:e.slice(0,r).trim()||null}function nt(e,t){let n=t,r=e.replace(/\s+$/,"").length;for(;n<r&&/\s/.test(e[n]);)n++;let i=0,s=null;for(;n<r;n++){let l=e[n];if(l==="\\")n++;else if(s)l===s&&(s=null);else if(l==='"'||l==="'")s=l;else if(l==="["||l==="(")i++;else if(l==="]"||l===")")i>0&&i--;else if(i===0&&(l==="+"||l==="~"||/\s/.test(l)))return!1}return!0}function C(e,t,n,r={}){if(Object.prototype.hasOwnProperty.call(r,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");return fe(e,t,n,{depth:0,path:[]},r)}function fe(e,t,n,r,i){if(r.depth>L)throw new P(r.path);if(typeof n=="string")return rt(e,t,n,r,i);if(Array.isArray(n)){let[s,l]=n,c=e.find(t,s,i);return xe(i,r,c),c.map((o,f)=>fe(e,o,l,{depth:r.depth+1,path:[...r.path,f]},i))}if(typeof n=="object"&&n!==null){let s={};for(let[l,c]of Object.entries(n))s[l]=fe(e,t,c,{depth:r.depth+1,path:[...r.path,l]},i);return s}return null}function rt(e,t,n,r,i){if(n.endsWith("[]")){let c=n.slice(0,-2),o=e.find(t,c,i);return xe(i,r,o),o.map(f=>e.text(f))}if(n.startsWith("@"))return Oe(e,t,n.slice(1));let s=b(n);if(s!==-1){let c=n.slice(0,s),o=n.slice(s+1),f=c?e.find(t,c,i):[t];return f.length===0?null:Oe(e,f[0],o)}if(n===".")return e.text(t);let l=e.find(t,n,i);return l.length===0?null:e.text(l[0])}function xe(e,t,n){if(typeof e.onRowsRead=="function")try{e.onRowsRead(t.path.slice(),n)}catch(r){console.warn(`[hyper-html-api] onRowsRead threw at "${t.path.join(".")||"(root)"}"`,r)}}function Oe(e,t,n){if(Y.has(n)){let i=e.prop(t,n);return i==null?null:String(i)}let r=e.attr(t,n);return r??null}function Re(e,t,n,r){let i=e.length,s=t.length,l=new Array(i).fill(-1);if(r){let h=new Set;for(let y=0;y<i;y++){let A=r[y];!(A>=0&&A<s)||h.has(A)||(l[y]=A,h.add(A))}}if(i===0||s===0)return l;let c=e.map(h=>Se(h,n)),o=t.map(h=>Se(h,n)),f=new Array(s).fill(!1);for(let h of l)h>=0&&(f[h]=!0);let u=new Map;o.forEach((h,y)=>{f[y]||u.set(h,u.has(h)?-1:y)});let m=new Map;c.forEach((h,y)=>{l[y]>=0||m.set(h,(m.get(h)||0)+1)}),c.forEach((h,y)=>{if(l[y]>=0||m.get(h)!==1)return;let A=u.get(h);A===void 0||A===-1||f[A]||(l[y]=A,f[A]=!0)});let d=[];for(let h=0;h<i;h++)l[h]<0&&d.push(h);let w=[];for(let h=0;h<s;h++)f[h]||w.push(h);if(d.length===0||w.length===0)return l;let a=i*s+1,p=it(e,t,n),g=(h,y)=>p(h,y)*a+Math.abs(h-y);for(let[h,y]of ot(d,w,g))l[h]=y;return l}var Ne=e=>typeof e=="object"&&e!==null;function Se(e,t){if(!Ne(t))return e==null?" null":String(e);let n=Object.keys(t);return JSON.stringify(n.map(r=>{let i=JSON.stringify(e?.[r]);return i===void 0?" undef":i}))}function it(e,t,n){if(!Ne(n))return(c,o)=>e[c]===t[o]?0:1;let r=Object.keys(n),i=c=>r.map(o=>JSON.stringify(c?.[o])),s=e.map(i),l=t.map(i);return(c,o)=>{let f=s[c],u=l[o],m=0;for(let d=0;d<r.length;d++)f[d]!==u[d]&&m++;return m}}function ot(e,t,n){return e.length<=t.length?be(e,t,n,!1):be(t,e,(r,i)=>n(i,r),!0)}function be(e,t,n,r){let i=e.length,s=t.length,l=[];for(let m=0;m<=i;m++)l.push(new Float64Array(s+1).fill(1/0));let c=[];for(let m=0;m<=i;m++)c.push(new Uint8Array(s+1));for(let m=0;m<=s;m++)l[i][m]=0;for(let m=i-1;m>=0;m--)for(let d=s-1;d>=0;d--){let w=n(e[m],t[d])+l[m+1][d+1],a=l[m][d+1];w<=a?(l[m][d]=w,c[m][d]=1):l[m][d]=a}let o=[],f=0,u=0;for(;f<i&&u<s;)c[f][u]&&(o.push(r?[t[u],e[f]]:[e[f],t[u]]),f++),u++;return o}function ae(e,t,n,r,i,s,l,c={}){let o=e.find(t,n,c);if(i.length===0){o.forEach(T=>e.remove(T)),ue(c,"onRowsApplied",s.path,[]);return}let f=i.length>o.length,u=o[0]||null;if(f&&!u&&(u=ft(e,t,n,c),!u))throw new N(s.path);let m=o.map(T=>ct(e,T,r,c)),d=null;if(f&&u){d=e.clone(u),c.templateAttr&&e.removeAttr(d,c.templateAttr);let T=e.stripIds(d);T>0&&console.warn(`[hyper-html-api] stripped ${T} id attribute(s) from cloned template at "${s.path.join(".")||"(root)"}"`)}let w=Re(i,m,r,st(e,o,i,s,c)),a=o.length>0?e.parent(o[0]):dt(e,t,n,u,s,c),p=o.length>0?ke(e,a,o[0]):0,g=yt(e,o),h=new Set,y=[],A=i.map((T,S)=>{let O=w[S];if(O>=0)return h.add(O),y.push(!1),o[O];y.push(!0);let E=e.clone(d);return e.stripIds(E),E});o.forEach((T,S)=>{h.has(S)||e.remove(T)}),g?mt(e,a,p,A,y):gt(e,A,y,a,p),lt(e,A,r,i,s,l,c),ue(c,"onRowsApplied",s.path,A)}function ue(e,t,n,r){if(typeof e[t]=="function")try{return e[t](n.slice(),r)}catch(i){console.warn(`[hyper-html-api] ${t} threw at "${n.join(".")||"(root)"}"`,i);return}}function st(e,t,n,r,i){let s=ue(i,"identifyRows",r.path,n);if(!Array.isArray(s))return null;let l=new Array(n.length).fill(-1),c=new Set,o=new Map(t.map((f,u)=>[e.identity(f),u]));for(let f=0;f<n.length;f++){if(!s[f])continue;let u=o.get(e.identity(s[f]));u===void 0||c.has(u)||(l[f]=u,c.add(u))}return l}function lt(e,t,n,r,i,s,l){t.forEach((c,o)=>{if(n===null){let f=r[o],u=f==null?"":String(f);e.text(c)!==u&&e.text(c,u)}else{let f=s(e,c,n,r[o],{depth:i.depth+1,path:[...i.path,o]},l);f&&f!==c&&(t[o]=f)}})}function ct(e,t,n,r){return n===null?e.text(t):C(e,t,n,r.onRowsRead?{...r,onRowsRead:void 0}:r)}function ke(e,t,n){let r=e.children(t);for(let i=0;i<r.length;i++)if(e.sameNode(r[i],n))return i;return-1}function ft(e,t,n,r){if(!r.templateAttr)return null;let i=/^\s*:scope\s*>\s*/.test(n),s=new RegExp(":not\\(\\["+r.templateAttr.replace(/[.*+?^${}()|[\]\\-]/g,"\\$&")+"\\]\\)","g"),l=n.replace(/^\s*:scope\s*>\s*/,"").replace(s,""),c=i?ut(l):0,o=ce(l),f=t;for(;f;){let u=e.find(f,l,{includeRulesTag:!1,templateAttr:null});for(let m of u)if(e.attr(m,r.templateAttr)!=null&&!(i&&!ht(e,t,m,c))&&!(o&&!e.matches(e.parent(m),o)))return m;f=e.parent(f)}return null}function ut(e){let t=0,n=null,r=1;for(let i=0;i<e.length;i++){let s=e[i];if(s==="\\")i++;else if(n)s===n&&(n=null);else if(s==='"'||s==="'")n=s;else if(s==="["||s==="(")t++;else if(s==="]"||s===")")t>0&&t--;else if(t===0&&s===">")r++;else{if(t===0&&(s==="+"||s==="~"))return null;if(t===0&&/\s/.test(s)){if(!at(e,i))return null;for(;i+1<e.length&&/\s/.test(e[i+1]);)i++}}}return r}function at(e,t){let n=t;for(;n<e.length&&/\s/.test(e[n]);)n++;let r=t>0?e[t-1]:"",i=n<e.length?e[n]:"";return Ce(r)||Ce(i)}function Ce(e){return e===">"||e==="+"||e==="~"}function ht(e,t,n,r){if(r===null)return!0;let i=n;for(let o=0;o<r;o++)if(i=e.parent(i),!i)return!1;let s=e.prop(t,"tagName");if(!s)return!0;let l=e.prop(i,"tagName");if(!l||String(l).toLowerCase()!==String(s).toLowerCase())return!1;let c=new Set(Me(e,i));return Me(e,t).every(o=>c.has(o))}function Me(e,t){let n=e.attr(t,"class");return n?String(n).split(/\s+/).filter(Boolean):[]}function dt(e,t,n,r,i,s){let l=e.parent(r);if(l&&pt(e,t,l)&&!Ie(e,l,s))return l;let c=ce(n);if(!c)throw new N(i.path,`the list selector "${n}" names no container to hold the new rows \u2014 write it as "container > row" (for example "ol.comments > li") so the cloned row lands in the list`);let f=(c===":scope"?e.prop(t,"tagName")?[t]:[]:e.find(t,c,s)).filter(u=>!Ie(e,u,s));if(f.length===0)throw new N(i.path,`no container matching "${c}" inside this context to hold the new rows`);if(f.length>1)throw new N(i.path,`"${c}" matches ${f.length} containers inside this context, so the new rows have no single destination`);return f[0]}function pt(e,t,n){let r=n;for(;r;){if(e.sameNode(r,t))return!0;r=e.parent(r)}return e.parent(t)?!1:e.find(t,"*",{includeRulesTag:!0,templateAttr:null}).some(i=>e.sameNode(i,n))}var Pe=["no-data","editor-ui"];function Ie(e,t,n){let r=t;for(;r;){if(n.templateAttr&&e.attr(r,n.templateAttr)!=null||Pe.some(s=>e.attr(r,s)!=null))return!0;let i=e.attr(r,"clay");if(i&&i.split(/\s+/).some(s=>Pe.includes(s)))return!0;r=e.parent(r)}return!1}function mt(e,t,n,r,i){let s=e.children(t),l=s.map(o=>e.identity(o)),c=!1;r.forEach((o,f)=>{let u=e.identity(o),m=n+f;if(l[m]===u)return;if(!i[f]){let w=l.indexOf(u);w!==-1&&(l.splice(w,1),s.splice(w,1))}let d=Math.min(m,s.length);d<s.length?e.insertBefore(s[d],o):s.length?c?e.insertAfter(s[s.length-1],o):(e.insertAt(t,o,m),c=!0):e.insertAt(t,o,0),l.splice(d,0,u),s.splice(d,0,o)})}function yt(e,t){if(t.length<=1)return!0;let n=e.parent(t[0]);if(!n)return!1;let r=new Map(e.children(n).map((s,l)=>[e.identity(s),l])),i=[];for(let s of t){let l=r.get(e.identity(s));if(l===void 0)return!1;i.push(l)}return i.sort((s,l)=>s-l),i[i.length-1]-i[0]===i.length-1}function gt(e,t,n,r,i){let s=null,l=i;for(let c=0;c<t.length;c++){if(!n[c]){s=t[c];continue}let o=s?e.parent(s):r;if(!o)continue;let f=s?ke(e,o,s)+1:l++;e.insertAt(o,t[c],f),s=t[c]}}function I(e,t,n,r,i={}){if(Object.prototype.hasOwnProperty.call(i,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");let s=[];if(he(n,r,[],s),s.length)throw new v(s);Q(e,t,n,r,{depth:0,path:[]},i)}function Q(e,t,n,r,i,s={}){if(i.depth>L)throw new P(i.path);if(r===void 0)return t;if(typeof n=="string")return At(e,t,n,r,i,s);if(Array.isArray(n)){let[l,c]=n;return ae(e,t,l,c,r,i,Q,s),t}if(typeof n=="object"&&n!==null){for(let[l,c]of Object.entries(n)){let o=Q(e,t,c,r==null?r:r[l],{depth:i.depth+1,path:[...i.path,l]},s);o&&o!==t&&(t=o)}return t}return t}function At(e,t,n,r,i,s){if(n.endsWith("[]")){let o=n.slice(0,-2);return ae(e,t,o,null,r,i,Q,s),t}if(n.startsWith("@"))return je(e,t,n.slice(1),r);let l=b(n);if(l!==-1){let o=n.slice(0,l),f=n.slice(l+1),u=o?e.find(t,o,s):[t];return u.length===0||je(e,u[0],f,r),t}if(n===".")return Le(e,t,r),t;let c=e.find(t,n,s);return c.length===0||Le(e,c[0],r),t}function Le(e,t,n){let r=n==null?"":String(n);e.text(t)!==r&&e.text(t,r)}function je(e,t,n,r){if($.has(n)){let i=e.prop(t,n);if(i===r||i!=null&&r!=null&&String(i)===String(r))return t;throw new B(n)}if(n==="outerHTML"){let i=r==null?"":String(r);return e.replaceWith(t,i)}if(re.has(n)){let i=ie(n,r);return e.prop(t,n)!==i&&e.prop(t,n,i),t}if(r==null)e.attr(t,n)!=null&&e.removeAttr(t,n);else{let i=String(r);e.attr(t,n)!==i&&e.attr(t,n,i)}return t}function he(e,t,n,r){if(t!==void 0){if(typeof e=="string"){if(e.endsWith("[]")){Array.isArray(t)?t.forEach((i,s)=>{typeof i=="object"&&i!==null&&r.push({path:U([...n,s]),expected:"scalar",got:q(i)})}):r.push({path:U(n),expected:"array",got:q(t)});return}t!==null&&typeof t=="object"&&r.push({path:U(n),expected:"scalar",got:q(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){r.push({path:U(n),expected:"array",got:q(t)});return}let i=e[1];t.forEach((s,l)=>he(i,s,[...n,l],r));return}if(typeof e=="object"&&e!==null){if(t===null||Array.isArray(t)||typeof t!="object"){r.push({path:U(n),expected:"object",got:q(t)});return}for(let[i,s]of Object.entries(e))he(s,t[i],[...n,i],r)}}}function q(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function U(e){return e.join(".")}function de(e){try{return JSON.parse(e)}catch(t){throw new k(`Invalid strict JSON: ${t.message}`,t)}}function z(e){try{return JSON.parse(e)}catch{}let t={BRACE_OPEN:"{",BRACE_CLOSE:"}",BRACKET_OPEN:"[",BRACKET_CLOSE:"]",COLON:":",COMMA:",",STRING:"STRING",SELECTOR:"SELECTOR",IDENTIFIER:"IDENTIFIER",NUMBER:"NUMBER",BOOLEAN:"BOOLEAN"};function n(i){let s=[],l=0;for(;l<i.length;){let c=i[l];if(/\s/.test(c)){l++;continue}if("{}".includes(c)){s.push({type:c,value:c}),l++;continue}if(c==="["){let m=!1,d=l+1;for(;d<i.length&&/\s/.test(i[d]);)d++;if(d<i.length&&/[a-zA-Z_]/.test(i[d])&&(m=!0),!m){s.push({type:c,value:c}),l++;continue}}if(c==="]"){s.push({type:c,value:c}),l++;continue}if(c===":"){s.push({type:t.COLON,value:c}),l++;continue}if(c===","){s.push({type:t.COMMA,value:c}),l++;continue}if(c==='"'||c==="'"){let m=c,d=l+1;for(;d<i.length&&i[d]!==m;)i[d]==="\\"&&d++,d++;s.push({type:t.STRING,value:i.substring(l+1,d),quoted:!0,sourceQuote:m}),l=d+1;continue}let o=l,f;for(;o<i.length&&!/[{},]/.test(i[o]);)if(i[o]===":"){let m=[":first",":last",":nth-child",":nth-of-type",":first-child",":last-child",":first-of-type",":last-of-type",":only-child",":only-of-type",":hover",":focus",":active",":visited",":disabled",":enabled",":checked",":empty",":root",":target",":not",":before",":after",":nth-last-child",":nth-last-of-type"],d=!1;for(let w of m){let a=w.substring(1);if(i.substring(o+1,o+1+a.length)===a){d=!0,o+=a.length;break}}if(!d)break}else if(i[o]==="["){for(o++;o<i.length&&i[o]!=="]";){if(i[o]==='"'||i[o]==="'"){let m=i[o];for(o++;o<i.length&&i[o]!==m;)i[o]==="\\"&&o++,o++}o++}o<i.length&&i[o]==="]"&&o++}else o++;f=i.substring(l,o);let u=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(f)?u=t.NUMBER:f==="true"||f==="false"||f==="null"?u=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(f)&&(u=t.SELECTOR),s.push({type:u,value:f,quoted:!1}),l=o}return s}function r(i){let s="";for(let l=0;l<i.length;l++){let c=i[l];if("{}".includes(c.type)||"[]".includes(c.type)){s+=c.value;continue}if(c.type===t.COLON){s+=c.value;continue}if(c.type===t.COMMA){let o=i[l+1];if(o&&(o.type==="}"||o.type==="]"))continue;s+=c.value;continue}if(c.type===t.STRING&&c.quoted){let o=c.value;c.sourceQuote==="'"&&(o=o.replace(/\\'/g,"'"),o=o.replace(/(\\*)"/g,(f,u)=>u.length%2===0?u+'\\"':f)),s+=`"${o}"`;continue}if(c.type===t.NUMBER||c.type===t.BOOLEAN){s+=c.value;continue}if(c.type===t.SELECTOR||c.type===t.IDENTIFIER){s+=`"${c.value}"`;continue}s+=`"${c.value}"`}return s}try{let i=n(e),s=r(i);return JSON.parse(s)}catch(i){throw new k("Invalid extraction rules syntax: "+i.message,i)}}var Tt="1",_e=/^[a-zA-Z0-9_-]+$/;function j(e,t,n){let r;if(n===void 0)r="script[data-rules-name]";else{if(typeof n!="string"||!_e.test(n))throw new Error(`hyper-html-api: invalid rules token ${JSON.stringify(n)} (must match ${_e})`);r=`script[data-rules-name~="${n}"]`}let i=e.find(t,r,{includeRulesTag:!0});if(i.length===0)return null;n!==void 0&&i.length>1&&console.warn(`hyper-html-api: ${i.length} rules tags match data-rules-name~="${n}"; using the first.`);let s=i[0],l=e.attr(s,"data-rules-version");if(l!==Tt)throw new W(l);return{rules:z(e.text(s)),tagNode:s}}var ee=Object.freeze({data:Object.freeze({tokens:["no-data"],bundles:["editor-ui"]}),save:Object.freeze({tokens:["no-save"],bundles:["editor-ui"]}),snapshot:Object.freeze({tokens:["no-snapshot"],bundles:["editor-ui"]}),watch:Object.freeze({tokens:["no-watch"],bundles:["editor-ui"]}),undo:Object.freeze({tokens:["no-undo"],bundles:["editor-ui"]}),history:Object.freeze({tokens:[],bundles:["editor-ui"]})}),wt=Object.freeze({"editor-ui":Object.freeze(["no-data","no-save","no-snapshot","no-watch","no-undo"])}),De=Object.freeze(["no-save","no-snapshot","no-trigger-autosave","no-dirty","no-watch","no-undo","no-data","freeze","editor-ui","live"]);function K(e,t){if(!e||e.nodeType!==1)return!1;let n=e.getAttribute?.("clay");return!!(n&&n.split(/\s+/).includes(t)||e.hasAttribute?.(t))}function pe(e,t){if(K(e,t))return!0;for(let[n,r]of Object.entries(wt))if(r.includes(t)&&K(e,n))return!0;return!1}function F(e){let t=ee[e];if(!t)throw new Error(`Unknown region capability: ${e}`);return[...t.tokens,...t.bundles].flatMap(n=>[`[clay~="${n}"]`,`[${n}]`]).join(", ")}function Et(e,t){let n=e&&e.nodeType===1?e:e?.parentElement;for(;n&&n.nodeType===1;){let r=ee[t];if(!r)throw new Error(`Unknown region capability: ${t}`);if(r.tokens.some(i=>pe(n,i))||r.bundles.some(i=>K(n,i)))return n;n=n.parentElement}return null}function $e(e,t){return!!Et(e,t)}var me=Object.freeze({refusedRuleForms:["innerHTML","outerHTML"],refusedTargets:["script","style","template","noscript","iframe","object","embed","xmp","plaintext","noembed","noframes","meta","link","base","animate","set","animatemotion","animatetransform"],refusedAttributes:["style","srcdoc","is","http-equiv","sandbox","allow","nonce","integrity","charset","htmlclaytoken","htmlclayid","data-rules-name","data-rules-version","clay","contenteditable",...De],refusedAttributePrefixes:["on"],urlAttributes:["href","src","srcset","action","formaction","poster","cite","data","ping","background","longdesc","usemap","xlink:href","manifest","codebase","icon"],refusedSchemes:["javascript","vbscript","data"]}),Ot=new Set(["textContent","innerText"]);function We(e){let n=String(e).replace(/^[\u0000- ]+|[\u0000- ]+$/g,"").replace(/[\t\n\r]/g,"").match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/);return n?n[1].toLowerCase():null}var xt=/^[^\t\n\f\r "'>/=\u0000-\u001f\u007f]+$/;function ve(e,t,n=me){if(!xt.test(String(e)))return`attribute name ${JSON.stringify(String(e))} is not valid`;let r=String(e).toLowerCase();if(n.refusedAttributePrefixes.some(i=>r.startsWith(i)))return`attribute "${r}" can run script`;if(n.refusedAttributes.includes(r))return`attribute "${r}" is not content`;if(n.urlAttributes.includes(r)&&t!=null){let i=r==="srcset"?String(t).split(",").map(s=>s.trim().split(/\s+/)[0]).filter(Boolean):[String(t)];for(let s of i){let l=We(s);if(l&&n.refusedSchemes.includes(l))return`"${l}:" URLs are not allowed in "${r}"`}}return null}function ye(e,t){let n=e.prop(t,"tagName");return n?String(n).toLowerCase():""}function St(e,t){let n=ye(e,t)||"node",r=e.attr(t,"id");return r?`<${n}#${r}>`:`<${n}>`}function bt(e,t,n){let r=t;for(;r;){let i=ye(e,r);if(i&&n.refusedTargets.includes(i))return i;r=e.parent(r)}return null}function Be(e,t){return e.find(t,"script[data-rules-name]",{includeRulesTag:!0,templateAttr:null}).length>0}function Rt(e,t){return ye(e,t)==="script"&&e.attr(t,"data-rules-name")!=null?!0:Be(e,t)}function te(e,t=me){let n=[],r=(o,f)=>(n.push({target:St(e,o),reason:f}),!1),i=o=>{let f=bt(e,o,t);return f?r(o,`inside <${f}>, which is not content`):!0},s=o=>i(o)?Be(e,o)?r(o,"a text write here would delete the data rules tag"):!0:!1,l=(o,f,u)=>{if(!i(o))return!1;let m=ve(f,u,t);return m?r(o,m):!0};return{...e,text(o,f){if(f===void 0)return e.text(o);s(o)&&e.text(o,f)},attr(o,f,u){if(u===void 0)return e.attr(o,f);l(o,f,u)&&e.attr(o,f,u)},removeAttr(o,f){l(o,f,null)&&e.removeAttr(o,f)},prop(o,f,u){if(u===void 0)return e.prop(o,f);if(t.refusedRuleForms.includes(f))return r(o,`"@${f}" writes HTML, only text is allowed`);if(Ot.has(f)){s(o)&&e.prop(o,f,u);return}l(o,f==="className"?"class":f,u)&&e.prop(o,f,u)},remove(o){if(Rt(e,o)){r(o,"removing this would delete the data rules tag");return}e.remove(o)},replaceWith(o,f){return f===e.prop(o,"outerHTML")||r(o,'"@outerHTML" writes HTML, only text is allowed'),o},refusals:n,assertClean(){if(n.length)throw new H(n.slice())}}}function V(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function He(e){return e.reduce((t,n)=>typeof n=="number"?`${t}[${n}]`:t?`${t}.${n}`:n,"")}function ge(e,t,n,r,i={}){let s=[],l=[];function c(f,u,m){if(Array.isArray(f)){let[,d]=f;if(!Array.isArray(u)||!V(d))return;u.forEach((w,a)=>c(d,w,[...m,a]));return}if(!(!V(f)||!V(u)))for(let d of Object.keys(u))Object.prototype.hasOwnProperty.call(f,d)?c(f[d],u[d],[...m,d]):s.push(He([...m,d]))}function o(f,u,m,d){if(m!==void 0){if(typeof u=="string"){if(u.endsWith("[]")||u==="."||u.startsWith("@"))return;let w=b(u),a=w===-1?u:u.slice(0,w);if(!a)return;e.find(f,a,i).length===0&&l.push({path:He(d),selector:a});return}if(!Array.isArray(u)&&V(u)&&V(m))for(let[w,a]of Object.entries(u))o(f,a,m[w],[...d,w])}}return c(n,r,[]),o(t,n,r,[]),{unknownKeys:s,unmatched:l}}function Ae(e,t,n){if(n&&typeof n=="object")return{rules:n,tagNode:null};if(typeof n=="string"){let r=t&&t.ownerDocument?t.ownerDocument:t;return j(e,r,n)}return null}var Ct=/:(?:focus(?:-within|-visible)?|hover|active|visited|defined)\b/i;function Mt(e,t){if(!/^(INPUT|TEXTAREA|SELECT|OPTION)$/.test(e.tagName||""))return;let n=(e.getAttribute?.("type")||"").toLowerCase();"value"in e&&"value"in t&&e.tagName!=="OPTION"&&n!=="checkbox"&&n!=="radio"&&n!=="file"&&(t.value=e.value),e.tagName==="INPUT"&&(n==="checkbox"||n==="radio")&&(t.checked=e.checked),e.tagName==="OPTION"&&(t.selected=e.selected),"indeterminate"in e&&"indeterminate"in t&&(t.indeterminate=e.indeterminate)}function qe(e,t,n,r){if(r)return!!e.closest?.(t);let i=e;for(;i?.nodeType===1;){if(i.matches(t))return!0;if(i===n)break;i=i.parentElement}return!1}function Ue(e,t,n,r,i,s){return(s?$e(e,t):qe(e,n,i,!1))||!!(r&&(s&&e!==i?e.matches(r):qe(e,r,i,s)))}function Pt(e,t){let n=ee[t];return n.tokens.some(r=>pe(e,r))||n.bundles.some(r=>K(e,r))}var It=new Set(["INPUT","TEXTAREA","SELECT","OPTION"]);function ze(e,t,n,r){if(e.nodeType===1&&r(e)){n.dropped.push(t);return}n.cloneToLive.set(t,e),n.liveToClone.set(e,t);let i=e,s=t;if(e.nodeType===1){if(It.has(e.tagName)&&n.controls.push(e,t),e.tagName==="TEMPLATE"){for(;t.firstChild;)t.removeChild(t.firstChild);i=e.content,s=t.content,n.cloneToLive.set(s,i),n.liveToClone.set(i,s)}}else if(e.nodeType!==11)return;let l=s.firstChild;for(let c=i.firstChild;c&&l;c=c.nextSibling)ze(c,l,n,r),l=l.nextSibling}function J(e,{capability:t="data",exclude:n=null,inherit:r=!0,provenance:i=null}={}){if(!e)throw new TypeError("createContentView requires a DOM context");let s=e.nodeType===9?e:e.ownerDocument;if(!s?.implementation?.createHTMLDocument)throw new TypeError("createContentView requires an HTML DOM implementation");let l=s.implementation.createHTMLDocument(""),c=i||new WeakMap,o=new WeakMap,f=e.nodeType===9?e.documentElement:e;n&&l.documentElement.matches(n);let u=F(t),m=r?a=>Pt(a,t)||!!(n&&a.matches(n)):a=>Ue(a,t,u,n,f,!1),d=null;if(f.nodeType!==1||!Ue(f,t,u,n,f,r)){d=l.importNode(f,!0);let a={cloneToLive:c,liveToClone:o,dropped:[],controls:[]};ze(f,d,a,m);for(let p of a.dropped)p.remove();for(let p=0;p<a.controls.length;p+=2)Mt(a.controls[p],a.controls[p+1])}e.nodeType===9&&d&&(l.replaceChild(d,l.documentElement),o.set(e,l),c.set(l,e));let w=a=>{if(Ct.test(a))throw new Error(`Filtered content queries do not support stateful selector: ${a}`)};return{root:d,document:l,capability:t,selector:F(t),cloneToLive:c,liveToClone:o,original(a){return c.get(a)||null},cloneOf(a){return o.get(a)||null},query(a,p=d){return w(a),Array.from(p.querySelectorAll(a),g=>c.get(g)||g)},text(a=d){return(a===d?d:o.get(a))?.textContent||""},html(a=d){return(a===d?d:o.get(a))?.innerHTML??""},clone(a=d){let p=a===d?d:o.get(a);return p?l.importNode(p,!0):null}}}function Fe(e){return e&&e.nodeType===1&&e.tagName==="SCRIPT"&&e.hasAttribute&&e.hasAttribute("data-rules-name")}function kt(e){return e?(e.nodeType===9||e.nodeType===11,e):null}function Ke(e,t,n){!e||e.nodeType!==1||(t==="value"&&e.tagName==="INPUT"?e.value=n===null?"":n:t==="checked"&&e.tagName==="INPUT"?e.checked=n!==null:t==="selected"&&e.tagName==="OPTION"&&(e.selected=n!==null))}function Ve(e,t){e&&e.tagName==="TEXTAREA"&&(e.value=t)}function Je(e){if(!e||e.nodeType!==1)return;let t=[e,...e.querySelectorAll?e.querySelectorAll("textarea, input, option"):[]];for(let n of t)if(n.tagName==="TEXTAREA")n.value=n.defaultValue;else if(n.tagName==="INPUT"){let r=n.type;r!=="file"&&r!=="checkbox"&&r!=="radio"&&(n.value=n.defaultValue),n.checked=n.defaultChecked}else n.tagName==="OPTION"&&(n.selected=n.defaultSelected)}var x={semanticExclude:!0,find(e,t,n={}){let r=kt(e);if(!r||!r.querySelectorAll)return[];let i=Array.from(r.querySelectorAll(t));n.includeRulesTag||(i=i.filter(c=>!Fe(c)));let s=[];n.skip&&s.push(n.skip);let l=n.templateAttr===null?null:n.templateAttr||"cms-template";if(l&&s.push("["+l+"]"),s.length){let c=s.join(", ");i=i.filter(o=>!o.closest||!o.closest(c))}return i},parent(e){return e?e.parentElement:null},children(e){return e?Array.from(e.children):[]},matches(e,t){return!!(e&&e.matches)&&e.matches(t)},text(e,t){if(t===void 0)return(e.textContent||"").trim();e.textContent=t,Ve(e,t)},attr(e,t,n){if(n===void 0)return e.hasAttribute&&e.hasAttribute(t)?e.getAttribute(t):null;e.setAttribute(t,n),Ke(e,t,n)},removeAttr(e,t){e&&e.removeAttribute&&e.removeAttribute(t),Ke(e,t,null)},prop(e,t,n){if(n===void 0){let r=e?e[t]:void 0;return r!==void 0?r:null}e[t]=n},clone(e){let t=e.cloneNode(!0);return Je(t),t},insertAt(e,t,n){let r=e.children[n]||null;e.insertBefore(t,r)},insertBefore(e,t){e.parentNode.insertBefore(t,e)},insertAfter(e,t){e.parentNode.insertBefore(t,e.nextSibling)},identity(e){return e||null},remove(e){e&&e.parentNode&&e.parentNode.removeChild(e)},replaceWith(e,t){if(!e||!e.parentNode)throw new Error("dom.replaceWith: node has no parent");let r=e.ownerDocument.createElement("template");r.innerHTML=t;let i=r.content.firstElementChild;if(!i)throw new Error("dom.replaceWith: html did not parse to an element");return e.parentNode.replaceChild(i,e),i},stripIds(e){let t=0;return e.id&&(e.removeAttribute("id"),t++),(e.querySelectorAll?e.querySelectorAll("[id]"):[]).forEach(r=>{r.removeAttribute("id"),t++}),t},sameNode(e,t){return e===t}};function M(e,t={}){if(t.exclude===null)return x;let n=[F("data"),t.exclude].filter(Boolean).join(", "),r=e.nodeType===9?e:e.ownerDocument||e,i=e.nodeType===9?e.documentElement:e;if(!t._write&&!i?.matches?.(n)&&!i?.querySelector?.(n)&&!r?.querySelector?.(n))return x;let s=e.nodeType===9||!e.isConnected?e:e.ownerDocument,l=e.nodeType===9?e:e.ownerDocument,c=null,o=()=>c||(c=J(s,{capability:"data",exclude:t.exclude||null})),f=a=>{let p=o();return a===e?p.cloneOf(e):p.cloneOf(a)||a},u=a=>c?.original(a)||a,m=(a,p)=>{o().liveToClone.set(a,p),o().cloneToLive.set(p,a);let g=a.childNodes||[],h=p.childNodes||[];for(let y=0;y<Math.min(g.length,h.length);y++)m(g[y],h[y])},d=(a,p,g,h)=>{let y=Array.from(a.childNodes).filter(E=>c.cloneOf(E)),T=y[0];for(;T&&y.includes(T);)T=T.nextSibling;for(let E of y)E.remove();if(g==="innerHTML"){let E=l.createElement("template");E.innerHTML=h;for(let D of Array.from(E.content.childNodes))a.insertBefore(D,T||null)}else a.insertBefore(l.createTextNode(h),T||null),Ve(a,h);let S=J(a,{capability:"data",exclude:t.exclude||null});p.replaceChildren(...Array.from(S.root?.childNodes||[]));let O=E=>{let D=S.original(E);D&&(c.liveToClone.set(D,E),c.cloneToLive.set(E,D));for(let Ze of Array.from(E.childNodes||[]))O(Ze)};for(let E of Array.from(p.childNodes))O(E)},w={...x,find(a,p,g={}){let h=f(a);if(!h?.querySelectorAll)return[];let y=o().query(p,h);g.includeRulesTag||(y=y.filter(S=>!Fe(S)));let A=[];g.skip&&A.push(g.skip);let T=g.templateAttr===null?null:g.templateAttr||"cms-template";if(T&&A.push(`[${T}]`),A.length){let S=A.join(", ");y=y.filter(O=>!O.closest?.(S))}return y},parent(a){let p=f(a)?.parentElement;return p?u(p):null},children(a){return Array.from(f(a)?.children||[],u)},text(a,p){if(p===void 0){let y=u(a);return!y?.matches?.(n)&&!y?.querySelector?.(n)?x.text(y):(f(a)?.textContent||"").trim()}let g=u(a);if(!g?.matches?.(n)&&!g?.querySelector?.(n)&&!c){x.text(g,p);return}let h=o().cloneOf(g);h?d(g,h,"textContent",p):x.text(g,p)},attr(a,p,g){let h=u(a);if(g===void 0)return x.attr(h,p);x.attr(h,p,g);let y=c?.cloneOf(h);y&&(x.attr(y,p,g),J(h,{capability:"data",exclude:t.exclude||null}).root===null&&(y.remove(),c.liveToClone.delete(h),c.cloneToLive.delete(y)))},removeAttr(a,p){let g=u(a);x.removeAttr(g,p);let h=c?.cloneOf(g);h&&x.removeAttr(h,p)},prop(a,p,g){let h=u(a);if(g===void 0)return p==="innerHTML"||p==="outerHTML"||p==="textContent"||p==="innerText"?x.prop(f(h),p):x.prop(h,p);let y=p==="innerHTML"||p==="textContent"||p==="innerText",A=y?o().cloneOf(h):c?.cloneOf(h);A&&y?d(h,A,p,g):(x.prop(h,p,g),A&&x.prop(A,p,g))},clone(a){let p=f(a);if(p===a)return x.clone(a);let g=l.importNode(p,!0);return Je(g),g},insertAt(a,p,g){let h=u(a),A=w.children(h)[g]||(()=>{for(let O=h.children.length-1;O>=0;O--){let E=h.children[O];if(o().cloneOf(E))return E.nextElementSibling}return h.firstElementChild})(),T=u(p);h.insertBefore(T,A||null);let S=o().cloneOf(h);if(S){let O=o().cloneOf(T);O||(O=l.importNode(T,!0),m(T,O));let E=Array.from(S.children);S.insertBefore(O,E[g]||null)}},insertBefore(a,p){let g=u(a),h=u(p);g.parentNode.insertBefore(h,g);let y=o().cloneOf(g.parentNode);if(y){let A=o().cloneOf(h);A||(A=l.importNode(h,!0),m(h,A));let T=o().cloneOf(g);T?T.before(A):y.appendChild(A)}},insertAfter(a,p){let g=u(a),h=u(p);g.parentNode.insertBefore(h,g.nextSibling);let y=o().cloneOf(g.parentNode);if(y){let A=o().cloneOf(h);A||(A=l.importNode(h,!0),m(h,A));let T=o().cloneOf(g);T?T.after(A):y.appendChild(A)}},identity(a){return u(a)||null},remove(a){let p=u(a),g=o().cloneOf(p);x.remove(p),g&&x.remove(g)},replaceWith(a,p){let g=u(a),h=o().cloneOf(g),y=x.replaceWith(g,p);if(h){let A=J(y,{capability:"data",exclude:t.exclude||null});if(!A.root)h.remove();else{h.replaceWith(A.root);let T=S=>{let O=A.original(S);O&&(c.liveToClone.set(O,S),c.cloneToLive.set(S,O));for(let E of Array.from(S.childNodes||[]))T(E)};T(A.root)}}return y}};return w}var G=x;var ne={extract:(e,t,n={})=>C(M(e,n),e,t,n),apply:(e,t,n,r={})=>I(M(e,{...r,_write:!0}),e,t,n,r),findRulesIn:(e,t)=>j(G,e,t),findRules:(e,t)=>Ae(G,e,t),bind:(e,t,n={})=>{let r=Ae(G,e,t);if(!r){let i=typeof t=="string"?`data-rules-name~="${t}"`:"the provided rules object";throw new Error(`hyper-html-api: could not resolve rules for ${i}`)}return{...r,get:()=>C(M(e,n),e,r.rules,n),set:i=>I(M(e,{...n,_write:!0}),e,r.rules,i,n)}},parseStrict:de,parseRelaxed:z,ruleAttrIndex:b,splitRule:le,errors:R,DOM_PROPERTIES:X},Te=e=>!!e&&typeof e.nodeType=="number";function Ge(e){let t=e&&e.ownerDocument?e.ownerDocument:e,n=j(G,t,"api");if(!n)throw new R.NoRulesTag("api");return n.rules}function Lt(e){if(e.nodeType===9)return e;let t=e.ownerDocument?.documentElement;if(t?.contains(e))return t;let n=e;for(;n.parentNode;)n=n.parentNode;return n}function jt(e){if(e.nodeType!==11||!e.host)return e.cloneNode(!0);let t=e.ownerDocument.createDocumentFragment();for(let n of e.childNodes)t.appendChild(n.cloneNode(!0));return t}function _t(e,t){let n=[];for(;t!==e;){let r=t.parentNode;n.push(Array.prototype.indexOf.call(r.childNodes,t)),t=r}return n.reverse()}function Dt(e,t){return t.reduce((n,r)=>n.childNodes[r],e)}function _(e,t){let n=e.querySelectorAll?Array.from(e.querySelectorAll(t)):[];return e.matches?.(t)&&n.unshift(e),n}function $t(e,t){let n=_(e,"option"),r=_(t,"option");n.forEach((o,f)=>r[f].selected=o.selected);let i=_(e,"input"),s=_(t,"input");i.forEach((o,f)=>{let u=o.type.toLowerCase();u!=="file"&&(s[f].value=o.value),(u==="checkbox"||u==="radio")&&(s[f].checked=o.checked)});let l=_(e,"textarea"),c=_(t,"textarea");l.forEach((o,f)=>c[f].value=o.value)}function we(e,t){if(t!==void 0){if(typeof e=="string"){if(e.endsWith("[]"))return;let n=e.startsWith("@")?0:b(e);if(n===-1)return;let r=e.slice(n+1);if($.has(r))throw new R.RuleTargetReadOnly(r);return}if(Array.isArray(e)){if(!Array.isArray(t))return;t.forEach(n=>we(e[1],n));return}if(e&&typeof e=="object"&&t&&typeof t=="object"&&!Array.isArray(t))for(let[n,r]of Object.entries(e))we(r,t[n])}}function Wt(e,t,n){let r={templateAttr:"cms-template"},i=Lt(e),s=_t(i,e),l=jt(i);$t(i,l);let c=Dt(l,s),o=M(l,{...r,_write:!0}),f=ge(o,c,t,n,r);if(f.unknownKeys.length||f.unmatched.length)throw new R.WriteRejected(f.unknownKeys,f.unmatched);let u=te(o);I(u,c,t,n,r),u.assertClean(),we(t,n);let m=te(M(i,{...r,_write:!0}));I(m,e,t,n,r),m.assertClean()}function vt(e){if(!(e instanceof Error))return e;let t=e.name||"Error";try{e.code=t}catch{Object.defineProperty(e,"code",{value:t,configurable:!0,enumerable:!0})}return e instanceof R.WriteRefused?e.details=e.refusals:e instanceof R.WriteRejected?e.details={unknownKeys:e.unknownKeys,unmatched:e.unmatched}:e instanceof R.ShapeMismatch?e.details=e.mismatches:Array.isArray(e.path)?e.details={path:e.path}:typeof e.target=="string"?e.details={target:e.target}:e.token!==void 0?e.details={token:e.token}:e.version!==void 0?e.details={version:e.version}:e.details={},e}function Xe(e,t){let n=Te(e)?e:document,r=Te(e)?t:e;return r===void 0?C(M(n),n,Ge(n)):ne.bind(n,r).get()}function Ye(e,t,n){try{if(!Te(e))throw new Error("hyper-html-api: applyData(root, data, source?) needs a DOM root as the first argument.");let r=n===void 0?Ge(e):ne.bind(e,n).rules;Wt(e,r,t)}catch(r){throw vt(r)}return e}var Bt={engine:ne,extractData:Xe,applyData:Ye},Fn=Bt;export{Ye as applyData,Fn as default,ne as engine,Xe as extractData};
|