@panphora/clayjs 0.4.2 → 0.5.0
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/package.json +1 -1
- package/src/core/admin-contenteditable.js +4 -3
- package/src/core/admin-inputs.js +5 -3
- package/src/core/admin-onclick.js +4 -3
- package/src/core/admin-resources.js +8 -4
- package/src/core/is-edit-mode.js +3 -2
- package/src/core/save.js +16 -3
- package/src/core/snapshot.js +59 -4
- package/src/lib/dirty-gate.js +152 -0
- package/src/lib/root-attrs.js +5 -1
- package/src/sync/live-sync.js +440 -38
- package/src/sync/splice-merge.js +259 -0
- package/src/vendor/hyper-morph.vendor.js +4 -2
- package/src/vendor/hypercms.vendor.js +14 -14
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* splice-merge.js — scoped live sync's clayjs adapter.
|
|
3
|
+
*
|
|
4
|
+
* The shared core (findChangedRoots + spliceProtected, vendored from
|
|
5
|
+
* hyper-morph) is pure tree logic. This module owns everything clayjs-specific
|
|
6
|
+
* about feeding it: which capture pairs with which baseline, per lane, so the
|
|
7
|
+
* diff always compares trees from ONE serialization domain.
|
|
8
|
+
*
|
|
9
|
+
* Disk frames (htmlclay external changes; save domain on the wire):
|
|
10
|
+
* diff comparison clone vs parse(lastSavedContents) [same domain]
|
|
11
|
+
* splice save-clone subtrees into the incoming disk doc [same domain]
|
|
12
|
+
* The two clones come from ONE snapshot via captureForMerge(), whose
|
|
13
|
+
* pairMap bridges them. Save-domain subtrees still carry the
|
|
14
|
+
* no-trigger-autosave / freeze / no-watch children the comparison strips.
|
|
15
|
+
*
|
|
16
|
+
* Peer frames (live-lane relays; snapshot domain on the wire):
|
|
17
|
+
* diff snapshot clone vs parse(lastHtml) [same domain]
|
|
18
|
+
* splice snapshot subtrees into the incoming peer doc [same domain]
|
|
19
|
+
* Snapshot clones carry persist-finalized control values; live elements
|
|
20
|
+
* do not, which is why the splice never imports clones of live elements.
|
|
21
|
+
*
|
|
22
|
+
* Also owns edit-mode activation of incoming disk documents: disk holds the
|
|
23
|
+
* inert attribute forms (inert-contenteditable, inert-onclick, disabled
|
|
24
|
+
* viewmode inputs, type="inert/…" admin resources) and the live DOM holds the
|
|
25
|
+
* activated forms, so the patched document is run through the same enable
|
|
26
|
+
* passes boot runs before it is morphed in.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { findChangedRoots, spliceProtected } from '../vendor/hyper-morph.vendor.js';
|
|
30
|
+
import { captureSnapshot, captureForMerge } from '../core/snapshot.js';
|
|
31
|
+
// save.js is edit-only in the loader waves but safe to reach from here: its
|
|
32
|
+
// module body guards every init on isEditMode, and the disk lane that needs
|
|
33
|
+
// this state only ever runs in edit-mode tabs.
|
|
34
|
+
import { getLastSavedContents } from '../core/save.js';
|
|
35
|
+
import { TAB_LOCAL_ROOT_ATTRS } from '../lib/root-attrs.js';
|
|
36
|
+
import {
|
|
37
|
+
isSnapshotRemoved,
|
|
38
|
+
STRIP_FROM_SAVE,
|
|
39
|
+
FREEZE_SELECTOR,
|
|
40
|
+
SNAPSHOT_REMOVE_SELECTOR,
|
|
41
|
+
} from '../lib/region-policy.js';
|
|
42
|
+
import { probeMarkClean } from '../lib/dirty-gate.js';
|
|
43
|
+
import { isEditMode } from '../core/is-edit-mode.js';
|
|
44
|
+
import { enableContentEditable } from '../core/admin-contenteditable.js';
|
|
45
|
+
import { enableOnClick } from '../core/admin-onclick.js';
|
|
46
|
+
import { enableAdminInputs } from '../core/admin-inputs.js';
|
|
47
|
+
import { enableAdminResources } from '../core/admin-resources.js';
|
|
48
|
+
|
|
49
|
+
// Per-tab chrome the peer-lane diff must skip on BOTH sides: these regions
|
|
50
|
+
// legitimately differ between tabs, and the morph never touches them anyway
|
|
51
|
+
// (hyper-morph's sync-ignore set, composed from the same policy selectors).
|
|
52
|
+
const PEER_SKIP_SELECTOR = [
|
|
53
|
+
STRIP_FROM_SAVE,
|
|
54
|
+
FREEZE_SELECTOR,
|
|
55
|
+
SNAPSHOT_REMOVE_SELECTOR,
|
|
56
|
+
'[save-ignore]',
|
|
57
|
+
].join(', ');
|
|
58
|
+
|
|
59
|
+
function peerSkip(el) {
|
|
60
|
+
return el.matches(PEER_SKIP_SELECTOR);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Root attributes owned by the host or this tab: never a local edit.
|
|
64
|
+
function ignoreTabLocalRootAttrs(el, name) {
|
|
65
|
+
return !el.parentElement && TAB_LOCAL_ROOT_ATTRS.has(name);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// One-deep parse cache per lane: sender bursts reuse the same baseline string
|
|
69
|
+
// across consecutive frames, and parsing a full document per frame is the
|
|
70
|
+
// dirty path's single biggest avoidable cost.
|
|
71
|
+
function makeParseCache() {
|
|
72
|
+
let lastString = null;
|
|
73
|
+
let lastDoc = null;
|
|
74
|
+
return (html) => {
|
|
75
|
+
if (html !== lastString) {
|
|
76
|
+
lastDoc = new DOMParser().parseFromString(html, 'text/html');
|
|
77
|
+
lastString = html;
|
|
78
|
+
}
|
|
79
|
+
return lastDoc;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const parsePeerBase = makeParseCache();
|
|
84
|
+
const parseDiskBase = makeParseCache();
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Walk two identically-shaped element trees in lockstep, invoking cb(a, b)
|
|
88
|
+
* per pair. Used to carry synthetic ids across cloning and importing.
|
|
89
|
+
*/
|
|
90
|
+
function walkPairs(a, b, cb) {
|
|
91
|
+
cb(a, b);
|
|
92
|
+
const aKids = a.children;
|
|
93
|
+
const bKids = b.children;
|
|
94
|
+
for (let i = 0; i < aKids.length; i++) {
|
|
95
|
+
walkPairs(aKids[i], bKids[i], cb);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Copy synthetic ids from live elements onto their snapshot-clone twins.
|
|
101
|
+
* Mirrors _buildIdentityMap's walk: the live side filters [no-snapshot]
|
|
102
|
+
* chrome to stay aligned with what captureSnapshot stripped, and a subtree
|
|
103
|
+
* whose child counts diverge (extension noise beside the clone's strip) is
|
|
104
|
+
* skipped — those elements fall back to data-id / id matching.
|
|
105
|
+
*/
|
|
106
|
+
function fillCloneIds(liveEl, cloneEl, liveWeakMap, idOf) {
|
|
107
|
+
const id = liveWeakMap.get(liveEl);
|
|
108
|
+
if (id) idOf.set(cloneEl, id);
|
|
109
|
+
const liveKids = [];
|
|
110
|
+
for (const c of liveEl.children) {
|
|
111
|
+
if (!isSnapshotRemoved(c)) liveKids.push(c);
|
|
112
|
+
}
|
|
113
|
+
const cloneKids = cloneEl.children;
|
|
114
|
+
if (liveKids.length !== cloneKids.length) return;
|
|
115
|
+
for (let i = 0; i < liveKids.length; i++) {
|
|
116
|
+
fillCloneIds(liveKids[i], cloneKids[i], liveWeakMap, idOf);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Fill ids onto a parsed tree from a path-keyed identityMap (the wire format
|
|
122
|
+
* peers send). Same dot-path scheme as live-sync's _walkParsedTree.
|
|
123
|
+
*/
|
|
124
|
+
function fillParsedIds(root, identityMap, idOf) {
|
|
125
|
+
if (!root || !identityMap) return;
|
|
126
|
+
const visit = (el, path) => {
|
|
127
|
+
const id = identityMap[path];
|
|
128
|
+
if (id) idOf.set(el, id);
|
|
129
|
+
const kids = el.children;
|
|
130
|
+
for (let i = 0; i < kids.length; i++) {
|
|
131
|
+
visit(kids[i], path === '' ? String(i) : `${path}.${i}`);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
visit(root, '');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Protect local dirty regions in an incoming PEER document (snapshot domain).
|
|
139
|
+
* Mutates newDoc in place on success.
|
|
140
|
+
*
|
|
141
|
+
* @returns {{ ok: boolean, entries: Array, held?: object }}
|
|
142
|
+
* ok:false means the frame must be held back (applied not at all).
|
|
143
|
+
*/
|
|
144
|
+
export function protectPeerDoc({ newDoc, parsedWeakMap, baseHtml, baseIdentityMap, liveWeakMap }) {
|
|
145
|
+
// No baseline yet: nothing to diff against, and a dirty page must not be
|
|
146
|
+
// full-morphed over. The next frame (or our own first send) sets one.
|
|
147
|
+
if (typeof baseHtml !== 'string' || !baseHtml) {
|
|
148
|
+
return { ok: false, entries: [], held: null };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const localClone = captureSnapshot({ flushUndo: false });
|
|
152
|
+
const baseDoc = parsePeerBase(baseHtml);
|
|
153
|
+
if (!baseDoc.documentElement) return { ok: false, entries: [], held: null };
|
|
154
|
+
|
|
155
|
+
// One synthetic-identity space across all three trees. Local clone ids come
|
|
156
|
+
// from the live elements; base ids from the last frame's identityMap; the
|
|
157
|
+
// incoming doc's ids are already in parsedWeakMap.
|
|
158
|
+
const idOf = new WeakMap();
|
|
159
|
+
fillCloneIds(document.documentElement, localClone, liveWeakMap, idOf);
|
|
160
|
+
fillParsedIds(baseDoc.documentElement, baseIdentityMap, idOf);
|
|
161
|
+
|
|
162
|
+
const tiers = [
|
|
163
|
+
(el) => idOf.get(el) || (parsedWeakMap && parsedWeakMap.get(el)) || null,
|
|
164
|
+
(el) => el.getAttribute('data-id'),
|
|
165
|
+
(el) => el.getAttribute('id'),
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
const { entries } = findChangedRoots(localClone, baseDoc.documentElement, {
|
|
169
|
+
skip: peerSkip,
|
|
170
|
+
ignoreAttr: ignoreTabLocalRootAttrs,
|
|
171
|
+
tiers,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
if (!entries.length) {
|
|
175
|
+
probeMarkClean();
|
|
176
|
+
return { ok: true, entries };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const res = spliceProtected(newDoc, entries, { tiers });
|
|
180
|
+
if (!res.ok) {
|
|
181
|
+
return { ok: false, entries, held: res.held };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// The imported clones are fresh nodes; hand them their originals' synthetic
|
|
185
|
+
// ids so the morph pairs each protected region with the exact live elements
|
|
186
|
+
// it came from (zero churn, caret intact).
|
|
187
|
+
if (parsedWeakMap) {
|
|
188
|
+
for (const { entry, imported } of res.placed) {
|
|
189
|
+
walkPairs(entry.el, imported, (original, copy) => {
|
|
190
|
+
const id = idOf.get(original);
|
|
191
|
+
if (id) parsedWeakMap.set(copy, id);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return { ok: true, entries };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Protect local dirty regions in an incoming DISK document (save domain).
|
|
201
|
+
* Mutates newDoc in place on success.
|
|
202
|
+
*
|
|
203
|
+
* @returns {{ ok: boolean, entries: Array, held?: object }}
|
|
204
|
+
*/
|
|
205
|
+
export function protectDiskDoc({ newDoc }) {
|
|
206
|
+
const base = getLastSavedContents();
|
|
207
|
+
if (!base) return { ok: false, entries: [], held: null };
|
|
208
|
+
|
|
209
|
+
const { saveClone, compareClone, pairMap } = captureForMerge();
|
|
210
|
+
const baseDoc = parseDiskBase(base);
|
|
211
|
+
if (!baseDoc.documentElement) return { ok: false, entries: [], held: null };
|
|
212
|
+
|
|
213
|
+
const { entries } = findChangedRoots(compareClone, baseDoc.documentElement, {
|
|
214
|
+
ignoreAttr: ignoreTabLocalRootAttrs,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
if (!entries.length) {
|
|
218
|
+
probeMarkClean();
|
|
219
|
+
return { ok: true, entries };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Dirty roots were found on the comparison clone; the subtrees that go into
|
|
223
|
+
// the (save-domain) disk doc are their save-clone twins. An entry pairMap
|
|
224
|
+
// can't bridge means an authored transform grew the comparison clone after
|
|
225
|
+
// the pairing — unmappable, so the frame holds rather than guesses.
|
|
226
|
+
const spliceEntries = [];
|
|
227
|
+
for (const entry of entries) {
|
|
228
|
+
if (entry.type === 'deletion') {
|
|
229
|
+
spliceEntries.push(entry);
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const saveEl = pairMap.get(entry.el);
|
|
233
|
+
if (!saveEl) return { ok: false, entries, held: entry };
|
|
234
|
+
spliceEntries.push({ ...entry, el: saveEl });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const res = spliceProtected(newDoc, spliceEntries, {});
|
|
238
|
+
if (!res.ok) {
|
|
239
|
+
return { ok: false, entries, held: res.held };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return { ok: true, entries };
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Convert an incoming disk document from its saved (inert) form to the live
|
|
247
|
+
* edit-mode form, exactly as boot does on page load, so the morph compares
|
|
248
|
+
* like with like: without this, every disk frame would swap the live page's
|
|
249
|
+
* contenteditable/onclick/admin state back to inert — caret killed mid-edit.
|
|
250
|
+
* Root attributes (editmode, savestatus, tokens) need no reversal here; the
|
|
251
|
+
* morph's beforeAttributeUpdated veto keeps the live root's own.
|
|
252
|
+
*/
|
|
253
|
+
export function activateIncomingDoc(rootEl) {
|
|
254
|
+
if (!isEditMode || !rootEl) return;
|
|
255
|
+
enableContentEditable(rootEl);
|
|
256
|
+
enableOnClick(rootEl);
|
|
257
|
+
enableAdminInputs(rootEl);
|
|
258
|
+
enableAdminResources(rootEl);
|
|
259
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var HyperMorph=(()=>{var
|
|
2
|
-
`;)n++;continue}if(e[n]==="/"&&e[n+1]==="*"){let t=e.indexOf("*/",n+2);if(t===-1)return e.length;n=t+2;continue}return n}}function Ee(e){return e.replace(/\\'/g,"'").replace(/(\\*)"/g,(n,t)=>t.length%2===0?t+'\\"':n)}var Ge=/^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?$/,Ze=/^[A-Za-z_$][A-Za-z0-9_$]*$/;function ne(e){try{return JSON.parse(e)}catch{return JSON.parse(Qe(e))}}function Qe(e){let n="",t=0,d=(o,p)=>{throw new Error(`Invalid relaxed JSON: ${o} at position ${p}`)};for(;t<e.length&&(t=he(e,t),!(t>=e.length));){let o=e[t];if("{}[]:".includes(o)){n+=o,t++;continue}if(o===","){let u=he(e,t+1);if(e[u]==="}"||e[u]==="]"){t++;continue}n+=o,t++;continue}if(o==='"'||o==="'"){let u=t+1;for(;u<e.length&&e[u]!==o;)e[u]==="\\"&&u++,u++;u>=e.length&&d("unterminated string",t);let b=e.slice(t+1,u);o==="'"&&(b=Ee(b)),n+='"'+b+'"',t=u+1;continue}let p=t;for(;p<e.length&&/[A-Za-z0-9_$.+\-]/.test(e[p]);)p++;p===t&&d("unexpected character "+JSON.stringify(o),t);let m=e.slice(t,p);if(m==="true"||m==="false"||m==="null"||Ge.test(m)){n+=m,t=p;continue}if(Ze.test(m)){if(e[he(e,p)]===":"){n+='"'+m+'"',t=p;continue}d("unquoted value "+JSON.stringify(m),t)}d("invalid token "+JSON.stringify(m),t)}return n}function pe(e){try{return JSON.parse(e)}catch{}let n={BRACE_OPEN:"{",BRACE_CLOSE:"}",BRACKET_OPEN:"[",BRACKET_CLOSE:"]",COLON:":",COMMA:",",STRING:"STRING",SELECTOR:"SELECTOR",IDENTIFIER:"IDENTIFIER",NUMBER:"NUMBER",BOOLEAN:"BOOLEAN"};function t(o){let p=[],m=0;for(;m<o.length;){let u=o[m];if(/\s/.test(u)){m++;continue}if("{}".includes(u)){p.push({type:u,value:u}),m++;continue}if(u==="["){let N=!1,k=m+1;for(;k<o.length&&/\s/.test(o[k]);)k++;if(k<o.length&&/[a-zA-Z_]/.test(o[k])&&(N=!0),!N){p.push({type:u,value:u}),m++;continue}}if(u==="]"){p.push({type:u,value:u}),m++;continue}if(u===":"){p.push({type:n.COLON,value:u}),m++;continue}if(u===","){p.push({type:n.COMMA,value:u}),m++;continue}if(u==='"'||u==="'"){let N=u,k=m+1;for(;k<o.length&&o[k]!==N;)o[k]==="\\"&&k++,k++;p.push({type:n.STRING,value:o.substring(m+1,k),quoted:!0,sourceQuote:N}),m=k+1;continue}let b=m,T;for(;b<o.length&&!/[{},]/.test(o[b]);)if(o[b]===":"){let N=[":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"],k=!1;for(let S of N){let v=S.substring(1);if(o.substring(b+1,b+1+v.length)===v){k=!0,b+=v.length;break}}if(!k)break}else if(o[b]==="["){for(b++;b<o.length&&o[b]!=="]";){if(o[b]==='"'||o[b]==="'"){let N=o[b];for(b++;b<o.length&&o[b]!==N;)o[b]==="\\"&&b++,b++}b++}b<o.length&&o[b]==="]"&&b++}else b++;T=o.substring(m,b);let C=n.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(T)?C=n.NUMBER:T==="true"||T==="false"||T==="null"?C=n.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(T)&&(C=n.SELECTOR),p.push({type:C,value:T,quoted:!1}),m=b}return p}function d(o){let p="";for(let m=0;m<o.length;m++){let u=o[m];if("{}".includes(u.type)||"[]".includes(u.type)){p+=u.value;continue}if(u.type===n.COLON){p+=u.value;continue}if(u.type===n.COMMA){let b=o[m+1];if(b&&(b.type==="}"||b.type==="]"))continue;p+=u.value;continue}if(u.type===n.STRING){let b=u.value;u.sourceQuote==="'"&&(b=Ee(b)),p+=`"${b}"`;continue}if(u.type===n.NUMBER||u.type===n.BOOLEAN){p+=u.value;continue}p+=`"${u.value}"`}return p}try{let o=t(e),p=d(o);return JSON.parse(p)}catch(o){throw new Error("Invalid extraction rules syntax: "+o.message)}}var H=Symbol("hyper-morph-json-merge:missing"),we=["id","_id","uuid","key","slug","code","name"];function te(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function re(e,n){return Object.prototype.hasOwnProperty.call(e,n)}function Ye(e,n,t){Object.defineProperty(e,n,{value:t,enumerable:!0,writable:!0,configurable:!0})}function Z(e,n){if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n)){if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(!Z(e[t],n[t]))return!1;return!0}if(te(e)&&te(n)){let t=Object.keys(e);if(t.length!==Object.keys(n).length)return!1;for(let d of t)if(!re(n,d)||!Z(e[d],n[d]))return!1;return!0}return!1}function Ie(e,n,t,d){return Z(n,t)?n:Z(n,e)?t:Z(t,e)?n:te(n)&&te(t)?Xe(te(e)?e:{},n,t,d):Array.isArray(n)&&Array.isArray(t)?rt(Array.isArray(e)?e:[],n,t,d):t}function Ne(e,n,t,d){return n===H&&t===H?H:n===H?e===H?t:Z(t,e)?H:t:t===H?e===H?n:H:Ie(e,n,t,d)}function Xe(e,n,t,d){let o={},p=new Set([...Object.keys(e),...Object.keys(n),...Object.keys(t)]);for(let m of p){let u=Ne(re(e,m)?e[m]:H,re(n,m)?n[m]:H,re(t,m)?t[m]:H,d);u!==H&&Ye(o,m,u)}return o}function et(e){return e===null||typeof e!="object"}function ie(e){return typeof e+":"+String(e)}function tt(e,n){for(let t of n){let d=new Set;for(let o of t){if(!re(o,e))return!1;let p=o[e];if(typeof p!="string"&&typeof p!="number")return!1;let m=ie(p);if(d.has(m))return!1;d.add(m)}}return!0}function nt(e,n,t,d){let o=[e,n,t],p=!0;for(let m of o)for(let u of m)te(u)||(p=!1);if(p){for(let m of d.keyCandidates)if(tt(m,o))return{kind:"keyed",field:m};return null}for(let m of o){let u=new Set;for(let b of m){if(!et(b))return null;let T=ie(b);if(u.has(T))return null;u.add(T)}}return{kind:"self"}}function rt(e,n,t,d){let o=nt(e,n,t,d);if(!o)return t;let p=o.kind==="self"?ie:S=>ie(S[o.field]),m=S=>{let v=new Map;for(let B of S)v.set(p(B),B);return v},u=m(e),b=m(n),T=m(t),C=new Map,N=new Set([...u.keys(),...b.keys(),...T.keys()]);for(let S of N){let v=Ne(u.has(S)?u.get(S):H,b.has(S)?b.get(S):H,T.has(S)?T.get(S):H,d);v!==H&&C.set(S,v)}let k=[];for(let S of t){let v=p(S);C.has(v)&&k.push(v)}for(let S=0;S<n.length;S++){let v=p(n[S]);if(!C.has(v)||k.includes(v))continue;let B=0;for(let $=S-1;$>=0;$--){let j=k.indexOf(p(n[$]));if(j!==-1){B=j+1;break}}k.splice(B,0,v)}return k.map(S=>C.get(S))}function oe(e,n,t,d={}){let o=d.keyCandidates?[...d.keyCandidates,...we]:we;return Ie(e===void 0?H:e,n,t,{keyCandidates:o})}function ae(e,n,t,d={}){let o=d.parse||ne,p=[],m=(N,k)=>{if(typeof N!="string")return H;try{return o(N)}catch(S){return p.push(`${k} side is not valid JSON (${S.message})`),H}},u=m(n,"local"),b=m(t,"remote");if(u===H)return{text:t,warnings:p};if(b===H)return{text:n,warnings:p};let T=m(e,"base"),C=oe(T===H?void 0:T,u,b,d);return Z(C,b)?{text:t,warnings:p}:Z(C,u)?{text:n,warnings:p}:{text:JSON.stringify(C,null,2),warnings:p}}var ce=(function(){"use strict";let e=()=>{},n='[save-ignore],[snapshot-remove],[no-snapshot],[no-save],[save-remove],[freeze],[save-freeze],[clay~="no-save"],[clay~="no-snapshot"],[clay~="freeze"]';function t(l){if(!(l instanceof Element))return!1;if(l.matches(n))return!0;if(l.tagName==="LINK"||l.tagName==="SCRIPT"){let A=l.getAttribute("src")||l.getAttribute("href")||"";if(A.startsWith("chrome-extension://")||A.startsWith("moz-extension://")||A.startsWith("safari-web-extension://"))return!0}return!1}function d(l){return l instanceof Element?l.closest(n)?!0:t(l):!1}let o=ke({shouldIgnore:d});function p(l,A,M){if(M){let O=M.identityOf(l);if(O&&!M.disabled.has(O.key))return"hm-merge:"+O.key}if(A!=="smart")return l.outerHTML;let I=l.getAttribute("src"),E=l.getAttribute("type")||"text/javascript";if(I)try{let O=new URL(I,window.location.href);return`ext:${E}:${O.origin}${O.pathname}${O.search}`}catch{return`ext:${E}:${I}`}else{let O=l.textContent.trim(),c=5381;for(let y=0;y<O.length;y++)c=(c<<5)+c^O.charCodeAt(y);return`inline:${E}:${Math.abs(c).toString(36)}`}}let m="http://www.w3.org/1999/xhtml";function u(l){return l instanceof Element&&l.tagName==="SCRIPT"&&l.namespaceURI===m}function b(l){let A=document.createElement("div");A.innerHTML="<script><\/script>";let M=A.firstChild;for(let I of l.attributes)M.setAttribute(I.name,I.value);return M.textContent=l.textContent,M}function T(l){if(u(l))return b(l);if(l instanceof Element)for(let A of l.querySelectorAll("script"))u(A)&&A.replaceWith(b(A));return l}function C(l){let A=(l.getAttribute("type")||"").split(";")[0].trim().toLowerCase();return A==="application/json"||A.endsWith("+json")}let N={match:l=>l.hasAttribute("merge"),identity:l=>l.getAttribute("merge")};function k(l,A,M){if(M.merge===!1)return null;let I=[N,...M.mergeTags||[]],E=new WeakMap,O=i=>{if(E.has(i))return E.get(i);let h=null;if(u(i)&&!i.getAttribute("src")&&!d(i)){let g=i;for(let w=0;w<I.length;w++)if(I[w].match(g)){if(!C(g))console.warn("[hyper-morph] merge ignored: script type is not JSON",g);else{let x=I[w].identity(g);x!=null&&x!==""&&(h={key:w+":"+x,raw:x,recognizer:I[w]})}break}}return E.set(i,h),h},c=new Set,y=i=>{let h=new Map,g=w=>{let x=O(w);x&&(h.has(x.key)?(c.add(x.key),console.warn(`[hyper-morph] merge disabled for duplicate identity "${x.raw}"`)):h.set(x.key,w))};u(i)&&g(i);for(let w of i.querySelectorAll("script"))g(w);return h},a=y(l),s=y(A.__hyperMorphRoot||A);if(a.size===0&&s.size===0)return null;let r=null;return{identityOf:O,disabled:c,oldByKey:a,newByKey:s,baseTexts:()=>{if(r)return r;r=new Map;let i=M.mergeBase;if(!i)return r;let h;typeof i=="string"?h=new DOMParser().parseFromString(i,"text/html").documentElement:i instanceof Document?h=i.documentElement:h=i;let g=w=>{let x=O(w);x&&!r.has(x.key)&&r.set(x.key,w.textContent)};u(h)&&g(h);for(let w of h.querySelectorAll("script"))g(w);return r}}}function S(l,A,M){let I=l.merge;if(!I)return!1;let E=I.identityOf(A);if(!E||I.disabled.has(E.key))return!1;let O=I.identityOf(M);if(!O||O.key!==E.key)return!1;let c=A,y=M,a=y.getAttribute("merge-key")||c.getAttribute("merge-key"),{text:s,warnings:r}=ae(I.baseTexts().get(E.key),c.textContent,y.textContent,{parse:E.recognizer.parse,keyCandidates:a?a.split(/[\s,]+/).filter(Boolean):void 0});for(let f of r)console.warn(`[hyper-morph] merge "${E.raw}": ${f}`);return c.textContent!==s&&(c.textContent=s),!0}let v={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:e,afterNodeAdded:e,beforeNodeMorphed:e,afterNodeMorphed:e,beforeNodeRemoved:e,afterNodeRemoved:e,beforeAttributeUpdated:e},head:{style:"merge",shouldPreserve:l=>l.getAttribute("im-preserve")==="true",shouldReAppend:l=>l.getAttribute("im-re-append")==="true",shouldRemove:e,afterHeadMorphed:e},scripts:{handle:!0,matchMode:"outerHTML",shouldPreserve:l=>l.getAttribute("im-preserve")==="true",shouldReAppend:l=>l.getAttribute("im-re-append")==="true",shouldRemove:e,afterScriptsHandled:e},restoreFocus:!0},B={computeMatches(l,A){let{computeMatches:M}=o.session();return M(l,A)}};function $(l,A,M={}){l=xe(l);let I=ge(A),E=Te(l,I,M),O=E.scripts.handle?new Set(Array.from(l.querySelectorAll("script")).map(s=>p(s,E.scripts.matchMode,E.merge))):null,c=K(E),y=U(E,l,I,s=>s.morphStyle==="innerHTML"?(q(s,l,I),Array.from(l.childNodes)):V(s,l,I)),a=s=>{c&&X(E,c),j(E);let r=O?Oe(s,O,E):[];return r.length>0?Promise.all(r).then(()=>s):s};return y instanceof Promise?y.then(a):a(y)}function j(l){for(let A of Array.from(l.pantry.childNodes))l.callbacks.beforeNodeRemoved(A)!==!1&&l.callbacks.afterNodeRemoved(A);l.pantry.remove()}function V(l,A,M){let I=ge(A);return q(l,I,M,A,A.nextSibling),Array.from(I.childNodes)}function K(l){if(!l.config.restoreFocus)return null;let A=document.activeElement;if(!(A instanceof HTMLInputElement||A instanceof HTMLTextAreaElement))return null;let{id:M,selectionStart:I,selectionEnd:E}=A;return{element:A,id:M,selectionStart:I,selectionEnd:E}}function X(l,A){let M=A.element;if(A.id&&A.id!==document.activeElement?.getAttribute("id")&&(M=l.target.querySelector(`[id="${CSS.escape(A.id)}"]`),M?.focus()),M&&!M.selectionEnd&&A.selectionEnd!=null)try{M.setSelectionRange(A.selectionStart,A.selectionEnd)}catch{}}let q=(function(){function l(s,r,f,i=null,h=null){r instanceof HTMLTemplateElement&&f instanceof HTMLTemplateElement&&(r=r.content,f=f.content),i||=r.firstChild;for(let g of f.childNodes){if(t(g))continue;if(i&&i!=h){let x=M(s,g,i,h);if(x){x!==i&&E(s,i,x),W(x,g,s),i=x.nextSibling;continue}}if(g instanceof Element){let x=g.getAttribute("id");if(s.persistentIds.has(x)){let L=O(r,x,i,s);W(L,g,s),i=L.nextSibling;continue}if(!s.idMap.has(g)){let L=s.hyperMatches.get(g);if(L&&!s.idMap.has(L)&&!a(L,r)){y(r,L,i),W(L,g,s),i=L.nextSibling;continue}}}let w=A(r,g,i,s);w&&(i=w.nextSibling)}for(;i&&i!=h;){let g=i;i=i.nextSibling,t(g)||I(s,g)}}function A(s,r,f,i){if(i.callbacks.beforeNodeAdded(r)===!1)return null;if(i.idMap.has(r)){let h=r,g=document.createElementNS(h.namespaceURI,h.localName);return s.insertBefore(g,f),W(g,r,i),i.callbacks.afterNodeAdded(g),g}else{let h=T(document.importNode(r,!0));return s.insertBefore(h,f),i.callbacks.afterNodeAdded(h),h}}let M=(function(){function s(i,h,g,w){let x=h instanceof Element&&!i.idMap.has(h)?i.hyperMatches.get(h):null,L=null,F=h.nextSibling,J=0,R=g;for(;R&&R!=w;){if(t(R)){R=R.nextSibling;continue}if(f(R,h)){if(r(i,R,h)||R===x&&!i.idMap.has(R))return R;if(L===null){let P=R instanceof Element&&i.hyperMatchedOldElements.has(R);!i.idMap.has(R)&&!P&&(L=R)}}if(L===null&&F&&f(R,F)&&(J++,F=F.nextSibling,J>=2&&(L=void 0)),i.activeElementAndParents.includes(R))break;R=R.nextSibling}return L||null}function r(i,h,g){let w=i.idMap.get(h),x=i.idMap.get(g);if(!x||!w)return!1;for(let L of w)if(x.has(L))return!0;return!1}function f(i,h){let g=i,w=h;return g.nodeType===w.nodeType&&g.tagName===w.tagName&&(!g.getAttribute?.("id")||g.getAttribute?.("id")===w.getAttribute?.("id"))}return s})();function I(s,r){let f=r instanceof Element&&s.hyperMatchedOldElements.has(r)&&!s.idMap.has(r);if(s.idMap.has(r)||f)y(s.pantry,r,null);else{if(s.callbacks.beforeNodeRemoved(r)===!1)return;r.parentNode?.removeChild(r),s.callbacks.afterNodeRemoved(r)}}function E(s,r,f){let i=r;for(;i&&i!==f;){let h=i;i=i.nextSibling,t(h)||I(s,h)}return i}function O(s,r,f,i){let h=i.target.getAttribute?.("id")===r&&i.target||i.target.querySelector(`[id="${CSS.escape(r)}"]`)||i.pantry.querySelector(`[id="${CSS.escape(r)}"]`);return c(h,i),y(s,h,f),h}function c(s,r){let f=s.getAttribute("id");for(;s=s.parentNode;){let i=r.idMap.get(s);i&&(i.delete(f),i.size||r.idMap.delete(s))}}function y(s,r,f){if(s.moveBefore)try{s.moveBefore(r,f)}catch{s.insertBefore(r,f)}else s.insertBefore(r,f)}function a(s,r){let f=r instanceof Element?r:r.realParentNode;return!!f&&s.contains(f)}return l})(),W=(function(){function l(c,y,a){return a.ignoreActive&&c===document.activeElement?null:(a.callbacks.beforeNodeMorphed(c,y)===!1||(c instanceof HTMLHeadElement&&a.head.ignore||(c instanceof HTMLHeadElement&&a.head.style!=="morph"?Q(c,y,a):(A(c,y,a),S(a,c,y)||O(c,a)||q(a,c,y))),a.callbacks.afterNodeMorphed(c,y)),c)}function A(c,y,a){let s=y.nodeType;if(s===1){let r=c,f=y,i=r.attributes,h=f.attributes;for(let g of h)E(g.name,r,"update",a)||r.getAttribute(g.name)!==g.value&&r.setAttribute(g.name,g.value);for(let g=i.length-1;0<=g;g--){let w=i[g];if(w&&!f.hasAttribute(w.name)){if(E(w.name,r,"remove",a))continue;r.removeAttribute(w.name)}}O(r,a)||M(r,f,a)}(s===8||s===3)&&c.nodeValue!==y.nodeValue&&(c.nodeValue=y.nodeValue)}function M(c,y,a){if(c instanceof HTMLInputElement&&y instanceof HTMLInputElement&&y.type!=="file"){let s=y.value,r=c.value;I(c,y,"checked",a),I(c,y,"disabled",a),a.formStateSync==="property"&&c.indeterminate!==y.indeterminate&&(c.indeterminate=y.indeterminate),a.formStateSync==="property"?r!==s&&(E("value",c,"update",a)||(c.value=s)):y.hasAttribute("value")?r!==s&&(E("value",c,"update",a)||(c.setAttribute("value",s),c.value=s)):E("value",c,"remove",a)||(c.value="",c.removeAttribute("value"))}else if(c instanceof HTMLOptionElement&&y instanceof HTMLOptionElement)I(c,y,"selected",a);else if(c instanceof HTMLTextAreaElement&&y instanceof HTMLTextAreaElement){let s=y.value,r=c.value;if(E("value",c,"update",a)||(s!==r&&(c.value=s),a.formStateSync==="property"))return;c.firstChild&&c.firstChild.nodeValue!==s&&(c.firstChild.nodeValue=s)}}function I(c,y,a,s){let r=y[a],f=c[a];if(r!==f){let i=E(a,c,"update",s);if(i||(c[a]=y[a]),s.formStateSync==="property")return;r?i||c.setAttribute(a,""):E(a,c,"remove",s)||c.removeAttribute(a)}}function E(c,y,a,s){return c==="value"&&s.ignoreActiveValue&&y===document.activeElement?!0:s.callbacks.beforeAttributeUpdated(c,y,a)===!1}function O(c,y){return!!y.ignoreActiveValue&&c===document.activeElement&&c!==document.body}return l})();function U(l,A,M,I){if(l.head.block){let E=A.querySelector("head"),O=M.querySelector("head");if(E&&O){let c=Q(E,O,l);return Promise.all(c).then(()=>(l.head.block=!1,l.head.ignore=!0,I(l)))}}return I(l)}function se(l){return l.tagName==="SCRIPT"?!!l.getAttribute("src"):l.tagName==="LINK"?(l.getAttribute("rel")||"").toLowerCase().split(/\s+/).includes("stylesheet")&&!!l.getAttribute("href"):!1}function Q(l,A,M){let I=[],E=[],O=[],c=[],y=M.scripts.matchMode,a=f=>{if(f.tagName==="SCRIPT")return p(f,y,M.merge);if(f.tagName==="LINK"&&y==="smart"){let i=f.getAttribute("href");if(i)try{let h=new URL(i,window.location.href);return`link:${f.getAttribute("rel")||""}:${h.origin}${h.pathname}${h.search}`}catch{}}return f.outerHTML},s=new Map;for(let f of A.children){if(t(f))continue;let i=a(f),h=s.get(i);h||(h=[],s.set(i,h)),h.push(f)}for(let f of l.children){let i=a(f),h=s.get(i),g=!!(h&&h.length),w=M.head.shouldReAppend(f),x=M.head.shouldPreserve(f);if(g||x)if(w)E.push(f);else{if(h&&h.length){let L=h.pop();h.length||s.delete(i),S(M,f,L)}O.push(f)}else M.head.style==="append"?w&&(E.push(f),c.push(f)):M.head.shouldRemove(f)!==!1&&!t(f)&&E.push(f)}for(let f of s.values())c.push(...f);let r=[];for(let f of c){let i=document.createRange().createContextualFragment(f.outerHTML).firstChild;if(M.callbacks.beforeNodeAdded(i)!==!1){if(i instanceof Element&&se(i)){let h,g=new Promise(function(w){h=w});i.addEventListener("load",function(){h()}),i.addEventListener("error",function(){h()}),r.push(g)}l.appendChild(i),M.callbacks.afterNodeAdded(i),I.push(i)}}for(let f of E)M.callbacks.beforeNodeRemoved(f)!==!1&&(l.removeChild(f),M.callbacks.afterNodeRemoved(f));return M.head.afterHeadMorphed(l,{added:I,kept:O,removed:E}),r}function Oe(l,A,M){if(!M.scripts.handle)return[];let I=[],E=[],O=[],c=[],y=M.scripts.matchMode,a=[];for(let r of l)if(r instanceof Element){u(r)&&a.push(r);for(let f of r.querySelectorAll("script"))u(f)&&a.push(f)}for(let r of a){if(r.closest("head")||d(r))continue;let f=p(r,y,M.merge),i=A.has(f),h=M.scripts.shouldPreserve(r),g=M.scripts.shouldReAppend(r);i||h?g?(E.push(r),c.push(r)):O.push(r):c.push(r)}let s=[];for(let r of c){if(M.callbacks.beforeNodeAdded(r)===!1)continue;let f=document.createElement("script");for(let i of r.attributes)f.setAttribute(i.name,i.value);if(f.textContent=r.textContent,f.src){let i,h=new Promise(function(g){i=g});f.addEventListener("load",function(){i()}),f.addEventListener("error",function(){i()}),s.push(h)}r.replaceWith(f),M.callbacks.afterNodeAdded(f),I.push(f)}return M.scripts.afterScriptsHandled(M.target,{added:I,kept:O,removed:E}),s}let Te=(function(){function l(a,s,r){let{persistentIds:f,idMap:i}=c(a,s),h=B.computeMatches(a,s);if(typeof r.key=="function"){let F=new Map,J=new Set,R=D=>{let _=r.key(D);_!=null&&(F.has(_)?J.add(_):F.set(_,D))};a instanceof Element&&R(a);for(let D of a.querySelectorAll("*"))R(D);for(let D of J)F.delete(D);let P=new Map;for(let[D,_]of h)P.set(_,D);let Y=s.__hyperMorphRoot||s,G=new Map,me=new Set,ye=D=>{let _=r.key(D);_!=null&&(G.has(_)?me.add(_):G.set(_,D))};Y instanceof Element&&ye(Y);for(let D of Y.querySelectorAll("*"))ye(D);for(let D of me)G.delete(D);for(let[D,_]of G){let ee=F.get(D);if(!ee||ee.tagName!==_.tagName)continue;let ue=P.get(ee);ue&&ue!==_&&h.delete(ue);let le=h.get(_);le&&le!==ee&&P.delete(le),h.set(_,ee),P.set(ee,_)}}let g=A(r),w=k(a,s,g.scripts);if(w){let F=new Map;for(let[J,R]of h)F.set(R,J);for(let[J,R]of w.newByKey){if(w.disabled.has(J))continue;let P=w.oldByKey.get(J);if(!P)continue;let Y=F.get(P);Y&&Y!==R&&h.delete(Y);let G=h.get(R);G&&G!==P&&F.delete(G),h.set(R,P),F.set(P,R)}}let x=new Set;for(let F of h.values())x.add(F);let L=g.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(L))throw new Error(`Do not understand how to morph style ${L}`);return{target:a,newContent:s,config:g,morphStyle:L,ignoreActive:g.ignoreActive,ignoreActiveValue:g.ignoreActiveValue,restoreFocus:g.restoreFocus,formStateSync:g.formStateSync||"attribute",idMap:i,persistentIds:f,hyperMatches:h,hyperMatchedOldElements:x,merge:w,pantry:M(),activeElementAndParents:I(a),callbacks:g.callbacks,head:g.head,scripts:g.scripts}}function A(a){let s=Object.assign({},v);return Object.assign(s,a),s.callbacks=Object.assign({},v.callbacks,a.callbacks),s.head=Object.assign({},v.head,a.head),s.scripts=Object.assign({},v.scripts,a.scripts),s}function M(){let a=document.createElement("div");return a.hidden=!0,document.body.insertAdjacentElement("afterend",a),a}function I(a){let s=[],r=document.activeElement;if(r?.tagName!=="BODY"&&a.contains(r))for(;r&&(s.push(r),r!==a);)r=r.parentElement;return s}function E(a){let s=Array.from(a.querySelectorAll("[id]"));return a.getAttribute?.("id")&&s.push(a),s}function O(a,s,r,f){for(let i of f){let h=i.getAttribute("id");if(s.has(h)){let g=i;for(;g;){let w=a.get(g);if(w==null&&(w=new Set,a.set(g,w)),w.add(h),g===r)break;g=g.parentElement}}}}function c(a,s){let r=E(a),f=E(s),i=y(r,f),h=new Map;O(h,i,a,r);let g=s.__hyperMorphRoot||s;return O(h,i,g,f),{persistentIds:i,idMap:h}}function y(a,s){let r=new Set,f=new Map;for(let h of a){let g=h.getAttribute("id");f.has(g)?r.add(g):f.set(g,h.tagName)}let i=new Set;for(let h of s){let g=h.getAttribute("id");i.has(g)?r.add(g):f.get(g)===h.tagName&&i.add(g)}for(let h of r)i.delete(h);return i}return l})(),{normalizeElement:xe,normalizeParent:ge}=(function(){let l=new WeakSet;function A(c){return c instanceof Document?c.documentElement:c}function M(c){if(c==null)return document.createElement("div");if(typeof c=="string")return M(O(c));if(l.has(c))return c;if(c instanceof Node){if(c.parentNode)return new I(c);{let y=document.createElement("div");return y.append(c),y}}else{let y=document.createElement("div");for(let a of[...c])y.append(a);return y}}class I{constructor(y){this.originalNode=y,this.realParentNode=y.parentNode,this.previousSibling=y.previousSibling,this.nextSibling=y.nextSibling}get childNodes(){let y=[],a=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;for(;a&&a!=this.nextSibling;)y.push(a),a=a.nextSibling;return y}querySelectorAll(y){return this.childNodes.reduce((a,s)=>{if(s instanceof Element){s.matches(y)&&a.push(s);let r=s.querySelectorAll(y);for(let f=0;f<r.length;f++)a.push(r[f])}return a},[])}insertBefore(y,a){return this.realParentNode.insertBefore(y,a)}moveBefore(y,a){return this.realParentNode.moveBefore(y,a)}get __hyperMorphRoot(){return this.originalNode}}function E(c){let y=f=>`<${f}(?:\\s(?:[^>"']|"[^"]*"|'[^']*')*)?>`,a=c.replace(/<!--[\s\S]*?-->/g,"");for(let f of["script","style","textarea","title"])a=a.replace(new RegExp(`${y(f)}[\\s\\S]*?</${f}\\s*>`,"gi"),"");let s=new RegExp(`${y("svg")}[\\s\\S]*?</svg\\s*>`,"gi"),r;do r=a,a=a.replace(s,"");while(a!==r);return a}function O(c){let y=new DOMParser,a=E(c);if(a.match(/<\/html>/)||a.match(/<\/head>/)||a.match(/<\/body>/)){let s=y.parseFromString(c,"text/html");if(a.match(/<\/html>/))return l.add(s),s;{let r=s.firstChild;return r&&l.add(r),r}}else{let r=y.parseFromString("<body><template>"+c+"</template></body>","text/html").body.querySelector("template").content;return l.add(r),r}}return{normalizeElement:A,normalizeParent:M}})();return{morph:$,defaults:v,mergeJson:oe,mergeScriptText:ae,parseJsonRelaxed:ne,parseRulesRelaxed:pe}})();var st=ce.morph,it=ce.defaults;var ot=ce;return $e(at);})();
|
|
1
|
+
var HyperMorph=(()=>{var ke=Object.defineProperty;var Ze=Object.getOwnPropertyDescriptor;var Qe=Object.getOwnPropertyNames;var Xe=Object.prototype.hasOwnProperty;var et=(e,n)=>{for(var t in n)ke(e,t,{get:n[t],enumerable:!0})},tt=(e,n,t,p)=>{if(n&&typeof n=="object"||typeof n=="function")for(let u of Qe(n))!Xe.call(e,u)&&u!==t&&ke(e,u,{get:()=>n[u],enumerable:!(p=Ze(n,u))||p.enumerable});return e};var nt=e=>tt(ke({},"__esModule",{value:!0}),e);var Ot={};et(Ot,{HyperMorph:()=>fe,default:()=>It,defaults:()=>wt,findChangedRoots:()=>Nt,mergeJson:()=>be,mergeScriptText:()=>Ae,morph:()=>Et,parseJsonRelaxed:()=>pe,parseRulesRelaxed:()=>Ne,spliceProtected:()=>Tt});var $e={includeClasses:!0,includeAttributes:["href","src","name","type","role","aria-label","alt","title"],excludeAttributePrefixes:["data-morph-","data-hyper-","data-im-"],textHintLength:64,excludeIds:!0,maxPathDepth:4,landmarks:["HEADER","NAV","MAIN","ASIDE","FOOTER","SECTION","ARTICLE"],weights:{signature:100,pathSegment:10,textMatch:20,textMismatch:25,uniqueCandidate:50,positionPenalty:1,maxDriftPenalty:19,slotMatch:30},minConfidence:101,maxScoredCandidates:16};function rt(e){let n=5381;for(let t=0;t<e.length;t++)n=(n<<5)+n^e.charCodeAt(t);return Math.abs(n).toString(36)}function st(e){if(e.classList&&e.classList.length>0)return Array.from(e.classList).sort().join(" ");let n=e.getAttribute?.("class");return n?n.split(/\s+/).filter(Boolean).sort().join(" "):""}function it(e,n){let t=[];for(let p of e.attributes||[]){let u=p.name;u==="id"||u==="class"||n.excludeAttributePrefixes.some(g=>u.startsWith(g))||n.includeAttributes.includes(u)&&t.push(`${u}=${p.value}`)}return t.sort().join("|")}function ot(e,n){return(e.textContent||"").replace(/\s+/g," ").trim().slice(0,n.textHintLength)}function at(e,n){let t=[e.tagName];return n.includeClasses&&t.push(st(e)),t.push(it(e,n)),rt(t.join("|"))}function ut(e){let n=e.tagName,t=1,p=e.previousElementSibling;for(;p;)p.tagName===n&&t++,p=p.previousElementSibling;return t}function ct(e,n){return e.getAttribute?.("id")||e.getAttribute?.("role")?!0:n.landmarks.includes(e.tagName)}function lt(e){let n=e.getAttribute?.("id");if(n)return`#${n}`;let t=e.getAttribute?.("role");return t?`@${t}`:e.tagName}function ft(e,n){let t=[],p=e;for(;p&&p.tagName&&t.length<n.maxPathDepth;){let u=`${p.tagName}:${ut(p)}`;if(t.unshift(u),p!==e&&ct(p,n)){t.unshift(lt(p));break}p=p.parentElement}return t}function dt(e,n){let t=0,p=e.length-1,u=n.length-1;for(;p>=0&&u>=0&&e[p]===n[u];)t++,p--,u--;return t}function Q(e,n,t){if(t.has(e))return t.get(e);let p={signature:at(e,n),path:ft(e,n),textHint:ot(e,n)};return t.set(e,p),p}function Pe(e,n,t,p){if(p.has(e))return p.get(e);let u=new Map,g=e.querySelectorAll("*"),y=0;for(let f of g){let S=Q(f,n,t);S.domIndex=y++,!n.shouldIgnore?.(f)&&(u.has(S.signature)||u.set(S.signature,[]),u.get(S.signature).push(f))}return p.set(e,u),u}function ht(e,n,t){t.delete(e),n.delete(e);let p=e.querySelectorAll("*");for(let u of p)n.delete(u)}function Ee(e,n,t,p,u){let g=Q(e,t,p),y=Q(n,t,p),f=t.weights,S={},j=0;if(g.signature!==y.signature)return{score:0,breakdown:{rejected:"signature mismatch"}};j+=f.signature,S.signature=f.signature;let R=dt(g.path,y.path)*f.pathSegment;j+=R,S.path=R;let O=!0;if(g.textHint&&y.textHint?g.textHint===y.textHint?(j+=f.textMatch,S.text=f.textMatch):(j-=f.textMismatch,S.text=-f.textMismatch,O=!1):g.textHint!==y.textHint&&(j-=f.textMismatch,S.text=-f.textMismatch,O=!1),u.candidateCount===1&&O&&(j+=f.uniqueCandidate,S.unique=f.uniqueCandidate),typeof g.domIndex=="number"&&typeof y.domIndex=="number"){let E=Math.abs(g.domIndex-y.domIndex),T=Math.min(E*f.positionPenalty,f.maxDriftPenalty);j-=T,S.drift=-T}return{score:j,breakdown:S}}function je(e,n,t,p,u){if(t.excludeIds&&e.getAttribute("id"))return null;let g=Pe(n,t,p,u),y=Q(e,t,p);if(typeof y.domIndex!="number"){let O=0,E=e.previousElementSibling;for(;E;)O++,E=E.previousElementSibling;y.domIndex=O}let f=g.get(y.signature)||[],S=t.excludeIds?f.filter(O=>!O.getAttribute("id")):f;if(S.length===0)return null;let j=null,q=0,R=null;for(let O of S){let{score:E,breakdown:T}=Ee(e,O,t,p,{candidateCount:S.length});E>q&&(q=E,j=O,R=T)}return q<t.minConfidence?null:{element:j,confidence:q,breakdown:R}}function pt(e,n,t,p){let u=[],g=t.weights.signature+t.weights.slotMatch,y={slot:g};function f(R){if(R.children)return R.children;let O=R.childNodes;if(!O)return[];let E=[];for(let T=0;T<O.length;T++)O[T].nodeType===1&&E.push(O[T]);return E}function S(R,O){let E=f(R),T=f(O);if(E.length===T.length)for(let z=0;z<E.length;z++){let J=E[z],U=T[z];if(t.shouldIgnore?.(J)||t.shouldIgnore?.(U)||t.excludeIds&&(J.getAttribute("id")||U.getAttribute("id"))||J.tagName!==U.tagName)continue;let ee=Q(J,t,p).signature,X=Q(U,t,p).signature;ee!==X&&u.push({newEl:J,oldEl:U,score:g,breakdown:y}),S(J,U)}}function j(R,O){for(;;){if(R.tagName===O.tagName)return[R,O];let E=f(R);if(!R.tagName&&E.length===1){R=E[0];continue}let T=f(O);if(T.length===1&&T[0].tagName===R.tagName){O=T[0];continue}return null}}let q=j(e,n);return q&&S(q[0],q[1]),u}function De(e,n,t,p,u){let g=n.querySelectorAll("*"),y=Pe(e,t,p,u),f=0;for(let E of g){let T=Q(E,t,p);T.domIndex=f++}let S=[],j=new Map;function q(E,T,z){let J=new Set;if(E.textHint){let W=j.get(E.signature);if(!W){W=new Map;for(let te of T){let ge=Q(te,t,p).textHint,ie=W.get(ge);ie||(ie=[],W.set(ge,ie)),ie.push(te)}j.set(E.signature,W)}let ne=W.get(E.textHint);if(ne)for(let te=0;te<ne.length&&te<z;te++)J.add(ne[te])}let U=0,ee=T.length;for(;U<ee;){let W=U+ee>>1;Q(T[W],t,p).domIndex<E.domIndex?U=W+1:ee=W}let X=Math.max(0,Math.min(U-(z>>1),T.length-z)),ae=Math.min(X+z,T.length);for(let W=X;W<ae;W++)J.add(T[W]);return[...J]}for(let E of g){if(t.shouldIgnore?.(E)||t.excludeIds&&E.getAttribute("id"))continue;let T=Q(E,t,p),z=y.get(T.signature)||[],J=t.excludeIds?z.filter(X=>!X.getAttribute("id")):z,U=t.maxScoredCandidates,ee=U&&J.length>U?q(T,J,U):J;for(let X of ee){let{score:ae,breakdown:W}=Ee(E,X,t,p,{candidateCount:J.length});ae>=t.minConfidence&&S.push({newEl:E,oldEl:X,score:ae,breakdown:W})}}if(t.weights.slotMatch>0){let E=pt(n,e,t,p);for(let T of E)S.push(T)}S.sort((E,T)=>T.score-E.score);let R=new Map,O=new Set;for(let{newEl:E,oldEl:T}of S)R.has(E)||O.has(T)||(R.set(E,T),O.add(T));return R}function qe(e,n,t,p){let u=Q(e,t,p),g=Q(n,t,p),{score:y,breakdown:f}=Ee(e,n,t,p,{candidateCount:1});return{matches:y>=t.minConfidence,score:y,breakdown:f,newMeta:{signature:u.signature,path:u.path,textHint:u.textHint},oldMeta:{signature:g.signature,path:g.path,textHint:g.textHint}}}function _e(e={}){let n={...$e,...e,weights:{...$e.weights,...e.weights}},t=new WeakMap,p=new WeakMap;return{findMatch:(u,g)=>je(u,g,n,t,p),computeMatches:(u,g)=>De(u,g,n,t,p),explain:(u,g)=>qe(u,g,n,t),invalidate:u=>ht(u,t,p),session:()=>{let u=new WeakMap,g=new WeakMap;return{findMatch:(y,f)=>je(y,f,n,u,g),computeMatches:(y,f)=>De(y,f,n,u,g),explain:(y,f)=>qe(y,f,n,u)}},getConfig:()=>({...n})}}function we(e,n){for(;;){for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]==="/"&&e[n+1]==="/"){for(;n<e.length&&e[n]!==`
|
|
2
|
+
`;)n++;continue}if(e[n]==="/"&&e[n+1]==="*"){let t=e.indexOf("*/",n+2);if(t===-1)return e.length;n=t+2;continue}return n}}function Fe(e){return e.replace(/\\'/g,"'").replace(/(\\*)"/g,(n,t)=>t.length%2===0?t+'\\"':n)}var mt=/^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?$/,gt=/^[A-Za-z_$][A-Za-z0-9_$]*$/;function pe(e){try{return JSON.parse(e)}catch{return JSON.parse(yt(e))}}function yt(e){let n="",t=0,p=(u,g)=>{throw new Error(`Invalid relaxed JSON: ${u} at position ${g}`)};for(;t<e.length&&(t=we(e,t),!(t>=e.length));){let u=e[t];if("{}[]:".includes(u)){n+=u,t++;continue}if(u===","){let f=we(e,t+1);if(e[f]==="}"||e[f]==="]"){t++;continue}n+=u,t++;continue}if(u==='"'||u==="'"){let f=t+1;for(;f<e.length&&e[f]!==u;)e[f]==="\\"&&f++,f++;f>=e.length&&p("unterminated string",t);let S=e.slice(t+1,f);u==="'"&&(S=Fe(S)),n+='"'+S+'"',t=f+1;continue}let g=t;for(;g<e.length&&/[A-Za-z0-9_$.+\-]/.test(e[g]);)g++;g===t&&p("unexpected character "+JSON.stringify(u),t);let y=e.slice(t,g);if(y==="true"||y==="false"||y==="null"||mt.test(y)){n+=y,t=g;continue}if(gt.test(y)){if(e[we(e,g)]===":"){n+='"'+y+'"',t=g;continue}p("unquoted value "+JSON.stringify(y),t)}p("invalid token "+JSON.stringify(y),t)}return n}function Ne(e){try{return JSON.parse(e)}catch{}let n={BRACE_OPEN:"{",BRACE_CLOSE:"}",BRACKET_OPEN:"[",BRACKET_CLOSE:"]",COLON:":",COMMA:",",STRING:"STRING",SELECTOR:"SELECTOR",IDENTIFIER:"IDENTIFIER",NUMBER:"NUMBER",BOOLEAN:"BOOLEAN"};function t(u){let g=[],y=0;for(;y<u.length;){let f=u[y];if(/\s/.test(f)){y++;continue}if("{}".includes(f)){g.push({type:f,value:f}),y++;continue}if(f==="["){let R=!1,O=y+1;for(;O<u.length&&/\s/.test(u[O]);)O++;if(O<u.length&&/[a-zA-Z_]/.test(u[O])&&(R=!0),!R){g.push({type:f,value:f}),y++;continue}}if(f==="]"){g.push({type:f,value:f}),y++;continue}if(f===":"){g.push({type:n.COLON,value:f}),y++;continue}if(f===","){g.push({type:n.COMMA,value:f}),y++;continue}if(f==='"'||f==="'"){let R=f,O=y+1;for(;O<u.length&&u[O]!==R;)u[O]==="\\"&&O++,O++;g.push({type:n.STRING,value:u.substring(y+1,O),quoted:!0,sourceQuote:R}),y=O+1;continue}let S=y,j;for(;S<u.length&&!/[{},]/.test(u[S]);)if(u[S]===":"){let R=[":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"],O=!1;for(let E of R){let T=E.substring(1);if(u.substring(S+1,S+1+T.length)===T){O=!0,S+=T.length;break}}if(!O)break}else if(u[S]==="["){for(S++;S<u.length&&u[S]!=="]";){if(u[S]==='"'||u[S]==="'"){let R=u[S];for(S++;S<u.length&&u[S]!==R;)u[S]==="\\"&&S++,S++}S++}S<u.length&&u[S]==="]"&&S++}else S++;j=u.substring(y,S);let q=n.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(j)?q=n.NUMBER:j==="true"||j==="false"||j==="null"?q=n.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(j)&&(q=n.SELECTOR),g.push({type:q,value:j,quoted:!1}),y=S}return g}function p(u){let g="";for(let y=0;y<u.length;y++){let f=u[y];if("{}".includes(f.type)||"[]".includes(f.type)){g+=f.value;continue}if(f.type===n.COLON){g+=f.value;continue}if(f.type===n.COMMA){let S=u[y+1];if(S&&(S.type==="}"||S.type==="]"))continue;g+=f.value;continue}if(f.type===n.STRING){let S=f.value;f.sourceQuote==="'"&&(S=Fe(S)),g+=`"${S}"`;continue}if(f.type===n.NUMBER||f.type===n.BOOLEAN){g+=f.value;continue}g+=`"${f.value}"`}return g}try{let u=t(e),g=p(u);return JSON.parse(g)}catch(u){throw new Error("Invalid extraction rules syntax: "+u.message)}}var K=Symbol("hyper-morph-json-merge:missing"),Ve=["id","_id","uuid","key","slug","code","name"];function le(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function me(e,n){return Object.prototype.hasOwnProperty.call(e,n)}function bt(e,n,t){Object.defineProperty(e,n,{value:t,enumerable:!0,writable:!0,configurable:!0})}function se(e,n){if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n)){if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(!se(e[t],n[t]))return!1;return!0}if(le(e)&&le(n)){let t=Object.keys(e);if(t.length!==Object.keys(n).length)return!1;for(let p of t)if(!me(n,p)||!se(e[p],n[p]))return!1;return!0}return!1}function Ke(e,n,t,p){return se(n,t)?n:se(n,e)?t:se(t,e)?n:le(n)&&le(t)?At(le(e)?e:{},n,t,p):Array.isArray(n)&&Array.isArray(t)?kt(Array.isArray(e)?e:[],n,t,p):t}function ze(e,n,t,p){return n===K&&t===K?K:n===K?e===K?t:se(t,e)?K:t:t===K?e===K?n:K:Ke(e,n,t,p)}function At(e,n,t,p){let u={},g=new Set([...Object.keys(e),...Object.keys(n),...Object.keys(t)]);for(let y of g){let f=ze(me(e,y)?e[y]:K,me(n,y)?n[y]:K,me(t,y)?t[y]:K,p);f!==K&&bt(u,y,f)}return u}function St(e){return e===null||typeof e!="object"}function ye(e){return typeof e+":"+String(e)}function Mt(e,n){for(let t of n){let p=new Set;for(let u of t){if(!me(u,e))return!1;let g=u[e];if(typeof g!="string"&&typeof g!="number")return!1;let y=ye(g);if(p.has(y))return!1;p.add(y)}}return!0}function vt(e,n,t,p){let u=[e,n,t],g=!0;for(let y of u)for(let f of y)le(f)||(g=!1);if(g){for(let y of p.keyCandidates)if(Mt(y,u))return{kind:"keyed",field:y};return null}for(let y of u){let f=new Set;for(let S of y){if(!St(S))return null;let j=ye(S);if(f.has(j))return null;f.add(j)}}return{kind:"self"}}function kt(e,n,t,p){let u=vt(e,n,t,p);if(!u)return t;let g=u.kind==="self"?ye:E=>ye(E[u.field]),y=E=>{let T=new Map;for(let z of E)T.set(g(z),z);return T},f=y(e),S=y(n),j=y(t),q=new Map,R=new Set([...f.keys(),...S.keys(),...j.keys()]);for(let E of R){let T=ze(f.has(E)?f.get(E):K,S.has(E)?S.get(E):K,j.has(E)?j.get(E):K,p);T!==K&&q.set(E,T)}let O=[];for(let E of t){let T=g(E);q.has(T)&&O.push(T)}for(let E=0;E<n.length;E++){let T=g(n[E]);if(!q.has(T)||O.includes(T))continue;let z=0;for(let J=E-1;J>=0;J--){let U=O.indexOf(g(n[J]));if(U!==-1){z=U+1;break}}O.splice(z,0,T)}return O.map(E=>q.get(E))}function be(e,n,t,p={}){let u=p.keyCandidates?[...p.keyCandidates,...Ve]:Ve;return Ke(e===void 0?K:e,n,t,{keyCandidates:u})}function Ae(e,n,t,p={}){let u=p.parse||pe,g=[],y=(R,O)=>{if(typeof R!="string")return K;try{return u(R)}catch(E){return g.push(`${O} side is not valid JSON (${E.message})`),K}},f=y(n,"local"),S=y(t,"remote");if(f===K)return{text:t,warnings:g};if(S===K)return{text:n,warnings:g};let j=y(e,"base"),q=be(j===K?void 0:j,f,S,p);return se(q,S)?{text:t,warnings:g}:se(q,f)?{text:n,warnings:g}:{text:JSON.stringify(q,null,2),warnings:g}}var fe=(function(){"use strict";let e=()=>{},n='[save-ignore],[snapshot-remove],[no-snapshot],[no-save],[save-remove],[freeze],[save-freeze],[clay~="no-save"],[clay~="no-snapshot"],[clay~="freeze"]';function t(i){if(!(i instanceof Element))return!1;if(i.matches(n))return!0;if(i.tagName==="LINK"||i.tagName==="SCRIPT"){let v=i.getAttribute("src")||i.getAttribute("href")||"";if(v.startsWith("chrome-extension://")||v.startsWith("moz-extension://")||v.startsWith("safari-web-extension://"))return!0}return!1}function p(i){return i instanceof Element?i.closest(n)?!0:t(i):!1}let u=_e({shouldIgnore:p});function g(i,v,A){if(A){let w=A.identityOf(i);if(w&&!A.disabled.has(w.key))return"hm-merge:"+w.key}if(v!=="smart")return i.outerHTML;let k=i.getAttribute("src"),M=i.getAttribute("type")||"text/javascript";if(k)try{let w=new URL(k,window.location.href);return`ext:${M}:${w.origin}${w.pathname}${w.search}`}catch{return`ext:${M}:${k}`}else{let w=i.textContent.trim(),c=5381;for(let m=0;m<w.length;m++)c=(c<<5)+c^w.charCodeAt(m);return`inline:${M}:${Math.abs(c).toString(36)}`}}let y="http://www.w3.org/1999/xhtml";function f(i){return i instanceof Element&&i.tagName==="SCRIPT"&&i.namespaceURI===y}function S(i){let v=document.createElement("div");v.innerHTML="<script><\/script>";let A=v.firstChild;for(let k of i.attributes)A.setAttribute(k.name,k.value);return A.textContent=i.textContent,A}function j(i){if(f(i))return S(i);if(i instanceof Element)for(let v of i.querySelectorAll("script"))f(v)&&v.replaceWith(S(v));return i}function q(i){let v=(i.getAttribute("type")||"").split(";")[0].trim().toLowerCase();return v==="application/json"||v.endsWith("+json")}let R={match:i=>i.hasAttribute("merge"),identity:i=>i.getAttribute("merge")};function O(i,v,A){if(A.merge===!1)return null;let k=[R,...A.mergeTags||[]],M=new WeakMap,w=o=>{if(M.has(o))return M.get(o);let d=null;if(f(o)&&!o.getAttribute("src")&&!p(o)){let h=o;for(let I=0;I<k.length;I++)if(k[I].match(h)){if(!q(h))console.warn("[hyper-morph] merge ignored: script type is not JSON",h);else{let $=k[I].identity(h);$!=null&&$!==""&&(d={key:I+":"+$,raw:$,recognizer:k[I]})}break}}return M.set(o,d),d},c=new Set,m=o=>{let d=new Map,h=I=>{let $=w(I);$&&(d.has($.key)?(c.add($.key),console.warn(`[hyper-morph] merge disabled for duplicate identity "${$.raw}"`)):d.set($.key,I))};f(o)&&h(o);for(let I of o.querySelectorAll("script"))h(I);return d},a=m(i),s=m(v.__hyperMorphRoot||v);if(a.size===0&&s.size===0)return null;let r=null;return{identityOf:w,disabled:c,oldByKey:a,newByKey:s,baseTexts:()=>{if(r)return r;r=new Map;let o=A.mergeBase;if(!o)return r;let d;typeof o=="string"?d=new DOMParser().parseFromString(o,"text/html").documentElement:o instanceof Document?d=o.documentElement:d=o;let h=I=>{let $=w(I);$&&!r.has($.key)&&r.set($.key,I.textContent)};f(d)&&h(d);for(let I of d.querySelectorAll("script"))h(I);return r}}}function E(i,v,A){let k=i.merge;if(!k)return!1;let M=k.identityOf(v);if(!M||k.disabled.has(M.key))return!1;let w=k.identityOf(A);if(!w||w.key!==M.key)return!1;let c=v,m=A,a=m.getAttribute("merge-key")||c.getAttribute("merge-key"),{text:s,warnings:r}=Ae(k.baseTexts().get(M.key),c.textContent,m.textContent,{parse:M.recognizer.parse,keyCandidates:a?a.split(/[\s,]+/).filter(Boolean):void 0});for(let l of r)console.warn(`[hyper-morph] merge "${M.raw}": ${l}`);return c.textContent!==s&&(c.textContent=s),!0}let T={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:e,afterNodeAdded:e,beforeNodeMorphed:e,afterNodeMorphed:e,beforeNodeRemoved:e,afterNodeRemoved:e,beforeAttributeUpdated:e},head:{style:"merge",shouldPreserve:i=>i.getAttribute("im-preserve")==="true",shouldReAppend:i=>i.getAttribute("im-re-append")==="true",shouldRemove:e,afterHeadMorphed:e},scripts:{handle:!0,matchMode:"outerHTML",shouldPreserve:i=>i.getAttribute("im-preserve")==="true",shouldReAppend:i=>i.getAttribute("im-re-append")==="true",shouldRemove:e,afterScriptsHandled:e},restoreFocus:!0},z={computeMatches(i,v){let{computeMatches:A}=u.session();return A(i,v)}};function J(i,v,A={}){i=We(i);let k=Te(v),M=Ue(i,k,A),w=M.scripts.handle?new Set(Array.from(i.querySelectorAll("script")).map(s=>g(s,M.scripts.matchMode,M.merge))):null,c=X(M),m=te(M,i,k,s=>s.morphStyle==="innerHTML"?(W(s,i,k),Array.from(i.childNodes)):ee(s,i,k)),a=s=>{c&&ae(M,c),U(M);let r=w?Je(s,w,M):[];return r.length>0?Promise.all(r).then(()=>s):s};return m instanceof Promise?m.then(a):a(m)}function U(i){for(let v of Array.from(i.pantry.childNodes))i.callbacks.beforeNodeRemoved(v)!==!1&&i.callbacks.afterNodeRemoved(v);i.pantry.remove()}function ee(i,v,A){let k=Te(v);return W(i,k,A,v,v.nextSibling),Array.from(k.childNodes)}function X(i){if(!i.config.restoreFocus)return null;let v=document.activeElement;if(!(v instanceof HTMLInputElement||v instanceof HTMLTextAreaElement))return null;let{id:A,selectionStart:k,selectionEnd:M}=v;return{element:v,id:A,selectionStart:k,selectionEnd:M}}function ae(i,v){let A=v.element;if(v.id&&v.id!==document.activeElement?.getAttribute("id")&&(A=i.target.querySelector(`[id="${CSS.escape(v.id)}"]`),A?.focus()),A&&!A.selectionEnd&&v.selectionEnd!=null)try{A.setSelectionRange(v.selectionStart,v.selectionEnd)}catch{}}let W=(function(){function i(s,r,l,o=null,d=null){r instanceof HTMLTemplateElement&&l instanceof HTMLTemplateElement&&(r=r.content,l=l.content),o||=r.firstChild;for(let h of l.childNodes){if(t(h))continue;if(o&&o!=d){let $=A(s,h,o,d);if($){$!==o&&M(s,o,$),ne($,h,s),o=$.nextSibling;continue}}if(h instanceof Element){let $=h.getAttribute("id");if(s.persistentIds.has($)){let b=w(r,$,o,s);ne(b,h,s),o=b.nextSibling;continue}if(!s.idMap.has(h)){let b=s.hyperMatches.get(h);if(b&&!s.idMap.has(b)&&!a(b,r)){m(r,b,o),ne(b,h,s),o=b.nextSibling;continue}}}let I=v(r,h,o,s);I&&(o=I.nextSibling)}for(;o&&o!=d;){let h=o;o=o.nextSibling,t(h)||k(s,h)}}function v(s,r,l,o){if(o.callbacks.beforeNodeAdded(r)===!1)return null;if(o.idMap.has(r)){let d=r,h=document.createElementNS(d.namespaceURI,d.localName);return s.insertBefore(h,l),ne(h,r,o),o.callbacks.afterNodeAdded(h),h}else{let d=j(document.importNode(r,!0));return s.insertBefore(d,l),o.callbacks.afterNodeAdded(d),d}}let A=(function(){function s(o,d,h,I){let $=d instanceof Element&&!o.idMap.has(d)?o.hyperMatches.get(d):null,b=null,N=d.nextSibling,P=0,H=h;for(;H&&H!=I;){if(t(H)){H=H.nextSibling;continue}if(l(H,d)){if(r(o,H,d)||H===$&&!o.idMap.has(H))return H;if(b===null){let _=H instanceof Element&&o.hyperMatchedOldElements.has(H);!o.idMap.has(H)&&!_&&(b=H)}}if(b===null&&N&&l(H,N)&&(P++,N=N.nextSibling,P>=2&&(b=void 0)),o.activeElementAndParents.includes(H))break;H=H.nextSibling}return b||null}function r(o,d,h){let I=o.idMap.get(d),$=o.idMap.get(h);if(!$||!I)return!1;for(let b of I)if($.has(b))return!0;return!1}function l(o,d){let h=o,I=d;return h.nodeType===I.nodeType&&h.tagName===I.tagName&&(!h.getAttribute?.("id")||h.getAttribute?.("id")===I.getAttribute?.("id"))}return s})();function k(s,r){let l=r instanceof Element&&s.hyperMatchedOldElements.has(r)&&!s.idMap.has(r);if(s.idMap.has(r)||l)m(s.pantry,r,null);else{if(s.callbacks.beforeNodeRemoved(r)===!1)return;r.parentNode?.removeChild(r),s.callbacks.afterNodeRemoved(r)}}function M(s,r,l){let o=r;for(;o&&o!==l;){let d=o;o=o.nextSibling,t(d)||k(s,d)}return o}function w(s,r,l,o){let d=o.target.getAttribute?.("id")===r&&o.target||o.target.querySelector(`[id="${CSS.escape(r)}"]`)||o.pantry.querySelector(`[id="${CSS.escape(r)}"]`);return c(d,o),m(s,d,l),d}function c(s,r){let l=s.getAttribute("id");for(;s=s.parentNode;){let o=r.idMap.get(s);o&&(o.delete(l),o.size||r.idMap.delete(s))}}function m(s,r,l){if(s.moveBefore)try{s.moveBefore(r,l)}catch{s.insertBefore(r,l)}else s.insertBefore(r,l)}function a(s,r){let l=r instanceof Element?r:r.realParentNode;return!!l&&s.contains(l)}return i})(),ne=(function(){function i(c,m,a){return a.ignoreActive&&c===document.activeElement?null:(a.callbacks.beforeNodeMorphed(c,m)===!1||(c instanceof HTMLHeadElement&&a.head.ignore||(c instanceof HTMLHeadElement&&a.head.style!=="morph"?ie(c,m,a):(v(c,m,a),E(a,c,m)||w(c,a)||W(a,c,m))),a.callbacks.afterNodeMorphed(c,m)),c)}function v(c,m,a){let s=m.nodeType;if(s===1){let r=c,l=m,o=r.attributes,d=l.attributes;for(let h of d)M(h.name,r,"update",a)||r.getAttribute(h.name)!==h.value&&r.setAttribute(h.name,h.value);for(let h=o.length-1;0<=h;h--){let I=o[h];if(I&&!l.hasAttribute(I.name)){if(M(I.name,r,"remove",a))continue;r.removeAttribute(I.name)}}w(r,a)||A(r,l,a)}(s===8||s===3)&&c.nodeValue!==m.nodeValue&&(c.nodeValue=m.nodeValue)}function A(c,m,a){if(c instanceof HTMLInputElement&&m instanceof HTMLInputElement&&m.type!=="file"){let s=m.value,r=c.value;k(c,m,"checked",a),k(c,m,"disabled",a),a.formStateSync==="property"&&c.indeterminate!==m.indeterminate&&(c.indeterminate=m.indeterminate),a.formStateSync==="property"?r!==s&&(M("value",c,"update",a)||(c.value=s)):m.hasAttribute("value")?r!==s&&(M("value",c,"update",a)||(c.setAttribute("value",s),c.value=s)):M("value",c,"remove",a)||(c.value="",c.removeAttribute("value"))}else if(c instanceof HTMLOptionElement&&m instanceof HTMLOptionElement)k(c,m,"selected",a);else if(c instanceof HTMLTextAreaElement&&m instanceof HTMLTextAreaElement){let s=m.value,r=c.value;if(M("value",c,"update",a)||(s!==r&&(c.value=s),a.formStateSync==="property"))return;c.firstChild&&c.firstChild.nodeValue!==s&&(c.firstChild.nodeValue=s)}}function k(c,m,a,s){let r=m[a],l=c[a];if(r!==l){let o=M(a,c,"update",s);if(o||(c[a]=m[a]),s.formStateSync==="property")return;r?o||c.setAttribute(a,""):M(a,c,"remove",s)||c.removeAttribute(a)}}function M(c,m,a,s){return c==="value"&&s.ignoreActiveValue&&m===document.activeElement?!0:s.callbacks.beforeAttributeUpdated(c,m,a)===!1}function w(c,m){return!!m.ignoreActiveValue&&c===document.activeElement&&c!==document.body}return i})();function te(i,v,A,k){if(i.head.block){let M=v.querySelector("head"),w=A.querySelector("head");if(M&&w){let c=ie(M,w,i);return Promise.all(c).then(()=>(i.head.block=!1,i.head.ignore=!0,k(i)))}}return k(i)}function ge(i){return i.tagName==="SCRIPT"?!!i.getAttribute("src"):i.tagName==="LINK"?(i.getAttribute("rel")||"").toLowerCase().split(/\s+/).includes("stylesheet")&&!!i.getAttribute("href"):!1}function ie(i,v,A){let k=[],M=[],w=[],c=[],m=A.scripts.matchMode,a=l=>{if(l.tagName==="SCRIPT")return g(l,m,A.merge);if(l.tagName==="LINK"&&m==="smart"){let o=l.getAttribute("href");if(o)try{let d=new URL(o,window.location.href);return`link:${l.getAttribute("rel")||""}:${d.origin}${d.pathname}${d.search}`}catch{}}return l.outerHTML},s=new Map;for(let l of v.children){if(t(l))continue;let o=a(l),d=s.get(o);d||(d=[],s.set(o,d)),d.push(l)}for(let l of i.children){let o=a(l),d=s.get(o),h=!!(d&&d.length),I=A.head.shouldReAppend(l),$=A.head.shouldPreserve(l);if(h||$)if(I)M.push(l);else{if(d&&d.length){let b=d.pop();d.length||s.delete(o),E(A,l,b)}w.push(l)}else A.head.style==="append"?I&&(M.push(l),c.push(l)):A.head.shouldRemove(l)!==!1&&!t(l)&&M.push(l)}for(let l of s.values())c.push(...l);let r=[];for(let l of c){let o=document.createRange().createContextualFragment(l.outerHTML).firstChild;if(A.callbacks.beforeNodeAdded(o)!==!1){if(o instanceof Element&&ge(o)){let d,h=new Promise(function(I){d=I});o.addEventListener("load",function(){d()}),o.addEventListener("error",function(){d()}),r.push(h)}i.appendChild(o),A.callbacks.afterNodeAdded(o),k.push(o)}}for(let l of M)A.callbacks.beforeNodeRemoved(l)!==!1&&(i.removeChild(l),A.callbacks.afterNodeRemoved(l));return A.head.afterHeadMorphed(i,{added:k,kept:w,removed:M}),r}function Je(i,v,A){if(!A.scripts.handle)return[];let k=[],M=[],w=[],c=[],m=A.scripts.matchMode,a=[];for(let r of i)if(r instanceof Element){f(r)&&a.push(r);for(let l of r.querySelectorAll("script"))f(l)&&a.push(l)}for(let r of a){if(r.closest("head")||p(r))continue;let l=g(r,m,A.merge),o=v.has(l),d=A.scripts.shouldPreserve(r),h=A.scripts.shouldReAppend(r);o||d?h?(M.push(r),c.push(r)):w.push(r):c.push(r)}let s=[];for(let r of c){if(A.callbacks.beforeNodeAdded(r)===!1)continue;let l=document.createElement("script");for(let o of r.attributes)l.setAttribute(o.name,o.value);if(l.textContent=r.textContent,l.src){let o,d=new Promise(function(h){o=h});l.addEventListener("load",function(){o()}),l.addEventListener("error",function(){o()}),s.push(d)}r.replaceWith(l),A.callbacks.afterNodeAdded(l),k.push(l)}return A.scripts.afterScriptsHandled(A.target,{added:k,kept:w,removed:M}),s}let Ue=(function(){function i(a,s,r){let{persistentIds:l,idMap:o}=c(a,s),d=z.computeMatches(a,s);if(typeof r.key=="function"){let N=new Map,P=new Set,H=C=>{let x=r.key(C);x!=null&&(N.has(x)?P.add(x):N.set(x,C))};a instanceof Element&&H(a);for(let C of a.querySelectorAll("*"))H(C);for(let C of P)N.delete(C);let _=new Map;for(let[C,x]of d)_.set(x,C);let Z=s.__hyperMorphRoot||s,Y=new Map,V=new Set,L=C=>{let x=r.key(C);x!=null&&(Y.has(x)?V.add(x):Y.set(x,C))};Z instanceof Element&&L(Z);for(let C of Z.querySelectorAll("*"))L(C);for(let C of V)Y.delete(C);for(let[C,x]of Y){let D=N.get(C);if(!D||D.tagName!==x.tagName)continue;let F=_.get(D);F&&F!==x&&d.delete(F);let oe=d.get(x);oe&&oe!==D&&_.delete(oe),d.set(x,D),_.set(D,x)}}let h=v(r),I=O(a,s,h.scripts);if(I){let N=new Map;for(let[P,H]of d)N.set(H,P);for(let[P,H]of I.newByKey){if(I.disabled.has(P))continue;let _=I.oldByKey.get(P);if(!_)continue;let Z=N.get(_);Z&&Z!==H&&d.delete(Z);let Y=d.get(H);Y&&Y!==_&&N.delete(Y),d.set(H,_),N.set(_,H)}}let $=new Set;for(let N of d.values())$.add(N);let b=h.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(b))throw new Error(`Do not understand how to morph style ${b}`);return{target:a,newContent:s,config:h,morphStyle:b,ignoreActive:h.ignoreActive,ignoreActiveValue:h.ignoreActiveValue,restoreFocus:h.restoreFocus,formStateSync:h.formStateSync||"attribute",idMap:o,persistentIds:l,hyperMatches:d,hyperMatchedOldElements:$,merge:I,pantry:A(),activeElementAndParents:k(a),callbacks:h.callbacks,head:h.head,scripts:h.scripts}}function v(a){let s=Object.assign({},T);return Object.assign(s,a),s.callbacks=Object.assign({},T.callbacks,a.callbacks),s.head=Object.assign({},T.head,a.head),s.scripts=Object.assign({},T.scripts,a.scripts),s}function A(){let a=document.createElement("div");return a.hidden=!0,document.body.insertAdjacentElement("afterend",a),a}function k(a){let s=[],r=document.activeElement;if(r?.tagName!=="BODY"&&a.contains(r))for(;r&&(s.push(r),r!==a);)r=r.parentElement;return s}function M(a){let s=Array.from(a.querySelectorAll("[id]"));return a.getAttribute?.("id")&&s.push(a),s}function w(a,s,r,l){for(let o of l){let d=o.getAttribute("id");if(s.has(d)){let h=o;for(;h;){let I=a.get(h);if(I==null&&(I=new Set,a.set(h,I)),I.add(d),h===r)break;h=h.parentElement}}}}function c(a,s){let r=M(a),l=M(s),o=m(r,l),d=new Map;w(d,o,a,r);let h=s.__hyperMorphRoot||s;return w(d,o,h,l),{persistentIds:o,idMap:d}}function m(a,s){let r=new Set,l=new Map;for(let d of a){let h=d.getAttribute("id");l.has(h)?r.add(h):l.set(h,d.tagName)}let o=new Set;for(let d of s){let h=d.getAttribute("id");o.has(h)?r.add(h):l.get(h)===d.tagName&&o.add(h)}for(let d of r)o.delete(d);return o}return i})(),{normalizeElement:We,normalizeParent:Te}=(function(){let i=new WeakSet;function v(c){return c instanceof Document?c.documentElement:c}function A(c){if(c==null)return document.createElement("div");if(typeof c=="string")return A(w(c));if(i.has(c))return c;if(c instanceof Node){if(c.parentNode)return new k(c);{let m=document.createElement("div");return m.append(c),m}}else{let m=document.createElement("div");for(let a of[...c])m.append(a);return m}}class k{constructor(m){this.originalNode=m,this.realParentNode=m.parentNode,this.previousSibling=m.previousSibling,this.nextSibling=m.nextSibling}get childNodes(){let m=[],a=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;for(;a&&a!=this.nextSibling;)m.push(a),a=a.nextSibling;return m}querySelectorAll(m){return this.childNodes.reduce((a,s)=>{if(s instanceof Element){s.matches(m)&&a.push(s);let r=s.querySelectorAll(m);for(let l=0;l<r.length;l++)a.push(r[l])}return a},[])}insertBefore(m,a){return this.realParentNode.insertBefore(m,a)}moveBefore(m,a){return this.realParentNode.moveBefore(m,a)}get __hyperMorphRoot(){return this.originalNode}}function M(c){let m=l=>`<${l}(?:\\s(?:[^>"']|"[^"]*"|'[^']*')*)?>`,a=c.replace(/<!--[\s\S]*?-->/g,"");for(let l of["script","style","textarea","title"])a=a.replace(new RegExp(`${m(l)}[\\s\\S]*?</${l}\\s*>`,"gi"),"");let s=new RegExp(`${m("svg")}[\\s\\S]*?</svg\\s*>`,"gi"),r;do r=a,a=a.replace(s,"");while(a!==r);return a}function w(c){let m=new DOMParser,a=M(c);if(a.match(/<\/html>/)||a.match(/<\/head>/)||a.match(/<\/body>/)){let s=m.parseFromString(c,"text/html");if(a.match(/<\/html>/))return i.add(s),s;{let r=s.firstChild;return r&&i.add(r),r}}else{let r=m.parseFromString("<body><template>"+c+"</template></body>","text/html").body.querySelector("template").content;return i.add(r),r}}return{normalizeElement:v,normalizeParent:A}})(),Ie=Symbol("hyper-morph-duplicate-key"),Oe=[i=>i.getAttribute("data-id"),i=>i.getAttribute("id")];function de(i,v){return v.map(A=>{let k=new Map;for(let M of i){if(M.nodeType!==1)continue;let w=A(M);w==null||w===""||k.set(w,k.has(w)?Ie:M)}return k})}function xe(i,v,A,k){for(let M=0;M<k.length;M++){let w=k[M](i);if(w==null||w===""||v[M].get(w)!==i)continue;let c=A[M].get(w);if(!(!c||c===Ie)&&c.tagName===i.tagName)return c}return null}function ue(i,v,A){for(let k=0;k<A.length;k++){let M=A[k](i);if(!(M==null||M==="")&&v[k].get(M)===i)return!0}return!1}function Ge(i,v,A={}){let k=A.skip||(()=>!1),M=A.ignoreAttr||(()=>!1),w=A.tiers&&A.tiers.length?A.tiers:Oe,c=null;function m(){return c||(c=de([i,...i.querySelectorAll("*")],w)),c}let a=null;function s(){return a||(a=de([v,...v.querySelectorAll("*")],w)),a}function r(L){return!L.parentElement||!L.parentElement.parentElement}function l(L,C,x){return r(L)||ue(L,m(),w)?(x.push({type:"subtree",el:L,base:C}),!1):!0}function o(L,C){let x=[];for(let D of L.attributes)M(L,D.name)||C.getAttribute(D.name)!==D.value&&x.push(D.name);for(let D of C.attributes)M(L,D.name)||L.hasAttribute(D.name)||x.push(D.name);return x}function d(L){let C=[],x=null,D=()=>{x!==null&&(C.push({nodeType:3,nodeValue:x}),x=null)};for(let F of L.childNodes){if(F.nodeType===3){x=(x===null?"":x)+F.nodeValue;continue}F.nodeType===1&&k(F)||(D(),(F.nodeType===1||F.nodeType===8)&&C.push(F))}return D(),C}function h(L,C){if(L.nodeType!==C.nodeType)return!1;if(L.nodeType!==1)return!0;if(L.tagName!==C.tagName)return!1;for(let x of w){let D=x(L),F=x(C);if(D!=null&&D!==""&&F!=null&&F!==""&&D!==F)return!1}return!0}function I(L){let C="";for(let x of L)x.nodeType===3&&x.nodeValue.trim()!==""?C+="\0"+x.nodeValue:x.nodeType===8&&(C+=""+x.nodeValue);return C}function $(L,C,x){let D=d(L),F=d(C);if(D.length===F.length){let B=!0;for(let G=0;G<D.length;G++)if(!h(D[G],F[G])){B=!1;break}if(B){for(let G=0;G<D.length;G++){let ce=D[G];if(ce.nodeType===1){if(b(ce,F[G],x))return!0}else if(ce.nodeValue!==F[G].nodeValue)return!0}return!1}}let oe=D.filter(B=>B.nodeType===1),Se=F.filter(B=>B.nodeType===1);if(I(D)!==I(F))return!0;let Le=de(oe,w),Ce=de(Se,w),Me=[],ve=new Set,He=[];for(let B of oe){let G=xe(B,Le,Ce,w);G&&!ve.has(G)?(Me.push([B,G]),ve.add(G)):He.push(B)}let re=[];for(let B of He)ue(B,Le,w)?x.push({type:"subtree",el:B,base:null}):re.push(B);let he=[];for(let B of Se)ve.has(B)||(ue(B,Ce,w)?x.push({type:"deletion",el:B}):he.push(B));if(re.length!==he.length)return!0;for(let B=0;B<re.length;B++)if(!h(re[B],he[B]))return!0;let Re=new Map(Me);for(let B=0;B<re.length;B++)Re.set(re[B],he[B]);let Be=-1;for(let B of oe){let G=Re.get(B);if(!G)continue;let ce=Se.indexOf(G);if(ce<Be)return!0;Be=ce}for(let B=0;B<re.length;B++)if(b(re[B],he[B],x))return!0;for(let[B,G]of Me)if(b(B,G,x))return!0;return!1}function b(L,C,x){if(L.tagName!==C.tagName)return l(L,C,x);let D=o(L,C),F=[];if($(L,C,F))return l(L,C,x);if(D.length){if(!r(L)&&!ue(C,s(),w))return!0;x.push({type:"attrs",el:L,names:D,base:C})}return x.push(...F),!1}let N=[],P=o(i,v);P.length&&N.push({type:"attrs",el:i,names:P});let H=(L,C)=>Array.from(L.children).find(x=>x.tagName===C)||null,_=H(i,"HEAD"),Z=H(v,"HEAD");if(_&&Z){let L=[];b(_,Z,L),L.length&&N.push({type:"head",el:_})}else(_||Z)&&_&&N.push({type:"head",el:_});let Y=H(i,"BODY"),V=H(v,"BODY");return Y&&V?b(Y,V,N):Y&&N.push({type:"subtree",el:Y,base:null}),{entries:N}}function Ye(i,v,A={}){let k=A.tiers&&A.tiers.length?A.tiers:Oe,M=i.documentElement,w=[],c=0,m=b=>({ok:!1,placed:w,held:b,skippedAttrs:c});if(!M)return m(null);function a(b){let N=[b,...b.querySelectorAll("*")];return de(N,k)}let s=a(M),r=new Map,l=b=>{let N=b.getRootNode(),P=r.get(N);if(!P){let H=N.nodeType===9?N.documentElement:N;P=a(H),r.set(N,P)}return P};function o(b){if(!b.parentElement&&b.tagName==="HTML")return M;if(b.parentElement&&!b.parentElement.parentElement&&b.parentElement.tagName==="HTML"){if(b.tagName==="BODY")return i.body||null;if(b.tagName==="HEAD")return i.head||null}return null}function d(b){let N=o(b);return N||xe(b,l(b),s,k)}function h(b){if(!b)return null;let N=d(b);return N&&N.isConnected?N:null}function I(b){for(let N=0;N<k.length;N++){let P=k[N](b);P!=null&&P!==""&&s[N].set(P,b)}}for(let b of v){if(b.type!=="deletion")continue;let N=d(b.el);N&&N!==M&&N.remove()}let $=v.filter(b=>b.type!=="deletion").sort((b,N)=>b.el===N.el?0:b.el.compareDocumentPosition(N.el)&Node.DOCUMENT_POSITION_FOLLOWING?-1:1);for(let b of $){if(b.type==="head"){let V=i.importNode(b.el,!0);i.head?i.head.replaceWith(V):M.insertBefore(V,M.firstChild),w.push({entry:b,imported:V});continue}if(b.type==="attrs"){let V=h(b.el)||h(b.base);if(!V){c++;continue}for(let L of b.names)b.el.hasAttribute(L)?V.setAttribute(L,b.el.getAttribute(L)):V.removeAttribute(L);continue}let N=b.el;if(o(N))return m(b);let P=h(N)||h(b.base);if(P){let V=i.importNode(N,!0);P.replaceWith(V),I(V),w.push({entry:b,imported:V});continue}if(b.base!=null&&!ue(b.base,l(b.base),k)||!ue(N,l(N),k))return m(b);let H=N.parentElement;if(!H)return m(b);let _=h(H);if(!_)return m(b);let Z=null;for(let V=N.previousElementSibling;V;V=V.previousElementSibling){let L=h(V);if(L&&L.parentNode===_){Z=L;break}}let Y=i.importNode(N,!0);if(Z)_.insertBefore(Y,Z.nextSibling);else{let V=Array.prototype.indexOf.call(H.children,N);_.insertBefore(Y,_.children[V]||null)}I(Y),w.push({entry:b,imported:Y})}return{ok:!0,placed:w,held:null,skippedAttrs:c}}return{morph:J,defaults:T,findChangedRoots:Ge,spliceProtected:Ye,mergeJson:be,mergeScriptText:Ae,parseJsonRelaxed:pe,parseRulesRelaxed:Ne}})();var Et=fe.morph,wt=fe.defaults,Nt=fe.findChangedRoots,Tt=fe.spliceProtected;var It=fe;return nt(Ot);})();
|
|
3
3
|
|
|
4
4
|
// Convenience morph wrapper with data-id support
|
|
5
5
|
var morph = function(oldEl, newEl, options = {}) {
|
|
@@ -20,4 +20,6 @@ if (!window.__hyperclayNoAutoExport) {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export { HyperMorph, morph };
|
|
23
|
+
export const findChangedRoots = HyperMorph.findChangedRoots;
|
|
24
|
+
export const spliceProtected = HyperMorph.spliceProtected;
|
|
23
25
|
export default HyperMorph;
|