haori 0.4.16 → 0.4.17

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.ja.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Haori.js は、HTML 属性を中心にして動的な UI を実現する軽量なライブラリです。JavaScript をほとんど書かずに、データバインディング、条件分岐、繰り返し処理、フォームの双方向バインディング、サーバー通信などを HTML 属性で宣言できます。
4
4
 
5
- バージョン: 0.4.16
5
+ バージョン: 0.4.17
6
6
 
7
7
  ---
8
8
 
@@ -101,6 +101,8 @@ Haori.mount(document.body, {items: [{name: 'りんご'}, {name: 'みかん'}]});
101
101
 
102
102
  テンプレート式では、プロパティアクセス、動的インデックスを含むブラケットアクセス、optional chaining、三項演算子、配列 `map` / `filter` のアロー関数、spread を伴う呼び出しなどの安全な構文を利用できます。一方で、グローバルオブジェクト、`eval` や `arguments`、`constructor`、`__proto__`、`prototype`、`Reflect` などの脱出経路は使用できません。
103
103
 
104
+ `data-fetch` と `data-import` は、バインディング更新時に評価結果が変化した場合のみ自動で再評価されます。`data-fetch` は評価後の URL、HTTP メソッド、ヘッダー、body を含む実行シグネチャで比較し、`data-import` は評価後 URL で比較します。これらの属性値に未解決参照が 1 つでも含まれる場合、その時点では実行されず、後続のバインディング更新で参照が解決したときに初めて実行対象になります。
105
+
104
106
  `src` や `type="number"` の `value` のように、ブラウザが HTML 解析時に先に解釈する属性へテンプレート式を直接書くと、初期表示時に警告や不要なアクセスが発生することがあります。こうした属性は `data-attr-*` を使ってください。`data-attr-xxx` は対応する `xxx` 属性だけを更新し、`input.value` のような DOM property 同期は行いません。
105
107
 
106
108
  詳しい使い方や多数のサンプルについては、公式ドキュメントを参照してください。
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Haori.js is a lightweight, HTML-first UI library that enables dynamic user interfaces primarily through HTML attributes. It lets you declare data bindings, conditional rendering, list rendering, form two-way binding, server fetches, and HTML imports without writing much JavaScript.
4
4
 
5
- Version: 0.4.16
5
+ Version: 0.4.17
6
6
 
7
7
  ---
8
8
 
@@ -101,6 +101,8 @@ Haori.mount(document.body, {items: [{name: 'apple'}, {name: 'orange'}]});
101
101
 
102
102
  Template expressions support safe JavaScript-like syntax such as property access, bracket access with dynamic indexes, optional chaining, ternary expressions, and method chains including array `map`/`filter` with arrow functions and spread calls. Access to global objects, `eval` or `arguments`, and prototype escape paths such as `constructor`, `__proto__`, `prototype`, or `Reflect` is blocked.
103
103
 
104
+ `data-fetch` and `data-import` are automatically re-evaluated only when their evaluated values change after a binding update. `data-fetch` compares a request signature composed of the resolved URL, HTTP method, headers, and body, while `data-import` compares only the resolved URL. If either attribute contains even one unresolved reference, it is treated as invalid for that evaluation cycle, is not executed, and becomes executable only after a later binding update resolves the reference.
105
+
104
106
  When the browser interprets an attribute during HTML parsing, such as `src` or `value` on `input type="number"`, writing template expressions directly in that attribute can cause warnings or unwanted requests before Haori runs. Use `data-attr-*` for those cases. `data-attr-xxx` updates only the matching `xxx` attribute and does not synchronize DOM properties such as `input.value`.
105
107
 
106
108
  For detailed usage and many examples, see the official documentation.
package/dist/haori.cjs.js CHANGED
@@ -1,17 +1,17 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const C=class C{static isEnabled(){return C.devMode}static enable(){C.devMode=!0}static disable(){C.devMode=!1}static set(t){C.devMode=t}};C.devMode=!1;let B=C;const Q="embedded";function it(P){return P==="embedded"||P==="demo"}function st(P){return P===null?null:it(P)?P:Q}const k=class k{static get runtime(){return k._runtime}static setRuntime(t){k._runtime=it(t)?t:Q}static detect(){try{const t=document.currentScript||document.querySelector('script[src*="haori"]');if(t instanceof HTMLScriptElement){const r=t.getAttribute("data-prefix")||k._prefix;k._prefix=r.endsWith("-")?r:r+"-";const i=st(t.getAttribute("data-runtime"));i!==null&&(k._runtime=i)}if(t instanceof HTMLScriptElement&&t.hasAttribute(`${k._prefix}dev`)){B.set(!0);return}const e=window.location.hostname;if(e==="localhost"||e.endsWith(".localhost")||e==="127.0.0.1"||e==="::1"||e.endsWith(".local")){B.set(!0);return}B.set(!1)}catch{}}static get prefix(){return k._prefix}};k._prefix="data-",k._runtime=Q;let u=k;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",u.detect):u.detect();class f{static info(t,...e){B.isEnabled()&&console.log&&console.log(t,...e)}static warn(t,...e){B.isEnabled()&&console.warn&&console.warn(t,...e)}static error(t,...e){console.error(t,...e)}}class nt{constructor(){this.MAX_BUDGET=8,this.queue=[],this.processing=!1}enqueue(t,e=!1){let r,i;const n=new Promise((a,o)=>{r=a,i=o}),s={task:t,timestamp:performance.now(),promise:n,resolve:r,reject:i};return e?this.queue.unshift(s):this.queue.push(s),this.scheduleProcessing(),n}async processQueue(){if(!(this.processing||this.queue.length===0)){this.processing=!0;try{const t=performance.now();for(;this.queue.length>0;){const e=this.queue.shift();if(!e)return;try{const r=await e.task();e.resolve(r)}catch(r){e.reject(r),f.error("[Haori]",`Task ${e.timestamp} failed:`,r)}if(performance.now()-t>this.MAX_BUDGET)break}}catch(t){f.error("[Haori]","Error processing queue:",t)}finally{this.processing=!1,this.queue.length>0&&this.scheduleProcessing()}}}scheduleProcessing(){this.processing||(typeof requestAnimationFrame<"u"?requestAnimationFrame(()=>{this.processQueue()}):setTimeout(()=>{this.processQueue()},16))}async wait(){if(this.queue.length===0&&!this.processing)return;const t=this.queue.map(e=>e.promise);t.length>0&&await Promise.allSettled(t)}}const tt=class tt{static enqueue(t,e=!1){return this.ASYNC_QUEUE.enqueue(t,e)}static wait(){return this.ASYNC_QUEUE.wait()}};tt.ASYNC_QUEUE=new nt;let F=tt;class U{static get runtime(){return u.runtime}static setRuntime(t){u.setRuntime(t)}static dialog(t){return F.enqueue(()=>{window.alert(t)},!0)}static async toast(t,e="info"){const r=document.createElement("div");r.className=`haori-toast haori-toast-${e}`,r.textContent=t,r.setAttribute("popover","manual"),r.setAttribute("role","status"),r.setAttribute("aria-live",e==="error"?"assertive":"polite"),document.body.appendChild(r),r.showPopover(),setTimeout(()=>{try{r.hidePopover()}finally{r.remove()}},3e3)}static confirm(t){return F.enqueue(()=>window.confirm(t),!0)}static openDialog(t){return F.enqueue(()=>{t instanceof HTMLDialogElement?t.showModal():f.error("[Haori]","Element is not a dialog: ",t)},!0)}static closeDialog(t){return F.enqueue(()=>{t instanceof HTMLDialogElement?t.close():f.error("[Haori]","Element is not a dialog: ",t)},!0)}static addErrorMessage(t,e){return U.addMessage(t,e,"error")}static addMessage(t,e,r){return F.enqueue(()=>{const i=t instanceof HTMLFormElement?t:t.parentElement??t;i.setAttribute("data-message",e),r!==void 0?i.setAttribute("data-message-level",r):i.removeAttribute("data-message-level")},!0)}static clearMessages(t){return F.enqueue(()=>{t.removeAttribute("data-message"),t.removeAttribute("data-message-level"),t.querySelectorAll("[data-message]").forEach(e=>{e.removeAttribute("data-message"),e.removeAttribute("data-message-level")})},!0)}}const at=["addErrorMessage","clearMessages"];function rt(){const t=globalThis.window?.Haori;return at.every(r=>typeof t?.[r]=="function")?t:U}class y{static getValues(t){const e={};return y.getPartValues(t,e)}static getPartValues(t,e){const r=t.getAttribute("name"),i=t.getAttribute(`${u.prefix}form-object`),n=t.getAttribute(`${u.prefix}form-list`);if(r){n?Array.isArray(e[String(r)])?e[String(r)].push(t.getValue()):e[String(r)]=[t.getValue()]:e[String(r)]=t.getValue(),i&&f.warn("Haori",`Element cannot have both ${u.prefix}form-object and name attributes.`);for(const s of t.getChildElementFragments())y.getPartValues(s,e)}else if(i){const s={};for(const a of t.getChildElementFragments())y.getPartValues(a,s);Object.keys(s).length>0&&(e[String(i)]=s),n&&f.warn("Haori",`Element cannot have both ${u.prefix}form-list and ${u.prefix}form-object attributes.`)}else if(n){const s=[];for(const a of t.getChildElementFragments()){const o={};y.getPartValues(a,o),Object.keys(o).length>0&&s.push(o)}s.length>0&&(e[String(n)]=s)}else for(const s of t.getChildElementFragments())y.getPartValues(s,e);return e}static setValues(t,e,r=!1){return y.setPartValues(t,e,null,r,!0)}static syncValues(t,e,r=!1){return y.setPartValues(t,e,null,r,!1)}static applyFragmentValue(t,e,r){return r?t.setValue(e):t.syncBindingValue(e)}static setPartValues(t,e,r=null,i=!1,n=!0){const s=[],a=t.getAttribute("name"),o=t.getAttribute(`${u.prefix}form-object`),l=t.getAttribute(`${u.prefix}form-list`),g=t.getAttribute(`${u.prefix}form-detach`);if(a){if(!g||i){const p=e[String(a)];l&&Array.isArray(p)&&r!==null?s.push(y.applyFragmentValue(t,p[r]??null,n)):typeof p>"u"||(typeof p=="string"||typeof p=="number"||typeof p=="boolean"||p===null?s.push(y.applyFragmentValue(t,p,n)):s.push(y.applyFragmentValue(t,String(p),n)))}}else if(o){const p=e[String(o)];if(p&&typeof p=="object")for(const E of t.getChildElementFragments())s.push(y.setPartValues(E,p,null,i,n))}else if(l){const p=e[String(l)];if(Array.isArray(p)){const E=t.getChildElementFragments();for(let T=0;T<E.length;T++){const h=E[T];p.length>T?s.push(y.setPartValues(h,p[T],T,i,n)):s.push(y.setPartValues(h,{},T,i,n))}}}else for(const p of t.getChildElementFragments())s.push(y.setPartValues(p,e,null,i,n));return Promise.all(s).then(()=>{})}static async reset(t){y.clearValues(t),await Promise.all([y.clearMessages(t),y.clearEachClones(t)]),await F.enqueue(()=>{const e=t.getTarget();if(e instanceof HTMLFormElement)e.reset();else{const r=e.parentElement;if(r){const i=e.nextElementSibling,n=document.createElement("form");n.appendChild(e),n.reset(),r.insertBefore(e,i)}}}),await R.evaluateAll(t)}static clearEachClones(t){const e=[],r=n=>{if(n.hasAttribute(`${u.prefix}each`))for(const s of n.getChildElementFragments()){const a=s.hasAttribute(`${u.prefix}each-before`),o=s.hasAttribute(`${u.prefix}each-after`);!a&&!o&&e.push(s.remove())}},i=n=>{r(n);for(const s of n.getChildElementFragments())i(s)};r(t);for(const n of t.getChildElementFragments())i(n);return Promise.all(e).then(()=>{})}static clearValues(t){t.clearValue();for(const e of t.getChildElementFragments())y.clearValues(e)}static clearMessages(t){return rt().clearMessages(t.getTarget())}static addErrorMessage(t,e,r){return y.addMessage(t,e,r,"error")}static addMessage(t,e,r,i){const n=[],s=rt(),a=s.addMessage,o=g=>typeof a=="function"?a.call(s,g,r,i):s.addErrorMessage(g,r),l=y.findFragmentsByKey(t,e);return l.forEach(g=>{n.push(o(g.getTarget()))}),l.length===0&&n.push(o(t.getTarget())),Promise.all(n).then(()=>{})}static findFragmentsByKey(t,e){return y.findFragmentByKeyParts(t,e.split("."))}static findFragmentByKeyParts(t,e){const r=[],i=e[0];if(e.length==1&&t.getAttribute("name")===i&&r.push(t),t.hasAttribute(`${u.prefix}form-object`))e.length>1&&t.getAttribute(`${u.prefix}form-object`)===i&&t.getChildElementFragments().forEach(s=>{r.push(...y.findFragmentByKeyParts(s,e.slice(1)))});else if(t.hasAttribute(`${u.prefix}form-list`)){if(e.length>1){const n=t.getAttribute(`${u.prefix}form-list`),s=i.lastIndexOf("["),a=i.lastIndexOf("]");if(s!==-1&&a!==-1&&s<a){const o=i.substring(0,s);if(n===o){const l=i.substring(s+1,a),g=Number(l);if(isNaN(g))f.error("Haori",`Invalid index: ${i}`);else{const p=t.getChildElementFragments().filter(E=>E.hasAttribute(`${u.prefix}row`));g<p.length&&r.push(...y.findFragmentByKeyParts(p[g],e.slice(1)))}}}}}else t.getChildElementFragments().forEach(n=>{r.push(...y.findFragmentByKeyParts(n,e))});return r}static getFormFragment(t){if(t.getTarget()instanceof HTMLFormElement)return t;const r=t.getParent();return r?this.getFormFragment(r):null}}const M=class M{static getForbiddenBindingValues(){const t=globalThis,e=[t,t.window,t.document,t.navigator,t.history,t.localStorage,t.sessionStorage,t.fetch,t.Function,t.setTimeout,t.setInterval,t.requestAnimationFrame,t.alert,t.confirm,t.prompt];return t.window?.location&&e.push(t.window.location),e.filter(r=>r!=null)}static buildAssignments(t){const e=new Set(t);return this.FORBIDDEN_NAMES.filter(r=>!e.has(r)).map(r=>`const ${r} = undefined`).join(`;
2
- `)}static evaluate(t,e={}){if(t.trim()==="")return f.warn("[Haori]",t,"Expression is empty"),null;if(this.containsDangerousPatterns(t))return f.warn("[Haori]",t,"Expression contains dangerous patterns"),null;if(this.containsForbiddenKeys(e))return f.warn("[Haori]",e,"Binded values contain forbidden keys"),null;if(this.containsForbiddenBindingValues(e))return f.warn("[Haori]",e,"Binded values contain forbidden values"),null;const r=Object.keys(e).filter(s=>!this.FORBIDDEN_BINDING_NAMES.has(s)).sort(),i=`${t}:${r.join(",")}`;let n=this.EXPRESSION_CACHE.get(i);if(!n){const s=this.buildAssignments(r),a=s?`"use strict";
3
- ${s};
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const O=class O{static isEnabled(){return O.devMode}static enable(){O.devMode=!0}static disable(){O.devMode=!1}static set(t){O.devMode=t}};O.devMode=!1;let B=O;const Q="embedded";function st(A){return A==="embedded"||A==="demo"}function it(A){return A===null?null:st(A)?A:Q}const x=class x{static get runtime(){return x._runtime}static setRuntime(t){x._runtime=st(t)?t:Q}static detect(){try{const t=document.currentScript||document.querySelector('script[src*="haori"]');if(t instanceof HTMLScriptElement){const r=t.getAttribute("data-prefix")||x._prefix;x._prefix=r.endsWith("-")?r:r+"-";const s=it(t.getAttribute("data-runtime"));s!==null&&(x._runtime=s)}if(t instanceof HTMLScriptElement&&t.hasAttribute(`${x._prefix}dev`)){B.set(!0);return}const e=window.location.hostname;if(e==="localhost"||e.endsWith(".localhost")||e==="127.0.0.1"||e==="::1"||e.endsWith(".local")){B.set(!0);return}B.set(!1)}catch{}}static get prefix(){return x._prefix}};x._prefix="data-",x._runtime=Q;let u=x;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",u.detect):u.detect();class p{static info(t,...e){B.isEnabled()&&console.log&&console.log(t,...e)}static warn(t,...e){B.isEnabled()&&console.warn&&console.warn(t,...e)}static error(t,...e){console.error(t,...e)}}class nt{constructor(){this.MAX_BUDGET=8,this.queue=[],this.processing=!1}enqueue(t,e=!1){let r,s;const i=new Promise((a,o)=>{r=a,s=o}),n={task:t,timestamp:performance.now(),promise:i,resolve:r,reject:s};return e?this.queue.unshift(n):this.queue.push(n),this.scheduleProcessing(),i}async processQueue(){if(!(this.processing||this.queue.length===0)){this.processing=!0;try{const t=performance.now();for(;this.queue.length>0;){const e=this.queue.shift();if(!e)return;try{const r=await e.task();e.resolve(r)}catch(r){e.reject(r),p.error("[Haori]",`Task ${e.timestamp} failed:`,r)}if(performance.now()-t>this.MAX_BUDGET)break}}catch(t){p.error("[Haori]","Error processing queue:",t)}finally{this.processing=!1,this.queue.length>0&&this.scheduleProcessing()}}}scheduleProcessing(){this.processing||(typeof requestAnimationFrame<"u"?requestAnimationFrame(()=>{this.processQueue()}):setTimeout(()=>{this.processQueue()},16))}async wait(){if(this.queue.length===0&&!this.processing)return;const t=this.queue.map(e=>e.promise);t.length>0&&await Promise.allSettled(t)}}const tt=class tt{static enqueue(t,e=!1){return this.ASYNC_QUEUE.enqueue(t,e)}static wait(){return this.ASYNC_QUEUE.wait()}};tt.ASYNC_QUEUE=new nt;let F=tt;class V{static get runtime(){return u.runtime}static setRuntime(t){u.setRuntime(t)}static dialog(t){return F.enqueue(()=>{window.alert(t)},!0)}static async toast(t,e="info"){const r=document.createElement("div");r.className=`haori-toast haori-toast-${e}`,r.textContent=t,r.setAttribute("popover","manual"),r.setAttribute("role","status"),r.setAttribute("aria-live",e==="error"?"assertive":"polite"),document.body.appendChild(r),r.showPopover(),setTimeout(()=>{try{r.hidePopover()}finally{r.remove()}},3e3)}static confirm(t){return F.enqueue(()=>window.confirm(t),!0)}static openDialog(t){return F.enqueue(()=>{t instanceof HTMLDialogElement?t.showModal():p.error("[Haori]","Element is not a dialog: ",t)},!0)}static closeDialog(t){return F.enqueue(()=>{t instanceof HTMLDialogElement?t.close():p.error("[Haori]","Element is not a dialog: ",t)},!0)}static addErrorMessage(t,e){return V.addMessage(t,e,"error")}static addMessage(t,e,r){return F.enqueue(()=>{const s=t instanceof HTMLFormElement?t:t.parentElement??t;s.setAttribute("data-message",e),r!==void 0?s.setAttribute("data-message-level",r):s.removeAttribute("data-message-level")},!0)}static clearMessages(t){return F.enqueue(()=>{t.removeAttribute("data-message"),t.removeAttribute("data-message-level"),t.querySelectorAll("[data-message]").forEach(e=>{e.removeAttribute("data-message"),e.removeAttribute("data-message-level")})},!0)}}const at=["addErrorMessage","clearMessages"];function rt(){const t=globalThis.window?.Haori;return at.every(r=>typeof t?.[r]=="function")?t:V}class y{static getValues(t){const e={};return y.getPartValues(t,e)}static getPartValues(t,e){const r=t.getAttribute("name"),s=t.getAttribute(`${u.prefix}form-object`),i=t.getAttribute(`${u.prefix}form-list`);if(r){i?Array.isArray(e[String(r)])?e[String(r)].push(t.getValue()):e[String(r)]=[t.getValue()]:e[String(r)]=t.getValue(),s&&p.warn("Haori",`Element cannot have both ${u.prefix}form-object and name attributes.`);for(const n of t.getChildElementFragments())y.getPartValues(n,e)}else if(s){const n={};for(const a of t.getChildElementFragments())y.getPartValues(a,n);Object.keys(n).length>0&&(e[String(s)]=n),i&&p.warn("Haori",`Element cannot have both ${u.prefix}form-list and ${u.prefix}form-object attributes.`)}else if(i){const n=[];for(const a of t.getChildElementFragments()){const o={};y.getPartValues(a,o),Object.keys(o).length>0&&n.push(o)}n.length>0&&(e[String(i)]=n)}else for(const n of t.getChildElementFragments())y.getPartValues(n,e);return e}static setValues(t,e,r=!1){return y.setPartValues(t,e,null,r,!0)}static syncValues(t,e,r=!1){return y.setPartValues(t,e,null,r,!1)}static applyFragmentValue(t,e,r){return r?t.setValue(e):t.syncBindingValue(e)}static setPartValues(t,e,r=null,s=!1,i=!0){const n=[],a=t.getAttribute("name"),o=t.getAttribute(`${u.prefix}form-object`),h=t.getAttribute(`${u.prefix}form-list`),g=t.getAttribute(`${u.prefix}form-detach`);if(a){if(!g||s){const m=e[String(a)];h&&Array.isArray(m)&&r!==null?n.push(y.applyFragmentValue(t,m[r]??null,i)):typeof m>"u"||(typeof m=="string"||typeof m=="number"||typeof m=="boolean"||m===null?n.push(y.applyFragmentValue(t,m,i)):n.push(y.applyFragmentValue(t,String(m),i)))}}else if(o){const m=e[String(o)];if(m&&typeof m=="object")for(const b of t.getChildElementFragments())n.push(y.setPartValues(b,m,null,s,i))}else if(h){const m=e[String(h)];if(Array.isArray(m)){const b=t.getChildElementFragments();for(let v=0;v<b.length;v++){const l=b[v];m.length>v?n.push(y.setPartValues(l,m[v],v,s,i)):n.push(y.setPartValues(l,{},v,s,i))}}}else for(const m of t.getChildElementFragments())n.push(y.setPartValues(m,e,null,s,i));return Promise.all(n).then(()=>{})}static async reset(t){y.clearValues(t),await Promise.all([y.clearMessages(t),y.clearEachClones(t)]),await F.enqueue(()=>{const e=t.getTarget();if(e instanceof HTMLFormElement)e.reset();else{const r=e.parentElement;if(r){const s=e.nextElementSibling,i=document.createElement("form");i.appendChild(e),i.reset(),r.insertBefore(e,s)}}}),await P.evaluateAll(t)}static clearEachClones(t){const e=[],r=i=>{if(i.hasAttribute(`${u.prefix}each`))for(const n of i.getChildElementFragments()){const a=n.hasAttribute(`${u.prefix}each-before`),o=n.hasAttribute(`${u.prefix}each-after`);!a&&!o&&e.push(n.remove())}},s=i=>{r(i);for(const n of i.getChildElementFragments())s(n)};r(t);for(const i of t.getChildElementFragments())s(i);return Promise.all(e).then(()=>{})}static clearValues(t){t.clearValue();for(const e of t.getChildElementFragments())y.clearValues(e)}static clearMessages(t){return rt().clearMessages(t.getTarget())}static addErrorMessage(t,e,r){return y.addMessage(t,e,r,"error")}static addMessage(t,e,r,s){const i=[],n=rt(),a=n.addMessage,o=g=>typeof a=="function"?a.call(n,g,r,s):n.addErrorMessage(g,r),h=y.findFragmentsByKey(t,e);return h.forEach(g=>{i.push(o(g.getTarget()))}),h.length===0&&i.push(o(t.getTarget())),Promise.all(i).then(()=>{})}static findFragmentsByKey(t,e){return y.findFragmentByKeyParts(t,e.split("."))}static findFragmentByKeyParts(t,e){const r=[],s=e[0];if(e.length==1&&t.getAttribute("name")===s&&r.push(t),t.hasAttribute(`${u.prefix}form-object`))e.length>1&&t.getAttribute(`${u.prefix}form-object`)===s&&t.getChildElementFragments().forEach(n=>{r.push(...y.findFragmentByKeyParts(n,e.slice(1)))});else if(t.hasAttribute(`${u.prefix}form-list`)){if(e.length>1){const i=t.getAttribute(`${u.prefix}form-list`),n=s.lastIndexOf("["),a=s.lastIndexOf("]");if(n!==-1&&a!==-1&&n<a){const o=s.substring(0,n);if(i===o){const h=s.substring(n+1,a),g=Number(h);if(isNaN(g))p.error("Haori",`Invalid index: ${s}`);else{const m=t.getChildElementFragments().filter(b=>b.hasAttribute(`${u.prefix}row`));g<m.length&&r.push(...y.findFragmentByKeyParts(m[g],e.slice(1)))}}}}}else t.getChildElementFragments().forEach(i=>{r.push(...y.findFragmentByKeyParts(i,e))});return r}static getFormFragment(t){if(t.getTarget()instanceof HTMLFormElement)return t;const r=t.getParent();return r?this.getFormFragment(r):null}}const M=class M{static getForbiddenBindingValues(){const t=globalThis,e=[t,t.window,t.document,t.navigator,t.history,t.localStorage,t.sessionStorage,t.fetch,t.Function,t.setTimeout,t.setInterval,t.requestAnimationFrame,t.alert,t.confirm,t.prompt];return t.window?.location&&e.push(t.window.location),e.filter(r=>r!=null)}static buildAssignments(t){const e=new Set(t);return this.FORBIDDEN_NAMES.filter(r=>!e.has(r)).map(r=>`const ${r} = undefined`).join(`;
2
+ `)}static evaluate(t,e={}){return this.evaluateDetailed(t,e).value}static evaluateDetailed(t,e={}){if(t.trim()==="")return p.warn("[Haori]",t,"Expression is empty"),{value:null,unresolvedReference:!1};if(this.containsDangerousPatterns(t))return p.warn("[Haori]",t,"Expression contains dangerous patterns"),{value:null,unresolvedReference:!1};if(this.containsForbiddenKeys(e))return p.warn("[Haori]",e,"Binded values contain forbidden keys"),{value:null,unresolvedReference:!1};if(this.containsForbiddenBindingValues(e))return p.warn("[Haori]",e,"Binded values contain forbidden values"),{value:null,unresolvedReference:!1};const r=Object.keys(e).filter(n=>!this.FORBIDDEN_BINDING_NAMES.has(n)).sort(),s=`${t}:${r.join(",")}`;let i=this.EXPRESSION_CACHE.get(s);if(!i){const n=this.buildAssignments(r),a=n?`"use strict";
3
+ ${n};
4
4
  return (${t});`:`"use strict";
5
- return (${t});`;try{n=new Function(...r,a),this.EXPRESSION_CACHE.set(i,n)}catch(o){return f.error("[Haori]","Failed to compile expression:",t,o),null}}try{const s=[],a=this.wrapBoundValues(e);return r.forEach(o=>{s.push(a[o])}),this.withBlockedPropertyAccess(()=>n(...s))}catch(s){return f.error("[Haori]","Expression evaluation error:",t,s),s instanceof ReferenceError?void 0:null}}static containsDangerousPatterns(t){return this.hasAllowedSyntax(t)?[/\beval\s*\(/,/\barguments\s*\[/,/\barguments\s*\./].some(r=>r.test(t)):!0}static hasAllowedSyntax(t){const e=this.tokenizeExpression(t);if(e===null||e.length===0)return!1;const r=[];let i=null;for(let n=0;n<e.length;n++){const s=e[n],a=e[n+1]||null,o=r[r.length-1]||null,l=e[n-2]||null,g=e[n-3]||null;if(this.startsObjectKey(o,i,l,g)&&(s.value==="["||s.type==="identifier"&&this.FORBIDDEN_PROPERTY_NAMES.has(s.value)||s.type==="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(this.decodeStringLiteral(s.value)))||s.type==="identifier"&&(this.DISALLOWED_KEYWORDS.has(s.value)||this.STRICT_FORBIDDEN_NAMES.includes(s.value)||(i?.value==="."||i?.value==="?.")&&this.FORBIDDEN_PROPERTY_NAMES.has(s.value))||o==="member"&&s.value!=="]"&&s.type==="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(this.decodeStringLiteral(s.value))||s.value==="."&&a?.type!=="identifier"||s.value==="?."&&a?.type!=="identifier"&&a?.value!=="["&&a?.value!=="(")return!1;switch(s.value){case"(":r.push("paren");break;case")":{if(r.pop()!=="paren")return!1;break}case"[":{const p=this.startsMemberAccess(i)?"member":"array";r.push(p);break}case"{":r.push("object");break;case"]":{if(r.pop()===void 0)return!1;break}case"}":{if(r.pop()!=="object")return!1;break}}i=s}return r.length===0}static tokenizeExpression(t){const e=[],r=["===","!==","...","?.","&&","||",">=","<=","==","!=","=>"],i=new Set(["(",")","{","}","[","]",".",",","?",":","+","-","*","/","%","!",">","<"]);let n=0;for(;n<t.length;){const s=t[n];if(/\s/.test(s)){n+=1;continue}if(s==="/"&&(t[n+1]==="/"||t[n+1]==="*"))return null;if(s==='"'||s==="'"){const o=this.readStringToken(t,n);if(o===null)return null;e.push(o.token),n=o.nextIndex;continue}const a=r.find(o=>t.startsWith(o,n));if(a){e.push({type:"operator",value:a,position:n}),n+=a.length;continue}if(/[0-9]/.test(s)){const o=this.readNumberToken(t,n);e.push(o.token),n=o.nextIndex;continue}if(/[A-Za-z_$]/.test(s)){const o=this.readIdentifierToken(t,n);e.push(o.token),n=o.nextIndex;continue}if(i.has(s)){e.push({type:"operator",value:s,position:n}),n+=1;continue}return null}return e}static readStringToken(t,e){const r=t[e];let i=e+1;for(;i<t.length;){const n=t[i];if(n==="\\"){i+=2;continue}if(n===r)return{token:{type:"string",value:t.slice(e,i+1),position:e},nextIndex:i+1};i+=1}return null}static readNumberToken(t,e){let r=e;for(;r<t.length&&/[0-9_]/.test(t[r]);)r+=1;if(t[r]===".")for(r+=1;r<t.length&&/[0-9_]/.test(t[r]);)r+=1;return{token:{type:"number",value:t.slice(e,r),position:e},nextIndex:r}}static readIdentifierToken(t,e){let r=e;for(;r<t.length&&/[A-Za-z0-9_$]/.test(t[r]);)r+=1;return{token:{type:"identifier",value:t.slice(e,r),position:e},nextIndex:r}}static startsMemberAccess(t){return t===null?!1:t.type==="identifier"||t.type==="number"?!0:t.value===")"||t.value==="]"||t.value==="?."}static startsObjectKey(t,e,r,i){return t!=="object"?!1:e?.value==="{"||e?.value===","||e?.type==="identifier"&&this.OBJECT_PROPERTY_MODIFIERS.has(e.value)&&(r?.value==="{"||r?.value===",")?!0:e?.value!=="*"?!1:r?.value==="{"||r?.value===","?!0:r?.type==="identifier"&&r.value==="async"&&(i?.value==="{"||i?.value===",")}static decodeStringLiteral(t){return t.slice(1,-1).replace(/\\u\{([0-9a-fA-F]+)\}/g,(e,r)=>String.fromCodePoint(parseInt(r,16))).replace(/\\u([0-9a-fA-F]{4})/g,(e,r)=>String.fromCharCode(parseInt(r,16))).replace(/\\x([0-9a-fA-F]{2})/g,(e,r)=>String.fromCharCode(parseInt(r,16))).replace(/\\(["'\\bfnrtv0])/g,(e,r)=>{switch(r){case"b":return"\b";case"f":return"\f";case"n":return`
6
- `;case"r":return"\r";case"t":return" ";case"v":return"\v";case"0":return"\0";default:return r}})}static wrapBoundValues(t){const e=new WeakMap,r={};return Object.entries(t).forEach(([i,n])=>{r[i]=this.wrapBoundValue(n,e)}),r}static wrapBoundValue(t,e){if(!this.shouldWrapValue(t))return t;const r=t,i=e.get(r);if(i!==void 0)return i;const n=new Proxy(r,{get:(s,a,o)=>{if(typeof a=="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(a))return;const l=Reflect.get(s,a,o);return typeof a=="symbol"?l:this.wrapBoundValue(l,e)},has:(s,a)=>typeof a=="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(a)?!1:Reflect.has(s,a),getOwnPropertyDescriptor:(s,a)=>{if(!(typeof a=="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(a)))return Reflect.getOwnPropertyDescriptor(s,a)},apply:(s,a,o)=>{const l=Reflect.apply(s,a,o);return this.isIteratorLike(l)?l:this.wrapBoundValue(l,e)},construct:(s,a,o)=>this.wrapBoundValue(Reflect.construct(s,a,o),e)});return e.set(r,n),n}static shouldWrapValue(t){if(typeof t=="function")return!0;if(t===null||typeof t!="object")return!1;if(Array.isArray(t))return!0;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}static withBlockedPropertyAccess(t){const r=[{target:Object.prototype,property:"constructor"},{target:Function.prototype,property:"constructor"},{target:Object.prototype,property:"__proto__"}].map(i=>({...i,descriptor:Object.getOwnPropertyDescriptor(i.target,i.property)})).filter(i=>i.descriptor?.configurable===!0);r.forEach(({target:i,property:n})=>{Object.defineProperty(i,n,{configurable:!0,enumerable:!1,get:()=>{},set:()=>{}})});try{return t()}finally{r.forEach(({target:i,property:n,descriptor:s})=>{s!==void 0&&Object.defineProperty(i,n,s)})}}static isIteratorLike(t){return t===null||typeof t!="object"?!1:typeof t.next=="function"}static containsForbiddenKeys(t){if(!t||typeof t!="object")return!1;for(const e of Object.keys(t))if(this.FORBIDDEN_BINDING_NAMES.has(e))return!0;return!1}static containsForbiddenBindingValues(t,e=new WeakSet){if(!t||typeof t!="object"||e.has(t))return!1;if(e.add(t),this.getForbiddenBindingValues().some(r=>r===t))return!0;for(const r of Object.values(t)){if(typeof r=="function"){if(this.getForbiddenBindingValues().some(i=>i===r))return!0;continue}if(this.containsForbiddenBindingValues(r,e))return!0}return!1}};M.FORBIDDEN_NAMES=["window","self","globalThis","frames","parent","top","Function","setTimeout","setInterval","requestAnimationFrame","alert","confirm","prompt","fetch","XMLHttpRequest","Reflect","constructor","__proto__","prototype","Object","document","location","navigator","localStorage","sessionStorage","IndexedDB","history"],M.STRICT_FORBIDDEN_NAMES=["eval","arguments"],M.REBINDABLE_FORBIDDEN_NAMES=new Set(["location"]),M.FORBIDDEN_BINDING_NAMES=new Set([...M.FORBIDDEN_NAMES.filter(t=>!M.REBINDABLE_FORBIDDEN_NAMES.has(t)),"constructor","__proto__","prototype",...M.STRICT_FORBIDDEN_NAMES]),M.FORBIDDEN_PROPERTY_NAMES=new Set(["constructor","__proto__","prototype"]),M.OBJECT_PROPERTY_MODIFIERS=new Set(["get","set","async"]),M.DISALLOWED_KEYWORDS=new Set(["await","break","case","catch","class","const","continue","debugger","default","delete","do","else","export","finally","for","function","if","import","in","instanceof","let","new","return","switch","this","throw","try","typeof","var","void","while","with","yield"]),M.EXPRESSION_CACHE=new Map;let j=M;const I=class I{constructor(t){this.parent=null,this.mounted=!1,this.skipMutationNodes=!1,this.target=t,I.FRAGMENT_CACHE.set(t,this)}static get(t){if(t==null)return null;if(I.FRAGMENT_CACHE.has(t))return I.FRAGMENT_CACHE.get(t);let e;switch(t.nodeType){case Node.ELEMENT_NODE:e=new x(t);break;case Node.TEXT_NODE:e=new O(t);break;case Node.COMMENT_NODE:e=new _(t);break;default:return f.warn("[Haori]","Unsupported node type:",t.nodeType),null}return e}isSkipMutationNodes(){return this.skipMutationNodes}unmount(){if(!this.mounted||this.skipMutationNodes)return Promise.resolve();if(this.parent){const t=this.parent,e=t.skipMutationNodes;return F.enqueue(()=>{t.skipMutationNodes=!0,this.target.parentNode===t.getTarget()&&t.getTarget().removeChild(this.target),this.mounted=!1}).finally(()=>{t.skipMutationNodes=e})}else{const t=this.target.parentNode;if(t)return F.enqueue(()=>{this.target.parentNode===t&&t.removeChild(this.target),this.mounted=!1});this.mounted=!1}return Promise.resolve()}mount(){if(this.mounted||this.skipMutationNodes)return Promise.resolve();if(this.parent){const t=this.parent,e=t.skipMutationNodes;return F.enqueue(()=>{t.skipMutationNodes=!0,this.target.parentNode!==t.getTarget()&&t.getTarget().appendChild(this.target),this.mounted=!0}).finally(()=>{t.skipMutationNodes=e})}return Promise.resolve()}isMounted(){return this.mounted}setMounted(t){this.mounted=t}remove(t=!0){return this.parent&&this.parent.removeChild(this),I.FRAGMENT_CACHE.delete(this.target),t?this.unmount():Promise.resolve()}getTarget(){return this.target}getParent(){return this.parent}setParent(t){this.parent=t}};I.FRAGMENT_CACHE=new WeakMap;let w=I;class x extends w{constructor(t){super(t),this.INPUT_EVENT_TYPES=["text","password","email","url","tel","search","number","range","color","date","datetime-local","month","time","week"],this.children=[],this.attributeMap=new Map,this.bindingData=null,this.bindingDataCache=null,this.visible=!0,this.display=null,this.displayPriority=null,this.template=null,this.listKey=null,this.value=null,this.skipMutationAttributes=!1,this.skipChangeValue=!1,this.syncValue(),t.getAttributeNames().forEach(e=>{const r=t.getAttribute(e);if(r!==null&&!this.attributeMap.has(e)){const i=new q(e,r);this.attributeMap.set(e,i)}}),t.childNodes.forEach(e=>{const r=w.get(e);r.setParent(this),this.children.push(r)})}getChildren(){return this.children}getChildElementFragments(){return this.children.filter(t=>t instanceof x)}pushChild(t){this.children.push(t),t.setParent(this)}removeChild(t){const e=this.children.indexOf(t);if(e<0){f.warn("[Haori]","Child fragment not found.",t);return}this.children.splice(e,1),t.setParent(null)}clone(){const t=new x(this.target.cloneNode(!1));return this.attributeMap.forEach((e,r)=>{t.attributeMap.set(r,e)}),this.children.forEach(e=>{const r=e.clone();t.getTarget().appendChild(r.getTarget()),t.pushChild(r)}),t.mounted=!1,t.bindingData=this.bindingData,t.clearBindingDataCache(),t.visible=!0,t.display=this.display,t.displayPriority=this.displayPriority,t.template=this.template,t.normalizeClonedVisibilityState(),t}normalizeClonedVisibilityState(){(this.visible===!1||this.getTarget().style.display==="none"||this.getTarget().hasAttribute(`${u.prefix}if-false`))&&(this.visible=!0,this.display=null,this.displayPriority=null,this.getTarget().style.removeProperty("display"),this.getTarget().removeAttribute(`${u.prefix}if-false`)),this.children.forEach(t=>{t instanceof x&&t.normalizeClonedVisibilityState()})}remove(t=!0){const e=[];return this.children.forEach(r=>{e.push(r.remove(!1))}),this.children.length=0,this.attributeMap.clear(),this.bindingData=null,this.bindingDataCache=null,this.template&&(e.push(this.template.remove(!1)),this.template=null),e.push(super.remove(t)),Promise.all(e).then(()=>{})}getTarget(){return this.target}getBindingData(){return this.bindingDataCache?this.bindingDataCache:(this.bindingDataCache={},this.parent&&Object.assign(this.bindingDataCache,this.parent.getBindingData()),this.bindingData&&Object.assign(this.bindingDataCache,this.bindingData),this.bindingDataCache)}getRawBindingData(){return this.bindingData}setBindingData(t){this.bindingData=t,this.clearBindingDataCache()}setParent(t){this.parent!==t&&(this.parent=t,this.clearBindingDataCache())}clearBindingDataCache(){this.bindingDataCache=null,this.children.forEach(t=>{t instanceof x&&t.clearBindingDataCache()})}getTemplate(){return this.template}setTemplate(t){this.template=t}setListKey(t){this.listKey=t}getListKey(){return this.listKey}setValue(t){return this.applyValue(t,!0)}syncBindingValue(t){return this.applyValue(t,!1)}applyValue(t,e){if(this.skipChangeValue||this.value===t)return Promise.resolve();const r=this.getTarget();if(r instanceof HTMLInputElement&&(r.type==="checkbox"||r.type==="radio")){const i=this.getAttribute("value"),n=r.type==="checkbox"&&i==="true";let s;return n?s=t===!0||t==="true":i==="false"?s=t===!1:s=i===String(t),this.value=n?s:s?t:null,r.checked===s?Promise.resolve():(this.skipChangeValue=!0,F.enqueue(()=>{r.checked=s,e&&r.dispatchEvent(new Event("change",{bubbles:!0}))}).finally(()=>{this.skipChangeValue=!1}))}else return r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement||r instanceof HTMLSelectElement?(this.value=t,this.skipChangeValue=!0,F.enqueue(()=>{r.value=t===null?"":String(t),e&&((r instanceof HTMLInputElement&&this.INPUT_EVENT_TYPES.includes(r.type)||r instanceof HTMLTextAreaElement)&&r.dispatchEvent(new Event("input",{bubbles:!0})),r.dispatchEvent(new Event("change",{bubbles:!0})))}).finally(()=>{this.skipChangeValue=!1})):(f.warn("[Haori]","setValue is not supported for this element type.",r),Promise.resolve())}getValue(){return this.value}clearValue(){this.value=null}syncValue(){const t=this.getTarget();if(t instanceof HTMLInputElement)if(t.type==="checkbox"||t.type==="radio"){const e=t.type==="checkbox"&&t.value==="true";if(t.checked){const r=t.value;e?this.value=!0:r==="false"?this.value=!1:this.value=r}else{const r=t.value;e?this.value=!1:r==="false"?this.value=!0:this.value=null}}else this.value=t.value;else t instanceof HTMLTextAreaElement?this.value=t.value:t instanceof HTMLSelectElement&&(this.value=t.value)}setAttribute(t,e,r=!1){return this.setAttributeInternal(t,t,e,!0,r)}setAliasedAttribute(t,e,r,i=!1){return this.setAttributeInternal(t,e,r,!1,i)}removeAliasedAttribute(t,e){if(this.skipMutationAttributes)return Promise.resolve();this.attributeMap.delete(t),this.skipMutationAttributes=!0;const r=this.getTarget();return F.enqueue(()=>{r.removeAttribute(t),e!==t&&r.removeAttribute(e)}).finally(()=>{this.skipMutationAttributes=!1})}setAttributeInternal(t,e,r,i,n=!1){if(this.skipMutationAttributes)return Promise.resolve();if(r===null)return t===e?this.removeAttribute(t):this.removeAliasedAttribute(t,e);const s=new q(t,r);if(n){const l=this.attributeMap.get(t);if(l&&(l.isEvaluate||l.isForceEvaluation())&&!s.isEvaluate&&!s.isForceEvaluation())return this.skipMutationAttributes=!0,F.enqueue(()=>{}).finally(()=>{this.skipMutationAttributes=!1})}this.attributeMap.set(t,s),this.skipMutationAttributes=!0;const a=this.getTarget(),o=s.isForceEvaluation()?r:this.getAttribute(t);return F.enqueue(()=>{if(a.getAttribute(t)!==r&&a.setAttribute(t,r),o===null||o===!1)a.removeAttribute(e);else{const l=String(o);a.getAttribute(e)!==l&&a.setAttribute(e,l),i&&s.isEvaluate&&e==="value"&&(a instanceof HTMLInputElement&&this.INPUT_EVENT_TYPES.includes(a.type)||a instanceof HTMLTextAreaElement||a instanceof HTMLSelectElement)&&(this.value=l,a.value!==l&&(a.value=l))}}).finally(()=>{this.skipMutationAttributes=!1})}removeAttribute(t){if(this.skipMutationAttributes)return Promise.resolve();this.attributeMap.delete(t),this.skipMutationAttributes=!0;const e=this.getTarget();return F.enqueue(()=>{e.removeAttribute(t)}).finally(()=>{this.skipMutationAttributes=!1})}getAttribute(t){const e=this.attributeMap.get(t);if(e===void 0)return null;const r=e.evaluate(this.getBindingData());return r.length===1?r[0]:L.joinEvaluateResults(r)}getRawAttribute(t){const e=this.attributeMap.get(t);return e===void 0?null:e.getValue()}getAttributeNames(){return Array.from(this.attributeMap.keys())}hasAttribute(t){return this.attributeMap.has(t)}resolveInsertionPointFromDom(t,e){const r=t.getTarget();if(r.parentNode!==this.target)return null;const i=e?r.nextSibling:r;let n=e?r.nextSibling:r;for(;n!==null;){const s=w.get(n);if(s!==null){const a=this.children.indexOf(s);if(a!==-1)return{index:a,referenceNode:i}}n=n.nextSibling}return{index:this.children.length,referenceNode:i}}insertBefore(t,e,r){if(this.skipMutationNodes)return Promise.resolve();if(t===this)return f.error("[Haori]","Cannot insert element as child of itself"),Promise.reject(new Error("Self-insertion not allowed"));const i=new Set;let n=this.parent;for(;n;)i.add(n),n=n.getParent();if(i.has(t))return f.error("[Haori]","Cannot create circular reference"),Promise.reject(new Error("Circular reference detected"));const s=t.getParent()===this;let a=-1,o=-1;s&&(a=this.children.indexOf(t),e!==null&&(o=this.children.indexOf(e)));const l=t.getParent();l!==null&&l.removeChild(t);let g=r===void 0?e?.getTarget()||null:r;if(e===null)this.children.push(t);else{let E;if(s?a!==-1&&a<o?E=o-1:E=o:E=this.children.indexOf(e),E===-1){const T=this.resolveInsertionPointFromDom(e,!1);T===null?(f.warn("[Haori]","Reference child not found in children.",e),this.children.push(t)):(this.children.splice(T.index,0,t),g=T.referenceNode)}else this.children.splice(E,0,t)}t.setParent(this),t.setMounted(this.mounted);const p=this.skipMutationNodes;return this.skipMutationNodes=!0,F.enqueue(()=>{this.target.insertBefore(t.getTarget(),g)}).finally(()=>{this.skipMutationNodes=p})}insertAfter(t,e){if(e==null)return this.insertBefore(t,null);const r=this.children.indexOf(e);if(r===-1){const i=this.resolveInsertionPointFromDom(e,!0);return i===null?(f.warn("[Haori]","Reference child not found in children.",e),this.insertBefore(t,null)):this.insertBefore(t,this.children[i.index]||null,i.referenceNode)}return this.insertBefore(t,this.children[r+1]||null)}getPrevious(){const t=this.getParent();if(t===null)return null;const e=t.getChildElementFragments(),r=e.indexOf(this);return r<=0?null:e[r-1]}getNext(){const t=this.getParent();if(t===null)return null;const e=t.getChildElementFragments(),r=e.indexOf(this);return r<0||r+1>=e.length?null:e[r+1]}isVisible(){return this.visible}hide(){if(!this.visible)return Promise.resolve();this.visible=!1;const t=this.getTarget();return this.display=t.style.getPropertyValue("display"),this.displayPriority=t.style.getPropertyPriority("display"),t.style.setProperty("display","none","important"),t.setAttribute(`${u.prefix}if-false`,""),Promise.resolve()}show(){if(this.visible)return Promise.resolve();const t=this.getTarget();return this.display===null||this.display===""?t.style.removeProperty("display"):t.style.setProperty("display",this.display,this.displayPriority??""),this.display=null,this.displayPriority=null,t.removeAttribute(`${u.prefix}if-false`),this.visible=!0,Promise.resolve()}closestByAttribute(t){if(this.hasAttribute(t))return this;const e=this.getParent();return e===null?null:e.closestByAttribute(t)}}class O extends w{constructor(t){super(t),this.skipMutation=!1,this.text=t.textContent||"",this.contents=new L(this.text)}clone(){const t=new O(this.target.cloneNode(!0));return t.mounted=!1,t.text=this.text,t.contents=this.contents,t}getTarget(){return this.target}setContent(t){return this.skipMutation||this.text===t?Promise.resolve():(this.text=t,this.contents=new L(t),this.evaluate())}evaluate(){return this.contents.isRawEvaluate&&this.parent===null?Promise.reject(new Error("Parent fragment is required for raw evaluation")):F.enqueue(()=>{this.skipMutation=!0,this.contents.isRawEvaluate?this.parent.getTarget().innerHTML=this.contents.evaluate(this.parent.getBindingData())[0]:this.contents.isEvaluate?this.target.textContent=L.joinEvaluateResults(this.contents.evaluate(this.parent.getBindingData())):this.target.textContent=this.text}).finally(()=>{this.skipMutation=!1})}}class _ extends w{constructor(t){super(t),this.skipMutation=!1,this.text=t.textContent||""}clone(){const t=new _(this.target.cloneNode(!0));return t.mounted=!1,t.text=this.text,t}getTarget(){return this.target}setContent(t){return this.skipMutation||this.text===t?Promise.resolve():(this.text=t,F.enqueue(()=>{this.skipMutation=!0,this.target.textContent=this.text}).finally(()=>{this.skipMutation=!1}))}}const G=class G{constructor(t){this.contents=[],this.isEvaluate=!1,this.isRawEvaluate=!1,this.value=t;const e=[...t.matchAll(G.PLACEHOLDER_REGEX)];let r=0,i=!1,n=!1;for(const s of e){s.index>r&&this.contents.push({text:t.slice(r,s.index),type:0});const a={text:s[1]??s[2],type:s[1]?2:1};i=!0,n=n||a.type===2,this.contents.push(a),r=s.index+s[0].length}r<t.length&&this.contents.push({text:t.slice(r),type:0}),this.isEvaluate=i,this.isRawEvaluate=n,this.checkRawExpressions()}static joinEvaluateResults(t){return t===null||t.length===0?"":t.map(e=>e==null||e===!1||Number.isNaN(e)?"":typeof e!="string"?String(e):e).join("")}getValue(){return this.value}checkRawExpressions(){for(let t=0;t<this.contents.length;t++)this.contents[t].type===2&&this.contents.length>1&&(f.error("[Haori]","Raw expressions are not allowed in multi-content expressions."),this.contents[t].type=1)}evaluate(t){if(!this.isEvaluate&&!this.isRawEvaluate)return this.contents.map(r=>r.text);const e=[];return this.contents.forEach(r=>{try{if(r.type===1||r.type===2){const i=j.evaluate(r.text,t);e.push(i)}else e.push(r.text)}catch(i){f.error("[Haori]",`Error evaluating text expression: ${r.text}`,i),e.push("")}}),e}};G.PLACEHOLDER_REGEX=/\{\{\{([\s\S]+?)\}\}\}|\{\{([\s\S]+?)\}\}/g;let L=G;const Y=class Y extends L{constructor(t,e){super(e),this.forceEvaluation=Y.FORCE_EVALUATION_ATTRIBUTES.includes(t)}isForceEvaluation(){return this.forceEvaluation}evaluate(t){if(!this.isEvaluate&&!this.forceEvaluation)return this.contents.map(r=>r.text);const e=[];return this.contents.forEach(r=>{try{if(this.forceEvaluation&&r.type===0||r.type===1||r.type===2){const i=j.evaluate(r.text,t);e.push(i)}else e.push(r.text)}catch(i){f.error("[Haori]",`Error evaluating attribute expression: ${r.text}`,i),e.push("")}}),this.forceEvaluation&&e.length>1?(f.error("[Haori]","each or if expressions must have a single content.",e),[e[0]]):e}};Y.FORCE_EVALUATION_ATTRIBUTES=["data-if","hor-if","data-each","hor-each"];let q=Y;class N{static dispatch(t,e,r,i){const n=new CustomEvent(`haori:${e}`,{bubbles:i?.bubbles??!0,cancelable:i?.cancelable??!1,composed:i?.composed??!0,detail:r});return t.dispatchEvent(n)}static ready(t){N.dispatch(document,"ready",{version:t})}static render(t){N.dispatch(t,"render",{target:t})}static importStart(t,e){N.dispatch(t,"importstart",{url:e,startedAt:performance.now()})}static importEnd(t,e,r,i){N.dispatch(t,"importend",{url:e,bytes:r,durationMs:performance.now()-i})}static importError(t,e,r){N.dispatch(t,"importerror",{url:e,error:r})}static bindChange(t,e,r,i="other"){const n=[],s=new Set(Object.keys(e||{})),a=new Set(Object.keys(r)),o=new Set([...s,...a]);for(const l of o){const g=e?.[l],p=r[l];g!==p&&n.push(l)}N.dispatch(t,"bindchange",{previous:e||{},next:r,changedKeys:n,reason:i})}static eachUpdate(t,e,r,i){N.dispatch(t,"eachupdate",{added:e,removed:r,order:i,total:i.length})}static rowAdd(t,e,r,i){N.dispatch(t,"rowadd",{key:e,index:r,item:i})}static rowRemove(t,e,r){N.dispatch(t,"rowremove",{key:e,index:r})}static rowMove(t,e,r,i){N.dispatch(t,"rowmove",{key:e,from:r,to:i})}static show(t){N.dispatch(t,"show",{visible:!0})}static hide(t){N.dispatch(t,"hide",{visible:!1})}static fetchStart(t,e,r,i,n){N.dispatch(t,"fetchstart",{url:e,options:r||{},payload:i,startedAt:performance.now(),...n})}static fetchEnd(t,e,r,i){N.dispatch(t,"fetchend",{url:e,status:r,durationMs:performance.now()-i})}static fetchError(t,e,r,i,n){N.dispatch(t,"fetcherror",{url:e,status:i,error:r,durationMs:n?performance.now()-n:void 0})}}const ot=["addErrorMessage","closeDialog","confirm","dialog","openDialog","toast"],lt="__haoriHistoryState__",J="data-haori-click-lock";function z(){const t=globalThis.window?.Haori;return ot.every(r=>typeof t?.[r]=="function")?t:U}const ut=new Set(["GET","HEAD","OPTIONS"]);function ct(P){return ut.has(P.toUpperCase())}function ht(P,t){for(const[e,r]of Object.entries(t))r!==void 0&&(r===null?P.append(e,""):Array.isArray(r)?r.forEach(i=>{P.append(e,String(i))}):typeof r=="object"||typeof r=="function"?P.append(e,JSON.stringify(r)):P.append(e,String(r)))}function ft(P,t){const e=new URL(P,window.location.href),r=new URLSearchParams(e.search);return ht(r,t),e.search=r.toString(),e.toString()}const c=class c{static attrName(t,e,r=!1){return t?`${u.prefix}${t}-${e}`:r?`${u.prefix}fetch-${e}`:`${u.prefix}${e}`}static resolveDataParamString(t,e){return t.replace(c.DATA_PLACEHOLDER_REGEX,(r,i,n)=>{const s=j.evaluate(i??n??"",e);return s==null||Number.isNaN(s)?"":encodeURIComponent(typeof s=="object"?JSON.stringify(s):String(s))})}static isJsonStringContext(t,e){let r=!1,i=!1;for(let n=0;n<e;n+=1){const s=t[n];if(i){i=!1;continue}if(s==="\\"){i=!0;continue}s==='"'&&(r=!r)}return r}static stringifyJsonTemplateValue(t){if(t===void 0||Number.isNaN(t))return"null";try{return JSON.stringify(t)??JSON.stringify(String(t))}catch{return JSON.stringify(String(t))}}static stringifyJsonTemplateStringContent(t){if(t==null||Number.isNaN(t))return"";const e=typeof t=="object"?c.stringifyJsonTemplateValue(t):String(t);return JSON.stringify(e).slice(1,-1)}static resolveDataJsonString(t,e){return t.replace(c.DATA_PLACEHOLDER_REGEX,(r,i,n,s)=>{const a=j.evaluate(i??n??"",e);return c.isJsonStringContext(t,s)?c.stringifyJsonTemplateStringContent(a):c.stringifyJsonTemplateValue(a)})}static resolveDataAttribute(t,e){const r=t.getRawAttribute(e),i=t.getAttribute(e);if(i&&typeof i=="object"&&!Array.isArray(i))return i;if(typeof i!="string"||r===null)return null;const n=r.trim();return c.SINGLE_PLACEHOLDER_REGEX.test(n)?R.parseDataBind(i):n.startsWith("{")||n.startsWith("[")?R.parseDataBind(c.resolveDataJsonString(r,t.getBindingData())):R.parseDataBind(c.resolveDataParamString(r,t.getBindingData()))}static buildOptions(t,e){const r={targetFragment:t};if(e){if(t.hasAttribute(c.attrName(e,"validate"))&&(r.valid=!0),t.hasAttribute(c.attrName(e,"confirm"))&&(r.confirmMessage=t.getAttribute(c.attrName(e,"confirm")).replace(/\\n/g,`
7
- `)),t.hasAttribute(c.attrName(e,"data"))&&(r.dataAttrName=c.attrName(e,"data")),t.hasAttribute(c.attrName(e,"form"))){const h=t.getRawAttribute(c.attrName(e,"form"));if(h){const d=document.body.querySelector(h);d!==null?r.formFragment=y.getFormFragment(w.get(d)):f.error("Haori",`Form element not found: ${h} (${c.attrName(e,"form")})`)}else r.formFragment=y.getFormFragment(t)}else e==="change"&&(r.formFragment=y.getFormFragment(t));if(t.hasAttribute(`${u.prefix}${e}-before-run`)){const h=t.getRawAttribute(`${u.prefix}${e}-before-run`);try{r.beforeCallback=new Function("fetchUrl","fetchOptions",`
5
+ return (${t});`;try{i=new Function(...r,a),this.EXPRESSION_CACHE.set(s,i)}catch(o){return p.error("[Haori]","Failed to compile expression:",t,o),{value:null,unresolvedReference:!1}}}try{const n=[],a=this.wrapBoundValues(e);return r.forEach(o=>{n.push(a[o])}),{value:this.withBlockedPropertyAccess(()=>i(...n)),unresolvedReference:!1}}catch(n){return p.error("[Haori]","Expression evaluation error:",t,n),n instanceof ReferenceError?{value:void 0,unresolvedReference:!0}:{value:null,unresolvedReference:!1}}}static containsDangerousPatterns(t){return this.hasAllowedSyntax(t)?[/\beval\s*\(/,/\barguments\s*\[/,/\barguments\s*\./].some(r=>r.test(t)):!0}static hasAllowedSyntax(t){const e=this.tokenizeExpression(t);if(e===null||e.length===0)return!1;const r=[];let s=null;for(let i=0;i<e.length;i++){const n=e[i],a=e[i+1]||null,o=r[r.length-1]||null,h=e[i-2]||null,g=e[i-3]||null;if(this.startsObjectKey(o,s,h,g)&&(n.value==="["||n.type==="identifier"&&this.FORBIDDEN_PROPERTY_NAMES.has(n.value)||n.type==="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(this.decodeStringLiteral(n.value)))||n.type==="identifier"&&(this.DISALLOWED_KEYWORDS.has(n.value)||this.STRICT_FORBIDDEN_NAMES.includes(n.value)||(s?.value==="."||s?.value==="?.")&&this.FORBIDDEN_PROPERTY_NAMES.has(n.value))||o==="member"&&n.value!=="]"&&n.type==="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(this.decodeStringLiteral(n.value))||n.value==="."&&a?.type!=="identifier"||n.value==="?."&&a?.type!=="identifier"&&a?.value!=="["&&a?.value!=="(")return!1;switch(n.value){case"(":r.push("paren");break;case")":{if(r.pop()!=="paren")return!1;break}case"[":{const m=this.startsMemberAccess(s)?"member":"array";r.push(m);break}case"{":r.push("object");break;case"]":{if(r.pop()===void 0)return!1;break}case"}":{if(r.pop()!=="object")return!1;break}}s=n}return r.length===0}static tokenizeExpression(t){const e=[],r=["===","!==","...","?.","&&","||",">=","<=","==","!=","=>"],s=new Set(["(",")","{","}","[","]",".",",","?",":","+","-","*","/","%","!",">","<"]);let i=0;for(;i<t.length;){const n=t[i];if(/\s/.test(n)){i+=1;continue}if(n==="/"&&(t[i+1]==="/"||t[i+1]==="*"))return null;if(n==='"'||n==="'"){const o=this.readStringToken(t,i);if(o===null)return null;e.push(o.token),i=o.nextIndex;continue}const a=r.find(o=>t.startsWith(o,i));if(a){e.push({type:"operator",value:a,position:i}),i+=a.length;continue}if(/[0-9]/.test(n)){const o=this.readNumberToken(t,i);e.push(o.token),i=o.nextIndex;continue}if(/[A-Za-z_$]/.test(n)){const o=this.readIdentifierToken(t,i);e.push(o.token),i=o.nextIndex;continue}if(s.has(n)){e.push({type:"operator",value:n,position:i}),i+=1;continue}return null}return e}static readStringToken(t,e){const r=t[e];let s=e+1;for(;s<t.length;){const i=t[s];if(i==="\\"){s+=2;continue}if(i===r)return{token:{type:"string",value:t.slice(e,s+1),position:e},nextIndex:s+1};s+=1}return null}static readNumberToken(t,e){let r=e;for(;r<t.length&&/[0-9_]/.test(t[r]);)r+=1;if(t[r]===".")for(r+=1;r<t.length&&/[0-9_]/.test(t[r]);)r+=1;return{token:{type:"number",value:t.slice(e,r),position:e},nextIndex:r}}static readIdentifierToken(t,e){let r=e;for(;r<t.length&&/[A-Za-z0-9_$]/.test(t[r]);)r+=1;return{token:{type:"identifier",value:t.slice(e,r),position:e},nextIndex:r}}static startsMemberAccess(t){return t===null?!1:t.type==="identifier"||t.type==="number"?!0:t.value===")"||t.value==="]"||t.value==="?."}static startsObjectKey(t,e,r,s){return t!=="object"?!1:e?.value==="{"||e?.value===","||e?.type==="identifier"&&this.OBJECT_PROPERTY_MODIFIERS.has(e.value)&&(r?.value==="{"||r?.value===",")?!0:e?.value!=="*"?!1:r?.value==="{"||r?.value===","?!0:r?.type==="identifier"&&r.value==="async"&&(s?.value==="{"||s?.value===",")}static decodeStringLiteral(t){return t.slice(1,-1).replace(/\\u\{([0-9a-fA-F]+)\}/g,(e,r)=>String.fromCodePoint(parseInt(r,16))).replace(/\\u([0-9a-fA-F]{4})/g,(e,r)=>String.fromCharCode(parseInt(r,16))).replace(/\\x([0-9a-fA-F]{2})/g,(e,r)=>String.fromCharCode(parseInt(r,16))).replace(/\\(["'\\bfnrtv0])/g,(e,r)=>{switch(r){case"b":return"\b";case"f":return"\f";case"n":return`
6
+ `;case"r":return"\r";case"t":return" ";case"v":return"\v";case"0":return"\0";default:return r}})}static wrapBoundValues(t){const e=new WeakMap,r={};return Object.entries(t).forEach(([s,i])=>{r[s]=this.wrapBoundValue(i,e)}),r}static wrapBoundValue(t,e){if(!this.shouldWrapValue(t))return t;const r=t,s=e.get(r);if(s!==void 0)return s;const i=new Proxy(r,{get:(n,a,o)=>{if(typeof a=="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(a))return;const h=Reflect.get(n,a,o);return typeof a=="symbol"?h:this.wrapBoundValue(h,e)},has:(n,a)=>typeof a=="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(a)?!1:Reflect.has(n,a),getOwnPropertyDescriptor:(n,a)=>{if(!(typeof a=="string"&&this.FORBIDDEN_PROPERTY_NAMES.has(a)))return Reflect.getOwnPropertyDescriptor(n,a)},apply:(n,a,o)=>{const h=Reflect.apply(n,a,o);return this.isIteratorLike(h)?h:this.wrapBoundValue(h,e)},construct:(n,a,o)=>this.wrapBoundValue(Reflect.construct(n,a,o),e)});return e.set(r,i),i}static shouldWrapValue(t){if(typeof t=="function")return!0;if(t===null||typeof t!="object")return!1;if(Array.isArray(t))return!0;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}static withBlockedPropertyAccess(t){const r=[{target:Object.prototype,property:"constructor"},{target:Function.prototype,property:"constructor"},{target:Object.prototype,property:"__proto__"}].map(s=>({...s,descriptor:Object.getOwnPropertyDescriptor(s.target,s.property)})).filter(s=>s.descriptor?.configurable===!0);r.forEach(({target:s,property:i})=>{Object.defineProperty(s,i,{configurable:!0,enumerable:!1,get:()=>{},set:()=>{}})});try{return t()}finally{r.forEach(({target:s,property:i,descriptor:n})=>{n!==void 0&&Object.defineProperty(s,i,n)})}}static isIteratorLike(t){return t===null||typeof t!="object"?!1:typeof t.next=="function"}static containsForbiddenKeys(t){if(!t||typeof t!="object")return!1;for(const e of Object.keys(t))if(this.FORBIDDEN_BINDING_NAMES.has(e))return!0;return!1}static containsForbiddenBindingValues(t,e=new WeakSet){if(!t||typeof t!="object"||e.has(t))return!1;if(e.add(t),this.getForbiddenBindingValues().some(r=>r===t))return!0;for(const r of Object.values(t)){if(typeof r=="function"){if(this.getForbiddenBindingValues().some(s=>s===r))return!0;continue}if(this.containsForbiddenBindingValues(r,e))return!0}return!1}};M.FORBIDDEN_NAMES=["window","self","globalThis","frames","parent","top","Function","setTimeout","setInterval","requestAnimationFrame","alert","confirm","prompt","fetch","XMLHttpRequest","Reflect","constructor","__proto__","prototype","Object","document","location","navigator","localStorage","sessionStorage","IndexedDB","history"],M.STRICT_FORBIDDEN_NAMES=["eval","arguments"],M.REBINDABLE_FORBIDDEN_NAMES=new Set(["location"]),M.FORBIDDEN_BINDING_NAMES=new Set([...M.FORBIDDEN_NAMES.filter(t=>!M.REBINDABLE_FORBIDDEN_NAMES.has(t)),"constructor","__proto__","prototype",...M.STRICT_FORBIDDEN_NAMES]),M.FORBIDDEN_PROPERTY_NAMES=new Set(["constructor","__proto__","prototype"]),M.OBJECT_PROPERTY_MODIFIERS=new Set(["get","set","async"]),M.DISALLOWED_KEYWORDS=new Set(["await","break","case","catch","class","const","continue","debugger","default","delete","do","else","export","finally","for","function","if","import","in","instanceof","let","new","return","switch","this","throw","try","typeof","var","void","while","with","yield"]),M.EXPRESSION_CACHE=new Map;let j=M;const I=class I{constructor(t){this.parent=null,this.mounted=!1,this.skipMutationNodes=!1,this.target=t,I.FRAGMENT_CACHE.set(t,this)}static get(t){if(t==null)return null;if(I.FRAGMENT_CACHE.has(t))return I.FRAGMENT_CACHE.get(t);let e;switch(t.nodeType){case Node.ELEMENT_NODE:e=new D(t);break;case Node.TEXT_NODE:e=new C(t);break;case Node.COMMENT_NODE:e=new _(t);break;default:return p.warn("[Haori]","Unsupported node type:",t.nodeType),null}return e}isSkipMutationNodes(){return this.skipMutationNodes}unmount(){if(!this.mounted||this.skipMutationNodes)return Promise.resolve();if(this.parent){const t=this.parent,e=t.skipMutationNodes;return F.enqueue(()=>{t.skipMutationNodes=!0,this.target.parentNode===t.getTarget()&&t.getTarget().removeChild(this.target),this.mounted=!1}).finally(()=>{t.skipMutationNodes=e})}else{const t=this.target.parentNode;if(t)return F.enqueue(()=>{this.target.parentNode===t&&t.removeChild(this.target),this.mounted=!1});this.mounted=!1}return Promise.resolve()}mount(){if(this.mounted||this.skipMutationNodes)return Promise.resolve();if(this.parent){const t=this.parent,e=t.skipMutationNodes;return F.enqueue(()=>{t.skipMutationNodes=!0,this.target.parentNode!==t.getTarget()&&t.getTarget().appendChild(this.target),this.mounted=!0}).finally(()=>{t.skipMutationNodes=e})}return Promise.resolve()}isMounted(){return this.mounted}setMounted(t){this.mounted=t}remove(t=!0){return this.parent&&this.parent.removeChild(this),I.FRAGMENT_CACHE.delete(this.target),t?this.unmount():Promise.resolve()}getTarget(){return this.target}getParent(){return this.parent}setParent(t){this.parent=t}};I.FRAGMENT_CACHE=new WeakMap;let T=I;class D extends T{constructor(t){super(t),this.INPUT_EVENT_TYPES=["text","password","email","url","tel","search","number","range","color","date","datetime-local","month","time","week"],this.children=[],this.attributeMap=new Map,this.bindingData=null,this.bindingDataCache=null,this.visible=!0,this.display=null,this.displayPriority=null,this.template=null,this.listKey=null,this.value=null,this.skipMutationAttributes=!1,this.skipChangeValue=!1,this.syncValue(),t.getAttributeNames().forEach(e=>{const r=t.getAttribute(e);if(r!==null&&!this.attributeMap.has(e)){const s=new q(e,r);this.attributeMap.set(e,s)}}),t.childNodes.forEach(e=>{const r=T.get(e);r.setParent(this),this.children.push(r)})}getChildren(){return this.children}getChildElementFragments(){return this.children.filter(t=>t instanceof D)}pushChild(t){this.children.push(t),t.setParent(this)}removeChild(t){const e=this.children.indexOf(t);if(e<0){p.warn("[Haori]","Child fragment not found.",t);return}this.children.splice(e,1),t.setParent(null)}clone(){const t=new D(this.target.cloneNode(!1));return this.attributeMap.forEach((e,r)=>{t.attributeMap.set(r,e)}),this.children.forEach(e=>{const r=e.clone();t.getTarget().appendChild(r.getTarget()),t.pushChild(r)}),t.mounted=!1,t.bindingData=this.bindingData,t.clearBindingDataCache(),t.visible=!0,t.display=this.display,t.displayPriority=this.displayPriority,t.template=this.template,t.normalizeClonedVisibilityState(),t}normalizeClonedVisibilityState(){(this.visible===!1||this.getTarget().style.display==="none"||this.getTarget().hasAttribute(`${u.prefix}if-false`))&&(this.visible=!0,this.display=null,this.displayPriority=null,this.getTarget().style.removeProperty("display"),this.getTarget().removeAttribute(`${u.prefix}if-false`)),this.children.forEach(t=>{t instanceof D&&t.normalizeClonedVisibilityState()})}remove(t=!0){const e=[];return this.children.forEach(r=>{e.push(r.remove(!1))}),this.children.length=0,this.attributeMap.clear(),this.bindingData=null,this.bindingDataCache=null,this.template&&(e.push(this.template.remove(!1)),this.template=null),e.push(super.remove(t)),Promise.all(e).then(()=>{})}getTarget(){return this.target}getBindingData(){return this.bindingDataCache?this.bindingDataCache:(this.bindingDataCache={},this.parent&&Object.assign(this.bindingDataCache,this.parent.getBindingData()),this.bindingData&&Object.assign(this.bindingDataCache,this.bindingData),this.bindingDataCache)}getRawBindingData(){return this.bindingData}setBindingData(t){this.bindingData=t,this.clearBindingDataCache()}setParent(t){this.parent!==t&&(this.parent=t,this.clearBindingDataCache())}clearBindingDataCache(){this.bindingDataCache=null,this.children.forEach(t=>{t instanceof D&&t.clearBindingDataCache()})}getTemplate(){return this.template}setTemplate(t){this.template=t}setListKey(t){this.listKey=t}getListKey(){return this.listKey}setValue(t){return this.applyValue(t,!0)}syncBindingValue(t){return this.applyValue(t,!1)}applyValue(t,e){if(this.skipChangeValue||this.value===t)return Promise.resolve();const r=this.getTarget();if(r instanceof HTMLInputElement&&(r.type==="checkbox"||r.type==="radio")){const s=this.getAttribute("value"),i=r.type==="checkbox"&&s==="true";let n;return i?n=t===!0||t==="true":s==="false"?n=t===!1:n=s===String(t),this.value=i?n:n?t:null,r.checked===n?Promise.resolve():(this.skipChangeValue=!0,F.enqueue(()=>{r.checked=n,e&&r.dispatchEvent(new Event("change",{bubbles:!0}))}).finally(()=>{this.skipChangeValue=!1}))}else return r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement||r instanceof HTMLSelectElement?(this.value=t,this.skipChangeValue=!0,F.enqueue(()=>{r.value=t===null?"":String(t),e&&((r instanceof HTMLInputElement&&this.INPUT_EVENT_TYPES.includes(r.type)||r instanceof HTMLTextAreaElement)&&r.dispatchEvent(new Event("input",{bubbles:!0})),r.dispatchEvent(new Event("change",{bubbles:!0})))}).finally(()=>{this.skipChangeValue=!1})):(p.warn("[Haori]","setValue is not supported for this element type.",r),Promise.resolve())}getValue(){return this.value}clearValue(){this.value=null}syncValue(){const t=this.getTarget();if(t instanceof HTMLInputElement)if(t.type==="checkbox"||t.type==="radio"){const e=t.type==="checkbox"&&t.value==="true";if(t.checked){const r=t.value;e?this.value=!0:r==="false"?this.value=!1:this.value=r}else{const r=t.value;e?this.value=!1:r==="false"?this.value=!0:this.value=null}}else this.value=t.value;else t instanceof HTMLTextAreaElement?this.value=t.value:t instanceof HTMLSelectElement&&(this.value=t.value)}setAttribute(t,e,r=!1){return this.setAttributeInternal(t,t,e,!0,r)}setAliasedAttribute(t,e,r,s=!1){return this.setAttributeInternal(t,e,r,!1,s)}removeAliasedAttribute(t,e){if(this.skipMutationAttributes)return Promise.resolve();this.attributeMap.delete(t),this.skipMutationAttributes=!0;const r=this.getTarget();return F.enqueue(()=>{r.removeAttribute(t),e!==t&&r.removeAttribute(e)}).finally(()=>{this.skipMutationAttributes=!1})}setAttributeInternal(t,e,r,s,i=!1){if(this.skipMutationAttributes)return Promise.resolve();if(r===null)return t===e?this.removeAttribute(t):this.removeAliasedAttribute(t,e);const n=new q(t,r);if(i){const h=this.attributeMap.get(t);if(h&&(h.isEvaluate||h.isForceEvaluation())&&!n.isEvaluate&&!n.isForceEvaluation())return this.skipMutationAttributes=!0,F.enqueue(()=>{}).finally(()=>{this.skipMutationAttributes=!1})}this.attributeMap.set(t,n),this.skipMutationAttributes=!0;const a=this.getTarget(),o=n.isForceEvaluation()?r:this.getAttribute(t);return F.enqueue(()=>{if(a.getAttribute(t)!==r&&a.setAttribute(t,r),o===null||o===!1)a.removeAttribute(e);else{const h=String(o);a.getAttribute(e)!==h&&a.setAttribute(e,h),s&&n.isEvaluate&&e==="value"&&(a instanceof HTMLInputElement&&this.INPUT_EVENT_TYPES.includes(a.type)||a instanceof HTMLTextAreaElement||a instanceof HTMLSelectElement)&&(this.value=h,a.value!==h&&(a.value=h))}}).finally(()=>{this.skipMutationAttributes=!1})}removeAttribute(t){if(this.skipMutationAttributes)return Promise.resolve();this.attributeMap.delete(t),this.skipMutationAttributes=!0;const e=this.getTarget();return F.enqueue(()=>{e.removeAttribute(t)}).finally(()=>{this.skipMutationAttributes=!1})}getAttribute(t){return this.getAttributeEvaluation(t)?.value??null}getAttributeEvaluation(t){const e=this.attributeMap.get(t);if(e===void 0)return null;const r=e.evaluateDetailed(this.getBindingData());return r.results.length===1?{value:r.results[0],hasUnresolvedReference:r.hasUnresolvedReference}:{value:L.joinEvaluateResults(r.results),hasUnresolvedReference:r.hasUnresolvedReference}}getRawAttribute(t){const e=this.attributeMap.get(t);return e===void 0?null:e.getValue()}getAttributeNames(){return Array.from(this.attributeMap.keys())}hasAttribute(t){return this.attributeMap.has(t)}resolveInsertionPointFromDom(t,e){const r=t.getTarget();if(r.parentNode!==this.target)return null;const s=e?r.nextSibling:r;let i=e?r.nextSibling:r;for(;i!==null;){const n=T.get(i);if(n!==null){const a=this.children.indexOf(n);if(a!==-1)return{index:a,referenceNode:s}}i=i.nextSibling}return{index:this.children.length,referenceNode:s}}insertBefore(t,e,r){if(this.skipMutationNodes)return Promise.resolve();if(t===this)return p.error("[Haori]","Cannot insert element as child of itself"),Promise.reject(new Error("Self-insertion not allowed"));const s=new Set;let i=this.parent;for(;i;)s.add(i),i=i.getParent();if(s.has(t))return p.error("[Haori]","Cannot create circular reference"),Promise.reject(new Error("Circular reference detected"));const n=t.getParent()===this;let a=-1,o=-1;n&&(a=this.children.indexOf(t),e!==null&&(o=this.children.indexOf(e)));const h=t.getParent();h!==null&&h.removeChild(t);let g=r===void 0?e?.getTarget()||null:r;if(e===null)this.children.push(t);else{let b;if(n?a!==-1&&a<o?b=o-1:b=o:b=this.children.indexOf(e),b===-1){const v=this.resolveInsertionPointFromDom(e,!1);v===null?(p.warn("[Haori]","Reference child not found in children.",e),this.children.push(t)):(this.children.splice(v.index,0,t),g=v.referenceNode)}else this.children.splice(b,0,t)}t.setParent(this),t.setMounted(this.mounted);const m=this.skipMutationNodes;return this.skipMutationNodes=!0,F.enqueue(()=>{this.target.insertBefore(t.getTarget(),g)}).finally(()=>{this.skipMutationNodes=m})}insertAfter(t,e){if(e==null)return this.insertBefore(t,null);const r=this.children.indexOf(e);if(r===-1){const s=this.resolveInsertionPointFromDom(e,!0);return s===null?(p.warn("[Haori]","Reference child not found in children.",e),this.insertBefore(t,null)):this.insertBefore(t,this.children[s.index]||null,s.referenceNode)}return this.insertBefore(t,this.children[r+1]||null)}getPrevious(){const t=this.getParent();if(t===null)return null;const e=t.getChildElementFragments(),r=e.indexOf(this);return r<=0?null:e[r-1]}getNext(){const t=this.getParent();if(t===null)return null;const e=t.getChildElementFragments(),r=e.indexOf(this);return r<0||r+1>=e.length?null:e[r+1]}isVisible(){return this.visible}hide(){if(!this.visible)return Promise.resolve();this.visible=!1;const t=this.getTarget();return this.display=t.style.getPropertyValue("display"),this.displayPriority=t.style.getPropertyPriority("display"),t.style.setProperty("display","none","important"),t.setAttribute(`${u.prefix}if-false`,""),Promise.resolve()}show(){if(this.visible)return Promise.resolve();const t=this.getTarget();return this.display===null||this.display===""?t.style.removeProperty("display"):t.style.setProperty("display",this.display,this.displayPriority??""),this.display=null,this.displayPriority=null,t.removeAttribute(`${u.prefix}if-false`),this.visible=!0,Promise.resolve()}closestByAttribute(t){if(this.hasAttribute(t))return this;const e=this.getParent();return e===null?null:e.closestByAttribute(t)}}class C extends T{constructor(t){super(t),this.skipMutation=!1,this.text=t.textContent||"",this.contents=new L(this.text)}clone(){const t=new C(this.target.cloneNode(!0));return t.mounted=!1,t.text=this.text,t.contents=this.contents,t}getTarget(){return this.target}setContent(t){return this.skipMutation||this.text===t?Promise.resolve():(this.text=t,this.contents=new L(t),this.evaluate())}evaluate(){return this.contents.isRawEvaluate&&this.parent===null?Promise.reject(new Error("Parent fragment is required for raw evaluation")):F.enqueue(()=>{this.skipMutation=!0,this.contents.isRawEvaluate?this.parent.getTarget().innerHTML=this.contents.evaluate(this.parent.getBindingData())[0]:this.contents.isEvaluate?this.target.textContent=L.joinEvaluateResults(this.contents.evaluate(this.parent.getBindingData())):this.target.textContent=this.text}).finally(()=>{this.skipMutation=!1})}}class _ extends T{constructor(t){super(t),this.skipMutation=!1,this.text=t.textContent||""}clone(){const t=new _(this.target.cloneNode(!0));return t.mounted=!1,t.text=this.text,t}getTarget(){return this.target}setContent(t){return this.skipMutation||this.text===t?Promise.resolve():(this.text=t,F.enqueue(()=>{this.skipMutation=!0,this.target.textContent=this.text}).finally(()=>{this.skipMutation=!1}))}}const G=class G{constructor(t){this.contents=[],this.isEvaluate=!1,this.isRawEvaluate=!1,this.value=t;const e=[...t.matchAll(G.PLACEHOLDER_REGEX)];let r=0,s=!1,i=!1;for(const n of e){n.index>r&&this.contents.push({text:t.slice(r,n.index),type:0});const a={text:n[1]??n[2],type:n[1]?2:1};s=!0,i=i||a.type===2,this.contents.push(a),r=n.index+n[0].length}r<t.length&&this.contents.push({text:t.slice(r),type:0}),this.isEvaluate=s,this.isRawEvaluate=i,this.checkRawExpressions()}static joinEvaluateResults(t){return t===null||t.length===0?"":t.map(e=>e==null||e===!1||Number.isNaN(e)?"":typeof e!="string"?String(e):e).join("")}getValue(){return this.value}checkRawExpressions(){for(let t=0;t<this.contents.length;t++)this.contents[t].type===2&&this.contents.length>1&&(p.error("[Haori]","Raw expressions are not allowed in multi-content expressions."),this.contents[t].type=1)}evaluate(t){return this.evaluateDetailed(t).results}evaluateDetailed(t){if(!this.isEvaluate&&!this.isRawEvaluate)return{results:this.contents.map(s=>s.text),hasUnresolvedReference:!1};const e=[];let r=!1;return this.contents.forEach(s=>{try{if(s.type===1||s.type===2){const i=j.evaluateDetailed(s.text,t);r=r||i.unresolvedReference,e.push(i.value)}else e.push(s.text)}catch(i){p.error("[Haori]",`Error evaluating text expression: ${s.text}`,i),e.push("")}}),{results:e,hasUnresolvedReference:r}}};G.PLACEHOLDER_REGEX=/\{\{\{([\s\S]+?)\}\}\}|\{\{([\s\S]+?)\}\}/g;let L=G;const W=class W extends L{constructor(t,e){super(e),this.forceEvaluation=W.FORCE_EVALUATION_ATTRIBUTES.includes(t)}isForceEvaluation(){return this.forceEvaluation}evaluate(t){return this.evaluateDetailed(t).results}evaluateDetailed(t){if(!this.isEvaluate&&!this.forceEvaluation)return{results:this.contents.map(s=>s.text),hasUnresolvedReference:!1};const e=[];let r=!1;return this.contents.forEach(s=>{try{if(this.forceEvaluation&&s.type===0||s.type===1||s.type===2){const i=j.evaluateDetailed(s.text,t);r=r||i.unresolvedReference,e.push(i.value)}else e.push(s.text)}catch(i){p.error("[Haori]",`Error evaluating attribute expression: ${s.text}`,i),e.push("")}}),this.forceEvaluation&&e.length>1?(p.error("[Haori]","each or if expressions must have a single content.",e),{results:[e[0]],hasUnresolvedReference:r}):{results:e,hasUnresolvedReference:r}}};W.FORCE_EVALUATION_ATTRIBUTES=["data-if","hor-if","data-each","hor-each"];let q=W;class S{static dispatch(t,e,r,s){const i=new CustomEvent(`haori:${e}`,{bubbles:s?.bubbles??!0,cancelable:s?.cancelable??!1,composed:s?.composed??!0,detail:r});return t.dispatchEvent(i)}static ready(t){S.dispatch(document,"ready",{version:t})}static render(t){S.dispatch(t,"render",{target:t})}static importStart(t,e){S.dispatch(t,"importstart",{url:e,startedAt:performance.now()})}static importEnd(t,e,r,s){S.dispatch(t,"importend",{url:e,bytes:r,durationMs:performance.now()-s})}static importError(t,e,r){S.dispatch(t,"importerror",{url:e,error:r})}static bindChange(t,e,r,s="other"){const i=[],n=new Set(Object.keys(e||{})),a=new Set(Object.keys(r)),o=new Set([...n,...a]);for(const h of o){const g=e?.[h],m=r[h];g!==m&&i.push(h)}S.dispatch(t,"bindchange",{previous:e||{},next:r,changedKeys:i,reason:s})}static eachUpdate(t,e,r,s){S.dispatch(t,"eachupdate",{added:e,removed:r,order:s,total:s.length})}static rowAdd(t,e,r,s){S.dispatch(t,"rowadd",{key:e,index:r,item:s})}static rowRemove(t,e,r){S.dispatch(t,"rowremove",{key:e,index:r})}static rowMove(t,e,r,s){S.dispatch(t,"rowmove",{key:e,from:r,to:s})}static show(t){S.dispatch(t,"show",{visible:!0})}static hide(t){S.dispatch(t,"hide",{visible:!1})}static fetchStart(t,e,r,s,i){S.dispatch(t,"fetchstart",{url:e,options:r||{},payload:s,startedAt:performance.now(),...i})}static fetchEnd(t,e,r,s){S.dispatch(t,"fetchend",{url:e,status:r,durationMs:performance.now()-s})}static fetchError(t,e,r,s,i){S.dispatch(t,"fetcherror",{url:e,status:s,error:r,durationMs:i?performance.now()-i:void 0})}}const ot=["addErrorMessage","closeDialog","confirm","dialog","openDialog","toast"],lt="__haoriHistoryState__",X="data-haori-click-lock";function z(){const t=globalThis.window?.Haori;return ot.every(r=>typeof t?.[r]=="function")?t:V}const ut=new Set(["GET","HEAD","OPTIONS"]);function ct(A){return ut.has(A.toUpperCase())}function ht(A,t){for(const[e,r]of Object.entries(t))r!==void 0&&(r===null?A.append(e,""):Array.isArray(r)?r.forEach(s=>{A.append(e,String(s))}):typeof r=="object"||typeof r=="function"?A.append(e,JSON.stringify(r)):A.append(e,String(r)))}function ft(A,t){const e=new URL(A,window.location.href),r=new URLSearchParams(e.search);return ht(r,t),e.search=r.toString(),e.toString()}function dt(A){return A==null?null:typeof A=="string"?A:A instanceof URLSearchParams?A.toString():A instanceof FormData?Array.from(A.entries()).map(([t,e])=>[t,e instanceof File?{type:"file",name:e.name,size:e.size,mimeType:e.type}:String(e)]):String(A)}function pt(A,t){const e=new Headers(t.headers||void 0),r=Array.from(e.entries()).sort(([s],[i])=>s.localeCompare(i));return JSON.stringify({url:A,method:String(t.method||"GET").toUpperCase(),headers:r,body:dt(t.body||null)})}const c=class c{static attrName(t,e,r=!1){return t?`${u.prefix}${t}-${e}`:r?`${u.prefix}fetch-${e}`:`${u.prefix}${e}`}static resolveDataParamString(t,e){return c.resolveDataParamStringDetailed(t,e).value}static resolveDataParamStringDetailed(t,e){let r=!1;return{value:t.replace(c.DATA_PLACEHOLDER_REGEX,(i,n,a)=>{const o=j.evaluateDetailed(n??a??"",e);return r=r||o.unresolvedReference,o.value===null||o.value===void 0||Number.isNaN(o.value)?"":typeof o.value=="object"?encodeURIComponent(JSON.stringify(o.value)):encodeURIComponent(String(o.value))}),hasUnresolvedReference:r}}static isJsonStringContext(t,e){let r=!1,s=!1;for(let i=0;i<e;i+=1){const n=t[i];if(s){s=!1;continue}if(n==="\\"){s=!0;continue}n==='"'&&(r=!r)}return r}static stringifyJsonTemplateValue(t){if(t===void 0||Number.isNaN(t))return"null";try{return JSON.stringify(t)??JSON.stringify(String(t))}catch{return JSON.stringify(String(t))}}static stringifyJsonTemplateStringContent(t){if(t==null||Number.isNaN(t))return"";const e=typeof t=="object"?c.stringifyJsonTemplateValue(t):String(t);return JSON.stringify(e).slice(1,-1)}static resolveDataJsonString(t,e){return c.resolveDataJsonStringDetailed(t,e).value}static resolveDataJsonStringDetailed(t,e){let r=!1;return{value:t.replace(c.DATA_PLACEHOLDER_REGEX,(i,n,a,o)=>{const h=j.evaluateDetailed(n??a??"",e);return r=r||h.unresolvedReference,c.isJsonStringContext(t,o)?c.stringifyJsonTemplateStringContent(h.value):c.stringifyJsonTemplateValue(h.value)}),hasUnresolvedReference:r}}static resolveDataAttribute(t,e){return c.resolveDataAttributeDetailed(t,e).value}static resolveDataAttributeDetailed(t,e){const r=t.getRawAttribute(e),s=t.getAttributeEvaluation(e),i=s?.value??null,n=s?.hasUnresolvedReference??!1;if(i&&typeof i=="object"&&!Array.isArray(i))return{value:i,hasUnresolvedReference:n};if(typeof i!="string"||r===null)return{value:null,hasUnresolvedReference:n};const a=r.trim();if(c.SINGLE_PLACEHOLDER_REGEX.test(a))return{value:P.parseDataBind(i),hasUnresolvedReference:n};if(a.startsWith("{")||a.startsWith("[")){const h=c.resolveDataJsonStringDetailed(r,t.getBindingData());return{value:P.parseDataBind(h.value),hasUnresolvedReference:n||h.hasUnresolvedReference}}const o=c.resolveDataParamStringDetailed(r,t.getBindingData());return{value:P.parseDataBind(o.value),hasUnresolvedReference:n||o.hasUnresolvedReference}}static buildOptions(t,e){const r={targetFragment:t};if(e){if(t.hasAttribute(c.attrName(e,"validate"))&&(r.valid=!0),t.hasAttribute(c.attrName(e,"confirm"))&&(r.confirmMessage=t.getAttribute(c.attrName(e,"confirm")).replace(/\\n/g,`
7
+ `)),t.hasAttribute(c.attrName(e,"data"))&&(r.dataAttrName=c.attrName(e,"data")),t.hasAttribute(c.attrName(e,"form"))){const l=t.getRawAttribute(c.attrName(e,"form"));if(l){const f=document.body.querySelector(l);f!==null?r.formFragment=y.getFormFragment(T.get(f)):p.error("Haori",`Form element not found: ${l} (${c.attrName(e,"form")})`)}else r.formFragment=y.getFormFragment(t)}else e==="change"&&(r.formFragment=y.getFormFragment(t));if(t.hasAttribute(`${u.prefix}${e}-before-run`)){const l=t.getRawAttribute(`${u.prefix}${e}-before-run`);try{r.beforeCallback=new Function("fetchUrl","fetchOptions",`
8
8
  "use strict";
9
- ${h}
10
- `)}catch(d){f.error("Haori",`Invalid before script: ${d}`)}}}const i=c.attrName(e,"fetch"),n=t.hasAttribute(i);n&&(r.fetchUrl=t.getAttribute(i));const s={};if(e){const h=c.attrName(e,"fetch-method");t.hasAttribute(h)&&(s.method=t.getAttribute(h))}else{const h=c.attrName(null,"method",!0);t.hasAttribute(h)&&(s.method=t.getAttribute(h))}if(e){const h=c.attrName(e,"fetch-headers");if(t.hasAttribute(h)){const d=t.getRawAttribute(h);try{s.headers=R.parseDataBind(d)}catch(b){f.error("Haori",`Invalid fetch headers: ${b}`)}}}else{const h=c.attrName(null,"headers",!0);if(t.hasAttribute(h)){const d=t.getRawAttribute(h);try{s.headers=R.parseDataBind(d)}catch(b){f.error("Haori",`Invalid fetch headers: ${b}`)}}}if(e){const h=c.attrName(e,"fetch-content-type");if(t.hasAttribute(h))s.headers={...s.headers,"Content-Type":t.getAttribute(h)};else if(s.method&&s.method!=="GET"&&s.method!=="HEAD"&&s.method!=="OPTIONS"){let d=!1;s.headers&&typeof s.headers=="object"&&(d="Content-Type"in s.headers),d||(s.headers={...s.headers,"Content-Type":"application/json"})}else s.method&&(s.method==="GET"||s.method==="HEAD"||s.method==="OPTIONS")&&(s.headers={...s.headers,"Content-Type":"application/x-www-form-urlencoded"})}else{const h=c.attrName(null,"content-type",!0);if(t.hasAttribute(h))s.headers={...s.headers,"Content-Type":t.getAttribute(h)};else if(s.method&&s.method!=="GET"&&s.method!=="HEAD"&&s.method!=="OPTIONS"){let d=!1;s.headers&&typeof s.headers=="object"&&(d="Content-Type"in s.headers),d||(s.headers={...s.headers,"Content-Type":"application/json"})}else s.method&&(s.method==="GET"||s.method==="HEAD"||s.method==="OPTIONS")&&(s.headers={...s.headers,"Content-Type":"application/x-www-form-urlencoded"})}Object.keys(s).length>0&&(r.fetchOptions=s);const a=e?c.attrName(e,"bind"):c.attrName(null,"bind",!0);if(t.hasAttribute(a)){const h=t.getRawAttribute(a);if(h){const d=document.body.querySelectorAll(h);d.length>0?(r.bindFragments=[],d.forEach(b=>{const v=w.get(b);v&&r.bindFragments.push(v)})):f.error("Haori",`Bind element not found: ${h} (${a})`)}}const o=c.attrName(e,"bind-arg"),l=c.attrName(null,"arg",!0),g=c.attrName(null,"bind-arg",!0);e?t.hasAttribute(o)&&(r.bindArg=t.getRawAttribute(o)):t.hasAttribute(l)?r.bindArg=t.getRawAttribute(l):t.hasAttribute(g)&&(r.bindArg=t.getRawAttribute(g));const p=e?c.attrName(e,"bind-params"):c.attrName(null,"bind-params",!0);if(t.hasAttribute(p)){const h=t.getRawAttribute(p);r.bindParams=h.split("&").map(d=>d.trim())}const E=e?c.attrName(e,"bind-append"):c.attrName(null,"bind-append",!0);if(t.hasAttribute(E)){const h=t.getRawAttribute(E);r.bindAppendParams=h.split("&").map(d=>d.trim()).filter(Boolean)}const T=e?c.attrName(e,"copy-params"):null;if(T&&t.hasAttribute(T)){const h=t.getRawAttribute(T);r.copyParams=h.split("&").map(d=>d.trim()).filter(Boolean)}if(e){if(t.hasAttribute(c.attrName(e,"adjust"))){const d=t.getRawAttribute(c.attrName(e,"adjust"));if(d){const b=document.body.querySelectorAll(d);b.length>0?(r.adjustFragments=[],b.forEach(v=>{const A=w.get(v);A&&r.adjustFragments.push(A)})):f.error("Haori",`Adjust element not found: ${d} (${c.attrName(e,"adjust")})`)}if(t.hasAttribute(c.attrName(e,"adjust-value"))){const b=t.getRawAttribute(c.attrName(e,"adjust-value")),v=Number(b);isNaN(v)||(r.adjustValue=v)}}if(t.hasAttribute(c.attrName(e,"row-add"))&&(r.rowAdd=!0),t.hasAttribute(c.attrName(e,"row-remove"))&&(r.rowRemove=!0),t.hasAttribute(c.attrName(e,"row-prev"))&&(r.rowMovePrev=!0),t.hasAttribute(c.attrName(e,"row-next"))&&(r.rowMoveNext=!0),t.hasAttribute(`${u.prefix}${e}-after-run`)){const d=t.getRawAttribute(`${u.prefix}${e}-after-run`);try{r.afterCallback=new Function("response",`
9
+ ${l}
10
+ `)}catch(f){p.error("Haori",`Invalid before script: ${f}`)}}}const s=c.attrName(e,"fetch"),i=t.hasAttribute(s);if(i){const l=t.getAttributeEvaluation(s);l&&(r.fetchHasUnresolvedReference=l.hasUnresolvedReference,r.fetchUrl=l.hasUnresolvedReference?null:l.value)}const n={};if(e){const l=c.attrName(e,"fetch-method");if(t.hasAttribute(l)){const f=t.getAttributeEvaluation(l);f?.hasUnresolvedReference?r.fetchHasUnresolvedReference=!0:n.method=f?.value}}else{const l=c.attrName(null,"method",!0);if(t.hasAttribute(l)){const f=t.getAttributeEvaluation(l);f?.hasUnresolvedReference?r.fetchHasUnresolvedReference=!0:n.method=f?.value}}if(e){const l=c.attrName(e,"fetch-headers");if(t.hasAttribute(l)){const f=t.getRawAttribute(l);try{n.headers=P.parseDataBind(f)}catch(E){p.error("Haori",`Invalid fetch headers: ${E}`)}}}else{const l=c.attrName(null,"headers",!0);if(t.hasAttribute(l)){const f=t.getRawAttribute(l);try{n.headers=P.parseDataBind(f)}catch(E){p.error("Haori",`Invalid fetch headers: ${E}`)}}}if(e){const l=c.attrName(e,"fetch-content-type");if(t.hasAttribute(l)){const f=t.getAttributeEvaluation(l);f?.hasUnresolvedReference&&(r.fetchHasUnresolvedReference=!0),n.headers={...n.headers,"Content-Type":f?.value}}else if(n.method&&n.method!=="GET"&&n.method!=="HEAD"&&n.method!=="OPTIONS"){let f=!1;n.headers&&typeof n.headers=="object"&&(f="Content-Type"in n.headers),f||(n.headers={...n.headers,"Content-Type":"application/json"})}else n.method&&(n.method==="GET"||n.method==="HEAD"||n.method==="OPTIONS")&&(n.headers={...n.headers,"Content-Type":"application/x-www-form-urlencoded"})}else{const l=c.attrName(null,"content-type",!0);if(t.hasAttribute(l)){const f=t.getAttributeEvaluation(l);f?.hasUnresolvedReference&&(r.fetchHasUnresolvedReference=!0),n.headers={...n.headers,"Content-Type":f?.value}}else if(n.method&&n.method!=="GET"&&n.method!=="HEAD"&&n.method!=="OPTIONS"){let f=!1;n.headers&&typeof n.headers=="object"&&(f="Content-Type"in n.headers),f||(n.headers={...n.headers,"Content-Type":"application/json"})}else n.method&&(n.method==="GET"||n.method==="HEAD"||n.method==="OPTIONS")&&(n.headers={...n.headers,"Content-Type":"application/x-www-form-urlencoded"})}Object.keys(n).length>0&&(r.fetchOptions=n);const a=e?c.attrName(e,"bind"):c.attrName(null,"bind",!0);if(t.hasAttribute(a)){const l=t.getRawAttribute(a);if(l){const f=document.body.querySelectorAll(l);f.length>0?(r.bindFragments=[],f.forEach(E=>{const N=T.get(E);N&&r.bindFragments.push(N)})):p.error("Haori",`Bind element not found: ${l} (${a})`)}}const o=c.attrName(e,"bind-arg"),h=c.attrName(null,"arg",!0),g=c.attrName(null,"bind-arg",!0);e?t.hasAttribute(o)&&(r.bindArg=t.getRawAttribute(o)):t.hasAttribute(h)?r.bindArg=t.getRawAttribute(h):t.hasAttribute(g)&&(r.bindArg=t.getRawAttribute(g));const m=e?c.attrName(e,"bind-params"):c.attrName(null,"bind-params",!0);if(t.hasAttribute(m)){const l=t.getRawAttribute(m);r.bindParams=l.split("&").map(f=>f.trim())}const b=e?c.attrName(e,"bind-append"):c.attrName(null,"bind-append",!0);if(t.hasAttribute(b)){const l=t.getRawAttribute(b);r.bindAppendParams=l.split("&").map(f=>f.trim()).filter(Boolean)}const v=e?c.attrName(e,"copy-params"):null;if(v&&t.hasAttribute(v)){const l=t.getRawAttribute(v);r.copyParams=l.split("&").map(f=>f.trim()).filter(Boolean)}if(e){if(t.hasAttribute(c.attrName(e,"adjust"))){const f=t.getRawAttribute(c.attrName(e,"adjust"));if(f){const E=document.body.querySelectorAll(f);E.length>0?(r.adjustFragments=[],E.forEach(N=>{const w=T.get(N);w&&r.adjustFragments.push(w)})):p.error("Haori",`Adjust element not found: ${f} (${c.attrName(e,"adjust")})`)}if(t.hasAttribute(c.attrName(e,"adjust-value"))){const E=t.getRawAttribute(c.attrName(e,"adjust-value")),N=Number(E);isNaN(N)||(r.adjustValue=N)}}if(t.hasAttribute(c.attrName(e,"row-add"))&&(r.rowAdd=!0),t.hasAttribute(c.attrName(e,"row-remove"))&&(r.rowRemove=!0),t.hasAttribute(c.attrName(e,"row-prev"))&&(r.rowMovePrev=!0),t.hasAttribute(c.attrName(e,"row-next"))&&(r.rowMoveNext=!0),t.hasAttribute(`${u.prefix}${e}-after-run`)){const f=t.getRawAttribute(`${u.prefix}${e}-after-run`);try{r.afterCallback=new Function("response",`
11
11
  "use strict";
12
- ${d}
13
- `)}catch(b){f.error("Haori",`Invalid after script: ${b}`)}}if(t.hasAttribute(c.attrName(e,"dialog"))&&(r.dialogMessage=t.getAttribute(c.attrName(e,"dialog")).replace(/\\n/g,`
14
- `)),t.hasAttribute(c.attrName(e,"toast"))){r.toastMessage=t.getAttribute(c.attrName(e,"toast"));const d=t.getRawAttribute(c.attrName(e,"toast-level")),v=["info","warning","error","success"].includes(d);r.toastLevel=v?d:null}if(t.hasAttribute(c.attrName(e,"redirect"))&&(r.redirectUrl=t.getAttribute(c.attrName(e,"redirect"))),t.hasAttribute(c.attrName(e,"scroll-error"))&&(r.scrollOnError=!0),t.hasAttribute(c.attrName(e,"scroll"))&&(r.scrollTarget=t.getAttribute(c.attrName(e,"scroll"))),t.hasAttribute(c.attrName(e,"history"))&&(r.historyUrl=t.getAttribute(c.attrName(e,"history"))),t.hasAttribute(c.attrName(e,"history-data"))&&(r.historyDataAttrName=c.attrName(e,"history-data")),t.hasAttribute(c.attrName(e,"history-form"))){const d=t.getRawAttribute(c.attrName(e,"history-form"));if(d){const b=document.body.querySelector(d);b!==null?r.historyFormFragment=y.getFormFragment(w.get(b)):f.error("Haori",`Form element not found: ${d} (${c.attrName(e,"history-form")})`)}else r.historyFormFragment=y.getFormFragment(t)}["reset-before","reset","refetch","click","copy","open","close"].forEach(d=>{const b=c.attrName(e,d);if(!t.hasAttribute(b))return;const v=t.getRawAttribute(b),A=[];if(v?(document.body.querySelectorAll(v).forEach(X=>{const et=w.get(X);et&&A.push(et)}),A.length===0&&f.error("Haori",`Element not found: ${v} (${b})`)):A.push(t),A.length>0)switch(d){case"reset-before":r.resetBeforeFragments=A;break;case"reset":r.resetFragments=A;break;case"refetch":r.refetchFragments=A;break;case"click":r.clickFragments=A;break;case"copy":r.copyFragments=A;break;case"open":r.openFragments=A;break;case"close":r.closeFragments=A;break}})}if(!e&&(t.hasAttribute(c.attrName(null,"data",!0))&&(r.dataAttrName=c.attrName(null,"data",!0)),t.hasAttribute(c.attrName(null,"form",!0)))){const h=t.getRawAttribute(c.attrName(null,"form",!0));if(h){const d=document.body.querySelector(h);d!==null?r.formFragment=y.getFormFragment(w.get(d)):f.error("Haori",`Form element not found: ${h} (${c.attrName(null,"fetch-form",!0)})`)}else r.formFragment=y.getFormFragment(t)}return n&&(!r.bindFragments||r.bindFragments.length===0)&&(r.bindFragments=[t]),r}static isElementFragment(t){if(typeof t!="object"||t===null)return!1;const e=t;return typeof e.getTarget=="function"&&typeof e.getChildElementFragments=="function"}constructor(t,e=null){c.isElementFragment(t)?(this.options=c.buildOptions(t,e),this.eventType=e):(this.options=t,this.eventType=null)}run(){return this.runWithResult().then(()=>{})}runWithResult(){return this.execute()}async execute(){const t=this.acquireExecutionLock();if(t===!1)return!1;try{if(Object.keys(this.options).length===0||this.options.formFragment&&this.validate(this.options.formFragment)===!1||!await this.confirm())return!1;this.options.resetBeforeFragments&&this.options.resetBeforeFragments.length>0&&(await Promise.all(this.options.resetBeforeFragments.map(l=>y.reset(l))),this.captureHistorySnapshots());const r=this.buildPayload();let i=this.options.fetchUrl,n=this.options.fetchOptions;if(this.options.beforeCallback){const l=this.options.beforeCallback(i||null,n||null);if(l!=null){if(l===!1||typeof l=="object"&&l.stop)return!1;typeof l=="object"&&(i="fetchUrl"in l?l.fetchUrl:i,n="fetchOptions"in l?l.fetchOptions:n)}}const s=Object.keys(r).length>0;if(i){const l={...n||{}},g=new Headers(l.headers||void 0),p=(l.method||"GET").toUpperCase(),E=u.runtime==="demo"&&!ct(p),T=E?"GET":p;if(l.method=T,T==="GET"||T==="HEAD"||T==="OPTIONS")s&&(i=ft(i,r));else if(s){const d=g.get("Content-Type")||"";if(/multipart\/form-data/i.test(d)){g.delete("Content-Type");const b=new FormData;for(const[v,A]of Object.entries(r))A==null?b.append(v,""):A instanceof Blob?b.append(v,A):Array.isArray(A)?A.forEach(D=>b.append(v,String(D))):typeof A=="object"?b.append(v,JSON.stringify(A)):b.append(v,String(A));l.body=b}else if(/application\/x-www-form-urlencoded/i.test(d)){const b=new URLSearchParams;for(const[v,A]of Object.entries(r))A!==void 0&&(A===null?b.append(v,""):Array.isArray(A)?A.forEach(D=>b.append(v,String(D))):typeof A=="object"?b.append(v,JSON.stringify(A)):b.append(v,String(A)));l.body=b}else g.set("Content-Type","application/json"),l.body=JSON.stringify(r)}l.headers=g;let h;if(E&&(h=i&&new URL(i,window.location.href).search||void 0,g.delete("Content-Type"),f.info("Haori demo fetch normalization",{runtime:u.runtime,requestedMethod:p,effectiveMethod:T,transportMode:"query-get",url:i,payload:s?r:void 0,queryString:h})),this.options.targetFragment&&i){const d=performance.now(),b={runtime:u.runtime,requestedMethod:p,effectiveMethod:T,transportMode:E?"query-get":"http",...E?{queryString:h}:{}};return N.fetchStart(this.options.targetFragment.getTarget(),i,l,s?r:void 0,b),fetch(i,l).then(v=>this.handleFetchResult(v,i||void 0,d)).catch(v=>{throw i&&N.fetchError(this.options.targetFragment.getTarget(),i,v),v})}return fetch(i,l).then(d=>this.handleFetchResult(d,i||void 0))}if((!this.options.bindFragments||this.options.bindFragments.length===0)&&this.options.formFragment&&s){const l=this.options.formFragment,g=l.getTarget(),p=new Set;t&&t.appliedDisabledAttribute&&this.options.targetFragment&&p.add(this.options.targetFragment),g.setAttribute(`${u.prefix}bind`,JSON.stringify(r));const E=l.getBindingData();Object.assign(E,r),await R.setBindingData(g,E,p)}const a=s?r:{},o=new Response(JSON.stringify(a),{headers:{"Content-Type":"application/json"}});return this.handleFetchResult(o)}finally{this.releaseExecutionLock(t)}}acquireExecutionLock(){if(this.eventType!=="click"||!this.options.targetFragment)return null;const e=this.options.targetFragment.getTarget();return c.RUNNING_CLICK_TARGETS.has(e)||e.matches(":disabled")||e.hasAttribute("disabled")||e.hasAttribute(J)?!1:(c.RUNNING_CLICK_TARGETS.add(e),e.setAttribute(J,""),e.setAttribute("disabled",""),{target:e,appliedDisabledAttribute:!0})}releaseExecutionLock(t){t&&(c.RUNNING_CLICK_TARGETS.delete(t.target),t.appliedDisabledAttribute&&(t.target.removeAttribute("disabled"),t.target.removeAttribute(J)))}async handleFetchResult(t,e,r){const i=z();if(!t.ok)return this.options.targetFragment&&e&&N.fetchError(this.options.targetFragment.getTarget(),e,new Error(`${t.status} ${t.statusText}`),t.status,r),await this.handleFetchError(t),!1;if(this.options.targetFragment&&e&&r&&N.fetchEnd(this.options.targetFragment.getTarget(),e,t.status,r),this.options.afterCallback){const a=this.options.afterCallback(t);if(a!=null){if(a===!1||typeof a=="object"&&a.stop)return!1;typeof a=="object"&&"response"in a&&(t="response"in a?a.response:t)}}const n=[];n.push(this.bindResult(t)),n.push(this.adjust()),n.push(this.addRow()),n.push(this.removeRow()),n.push(this.movePrevRow()),n.push(this.moveNextRow()),await Promise.all(n),this.options.resetFragments&&this.options.resetFragments.length>0&&await Promise.all(this.options.resetFragments.map(a=>y.reset(a))),await this.copy();const s=[];return this.options.refetchFragments&&this.options.refetchFragments.length>0&&this.options.refetchFragments.forEach(a=>{s.push(new c(a,null).run())}),this.options.clickFragments&&this.options.clickFragments.length>0&&this.options.clickFragments.forEach(a=>{const o=a.getTarget();typeof o.click=="function"?o.click():o.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0}))}),this.options.openFragments&&this.options.openFragments.length>0&&this.options.openFragments.forEach(a=>{const o=a.getTarget();o instanceof HTMLElement?s.push(i.openDialog(o)):f.error("Haori","Element is not an HTML element: ",o)}),this.options.closeFragments&&this.options.closeFragments.length>0&&this.options.closeFragments.forEach(a=>{const o=a.getTarget();o instanceof HTMLElement?s.push(i.closeDialog(o)):f.error("Haori","Element is not an HTML element: ",o)}),await Promise.all(s),this.options.dialogMessage&&await i.dialog(this.options.dialogMessage),this.options.toastMessage&&await i.toast(this.options.toastMessage,this.options.toastLevel??"info"),this.pushHistory(),this.options.scrollTarget&&document.querySelector(this.options.scrollTarget)?.scrollIntoView({behavior:"smooth",block:"nearest"}),this.options.redirectUrl&&(window.location.href=this.options.redirectUrl),!0}pushHistory(){const t=this.options.historyUrl!==void 0&&this.options.historyUrl!==null,e=this.resolveHistoryDataValues(),r=this.resolveHistoryFormValues(),i=e!=null,n=r!=null;if(!(!t&&!i&&!n))try{const s=t?this.options.historyUrl:window.location.pathname,a=new URL(s,window.location.href);if(a.origin!==window.location.origin){const l="history.pushState: cross-origin URL is not allowed: "+a.toString();f.error("Haori",l);return}const o=l=>{for(const[g,p]of Object.entries(l))p!=null&&(Array.isArray(p)?p.forEach(E=>a.searchParams.append(g,String(E))):typeof p=="object"?a.searchParams.set(g,JSON.stringify(p)):a.searchParams.set(g,String(p)))};i&&o(e),n&&o(r),history.pushState({[lt]:!0},"",a.toString())}catch(s){f.error("Haori",`history.pushState failed: ${s}`)}}async handleFetchError(t){let e=null;this.options.formFragment?e=this.options.formFragment:this.options.targetFragment&&(e=y.getFormFragment(this.options.targetFragment)||this.options.targetFragment);const r=async s=>{const a=e?e.getTarget():document.body;await z().addErrorMessage(a,s)},i=()=>{if(!this.options.scrollOnError)return;const s=e?e.getTarget():document.body;(s.getAttribute("data-message-level")==="error"?s:s.parentElement?.getAttribute("data-message-level")==="error"?s.parentElement:s.querySelector('[data-message-level="error"]'))?.scrollIntoView({behavior:"smooth",block:"nearest"})};if((t.headers.get("Content-Type")||"").includes("application/json"))try{const s=await t.json(),a=[];if(s&&typeof s=="object"){if(typeof s.message=="string"&&a.push({message:s.message}),Array.isArray(s.messages))for(const o of s.messages)typeof o=="string"&&a.push({message:o});if(s.errors&&typeof s.errors=="object")for(const[o,l]of Object.entries(s.errors))Array.isArray(l)?a.push({key:o,message:l.join(`
15
- `)}):typeof l=="string"?a.push({key:o,message:l}):l!=null&&a.push({key:o,message:String(l)});if(a.length===0)for(const[o,l]of Object.entries(s))o==="message"||o==="messages"||o==="errors"||(Array.isArray(l)?a.push({key:o,message:l.join(`
16
- `)}):typeof l=="string"&&a.push({key:o,message:l}))}if(a.length===0)return await r(`${t.status} ${t.statusText}`),i(),!1;for(const o of a)o.key&&e?await y.addErrorMessage(e,o.key,o.message):await r(o.message);return i(),!1}catch{}try{const s=await t.text();s&&s.trim().length>0?await r(s.trim()):await r(`${t.status} ${t.statusText}`)}catch{await r(`${t.status} ${t.statusText}`)}return i(),!1}validate(t){if(this.options.valid!==!0)return!0;const e=this.findFirstInvalid(t);return e===null?!0:(e.reportValidity(),e.focus(),this.options.scrollOnError&&e.scrollIntoView({behavior:"smooth",block:"nearest"}),!1)}findFirstInvalid(t){let e=null;for(const r of t.getChildElementFragments().reverse()){const i=this.findFirstInvalid(r);i!==null&&(e=i)}return this.checkOne(t)?e:t.getTarget()}checkOne(t){const e=t.getTarget();return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?e.checkValidity():!0}confirm(){const t=this.options.confirmMessage;return t==null?Promise.resolve(!0):z().confirm(t)}bindResult(t){return!this.options.bindFragments||this.options.bindFragments.length===0?Promise.resolve():(t.headers.get("Content-Type")?.includes("application/json")?t.json():t.text()).then(r=>{if(this.options.bindParams){const n={};this.options.bindParams.forEach(s=>{r&&typeof r=="object"&&s in r&&(n[s]=r[s])}),r=n}const i=[];if(this.options.bindArg)this.options.bindFragments.forEach(n=>{const s=n.getBindingData(),a=this.options.bindArg;if(r&&typeof r=="object"&&!Array.isArray(r)){const o=s[a],l=o&&typeof o=="object"&&!Array.isArray(o)?o:{};s[a]=this.mergeAppendBindingData(n,r,l)}else s[a]=r;i.push(R.setBindingData(n.getTarget(),s))});else{if(typeof r=="string")return f.error("Haori","string data cannot be bound without a bindArg."),Promise.reject(new Error("string data cannot be bound without a bindArg."));this.options.bindFragments.forEach(n=>{const s=this.mergeAppendBindingData(n,r);i.push(R.setBindingData(n.getTarget(),s))})}return Promise.all(i).then(()=>{})})}mergeAppendBindingData(t,e,r=t.getBindingData()){if(!this.options.bindAppendParams||this.options.bindAppendParams.length===0)return e;const i={...e},n=r;for(const s of this.options.bindAppendParams){const a=i[s],o=n[s];Array.isArray(o)&&Array.isArray(a)&&(i[s]=o.concat(a))}return i}copy(){if(!this.options.copyFragments||this.options.copyFragments.length===0)return Promise.resolve();const t=this.resolveCopySourceData(),e=this.pickCopyData(t),r=this.options.copyFragments.map(i=>{const n={...i.getBindingData(),...e};return R.setBindingData(i.getTarget(),n)});return Promise.all(r).then(()=>{})}resolveCopySourceData(){return this.options.formFragment?y.getValues(this.options.formFragment):this.options.targetFragment?{...this.options.targetFragment.getBindingData()}:{}}buildPayload(){const t={};if(this.options.formFragment&&Object.assign(t,y.getValues(this.options.formFragment)),this.options.data&&typeof this.options.data=="object"&&Object.assign(t,this.options.data),this.options.targetFragment&&this.options.dataAttrName){const e=c.resolveDataAttribute(this.options.targetFragment,this.options.dataAttrName);e&&Object.assign(t,e)}return t}captureHistorySnapshots(){this.options.targetFragment&&this.options.historyDataAttrName?this.historyDataSnapshot=c.resolveDataAttribute(this.options.targetFragment,this.options.historyDataAttrName):this.historyDataSnapshot=void 0,this.historyFormSnapshot=this.options.historyFormFragment?y.getValues(this.options.historyFormFragment):void 0}resolveHistoryDataValues(){return this.historyDataSnapshot!==void 0?this.historyDataSnapshot:this.options.targetFragment&&this.options.historyDataAttrName?c.resolveDataAttribute(this.options.targetFragment,this.options.historyDataAttrName):this.options.historyData}resolveHistoryFormValues(){if(this.historyFormSnapshot!==void 0)return this.historyFormSnapshot;if(this.options.historyFormFragment)return y.getValues(this.options.historyFormFragment)}pickCopyData(t){if(!this.options.copyParams||this.options.copyParams.length===0)return t;const e=new Set,r=new Set;this.options.copyParams.forEach(s=>{const a=s.trim();if(a){if(a.startsWith("!")){const o=a.slice(1).trim();o&&r.add(o);return}e.add(a)}});const i={};return(e.size>0?Array.from(e):Object.keys(t)).forEach(s=>{s in t&&(r.has(s)||(i[s]=t[s]))}),i}adjust(){if(!this.options.adjustFragments||this.options.adjustFragments.length===0)return Promise.resolve();const t=this.options.adjustValue??0,e=[];for(const r of this.options.adjustFragments){let i=r.getValue();(i==null||i==="")&&(i="0");let n=Number(i);isNaN(n)&&(n=0),n+=t,e.push(r.setValue(String(n)))}return Promise.all(e).then(()=>{})}getRowFragment(){if(!this.options.targetFragment)return f.error("Haori","Target fragment is not specified for row operation."),null;const t=this.options.targetFragment.closestByAttribute(`${u.prefix}row`);return t||(f.error("Haori","Row fragment not found."),null)}addRow(){if(this.options.rowAdd!==!0)return Promise.resolve();const t=this.getRowFragment();if(!t)return Promise.reject(new Error("Row fragment not found."));const e=[],r=t.clone();return e.push(t.getParent().insertAfter(r,t)),e.push(R.evaluateAll(r)),e.push(y.reset(r)),Promise.all(e).then(()=>{})}removeRow(){if(this.options.rowRemove!==!0)return Promise.resolve();const t=this.getRowFragment();if(!t)return Promise.reject(new Error("Row fragment not found."));const e=t.getParent();return e&&e.getChildElementFragments().filter(i=>!i.hasAttribute(`${u.prefix}each-before`)&&!i.hasAttribute(`${u.prefix}each-after`)).length<=1?Promise.resolve():t.remove()}movePrevRow(){if(this.options.rowMovePrev!==!0)return Promise.resolve();const t=this.getRowFragment();if(!t)return Promise.reject(new Error("Row fragment not found."));const e=t.getPrevious();if(!e)return Promise.resolve();const r=t.getParent();return r?r.insertBefore(t,e):Promise.resolve()}moveNextRow(){if(this.options.rowMoveNext!==!0)return Promise.resolve();const t=this.getRowFragment();if(!t)return Promise.reject(new Error("Row fragment not found."));const e=t.getNext();if(!e)return Promise.resolve();const r=t.getParent();return r?r.insertAfter(t,e):Promise.resolve()}};c.DATA_PLACEHOLDER_REGEX=/\{\{\{([\s\S]+?)\}\}\}|\{\{([\s\S]+?)\}\}/g,c.SINGLE_PLACEHOLDER_REGEX=/^(\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\})$/,c.RUNNING_CLICK_TARGETS=new WeakSet;let V=c;class dt{static readParams(){const t={},e=window.location.search;return new URLSearchParams(e).forEach((i,n)=>{t[n]=i}),t}}class pt{static async load(t,e){let r;try{r=await fetch(t,e)}catch(n){throw f.error("[Haori]","Failed to fetch import source:",t,n),new Error(`Failed to fetch: ${t}`)}if(!r.ok){const n=`${r.status} ${r.statusText}`;throw f.error("[Haori]","Import HTTP error:",t,n),new Error(`Failed to load ${t}: ${n}`)}let i;try{i=await r.text()}catch(n){throw f.error("[Haori]","Failed to read response text:",t,n),new Error(`Failed to read response from: ${t}`)}try{const s=new DOMParser().parseFromString(i,"text/html");return s&&s.body?s.body.innerHTML:(f.warn("[Haori]","No body found in imported document:",t),i)}catch(n){return f.error("[Haori]","Failed to parse imported HTML:",t,n),i}}}const m=class m{static isDeferredAttributeName(t){return m.DEFERRED_ATTRIBUTE_SUFFIXES.some(e=>t===`${u.prefix}${e}`)}static isEvaluateAllExcludedAttributeName(t){return m.EVALUATE_ALL_EXCLUDED_ATTRIBUTE_SUFFIXES.some(e=>t===`${u.prefix}${e}`)}static shouldReevaluateAttribute(t,e){return e!==null&&!m.isEvaluateAllExcludedAttributeName(t)&&m.ATTRIBUTE_PLACEHOLDER_REGEX.test(e)}static getAliasedAttributeName(t){const e=`${u.prefix}${m.ATTRIBUTE_ALIAS_SUFFIX}`;return!t.startsWith(e)||t.length<=e.length?null:t.slice(e.length)}static isAliasedAttributeReflection(t,e){const r=w.get(t);return r instanceof x?r.hasAttribute(`${u.prefix}${m.ATTRIBUTE_ALIAS_SUFFIX}${e}`):!1}static reevaluateInterpolatedAttributes(t){let e=Promise.resolve();for(const r of t.getAttributeNames()){const i=t.getRawAttribute(r);m.shouldReevaluateAttribute(r,i)&&(e=e.then(()=>m.setAttribute(t.getTarget(),r,i)))}return e.then(()=>{})}static scan(t){const e=w.get(t);if(!e)return Promise.resolve();t.parentNode&&(w.get(t.parentNode)?.isMounted()||document.body.contains(t)?e.setMounted(!0):e.setMounted(!1));let r=Promise.resolve();const i=new Set;for(const n of m.PRIORITY_ATTRIBUTE_SUFFIXES){const s=u.prefix+n;e.hasAttribute(s)&&(r=r.then(()=>m.setAttribute(e.getTarget(),s,e.getRawAttribute(s))),i.add(s))}for(const n of e.getAttributeNames()){if(i.has(n)||m.isDeferredAttributeName(n))continue;const s=e.getRawAttribute(n);s!==null&&(r=r.then(()=>m.setAttribute(e.getTarget(),n,s)))}for(const n of m.DEFERRED_ATTRIBUTE_SUFFIXES){const s=u.prefix+n;e.hasAttribute(s)&&(r=r.then(()=>m.setAttribute(e.getTarget(),s,e.getRawAttribute(s))),i.add(s))}return r.then(()=>{const n=[];return e.getChildren().forEach(s=>{s instanceof x?n.push(m.scan(s.getTarget())):s instanceof O&&n.push(m.evaluateText(s))}),Promise.all(n).then(()=>{})}).then(()=>{})}static setAttribute(t,e,r,i=!1){const n=w.get(t),s=m.getAliasedAttributeName(e);if(s!==null)return r===null?n.removeAliasedAttribute(e,s):n.setAliasedAttribute(e,s,r,i);const a=[];switch(e){case`${u.prefix}bind`:{r===null?(n.clearBindingDataCache(),n.setBindingData({})):n.setBindingData(m.parseDataBind(r));break}case`${u.prefix}if`:a.push(m.evaluateIf(n));break;case`${u.prefix}each`:a.push(m.evaluateEach(n));break;case`${u.prefix}fetch`:a.push(new V(n,null).run().then(()=>{}));break;case`${u.prefix}import`:{if(typeof r=="string"){const o=n.getTarget(),l=performance.now();o.setAttribute(`${u.prefix}importing`,""),N.importStart(o,r),a.push(pt.load(r).then(g=>{const p=new TextEncoder().encode(g).length;return F.enqueue(()=>{o.innerHTML=g}).then(()=>{if(o.removeAttribute(`${u.prefix}importing`),N.importEnd(o,r,p,l),!document.body.hasAttribute("data-haori-ready")){const E=[];return o.childNodes.forEach(T=>{const h=w.get(T);h instanceof x?E.push(m.scan(h.getTarget())):h instanceof O&&E.push(m.evaluateText(h))}),Promise.all(E).then(()=>{})}})}).catch(g=>{o.removeAttribute(`${u.prefix}importing`),N.importError(o,r,g),f.error("[Haori]","Failed to import HTML:",r,g)}))}break}case`${u.prefix}url-param`:{const o=n.getAttribute(`${u.prefix}url-arg`),l=dt.readParams();if(o===null)a.push(m.setBindingData(t,l));else{const g=n.getRawBindingData()||{};g[String(o)]=l,a.push(m.setBindingData(t,g))}break}}return r===null?a.push(n.removeAttribute(e)):a.push(n.setAttribute(e,r,i)),Promise.all(a).then(()=>{})}static setBindingData(t,e,r=new Set){const i=w.get(t),n=i.getRawBindingData();i.setBindingData(e);let s=i.setAttribute(`${u.prefix}bind`,JSON.stringify(e));if(t.tagName==="FORM"){const a=i.getAttribute(`${u.prefix}form-arg`),o=a&&e[String(a)]&&typeof e[String(a)]=="object"&&!Array.isArray(e[String(a)])?e[String(a)]:a?{}:e;s=s.then(()=>y.syncValues(i,o))}return s=s.then(()=>m.evaluateAll(i,r)),N.bindChange(t,n,e,"manual"),s.then(()=>{})}static parseDataBind(t){if(t.startsWith("{")||t.startsWith("["))try{return JSON.parse(t)}catch(e){return f.error("[Haori]","Invalid JSON in data-bind:",e),{}}else{const e=new URLSearchParams(t),r={};for(const[i,n]of e.entries())r[i]!==void 0?Array.isArray(r[i])?r[i].push(n):r[i]=[r[i],n]:r[i]=n;return r}}static addNode(t,e){const r=w.get(t);if(r.isSkipMutationNodes())return;const i=w.get(e.nextSibling),n=w.get(e);n&&(r.insertBefore(n,i),n instanceof x?m.scan(n.getTarget()):n instanceof O&&m.evaluateText(n))}static removeNode(t){const e=w.get(t);if(e){const r=e.getParent();if(r&&r.isSkipMutationNodes())return;e.remove()}}static changeText(t,e){const r=w.get(t);r&&r.setContent(e)}static changeValue(t,e){const r=w.get(t);if(r.getValue()===e)return Promise.resolve();const i=[];i.push(r.setValue(e));const n=m.getFormFragment(r);if(n){const s=y.getValues(n),a=n.getAttribute(`${u.prefix}form-arg`);let o;a?(o=n.getRawBindingData(),o||(o={}),o[String(a)]=s):o=s,i.push(m.setBindingData(n.getTarget(),o))}return Promise.all(i).then(()=>{})}static getFormFragment(t){if(t.getTarget()instanceof HTMLFormElement)return t;const e=t.getParent();return e?m.getFormFragment(e):null}static evaluateAll(t,e=new Set){if(e.has(t))return Promise.resolve();const r=[];return r.push(m.reevaluateInterpolatedAttributes(t)),t.hasAttribute(`${u.prefix}if`)&&r.push(m.evaluateIf(t)),t.hasAttribute(`${u.prefix}each`)?Promise.all(r).then(()=>m.evaluateEach(t)):(t.getChildren().forEach(i=>{i instanceof x?r.push(m.evaluateAll(i,e)):i instanceof O&&r.push(m.evaluateText(i))}),Promise.all(r).then(()=>{}))}static evaluateText(t){return t.evaluate()}static evaluateIf(t){const e=[],r=t.getAttribute(`${u.prefix}if`);if(r===!1||r===void 0||r===null||Number.isNaN(r))e.push(t.hide().then(()=>{N.hide(t.getTarget())}));else{const i=[];t.getChildren().forEach(n=>{n instanceof x?i.push(m.evaluateAll(n)):n instanceof O&&i.push(m.evaluateText(n))}),e.push(t.show().then(()=>{N.show(t.getTarget())})),e.push(Promise.all(i).then(()=>{}))}return Promise.all(e).then(()=>{})}static evaluateEach(t){if(!t.isVisible()||!t.isMounted())return Promise.resolve();let e=t.getTemplate();if(e===null){let i=!1;t.getChildren().forEach(s=>{if(!i&&s instanceof x){if(s.hasAttribute(`${u.prefix}each-before`)||s.hasAttribute(`${u.prefix}each-after`))return;e=s.clone(),t.setTemplate(e),i=!0,t.removeChild(s);const a=s.getTarget();a.parentNode&&a.parentNode.removeChild(a),s.setMounted(!1)}});const n=t.getAttribute(`${u.prefix}each`);return Array.isArray(n)?this.updateDiff(t,n):(f.error("[Haori]","Invalid each attribute:",n),Promise.reject(new Error("Invalid each attribute.")))}const r=t.getAttribute(`${u.prefix}each`);return Array.isArray(r)?this.updateDiff(t,r):(f.error("[Haori]","Invalid each attribute:",r),Promise.reject(new Error("Invalid each attribute.")))}static updateDiff(t,e){const r=t.getTemplate();if(r===null)return f.error("[Haori]","Template is not set for each element."),Promise.resolve();let i=t.getAttribute(`${u.prefix}each-index`);i&&(i=String(i));const n=t.getAttribute(`${u.prefix}each-key`),s=t.getAttribute(`${u.prefix}each-arg`),a=new Map,o=[];e.forEach((h,d)=>{const b=m.createListKey(h,n?String(n):null,d);o.push(b),a.set(b,{item:h,itemIndex:d})});const l=[];let g=t.getChildren().filter(h=>h instanceof x).filter(h=>!h.hasAttribute(`${u.prefix}each-before`)&&!h.hasAttribute(`${u.prefix}each-after`));g=g.filter(h=>o.indexOf(String(h.getListKey()))===-1?(l.push(h.remove()),!1):!0);const p=g.map(h=>h.getListKey()),E=t.getChildren().filter(h=>h instanceof x).filter(h=>h.hasAttribute(`${u.prefix}each-before`)).length;let T=Promise.resolve();return o.forEach((h,d)=>{const b=p.indexOf(h),{item:v,itemIndex:A}=a.get(h);let D;if(b!==-1)D=g[b],T=T.then(()=>m.updateRowFragment(D,v,i,A,s?String(s):null,h).then(()=>m.evaluateAll(D)).then(()=>m.scheduleEvaluateAll(D)));else{D=r.clone();const X=E+d;T=T.then(()=>m.updateRowFragment(D,v,i,A,s?String(s):null,h).then(()=>t.insertBefore(D,t.getChildren()[X]||null).then(()=>m.evaluateAll(D)).then(()=>m.scheduleEvaluateAll(D))))}}),Promise.all(l).then(()=>T).then(()=>{const h=o.filter(A=>A!==null),d=p.filter(A=>A!==null),b=h.filter(A=>!d.includes(A)),v=d.filter(A=>!h.includes(A));N.eachUpdate(t.getTarget(),b,v,h)})}static createListKey(t,e,r){let i;if(typeof t=="object"&&t!==null)if(e){const n=t[e];n==null?i=`__index_${r}`:typeof n=="object"?i=JSON.stringify(n):i=String(n)}else i=`__index_${r}`;else i=String(t);return i}static updateRowFragment(t,e,r,i,n,s){let a=e;if(typeof e=="object"&&e!==null)a={...e},r&&(a[r]=i),n&&(a={[n]:a});else if(n)a={[n]:e},r&&(a[r]=i);else return f.error("[Haori]",`Primitive value requires '${u.prefix}each-arg' attribute: ${e}`),Promise.resolve();return t.setListKey(s),t.setBindingData(a),t.setAttribute(`${u.prefix}row`,s)}static scheduleEvaluateAll(t){setTimeout(()=>{m.evaluateAll(t)},100)}};m.ATTRIBUTE_ALIAS_SUFFIX="attr-",m.PRIORITY_ATTRIBUTE_SUFFIXES=["bind","if","each"],m.DEFERRED_ATTRIBUTE_SUFFIXES=["fetch","url-param"],m.EVALUATE_ALL_EXCLUDED_ATTRIBUTE_SUFFIXES=["bind","if","each","fetch","import","url-param"],m.ATTRIBUTE_PLACEHOLDER_REGEX=/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/;let R=m;const W=class W{constructor(t=document){this.onClick=e=>this.delegate(e,"click"),this.onChange=e=>this.delegate(e,"change"),this.onLoadCapture=e=>this.delegate(e,"load"),this.onWindowLoad=()=>{const e=document.documentElement,r=w.get(e);r&&new V(r,"load").run()},this.onPopstate=e=>{const r=e.state;!r||r[W.HISTORY_STATE_KEY]!==!0||location.reload()},this.root=t}start(){this.root.addEventListener("click",this.onClick),this.root.addEventListener("change",this.onChange),this.root.addEventListener("load",this.onLoadCapture,!0),window.addEventListener("load",this.onWindowLoad,{once:!0}),window.addEventListener("popstate",this.onPopstate)}stop(){this.root.removeEventListener("click",this.onClick),this.root.removeEventListener("change",this.onChange),this.root.removeEventListener("load",this.onLoadCapture,!0),window.removeEventListener("load",this.onWindowLoad),window.removeEventListener("popstate",this.onPopstate)}delegate(t,e){const r=this.getElementFromTarget(t.target,e);if(!r)return;const i=w.get(r);i&&(e==="change"&&i instanceof x&&i.syncValue(),new V(i,e).run().catch(n=>{f.error("[Haori]","Procedure execution error:",n)}))}getElementFromTarget(t,e){if(!t)return null;if(t instanceof HTMLElement)return e==="click"?this.findClickableElement(t):t;if(t instanceof Node){const r=t.parentElement;return r?e==="click"?this.findClickableElement(r):r:null}return null}findClickableElement(t){let e=t;for(;e;){if(e.getAttributeNames().some(r=>r.startsWith("data-click-")))return e;e=e.parentElement}return null}};W.HISTORY_STATE_KEY="__haoriHistoryState__";let Z=W;const S=class S{static syncTree(t){(t instanceof Element||t instanceof DocumentFragment)&&(t instanceof HTMLElement&&S.syncElement(t),t.querySelectorAll("*").forEach(e=>{S.syncElement(e)}))}static syncElement(t){const e=S.registrations.get(t),r=w.get(t);if(!r||!S.shouldObserve(r)){e&&(e.observer.disconnect(),S.registrations.delete(t));return}if(typeof IntersectionObserver>"u")return;const i=S.resolveRoot(r),n=S.resolveRootMargin(r),s=S.resolveThreshold(r),a=r.hasAttribute(`${u.prefix}intersect-once`);if(e&&e.observer.root===i&&e.observer.rootMargin===n&&S.sameThreshold(e.observer.thresholds,s)&&e.once===a){e.fragment=r;return}e&&(e.observer.disconnect(),S.registrations.delete(t));const o=new IntersectionObserver(l=>{const g=S.registrations.get(t);g&&l.forEach(p=>{!p.isIntersecting||g.running||S.isDisabled(g.fragment)||(g.running=!0,new V(g.fragment,"intersect").runWithResult().then(E=>{E&&g.once&&(g.observer.disconnect(),S.registrations.delete(t))}).catch(E=>{f.error("[Haori]","Intersect procedure execution error:",E)}).finally(()=>{const E=S.registrations.get(t);E&&(E.running=!1)}))})},{root:i,rootMargin:n,threshold:s});o.observe(t),S.registrations.set(t,{fragment:r,observer:o,once:a,running:!1})}static cleanupTree(t){if(t instanceof HTMLElement){const e=S.registrations.get(t);e&&(e.observer.disconnect(),S.registrations.delete(t))}(t instanceof Element||t instanceof DocumentFragment)&&t.querySelectorAll("*").forEach(e=>{const r=S.registrations.get(e);r&&(r.observer.disconnect(),S.registrations.delete(e))})}static disconnectAll(){S.registrations.forEach(t=>{t.observer.disconnect()}),S.registrations.clear()}static shouldObserve(t){return t.getAttributeNames().some(e=>{if(!e.startsWith(`${u.prefix}intersect-`))return!1;const r=e.slice(`${u.prefix}intersect-`.length);return!S.CONFIG_KEYS.has(r)})}static resolveRoot(t){const e=`${u.prefix}intersect-root`;if(!t.hasAttribute(e))return null;const r=t.getAttribute(e);if(typeof r!="string"||r.trim()==="")return null;const i=document.querySelector(r);return i instanceof HTMLElement?i:(f.error("[Haori]",`Intersect root element not found: ${r}`),null)}static resolveRootMargin(t){const e=`${u.prefix}intersect-root-margin`,r=t.getAttribute(e);return r===null||r===!1||r===""?"0px":String(r)}static resolveThreshold(t){const e=`${u.prefix}intersect-threshold`,r=t.getAttribute(e),i=typeof r=="number"?r:Number.parseFloat(String(r??0));return Number.isNaN(i)?0:Math.min(1,Math.max(0,i))}static isDisabled(t){const e=`${u.prefix}intersect-disabled`,r=t.getAttribute(e);if(r===null||r===!1)return!1;if(typeof r=="boolean")return r;const i=String(r).trim().toLowerCase();return i!==""&&i!=="false"&&i!=="0"}static sameThreshold(t,e){return t.length===1&&t[0]===e}};S.CONFIG_KEYS=new Set(["root","root-margin","threshold","disabled","once"]),S.registrations=new Map;let $=S;const H=class H{static async init(){if(H._initialized)return;H._initialized=!0;const t=await Promise.allSettled([R.scan(document.head),R.scan(document.body)]),[e,r]=t;e.status!=="fulfilled"&&f.error("[Haori]","Failed to build head fragment:",e.reason),r.status!=="fulfilled"&&f.error("[Haori]","Failed to build body fragment:",r.reason),await F.wait(),document.body.setAttribute("data-haori-ready",""),H.observe(document.head),H.observe(document.body),new Z().start(),$.syncTree(document.body)}static observe(t){new MutationObserver(async r=>{for(const i of r)try{switch(i.type){case"attributes":{f.info("[Haori]","Attribute changed:",i.target,i.attributeName);const n=i.target;if(i.attributeName&&n.hasAttribute("data-haori-click-lock")&&(i.attributeName==="disabled"||i.attributeName==="data-haori-click-lock")||i.attributeName&&R.isAliasedAttributeReflection(n,i.attributeName))break;R.setAttribute(n,i.attributeName,n.getAttribute(i.attributeName),!0),$.syncElement(n);break}case"childList":{f.info("[Haori]","Child list changed:",Array.from(i.removedNodes).map(n=>n.nodeName),Array.from(i.addedNodes).map(n=>n.nodeName)),Array.from(i.removedNodes).forEach(n=>{$.cleanupTree(n),R.removeNode(n)}),Array.from(i.addedNodes).forEach(n=>{n.parentElement instanceof HTMLElement&&(R.addNode(n.parentElement,n),$.syncTree(n))});break}case"characterData":{f.info("[Haori]","Character data changed:",i.target,i.target.textContent),i.target instanceof Text||i.target instanceof Comment?R.changeText(i.target,i.target.textContent):f.warn("[Haori]","Unsupported character data type:",i.target);break}default:f.warn("[Haori]","Unknown mutation type:",i.type);continue}}catch(n){f.error("[Haori]","Error processing mutation:",n)}}).observe(t,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),f.info("[Haori]","Observer initialized for",t)}};H._initialized=!1;let K=H;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",K.init):K.init();const gt="0.4.13";exports.Core=R;exports.Env=u;exports.Form=y;exports.Fragment=w;exports.Haori=U;exports.Log=f;exports.Queue=F;exports.default=U;exports.version=gt;
12
+ ${f}
13
+ `)}catch(E){p.error("Haori",`Invalid after script: ${E}`)}}if(t.hasAttribute(c.attrName(e,"dialog"))&&(r.dialogMessage=t.getAttribute(c.attrName(e,"dialog")).replace(/\\n/g,`
14
+ `)),t.hasAttribute(c.attrName(e,"toast"))){r.toastMessage=t.getAttribute(c.attrName(e,"toast"));const f=t.getRawAttribute(c.attrName(e,"toast-level")),N=["info","warning","error","success"].includes(f);r.toastLevel=N?f:null}if(t.hasAttribute(c.attrName(e,"redirect"))&&(r.redirectUrl=t.getAttribute(c.attrName(e,"redirect"))),t.hasAttribute(c.attrName(e,"scroll-error"))&&(r.scrollOnError=!0),t.hasAttribute(c.attrName(e,"scroll"))&&(r.scrollTarget=t.getAttribute(c.attrName(e,"scroll"))),t.hasAttribute(c.attrName(e,"history"))&&(r.historyUrl=t.getAttribute(c.attrName(e,"history"))),t.hasAttribute(c.attrName(e,"history-data"))&&(r.historyDataAttrName=c.attrName(e,"history-data")),t.hasAttribute(c.attrName(e,"history-form"))){const f=t.getRawAttribute(c.attrName(e,"history-form"));if(f){const E=document.body.querySelector(f);E!==null?r.historyFormFragment=y.getFormFragment(T.get(E)):p.error("Haori",`Form element not found: ${f} (${c.attrName(e,"history-form")})`)}else r.historyFormFragment=y.getFormFragment(t)}["reset-before","reset","refetch","click","copy","open","close"].forEach(f=>{const E=c.attrName(e,f);if(!t.hasAttribute(E))return;const N=t.getRawAttribute(E),w=[];if(N?(document.body.querySelectorAll(N).forEach(Y=>{const et=T.get(Y);et&&w.push(et)}),w.length===0&&p.error("Haori",`Element not found: ${N} (${E})`)):w.push(t),w.length>0)switch(f){case"reset-before":r.resetBeforeFragments=w;break;case"reset":r.resetFragments=w;break;case"refetch":r.refetchFragments=w;break;case"click":r.clickFragments=w;break;case"copy":r.copyFragments=w;break;case"open":r.openFragments=w;break;case"close":r.closeFragments=w;break}})}if(!e&&(t.hasAttribute(c.attrName(null,"data",!0))&&(r.dataAttrName=c.attrName(null,"data",!0)),t.hasAttribute(c.attrName(null,"form",!0)))){const l=t.getRawAttribute(c.attrName(null,"form",!0));if(l){const f=document.body.querySelector(l);f!==null?r.formFragment=y.getFormFragment(T.get(f)):p.error("Haori",`Form element not found: ${l} (${c.attrName(null,"fetch-form",!0)})`)}else r.formFragment=y.getFormFragment(t)}return i&&(!r.bindFragments||r.bindFragments.length===0)&&(r.bindFragments=[t]),r}static isElementFragment(t){if(typeof t!="object"||t===null)return!1;const e=t;return typeof e.getTarget=="function"&&typeof e.getChildElementFragments=="function"}constructor(t,e=null){c.isElementFragment(t)?(this.options=c.buildOptions(t,e),this.eventType=e):(this.options=t,this.eventType=null)}static resolveAutoFetchSignature(t){return new c(t,null).resolveFetchSignature()}run(){return this.runWithResult().then(()=>{})}runWithResult(){return this.execute()}async execute(){const t=this.acquireExecutionLock();if(t===!1)return!1;try{if(Object.keys(this.options).length===0||this.options.formFragment&&this.validate(this.options.formFragment)===!1||!await this.confirm())return!1;this.options.resetBeforeFragments&&this.options.resetBeforeFragments.length>0&&(await Promise.all(this.options.resetBeforeFragments.map(g=>y.reset(g))),this.captureHistorySnapshots());const r=this.prepareFetchRequest(),s=r.payload;let i=r.url,n=r.options;if(this.options.beforeCallback){const g=this.options.beforeCallback(i||null,n||null);if(g!=null){if(g===!1||typeof g=="object"&&g.stop)return!1;typeof g=="object"&&(i="fetchUrl"in g?g.fetchUrl:i,n="fetchOptions"in g?g.fetchOptions:n)}}const a=Object.keys(s).length>0;if(i){const g={...n||{}},m=r.requestedMethod,b=r.effectiveMethod,v=r.transportMode==="query-get",l=r.queryString;if(v&&p.info("Haori demo fetch normalization",{runtime:u.runtime,requestedMethod:m,effectiveMethod:b,transportMode:"query-get",url:i,payload:a?s:void 0,queryString:l}),this.options.targetFragment&&i){const f=performance.now(),E={runtime:u.runtime,requestedMethod:m,effectiveMethod:b,transportMode:v?"query-get":"http",...v?{queryString:l}:{}};return S.fetchStart(this.options.targetFragment.getTarget(),i,g,a?s:void 0,E),fetch(i,g).then(N=>this.handleFetchResult(N,i||void 0,f)).catch(N=>{throw i&&S.fetchError(this.options.targetFragment.getTarget(),i,N),N})}return fetch(i,g).then(f=>this.handleFetchResult(f,i||void 0))}if((!this.options.bindFragments||this.options.bindFragments.length===0)&&this.options.formFragment&&a){const g=this.options.formFragment,m=g.getTarget(),b=new Set;t&&t.appliedDisabledAttribute&&this.options.targetFragment&&b.add(this.options.targetFragment),m.setAttribute(`${u.prefix}bind`,JSON.stringify(s));const v=g.getBindingData();Object.assign(v,s),await P.setBindingData(m,v,b)}const o=a?s:{},h=new Response(JSON.stringify(o),{headers:{"Content-Type":"application/json"}});return this.handleFetchResult(h)}finally{this.releaseExecutionLock(t)}}acquireExecutionLock(){if(this.eventType!=="click"||!this.options.targetFragment)return null;const e=this.options.targetFragment.getTarget();return c.RUNNING_CLICK_TARGETS.has(e)||e.matches(":disabled")||e.hasAttribute("disabled")||e.hasAttribute(X)?!1:(c.RUNNING_CLICK_TARGETS.add(e),e.setAttribute(X,""),e.setAttribute("disabled",""),{target:e,appliedDisabledAttribute:!0})}releaseExecutionLock(t){t&&(c.RUNNING_CLICK_TARGETS.delete(t.target),t.appliedDisabledAttribute&&(t.target.removeAttribute("disabled"),t.target.removeAttribute(X)))}async handleFetchResult(t,e,r){const s=z();if(!t.ok)return this.options.targetFragment&&e&&S.fetchError(this.options.targetFragment.getTarget(),e,new Error(`${t.status} ${t.statusText}`),t.status,r),await this.handleFetchError(t),!1;if(this.options.targetFragment&&e&&r&&S.fetchEnd(this.options.targetFragment.getTarget(),e,t.status,r),this.options.afterCallback){const a=this.options.afterCallback(t);if(a!=null){if(a===!1||typeof a=="object"&&a.stop)return!1;typeof a=="object"&&"response"in a&&(t="response"in a?a.response:t)}}const i=[];i.push(this.bindResult(t)),i.push(this.adjust()),i.push(this.addRow()),i.push(this.removeRow()),i.push(this.movePrevRow()),i.push(this.moveNextRow()),await Promise.all(i),this.options.resetFragments&&this.options.resetFragments.length>0&&await Promise.all(this.options.resetFragments.map(a=>y.reset(a))),await this.copy();const n=[];return this.options.refetchFragments&&this.options.refetchFragments.length>0&&this.options.refetchFragments.forEach(a=>{n.push(new c(a,null).run())}),this.options.clickFragments&&this.options.clickFragments.length>0&&this.options.clickFragments.forEach(a=>{const o=a.getTarget();typeof o.click=="function"?o.click():o.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0}))}),this.options.openFragments&&this.options.openFragments.length>0&&this.options.openFragments.forEach(a=>{const o=a.getTarget();o instanceof HTMLElement?n.push(s.openDialog(o)):p.error("Haori","Element is not an HTML element: ",o)}),this.options.closeFragments&&this.options.closeFragments.length>0&&this.options.closeFragments.forEach(a=>{const o=a.getTarget();o instanceof HTMLElement?n.push(s.closeDialog(o)):p.error("Haori","Element is not an HTML element: ",o)}),await Promise.all(n),this.options.dialogMessage&&await s.dialog(this.options.dialogMessage),this.options.toastMessage&&await s.toast(this.options.toastMessage,this.options.toastLevel??"info"),this.pushHistory(),this.options.scrollTarget&&document.querySelector(this.options.scrollTarget)?.scrollIntoView({behavior:"smooth",block:"nearest"}),this.options.redirectUrl&&(window.location.href=this.options.redirectUrl),!0}pushHistory(){const t=this.options.historyUrl!==void 0&&this.options.historyUrl!==null,e=this.resolveHistoryDataValues(),r=this.resolveHistoryFormValues(),s=e!=null,i=r!=null;if(!(!t&&!s&&!i))try{const n=t?this.options.historyUrl:window.location.pathname,a=new URL(n,window.location.href);if(a.origin!==window.location.origin){const h="history.pushState: cross-origin URL is not allowed: "+a.toString();p.error("Haori",h);return}const o=h=>{for(const[g,m]of Object.entries(h))m!=null&&(Array.isArray(m)?m.forEach(b=>a.searchParams.append(g,String(b))):typeof m=="object"?a.searchParams.set(g,JSON.stringify(m)):a.searchParams.set(g,String(m)))};s&&o(e),i&&o(r),history.pushState({[lt]:!0},"",a.toString())}catch(n){p.error("Haori",`history.pushState failed: ${n}`)}}async handleFetchError(t){let e=null;this.options.formFragment?e=this.options.formFragment:this.options.targetFragment&&(e=y.getFormFragment(this.options.targetFragment)||this.options.targetFragment);const r=async n=>{const a=e?e.getTarget():document.body;await z().addErrorMessage(a,n)},s=()=>{if(!this.options.scrollOnError)return;const n=e?e.getTarget():document.body;(n.getAttribute("data-message-level")==="error"?n:n.parentElement?.getAttribute("data-message-level")==="error"?n.parentElement:n.querySelector('[data-message-level="error"]'))?.scrollIntoView({behavior:"smooth",block:"nearest"})};if((t.headers.get("Content-Type")||"").includes("application/json"))try{const n=await t.json(),a=[];if(n&&typeof n=="object"){if(typeof n.message=="string"&&a.push({message:n.message}),Array.isArray(n.messages))for(const o of n.messages)typeof o=="string"&&a.push({message:o});if(n.errors&&typeof n.errors=="object")for(const[o,h]of Object.entries(n.errors))Array.isArray(h)?a.push({key:o,message:h.join(`
15
+ `)}):typeof h=="string"?a.push({key:o,message:h}):h!=null&&a.push({key:o,message:String(h)});if(a.length===0)for(const[o,h]of Object.entries(n))o==="message"||o==="messages"||o==="errors"||(Array.isArray(h)?a.push({key:o,message:h.join(`
16
+ `)}):typeof h=="string"&&a.push({key:o,message:h}))}if(a.length===0)return await r(`${t.status} ${t.statusText}`),s(),!1;for(const o of a)o.key&&e?await y.addErrorMessage(e,o.key,o.message):await r(o.message);return s(),!1}catch{}try{const n=await t.text();n&&n.trim().length>0?await r(n.trim()):await r(`${t.status} ${t.statusText}`)}catch{await r(`${t.status} ${t.statusText}`)}return s(),!1}validate(t){if(this.options.valid!==!0)return!0;const e=this.findFirstInvalid(t);return e===null?!0:(e.reportValidity(),e.focus(),this.options.scrollOnError&&e.scrollIntoView({behavior:"smooth",block:"nearest"}),!1)}findFirstInvalid(t){let e=null;for(const r of t.getChildElementFragments().reverse()){const s=this.findFirstInvalid(r);s!==null&&(e=s)}return this.checkOne(t)?e:t.getTarget()}checkOne(t){const e=t.getTarget();return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?e.checkValidity():!0}confirm(){const t=this.options.confirmMessage;return t==null?Promise.resolve(!0):z().confirm(t)}bindResult(t){return!this.options.bindFragments||this.options.bindFragments.length===0?Promise.resolve():(t.headers.get("Content-Type")?.includes("application/json")?t.json():t.text()).then(r=>{if(this.options.bindParams){const i={};this.options.bindParams.forEach(n=>{r&&typeof r=="object"&&n in r&&(i[n]=r[n])}),r=i}const s=[];if(this.options.bindArg)this.options.bindFragments.forEach(i=>{const n=i.getBindingData(),a=this.options.bindArg;if(r&&typeof r=="object"&&!Array.isArray(r)){const o=n[a],h=o&&typeof o=="object"&&!Array.isArray(o)?o:{};n[a]=this.mergeAppendBindingData(i,r,h)}else n[a]=r;s.push(P.setBindingData(i.getTarget(),n))});else{if(typeof r=="string")return p.error("Haori","string data cannot be bound without a bindArg."),Promise.reject(new Error("string data cannot be bound without a bindArg."));this.options.bindFragments.forEach(i=>{const n=this.mergeAppendBindingData(i,r);s.push(P.setBindingData(i.getTarget(),n))})}return Promise.all(s).then(()=>{})})}mergeAppendBindingData(t,e,r=t.getBindingData()){if(!this.options.bindAppendParams||this.options.bindAppendParams.length===0)return e;const s={...e},i=r;for(const n of this.options.bindAppendParams){const a=s[n],o=i[n];Array.isArray(o)&&Array.isArray(a)&&(s[n]=o.concat(a))}return s}copy(){if(!this.options.copyFragments||this.options.copyFragments.length===0)return Promise.resolve();const t=this.resolveCopySourceData(),e=this.pickCopyData(t),r=this.options.copyFragments.map(s=>{const i={...s.getBindingData(),...e};return P.setBindingData(s.getTarget(),i)});return Promise.all(r).then(()=>{})}resolveCopySourceData(){return this.options.formFragment?y.getValues(this.options.formFragment):this.options.targetFragment?{...this.options.targetFragment.getBindingData()}:{}}buildPayload(){return this.buildPayloadResolution().payload}buildPayloadResolution(){const t={};let e=!1;if(this.options.formFragment&&Object.assign(t,y.getValues(this.options.formFragment)),this.options.data&&typeof this.options.data=="object"&&Object.assign(t,this.options.data),this.options.targetFragment&&this.options.dataAttrName){const r=c.resolveDataAttributeDetailed(this.options.targetFragment,this.options.dataAttrName);e=e||r.hasUnresolvedReference,r.value&&Object.assign(t,r.value)}return{payload:t,hasUnresolvedReference:e}}resolveFetchSignature(){const t=this.prepareFetchRequest();return{signature:t.signature,hasUnresolvedReference:t.hasUnresolvedReference}}prepareFetchRequest(){const t=this.buildPayloadResolution(),e=t.payload,r=!!this.options.fetchHasUnresolvedReference||t.hasUnresolvedReference;if(!this.options.fetchUrl||r)return{url:null,options:null,payload:e,hasUnresolvedReference:r,requestedMethod:"GET",effectiveMethod:"GET",transportMode:"http",signature:null};let s=this.options.fetchUrl;const i={...this.options.fetchOptions||{}},n=new Headers(i.headers||void 0),a=(i.method||"GET").toUpperCase(),o=u.runtime==="demo"&&!ct(a),h=o?"GET":a;if(i.method=h,h==="GET"||h==="HEAD"||h==="OPTIONS")Object.keys(e).length>0&&(s=ft(s,e));else if(Object.keys(e).length>0){const m=n.get("Content-Type")||"";if(/multipart\/form-data/i.test(m)){n.delete("Content-Type");const b=new FormData;for(const[v,l]of Object.entries(e))l==null?b.append(v,""):l instanceof Blob?b.append(v,l):Array.isArray(l)?l.forEach(f=>b.append(v,String(f))):typeof l=="object"?b.append(v,JSON.stringify(l)):b.append(v,String(l));i.body=b}else if(/application\/x-www-form-urlencoded/i.test(m)){const b=new URLSearchParams;for(const[v,l]of Object.entries(e))l!==void 0&&(l===null?b.append(v,""):Array.isArray(l)?l.forEach(f=>b.append(v,String(f))):typeof l=="object"?b.append(v,JSON.stringify(l)):b.append(v,String(l)));i.body=b}else n.set("Content-Type","application/json"),i.body=JSON.stringify(e)}i.headers=n;let g;return o&&(g=new URL(s,window.location.href).search||void 0,n.delete("Content-Type")),{url:s,options:i,payload:e,hasUnresolvedReference:!1,requestedMethod:a,effectiveMethod:h,queryString:g,transportMode:o?"query-get":"http",signature:pt(s,i)}}captureHistorySnapshots(){this.options.targetFragment&&this.options.historyDataAttrName?this.historyDataSnapshot=c.resolveDataAttribute(this.options.targetFragment,this.options.historyDataAttrName):this.historyDataSnapshot=void 0,this.historyFormSnapshot=this.options.historyFormFragment?y.getValues(this.options.historyFormFragment):void 0}resolveHistoryDataValues(){return this.historyDataSnapshot!==void 0?this.historyDataSnapshot:this.options.targetFragment&&this.options.historyDataAttrName?c.resolveDataAttribute(this.options.targetFragment,this.options.historyDataAttrName):this.options.historyData}resolveHistoryFormValues(){if(this.historyFormSnapshot!==void 0)return this.historyFormSnapshot;if(this.options.historyFormFragment)return y.getValues(this.options.historyFormFragment)}pickCopyData(t){if(!this.options.copyParams||this.options.copyParams.length===0)return t;const e=new Set,r=new Set;this.options.copyParams.forEach(n=>{const a=n.trim();if(a){if(a.startsWith("!")){const o=a.slice(1).trim();o&&r.add(o);return}e.add(a)}});const s={};return(e.size>0?Array.from(e):Object.keys(t)).forEach(n=>{n in t&&(r.has(n)||(s[n]=t[n]))}),s}adjust(){if(!this.options.adjustFragments||this.options.adjustFragments.length===0)return Promise.resolve();const t=this.options.adjustValue??0,e=[];for(const r of this.options.adjustFragments){let s=r.getValue();(s==null||s==="")&&(s="0");let i=Number(s);isNaN(i)&&(i=0),i+=t,e.push(r.setValue(String(i)))}return Promise.all(e).then(()=>{})}getRowFragment(){if(!this.options.targetFragment)return p.error("Haori","Target fragment is not specified for row operation."),null;const t=this.options.targetFragment.closestByAttribute(`${u.prefix}row`);return t||(p.error("Haori","Row fragment not found."),null)}addRow(){if(this.options.rowAdd!==!0)return Promise.resolve();const t=this.getRowFragment();if(!t)return Promise.reject(new Error("Row fragment not found."));const e=[],r=t.clone();return e.push(t.getParent().insertAfter(r,t)),e.push(P.evaluateAll(r)),e.push(y.reset(r)),Promise.all(e).then(()=>{})}removeRow(){if(this.options.rowRemove!==!0)return Promise.resolve();const t=this.getRowFragment();if(!t)return Promise.reject(new Error("Row fragment not found."));const e=t.getParent();return e&&e.getChildElementFragments().filter(s=>!s.hasAttribute(`${u.prefix}each-before`)&&!s.hasAttribute(`${u.prefix}each-after`)).length<=1?Promise.resolve():t.remove()}movePrevRow(){if(this.options.rowMovePrev!==!0)return Promise.resolve();const t=this.getRowFragment();if(!t)return Promise.reject(new Error("Row fragment not found."));const e=t.getPrevious();if(!e)return Promise.resolve();const r=t.getParent();return r?r.insertBefore(t,e):Promise.resolve()}moveNextRow(){if(this.options.rowMoveNext!==!0)return Promise.resolve();const t=this.getRowFragment();if(!t)return Promise.reject(new Error("Row fragment not found."));const e=t.getNext();if(!e)return Promise.resolve();const r=t.getParent();return r?r.insertAfter(t,e):Promise.resolve()}};c.DATA_PLACEHOLDER_REGEX=/\{\{\{([\s\S]+?)\}\}\}|\{\{([\s\S]+?)\}\}/g,c.SINGLE_PLACEHOLDER_REGEX=/^(\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\})$/,c.RUNNING_CLICK_TARGETS=new WeakSet;let $=c;class gt{static readParams(){const t={},e=window.location.search;return new URLSearchParams(e).forEach((s,i)=>{t[i]=s}),t}}class mt{static async load(t,e){let r;try{r=await fetch(t,e)}catch(i){throw p.error("[Haori]","Failed to fetch import source:",t,i),new Error(`Failed to fetch: ${t}`)}if(!r.ok){const i=`${r.status} ${r.statusText}`;throw p.error("[Haori]","Import HTTP error:",t,i),new Error(`Failed to load ${t}: ${i}`)}let s;try{s=await r.text()}catch(i){throw p.error("[Haori]","Failed to read response text:",t,i),new Error(`Failed to read response from: ${t}`)}try{const n=new DOMParser().parseFromString(s,"text/html");return n&&n.body?n.body.innerHTML:(p.warn("[Haori]","No body found in imported document:",t),s)}catch(i){return p.error("[Haori]","Failed to parse imported HTML:",t,i),s}}}const d=class d{static isDeferredAttributeName(t){return d.DEFERRED_ATTRIBUTE_SUFFIXES.some(e=>t===`${u.prefix}${e}`)}static isEvaluateAllExcludedAttributeName(t){return d.EVALUATE_ALL_EXCLUDED_ATTRIBUTE_SUFFIXES.some(e=>t===`${u.prefix}${e}`)}static shouldReevaluateAttribute(t,e){return e!==null&&!d.isEvaluateAllExcludedAttributeName(t)&&d.ATTRIBUTE_PLACEHOLDER_REGEX.test(e)}static getAliasedAttributeName(t){const e=`${u.prefix}${d.ATTRIBUTE_ALIAS_SUFFIX}`;return!t.startsWith(e)||t.length<=e.length?null:t.slice(e.length)}static isAliasedAttributeReflection(t,e){const r=T.get(t);return r instanceof D?r.hasAttribute(`${u.prefix}${d.ATTRIBUTE_ALIAS_SUFFIX}${e}`):!1}static reevaluateInterpolatedAttributes(t){let e=Promise.resolve();for(const r of t.getAttributeNames()){const s=t.getRawAttribute(r);d.shouldReevaluateAttribute(r,s)&&(e=e.then(()=>d.setAttribute(t.getTarget(),r,s)))}return e.then(()=>{})}static getReactiveFetchState(t){const e=d.REACTIVE_FETCH_STATES.get(t);if(e)return e;const r={lastSignature:null,running:!1,rerunRequested:!1};return d.REACTIVE_FETCH_STATES.set(t,r),r}static getReactiveImportState(t){const e=d.REACTIVE_IMPORT_STATES.get(t);if(e)return e;const r={lastUrl:null,running:!1,rerunRequested:!1};return d.REACTIVE_IMPORT_STATES.set(t,r),r}static reevaluateReactiveSpecialAttributes(t,e=new Set){if(e.has(t))return Promise.resolve();const r=[];return t.hasAttribute(`${u.prefix}fetch`)&&r.push(d.executeManagedFetch(t)),t.hasAttribute(`${u.prefix}import`)&&r.push(d.executeManagedImport(t)),t.getChildren().forEach(s=>{s instanceof D&&r.push(d.reevaluateReactiveSpecialAttributes(s,e))}),Promise.all(r).then(()=>{})}static executeManagedFetch(t){const e=t.getTarget(),r=d.getReactiveFetchState(e),s=$.resolveAutoFetchSignature(t);return r.running?((s.hasUnresolvedReference||s.signature!==r.lastSignature)&&(r.rerunRequested=!0),Promise.resolve()):s.hasUnresolvedReference||s.signature===null?(r.lastSignature=null,Promise.resolve()):r.lastSignature===s.signature?Promise.resolve():(r.lastSignature=s.signature,r.running=!0,new $(t,null).runWithResult().then(()=>{}).finally(()=>{if(r.running=!1,r.rerunRequested)return r.rerunRequested=!1,d.executeManagedFetch(t)}))}static executeManagedImport(t){const e=t.getTarget(),r=d.getReactiveImportState(e),s=t.getAttributeEvaluation(`${u.prefix}import`),i=s&&!s.hasUnresolvedReference&&typeof s.value=="string"?s.value:null;if(r.running)return i!==r.lastUrl&&(r.rerunRequested=!0),Promise.resolve();if(i===null)return r.lastUrl=null,Promise.resolve();if(r.lastUrl===i)return Promise.resolve();r.lastUrl=i,r.running=!0;const n=performance.now();return e.setAttribute(`${u.prefix}importing`,""),S.importStart(e,i),mt.load(i).then(a=>{const o=new TextEncoder().encode(a).length;return F.enqueue(()=>{e.innerHTML=a}).then(()=>{if(e.removeAttribute(`${u.prefix}importing`),S.importEnd(e,i,o,n),!document.body.hasAttribute("data-haori-ready")){const h=[];return e.childNodes.forEach(g=>{const m=T.get(g);m instanceof D?h.push(d.scan(m.getTarget())):m instanceof C&&h.push(d.evaluateText(m))}),Promise.all(h).then(()=>{})}})}).catch(a=>{e.removeAttribute(`${u.prefix}importing`),S.importError(e,i,a),p.error("[Haori]","Failed to import HTML:",i,a)}).finally(()=>{if(r.running=!1,r.rerunRequested)return r.rerunRequested=!1,d.executeManagedImport(t)})}static scan(t){const e=T.get(t);if(!e)return Promise.resolve();t.parentNode&&(T.get(t.parentNode)?.isMounted()||document.body.contains(t)?e.setMounted(!0):e.setMounted(!1));let r=Promise.resolve();const s=new Set;for(const i of d.PRIORITY_ATTRIBUTE_SUFFIXES){const n=u.prefix+i;e.hasAttribute(n)&&(r=r.then(()=>d.setAttribute(e.getTarget(),n,e.getRawAttribute(n))),s.add(n))}for(const i of e.getAttributeNames()){if(s.has(i)||d.isDeferredAttributeName(i))continue;const n=e.getRawAttribute(i);n!==null&&(r=r.then(()=>d.setAttribute(e.getTarget(),i,n)))}for(const i of d.DEFERRED_ATTRIBUTE_SUFFIXES){const n=u.prefix+i;e.hasAttribute(n)&&(r=r.then(()=>d.setAttribute(e.getTarget(),n,e.getRawAttribute(n))),s.add(n))}return r.then(()=>{const i=[];return e.getChildren().forEach(n=>{n instanceof D?i.push(d.scan(n.getTarget())):n instanceof C&&i.push(d.evaluateText(n))}),Promise.all(i).then(()=>{})}).then(()=>{})}static setAttribute(t,e,r,s=!1){const i=T.get(t),n=d.getAliasedAttributeName(e);if(n!==null)return r===null?i.removeAliasedAttribute(e,n):i.setAliasedAttribute(e,n,r,s);const a=[];switch(e){case`${u.prefix}bind`:{r===null?(i.clearBindingDataCache(),i.setBindingData({})):i.setBindingData(d.parseDataBind(r));break}case`${u.prefix}if`:a.push(d.evaluateIf(i));break;case`${u.prefix}each`:a.push(d.evaluateEach(i));break;case`${u.prefix}fetch`:a.push(d.executeManagedFetch(i));break;case`${u.prefix}import`:typeof r=="string"&&a.push(d.executeManagedImport(i));break;case`${u.prefix}url-param`:{const o=i.getAttribute(`${u.prefix}url-arg`),h=gt.readParams();if(o===null)a.push(d.setBindingData(t,h));else{const g=i.getRawBindingData()||{};g[String(o)]=h,a.push(d.setBindingData(t,g))}break}}return r===null?a.push(i.removeAttribute(e)):a.push(i.setAttribute(e,r,s)),Promise.all(a).then(()=>{})}static setBindingData(t,e,r=new Set){const s=T.get(t),i=s.getRawBindingData();s.setBindingData(e);let n=s.setAttribute(`${u.prefix}bind`,JSON.stringify(e));if(t.tagName==="FORM"){const a=s.getAttribute(`${u.prefix}form-arg`),o=a&&e[String(a)]&&typeof e[String(a)]=="object"&&!Array.isArray(e[String(a)])?e[String(a)]:a?{}:e;n=n.then(()=>y.syncValues(s,o))}return n=n.then(()=>d.evaluateAll(s,r)),n=n.then(()=>d.reevaluateReactiveSpecialAttributes(s,r)),S.bindChange(t,i,e,"manual"),n.then(()=>{})}static parseDataBind(t){if(t.startsWith("{")||t.startsWith("["))try{return JSON.parse(t)}catch(e){return p.error("[Haori]","Invalid JSON in data-bind:",e),{}}else{const e=new URLSearchParams(t),r={};for(const[s,i]of e.entries())r[s]!==void 0?Array.isArray(r[s])?r[s].push(i):r[s]=[r[s],i]:r[s]=i;return r}}static addNode(t,e){const r=T.get(t);if(r.isSkipMutationNodes())return;const s=T.get(e.nextSibling),i=T.get(e);i&&(r.insertBefore(i,s),i instanceof D?d.scan(i.getTarget()):i instanceof C&&d.evaluateText(i))}static removeNode(t){const e=T.get(t);if(e){const r=e.getParent();if(r&&r.isSkipMutationNodes())return;e.remove()}}static changeText(t,e){const r=T.get(t);r&&r.setContent(e)}static changeValue(t,e){const r=T.get(t);if(r.getValue()===e)return Promise.resolve();const s=[];s.push(r.setValue(e));const i=d.getFormFragment(r);if(i){const n=y.getValues(i),a=i.getAttribute(`${u.prefix}form-arg`);let o;a?(o=i.getRawBindingData(),o||(o={}),o[String(a)]=n):o=n,s.push(d.setBindingData(i.getTarget(),o))}return Promise.all(s).then(()=>{})}static getFormFragment(t){if(t.getTarget()instanceof HTMLFormElement)return t;const e=t.getParent();return e?d.getFormFragment(e):null}static evaluateAll(t,e=new Set){if(e.has(t))return Promise.resolve();const r=[];return r.push(d.reevaluateInterpolatedAttributes(t)),t.hasAttribute(`${u.prefix}if`)&&r.push(d.evaluateIf(t)),t.hasAttribute(`${u.prefix}each`)?Promise.all(r).then(()=>d.evaluateEach(t)):(t.getChildren().forEach(s=>{s instanceof D?r.push(d.evaluateAll(s,e)):s instanceof C&&r.push(d.evaluateText(s))}),Promise.all(r).then(()=>{}))}static evaluateText(t){return t.evaluate()}static evaluateIf(t){const e=[],r=t.getAttribute(`${u.prefix}if`);if(r===!1||r===void 0||r===null||Number.isNaN(r))e.push(t.hide().then(()=>{S.hide(t.getTarget())}));else{const s=[];t.getChildren().forEach(i=>{i instanceof D?s.push(d.evaluateAll(i)):i instanceof C&&s.push(d.evaluateText(i))}),e.push(t.show().then(()=>{S.show(t.getTarget())})),e.push(Promise.all(s).then(()=>{}))}return Promise.all(e).then(()=>{})}static evaluateEach(t){if(!t.isVisible()||!t.isMounted())return Promise.resolve();let e=t.getTemplate();if(e===null){let s=!1;t.getChildren().forEach(n=>{if(!s&&n instanceof D){if(n.hasAttribute(`${u.prefix}each-before`)||n.hasAttribute(`${u.prefix}each-after`))return;e=n.clone(),t.setTemplate(e),s=!0,t.removeChild(n);const a=n.getTarget();a.parentNode&&a.parentNode.removeChild(a),n.setMounted(!1)}});const i=t.getAttribute(`${u.prefix}each`);return Array.isArray(i)?this.updateDiff(t,i):(p.error("[Haori]","Invalid each attribute:",i),Promise.reject(new Error("Invalid each attribute.")))}const r=t.getAttribute(`${u.prefix}each`);return Array.isArray(r)?this.updateDiff(t,r):(p.error("[Haori]","Invalid each attribute:",r),Promise.reject(new Error("Invalid each attribute.")))}static updateDiff(t,e){const r=t.getTemplate();if(r===null)return p.error("[Haori]","Template is not set for each element."),Promise.resolve();let s=t.getAttribute(`${u.prefix}each-index`);s&&(s=String(s));const i=t.getAttribute(`${u.prefix}each-key`),n=t.getAttribute(`${u.prefix}each-arg`),a=new Map,o=[];e.forEach((l,f)=>{const E=d.createListKey(l,i?String(i):null,f);o.push(E),a.set(E,{item:l,itemIndex:f})});const h=[];let g=t.getChildren().filter(l=>l instanceof D).filter(l=>!l.hasAttribute(`${u.prefix}each-before`)&&!l.hasAttribute(`${u.prefix}each-after`));g=g.filter(l=>o.indexOf(String(l.getListKey()))===-1?(h.push(l.remove()),!1):!0);const m=g.map(l=>l.getListKey()),b=t.getChildren().filter(l=>l instanceof D).filter(l=>l.hasAttribute(`${u.prefix}each-before`)).length;let v=Promise.resolve();return o.forEach((l,f)=>{const E=m.indexOf(l),{item:N,itemIndex:w}=a.get(l);let k;if(E!==-1)k=g[E],v=v.then(()=>d.updateRowFragment(k,N,s,w,n?String(n):null,l).then(()=>d.evaluateAll(k)).then(()=>d.scheduleEvaluateAll(k)));else{k=r.clone();const Y=b+f;v=v.then(()=>d.updateRowFragment(k,N,s,w,n?String(n):null,l).then(()=>t.insertBefore(k,t.getChildren()[Y]||null).then(()=>d.evaluateAll(k)).then(()=>d.scheduleEvaluateAll(k))))}}),Promise.all(h).then(()=>v).then(()=>{const l=o.filter(w=>w!==null),f=m.filter(w=>w!==null),E=l.filter(w=>!f.includes(w)),N=f.filter(w=>!l.includes(w));S.eachUpdate(t.getTarget(),E,N,l)})}static createListKey(t,e,r){let s;if(typeof t=="object"&&t!==null)if(e){const i=t[e];i==null?s=`__index_${r}`:typeof i=="object"?s=JSON.stringify(i):s=String(i)}else s=`__index_${r}`;else s=String(t);return s}static updateRowFragment(t,e,r,s,i,n){let a=e;if(typeof e=="object"&&e!==null)a={...e},r&&(a[r]=s),i&&(a={[i]:a});else if(i)a={[i]:e},r&&(a[r]=s);else return p.error("[Haori]",`Primitive value requires '${u.prefix}each-arg' attribute: ${e}`),Promise.resolve();return t.setListKey(n),t.setBindingData(a),t.setAttribute(`${u.prefix}row`,n)}static scheduleEvaluateAll(t){setTimeout(()=>{d.evaluateAll(t)},100)}};d.ATTRIBUTE_ALIAS_SUFFIX="attr-",d.PRIORITY_ATTRIBUTE_SUFFIXES=["bind","if","each"],d.DEFERRED_ATTRIBUTE_SUFFIXES=["fetch","url-param"],d.EVALUATE_ALL_EXCLUDED_ATTRIBUTE_SUFFIXES=["bind","if","each","fetch","import","url-param"],d.ATTRIBUTE_PLACEHOLDER_REGEX=/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/,d.REACTIVE_FETCH_STATES=new WeakMap,d.REACTIVE_IMPORT_STATES=new WeakMap;let P=d;const J=class J{constructor(t=document){this.onClick=e=>this.delegate(e,"click"),this.onChange=e=>this.delegate(e,"change"),this.onLoadCapture=e=>this.delegate(e,"load"),this.onWindowLoad=()=>{const e=document.documentElement,r=T.get(e);r&&new $(r,"load").run()},this.onPopstate=e=>{const r=e.state;!r||r[J.HISTORY_STATE_KEY]!==!0||location.reload()},this.root=t}start(){this.root.addEventListener("click",this.onClick),this.root.addEventListener("change",this.onChange),this.root.addEventListener("load",this.onLoadCapture,!0),window.addEventListener("load",this.onWindowLoad,{once:!0}),window.addEventListener("popstate",this.onPopstate)}stop(){this.root.removeEventListener("click",this.onClick),this.root.removeEventListener("change",this.onChange),this.root.removeEventListener("load",this.onLoadCapture,!0),window.removeEventListener("load",this.onWindowLoad),window.removeEventListener("popstate",this.onPopstate)}delegate(t,e){const r=this.getElementFromTarget(t.target,e);if(!r)return;const s=T.get(r);s&&(e==="change"&&s instanceof D&&s.syncValue(),new $(s,e).run().catch(i=>{p.error("[Haori]","Procedure execution error:",i)}))}getElementFromTarget(t,e){if(!t)return null;if(t instanceof HTMLElement)return e==="click"?this.findClickableElement(t):t;if(t instanceof Node){const r=t.parentElement;return r?e==="click"?this.findClickableElement(r):r:null}return null}findClickableElement(t){let e=t;for(;e;){if(e.getAttributeNames().some(r=>r.startsWith("data-click-")))return e;e=e.parentElement}return null}};J.HISTORY_STATE_KEY="__haoriHistoryState__";let Z=J;const R=class R{static syncTree(t){(t instanceof Element||t instanceof DocumentFragment)&&(t instanceof HTMLElement&&R.syncElement(t),t.querySelectorAll("*").forEach(e=>{R.syncElement(e)}))}static syncElement(t){const e=R.registrations.get(t),r=T.get(t);if(!r||!R.shouldObserve(r)){e&&(e.observer.disconnect(),R.registrations.delete(t));return}if(typeof IntersectionObserver>"u")return;const s=R.resolveRoot(r),i=R.resolveRootMargin(r),n=R.resolveThreshold(r),a=r.hasAttribute(`${u.prefix}intersect-once`);if(e&&e.observer.root===s&&e.observer.rootMargin===i&&R.sameThreshold(e.observer.thresholds,n)&&e.once===a){e.fragment=r;return}e&&(e.observer.disconnect(),R.registrations.delete(t));const o=new IntersectionObserver(h=>{const g=R.registrations.get(t);g&&h.forEach(m=>{!m.isIntersecting||g.running||R.isDisabled(g.fragment)||(g.running=!0,new $(g.fragment,"intersect").runWithResult().then(b=>{b&&g.once&&(g.observer.disconnect(),R.registrations.delete(t))}).catch(b=>{p.error("[Haori]","Intersect procedure execution error:",b)}).finally(()=>{const b=R.registrations.get(t);b&&(b.running=!1)}))})},{root:s,rootMargin:i,threshold:n});o.observe(t),R.registrations.set(t,{fragment:r,observer:o,once:a,running:!1})}static cleanupTree(t){if(t instanceof HTMLElement){const e=R.registrations.get(t);e&&(e.observer.disconnect(),R.registrations.delete(t))}(t instanceof Element||t instanceof DocumentFragment)&&t.querySelectorAll("*").forEach(e=>{const r=R.registrations.get(e);r&&(r.observer.disconnect(),R.registrations.delete(e))})}static disconnectAll(){R.registrations.forEach(t=>{t.observer.disconnect()}),R.registrations.clear()}static shouldObserve(t){return t.getAttributeNames().some(e=>{if(!e.startsWith(`${u.prefix}intersect-`))return!1;const r=e.slice(`${u.prefix}intersect-`.length);return!R.CONFIG_KEYS.has(r)})}static resolveRoot(t){const e=`${u.prefix}intersect-root`;if(!t.hasAttribute(e))return null;const r=t.getAttribute(e);if(typeof r!="string"||r.trim()==="")return null;const s=document.querySelector(r);return s instanceof HTMLElement?s:(p.error("[Haori]",`Intersect root element not found: ${r}`),null)}static resolveRootMargin(t){const e=`${u.prefix}intersect-root-margin`,r=t.getAttribute(e);return r===null||r===!1||r===""?"0px":String(r)}static resolveThreshold(t){const e=`${u.prefix}intersect-threshold`,r=t.getAttribute(e),s=typeof r=="number"?r:Number.parseFloat(String(r??0));return Number.isNaN(s)?0:Math.min(1,Math.max(0,s))}static isDisabled(t){const e=`${u.prefix}intersect-disabled`,r=t.getAttribute(e);if(r===null||r===!1)return!1;if(typeof r=="boolean")return r;const s=String(r).trim().toLowerCase();return s!==""&&s!=="false"&&s!=="0"}static sameThreshold(t,e){return t.length===1&&t[0]===e}};R.CONFIG_KEYS=new Set(["root","root-margin","threshold","disabled","once"]),R.registrations=new Map;let U=R;const H=class H{static async init(){if(H._initialized)return;H._initialized=!0;const t=await Promise.allSettled([P.scan(document.head),P.scan(document.body)]),[e,r]=t;e.status!=="fulfilled"&&p.error("[Haori]","Failed to build head fragment:",e.reason),r.status!=="fulfilled"&&p.error("[Haori]","Failed to build body fragment:",r.reason),await F.wait(),document.body.setAttribute("data-haori-ready",""),H.observe(document.head),H.observe(document.body),new Z().start(),U.syncTree(document.body)}static observe(t){new MutationObserver(async r=>{for(const s of r)try{switch(s.type){case"attributes":{p.info("[Haori]","Attribute changed:",s.target,s.attributeName);const i=s.target;if(s.attributeName&&i.hasAttribute("data-haori-click-lock")&&(s.attributeName==="disabled"||s.attributeName==="data-haori-click-lock")||s.attributeName&&P.isAliasedAttributeReflection(i,s.attributeName))break;P.setAttribute(i,s.attributeName,i.getAttribute(s.attributeName),!0),U.syncElement(i);break}case"childList":{p.info("[Haori]","Child list changed:",Array.from(s.removedNodes).map(i=>i.nodeName),Array.from(s.addedNodes).map(i=>i.nodeName)),Array.from(s.removedNodes).forEach(i=>{U.cleanupTree(i),P.removeNode(i)}),Array.from(s.addedNodes).forEach(i=>{i.parentElement instanceof HTMLElement&&(P.addNode(i.parentElement,i),U.syncTree(i))});break}case"characterData":{p.info("[Haori]","Character data changed:",s.target,s.target.textContent),s.target instanceof Text||s.target instanceof Comment?P.changeText(s.target,s.target.textContent):p.warn("[Haori]","Unsupported character data type:",s.target);break}default:p.warn("[Haori]","Unknown mutation type:",s.type);continue}}catch(i){p.error("[Haori]","Error processing mutation:",i)}}).observe(t,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),p.info("[Haori]","Observer initialized for",t)}};H._initialized=!1;let K=H;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",K.init):K.init();const bt="0.4.13";exports.Core=P;exports.Env=u;exports.Form=y;exports.Fragment=T;exports.Haori=V;exports.Log=p;exports.Queue=F;exports.default=V;exports.version=bt;
17
17
  //# sourceMappingURL=haori.cjs.js.map