hyper-html-api 0.1.0 → 0.2.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/README.md +22 -8
- package/dist/hyper-html-api.min.js +3 -2
- package/package.json +7 -3
- package/src/adapters/cheerio.js +47 -7
- package/src/adapters/dom.js +31 -6
- package/src/cms/form-builder.js +431 -0
- package/src/cms/index.js +4 -0
- package/src/cms/morph.js +44 -0
- package/src/cms/path.js +105 -0
- package/src/cms/scaffold.js +24 -0
- package/src/cms/widget-handles.js +17 -0
- package/src/engine/apply.js +63 -27
- package/src/engine/diff.js +54 -16
- package/src/engine/dom-properties.js +53 -6
- package/src/engine/errors.js +11 -1
- package/src/engine/extract.js +16 -16
- package/src/engine/index.js +34 -0
- package/src/engine/rules-tag.js +28 -6
- package/src/engine/rules.js +24 -5
- package/src/hyper-html-api.js +13 -4
package/README.md
CHANGED
|
@@ -12,10 +12,11 @@ npm install hyper-html-api
|
|
|
12
12
|
|
|
13
13
|
## Rules tag
|
|
14
14
|
|
|
15
|
-
Pages describe their data layer with a
|
|
15
|
+
Pages describe their data layer with a script tag labeled by one or more
|
|
16
|
+
space-separated tokens in a single `data-rules-name` attribute:
|
|
16
17
|
|
|
17
18
|
```html
|
|
18
|
-
<script type="application/
|
|
19
|
+
<script type="application/json" data-rules-name="api cms collection" data-rules-version="1">
|
|
19
20
|
{
|
|
20
21
|
"title": "h1",
|
|
21
22
|
"user": { "name": ".user-name", "role": ".user-role" },
|
|
@@ -25,24 +26,37 @@ Pages describe their data layer with a single script tag:
|
|
|
25
26
|
</script>
|
|
26
27
|
```
|
|
27
28
|
|
|
29
|
+
Tokens are looked up with the CSS word-match selector
|
|
30
|
+
`script[data-rules-name~="<token>"]`, so a single tag can serve several roles at
|
|
31
|
+
once. There is no implicit unnamed tag: a consumer matches its token or finds
|
|
32
|
+
nothing.
|
|
33
|
+
|
|
28
34
|
## Browser API
|
|
29
35
|
|
|
30
36
|
```js
|
|
31
|
-
HyperHtmlApi.engine.extract(root, rules)
|
|
32
|
-
HyperHtmlApi.engine.apply(root, rules, data)
|
|
33
|
-
HyperHtmlApi.engine.findRulesIn(root)
|
|
34
|
-
HyperHtmlApi.engine.
|
|
37
|
+
HyperHtmlApi.engine.extract(root, rules) // → JSON
|
|
38
|
+
HyperHtmlApi.engine.apply(root, rules, data) // mutates the DOM
|
|
39
|
+
HyperHtmlApi.engine.findRulesIn(root, token?) // → { rules, tagNode } | null
|
|
40
|
+
HyperHtmlApi.engine.findRules(root, source) // object | token → { rules, tagNode } | null
|
|
41
|
+
HyperHtmlApi.engine.bind(root, source, opts?) // → { rules, tagNode, get(), set(data) }
|
|
42
|
+
HyperHtmlApi.engine.errors // error class refs
|
|
35
43
|
```
|
|
36
44
|
|
|
45
|
+
`bind` accepts a source that is either a literal rules object, a token string
|
|
46
|
+
(a tag with `data-rules-name~="token"`), and returns a small port whose `get()`
|
|
47
|
+
extracts data and `set(data)` writes it back. Token resolution is
|
|
48
|
+
document-scoped, so a tag mounted in `<head>` is found even when `bind` is given
|
|
49
|
+
a body or form element; `get()`/`set()` stay scoped to that element.
|
|
50
|
+
|
|
37
51
|
## Node API
|
|
38
52
|
|
|
39
53
|
```js
|
|
40
|
-
import { extract, apply, findRulesIn, errors } from 'hyper-html-api/engine'
|
|
54
|
+
import { extract, apply, findRulesIn, bind, errors } from 'hyper-html-api/engine'
|
|
41
55
|
import cheerioAdapter from 'hyper-html-api/cheerio'
|
|
42
56
|
import * as cheerio from 'cheerio'
|
|
43
57
|
|
|
44
58
|
const $ = cheerio.load(html)
|
|
45
|
-
const { rules } = findRulesIn(cheerioAdapter, $.root())
|
|
59
|
+
const { rules } = findRulesIn(cheerioAdapter, $.root(), 'api')
|
|
46
60
|
const data = extract(cheerioAdapter, $.root(), rules)
|
|
47
61
|
```
|
|
48
62
|
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
var HyperHtmlApi=(()=>{var B=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var ae=Object.prototype.hasOwnProperty;var ee=(e,t)=>{for(var r in t)B(e,r,{get:t[r],enumerable:!0})},ue=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of le(t))!ae.call(e,n)&&n!==r&&B(e,n,{get:()=>t[n],enumerable:!(o=ce(t,n))||o.enumerable});return e};var de=e=>ue(B({},"__esModule",{value:!0}),e);var Be={};ee(Be,{cms:()=>ie,default:()=>qe,engine:()=>se,upgrade:()=>fe});var C=["textContent","innerText","innerHTML","outerHTML","value","checked","selected","disabled","readOnly","type","tagName","nodeName","nodeType","nodeValue","childElementCount","id","className","classList","href","src","action","baseURI","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","dataset","currentSrc","duration","paused","title","documentURI","contentType"],O=new Set(C);var D={};ee(D,{EmptyListInsert:()=>b,MaxRuleDepthExceeded:()=>E,RulesParseError:()=>x,ShapeMismatch:()=>M,UnknownRulesVersion:()=>T,UpgradeAlreadyRegistered:()=>w});var x=class extends Error{constructor(t,r){super(t),this.name="RulesParseError",this.cause=r}},T=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},E=class extends Error{constructor(t){super(`rule depth exceeded 20 at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},M=class extends Error{constructor(t){super(`shape mismatch: ${t.length} field(s) failed validation`),this.name="ShapeMismatch",this.mismatches=t}},b=class extends Error{constructor(t){super(`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}},w=class extends Error{constructor(){super("upgrade transform already registered; only one registration is allowed per page."),this.name="UpgradeAlreadyRegistered"}};var pe=20;function A(e,t,r){return $(e,t,r,{depth:0,path:[]})}function $(e,t,r,o){if(o.depth>pe)throw new E(o.path);if(typeof r=="string")return he(e,t,r);if(Array.isArray(r)){let[n,s]=r;return e.find(t,n).map((i,f)=>$(e,i,s,{depth:o.depth+1,path:[...o.path,f]}))}if(typeof r=="object"&&r!==null){let n={};for(let[s,c]of Object.entries(r))n[s]=$(e,t,c,{depth:o.depth+1,path:[...o.path,s]});return n}return null}function he(e,t,r){if(r.endsWith("[]")){let n=r.slice(0,-2);return e.find(t,n).map(s=>e.text(s))}if(r.startsWith("@"))return te(e,t,r.slice(1));if(r.includes("@")){let[n,s]=r.split("@"),c=n?e.find(t,n):[t];return c.length===0?null:te(e,c[0],s)}if(r===".")return e.text(t);let o=e.find(t,r);return o.length===0?null:e.text(o[0])}function te(e,t,r){if(O.has(r)){let n=e.prop(t,r);return n==null?null:String(n)}let o=e.attr(t,r);return o||null}var ye=.5;function W(e,t,r,o,n,s,c){let i=e.find(t,r);if(n.length===0){i.forEach(d=>e.remove(d));return}if(n.length>i.length&&i.length===0)throw new b(s.path);let a=i.map(d=>me(e,d,o)),u=null;if(i.length>0){u=e.clone(i[0]);let d=e.stripIds(u);d>0&&console.warn(`[hyper-html-api] stripped ${d} id attribute(s) from cloned template at "${s.path.join(".")||"(root)"}"`)}let p=ge(n,a,o),l=e.parent(i[0]),R=Ae(e,l,i[0]),y=new Set,h=n.map((d,m)=>{let S=p[m];if(S>=0)return y.add(S),i[S];let v=e.clone(u);return e.stripIds(v),v});i.forEach((d,m)=>{y.has(m)||e.remove(d)}),y.forEach(d=>e.remove(i[d])),h.forEach((d,m)=>{e.insertAt(l,d,R+m)}),h.forEach((d,m)=>{if(o===null){let S=n[m];e.text(d,S==null?"":String(S))}else c(e,d,o,n[m],{depth:s.depth+1,path:[...s.path,m]})})}function me(e,t,r){return r===null?e.text(t):A(e,t,r)}function ge(e,t,r){let o=new Array(e.length).fill(-1),n=new Set;return e.forEach((s,c)=>{let i=-1,f=-1;t.forEach((a,u)=>{if(n.has(u))return;let p=Ee(s,a,r),l=p===f&&i>=0?Math.abs(u-c)<Math.abs(i-c):!1;(p>f||l)&&(f=p,i=u)}),f>=ye&&(o[c]=i,n.add(i))}),o}function Ee(e,t,r){if(r===null)return e===t?1:0;let o=Object.keys(r||{});if(o.length===0)return 0;let n=0;for(let s of o)JSON.stringify(e?.[s])===JSON.stringify(t?.[s])&&n++;return n/o.length}function Ae(e,t,r){let o=e.children(t);for(let n=0;n<o.length;n++)if(e.sameNode(o[n],r))return n;return-1}var Re=20,re=new Set(["checked","selected","disabled","readOnly","paused"]);function L(e,t,r,o){let n=[];if(F(r,o,[],n),n.length)throw new M(n);j(e,t,r,o,{depth:0,path:[]})}function j(e,t,r,o,n){if(n.depth>Re)throw new E(n.path);if(o!==void 0){if(typeof r=="string")return Se(e,t,r,o,n);if(Array.isArray(r)){let[s,c]=r;return W(e,t,s,c,o,n,j)}if(typeof r=="object"&&r!==null)for(let[s,c]of Object.entries(r))j(e,t,c,o==null?o:o[s],{depth:n.depth+1,path:[...n.path,s]})}}function Se(e,t,r,o,n){if(r.endsWith("[]")){let c=r.slice(0,-2);return W(e,t,c,null,o,n,j)}if(r.startsWith("@"))return ne(e,t,r.slice(1),o);if(r.includes("@")){let[c,i]=r.split("@"),f=c?e.find(t,c):[t];return f.length===0?void 0:ne(e,f[0],i,o)}if(r==="."){e.text(t,o==null?"":String(o));return}let s=e.find(t,r);s.length!==0&&e.text(s[0],o==null?"":String(o))}function ne(e,t,r,o){O.has(r)?e.prop(t,r,xe(r,o)):e.attr(t,r,o==null?"":String(o))}function xe(e,t){return t==null?re.has(e)?!1:"":re.has(e)?!!t:t}function F(e,t,r,o){if(!(t==null||t==="")){if(typeof e=="string"){if(e.endsWith("[]")){Array.isArray(t)?t.forEach((n,s)=>{typeof n=="object"&&n!==null&&o.push({path:N([...r,s]),expected:"scalar",got:I(n)})}):o.push({path:N(r),expected:"array",got:I(t)});return}typeof t=="object"&&o.push({path:N(r),expected:"scalar",got:I(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){o.push({path:N(r),expected:"array",got:I(t)});return}let n=e[1];t.forEach((s,c)=>F(n,s,[...r,c],o));return}if(typeof e=="object"&&e!==null){if(Array.isArray(t)||typeof t!="object"){o.push({path:N(r),expected:"object",got:I(t)});return}for(let[n,s]of Object.entries(e))F(s,t[n],[...r,n],o)}}}function I(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function N(e){return e.join(".")}function P(e){try{return JSON.parse(e)}catch(t){throw new x(`hyper-html-api script tags require strict JSON. Relaxed JSON (unquoted keys, single quotes, trailing commas) is only supported in the ?data= URL parameter. Original error: ${t.message}`,t)}}function J(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 r(n){let s=[],c=0;for(;c<n.length;){let i=n[c];if(/\s/.test(i)){c++;continue}if("{}".includes(i)){s.push({type:i,value:i}),c++;continue}if(i==="["){let p=!1,l=c+1;for(;l<n.length&&/\s/.test(n[l]);)l++;if(l<n.length&&/[a-zA-Z_]/.test(n[l])&&(p=!0),!p){s.push({type:i,value:i}),c++;continue}}if(i==="]"){s.push({type:i,value:i}),c++;continue}if(i===":"){s.push({type:t.COLON,value:i}),c++;continue}if(i===","){s.push({type:t.COMMA,value:i}),c++;continue}if(i==='"'||i==="'"){let p=i,l=c+1;for(;l<n.length&&n[l]!==p;)n[l]==="\\"&&l++,l++;s.push({type:t.STRING,value:n.substring(c+1,l),quoted:!0}),c=l+1;continue}let f=c,a;for(;f<n.length&&!/[{},]/.test(n[f]);)if(n[f]===":"){let p=[":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"],l=!1;for(let R of p){let y=R.substring(1);if(n.substring(f+1,f+1+y.length)===y){l=!0,f+=y.length;break}}if(!l)break}else if(n[f]==="["){for(f++;f<n.length&&n[f]!=="]";){if(n[f]==='"'||n[f]==="'"){let p=n[f];for(f++;f<n.length&&n[f]!==p;)n[f]==="\\"&&f++,f++}f++}f<n.length&&n[f]==="]"&&f++}else f++;a=n.substring(c,f);let u=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(a)?u=t.NUMBER:a==="true"||a==="false"||a==="null"?u=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(a)&&(u=t.SELECTOR),s.push({type:u,value:a,quoted:!1}),c=f}return s}function o(n){let s="";for(let c=0;c<n.length;c++){let i=n[c];if("{}".includes(i.type)||"[]".includes(i.type)){s+=i.value;continue}if(i.type===t.COLON){s+=i.value;continue}if(i.type===t.COMMA){s+=i.value;continue}if(i.type===t.STRING&&i.quoted){s+=`"${i.value}"`;continue}if(i.type===t.NUMBER||i.type===t.BOOLEAN){s+=i.value;continue}if(i.type===t.SELECTOR||i.type===t.IDENTIFIER){s+=`"${i.value}"`;continue}s+=`"${i.value}"`}return s}try{let n=r(e),s=o(n);return JSON.parse(s)}catch(n){throw new x("Invalid extraction rules syntax: "+n.message,n)}}var Oe="hyper-html-api",Te="1";function _(e,t){let r=e.find(t,`script#${Oe}`,{includeRulesTag:!0});if(r.length===0)return null;let o=r[0],n=e.attr(o,"data-rules-version");if(n!==Te)throw new T(n);let s=e.text(o);return{rules:P(s),tagNode:o}}var G=null;function V(e){if(typeof e!="function")throw new TypeError("registerUpgrade expects a function (v1Data) => v2Data");if(G)throw new w;G=e}function H(){return G}function U(e,t){let r={carriedOver:0,discarded:0,listItems:0},o=Y(t,e,r);return X(t,e,r),{data:o,summary:r}}function Y(e,t,r){if(typeof e=="string")return e.endsWith("[]")?Array.isArray(t)?(r.listItems+=t.length,r.carriedOver+=t.length,t):void 0:t==null?void 0:(r.carriedOver++,t);if(Array.isArray(e)){let[,o]=e;return Array.isArray(t)?(r.listItems+=t.length,t.map(n=>Y(o,n,r))):void 0}if(typeof e=="object"&&e!==null){let o={};for(let[n,s]of Object.entries(e)){let c=Y(s,t?.[n],r);c!==void 0&&(o[n]=c)}return o}}function X(e,t,r){if(t!=null){if(typeof e=="object"&&e!==null&&!Array.isArray(e)){if(typeof t!="object"||Array.isArray(t))return;let o=new Set(Object.keys(e));for(let n of Object.keys(t))o.has(n)?X(e[n],t[n],r):r.discarded+=k(t[n]);return}if(Array.isArray(e)&&Array.isArray(t)){let o=e[1];t.forEach(n=>X(o,n,r));return}typeof e=="string"&&!e.endsWith("[]")&&typeof t=="object"&&t!==null&&(r.discarded+=k(t))}}function k(e){return e==null?0:Array.isArray(e)?e.reduce((t,r)=>t+k(r),0):typeof e=="object"?Object.values(e).reduce((t,r)=>t+k(r),0):1}async function z({sourceUrl:e,v1Data:t,v1Version:r=null,parent:o=typeof window<"u"?window:null,timeoutMs:n=15e3,hidden:s=!0}={}){if(!o)throw new Error("upgrade.run requires a window context");if(!e)throw new Error("upgrade.run requires sourceUrl");let c=be(e,o.location.origin),i=new URL(c,o.location.href).origin,f=o.document.createElement("iframe");s&&(f.style.cssText="position:absolute;left:-9999px;top:-9999px;width:1px;height:1px;border:0;"),f.setAttribute("aria-hidden","true"),f.src=c,o.document.body.appendChild(f);let a=()=>{};try{return await new Promise((u,p)=>{let l=setTimeout(()=>{p(new Error(`upgrade.run: helper iframe timed out after ${n}ms`))},n),R=y=>{if(y.source!==f.contentWindow||y.origin!==i)return;let h=y.data;if(!(!h||typeof h!="object")){if(h.type==="hha:upgrade-ready"){f.contentWindow.postMessage({type:"hha:upgrade-data",v1Data:t,v1Version:r},i);return}if(h.type==="hha:upgrade-result"){clearTimeout(l),u({html:h.html,summary:h.summary});return}if(h.type==="hha:upgrade-error"){clearTimeout(l);let d=new Error(h.message||"helper error");d.name=h.name||"UpgradeHelperError",p(d);return}}};o.addEventListener("message",R),a=()=>{o.removeEventListener("message",R),clearTimeout(l),f.parentNode&&f.parentNode.removeChild(f)}})}finally{a()}}function be(e,t){let r=new URL(e,typeof location<"u"?location.href:void 0);return r.searchParams.set("_hyperHtmlApi","upgrade-helper"),r.searchParams.set("parentOrigin",t),r.toString()}var we="hyper-html-api";function Ie(e){return e&&e.nodeType===1&&e.id===we&&e.tagName==="SCRIPT"}function Ne(e){return e?(e.nodeType===9||e.nodeType===11,e):null}var Le={find(e,t,r={}){let o=Ne(e);if(!o||!o.querySelectorAll)return[];let n=Array.from(o.querySelectorAll(t));return r.includeRulesTag?n:n.filter(s=>!Ie(s))},parent(e){return e?e.parentElement:null},children(e){return e?Array.from(e.children):[]},text(e,t){if(t===void 0)return(e.textContent||"").trim();e.textContent=t},attr(e,t,r){if(r===void 0)return e.hasAttribute&&e.hasAttribute(t)?e.getAttribute(t):null;e.setAttribute(t,r)},prop(e,t,r){if(r===void 0){let o=e?e[t]:void 0;return o!==void 0?o:null}e[t]=r},clone(e){return e.cloneNode(!0)},insertAt(e,t,r){let o=e.children[r]||null;e.insertBefore(t,o)},remove(e){e&&e.parentNode&&e.parentNode.removeChild(e)},stripIds(e){let t=0;return e.id&&(e.removeAttribute("id"),t++),(e.querySelectorAll?e.querySelectorAll("[id]"):[]).forEach(o=>{o.removeAttribute("id"),t++}),t},sameNode(e,t){return e===t}},g=Le;var Pe="_hyperHtmlApi",_e="upgrade-helper",Ue="parentOrigin";function q(e=typeof location<"u"?location:null){if(!e)return!1;try{return new URLSearchParams(e.search).get(Pe)===_e}catch{return!1}}function oe(e=typeof location<"u"?location:null){return e?new URLSearchParams(e.search).get(Ue):null}function Z({win:e,doc:t,parentOrigin:r}={}){if(e=e||(typeof window<"u"?window:null),t=t||(typeof document<"u"?document:null),!e||!t||(r=r||oe(e.location),!r))return;let o=()=>Ce({win:e,doc:t,parentOrigin:r});t.readyState==="loading"?t.addEventListener("DOMContentLoaded",o,{once:!0}):o()}function Ce({win:e,doc:t,parentOrigin:r}){let o;try{o=_(g,t.body)}catch(f){return K(e,r,f)}if(!o)return K(e,r,new Error("helper-mode: no rules tag in v2 document"));let n=o.rules,s=je(t,"hyper-version"),c=!!H(),i=f=>{if(f.source!==e.parent||f.origin!==r)return;let a=f.data;if(!(!a||a.type!=="hha:upgrade-data")){e.removeEventListener("message",i);try{let u=De({doc:t,rules:n,v1Data:a.v1Data});e.parent.postMessage({type:"hha:upgrade-result",html:u.html,summary:u.summary},r)}catch(u){K(e,r,u)}}};e.addEventListener("message",i),e.parent.postMessage({type:"hha:upgrade-ready",rules:n,version:s,hasTransform:c},r)}function De({doc:e,rules:t,v1Data:r}){let o=H(),n=r,s=!1;o&&(n=o(r),s=!0);let{data:c,summary:i}=U(n,t);L(g,e.body,t,c);let f=A(g,e.body,t);return{html:`<!DOCTYPE html>
|
|
2
|
-
`+e.documentElement.outerHTML,summary:{...i,transformApplied:s,appliedFieldCount:Q(f)}}}function K(e,t,r){e.parent.postMessage({type:"hha:upgrade-error",name:r?.name||"Error",message:r?.message||String(r)},t)}function je(e,t){let r=e.querySelector(`meta[name="${t}"]`);return r?r.getAttribute("content"):null}function Q(e){return e==null?0:Array.isArray(e)?e.reduce((t,r)=>t+Q(r),0):typeof e=="object"?Object.values(e).reduce((t,r)=>t+Q(r),0):1}var se={extract:(e,t)=>A(g,e,t),apply:(e,t,r)=>L(g,e,t,r),findRulesIn:e=>_(g,e),parseStrict:P,parseRelaxed:J,errors:D,DOM_PROPERTIES:C},ie={},fe={registerUpgrade:V,run:z,shapeMatch:U,isHelperMode:q};typeof window<"u"&&q(window.location)&&Z({win:window,doc:document});var ke={engine:se,cms:ie,upgrade:fe},qe=ke;return de(Be);})();
|
|
1
|
+
var HyperHtmlApi=(()=>{var Ee=Object.defineProperty;var ht=Object.getOwnPropertyDescriptor;var mt=Object.getOwnPropertyNames;var gt=Object.prototype.hasOwnProperty;var Se=(e,t)=>{for(var r in t)Ee(e,r,{get:t[r],enumerable:!0})},yt=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of mt(t))!gt.call(e,o)&&o!==r&&Ee(e,o,{get:()=>t[o],enumerable:!(n=ht(t,o))||n.enumerable});return e};var bt=e=>yt(Ee({},"__esModule",{value:!0}),e);var yr={};Se(yr,{cms:()=>dt,default:()=>gr,engine:()=>ft,upgrade:()=>pt});var ce=["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"],ve=new Set(ce),Ke=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),ze=new Set(["tagName","nodeName","nodeType","nodeValue","childElementCount","classList","baseURI","documentURI","contentType","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","currentSrc","duration","paused","dataset"]);var ue={};Se(ue,{EmptyListInsert:()=>Z,MAX_RULE_DEPTH:()=>J,MaxRuleDepthExceeded:()=>U,RuleTargetReadOnly:()=>ee,RulesParseError:()=>z,ShapeMismatch:()=>X,UnknownRulesVersion:()=>Q,UpgradeAlreadyRegistered:()=>te});var z=class extends Error{constructor(t,r){super(t),this.name="RulesParseError",this.cause=r}},Q=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},J=20,U=class extends Error{constructor(t){super(`rule depth exceeded ${J} at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},X=class extends Error{constructor(t){super(`shape mismatch: ${t.length} field(s) failed validation`),this.name="ShapeMismatch",this.mismatches=t}},Z=class extends Error{constructor(t){super(`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}},ee=class extends Error{constructor(t){super(`cannot write to read-only DOM property "${t}"`),this.name="RuleTargetReadOnly",this.target=t}},te=class extends Error{constructor(){super("upgrade transform already registered; only one registration is allowed per page."),this.name="UpgradeAlreadyRegistered"}};function B(e,t,r,n={}){return xe(e,t,r,{depth:0,path:[]},n)}function xe(e,t,r,n,o){if(n.depth>J)throw new U(n.path);if(typeof r=="string")return At(e,t,r,o);if(Array.isArray(r)){let[i,u]=r;return e.find(t,i,o).map((a,M)=>xe(e,a,u,{depth:n.depth+1,path:[...n.path,M]},o))}if(typeof r=="object"&&r!==null){let i={};for(let[u,s]of Object.entries(r))i[u]=xe(e,t,s,{depth:n.depth+1,path:[...n.path,u]},o);return i}return null}function At(e,t,r,n){if(r.endsWith("[]")){let i=r.slice(0,-2);return e.find(t,i,n).map(u=>e.text(u))}if(r.startsWith("@"))return Je(e,t,r.slice(1));if(r.includes("@")){let i=r.lastIndexOf("@"),u=r.slice(0,i),s=r.slice(i+1),a=u?e.find(t,u,n):[t];return a.length===0?null:Je(e,a[0],s)}if(r===".")return e.text(t);let o=e.find(t,r,n);return o.length===0?null:e.text(o[0])}function Je(e,t,r){if(ve.has(r)){let o=e.prop(t,r);return o==null?null:String(o)}let n=e.attr(t,r);return n||null}var Mt=.5;function we(e,t,r,n,o,i,u,s={}){let a=e.find(t,r,s);if(o.length===0){a.forEach(S=>e.remove(S));return}let M=o.length>a.length,w=a[0]||null;if(M&&!w&&(w=wt(e,t,r,s),!w))throw new Z(i.path);let b=a.map(S=>Et(e,S,n,s)),h=null;if(w){h=e.clone(w),s.templateAttr&&e.removeAttr(h,s.templateAttr);let S=e.stripIds(h);S>0&&console.warn(`[hyper-html-api] stripped ${S} id attribute(s) from cloned template at "${i.path.join(".")||"(root)"}"`)}let R=St(o,b,n),N=a[0]||w,k=e.parent(N),m=a.length>0?xt(e,k,N):0,O=new Set,v=o.map((S,x)=>{let E=R[x];if(E>=0)return O.add(E),a[E];let d=e.clone(h);return e.stripIds(d),d});a.forEach((S,x)=>{O.has(x)||e.remove(S)}),v.forEach((S,x)=>{let E=m+x;e.children(k).findIndex(c=>e.sameNode(c,S))!==E&&e.insertAt(k,S,E)}),v.forEach((S,x)=>{if(n===null){let E=o[x],d=E==null?"":String(E);e.text(S)!==d&&e.text(S,d)}else{let E=u(e,S,n,o[x],{depth:i.depth+1,path:[...i.path,x]},s);E&&E!==S&&(v[x]=E)}})}function Et(e,t,r,n){return r===null?e.text(t):B(e,t,r,n)}function St(e,t,r){let n=new Array(e.length).fill(-1),o=new Set;return e.forEach((i,u)=>{let s=-1,a=-1;t.forEach((M,w)=>{if(o.has(w))return;let b=vt(i,M,r),h=b===a&&s>=0?Math.abs(w-u)<Math.abs(s-u):!1;(b>a||h)&&(a=b,s=w)}),a>=Mt&&(n[u]=s,o.add(s))}),n}function vt(e,t,r){if(r===null)return e===t?1:0;let n=Object.keys(r||{});if(n.length===0)return 0;let o=0;for(let i of n)JSON.stringify(e?.[i])===JSON.stringify(t?.[i])&&o++;return o/n.length}function xt(e,t,r){let n=e.children(t);for(let o=0;o<n.length;o++)if(e.sameNode(n[o],r))return o;return-1}function wt(e,t,r,n){if(!n.templateAttr)return null;let o=t;for(;o;){let i=e.find(o,r,{includeRulesTag:!1});for(let u of i)if(e.attr(u,n.templateAttr)!=null)return u;o=e.parent(o)}return null}var Ye=new Set(["checked","selected","disabled","readOnly","paused"]);function W(e,t,r,n,o={}){let i=[];if(Te(r,n,[],i),i.length)throw new X(i);le(e,t,r,n,{depth:0,path:[]},o)}function le(e,t,r,n,o,i={}){if(o.depth>J)throw new U(o.path);if(n===void 0)return t;if(typeof r=="string")return Tt(e,t,r,n,o,i);if(Array.isArray(r)){let[u,s]=r;return we(e,t,u,s,n,o,le,i),t}if(typeof r=="object"&&r!==null){for(let[u,s]of Object.entries(r)){let a=le(e,t,s,n==null?n:n[u],{depth:o.depth+1,path:[...o.path,u]},i);a&&a!==t&&(t=a)}return t}return t}function Tt(e,t,r,n,o,i){if(r.endsWith("[]")){let s=r.slice(0,-2);return we(e,t,s,null,n,o,le,i),t}if(r.startsWith("@"))return Ge(e,t,r.slice(1),n);if(r.includes("@")){let s=r.lastIndexOf("@"),a=r.slice(0,s),M=r.slice(s+1),w=a?e.find(t,a,i):[t];return w.length===0||Ge(e,w[0],M,n),t}if(r===".")return e.text(t,n==null?"":String(n)),t;let u=e.find(t,r,i);return u.length===0||e.text(u[0],n==null?"":String(n)),t}function Ge(e,t,r,n){if(ze.has(r))throw new ee(r);if(r==="outerHTML"){let o=n==null?"":String(n);return e.replaceWith(t,o)}return Ke.has(r)?(e.prop(t,r,Rt(r,n)),t):(e.attr(t,r,n==null?"":String(n)),t)}function Rt(e,t){return t==null?Ye.has(e)?!1:"":Ye.has(e)?!!t:t}function Te(e,t,r,n){if(t!==void 0){if(typeof e=="string"){if(e.endsWith("[]")){Array.isArray(t)?t.forEach((o,i)=>{typeof o=="object"&&o!==null&&n.push({path:ne([...r,i]),expected:"scalar",got:re(o)})}):n.push({path:ne(r),expected:"array",got:re(t)});return}t!==null&&typeof t=="object"&&n.push({path:ne(r),expected:"scalar",got:re(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){n.push({path:ne(r),expected:"array",got:re(t)});return}let o=e[1];t.forEach((i,u)=>Te(o,i,[...r,u],n));return}if(typeof e=="object"&&e!==null){if(t===null||Array.isArray(t)||typeof t!="object"){n.push({path:ne(r),expected:"object",got:re(t)});return}for(let[o,i]of Object.entries(e))Te(i,t[o],[...r,o],n)}}}function re(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function ne(e){return e.join(".")}function Re(e){try{return JSON.parse(e)}catch(t){throw new z(`Invalid strict JSON: ${t.message}`,t)}}function oe(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 r(o){let i=[],u=0;for(;u<o.length;){let s=o[u];if(/\s/.test(s)){u++;continue}if("{}".includes(s)){i.push({type:s,value:s}),u++;continue}if(s==="["){let b=!1,h=u+1;for(;h<o.length&&/\s/.test(o[h]);)h++;if(h<o.length&&/[a-zA-Z_]/.test(o[h])&&(b=!0),!b){i.push({type:s,value:s}),u++;continue}}if(s==="]"){i.push({type:s,value:s}),u++;continue}if(s===":"){i.push({type:t.COLON,value:s}),u++;continue}if(s===","){i.push({type:t.COMMA,value:s}),u++;continue}if(s==='"'||s==="'"){let b=s,h=u+1;for(;h<o.length&&o[h]!==b;)o[h]==="\\"&&h++,h++;i.push({type:t.STRING,value:o.substring(u+1,h),quoted:!0,sourceQuote:b}),u=h+1;continue}let a=u,M;for(;a<o.length&&!/[{},]/.test(o[a]);)if(o[a]===":"){let b=[":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"],h=!1;for(let R of b){let N=R.substring(1);if(o.substring(a+1,a+1+N.length)===N){h=!0,a+=N.length;break}}if(!h)break}else if(o[a]==="["){for(a++;a<o.length&&o[a]!=="]";){if(o[a]==='"'||o[a]==="'"){let b=o[a];for(a++;a<o.length&&o[a]!==b;)o[a]==="\\"&&a++,a++}a++}a<o.length&&o[a]==="]"&&a++}else a++;M=o.substring(u,a);let w=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(M)?w=t.NUMBER:M==="true"||M==="false"||M==="null"?w=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(M)&&(w=t.SELECTOR),i.push({type:w,value:M,quoted:!1}),u=a}return i}function n(o){let i="";for(let u=0;u<o.length;u++){let s=o[u];if("{}".includes(s.type)||"[]".includes(s.type)){i+=s.value;continue}if(s.type===t.COLON){i+=s.value;continue}if(s.type===t.COMMA){let a=o[u+1];if(a&&(a.type==="}"||a.type==="]"))continue;i+=s.value;continue}if(s.type===t.STRING&&s.quoted){let a=s.value;s.sourceQuote==="'"&&(a=a.replace(/\\'/g,"'"),a=a.replace(/(\\*)"/g,(M,w)=>w.length%2===0?w+'\\"':M)),i+=`"${a}"`;continue}if(s.type===t.NUMBER||s.type===t.BOOLEAN){i+=s.value;continue}if(s.type===t.SELECTOR||s.type===t.IDENTIFIER){i+=`"${s.value}"`;continue}i+=`"${s.value}"`}return i}try{let o=r(e),i=n(o);return JSON.parse(i)}catch(o){throw new z("Invalid extraction rules syntax: "+o.message,o)}}var Nt="1",Qe=/^[a-zA-Z0-9_-]+$/;function q(e,t,r){let n;if(r===void 0)n="script[data-rules-name]";else{if(typeof r!="string"||!Qe.test(r))throw new Error(`hyper-html-api: invalid rules token ${JSON.stringify(r)} (must match ${Qe})`);n=`script[data-rules-name~="${r}"]`}let o=e.find(t,n,{includeRulesTag:!0});if(o.length===0)return null;r!==void 0&&o.length>1&&console.warn(`hyper-html-api: ${o.length} rules tags match data-rules-name~="${r}"; using the first.`);let i=o[0],u=e.attr(i,"data-rules-version");if(u!==Nt)throw new Q(u);return{rules:oe(e.text(i)),tagNode:i}}function Ne(e,t,r){if(r&&typeof r=="object")return{rules:r,tagNode:null};if(typeof r=="string"){let n=t&&t.ownerDocument?t.ownerDocument:t;return q(e,n,r)}return null}function Xe(e,t,r,n){let o=Ne(e,t,r);if(!o){let s=typeof r=="string"?`data-rules-name~="${r}"`:"the provided rules object";throw new Error(`hyper-html-api: could not resolve rules for ${s}`)}let{rules:i,tagNode:u}=o;return{rules:i,tagNode:u,get:()=>B(e,t,i,n),set:s=>W(e,t,i,s,n)}}var de={};Se(de,{fromString:()=>fe,getRuleAtPath:()=>Oe,getValueAtPath:()=>ie,parseConfigKey:()=>kt,setAtPath:()=>F,toConfigKey:()=>It,toString:()=>_});function _(e){return e.map(String).join(".")}function It(e){return e.map(t=>typeof t=="number"?"*":String(t)).join(".")}function kt(e){return e===""?[]:e.split(".")}function fe(e){return e===""?[]:e.split(".").map(t=>/^\d+$/.test(t)?Number(t):t)}function Oe(e,t){let r=e;for(let n of t){if(r==null||typeof r=="string")return;if(Array.isArray(r)){if(typeof n!="number"&&n!=="*")return;r=r[1];continue}if(typeof r=="object"){if(typeof n=="number"||!(n in r))return;r=r[n];continue}return}return r}function ie(e,t){let r=e;for(let n of t){if(r==null)return;r=r[n]}return r}function F(e,t,r){if(t.length===0)return r;let[n,...o]=t;if(typeof n=="number"){let i=Array.isArray(e)?[...e]:[];return i[n]=F(i[n],o,r),i}return{...e&&typeof e=="object"?e:{},[n]:F((e||{})[n],o,r)}}function Y(e){if(typeof e=="string")return e.endsWith("[]")?[]:"";if(Array.isArray(e))return[];if(typeof e=="object"&&e!==null){let t={};for(let[r,n]of Object.entries(e))t[r]=Y(n);return t}return""}var pe=new WeakMap;var Lt=new Set(["checked","selected","disabled","readOnly","paused"]);function Ie({rules:e,data:t,appRoot:r,cmsRoot:n}){let o=document.createDocumentFragment(),i={rules:e,appRoot:r,cmsRoot:n};return o.appendChild(Le({rule:e,value:t,path:[],ctx:i})),o}function ke(e,{rules:t,getData:r,onChange:n}){e.setAttribute("data-hha-form-root",""),tt.set(e,{rules:t,getData:r,onChange:n}),Ct()}var tt=new WeakMap,Ze=!1;function Ct(){Ze||(document.addEventListener("input",et,!0),document.addEventListener("change",et,!0),document.addEventListener("click",Ht,!0),Ze=!0)}function rt(e){if(!(e instanceof Element))return null;let t=e.closest("[data-hha-form-root]");return t&&tt.get(t)||null}function Ht(e){if(!(e.target instanceof Element))return;let t=e.target.closest("[data-hha-action]");if(!t||e.defaultPrevented)return;let r=rt(t);if(!r)return;let{rules:n,getData:o,onChange:i}=r,u=t.getAttribute("data-hha-action"),s=fe(t.getAttribute("data-hha-path")||"");if(u==="scalar-array-add"){let a=ie(o(),s)||[];i(F(o(),s,[...a,""]),{structural:!0});return}if(u==="object-array-add"){let a=Oe(n,s);if(!Array.isArray(a))return;let M=ie(o(),s)||[];i(F(o(),s,[...M,Y(a[1])]),{structural:!0});return}if(u==="array-remove"){if(s.length===0)return;let a=s.slice(0,-1),M=s[s.length-1],w=ie(o(),a)||[];if(typeof M!="number")return;let b=w.filter((h,R)=>R!==M);i(F(o(),a,b),{structural:!0})}}function et(e){let t=e.target;if(!t?.matches?.("input, textarea, select"))return;let r=rt(t);if(!r)return;let{getData:n,onChange:o}=r,i=t.closest("[data-hha-path]");if(!i)return;let u=fe(i.getAttribute("data-hha-path")||""),s=t.type==="checkbox"?t.checked:t.value;o(F(n(),u,s),{structural:!1})}function Le({rule:e,value:t,path:r,ctx:n}){if(typeof e=="string")return e.endsWith("[]")?Dt({rule:e,value:t,path:r,ctx:n}):_t({rule:e,value:t,path:r,ctx:n});if(Array.isArray(e))return jt({rule:e,value:t,path:r,ctx:n});if(typeof e=="object"&&e!==null)return Pt({rule:e,value:t,path:r,ctx:n});let o=document.createElement("span");return o.textContent="(unsupported rule)",o}function Pt({rule:e,value:t,path:r,ctx:n}){let o=document.createElement("div");if(o.className="form-section",o.setAttribute("data-hha-path",_(r)),r.length>0){let i=document.createElement("div");i.className="form-section-label",i.textContent=he(r[r.length-1]),o.appendChild(i)}for(let[i,u]of Object.entries(e)){let s=[...r,i],a=t?.[i];o.appendChild(Le({rule:u,value:a,path:s,ctx:n}))}return o}function _t({rule:e,value:t,path:r,ctx:n}){let o=document.createElement("div");o.className="field-row",o.setAttribute("data-hha-path",_(r));let i=document.createElement("div");i.className="field-body";let u=document.createElement("label");u.className="field-label",u.textContent=he(r[r.length-1]||".")+Wt(e);let s=Bt(e,n.appRoot),a=$t(s,{value:t,rule:e,path:r,appRoot:n.appRoot}),M=a.el;return M.classList.add(s.type==="textarea"?"field-textarea":"field-input"),i.appendChild(u),i.appendChild(M),o.appendChild(i),pe.set(o,a),o}function Dt({rule:e,value:t,path:r,ctx:n}){let o=document.createElement("div");o.className="form-section",o.setAttribute("data-hha-path",_(r));let i=document.createElement("div");i.className="form-section-label",i.textContent=he(r[r.length-1]),o.appendChild(i);let u=Array.isArray(t)?t:[],s=document.createElement("div");o.appendChild(s),u.forEach((M,w)=>{let b=[...r,w],h=document.createElement("div");h.className="scalar-array-row",h.setAttribute("data-hha-path",_(b));let R=document.createElement("input");R.type="text",R.className="field-input",R.value=M==null?"":String(M);let N=document.createElement("button");N.type="button",N.className="array-remove",N.textContent="\xD7",N.title="remove",N.setAttribute("data-hha-action","array-remove"),N.setAttribute("data-hha-path",_(b)),h.appendChild(R),h.appendChild(N),s.appendChild(h)});let a=document.createElement("button");return a.type="button",a.className="array-add",a.textContent="+ add",a.setAttribute("data-hha-action","scalar-array-add"),a.setAttribute("data-hha-path",_(r)),o.appendChild(a),o}function jt({rule:e,value:t,path:r,ctx:n}){let[,o]=e,i=Array.isArray(t)?t:[],u=document.createElement("div");u.className="form-section",u.setAttribute("data-hha-path",_(r));let s=document.createElement("div");s.className="form-section-label",s.textContent=he(r[r.length-1]),u.appendChild(s),i.forEach((M,w)=>{let b=[...r,w],h=document.createElement("div");h.className="array-card",h.setAttribute("data-hha-path",_(b));let R=document.createElement("button");R.type="button",R.className="array-remove",R.textContent="\xD7",R.title="remove item",R.setAttribute("data-hha-action","array-remove"),R.setAttribute("data-hha-path",_(b)),h.appendChild(R);let N=Le({rule:o,value:M,path:b,ctx:n});N.querySelector(".form-section-label")?.remove(),h.appendChild(N),u.appendChild(h)});let a=document.createElement("button");return a.type="button",a.className="array-add",a.textContent="+ add",a.setAttribute("data-hha-action","object-array-add"),a.setAttribute("data-hha-path",_(r)),u.appendChild(a),u}function $t(e,t){let r=Ut(e);if(e.type==="select"&&e.options)for(let n of e.options){let o=document.createElement("option");o.value=n.value,o.textContent=n.text,String(t.value)===n.value&&(o.selected=!0),r.appendChild(o)}else e.type==="checkbox"?r.checked=t.value===!0||t.value==="true"||t.value==="checked":(e.type,r.value=t.value==null?"":String(t.value));return{el:r,destroy(){},focus(){r.focus()},validate(){}}}function Bt(e,t){let r=null;if(e.startsWith("@")?r=e.slice(1):e.includes("@")&&(r=e.split("@")[1]||null),r&&Lt.has(r))return{type:"checkbox"};if(r==="innerHTML")return{type:"textarea"};let n=Ft(e,t);if(!n)return{type:"text"};let o=(n.tagName||"").toLowerCase();if(o==="textarea")return{type:"textarea"};if(o==="select")return{type:"select",options:Array.from(n.querySelectorAll("option")).map(s=>({value:s.getAttribute("value")||s.textContent,text:s.textContent.trim()||s.getAttribute("value")||""}))};if(o==="input"){let u=(n.getAttribute("type")||"text").toLowerCase();if(u==="checkbox"||u==="radio")return{type:"checkbox"};if(u==="number")return{type:"number"}}let i=(n.textContent||"").trim();return i.length>60||i.includes(`
|
|
2
|
+
`)?{type:"textarea"}:{type:"text"}}function Ft(e,t){if(!t||e==="."||e===""||e.startsWith("@"))return null;let r=e.includes("@")?e.split("@")[0]:e;if(!r)return null;try{return t.querySelector(r)}catch{return null}}function Ut(e){if(e.type==="textarea")return document.createElement("textarea");if(e.type==="select")return document.createElement("select");let t=document.createElement("input");return t.type=e.type==="checkbox"?"checkbox":e.type==="number"?"number":"text",t}function he(e){return typeof e=="number"?`#${e+1}`:String(e).replace(/([a-z])([A-Z])/g,"$1 $2").replace(/[_-]+/g," ").replace(/^\w/,t=>t.toUpperCase())}function Wt(e){return` \xB7 ${e}`}var nt={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,slotMatch:30},minConfidence:101};function qt(e){let t=5381;for(let r=0;r<e.length;r++)t=(t<<5)+t^e.charCodeAt(r);return Math.abs(t).toString(36)}function Vt(e){if(e.classList&&e.classList.length>0)return Array.from(e.classList).sort().join(" ");let t=e.getAttribute?.("class");return t?t.split(/\s+/).filter(Boolean).sort().join(" "):""}function Kt(e,t){let r=[];for(let n of e.attributes||[]){let o=n.name;o==="id"||o==="class"||t.excludeAttributePrefixes.some(i=>o.startsWith(i))||t.includeAttributes.includes(o)&&r.push(`${o}=${n.value}`)}return r.sort().join("|")}function zt(e,t){return(e.textContent||"").replace(/\s+/g," ").trim().slice(0,t.textHintLength)}function Jt(e,t){let r=[e.tagName];return t.includeClasses&&r.push(Vt(e)),r.push(Kt(e,t)),qt(r.join("|"))}function Yt(e){let t=e.tagName,r=1,n=e.previousElementSibling;for(;n;)n.tagName===t&&r++,n=n.previousElementSibling;return r}function Gt(e,t){return e.id||e.getAttribute?.("role")?!0:t.landmarks.includes(e.tagName)}function Qt(e){if(e.id)return`#${e.id}`;let t=e.getAttribute?.("role");return t?`@${t}`:e.tagName}function Xt(e,t){let r=[],n=e;for(;n&&n.tagName&&r.length<t.maxPathDepth;){let o=`${n.tagName}:${Yt(n)}`;if(r.unshift(o),n!==e&&Gt(n,t)){r.unshift(Qt(n));break}n=n.parentElement}return r}function Zt(e,t){let r=0,n=e.length-1,o=t.length-1;for(;n>=0&&o>=0&&e[n]===t[o];)r++,n--,o--;return r}function j(e,t,r){if(r.has(e))return r.get(e);let n={signature:Jt(e,t),path:Xt(e,t),textHint:zt(e,t)};return r.set(e,n),n}function at(e,t,r,n){if(n.has(e))return n.get(e);let o=new Map,i=e.querySelectorAll("*"),u=0;for(let s of i){let a=j(s,t,r);a.domIndex=u++,o.has(a.signature)||o.set(a.signature,[]),o.get(a.signature).push(s)}return n.set(e,o),o}function er(e,t,r){r.delete(e),t.delete(e);let n=e.querySelectorAll("*");for(let o of n)t.delete(o)}function Ce(e,t,r,n,o){let i=j(e,r,n),u=j(t,r,n),s=r.weights,a={},M=0;if(i.signature!==u.signature)return{score:0,breakdown:{rejected:"signature mismatch"}};M+=s.signature,a.signature=s.signature;let b=Zt(i.path,u.path)*s.pathSegment;M+=b,a.path=b;let h=!0;if(i.textHint&&u.textHint?i.textHint===u.textHint?(M+=s.textMatch,a.text=s.textMatch):(M-=s.textMismatch,a.text=-s.textMismatch,h=!1):i.textHint!==u.textHint&&(M-=s.textMismatch,a.text=-s.textMismatch,h=!1),o.candidateCount===1&&h&&(M+=s.uniqueCandidate,a.unique=s.uniqueCandidate),typeof i.domIndex=="number"&&typeof u.domIndex=="number"){let R=Math.abs(i.domIndex-u.domIndex),N=Math.min(R*s.positionPenalty,20);M-=N,a.drift=-N}return{score:M,breakdown:a}}function ot(e,t,r,n,o){if(r.excludeIds&&e.id)return null;let i=at(t,r,n,o),u=j(e,r,n);if(typeof u.domIndex!="number"){let h=0,R=e.previousElementSibling;for(;R;)h++,R=R.previousElementSibling;u.domIndex=h}let s=i.get(u.signature)||[],a=r.excludeIds?s.filter(h=>!h.id):s;if(a.length===0)return null;let M=null,w=0,b=null;for(let h of a){let{score:R,breakdown:N}=Ce(e,h,r,n,{candidateCount:a.length});R>w&&(w=R,M=h,b=N)}return w<r.minConfidence?null:{element:M,confidence:w,breakdown:b}}function tr(e,t,r,n){let o=[],i=r.weights.signature+r.weights.slotMatch,u={slot:i};function s(b){if(b.children)return b.children;let h=b.childNodes;if(!h)return[];let R=[];for(let N=0;N<h.length;N++)h[N].nodeType===1&&R.push(h[N]);return R}function a(b,h){let R=s(b),N=s(h);if(R.length===N.length)for(let k=0;k<R.length;k++){let m=R[k],O=N[k];if(r.excludeIds&&(m.id||O.id)||m.tagName!==O.tagName)continue;let v=j(m,r,n).signature,S=j(O,r,n).signature;v!==S&&o.push({newEl:m,oldEl:O,score:i,breakdown:u}),a(m,O)}}function M(b,h){for(;;){if(b.tagName===h.tagName)return[b,h];let R=s(b);if(!b.tagName&&R.length===1){b=R[0];continue}let N=s(h);if(N.length===1&&N[0].tagName===b.tagName){h=N[0];continue}return null}}let w=M(e,t);return w&&a(w[0],w[1]),o}function it(e,t,r,n,o){let i=t.querySelectorAll("*"),u=at(e,r,n,o),s=0;for(let b of i){let h=j(b,r,n);h.domIndex=s++}let a=[];for(let b of i){if(r.excludeIds&&b.id)continue;let h=j(b,r,n),R=u.get(h.signature)||[],N=r.excludeIds?R.filter(k=>!k.id):R;for(let k of N){let{score:m,breakdown:O}=Ce(b,k,r,n,{candidateCount:N.length});m>=r.minConfidence&&a.push({newEl:b,oldEl:k,score:m,breakdown:O})}}if(r.weights.slotMatch>0){let b=tr(t,e,r,n);for(let h of b)a.push(h)}a.sort((b,h)=>h.score-b.score);let M=new Map,w=new Set;for(let{newEl:b,oldEl:h}of a)M.has(b)||w.has(h)||(M.set(b,h),w.add(h));return M}function st(e,t,r,n){let o=j(e,r,n),i=j(t,r,n),{score:u,breakdown:s}=Ce(e,t,r,n,{candidateCount:1});return{matches:u>=r.minConfidence,score:u,breakdown:s,newMeta:{signature:o.signature,path:o.path,textHint:o.textHint},oldMeta:{signature:i.signature,path:i.path,textHint:i.textHint}}}function ct(e={}){let t={...nt,...e,weights:{...nt.weights,...e.weights}},r=new WeakMap,n=new WeakMap;return{findMatch:(o,i)=>ot(o,i,t,r,n),computeMatches:(o,i)=>it(o,i,t,r,n),explain:(o,i)=>st(o,i,t,r),invalidate:o=>er(o,r,n),session:()=>{let o=new WeakMap,i=new WeakMap;return{findMatch:(u,s)=>ot(u,s,t,o,i),computeMatches:(u,s)=>it(u,s,t,o,i),explain:(u,s)=>st(u,s,t,o)}},getConfig:()=>({...t})}}var rr=ct(),He=function(){"use strict";let e=()=>{};function t(m){if(!(m instanceof Element))return!1;if(m.hasAttribute("save-ignore"))return!0;if(m.tagName==="LINK"||m.tagName==="SCRIPT"){let O=m.getAttribute("src")||m.getAttribute("href")||"";if(O.startsWith("chrome-extension://")||O.startsWith("moz-extension://")||O.startsWith("safari-web-extension://"))return!0}return!1}function r(m,O){if(O!=="smart")return m.outerHTML;let v=m.getAttribute("src"),S=m.getAttribute("type")||"text/javascript";if(v)try{let x=new URL(v,window.location.href);return`ext:${S}:${x.origin}${x.pathname}${x.search}`}catch{return`ext:${S}:${v}`}else{let x=m.textContent.trim(),E=5381;for(let d=0;d<x.length;d++)E=(E<<5)+E^x.charCodeAt(d);return`inline:${S}:${Math.abs(E).toString(36)}`}}let n={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:e,afterNodeAdded:e,beforeNodeMorphed:e,afterNodeMorphed:e,beforeNodeRemoved:e,afterNodeRemoved:e,beforeAttributeUpdated:e},head:{style:"merge",shouldPreserve:m=>m.getAttribute("im-preserve")==="true",shouldReAppend:m=>m.getAttribute("im-re-append")==="true",shouldRemove:e,afterHeadMorphed:e},scripts:{handle:!1,matchMode:"outerHTML",shouldPreserve:m=>m.getAttribute("im-preserve")==="true",shouldReAppend:m=>m.getAttribute("im-re-append")==="true",shouldRemove:e,afterScriptsHandled:e},restoreFocus:!0},o={computeMatches(m,O){let{computeMatches:v}=rr.session();return v(m,O)}};function i(m,O,v={}){m=N(m);let S=k(O),x=R(m,S,v),E=x.scripts.matchMode,d=new Set(Array.from(m.querySelectorAll("script")).map(l=>r(l,E))),y=s(x,()=>w(x,m,S,l=>l.morphStyle==="innerHTML"?(a(l,m,S),Array.from(m.childNodes)):u(l,m,S)));x.pantry.remove();let c=h(m,d,x);return c.length>0?y instanceof Promise?y.then(l=>Promise.all(c).then(()=>l)):Promise.all(c).then(()=>y):y}function u(m,O,v){let S=k(O);return a(m,S,v,O,O.nextSibling),Array.from(S.childNodes)}function s(m,O){if(!m.config.restoreFocus)return O();let v=document.activeElement;if(!(v instanceof HTMLInputElement||v instanceof HTMLTextAreaElement))return O();let{id:S,selectionStart:x,selectionEnd:E}=v,d=O();return S&&S!==document.activeElement?.getAttribute("id")&&(v=m.target.querySelector(`[id="${S}"]`),v?.focus()),v&&!v.selectionEnd&&E!=null&&v.setSelectionRange(x,E),d}let a=function(){function m(c,l,p,f=null,g=null){l instanceof HTMLTemplateElement&&p instanceof HTMLTemplateElement&&(l=l.content,p=p.content),f||=l.firstChild;for(let A of p.childNodes){if(t(A))continue;if(f&&f!=g){let I=v(c,A,f,g);if(I){I!==f&&x(c,f,I),M(I,A,c),f=I.nextSibling;continue}}if(A instanceof Element){let I=A.getAttribute("id");if(c.persistentIds.has(I)){let L=E(l,I,f,c);M(L,A,c),f=L.nextSibling;continue}if(!c.idMap.has(A)){let L=c.hyperMatches.get(A);if(L&&!c.idMap.has(L)){y(l,L,f),M(L,A,c),f=L.nextSibling;continue}}}let T=O(l,A,f,c);T&&(f=T.nextSibling)}for(;f&&f!=g;){let A=f;f=f.nextSibling,t(A)||S(c,A)}}function O(c,l,p,f){if(f.callbacks.beforeNodeAdded(l)===!1)return null;if(f.idMap.has(l)){let g=document.createElement(l.tagName);return c.insertBefore(g,p),M(g,l,f),f.callbacks.afterNodeAdded(g),g}else{let g=document.importNode(l,!0);return c.insertBefore(g,p),f.callbacks.afterNodeAdded(g),g}}let v=function(){function c(f,g,A,T){let I=g instanceof Element&&!f.idMap.has(g)?f.hyperMatches.get(g):null,L=null,D=g.nextSibling,G=0,C=A;for(;C&&C!=T;){if(p(C,g)){if(l(f,C,g)||C===I&&!f.idMap.has(C))return C;if(L===null){let V=C instanceof Element&&f.hyperMatchedOldElements.has(C);!f.idMap.has(C)&&!V&&(L=C)}}if(L===null&&D&&p(C,D)&&(G++,D=D.nextSibling,G>=2&&(L=void 0)),f.activeElementAndParents.includes(C))break;C=C.nextSibling}return L||null}function l(f,g,A){let T=f.idMap.get(g),I=f.idMap.get(A);if(!I||!T)return!1;for(let L of T)if(I.has(L))return!0;return!1}function p(f,g){let A=f,T=g;return A.nodeType===T.nodeType&&A.tagName===T.tagName&&(!A.getAttribute?.("id")||A.getAttribute?.("id")===T.getAttribute?.("id"))}return c}();function S(c,l){let p=l instanceof Element&&c.hyperMatchedOldElements.has(l)&&!c.idMap.has(l);if(c.idMap.has(l)||p)y(c.pantry,l,null);else{if(c.callbacks.beforeNodeRemoved(l)===!1)return;l.parentNode?.removeChild(l),c.callbacks.afterNodeRemoved(l)}}function x(c,l,p){let f=l;for(;f&&f!==p;){let g=f;f=f.nextSibling,t(g)||S(c,g)}return f}function E(c,l,p,f){let g=f.target.getAttribute?.("id")===l&&f.target||f.target.querySelector(`[id="${l}"]`)||f.pantry.querySelector(`[id="${l}"]`);return d(g,f),y(c,g,p),g}function d(c,l){let p=c.getAttribute("id");for(;c=c.parentNode;){let f=l.idMap.get(c);f&&(f.delete(p),f.size||l.idMap.delete(c))}}function y(c,l,p){if(c.moveBefore)try{c.moveBefore(l,p)}catch{c.insertBefore(l,p)}else c.insertBefore(l,p)}return m}(),M=function(){function m(d,y,c){return c.ignoreActive&&d===document.activeElement?null:(c.callbacks.beforeNodeMorphed(d,y)===!1||(d instanceof HTMLHeadElement&&c.head.ignore||(d instanceof HTMLHeadElement&&c.head.style!=="morph"?b(d,y,c):(O(d,y,c),E(d,c)||a(c,d,y))),c.callbacks.afterNodeMorphed(d,y)),d)}function O(d,y,c){let l=y.nodeType;if(l===1){let p=d,f=y,g=p.attributes,A=f.attributes;for(let T of A)x(T.name,p,"update",c)||p.getAttribute(T.name)!==T.value&&p.setAttribute(T.name,T.value);for(let T=g.length-1;0<=T;T--){let I=g[T];if(I&&!f.hasAttribute(I.name)){if(x(I.name,p,"remove",c))continue;p.removeAttribute(I.name)}}E(p,c)||v(p,f,c)}(l===8||l===3)&&d.nodeValue!==y.nodeValue&&(d.nodeValue=y.nodeValue)}function v(d,y,c){if(d instanceof HTMLInputElement&&y instanceof HTMLInputElement&&y.type!=="file"){let l=y.value,p=d.value;S(d,y,"checked",c),S(d,y,"disabled",c),c.formStateSync==="property"?p!==l&&(x("value",d,"update",c)||(d.value=l)):y.hasAttribute("value")?p!==l&&(x("value",d,"update",c)||(d.setAttribute("value",l),d.value=l)):x("value",d,"remove",c)||(d.value="",d.removeAttribute("value"))}else if(d instanceof HTMLOptionElement&&y instanceof HTMLOptionElement)S(d,y,"selected",c);else if(d instanceof HTMLTextAreaElement&&y instanceof HTMLTextAreaElement){let l=y.value,p=d.value;if(x("value",d,"update",c))return;l!==p&&(d.value=l),d.firstChild&&d.firstChild.nodeValue!==l&&(d.firstChild.nodeValue=l)}}function S(d,y,c,l){let p=y[c],f=d[c];if(p!==f){let g=x(c,d,"update",l);if(g||(d[c]=y[c]),l.formStateSync==="property")return;p?g||d.setAttribute(c,""):x(c,d,"remove",l)||d.removeAttribute(c)}}function x(d,y,c,l){return d==="value"&&l.ignoreActiveValue&&y===document.activeElement?!0:l.callbacks.beforeAttributeUpdated(d,y,c)===!1}function E(d,y){return!!y.ignoreActiveValue&&d===document.activeElement&&d!==document.body}return m}();function w(m,O,v,S){if(m.head.block){let x=O.querySelector("head"),E=v.querySelector("head");if(x&&E){let d=b(x,E,m);return Promise.all(d).then(()=>{let y=Object.assign(m,{head:{block:!1,ignore:!0}});return S(y)})}}return S(m)}function b(m,O,v){let S=[],x=[],E=[],d=[],y=v.scripts.matchMode,c=f=>{if(f.tagName==="SCRIPT")return r(f,y);if(f.tagName==="LINK"&&y==="smart"){let g=f.getAttribute("href");if(g)try{let A=new URL(g,window.location.href);return`link:${f.getAttribute("rel")||""}:${A.origin}${A.pathname}${A.search}`}catch{}}return f.outerHTML},l=new Map;for(let f of O.children)t(f)||l.set(c(f),f);for(let f of m.children){let g=c(f),A=l.has(g),T=v.head.shouldReAppend(f),I=v.head.shouldPreserve(f);A||I?T?x.push(f):(l.delete(g),E.push(f)):v.head.style==="append"?T&&(x.push(f),d.push(f)):v.head.shouldRemove(f)!==!1&&!t(f)&&x.push(f)}d.push(...l.values());let p=[];for(let f of d){let g=document.createRange().createContextualFragment(f.outerHTML).firstChild;if(v.callbacks.beforeNodeAdded(g)!==!1){if("href"in g&&g.href||"src"in g&&g.src){let A,T=new Promise(function(I){A=I});g.addEventListener("load",function(){A()}),p.push(T)}m.appendChild(g),v.callbacks.afterNodeAdded(g),S.push(g)}}for(let f of x)v.callbacks.beforeNodeRemoved(f)!==!1&&(m.removeChild(f),v.callbacks.afterNodeRemoved(f));return v.head.afterHeadMorphed(m,{added:S,kept:E,removed:x}),p}function h(m,O,v){if(!v.scripts.handle)return[];let S=[],x=[],E=[],d=[],y=v.scripts.matchMode,c=Array.from(m.querySelectorAll("script"));for(let p of c){let f=r(p,y),g=O.has(f),A=v.scripts.shouldPreserve(p),T=v.scripts.shouldReAppend(p);g||A?T?(x.push(p),d.push(p)):E.push(p):d.push(p)}for(let p of O){let f=c.some(g=>g.outerHTML===p)}let l=[];for(let p of d){if(v.callbacks.beforeNodeAdded(p)===!1)continue;let f=document.createRange().createContextualFragment(p.outerHTML).firstChild;if(f.src){let g,A=new Promise(function(T){g=T});f.addEventListener("load",function(){g()}),f.addEventListener("error",function(){g()}),l.push(A)}p.replaceWith(f),v.callbacks.afterNodeAdded(f),S.push(f)}return v.scripts.afterScriptsHandled(m,{added:S,kept:E,removed:x}),l}let R=function(){function m(c,l,p){let{persistentIds:f,idMap:g}=d(c,l),A=o.computeMatches(c,l);if(typeof p.key=="function"){let D=new Map,G=new Set,C=H=>{let P=p.key(H);P!=null&&(D.has(P)?G.add(P):D.set(P,H))};c instanceof Element&&C(c);for(let H of c.querySelectorAll("*"))C(H);for(let H of G)D.delete(H);let V=new Map;for(let[H,P]of A)V.set(P,H);let be=l.__hyperMorphRoot||l,ae=new Map,qe=new Set,Ve=H=>{let P=p.key(H);P!=null&&(ae.has(P)?qe.add(P):ae.set(P,H))};be instanceof Element&&Ve(be);for(let H of be.querySelectorAll("*"))Ve(H);for(let H of qe)ae.delete(H);for(let[H,P]of ae){let K=D.get(H);if(!K||K.tagName!==P.tagName)continue;let Ae=V.get(K);Ae&&Ae!==P&&A.delete(Ae);let Me=A.get(P);Me&&Me!==K&&V.delete(Me),A.set(P,K),V.set(K,P)}}let T=new Set;for(let D of A.values())T.add(D);let I=O(p),L=I.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(L))throw`Do not understand how to morph style ${L}`;return{target:c,newContent:l,config:I,morphStyle:L,ignoreActive:I.ignoreActive,ignoreActiveValue:I.ignoreActiveValue,restoreFocus:I.restoreFocus,formStateSync:I.formStateSync||"attribute",idMap:g,persistentIds:f,hyperMatches:A,hyperMatchedOldElements:T,pantry:v(),activeElementAndParents:S(c),callbacks:I.callbacks,head:I.head,scripts:I.scripts}}function O(c){let l=Object.assign({},n);return Object.assign(l,c),l.callbacks=Object.assign({},n.callbacks,c.callbacks),l.head=Object.assign({},n.head,c.head),l.scripts=Object.assign({},n.scripts,c.scripts),l}function v(){let c=document.createElement("div");return c.hidden=!0,document.body.insertAdjacentElement("afterend",c),c}function S(c){let l=[],p=document.activeElement;if(p?.tagName!=="BODY"&&c.contains(p))for(;p&&(l.push(p),p!==c);)p=p.parentElement;return l}function x(c){let l=Array.from(c.querySelectorAll("[id]"));return c.getAttribute?.("id")&&l.push(c),l}function E(c,l,p,f){for(let g of f){let A=g.getAttribute("id");if(l.has(A)){let T=g;for(;T;){let I=c.get(T);if(I==null&&(I=new Set,c.set(T,I)),I.add(A),T===p)break;T=T.parentElement}}}}function d(c,l){let p=x(c),f=x(l),g=y(p,f),A=new Map;E(A,g,c,p);let T=l.__hyperMorphRoot||l;return E(A,g,T,f),{persistentIds:g,idMap:A}}function y(c,l){let p=new Set,f=new Map;for(let{id:A,tagName:T}of c)f.has(A)?p.add(A):f.set(A,T);let g=new Set;for(let{id:A,tagName:T}of l)g.has(A)?p.add(A):f.get(A)===T&&g.add(A);for(let A of p)g.delete(A);return g}return m}(),{normalizeElement:N,normalizeParent:k}=function(){let m=new WeakSet;function O(E){return E instanceof Document?E.documentElement:E}function v(E){if(E==null)return document.createElement("div");if(typeof E=="string")return v(x(E));if(m.has(E))return E;if(E instanceof Node){if(E.parentNode)return new S(E);{let d=document.createElement("div");return d.append(E),d}}else{let d=document.createElement("div");for(let y of[...E])d.append(y);return d}}class S{constructor(d){this.originalNode=d,this.realParentNode=d.parentNode,this.previousSibling=d.previousSibling,this.nextSibling=d.nextSibling}get childNodes(){let d=[],y=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;for(;y&&y!=this.nextSibling;)d.push(y),y=y.nextSibling;return d}querySelectorAll(d){return this.childNodes.reduce((y,c)=>{if(c instanceof Element){c.matches(d)&&y.push(c);let l=c.querySelectorAll(d);for(let p=0;p<l.length;p++)y.push(l[p])}return y},[])}insertBefore(d,y){return this.realParentNode.insertBefore(d,y)}moveBefore(d,y){return this.realParentNode.moveBefore(d,y)}get __hyperMorphRoot(){return this.originalNode}}function x(E){let d=new DOMParser,y=E.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(y.match(/<\/html>/)||y.match(/<\/head>/)||y.match(/<\/body>/)){let c=d.parseFromString(E,"text/html");if(y.match(/<\/html>/))return m.add(c),c;{let l=c.firstChild;return l&&m.add(l),l}}else{let l=d.parseFromString("<body><template>"+E+"</template></body>","text/html").body.querySelector("template").content;return m.add(l),l}}return{normalizeElement:O,normalizeParent:v}}();return{morph:i,defaults:n}}();var Qr=He.morph,Xr=He.defaults,ut=He;function Pe(e,t,{onWidgetRemoved:r}={}){ut.morph(e,t,{morphStyle:"innerHTML",ignoreActiveValue:!0,restoreFocus:!0,formStateSync:"property",callbacks:{beforeNodeRemoved(n){let o=pe.get(n);o?.destroy&&o.destroy(),r?.(n)}}})}var _e=null;function De(e){if(typeof e!="function")throw new TypeError("registerUpgrade expects a function (v1Data) => v2Data");if(_e)throw new te;_e=e}function me(){return _e}function se(e,t){let r={carriedOver:0,discarded:0,listItems:0},n=je(t,e,r);return $e(t,e,r),{data:n,summary:r}}function je(e,t,r){if(typeof e=="string")return e.endsWith("[]")?Array.isArray(t)?(r.listItems+=t.length,r.carriedOver+=t.length,t):void 0:t==null?void 0:(r.carriedOver++,t);if(Array.isArray(e)){let[,n]=e;return Array.isArray(t)?(r.listItems+=t.length,t.map(o=>je(n,o,r))):void 0}if(typeof e=="object"&&e!==null){let n={};for(let[o,i]of Object.entries(e)){let u=je(i,t?.[o],r);u!==void 0&&(n[o]=u)}return n}}function $e(e,t,r){if(t!=null){if(typeof e=="object"&&e!==null&&!Array.isArray(e)){if(typeof t!="object"||Array.isArray(t))return;let n=new Set(Object.keys(e));for(let o of Object.keys(t))n.has(o)?$e(e[o],t[o],r):r.discarded+=ge(t[o]);return}if(Array.isArray(e)&&Array.isArray(t)){let n=e[1];t.forEach(o=>$e(n,o,r));return}typeof e=="string"&&!e.endsWith("[]")&&typeof t=="object"&&t!==null&&(r.discarded+=ge(t))}}function ge(e){return e==null?0:Array.isArray(e)?e.reduce((t,r)=>t+ge(r),0):typeof e=="object"?Object.values(e).reduce((t,r)=>t+ge(r),0):1}async function Be({sourceUrl:e,v1Data:t,v1Version:r=null,parent:n=typeof window<"u"?window:null,timeoutMs:o=15e3,hidden:i=!0}={}){if(!n)throw new Error("upgrade.run requires a window context");if(!e)throw new Error("upgrade.run requires sourceUrl");let u=or(e,n.location.origin),s=new URL(u,n.location.href).origin,a=n.document.createElement("iframe");i&&(a.style.cssText="position:absolute;left:-9999px;top:-9999px;width:1px;height:1px;border:0;"),a.setAttribute("aria-hidden","true"),a.src=u,n.document.body.appendChild(a);let M=()=>{};try{return await new Promise((w,b)=>{let h=setTimeout(()=>{b(new Error(`upgrade.run: helper iframe timed out after ${o}ms`))},o),R=N=>{if(N.source!==a.contentWindow||N.origin!==s)return;let k=N.data;if(!(!k||typeof k!="object")){if(k.type==="hha:upgrade-ready"){a.contentWindow.postMessage({type:"hha:upgrade-data",v1Data:t,v1Version:r},s);return}if(k.type==="hha:upgrade-result"){clearTimeout(h),w({html:k.html,summary:k.summary});return}if(k.type==="hha:upgrade-error"){clearTimeout(h);let m=new Error(k.message||"helper error");m.name=k.name||"UpgradeHelperError",b(m);return}}};n.addEventListener("message",R),M=()=>{n.removeEventListener("message",R),clearTimeout(h),a.parentNode&&a.parentNode.removeChild(a)}})}finally{M()}}function or(e,t){let r=new URL(e,typeof location<"u"?location.href:void 0);return r.searchParams.set("_hyperHtmlApi","upgrade-helper"),r.searchParams.set("parentOrigin",t),r.toString()}function ir(e){return e&&e.nodeType===1&&e.tagName==="SCRIPT"&&e.hasAttribute&&e.hasAttribute("data-rules-name")}function sr(e){return e?(e.nodeType===9||e.nodeType===11,e):null}var ar={find(e,t,r={}){let n=sr(e);if(!n||!n.querySelectorAll)return[];let o=Array.from(n.querySelectorAll(t));r.includeRulesTag||(o=o.filter(u=>!ir(u)));let i=[];if(r.skip&&i.push(r.skip),r.templateAttr&&i.push("["+r.templateAttr+"]"),i.length){let u=i.join(", ");o=o.filter(s=>!s.closest||!s.closest(u))}return o},parent(e){return e?e.parentElement:null},children(e){return e?Array.from(e.children):[]},text(e,t){if(t===void 0)return(e.textContent||"").trim();e.textContent=t},attr(e,t,r){if(r===void 0)return e.hasAttribute&&e.hasAttribute(t)?e.getAttribute(t):null;e.setAttribute(t,r)},removeAttr(e,t){e&&e.removeAttribute&&e.removeAttribute(t)},prop(e,t,r){if(r===void 0){let n=e?e[t]:void 0;return n!==void 0?n:null}e[t]=r},clone(e){return e.cloneNode(!0)},insertAt(e,t,r){let n=e.children[r]||null;e.insertBefore(t,n)},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 n=e.ownerDocument.createElement("template");n.innerHTML=t;let o=n.content.firstElementChild;if(!o)throw new Error("dom.replaceWith: html did not parse to an element");return e.parentNode.replaceChild(o,e),o},stripIds(e){let t=0;return e.id&&(e.removeAttribute("id"),t++),(e.querySelectorAll?e.querySelectorAll("[id]"):[]).forEach(n=>{n.removeAttribute("id"),t++}),t},sameNode(e,t){return e===t}},$=ar;var cr="_hyperHtmlApi",ur="upgrade-helper",lr="parentOrigin";function ye(e=typeof location<"u"?location:null){if(!e)return!1;try{return new URLSearchParams(e.search).get(cr)===ur}catch{return!1}}function lt(e=typeof location<"u"?location:null){return e?new URLSearchParams(e.search).get(lr):null}function We({win:e,doc:t,parentOrigin:r}={}){if(e=e||(typeof window<"u"?window:null),t=t||(typeof document<"u"?document:null),!e||!t||(r=r||lt(e.location),!r))return;let n=()=>fr({win:e,doc:t,parentOrigin:r});t.readyState==="loading"?t.addEventListener("DOMContentLoaded",n,{once:!0}):n()}function fr({win:e,doc:t,parentOrigin:r}){let n;try{n=q($,t.body)}catch(a){return Fe(e,r,a)}if(!n)return Fe(e,r,new Error("helper-mode: no rules tag in v2 document"));let o=n.rules,i=pr(t,"hyper-version"),u=!!me(),s=a=>{if(a.source!==e.parent||a.origin!==r)return;let M=a.data;if(!(!M||M.type!=="hha:upgrade-data")){e.removeEventListener("message",s);try{let w=dr({doc:t,rules:o,v1Data:M.v1Data});e.parent.postMessage({type:"hha:upgrade-result",html:w.html,summary:w.summary},r)}catch(w){Fe(e,r,w)}}};e.addEventListener("message",s),e.parent.postMessage({type:"hha:upgrade-ready",rules:o,version:i,hasTransform:u},r)}function dr({doc:e,rules:t,v1Data:r}){let n=me(),o=r,i=!1;n&&(o=n(r),i=!0);let{data:u,summary:s}=se(o,t);W($,e.body,t,u);let a=B($,e.body,t);return{html:`<!DOCTYPE html>
|
|
3
|
+
`+e.documentElement.outerHTML,summary:{...s,transformApplied:i,appliedFieldCount:Ue(a)}}}function Fe(e,t,r){e.parent.postMessage({type:"hha:upgrade-error",name:r?.name||"Error",message:r?.message||String(r)},t)}function pr(e,t){let r=e.querySelector(`meta[name="${t}"]`);return r?r.getAttribute("content"):null}function Ue(e){return e==null?0:Array.isArray(e)?e.reduce((t,r)=>t+Ue(r),0):typeof e=="object"?Object.values(e).reduce((t,r)=>t+Ue(r),0):1}var ft={extract:(e,t,r)=>B($,e,t,r),apply:(e,t,r,n)=>W($,e,t,r,n),findRulesIn:(e,t)=>q($,e,t),findRules:(e,t)=>Ne($,e,t),bind:(e,t,r)=>Xe($,e,t,r),parseStrict:Re,parseRelaxed:oe,errors:ue,DOM_PROPERTIES:ce},dt={buildForm:Ie,bindFormEvents:ke,scaffold:Y,morphForm:Pe,path:de},pt={registerUpgrade:De,run:Be,shapeMatch:se,isHelperMode:ye};typeof window<"u"&&ye(window.location)&&We({win:window,doc:document});var mr={engine:ft,cms:dt,upgrade:pt},gr=mr;return bt(yr);})();
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"apply",
|
|
10
10
|
"CMS"
|
|
11
11
|
],
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.2.0",
|
|
13
13
|
"homepage": "https://github.com/panphora/hyper-html-api",
|
|
14
14
|
"bugs": {
|
|
15
15
|
"url": "https://github.com/panphora/hyper-html-api/issues"
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"exports": {
|
|
28
28
|
".": "./src/hyper-html-api.js",
|
|
29
29
|
"./engine": "./src/engine/index.js",
|
|
30
|
+
"./cms": "./src/cms/index.js",
|
|
30
31
|
"./cheerio": "./src/adapters/cheerio.js",
|
|
31
32
|
"./dom": "./src/adapters/dom.js"
|
|
32
33
|
},
|
|
@@ -42,8 +43,8 @@
|
|
|
42
43
|
"test:webkit": "web-test-runner --playwright --browsers webkit",
|
|
43
44
|
"test:all": "web-test-runner --concurrency 1 --playwright --browsers chromium firefox webkit",
|
|
44
45
|
"test:node": "node --test 'test-node/**/*.test.js'",
|
|
45
|
-
"test:ci": "npm run test:node && npm run test:all -- --fail-only && node test/lib/ensure-full-coverage.
|
|
46
|
-
"test:coverage": "npm run test:chrome && node test/lib/ensure-full-coverage.
|
|
46
|
+
"test:ci": "npm run test:node && npm run test:all -- --fail-only && node test/lib/ensure-full-coverage.cjs",
|
|
47
|
+
"test:coverage": "npm run test:chrome && node test/lib/ensure-full-coverage.cjs",
|
|
47
48
|
"format": "prettier --write .",
|
|
48
49
|
"format:check": "prettier --check ."
|
|
49
50
|
},
|
|
@@ -51,6 +52,9 @@
|
|
|
51
52
|
"type": "git",
|
|
52
53
|
"url": "git+https://github.com/panphora/hyper-html-api.git"
|
|
53
54
|
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"hyper-morph": "^0.3.0"
|
|
57
|
+
},
|
|
54
58
|
"devDependencies": {
|
|
55
59
|
"@web/test-runner": "^0.20.0",
|
|
56
60
|
"@web/test-runner-playwright": "^0.11.0",
|
package/src/adapters/cheerio.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
const RULES_TAG_ID = 'hyper-html-api'
|
|
2
|
-
|
|
3
1
|
function isRulesTag(node) {
|
|
4
2
|
if (!node || !node.attr) return false
|
|
5
|
-
if (node.attr('id') !== RULES_TAG_ID) return false
|
|
6
3
|
const tag = node.prop ? node.prop('tagName') : ''
|
|
7
|
-
|
|
4
|
+
if (String(tag || '').toUpperCase() !== 'SCRIPT') return false
|
|
5
|
+
return node.attr('data-rules-name') !== undefined
|
|
8
6
|
}
|
|
9
7
|
|
|
10
8
|
function toWrappers(cheerioSet) {
|
|
@@ -16,9 +14,16 @@ function toWrappers(cheerioSet) {
|
|
|
16
14
|
const cheerioAdapter = {
|
|
17
15
|
find(ctx, selector, opts = {}) {
|
|
18
16
|
if (!ctx || !ctx.find) return []
|
|
19
|
-
|
|
20
|
-
if (opts.includeRulesTag)
|
|
21
|
-
|
|
17
|
+
let matches = toWrappers(ctx.find(selector))
|
|
18
|
+
if (!opts.includeRulesTag) matches = matches.filter((n) => !isRulesTag(n))
|
|
19
|
+
const skipParts = []
|
|
20
|
+
if (opts.skip) skipParts.push(opts.skip)
|
|
21
|
+
if (opts.templateAttr) skipParts.push('[' + opts.templateAttr + ']')
|
|
22
|
+
if (skipParts.length) {
|
|
23
|
+
const combined = skipParts.join(', ')
|
|
24
|
+
matches = matches.filter((n) => !n.closest || n.closest(combined).length === 0)
|
|
25
|
+
}
|
|
26
|
+
return matches
|
|
22
27
|
},
|
|
23
28
|
|
|
24
29
|
parent(node) {
|
|
@@ -45,14 +50,49 @@ const cheerioAdapter = {
|
|
|
45
50
|
node.attr(name, value)
|
|
46
51
|
},
|
|
47
52
|
|
|
53
|
+
removeAttr(node, name) {
|
|
54
|
+
if (node) node.removeAttr(name)
|
|
55
|
+
},
|
|
56
|
+
|
|
48
57
|
prop(node, name, value) {
|
|
49
58
|
if (value === undefined) {
|
|
59
|
+
// Cheerio's .prop() doesn't expose innerHTML/textContent/className as
|
|
60
|
+
// proper properties. Route reads through the matching cheerio API so
|
|
61
|
+
// they're symmetric with the writes below (and with the DOM adapter).
|
|
62
|
+
if (name === 'innerHTML') return node.html()
|
|
63
|
+
if (name === 'textContent' || name === 'innerText') return node.text()
|
|
64
|
+
if (name === 'className') {
|
|
65
|
+
const v = node.attr('class')
|
|
66
|
+
return v !== undefined ? v : null
|
|
67
|
+
}
|
|
50
68
|
const v = node.prop(name)
|
|
51
69
|
return v !== undefined ? v : null
|
|
52
70
|
}
|
|
71
|
+
// Cheerio's .prop() setter writes a literal attribute named `name`; it
|
|
72
|
+
// does NOT mutate the underlying property (cheerio has no live DOM).
|
|
73
|
+
// For names that have semantic write meaning, route through the right
|
|
74
|
+
// cheerio API instead.
|
|
75
|
+
const v = value == null ? '' : String(value)
|
|
76
|
+
if (name === 'innerHTML') return node.html(v)
|
|
77
|
+
if (name === 'textContent' || name === 'innerText') return node.text(v)
|
|
78
|
+
if (name === 'className') return node.attr('class', v)
|
|
53
79
|
node.prop(name, value)
|
|
54
80
|
},
|
|
55
81
|
|
|
82
|
+
replaceWith(node, html) {
|
|
83
|
+
// Capture the parent + index before detaching, then reparse the html
|
|
84
|
+
// and replace. Returns a fresh cheerio wrapper around the new node so
|
|
85
|
+
// callers can keep operating on it.
|
|
86
|
+
const parent = node.parent()
|
|
87
|
+
if (!parent || !parent.length) {
|
|
88
|
+
// Detached node — nothing meaningful we can do. Mirror DOM throwing.
|
|
89
|
+
throw new Error('cheerio.replaceWith: node has no parent')
|
|
90
|
+
}
|
|
91
|
+
const idx = parent.children().index(node[0])
|
|
92
|
+
node.replaceWith(html)
|
|
93
|
+
return parent.children().eq(idx)
|
|
94
|
+
},
|
|
95
|
+
|
|
56
96
|
clone(node) {
|
|
57
97
|
return node.clone()
|
|
58
98
|
},
|
package/src/adapters/dom.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const RULES_TAG_ID = 'hyper-html-api'
|
|
2
|
-
|
|
3
1
|
function isRulesTag(node) {
|
|
4
|
-
return node && node.nodeType === 1 && node.
|
|
2
|
+
return node && node.nodeType === 1 && node.tagName === 'SCRIPT'
|
|
3
|
+
&& node.hasAttribute && node.hasAttribute('data-rules-name')
|
|
5
4
|
}
|
|
6
5
|
|
|
7
6
|
function resolveSearchRoot(ctx) {
|
|
@@ -15,9 +14,16 @@ const dom = {
|
|
|
15
14
|
find(ctx, selector, opts = {}) {
|
|
16
15
|
const root = resolveSearchRoot(ctx)
|
|
17
16
|
if (!root || !root.querySelectorAll) return []
|
|
18
|
-
|
|
19
|
-
if (opts.includeRulesTag)
|
|
20
|
-
|
|
17
|
+
let all = Array.from(root.querySelectorAll(selector))
|
|
18
|
+
if (!opts.includeRulesTag) all = all.filter((n) => !isRulesTag(n))
|
|
19
|
+
const skipParts = []
|
|
20
|
+
if (opts.skip) skipParts.push(opts.skip)
|
|
21
|
+
if (opts.templateAttr) skipParts.push('[' + opts.templateAttr + ']')
|
|
22
|
+
if (skipParts.length) {
|
|
23
|
+
const combined = skipParts.join(', ')
|
|
24
|
+
all = all.filter((n) => !n.closest || !n.closest(combined))
|
|
25
|
+
}
|
|
26
|
+
return all
|
|
21
27
|
},
|
|
22
28
|
|
|
23
29
|
parent(node) {
|
|
@@ -40,6 +46,10 @@ const dom = {
|
|
|
40
46
|
node.setAttribute(name, value)
|
|
41
47
|
},
|
|
42
48
|
|
|
49
|
+
removeAttr(node, name) {
|
|
50
|
+
if (node && node.removeAttribute) node.removeAttribute(name)
|
|
51
|
+
},
|
|
52
|
+
|
|
43
53
|
prop(node, name, value) {
|
|
44
54
|
if (value === undefined) {
|
|
45
55
|
const v = node ? node[name] : undefined
|
|
@@ -61,6 +71,21 @@ const dom = {
|
|
|
61
71
|
if (node && node.parentNode) node.parentNode.removeChild(node)
|
|
62
72
|
},
|
|
63
73
|
|
|
74
|
+
replaceWith(node, html) {
|
|
75
|
+
if (!node || !node.parentNode) {
|
|
76
|
+
throw new Error('dom.replaceWith: node has no parent')
|
|
77
|
+
}
|
|
78
|
+
const doc = node.ownerDocument
|
|
79
|
+
const template = doc.createElement('template')
|
|
80
|
+
template.innerHTML = html
|
|
81
|
+
const newNode = template.content.firstElementChild
|
|
82
|
+
if (!newNode) {
|
|
83
|
+
throw new Error('dom.replaceWith: html did not parse to an element')
|
|
84
|
+
}
|
|
85
|
+
node.parentNode.replaceChild(newNode, node)
|
|
86
|
+
return newNode
|
|
87
|
+
},
|
|
88
|
+
|
|
64
89
|
stripIds(node) {
|
|
65
90
|
let count = 0
|
|
66
91
|
if (node.id) {
|