native-document 1.0.11 โ†’ 1.0.13

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.
@@ -356,6 +356,9 @@ var NativeDocument = (function (exports) {
356
356
  isFunction(value) {
357
357
  return typeof value === 'function';
358
358
  },
359
+ isAsyncFunction(value) {
360
+ return typeof value === 'function' && value.constructor.name === 'AsyncFunction';
361
+ },
359
362
  isObject(value) {
360
363
  return typeof value === 'object';
361
364
  },
@@ -493,17 +496,45 @@ var NativeDocument = (function (exports) {
493
496
  return new ObservableItem(value);
494
497
  }
495
498
 
499
+ /**
500
+ *
501
+ * @param {Function} callback
502
+ * @param {Array|Function} dependencies
503
+ * @returns {ObservableItem}
504
+ */
496
505
  Observable.computed = function(callback, dependencies = []) {
497
506
  const initialValue = callback();
498
507
  const observable = new ObservableItem(initialValue);
499
-
500
508
  const updatedValue = () => observable.set(callback());
501
509
 
510
+ if(Validator.isFunction(dependencies)) {
511
+ if(!Validator.isObservable(dependencies.$observer)) {
512
+ throw new NativeDocumentError('Observable.computed : dependencies must be valid batch function');
513
+ }
514
+ dependencies.$observer.subscribe(updatedValue);
515
+ return observable;
516
+ }
517
+
502
518
  dependencies.forEach(dependency => dependency.subscribe(updatedValue));
503
519
 
504
520
  return observable;
505
521
  };
506
522
 
523
+ Observable.batch = function(callback) {
524
+ const $observer = Observable(0);
525
+ const batch = function() {
526
+ if(Validator.isAsyncFunction(callback)) {
527
+ return (callback(...arguments)).then(() => {
528
+ $observer.trigger();
529
+ }).catch(error => { throw error; });
530
+ }
531
+ callback(...arguments);
532
+ $observer.trigger();
533
+ };
534
+ batch.$observer = $observer;
535
+ return batch;
536
+ };
537
+
507
538
  /**
508
539
  *
509
540
  * @param id
@@ -891,7 +922,7 @@ var NativeDocument = (function (exports) {
891
922
  if(Validator.isElement(child)) {
892
923
  return child;
893
924
  }
894
- return createTextNode(String(child))
925
+ return createTextNode(child)
895
926
  };
896
927
 
897
928
  function Anchor(name) {
@@ -1916,6 +1947,7 @@ var NativeDocument = (function (exports) {
1916
1947
  Menu: Menu,
1917
1948
  Meter: Meter,
1918
1949
  MonthInput: MonthInput,
1950
+ NativeDocumentFragment: Anchor,
1919
1951
  Nav: Nav,
1920
1952
  NumberInput: NumberInput,
1921
1953
  Option: Option,
@@ -1 +1 @@
1
- var NativeDocument=function(t){"use strict";function n(e,t,n){return e.addEventListener(t,n),e}const r={enabled:!1,enable(){this.enabled=!0,console.log("๐Ÿ” NativeDocument Debug Mode enabled")},disable(){this.enabled=!1},log(e,t,n){this.enabled&&(console.group(`๐Ÿ” [${e}] ${t}`),n&&console.log(n),console.trace(),console.groupEnd())},warn(e,t,n){this.enabled&&console.warn(`โš ๏ธ [${e}] ${t}`,n)},error(e,t,n){console.error(`โŒ [${e}] ${t}`,n)}},o=function(){let e=0;const t=new Map;let n=null;try{n=new FinalizationRegistry(e=>{r.log("MemoryManager","๐Ÿงน Auto-cleanup observable:",e),e.listeners.splice(0)})}catch(e){r.warn("MemoryManager","FinalizationRegistry not supported, observables will not be cleaned automatically")}return{register(r,o){const s=++e,i={id:s,listeners:o};return n&&n.register(r,i),t.set(s,new WeakRef(r)),s},getObservableById:e=>t.get(e)?.deref(),cleanup(){for(const[e,n]of t){const e=n.deref();e&&e.cleanup()}t.clear()},cleanObservables(e){if(t.size<e)return;let n=0;for(const[e,r]of t)r.deref()||(t.delete(e),n++);n>0&&r.log("Memory Auto Clean",`๐Ÿงน Cleaned ${n} orphaned observables`)}}}();class s extends Error{constructor(e,t={}){super(e),this.name="NativeDocumentError",this.context=t,this.timestamp=(new Date).toISOString()}}function i(e,t){this.observable=e,this.checker=t,this.subscribe=function(n){return e.subscribe(e=>{n&&n(t(e))})},this.val=function(){return t&&t(e.val())},this.check=function(t){return e.check(()=>t(this.val()))},this.set=function(t){return e.set(t)},this.trigger=function(){return e.trigger()},this.cleanup=function(){return e.cleanup()}}function a(e){if(void 0===e)throw new s("ObservableItem requires an initial value");if(e instanceof a)throw new s("ObservableItem cannot be an Observable");const t="object"==typeof e?JSON.parse(JSON.stringify(e)):e;let n=e,u=e,c=!1;const l=[],d=o.register(this,l);this.trigger=()=>{l.forEach(e=>{try{e(u,n)}catch(t){r.error("Listener Undefined","Error in observable listener:",t),this.unsubscribe(e)}})},this.originalValue=()=>t,this.set=e=>{const t="function"==typeof e?e(u):e;u!==t&&(n=u,u=t,this.trigger())},this.val=()=>u,this.cleanup=function(){l.splice(0),c=!0},this.subscribe=e=>{if(c)return r.warn("Observable subscription","โš ๏ธ Attempted to subscribe to a cleaned up observable."),()=>{};if("function"!=typeof e)throw new s("Callback must be a function");return l.push(e),()=>this.unsubscribe(e)},this.unsubscribe=e=>{const t=l.indexOf(e);t>-1&&l.splice(t,1)},this.check=function(e){return new i(this,e)};const p=this;Object.defineProperty(p,"$value",{get:()=>p.val(),set:e=>(p.set(e),p)}),this.toString=function(){return"{{#ObItem::("+d+")}}"}}const u={isObservable:e=>e instanceof a||e instanceof i,isProxy:e=>e?.__isProxy__,isObservableChecker:e=>e instanceof i,isArray:e=>Array.isArray(e),isString:e=>"string"==typeof e,isNumber:e=>"number"==typeof e,isBoolean:e=>"boolean"==typeof e,isFunction:e=>"function"==typeof e,isObject:e=>"object"==typeof e,isJson:e=>"object"==typeof e&&null!==e&&"Object"===e.constructor.name&&!Array.isArray(e),isElement:e=>e instanceof HTMLElement||e instanceof DocumentFragment||e instanceof Text,isFragment:e=>e instanceof DocumentFragment,isStringOrObservable(e){return this.isString(e)||this.isObservable(e)},isValidChild(e){return null===e||this.isElement(e)||this.isObservable(e)||["string","number","boolean"].includes(typeof e)},isValidChildren(e){Array.isArray(e)||(e=[e]);return 0===e.filter(e=>!this.isValidChild(e)).length},validateChildren(e){Array.isArray(e)||(e=[e]);const t=e.filter(e=>!this.isValidChild(e));if(t.length>0)throw new s(`Invalid children detected: ${t.map(e=>typeof e).join(", ")}`);return e},containsObservables:e=>!!e&&(u.isObject(e)&&Object.values(e).some(e=>u.isObservable(e))),containsObservableReference:e=>!(!e||"string"!=typeof e)&&/\{\{#ObItem::\([0-9]+\)\}\}/.test(e),validateAttributes(e){if(!e||"object"!=typeof e)return e;const t=[],n=Object.keys(e).filter(e=>t.includes(e));return n.length>0&&r.warn("Validator",`Reserved attributes found: ${n.join(", ")}`),e},validateEventCallback(e){if("function"!=typeof e)throw new s("Event callback must be a function")}},c=["checked","selected","disabled","readonly","required","autofocus","multiple","autocomplete","hidden","contenteditable","spellcheck","translate","draggable","async","defer","autoplay","controls","loop","muted","download","reversed","open","default","formnovalidate","novalidate","scoped","itemscope","allowfullscreen","allowpaymentrequest","playsinline"],l=function(e,t,n={}){let r=null,o=0;const{leading:s=!0,trailing:i=!0,debounce:a=!1}=n;return function(...n){const u=Date.now();if(a)return clearTimeout(r),void(r=setTimeout(()=>e.apply(this,n),t));s&&u-o>=t&&(e.apply(this,n),o=u),i&&!r&&(r=setTimeout(()=>{e.apply(this,n),o=Date.now(),r=null},t-(u-o)))}},d=function(e,t){return e.replace(new RegExp(`^[${t}]+|[${t}]+$`,"g"),"")};function p(e){return new a(e)}p.computed=function(e,t=[]){const n=new a(e()),r=()=>n.set(e());return t.forEach(e=>e.subscribe(r)),n},p.getById=function(e){const t=o.getObservableById(parseInt(e));if(!t)throw new s("Observable.getById : No observable found with id "+e);return t},p.cleanup=function(e){e.cleanup()},p.value=function(e){if(u.isObservable(e))return e.val();if(u.isProxy(e))return e.$val();if(u.isArray(e)){const t=[];return e.forEach(e=>{t.push(p.value(e))}),t}return e},p.init=function(e){const t={};for(const n in e){const r=e[n];u.isJson(r)?t[n]=p.init(r):u.isArray(r)?t[n]=p.array(r):t[n]=p(r)}const n=function(){const e={};for(const n in t){const r=t[n];u.isObservable(r)?e[n]=r.val():u.isProxy(r)?e[n]=r.$val():e[n]=r}return e},r=function(){};return new Proxy(t,{get:(e,t)=>"__isProxy__"===t||("$val"===t?n:"$clone"===t?r:void 0!==e[t]?e[t]:void 0),set(e,t,n){void 0!==e[t]&&e[t].set(n)}})},p.object=p.init,p.json=p.init,p.update=function(e,t){for(const n in t){const r=e[n],o=t[n];if(u.isObservable(r)){if(u.isArray(o)){p.update(r,o);continue}r.set(o)}else u.isProxy(r)?p.update(r,o):e[n]=o}},p.array=function(e){if(!Array.isArray(e))throw new s("Observable.array : target must be an array");const t=p(e);["push","pop","shift","unshift","reverse","sort","splice"].forEach(e=>{t[e]=function(...n){const r=t.val(),o=r[e].apply(r,arguments);return t.trigger(),o}});return["map","filter","reduce","some","every","find"].forEach(e=>{t[e]=function(n){return t.val()[e](n)}}),t},p.autoCleanup=function(e=!1,t={}){if(!e)return;const{interval:n=6e4,threshold:r=100}=t;window.addEventListener("beforeunload",()=>{o.cleanup()}),setInterval(()=>o.cleanObservables(r),n)};const h=function(e,t,n){n?e.classList.add(t):e.classList.remove(t)};function f(e,t){for(let n in t){const r=t[n];u.isObservable(r)?(h(e,n,r.val()),r.subscribe(t=>h(e,n,t))):h(e,n,r)}}function b(e,t){for(let n in t){const r=t[n];u.isObservable(r)?(e.style[n]=r.val(),r.subscribe(t=>{e.style[n]=t})):e.style[n]=r}}function m(e,t,n){const r=u.isObservable(n)?n.val():n;u.isBoolean(r)?e[t]=r:e[t]=r===e.value,u.isObservable(n)&&(["checked"].includes(t)&&e.addEventListener("input",()=>{u.isBoolean(r)?n.set(e[t]):n.set(e.value)}),n.subscribe(n=>{u.isBoolean(n)?e[t]=n:e[t]=n===e.value}))}function v(e,t,n){const r=n=>{"value"!==t?e.setAttribute(t,n):e.value=n};n.subscribe(r),r(n.val()),"value"===t&&e.addEventListener("input",()=>n.set(e.value))}const y={elements:new Map,observer:null,checkMutation:l(function(){for(const[e,t]of y.elements.entries()){const n=document.body.contains(e);n&&!t.inDom?(t.inDom=!0,t.mounted.forEach(t=>t(e))):!n&&t.inDom&&(t.inDom=!1,t.unmounted.forEach(t=>t(e)))}},10,{debounce:!0}),watch:function(e){let t={};if(y.elements.has(e))t=y.elements.get(e);else{const n=document.body.contains(e);t={inDom:n,mounted:new Set,unmounted:new Set},y.elements.set(e,t)}return{watch:()=>y.elements.set(e,t),disconnect:()=>y.elements.delete(e),mounted:e=>t.mounted.add(e),unmounted:e=>t.unmounted.add(e)}}};y.observer=new MutationObserver(y.checkMutation),y.observer.observe(document.body,{childList:!0,subtree:!0});const g=e=>u.isFunction(e)?g(e()):u.isElement(e)?e:S(String(e));function w(e){const t=document.createDocumentFragment(),n=document.createComment("Anchor Start : "+e),o=document.createComment("/ Anchor End "+e);t.appendChild(n),t.appendChild(o),t.nativeInsertBefore=t.insertBefore,t.nativeAppendChild=t.appendChild;const s=function(e,n,r){e!==t?e.insertBefore(g(n),r):e.nativeInsertBefore(g(n),r)};return t.appendChild=function(e,n=null){const i=o.parentNode;if(i){if(n=n??o,u.isArray(e))return e.forEach(e=>{s(i,e,n)}),t;s(i,e,n)}else r.error("Anchor","Anchor : parent not found",e)},t.remove=function(e){if(o.parentNode===t)return;let r,s=n.nextSibling;for(;s!==o;)r=s.nextSibling,e?s.remove():t.nativeAppendChild(s),s=r;e&&(o.remove(),n.remove())},t.insertBefore=function(e,n=null){t.appendChild(e,n)},t.clear=function(){t.remove()},t.endElement=function(){return o},t.startElement=function(){return n},t}const O=function(){const e=[];return{list:()=>e,add:t=>e.push(t)}}(),C=function(e,t){const n=document.createTextNode("");return t.subscribe(e=>n.textContent=String(e)),n.textContent=t.val(),e&&e.appendChild(n),n},E=function(e,t){const n=document.createTextNode("");return n.textContent=String(t),e&&e.appendChild(n),n},S=function(e){return u.isObservable(e)?C(null,e):E(null,e)},A={createElement:e=>e?document.createElement(e):new w("Fragment"),processChildren(e,t){if(null===e)return;(Array.isArray(e)?e:[e]).forEach(e=>{null!==e&&(u.isString(e)&&u.isFunction(e.resolveObservableTemplate)&&(e=e.resolveObservableTemplate()),u.isFunction(e)?this.processChildren(e(),t):u.isArray(e)?this.processChildren(e,t):u.isElement(e)?t.appendChild(e):u.isObservable(e)?C(t,e):e&&E(t,e))})},processAttributes(e,t){u.isFragment(e)||t&&function(e,t){if(u.validateAttributes(t),!u.isObject(t))throw new s("Attributes must be an object");for(let n in t){const r=n.toLowerCase();let o=t[r];if(u.isString(o)&&u.isFunction(o.resolveObservableTemplate)&&(o=o.resolveObservableTemplate(),u.isArray(o))){const e=o.filter(e=>u.isObservable(e));o=p.computed(()=>o.map(e=>u.isObservable(e)?e.val():e).join(" ")||" ",e)}c.includes(r)?m(e,r,o):u.isObservable(o)?v(e,r,o):"class"===r&&u.isJson(o)?f(e,o):"style"===r&&u.isJson(o)?b(e,o):e.setAttribute(r,o)}}(e,t)},setup(e,t,r){e.nd={},function(e){e.nd||(e.nd={}),e.nd.on=function(t){for(const r in t){const o=t[r];n(e,r,o)}return e},e.nd.on.prevent=function(t){for(const r in t){const o=t[r];n(e,r,t=>(t.preventDefault(),o&&o(t),e))}return e};const t={click:t=>n(e,"click",t),focus:t=>n(e,"focus",t),blur:t=>n(e,"blur",t),input:t=>n(e,"input",t),change:t=>n(e,"change",t),keyup:t=>n(e,"keyup",t),keydown:t=>n(e,"keydown",t),beforeInput:t=>n(e,"beforeinput",t),mouseOver:t=>n(e,"mouseover",t),mouseOut:t=>n(e,"mouseout",t),mouseDown:t=>n(e,"mousedown",t),mouseUp:t=>n(e,"mouseup",t),mouseMove:t=>n(e,"mousemove",t),hover:(t,n)=>{e.addEventListener("mouseover",t),e.addEventListener("mouseout",n)},dropped:t=>n(e,"drop",t),submit:t=>n(e,"submit",t),dragEnd:t=>n(e,"dragend",t),dragStart:t=>n(e,"dragstart",t),drop:t=>n(e,"drop",t),dragOver:t=>n(e,"dragover",t),dragEnter:t=>n(e,"dragenter",t),dragLeave:t=>n(e,"dragleave",t)};for(let r in t)e.nd.on[r]=t[r],e.nd.on.prevent[r]=function(t){return n(e,r.toLowerCase(),e=>{e.preventDefault(),t&&t(e)}),e}}(e);const o="function"==typeof r?r(e):e;return function(e){e.nd.wrap=t=>{if(!u.isFunction(t))throw new s("Callback must be a function");return t&&t(e),e},e.nd.ref=(t,n)=>(t[n]=e,e);let t=null;e.nd.appendChild=function(t){u.isArray(t)?A.processChildren(t,e):(u.isFunction(t)&&(t=t(),A.processChildren(t(),e)),u.isElement(t)&&A.processChildren(t,e))},e.nd.lifecycle=function(n){return t=t||y.watch(e),n.mounted&&t.mounted(n.mounted),n.unmounted&&t.unmounted(n.unmounted),e},e.nd.mounted=n=>(t=t||y.watch(e),t.mounted(n),e),e.nd.unmounted=n=>(t=t||y.watch(e),t.unmounted(n),e)}(o),O.list().forEach(e=>{e?.element?.setup&&e.element.setup(o,t)}),o}};function I(e,t){const n=e.toLowerCase().trim(),o=function(e,o=null){try{if(u.isValidChildren(e)){const t=o;o=e,e=t}const r=A.createElement(n);return A.processAttributes(r,e),A.processChildren(o,r),A.setup(r,e,t)}catch(e){r.error("ElementCreation",`Error creating ${n}`,e)}};return o.hold=(e,t)=>()=>o(e,t),o}class k extends Error{constructor(e,t){super(`${e}\n\n${t.join("\n")}\n\n`)}}const $={string:e=>({name:e,type:"string",validate:e=>u.isString(e)}),number:e=>({name:e,type:"number",validate:e=>u.isNumber(e)}),boolean:e=>({name:e,type:"boolean",validate:e=>u.isBoolean(e)}),observable:e=>({name:e,type:"observable",validate:e=>u.isObservable(e)}),element:e=>({name:e,type:"element",validate:e=>u.isElement(e)}),function:e=>({name:e,type:"function",validate:e=>u.isFunction(e)}),object:e=>({name:e,type:"object",validate:e=>u.isObject(e)}),objectNotNull:e=>({name:e,type:"object",validate:e=>u.isObject(e)&&null!==e}),children:e=>({name:e,type:"children",validate:e=>u.validateChildren(e)}),attributes:e=>({name:e,type:"attributes",validate:e=>u.validateAttributes(e)}),optional:e=>({...e,optional:!0}),oneOf:(e,...t)=>({name:e,type:"oneOf",types:t,validate:e=>t.some(t=>t.validate(e))})},R=(e,t,n="Function")=>{if(!u.isArray(t))throw new s("withValidation : argSchema must be an array");return function(...r){return((e,t,n="Function")=>{if(!t)return;const r=[],o=t.filter(e=>!e.optional).length;if(e.length<o&&r.push(`${n}: Expected at least ${o} arguments, got ${e.length}`),t.forEach((t,o)=>{const s=o+1,i=e[o];if(void 0!==i){if(!t.validate(i)){const e=i?.constructor?.name||typeof i;r.push(`${n}: Invalid argument '${t.name}' at position ${s}, expected ${t.type}, got ${e}`)}}else t.optional||r.push(`${n}: Missing required argument '${t.name}' at position ${s}`)}),r.length>0)throw new k("Argument validation failed",r)})(r,t,e.name||n),e.apply(this,r)}};Function.prototype.args=function(...e){return R(this,e)},Function.prototype.errorBoundary=function(e){return(...t)=>{try{return this.apply(this,t)}catch(t){return e(t)}}},String.prototype.use=function(e){const t=this;return p.computed(()=>t.replace(/\$\{(.*?)}/g,(t,n)=>{const r=e[n];return u.isObservable(r)?r.val():r}),Object.values(e))},String.prototype.resolveObservableTemplate=function(){return u.containsObservableReference(this)?this.split(/(\{\{#ObItem::\([0-9]+\)\}\})/g).filter(Boolean).map(e=>{if(!u.containsObservableReference(e))return e;const[t,n]=e.match(/\{\{#ObItem::\(([0-9]+)\)\}\}/);return p.getById(n)}):this};const F=function(){const e=new Map;return{use(t){const{observer:n,subscribers:r}=e.get(t),o=p(n.val()),s=n.subscribe(e=>o.set(e)),i=o.subscribe(e=>n.set(e));return o.destroy=()=>{s(),i(),o.cleanup()},r.add(o),o},follow(e){return this.use(e)},create(t,n){const r=p(n);return e.set(t,{observer:r,subscribers:new Set}),r},get(t){const n=e.get(t);return n?n.observer:null},getWithSubscribers:t=>e.get(t),delete(t){const n=e.get(t);n&&(n.observer.cleanup(),n.subscribers.forEach(e=>e.destroy()),n.observer.clear())}}}();const q=function(e,t,n=null){if(!u.isObservable(e))return r.warn("ShowIf","ShowIf : condition must be an Observable / "+n,e);const o=new w("Show if : "+(n||""));let s=null;const i=()=>s||(s="function"==typeof t?t():t,u.isStringOrObservable(s)&&(s=S(s)),s);return e.val()&&o.appendChild(i()),e.subscribe(e=>{e?o.appendChild(i()):o.remove()}),o},x=function(e,t){if(!u.isObservable(e))throw new s("Toggle : condition must be an Observable");const n=new w,r=new Map,o=function(e){if(r.has(e))return r.get(e);let n=t[e];return n?(u.isFunction(n)&&(n=n()),r.set(e,n),n):null},i=e.val(),a=o(i);return a&&n.appendChild(a),e.subscribe(e=>{const t=o(e);n.remove(),t&&n.appendChild(t)}),n},T=function(e,t,n){if(!u.isObservable(e))throw new s("Toggle : condition must be an Observable");return x(e,{true:t,false:n})},D=I("div"),j=I("span"),L=I("label"),B=I("p"),M=B,H=I("strong"),P=I("h1"),N=I("h2"),_=I("h3"),V=I("h4"),U=I("h5"),z=I("h6"),J=I("br"),W=I("a"),K=I("pre"),Q=I("code"),G=I("blockquote"),X=I("hr"),Y=I("em"),Z=I("small"),ee=I("mark"),te=I("del"),ne=I("ins"),re=I("sub"),oe=I("sup"),se=I("abbr"),ie=I("cite"),ae=I("q"),ue=I("dl"),ce=I("dt"),le=I("dd"),de=I("form",function(e){return e.submit=function(t){return"function"==typeof t?(e.on.submit(e=>{e.preventDefault(),t(e)}),e):(this.setAttribute("action",t),e)},e.multipartFormData=function(){return this.setAttribute("enctype","multipart/form-data"),e},e.post=function(t){return this.setAttribute("method","post"),this.setAttribute("action",t),e},e.get=function(e){this.setAttribute("method","get"),this.setAttribute("action",e)},e}),pe=I("input"),he=I("textarea"),fe=he,be=I("select"),me=I("fieldset"),ve=I("option"),ye=I("legend"),ge=I("datalist"),we=I("output"),Oe=I("progress"),Ce=I("meter"),Ee=I("button"),Se=I("main"),Ae=I("section"),Ie=I("article"),ke=I("aside"),$e=I("nav"),Re=I("figure"),Fe=I("figcaption"),qe=I("header"),xe=I("footer"),Te=I("img"),De=function(e,t){return Te({src:e,...t})},je=I("details"),Le=I("summary"),Be=I("dialog"),Me=I("menu"),He=I("ol"),Pe=I("ul"),Ne=I("li"),_e=I("audio"),Ve=I("video"),Ue=I("source"),ze=I("track"),Je=I("canvas"),We=I("svg"),Ke=I("time"),Qe=I("data"),Ge=I("address"),Xe=I("kbd"),Ye=I("samp"),Ze=I("var"),et=I("wbr"),tt=I("caption"),nt=I("table"),rt=I("thead"),ot=I("tfoot"),st=I("tbody"),it=I("tr"),at=it,ut=I("th"),ct=ut,lt=ut,dt=I("td"),pt=dt,ht=I("");var ft=Object.freeze({__proto__:null,Abbr:se,Address:Ge,Anchor:w,Article:Ie,Aside:ke,AsyncImg:function(e,t,n,r){const o=De(t||e,n),i=new Image;return i.onload=()=>{u.isFunction(r)&&r(null,o),o.src=e},i.onerror=()=>{u.isFunction(r)&&r(new s("Image not found"))},u.isObservable(e)&&e.subscribe(e=>{i.src=e}),i.src=e,o},Audio:_e,BaseImage:Te,Blockquote:G,Br:J,Button:Ee,Canvas:Je,Caption:tt,Checkbox:e=>pe({type:"checkbox",...e}),Cite:ie,Code:Q,ColorInput:e=>pe({type:"color",...e}),Data:Qe,Datalist:ge,DateInput:e=>pe({type:"date",...e}),DateTimeInput:e=>pe({type:"datetime-local",...e}),Dd:le,Del:te,Details:je,Dialog:Be,Div:D,Dl:ue,Dt:ce,Em:Y,EmailInput:e=>pe({type:"email",...e}),FieldSet:me,FigCaption:Fe,Figure:Re,FileInput:e=>pe({type:"file",...e}),Footer:xe,ForEach:function(e,t,n){const r=new w("ForEach"),o=r.endElement();let s=new Map;const i=(e,r)=>{const o=((e,t,n)=>{if(u.isFunction(n))return n(e,t);if(u.isObservable(e)){const r=e.val();return r&&n?r[n]:t}return e[n]??t})(e,r,n);if(s.has(o))s.get(o).indexObserver.set(r);else{const n=p(r);let i=t(e,n);u.isStringOrObservable(i)&&(i=S(i)),s.set(o,{child:i,indexObserver:n})}return o},a=new Set,c=()=>{const t=u.isObservable(e)?e.val():e,n=o.parentNode;if(!n)return;if(a.clear(),Array.isArray(t))t.forEach((e,t)=>a.add(i(e,t)));else for(const e in t)a.add(i(t[e],e));((e,t)=>{for(const[n,{child:r}]of e.entries())t.has(n)||r.remove()})(s,a);let r=o;for(const e of[...a].reverse()){const{child:t}=s.get(e);if(t){if(r&&r.previousSibling===t){r=t;continue}n.insertBefore(t,r),r=t}}};return c(),u.isObservable(e)&&e.subscribe(l((e,t)=>{c()},50,{debounce:!0})),r},Form:de,Fragment:ht,H1:P,H2:N,H3:_,H4:V,H5:U,H6:z,Header:qe,HiddenInput:e=>pe({type:"hidden",...e}),HideIf:function(e,t,n){const r=p(!e.val());return e.subscribe(e=>r.set(!e)),q(r,t,n)},HideIfNot:function(e,t,n){return q(e,t,n)},Hr:X,Img:De,Input:pe,Ins:ne,Kbd:Xe,Label:L,LazyImg:function(e,t){return De(e,{...t,loading:"lazy"})},Legend:ye,Link:W,ListItem:Ne,Main:Se,Mark:ee,Match:x,Menu:Me,Meter:Ce,MonthInput:e=>pe({type:"month",...e}),Nav:$e,NumberInput:e=>pe({type:"number",...e}),Option:ve,OrderedList:He,Output:we,P:B,Paragraph:M,PasswordInput:e=>pe({type:"password",...e}),Pre:K,Progress:Oe,Quote:ae,Radio:e=>pe({type:"radio",...e}),RangeInput:e=>pe({type:"range",...e}),ReadonlyInput:e=>pe({readonly:!0,...e}),Samp:Ye,SearchInput:e=>pe({type:"search",...e}),Section:Ae,Select:be,ShowIf:q,SimpleButton:(e,t)=>Ee(e,{type:"button",...t}),Small:Z,Source:Ue,Span:j,Strong:H,Sub:re,SubmitButton:(e,t)=>Ee(e,{type:"submit",...t}),Summary:Le,Sup:oe,Svg:We,Switch:T,TBody:st,TBodyCell:pt,TFoot:ot,TFootCell:lt,THead:rt,THeadCell:ct,TRow:at,Table:nt,Td:dt,TelInput:e=>pe({type:"tel",...e}),TextArea:he,TextInput:fe,Th:ut,Time:Ke,TimeInput:e=>pe({type:"time",...e}),Tr:it,Track:ze,UnorderedList:Pe,UrlInput:e=>pe({type:"url",...e}),Var:Ze,Video:Ve,Wbr:et,WeekInput:e=>pe({type:"week",...e}),When:function(e){if(!u.isObservable(e))throw new s("When : condition must be an Observable");let t=null,n=null;return{show(e){return t=e,this},otherwise:r=>(n=r,T(e,t,n))}}});const bt={};function mt(e,t,n={}){e="/"+d(e,"/");let r=null,o=n.name||null;const s=n.middlewares||[],i=n.shouldRebuild||!1,a=n.with||{},u={},c=[],l=e=>{if(!e)return null;const[t,n]=e.split(":");let r=a[t];return!r&&n&&(r=bt[n]),r||(r="[^/]+"),r=r.replace("(","(?:"),{name:t,pattern:`(${r})`}},p=()=>{if(r)return r;const t=e.replace(/\{(.*?)}/gi,(e,t)=>{const n=l(t);return n&&n.pattern?(u[n.name]=n.pattern,c.push(n.name),n.pattern):e});return r=new RegExp("^"+t+"$"),r};this.name=()=>o,this.component=()=>t,this.middlewares=()=>s,this.shouldRebuild=()=>i,this.path=()=>e,this.match=function(e){e="/"+d(e,"/");if(!p().exec(e))return!1;const t={};return p().exec(e).forEach((e,n)=>{if(n<1)return;const r=c[n-1];t[r]=e}),t},this.url=function(t){const n=e.replace(/\{(.*?)}/gi,(e,n)=>{const r=l(n);if(t.params&&t.params[r.name])return t.params[r.name];throw new Error(`Missing parameter '${r.name}'`)}),r="object"==typeof t.query?new URLSearchParams(t.query).toString():null;return(t.basePath?t.basePath:"")+(r?`${n}?${r}`:n)}}class vt extends Error{constructor(e,t){super(e),this.context=t}}const yt=(e,t)=>{const n=[];return e.forEach(e=>{n.push(d(e.suffix,"/"))}),n.push(d(t,"/")),n.join("/")},gt=(e,t)=>{const n=[];return e.forEach(e=>{e.options.middlewares&&n.push(...e.options.middlewares)}),t&&n.push(...t),n},wt=(e,t)=>{const n=[];return e.forEach(e=>{e.options?.name&&n.push(e.options.name)}),t&&n.push(t),n.join(".")};function Ot(){const e=[];let t=0;const n=n=>{const o=t+n;if(!e[o])return;t=o;const{route:s,params:i,query:a,path:u}=e[o];r(u)},r=e=>{window.location.replace(`${window.location.pathname}${window.location.search}#${e}`)},o=()=>window.location.hash.slice(1);this.push=function(n){const{route:s,params:i,query:a,path:u}=this.resolve(n);u!==o()&&(e.splice(t+1),e.push({route:s,params:i,query:a,path:u}),t++,r(u))},this.replace=function(n){const{route:r,params:s,query:i,path:a}=this.resolve(n);a!==o()&&(e[t]={route:r,params:s,query:i,path:a})},this.forward=function(){return t<e.length-1&&n(1)},this.back=function(){return t>0&&n(-1)},this.init=function(n){window.addEventListener("hashchange",()=>{const{route:e,params:t,query:n,path:r}=this.resolve(o());this.handleRouteChange(e,t,n,r)});const{route:r,params:s,query:i,path:a}=this.resolve(n||o());e.push({route:r,params:s,query:i,path:a}),t=0,this.handleRouteChange(r,s,i,a)}}function Ct(){this.push=function(e){try{const{route:t,path:n,params:r,query:o}=this.resolve(e);if(window.history.state&&window.history.state.path===n)return;window.history.pushState({name:t.name(),params:r,path:n},t.name()||n,n),this.handleRouteChange(t,r,o,n)}catch(e){r.error("HistoryRouter","Error in pushState",e)}},this.replace=function(e){const{route:t,path:n,params:o}=this.resolve(e);try{window.history.replaceState({name:t.name(),params:o,path:n},t.name()||n,n),this.handleRouteChange(t,o,{},n)}catch(e){r.error("HistoryRouter","Error in replaceState",e)}},this.forward=function(){window.history.forward()},this.back=function(){window.history.back()},this.init=function(e){window.addEventListener("popstate",e=>{try{if(!e.state||!e.state.path)return;const t=e.state.path,{route:n,params:r,query:o,path:s}=this.resolve(t);if(!n)return;this.handleRouteChange(n,r,o,s)}catch(e){r.error("HistoryRouter","Error in popstate event",e)}});const{route:t,params:n,query:o,path:s}=this.resolve(e||window.location.pathname+window.location.search);this.handleRouteChange(t,n,o,s)}}function Et(){const e=[];let t=0;const n=n=>{const r=t+n;if(!e[r])return;t=r;const{route:o,params:s,query:i,path:a}=e[r];this.handleRouteChange(o,s,i,a)};this.push=function(n){const{route:r,params:o,query:s,path:i}=this.resolve(n);e[t]&&e[t].path===i||(e.splice(t+1),e.push({route:r,params:o,query:s,path:i}),t++,this.handleRouteChange(r,o,s,i))},this.replace=function(n){const{route:r,params:o,query:s,path:i}=this.resolve(n);e[t]={route:r,params:o,query:s,path:i},this.handleRouteChange(r,o,s,i)},this.forward=function(){return t<e.length-1&&n(1)},this.back=function(){return t>0&&n(-1)},this.init=function(n){const r=n||window.location.pathname+window.location.search,{route:o,params:s,query:i,path:a}=this.resolve(r);e.push({route:o,params:s,query:i,path:a}),t=0,this.handleRouteChange(o,s,i,a)}}const St="default";function At(e={}){const t=[],n={},o=[],s=[],i={route:null,params:null,query:null,path:null,hash:null};if("hash"===e.mode)Ot.apply(this,[]);else if("history"===e.mode)Ct.apply(this,[]);else{if("memory"!==e.mode)throw new vt("Invalid router mode "+e.mode);Et.apply(this,[])}const a=function(e,t){for(const n of s)try{n(e),t&&t(e)}catch(e){r.warn("Route Listener","Error in listener:",e)}};this.routes=()=>[...t],this.currentState=()=>({...i}),this.add=function(e,r,s){const i=new mt(yt(o,e),r,{...s,middlewares:gt(o,s?.middlewares||[]),name:s?.name?wt(o,s.name):null});return t.push(i),i.name()&&(n[i.name()]=i),this},this.group=function(e,t,n){if(!u.isFunction(n))throw new vt("Callback must be a function");return o.push({suffix:e,options:t}),n(),o.pop(),this},this.generateUrl=function(e,t={},r={}){const o=n[e];if(!o)throw new vt(`Route not found for name: ${e}`);return o.url({params:t,query:r})},this.resolve=function(e){if(u.isJson(e)){const t=n[e.name];if(!t)throw new vt(`Route not found for name: ${e.name}`);return{route:t,params:e.params,query:e.query,path:t.url({...e})}}const[r,o]=e.split("?"),s="/"+d(r,"/");let i,a=null;for(const e of t)if(i=e.match(s),i){a=e;break}if(!a)throw new vt(`Route not found for url: ${r}`);const c={};if(o){const e=new URLSearchParams(o).entries();for(const[t,n]of e)c[t]=n}return{route:a,params:i,query:c,path:e}},this.subscribe=function(e){if(!u.isFunction(e))throw new vt("Listener must be a function");return s.push(e),()=>{s.splice(s.indexOf(e),1)}},this.handleRouteChange=function(e,t,n,r){i.route=e,i.params=t,i.query=n,i.path=r;const o=[...e.middlewares(),a];let s=0;const u={...i},c=e=>{if(s++,!(s>=o.length))return o[s](e||u,c)};return o[s](u,c)}}function It(e,t){const{to:n,href:r,...o}=e,s=n||r;if(u.isString(s)){const e=At.get();return W({...o,href:s},t).nd.on.prevent.click(()=>{e.push(s)})}const i=s.router||St,a=At.get(i);if(console.log(i),!a)throw new vt('Router not found "'+i+'" for link "'+s.name+'"');const c=a.generateUrl(s.name,s.params,s.query);return W({...o,href:c},t).nd.on.prevent.click(()=>{a.push(c)})}At.routers={},At.create=function(t,n){if(!u.isFunction(n))throw r.error("Router","Callback must be a function",e),new vt("Callback must be a function");const o=new At(t);return At.routers[t.name||St]=o,n(o),o.init(t.entry),o.mount=function(e){if(u.isString(e)){const t=document.querySelector(e);if(!t)throw new vt(`Container not found for selector: ${e}`);e=t}else if(!u.isElement(e))throw new vt("Container must be a string or an Element");return function(e,t){const n=new Map,r=function(e){t.innerHTML="",t.appendChild(e)},o=function(e){if(!e.route)return;const{route:t,params:o,query:s,path:i}=e;if(n.has(i)){const e=n.get(i);return void r(e)}const a=t.component()({params:o,query:s});n.set(i,a),r(a)};return e.subscribe(o),o(e.currentState()),t}(o,e)},o},At.get=function(e){const t=At.routers[e||St];if(!t)throw new vt(`Router not found for name: ${e}`);return t},At.push=function(e,t=null){return At.get(t).push(e)},At.replace=function(e,t=null){return At.get(t).replace(e)},At.forward=function(e=null){return At.get(e).forward()},At.back=function(e=null){return At.get(e).back()},It.blank=function(e,t){return W({...e,target:"_blank"},t)};var kt=Object.freeze({__proto__:null,Link:It,RouteParamPatterns:bt,Router:At});return t.ArgTypes=$,t.ElementCreator=A,t.HtmlElementWrapper=I,t.Observable=p,t.Store=F,t.elements=ft,t.router=kt,t.withValidation=R,t}({});
1
+ var NativeDocument=function(t){"use strict";function n(e,t,n){return e.addEventListener(t,n),e}const r={enabled:!1,enable(){this.enabled=!0,console.log("๐Ÿ” NativeDocument Debug Mode enabled")},disable(){this.enabled=!1},log(e,t,n){this.enabled&&(console.group(`๐Ÿ” [${e}] ${t}`),n&&console.log(n),console.trace(),console.groupEnd())},warn(e,t,n){this.enabled&&console.warn(`โš ๏ธ [${e}] ${t}`,n)},error(e,t,n){console.error(`โŒ [${e}] ${t}`,n)}},o=function(){let e=0;const t=new Map;let n=null;try{n=new FinalizationRegistry(e=>{r.log("MemoryManager","๐Ÿงน Auto-cleanup observable:",e),e.listeners.splice(0)})}catch(e){r.warn("MemoryManager","FinalizationRegistry not supported, observables will not be cleaned automatically")}return{register(r,o){const s=++e,i={id:s,listeners:o};return n&&n.register(r,i),t.set(s,new WeakRef(r)),s},getObservableById:e=>t.get(e)?.deref(),cleanup(){for(const[e,n]of t){const e=n.deref();e&&e.cleanup()}t.clear()},cleanObservables(e){if(t.size<e)return;let n=0;for(const[e,r]of t)r.deref()||(t.delete(e),n++);n>0&&r.log("Memory Auto Clean",`๐Ÿงน Cleaned ${n} orphaned observables`)}}}();class s extends Error{constructor(e,t={}){super(e),this.name="NativeDocumentError",this.context=t,this.timestamp=(new Date).toISOString()}}function i(e,t){this.observable=e,this.checker=t,this.subscribe=function(n){return e.subscribe(e=>{n&&n(t(e))})},this.val=function(){return t&&t(e.val())},this.check=function(t){return e.check(()=>t(this.val()))},this.set=function(t){return e.set(t)},this.trigger=function(){return e.trigger()},this.cleanup=function(){return e.cleanup()}}function a(e){if(void 0===e)throw new s("ObservableItem requires an initial value");if(e instanceof a)throw new s("ObservableItem cannot be an Observable");const t="object"==typeof e?JSON.parse(JSON.stringify(e)):e;let n=e,u=e,c=!1;const l=[],d=o.register(this,l);this.trigger=()=>{l.forEach(e=>{try{e(u,n)}catch(t){r.error("Listener Undefined","Error in observable listener:",t),this.unsubscribe(e)}})},this.originalValue=()=>t,this.set=e=>{const t="function"==typeof e?e(u):e;u!==t&&(n=u,u=t,this.trigger())},this.val=()=>u,this.cleanup=function(){l.splice(0),c=!0},this.subscribe=e=>{if(c)return r.warn("Observable subscription","โš ๏ธ Attempted to subscribe to a cleaned up observable."),()=>{};if("function"!=typeof e)throw new s("Callback must be a function");return l.push(e),()=>this.unsubscribe(e)},this.unsubscribe=e=>{const t=l.indexOf(e);t>-1&&l.splice(t,1)},this.check=function(e){return new i(this,e)};const p=this;Object.defineProperty(p,"$value",{get:()=>p.val(),set:e=>(p.set(e),p)}),this.toString=function(){return"{{#ObItem::("+d+")}}"}}const u={isObservable:e=>e instanceof a||e instanceof i,isProxy:e=>e?.__isProxy__,isObservableChecker:e=>e instanceof i,isArray:e=>Array.isArray(e),isString:e=>"string"==typeof e,isNumber:e=>"number"==typeof e,isBoolean:e=>"boolean"==typeof e,isFunction:e=>"function"==typeof e,isAsyncFunction:e=>"function"==typeof e&&"AsyncFunction"===e.constructor.name,isObject:e=>"object"==typeof e,isJson:e=>"object"==typeof e&&null!==e&&"Object"===e.constructor.name&&!Array.isArray(e),isElement:e=>e instanceof HTMLElement||e instanceof DocumentFragment||e instanceof Text,isFragment:e=>e instanceof DocumentFragment,isStringOrObservable(e){return this.isString(e)||this.isObservable(e)},isValidChild(e){return null===e||this.isElement(e)||this.isObservable(e)||["string","number","boolean"].includes(typeof e)},isValidChildren(e){Array.isArray(e)||(e=[e]);return 0===e.filter(e=>!this.isValidChild(e)).length},validateChildren(e){Array.isArray(e)||(e=[e]);const t=e.filter(e=>!this.isValidChild(e));if(t.length>0)throw new s(`Invalid children detected: ${t.map(e=>typeof e).join(", ")}`);return e},containsObservables:e=>!!e&&(u.isObject(e)&&Object.values(e).some(e=>u.isObservable(e))),containsObservableReference:e=>!(!e||"string"!=typeof e)&&/\{\{#ObItem::\([0-9]+\)\}\}/.test(e),validateAttributes(e){if(!e||"object"!=typeof e)return e;const t=[],n=Object.keys(e).filter(e=>t.includes(e));return n.length>0&&r.warn("Validator",`Reserved attributes found: ${n.join(", ")}`),e},validateEventCallback(e){if("function"!=typeof e)throw new s("Event callback must be a function")}},c=["checked","selected","disabled","readonly","required","autofocus","multiple","autocomplete","hidden","contenteditable","spellcheck","translate","draggable","async","defer","autoplay","controls","loop","muted","download","reversed","open","default","formnovalidate","novalidate","scoped","itemscope","allowfullscreen","allowpaymentrequest","playsinline"],l=function(e,t,n={}){let r=null,o=0;const{leading:s=!0,trailing:i=!0,debounce:a=!1}=n;return function(...n){const u=Date.now();if(a)return clearTimeout(r),void(r=setTimeout(()=>e.apply(this,n),t));s&&u-o>=t&&(e.apply(this,n),o=u),i&&!r&&(r=setTimeout(()=>{e.apply(this,n),o=Date.now(),r=null},t-(u-o)))}},d=function(e,t){return e.replace(new RegExp(`^[${t}]+|[${t}]+$`,"g"),"")};function p(e){return new a(e)}p.computed=function(e,t=[]){const n=new a(e()),r=()=>n.set(e());if(u.isFunction(t)){if(!u.isObservable(t.$observer))throw new s("Observable.computed : dependencies must be valid batch function");return t.$observer.subscribe(r),n}return t.forEach(e=>e.subscribe(r)),n},p.batch=function(e){const t=p(0),n=function(){if(u.isAsyncFunction(e))return e(...arguments).then(()=>{t.trigger()}).catch(e=>{throw e});e(...arguments),t.trigger()};return n.$observer=t,n},p.getById=function(e){const t=o.getObservableById(parseInt(e));if(!t)throw new s("Observable.getById : No observable found with id "+e);return t},p.cleanup=function(e){e.cleanup()},p.value=function(e){if(u.isObservable(e))return e.val();if(u.isProxy(e))return e.$val();if(u.isArray(e)){const t=[];return e.forEach(e=>{t.push(p.value(e))}),t}return e},p.init=function(e){const t={};for(const n in e){const r=e[n];u.isJson(r)?t[n]=p.init(r):u.isArray(r)?t[n]=p.array(r):t[n]=p(r)}const n=function(){const e={};for(const n in t){const r=t[n];u.isObservable(r)?e[n]=r.val():u.isProxy(r)?e[n]=r.$val():e[n]=r}return e},r=function(){};return new Proxy(t,{get:(e,t)=>"__isProxy__"===t||("$val"===t?n:"$clone"===t?r:void 0!==e[t]?e[t]:void 0),set(e,t,n){void 0!==e[t]&&e[t].set(n)}})},p.object=p.init,p.json=p.init,p.update=function(e,t){for(const n in t){const r=e[n],o=t[n];if(u.isObservable(r)){if(u.isArray(o)){p.update(r,o);continue}r.set(o)}else u.isProxy(r)?p.update(r,o):e[n]=o}},p.array=function(e){if(!Array.isArray(e))throw new s("Observable.array : target must be an array");const t=p(e);["push","pop","shift","unshift","reverse","sort","splice"].forEach(e=>{t[e]=function(...n){const r=t.val(),o=r[e].apply(r,arguments);return t.trigger(),o}});return["map","filter","reduce","some","every","find"].forEach(e=>{t[e]=function(n){return t.val()[e](n)}}),t},p.autoCleanup=function(e=!1,t={}){if(!e)return;const{interval:n=6e4,threshold:r=100}=t;window.addEventListener("beforeunload",()=>{o.cleanup()}),setInterval(()=>o.cleanObservables(r),n)};const h=function(e,t,n){n?e.classList.add(t):e.classList.remove(t)};function f(e,t){for(let n in t){const r=t[n];u.isObservable(r)?(h(e,n,r.val()),r.subscribe(t=>h(e,n,t))):h(e,n,r)}}function b(e,t){for(let n in t){const r=t[n];u.isObservable(r)?(e.style[n]=r.val(),r.subscribe(t=>{e.style[n]=t})):e.style[n]=r}}function m(e,t,n){const r=u.isObservable(n)?n.val():n;u.isBoolean(r)?e[t]=r:e[t]=r===e.value,u.isObservable(n)&&(["checked"].includes(t)&&e.addEventListener("input",()=>{u.isBoolean(r)?n.set(e[t]):n.set(e.value)}),n.subscribe(n=>{u.isBoolean(n)?e[t]=n:e[t]=n===e.value}))}function v(e,t,n){const r=n=>{"value"!==t?e.setAttribute(t,n):e.value=n};n.subscribe(r),r(n.val()),"value"===t&&e.addEventListener("input",()=>n.set(e.value))}const y={elements:new Map,observer:null,checkMutation:l(function(){for(const[e,t]of y.elements.entries()){const n=document.body.contains(e);n&&!t.inDom?(t.inDom=!0,t.mounted.forEach(t=>t(e))):!n&&t.inDom&&(t.inDom=!1,t.unmounted.forEach(t=>t(e)))}},10,{debounce:!0}),watch:function(e){let t={};if(y.elements.has(e))t=y.elements.get(e);else{const n=document.body.contains(e);t={inDom:n,mounted:new Set,unmounted:new Set},y.elements.set(e,t)}return{watch:()=>y.elements.set(e,t),disconnect:()=>y.elements.delete(e),mounted:e=>t.mounted.add(e),unmounted:e=>t.unmounted.add(e)}}};y.observer=new MutationObserver(y.checkMutation),y.observer.observe(document.body,{childList:!0,subtree:!0});const g=e=>u.isFunction(e)?g(e()):u.isElement(e)?e:S(e);function w(e){const t=document.createDocumentFragment(),n=document.createComment("Anchor Start : "+e),o=document.createComment("/ Anchor End "+e);t.appendChild(n),t.appendChild(o),t.nativeInsertBefore=t.insertBefore,t.nativeAppendChild=t.appendChild;const s=function(e,n,r){e!==t?e.insertBefore(g(n),r):e.nativeInsertBefore(g(n),r)};return t.appendChild=function(e,n=null){const i=o.parentNode;if(i){if(n=n??o,u.isArray(e))return e.forEach(e=>{s(i,e,n)}),t;s(i,e,n)}else r.error("Anchor","Anchor : parent not found",e)},t.remove=function(e){if(o.parentNode===t)return;let r,s=n.nextSibling;for(;s!==o;)r=s.nextSibling,e?s.remove():t.nativeAppendChild(s),s=r;e&&(o.remove(),n.remove())},t.insertBefore=function(e,n=null){t.appendChild(e,n)},t.clear=function(){t.remove()},t.endElement=function(){return o},t.startElement=function(){return n},t}const O=function(){const e=[];return{list:()=>e,add:t=>e.push(t)}}(),C=function(e,t){const n=document.createTextNode("");return t.subscribe(e=>n.textContent=String(e)),n.textContent=t.val(),e&&e.appendChild(n),n},E=function(e,t){const n=document.createTextNode("");return n.textContent=String(t),e&&e.appendChild(n),n},S=function(e){return u.isObservable(e)?C(null,e):E(null,e)},A={createElement:e=>e?document.createElement(e):new w("Fragment"),processChildren(e,t){if(null===e)return;(Array.isArray(e)?e:[e]).forEach(e=>{null!==e&&(u.isString(e)&&u.isFunction(e.resolveObservableTemplate)&&(e=e.resolveObservableTemplate()),u.isFunction(e)?this.processChildren(e(),t):u.isArray(e)?this.processChildren(e,t):u.isElement(e)?t.appendChild(e):u.isObservable(e)?C(t,e):e&&E(t,e))})},processAttributes(e,t){u.isFragment(e)||t&&function(e,t){if(u.validateAttributes(t),!u.isObject(t))throw new s("Attributes must be an object");for(let n in t){const r=n.toLowerCase();let o=t[r];if(u.isString(o)&&u.isFunction(o.resolveObservableTemplate)&&(o=o.resolveObservableTemplate(),u.isArray(o))){const e=o.filter(e=>u.isObservable(e));o=p.computed(()=>o.map(e=>u.isObservable(e)?e.val():e).join(" ")||" ",e)}c.includes(r)?m(e,r,o):u.isObservable(o)?v(e,r,o):"class"===r&&u.isJson(o)?f(e,o):"style"===r&&u.isJson(o)?b(e,o):e.setAttribute(r,o)}}(e,t)},setup(e,t,r){e.nd={},function(e){e.nd||(e.nd={}),e.nd.on=function(t){for(const r in t){const o=t[r];n(e,r,o)}return e},e.nd.on.prevent=function(t){for(const r in t){const o=t[r];n(e,r,t=>(t.preventDefault(),o&&o(t),e))}return e};const t={click:t=>n(e,"click",t),focus:t=>n(e,"focus",t),blur:t=>n(e,"blur",t),input:t=>n(e,"input",t),change:t=>n(e,"change",t),keyup:t=>n(e,"keyup",t),keydown:t=>n(e,"keydown",t),beforeInput:t=>n(e,"beforeinput",t),mouseOver:t=>n(e,"mouseover",t),mouseOut:t=>n(e,"mouseout",t),mouseDown:t=>n(e,"mousedown",t),mouseUp:t=>n(e,"mouseup",t),mouseMove:t=>n(e,"mousemove",t),hover:(t,n)=>{e.addEventListener("mouseover",t),e.addEventListener("mouseout",n)},dropped:t=>n(e,"drop",t),submit:t=>n(e,"submit",t),dragEnd:t=>n(e,"dragend",t),dragStart:t=>n(e,"dragstart",t),drop:t=>n(e,"drop",t),dragOver:t=>n(e,"dragover",t),dragEnter:t=>n(e,"dragenter",t),dragLeave:t=>n(e,"dragleave",t)};for(let r in t)e.nd.on[r]=t[r],e.nd.on.prevent[r]=function(t){return n(e,r.toLowerCase(),e=>{e.preventDefault(),t&&t(e)}),e}}(e);const o="function"==typeof r?r(e):e;return function(e){e.nd.wrap=t=>{if(!u.isFunction(t))throw new s("Callback must be a function");return t&&t(e),e},e.nd.ref=(t,n)=>(t[n]=e,e);let t=null;e.nd.appendChild=function(t){u.isArray(t)?A.processChildren(t,e):(u.isFunction(t)&&(t=t(),A.processChildren(t(),e)),u.isElement(t)&&A.processChildren(t,e))},e.nd.lifecycle=function(n){return t=t||y.watch(e),n.mounted&&t.mounted(n.mounted),n.unmounted&&t.unmounted(n.unmounted),e},e.nd.mounted=n=>(t=t||y.watch(e),t.mounted(n),e),e.nd.unmounted=n=>(t=t||y.watch(e),t.unmounted(n),e)}(o),O.list().forEach(e=>{e?.element?.setup&&e.element.setup(o,t)}),o}};function I(e,t){const n=e.toLowerCase().trim(),o=function(e,o=null){try{if(u.isValidChildren(e)){const t=o;o=e,e=t}const r=A.createElement(n);return A.processAttributes(r,e),A.processChildren(o,r),A.setup(r,e,t)}catch(e){r.error("ElementCreation",`Error creating ${n}`,e)}};return o.hold=(e,t)=>()=>o(e,t),o}class k extends Error{constructor(e,t){super(`${e}\n\n${t.join("\n")}\n\n`)}}const $={string:e=>({name:e,type:"string",validate:e=>u.isString(e)}),number:e=>({name:e,type:"number",validate:e=>u.isNumber(e)}),boolean:e=>({name:e,type:"boolean",validate:e=>u.isBoolean(e)}),observable:e=>({name:e,type:"observable",validate:e=>u.isObservable(e)}),element:e=>({name:e,type:"element",validate:e=>u.isElement(e)}),function:e=>({name:e,type:"function",validate:e=>u.isFunction(e)}),object:e=>({name:e,type:"object",validate:e=>u.isObject(e)}),objectNotNull:e=>({name:e,type:"object",validate:e=>u.isObject(e)&&null!==e}),children:e=>({name:e,type:"children",validate:e=>u.validateChildren(e)}),attributes:e=>({name:e,type:"attributes",validate:e=>u.validateAttributes(e)}),optional:e=>({...e,optional:!0}),oneOf:(e,...t)=>({name:e,type:"oneOf",types:t,validate:e=>t.some(t=>t.validate(e))})},F=(e,t,n="Function")=>{if(!u.isArray(t))throw new s("withValidation : argSchema must be an array");return function(...r){return((e,t,n="Function")=>{if(!t)return;const r=[],o=t.filter(e=>!e.optional).length;if(e.length<o&&r.push(`${n}: Expected at least ${o} arguments, got ${e.length}`),t.forEach((t,o)=>{const s=o+1,i=e[o];if(void 0!==i){if(!t.validate(i)){const e=i?.constructor?.name||typeof i;r.push(`${n}: Invalid argument '${t.name}' at position ${s}, expected ${t.type}, got ${e}`)}}else t.optional||r.push(`${n}: Missing required argument '${t.name}' at position ${s}`)}),r.length>0)throw new k("Argument validation failed",r)})(r,t,e.name||n),e.apply(this,r)}};Function.prototype.args=function(...e){return F(this,e)},Function.prototype.errorBoundary=function(e){return(...t)=>{try{return this.apply(this,t)}catch(t){return e(t)}}},String.prototype.use=function(e){const t=this;return p.computed(()=>t.replace(/\$\{(.*?)}/g,(t,n)=>{const r=e[n];return u.isObservable(r)?r.val():r}),Object.values(e))},String.prototype.resolveObservableTemplate=function(){return u.containsObservableReference(this)?this.split(/(\{\{#ObItem::\([0-9]+\)\}\})/g).filter(Boolean).map(e=>{if(!u.containsObservableReference(e))return e;const[t,n]=e.match(/\{\{#ObItem::\(([0-9]+)\)\}\}/);return p.getById(n)}):this};const R=function(){const e=new Map;return{use(t){const{observer:n,subscribers:r}=e.get(t),o=p(n.val()),s=n.subscribe(e=>o.set(e)),i=o.subscribe(e=>n.set(e));return o.destroy=()=>{s(),i(),o.cleanup()},r.add(o),o},follow(e){return this.use(e)},create(t,n){const r=p(n);return e.set(t,{observer:r,subscribers:new Set}),r},get(t){const n=e.get(t);return n?n.observer:null},getWithSubscribers:t=>e.get(t),delete(t){const n=e.get(t);n&&(n.observer.cleanup(),n.subscribers.forEach(e=>e.destroy()),n.observer.clear())}}}();const q=function(e,t,n=null){if(!u.isObservable(e))return r.warn("ShowIf","ShowIf : condition must be an Observable / "+n,e);const o=new w("Show if : "+(n||""));let s=null;const i=()=>s||(s="function"==typeof t?t():t,u.isStringOrObservable(s)&&(s=S(s)),s);return e.val()&&o.appendChild(i()),e.subscribe(e=>{e?o.appendChild(i()):o.remove()}),o},x=function(e,t){if(!u.isObservable(e))throw new s("Toggle : condition must be an Observable");const n=new w,r=new Map,o=function(e){if(r.has(e))return r.get(e);let n=t[e];return n?(u.isFunction(n)&&(n=n()),r.set(e,n),n):null},i=e.val(),a=o(i);return a&&n.appendChild(a),e.subscribe(e=>{const t=o(e);n.remove(),t&&n.appendChild(t)}),n},T=function(e,t,n){if(!u.isObservable(e))throw new s("Toggle : condition must be an Observable");return x(e,{true:t,false:n})},D=I("div"),j=I("span"),L=I("label"),B=I("p"),M=B,H=I("strong"),N=I("h1"),P=I("h2"),_=I("h3"),V=I("h4"),U=I("h5"),z=I("h6"),J=I("br"),W=I("a"),K=I("pre"),Q=I("code"),G=I("blockquote"),X=I("hr"),Y=I("em"),Z=I("small"),ee=I("mark"),te=I("del"),ne=I("ins"),re=I("sub"),oe=I("sup"),se=I("abbr"),ie=I("cite"),ae=I("q"),ue=I("dl"),ce=I("dt"),le=I("dd"),de=I("form",function(e){return e.submit=function(t){return"function"==typeof t?(e.on.submit(e=>{e.preventDefault(),t(e)}),e):(this.setAttribute("action",t),e)},e.multipartFormData=function(){return this.setAttribute("enctype","multipart/form-data"),e},e.post=function(t){return this.setAttribute("method","post"),this.setAttribute("action",t),e},e.get=function(e){this.setAttribute("method","get"),this.setAttribute("action",e)},e}),pe=I("input"),he=I("textarea"),fe=he,be=I("select"),me=I("fieldset"),ve=I("option"),ye=I("legend"),ge=I("datalist"),we=I("output"),Oe=I("progress"),Ce=I("meter"),Ee=I("button"),Se=I("main"),Ae=I("section"),Ie=I("article"),ke=I("aside"),$e=I("nav"),Fe=I("figure"),Re=I("figcaption"),qe=I("header"),xe=I("footer"),Te=I("img"),De=function(e,t){return Te({src:e,...t})},je=I("details"),Le=I("summary"),Be=I("dialog"),Me=I("menu"),He=I("ol"),Ne=I("ul"),Pe=I("li"),_e=I("audio"),Ve=I("video"),Ue=I("source"),ze=I("track"),Je=I("canvas"),We=I("svg"),Ke=I("time"),Qe=I("data"),Ge=I("address"),Xe=I("kbd"),Ye=I("samp"),Ze=I("var"),et=I("wbr"),tt=I("caption"),nt=I("table"),rt=I("thead"),ot=I("tfoot"),st=I("tbody"),it=I("tr"),at=it,ut=I("th"),ct=ut,lt=ut,dt=I("td"),pt=dt,ht=I("");var ft=Object.freeze({__proto__:null,Abbr:se,Address:Ge,Anchor:w,Article:Ie,Aside:ke,AsyncImg:function(e,t,n,r){const o=De(t||e,n),i=new Image;return i.onload=()=>{u.isFunction(r)&&r(null,o),o.src=e},i.onerror=()=>{u.isFunction(r)&&r(new s("Image not found"))},u.isObservable(e)&&e.subscribe(e=>{i.src=e}),i.src=e,o},Audio:_e,BaseImage:Te,Blockquote:G,Br:J,Button:Ee,Canvas:Je,Caption:tt,Checkbox:e=>pe({type:"checkbox",...e}),Cite:ie,Code:Q,ColorInput:e=>pe({type:"color",...e}),Data:Qe,Datalist:ge,DateInput:e=>pe({type:"date",...e}),DateTimeInput:e=>pe({type:"datetime-local",...e}),Dd:le,Del:te,Details:je,Dialog:Be,Div:D,Dl:ue,Dt:ce,Em:Y,EmailInput:e=>pe({type:"email",...e}),FieldSet:me,FigCaption:Re,Figure:Fe,FileInput:e=>pe({type:"file",...e}),Footer:xe,ForEach:function(e,t,n){const r=new w("ForEach"),o=r.endElement();let s=new Map;const i=(e,r)=>{const o=((e,t,n)=>{if(u.isFunction(n))return n(e,t);if(u.isObservable(e)){const r=e.val();return r&&n?r[n]:t}return e[n]??t})(e,r,n);if(s.has(o))s.get(o).indexObserver.set(r);else{const n=p(r);let i=t(e,n);u.isStringOrObservable(i)&&(i=S(i)),s.set(o,{child:i,indexObserver:n})}return o},a=new Set,c=()=>{const t=u.isObservable(e)?e.val():e,n=o.parentNode;if(!n)return;if(a.clear(),Array.isArray(t))t.forEach((e,t)=>a.add(i(e,t)));else for(const e in t)a.add(i(t[e],e));((e,t)=>{for(const[n,{child:r}]of e.entries())t.has(n)||r.remove()})(s,a);let r=o;for(const e of[...a].reverse()){const{child:t}=s.get(e);if(t){if(r&&r.previousSibling===t){r=t;continue}n.insertBefore(t,r),r=t}}};return c(),u.isObservable(e)&&e.subscribe(l((e,t)=>{c()},50,{debounce:!0})),r},Form:de,Fragment:ht,H1:N,H2:P,H3:_,H4:V,H5:U,H6:z,Header:qe,HiddenInput:e=>pe({type:"hidden",...e}),HideIf:function(e,t,n){const r=p(!e.val());return e.subscribe(e=>r.set(!e)),q(r,t,n)},HideIfNot:function(e,t,n){return q(e,t,n)},Hr:X,Img:De,Input:pe,Ins:ne,Kbd:Xe,Label:L,LazyImg:function(e,t){return De(e,{...t,loading:"lazy"})},Legend:ye,Link:W,ListItem:Pe,Main:Se,Mark:ee,Match:x,Menu:Me,Meter:Ce,MonthInput:e=>pe({type:"month",...e}),NativeDocumentFragment:w,Nav:$e,NumberInput:e=>pe({type:"number",...e}),Option:ve,OrderedList:He,Output:we,P:B,Paragraph:M,PasswordInput:e=>pe({type:"password",...e}),Pre:K,Progress:Oe,Quote:ae,Radio:e=>pe({type:"radio",...e}),RangeInput:e=>pe({type:"range",...e}),ReadonlyInput:e=>pe({readonly:!0,...e}),Samp:Ye,SearchInput:e=>pe({type:"search",...e}),Section:Ae,Select:be,ShowIf:q,SimpleButton:(e,t)=>Ee(e,{type:"button",...t}),Small:Z,Source:Ue,Span:j,Strong:H,Sub:re,SubmitButton:(e,t)=>Ee(e,{type:"submit",...t}),Summary:Le,Sup:oe,Svg:We,Switch:T,TBody:st,TBodyCell:pt,TFoot:ot,TFootCell:lt,THead:rt,THeadCell:ct,TRow:at,Table:nt,Td:dt,TelInput:e=>pe({type:"tel",...e}),TextArea:he,TextInput:fe,Th:ut,Time:Ke,TimeInput:e=>pe({type:"time",...e}),Tr:it,Track:ze,UnorderedList:Ne,UrlInput:e=>pe({type:"url",...e}),Var:Ze,Video:Ve,Wbr:et,WeekInput:e=>pe({type:"week",...e}),When:function(e){if(!u.isObservable(e))throw new s("When : condition must be an Observable");let t=null,n=null;return{show(e){return t=e,this},otherwise:r=>(n=r,T(e,t,n))}}});const bt={};function mt(e,t,n={}){e="/"+d(e,"/");let r=null,o=n.name||null;const s=n.middlewares||[],i=n.shouldRebuild||!1,a=n.with||{},u={},c=[],l=e=>{if(!e)return null;const[t,n]=e.split(":");let r=a[t];return!r&&n&&(r=bt[n]),r||(r="[^/]+"),r=r.replace("(","(?:"),{name:t,pattern:`(${r})`}},p=()=>{if(r)return r;const t=e.replace(/\{(.*?)}/gi,(e,t)=>{const n=l(t);return n&&n.pattern?(u[n.name]=n.pattern,c.push(n.name),n.pattern):e});return r=new RegExp("^"+t+"$"),r};this.name=()=>o,this.component=()=>t,this.middlewares=()=>s,this.shouldRebuild=()=>i,this.path=()=>e,this.match=function(e){e="/"+d(e,"/");if(!p().exec(e))return!1;const t={};return p().exec(e).forEach((e,n)=>{if(n<1)return;const r=c[n-1];t[r]=e}),t},this.url=function(t){const n=e.replace(/\{(.*?)}/gi,(e,n)=>{const r=l(n);if(t.params&&t.params[r.name])return t.params[r.name];throw new Error(`Missing parameter '${r.name}'`)}),r="object"==typeof t.query?new URLSearchParams(t.query).toString():null;return(t.basePath?t.basePath:"")+(r?`${n}?${r}`:n)}}class vt extends Error{constructor(e,t){super(e),this.context=t}}const yt=(e,t)=>{const n=[];return e.forEach(e=>{n.push(d(e.suffix,"/"))}),n.push(d(t,"/")),n.join("/")},gt=(e,t)=>{const n=[];return e.forEach(e=>{e.options.middlewares&&n.push(...e.options.middlewares)}),t&&n.push(...t),n},wt=(e,t)=>{const n=[];return e.forEach(e=>{e.options?.name&&n.push(e.options.name)}),t&&n.push(t),n.join(".")};function Ot(){const e=[];let t=0;const n=n=>{const o=t+n;if(!e[o])return;t=o;const{route:s,params:i,query:a,path:u}=e[o];r(u)},r=e=>{window.location.replace(`${window.location.pathname}${window.location.search}#${e}`)},o=()=>window.location.hash.slice(1);this.push=function(n){const{route:s,params:i,query:a,path:u}=this.resolve(n);u!==o()&&(e.splice(t+1),e.push({route:s,params:i,query:a,path:u}),t++,r(u))},this.replace=function(n){const{route:r,params:s,query:i,path:a}=this.resolve(n);a!==o()&&(e[t]={route:r,params:s,query:i,path:a})},this.forward=function(){return t<e.length-1&&n(1)},this.back=function(){return t>0&&n(-1)},this.init=function(n){window.addEventListener("hashchange",()=>{const{route:e,params:t,query:n,path:r}=this.resolve(o());this.handleRouteChange(e,t,n,r)});const{route:r,params:s,query:i,path:a}=this.resolve(n||o());e.push({route:r,params:s,query:i,path:a}),t=0,this.handleRouteChange(r,s,i,a)}}function Ct(){this.push=function(e){try{const{route:t,path:n,params:r,query:o}=this.resolve(e);if(window.history.state&&window.history.state.path===n)return;window.history.pushState({name:t.name(),params:r,path:n},t.name()||n,n),this.handleRouteChange(t,r,o,n)}catch(e){r.error("HistoryRouter","Error in pushState",e)}},this.replace=function(e){const{route:t,path:n,params:o}=this.resolve(e);try{window.history.replaceState({name:t.name(),params:o,path:n},t.name()||n,n),this.handleRouteChange(t,o,{},n)}catch(e){r.error("HistoryRouter","Error in replaceState",e)}},this.forward=function(){window.history.forward()},this.back=function(){window.history.back()},this.init=function(e){window.addEventListener("popstate",e=>{try{if(!e.state||!e.state.path)return;const t=e.state.path,{route:n,params:r,query:o,path:s}=this.resolve(t);if(!n)return;this.handleRouteChange(n,r,o,s)}catch(e){r.error("HistoryRouter","Error in popstate event",e)}});const{route:t,params:n,query:o,path:s}=this.resolve(e||window.location.pathname+window.location.search);this.handleRouteChange(t,n,o,s)}}function Et(){const e=[];let t=0;const n=n=>{const r=t+n;if(!e[r])return;t=r;const{route:o,params:s,query:i,path:a}=e[r];this.handleRouteChange(o,s,i,a)};this.push=function(n){const{route:r,params:o,query:s,path:i}=this.resolve(n);e[t]&&e[t].path===i||(e.splice(t+1),e.push({route:r,params:o,query:s,path:i}),t++,this.handleRouteChange(r,o,s,i))},this.replace=function(n){const{route:r,params:o,query:s,path:i}=this.resolve(n);e[t]={route:r,params:o,query:s,path:i},this.handleRouteChange(r,o,s,i)},this.forward=function(){return t<e.length-1&&n(1)},this.back=function(){return t>0&&n(-1)},this.init=function(n){const r=n||window.location.pathname+window.location.search,{route:o,params:s,query:i,path:a}=this.resolve(r);e.push({route:o,params:s,query:i,path:a}),t=0,this.handleRouteChange(o,s,i,a)}}const St="default";function At(e={}){const t=[],n={},o=[],s=[],i={route:null,params:null,query:null,path:null,hash:null};if("hash"===e.mode)Ot.apply(this,[]);else if("history"===e.mode)Ct.apply(this,[]);else{if("memory"!==e.mode)throw new vt("Invalid router mode "+e.mode);Et.apply(this,[])}const a=function(e,t){for(const n of s)try{n(e),t&&t(e)}catch(e){r.warn("Route Listener","Error in listener:",e)}};this.routes=()=>[...t],this.currentState=()=>({...i}),this.add=function(e,r,s){const i=new mt(yt(o,e),r,{...s,middlewares:gt(o,s?.middlewares||[]),name:s?.name?wt(o,s.name):null});return t.push(i),i.name()&&(n[i.name()]=i),this},this.group=function(e,t,n){if(!u.isFunction(n))throw new vt("Callback must be a function");return o.push({suffix:e,options:t}),n(),o.pop(),this},this.generateUrl=function(e,t={},r={}){const o=n[e];if(!o)throw new vt(`Route not found for name: ${e}`);return o.url({params:t,query:r})},this.resolve=function(e){if(u.isJson(e)){const t=n[e.name];if(!t)throw new vt(`Route not found for name: ${e.name}`);return{route:t,params:e.params,query:e.query,path:t.url({...e})}}const[r,o]=e.split("?"),s="/"+d(r,"/");let i,a=null;for(const e of t)if(i=e.match(s),i){a=e;break}if(!a)throw new vt(`Route not found for url: ${r}`);const c={};if(o){const e=new URLSearchParams(o).entries();for(const[t,n]of e)c[t]=n}return{route:a,params:i,query:c,path:e}},this.subscribe=function(e){if(!u.isFunction(e))throw new vt("Listener must be a function");return s.push(e),()=>{s.splice(s.indexOf(e),1)}},this.handleRouteChange=function(e,t,n,r){i.route=e,i.params=t,i.query=n,i.path=r;const o=[...e.middlewares(),a];let s=0;const u={...i},c=e=>{if(s++,!(s>=o.length))return o[s](e||u,c)};return o[s](u,c)}}function It(e,t){const{to:n,href:r,...o}=e,s=n||r;if(u.isString(s)){const e=At.get();return W({...o,href:s},t).nd.on.prevent.click(()=>{e.push(s)})}const i=s.router||St,a=At.get(i);if(console.log(i),!a)throw new vt('Router not found "'+i+'" for link "'+s.name+'"');const c=a.generateUrl(s.name,s.params,s.query);return W({...o,href:c},t).nd.on.prevent.click(()=>{a.push(c)})}At.routers={},At.create=function(t,n){if(!u.isFunction(n))throw r.error("Router","Callback must be a function",e),new vt("Callback must be a function");const o=new At(t);return At.routers[t.name||St]=o,n(o),o.init(t.entry),o.mount=function(e){if(u.isString(e)){const t=document.querySelector(e);if(!t)throw new vt(`Container not found for selector: ${e}`);e=t}else if(!u.isElement(e))throw new vt("Container must be a string or an Element");return function(e,t){const n=new Map,r=function(e){t.innerHTML="",t.appendChild(e)},o=function(e){if(!e.route)return;const{route:t,params:o,query:s,path:i}=e;if(n.has(i)){const e=n.get(i);return void r(e)}const a=t.component()({params:o,query:s});n.set(i,a),r(a)};return e.subscribe(o),o(e.currentState()),t}(o,e)},o},At.get=function(e){const t=At.routers[e||St];if(!t)throw new vt(`Router not found for name: ${e}`);return t},At.push=function(e,t=null){return At.get(t).push(e)},At.replace=function(e,t=null){return At.get(t).replace(e)},At.forward=function(e=null){return At.get(e).forward()},At.back=function(e=null){return At.get(e).back()},It.blank=function(e,t){return W({...e,target:"_blank"},t)};var kt=Object.freeze({__proto__:null,Link:It,RouteParamPatterns:bt,Router:At});return t.ArgTypes=$,t.ElementCreator=A,t.HtmlElementWrapper=I,t.Observable=p,t.Store=R,t.elements=ft,t.router=kt,t.withValidation=F,t}({});
package/docs/anchor.md CHANGED
@@ -6,9 +6,13 @@ Anchors are a NativeDocument class that enables dynamic DOM manipulation without
6
6
 
7
7
  Anchors are instances of the Anchor class that use two comment nodes as invisible markers:
8
8
 
9
+ `NativeDocumentFragment is Anchor alias`
10
+
9
11
  ```javascript
10
12
  // Create an anchor instance
11
13
  const anchor = new Anchor("My Content");
14
+ // Or
15
+ // const anchor = new NativeDocumentFragment("My Content");
12
16
 
13
17
  // In the DOM, this creates:
14
18
  // <!-- Anchor Start : My Content -->
@@ -177,7 +181,7 @@ fragment.appendChild(Div("Content"));
177
181
  // Gets replaced entirely when appended to parent
178
182
  ```
179
183
 
180
- **Use Anchor** for dynamic content management:
184
+ **Use Anchor (NativeDocumentFragment)** for dynamic content management:
181
185
 
182
186
  ```javascript
183
187
  // Dynamic content area that can be updated multiple times
@@ -170,6 +170,286 @@ const app = Div({ class: "counter" }, [
170
170
  ]);
171
171
  ```
172
172
 
173
+ # Batching Operations
174
+
175
+ Batching is a performance optimization technique that delays notifications to **dependent observers** (like computed observables) until the end of a batch operation. Individual observable subscribers still receive their notifications immediately, but computed observables that depend on the batch function are only triggered once at the end.
176
+
177
+ ### Understanding Batch Behavior
178
+
179
+ ```javascript
180
+ const name = Observable("John");
181
+ const age = Observable(25);
182
+
183
+ // Direct subscribers always get immediate notifications
184
+ name.subscribe(value => console.log("Name changed to:", value));
185
+ age.subscribe(value => console.log("Age changed to:", value));
186
+
187
+ const updateProfile = Observable.batch(() => {
188
+ name.set("Alice"); // Logs: "Name changed to: Alice"
189
+ age.set(30); // Logs: "Age changed to: 30"
190
+ });
191
+
192
+ updateProfile(); // Individual subscribers are notified immediately
193
+ ```
194
+
195
+ ### Batching with Computed Dependencies
196
+
197
+ The real power of batching shows when computed observables depend on the batch function:
198
+
199
+ ```javascript
200
+ const firstName = Observable("John");
201
+ const lastName = Observable("Doe");
202
+
203
+ // Direct subscribers get immediate notifications
204
+ firstName.subscribe(name => console.log("First name:", name));
205
+ lastName.subscribe(name => console.log("Last name:", name));
206
+
207
+ // Batch function for name updates
208
+ const updateName = Observable.batch((first, last) => {
209
+ firstName.set(first); // Logs: "First name: Alice"
210
+ lastName.set(last); // Logs: "Last name: Smith"
211
+ });
212
+
213
+ // Computed that depends on the BATCH FUNCTION (not individual observables)
214
+ const fullName = Observable.computed(() => {
215
+ return `${firstName.val()} ${lastName.val()}`;
216
+ }, updateName); // โ† Depends on the batch function
217
+
218
+ fullName.subscribe(name => console.log("Full name:", name));
219
+
220
+ // When we call the batch:
221
+ updateName("Alice", "Smith");
222
+ // Logs:
223
+ // "First name: Alice" โ† immediate notification
224
+ // "Last name: Smith" โ† immediate notification
225
+ // "Full name: Alice Smith" โ† single notification at the end
226
+ ```
227
+
228
+ ### Comparison: Normal vs Batch Dependencies
229
+
230
+ ```javascript
231
+ const score = Observable(0);
232
+ const lives = Observable(3);
233
+
234
+ // Method 1: Computed depends on individual observables
235
+ const gameStatus1 = Observable.computed(() => {
236
+ return `Score: ${score.val()}, Lives: ${lives.val()}`;
237
+ }, [score, lives]); // โ† Depends on individual observables
238
+
239
+ // Method 2: Computed depends on batch function
240
+ const updateGame = Observable.batch(() => {
241
+ score.set(score.val() + 100);
242
+ lives.set(lives.val() - 1);
243
+ });
244
+
245
+ const gameStatus2 = Observable.computed(() => {
246
+ return `Score: ${score.val()}, Lives: ${lives.val()}`;
247
+ }, updateGame); // โ† Depends on the batch function
248
+
249
+ // Without batching - gameStatus1 recalculates twice:
250
+ score.set(100); // gameStatus1 recalculates
251
+ lives.set(2); // gameStatus1 recalculates again
252
+
253
+ // With batching - gameStatus2 recalculates only once:
254
+ updateGame(); // gameStatus2 recalculates only at the end
255
+ ```
256
+
257
+ ### Practical Example: Shopping Cart
258
+
259
+ ```javascript
260
+ const items = Observable.array([]);
261
+ const discount = Observable(0);
262
+ const shippingCost = Observable(0);
263
+
264
+ // Individual subscribers for immediate UI updates
265
+ items.subscribe(items => {
266
+ console.log('Items count : '+items.length);
267
+ });
268
+
269
+ discount.subscribe(discount => {
270
+ console.log(`Discount: ${discount}%`);
271
+ });
272
+
273
+ // Batch function for cart operations
274
+ const updateCart = Observable.batch((cartData) => {
275
+ items.splice(0); // Clear current items
276
+ cartData.items.forEach(item => items.push(item));
277
+ discount.set(cartData.discount);
278
+ shippingCost.set(cartData.shipping);
279
+ });
280
+
281
+ // Expensive calculation that should only run after complete cart updates
282
+ const cartTotal = Observable.computed(() => {
283
+ const itemsTotal = items.val().reduce((sum, item) => sum + (item.price * item.quantity), 0);
284
+ const discountAmount = itemsTotal * (discount.val() / 100);
285
+ return itemsTotal - discountAmount + shippingCost.val();
286
+ }, updateCart); // โ† Only recalculates when updateCart() is called
287
+
288
+ // Example usage
289
+ updateCart({
290
+ items: [
291
+ { name: "Product A", price: 29.99, quantity: 2 },
292
+ { name: "Product B", price: 19.99, quantity: 1 }
293
+ ],
294
+ discount: 10,
295
+ shipping: 5.99
296
+ });
297
+ // Individual subscribers fire immediately, cartTotal calculates once at the end
298
+ ```
299
+
300
+ ### Async Batching
301
+
302
+ Batch functions handle asynchronous operations, delaying dependent notifications until the promise resolves:
303
+
304
+ ```javascript
305
+ const isLoading = Observable(false);
306
+ const userData = Observable(null);
307
+ const error = Observable(null);
308
+
309
+ // These subscribe immediately to loading states
310
+ isLoading.subscribe(loading => {
311
+ console.log('Loading.....');
312
+ });
313
+
314
+ const fetchUser = Observable.batch(async (userId) => {
315
+ isLoading.set(true); // Immediate notification
316
+ error.set(null); // Immediate notification
317
+
318
+ try {
319
+ const response = await fetch(`/api/users/${userId}`);
320
+ const data = await response.json();
321
+ userData.set(data); // Immediate notification
322
+ } catch (err) {
323
+ error.set(err.message); // Immediate notification
324
+ } finally {
325
+ isLoading.set(false); // Immediate notification
326
+ }
327
+ // Dependent computed observables are notified HERE
328
+ });
329
+
330
+ // This computed depends on the batch function
331
+ const userDisplay = Observable.computed(() => {
332
+ if (isLoading.val()) return "Loading...";
333
+ if (error.val()) return `Error: ${error.val()}`;
334
+ if (userData.val()) return `Hello ${userData.val().name}`;
335
+ return "No user";
336
+ }, fetchUser); // โ† Only updates when fetchUser() completes
337
+
338
+ await fetchUser(123);
339
+ ```
340
+
341
+ ### Single Batch Dependency Only
342
+
343
+ **Important**: Computed observables can only depend on **one batch function**, not multiple:
344
+
345
+ ```javascript
346
+ const user = Observable.object({ name: "", email: "" });
347
+ const settings = Observable.object({ theme: "light", lang: "en" });
348
+
349
+ const updateProfile = Observable.batch((profileData) => {
350
+ user.name.set(profileData.name);
351
+ user.email.set(profileData.email);
352
+ settings.theme.set(profileData.theme);
353
+ settings.lang.set(profileData.lang);
354
+ });
355
+
356
+ // โœ… Correct: Single batch dependency
357
+ const profileSummary = Observable.computed(() => {
358
+ return {
359
+ user: user.$val(),
360
+ settings: settings.$val(),
361
+ lastUpdated: Date.now()
362
+ };
363
+ }, updateProfile); // โ† Single batch function
364
+
365
+ // โŒ This is NOT supported:
366
+ // Observable.computed(callback, [batch1, batch2])
367
+ ```
368
+
369
+ ### Performance Benefits
370
+
371
+ ```javascript
372
+ const items = Observable.array([]);
373
+
374
+ // Expensive computed operation
375
+ const expensiveCalculation = Observable.computed(() => {
376
+ console.log("๐Ÿ”„ Recalculating..."); // This helps visualize when it runs
377
+ return items.val()
378
+ .filter(item => item.active)
379
+ .map(item => item.price * item.quantity)
380
+ .reduce((sum, total) => sum + total, 0);
381
+ }, [items]); // โ† Depends on individual observable
382
+
383
+ const batchUpdateItems = Observable.batch(() => {
384
+ items.push({ active: true, price: 10, quantity: 2 });
385
+ items.push({ active: true, price: 15, quantity: 1 });
386
+ items.push({ active: false, price: 20, quantity: 3 });
387
+ });
388
+
389
+ const optimizedCalculation = Observable.computed(() => {
390
+ console.log("โœ… Optimized recalculation");
391
+ return items.val()
392
+ .filter(item => item.active)
393
+ .map(item => item.price * item.quantity)
394
+ .reduce((sum, total) => sum + total, 0);
395
+ }, batchUpdateItems); // โ† Depends on batch function
396
+
397
+ // Without batching:
398
+ items.push({ active: true, price: 10, quantity: 2 }); // ๐Ÿ”„ Recalculating...
399
+ items.push({ active: true, price: 15, quantity: 1 }); // ๐Ÿ”„ Recalculating...
400
+ items.push({ active: false, price: 20, quantity: 3 }); // ๐Ÿ”„ Recalculating...
401
+
402
+ // With batching:
403
+ batchUpdateItems(); // โœ… Optimized recalculation (only once!)
404
+ ```
405
+
406
+ ### Best Practices
407
+
408
+ 1. **Use batch dependencies for expensive computations**: When you have costly computed observables that shouldn't recalculate on every individual change
409
+
410
+ 2. **Keep individual subscribers for immediate feedback**: UI feedback like input validation should use direct subscriptions
411
+
412
+ 3. **Batch related operations**: Group logically connected updates that should trigger dependent computations together
413
+
414
+ 4. **Don't over-batch**: Only use batching when you have computed observables that benefit from delayed updates
415
+
416
+ ### Common Patterns
417
+
418
+ ### State Machine with Batched Transitions
419
+ ```javascript
420
+ const gameState = Observable.object({
421
+ level: 1,
422
+ score: 0,
423
+ lives: 3
424
+ });
425
+
426
+ // Individual subscribers for immediate UI updates
427
+ gameState.score.subscribe(score => updateScoreDisplay(score));
428
+ gameState.lives.subscribe(lives => updateLivesDisplay(lives));
429
+
430
+ // Batch function for state transitions
431
+ const levelUp = Observable.batch(() => {
432
+ gameState.level.set(gameState.level.val() + 1);
433
+ gameState.score.set(gameState.score.val() + 1000);
434
+ gameState.lives.set(gameState.lives.val() + 1);
435
+ });
436
+
437
+ // Complex computed that should only run after complete transitions
438
+ const gameStatusMessage = Observable.computed(() => {
439
+ const state = gameState.$val();
440
+ return `Level ${state.level}: ${state.score} points, ${state.lives} lives remaining`;
441
+ }, levelUp); // โ† Only updates when levelUp() is called
442
+ ```
443
+
444
+ ### When NOT to Use Batch Dependencies
445
+
446
+ - **Real-time updates**: When computed observables need to update immediately
447
+ - **Simple computations**: When the computational cost is minimal
448
+ - **Debugging**: Batching can make the flow harder to debug
449
+ - **Single observable changes**: No benefit when only one observable changes
450
+
451
+ The key insight is that batching in NativeDocument is about **controlling when dependent computed observables recalculate**, not about suppressing individual observable notifications.
452
+
173
453
  ## String Templates with Observables
174
454
 
175
455
  ### The .use() Method
package/elements.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import Anchor from "./src/elements/anchor";
2
2
  export * from './src/elements/index';
3
3
 
4
- export { Anchor };
4
+ export { Anchor, Anchor as NativeDocumentFragment };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-document",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {
package/readme.md CHANGED
@@ -260,6 +260,33 @@ npm run dev
260
260
 
261
261
  MIT ยฉ [AfroCodeur](https://github.com/afrocodeur)
262
262
 
263
+ ## โค๏ธ Support the Project
264
+
265
+ NativeDocument is developed and maintained in my spare time.
266
+ If it helps you build better applications, consider supporting its development:
267
+
268
+ [![Ko-fi](https://img.shields.io/badge/โ˜•_Buy_me_a_coffee-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/native_document)
269
+
270
+ You can also support the project via crypto donations:
271
+
272
+ - **USDT (TRC20)**
273
+ - **USDT (BSC)**
274
+ - **USDC (Base)**
275
+
276
+ ```
277
+ 0xCe426776DDb07256aBd58c850dd57041BC85Ea7D
278
+ ```
279
+
280
+ Your support helps me:
281
+
282
+ - Maintain and improve NativeDocument
283
+ - Write better documentation and examples
284
+ - Fix bugs and ship new features
285
+ - Produce tutorials and learning content
286
+
287
+ Thanks for your support! ๐Ÿ™
288
+
289
+
263
290
  ## Acknowledgments
264
291
 
265
292
  Thanks to all contributors and the JavaScript community for inspiration.
@@ -14,17 +14,45 @@ export function Observable(value) {
14
14
  return new ObservableItem(value);
15
15
  }
16
16
 
17
+ /**
18
+ *
19
+ * @param {Function} callback
20
+ * @param {Array|Function} dependencies
21
+ * @returns {ObservableItem}
22
+ */
17
23
  Observable.computed = function(callback, dependencies = []) {
18
24
  const initialValue = callback();
19
25
  const observable = new ObservableItem(initialValue);
20
-
21
26
  const updatedValue = () => observable.set(callback());
22
27
 
28
+ if(Validator.isFunction(dependencies)) {
29
+ if(!Validator.isObservable(dependencies.$observer)) {
30
+ throw new NativeDocumentError('Observable.computed : dependencies must be valid batch function');
31
+ }
32
+ dependencies.$observer.subscribe(updatedValue);
33
+ return observable;
34
+ }
35
+
23
36
  dependencies.forEach(dependency => dependency.subscribe(updatedValue));
24
37
 
25
38
  return observable;
26
39
  };
27
40
 
41
+ Observable.batch = function(callback) {
42
+ const $observer = Observable(0);
43
+ const batch = function() {
44
+ if(Validator.isAsyncFunction(callback)) {
45
+ return (callback(...arguments)).then(() => {
46
+ $observer.trigger();
47
+ }).catch(error => { throw error; });
48
+ }
49
+ callback(...arguments);
50
+ $observer.trigger();
51
+ };
52
+ batch.$observer = $observer;
53
+ return batch;
54
+ }
55
+
28
56
  /**
29
57
  *
30
58
  * @param id
@@ -10,7 +10,7 @@ const getChildAsNode = (child) => {
10
10
  if(Validator.isElement(child)) {
11
11
  return child;
12
12
  }
13
- return createTextNode(String(child))
13
+ return createTextNode(child)
14
14
  }
15
15
 
16
16
  export default function Anchor(name) {
@@ -28,6 +28,9 @@ const Validator = {
28
28
  isFunction(value) {
29
29
  return typeof value === 'function';
30
30
  },
31
+ isAsyncFunction(value) {
32
+ return typeof value === 'function' && value.constructor.name === 'AsyncFunction';
33
+ },
31
34
  isObject(value) {
32
35
  return typeof value === 'object';
33
36
  },