lego-dom 2.1.6 → 2.1.8

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/dist/lego.d.ts CHANGED
@@ -54,7 +54,8 @@ export interface Lego {
54
54
  logic?: object,
55
55
  styles?: string,
56
56
  cascade?: string,
57
- error?: string
57
+ error?: string,
58
+ props?: string
58
59
  ): void;
59
60
 
60
61
  /**
package/dist/lego.min.js CHANGED
@@ -1,7 +1,7 @@
1
- (()=>{var y={},J=new WeakMap,O=new WeakMap,F=new WeakMap,se=new WeakMap,A=new Set,q=new Set,j=new Map,ne=new Map;var H={locked:!1},C=e=>(O.has(e)||O.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null}),O.get(e));var w={},$e=e=>{w=e};var ae=class{constructor(t=1e3){this.limit=t,this.cache=new Map}get(t){if(!this.cache.has(t))return;let o=this.cache.get(t);return this.cache.delete(t),this.cache.set(t,o),o}set(t,o){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.limit){let s=this.cache.keys().next().value;this.cache.delete(s)}this.cache.set(t,o)}get size(){return this.cache.size}clear(){this.cache.clear()}};var U=(e,t)=>{if(!e)return;let o=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;o;){let s=o.tagName?o.tagName.toLowerCase():"";if(s&&(t==="*"&&y[s]||s===t.toLowerCase()))return o;o=o.parentElement||o.getRootNode&&o.getRootNode().host}},ie=(e,t)=>{if(typeof e=="function"){let s=Array.from(document.querySelectorAll("*")).filter(r=>r.tagName.includes("-"));return[].concat(e(s))}if(e.startsWith("#")){let s=document.getElementById(e.slice(1));return s?[s]:[]}let o=t?.querySelectorAll(e)||[];return o.length>0?[...o]:[...document.querySelectorAll(e)]},z=e=>e.attributes?[...e.attributes].find(t=>t.name==="b-sync"||t.name.startsWith("b-sync.")):null,V=(e,t)=>{if(e.type==="checkbox")e.checked!==!!t&&(e.checked=!!t);else{let o=t==null?"":String(t);e.value!==o&&(e.value=o)}};var g={onError:(e,t,o)=>{console.error(`[Lego Error] [${t}]`,e,o)},metrics:{},debug:!1,syntax:"brackets"},W=(e,t)=>{!e||!t||Object.getOwnPropertyNames(e).forEach(o=>{let s=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,s)})},X=()=>g.syntax==="brackets"?["[[","]]"]:["{{","}}"],ue=new Map,Q=()=>{let[e,t]=X(),o=e+t;if(ue.has(o)){let n=ue.get(o);return n.lastIndex=0,n}let s=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`${s}(.*?)${r}`,"g");return ue.set(o,a),a},_e=e=>{let o=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!o.includes("-"))throw new Error(`[Lego] Invalid block definition: "${e}". Block names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return o},D=(e,t)=>{if(!e)return"";let o=e.trim().split("."),s=t;for(let r of o){if(s==null)return"";s=s[r]}return s??""},pe=e=>typeof Node<"u"&&e instanceof Node,k=(e,t,o)=>{if(t.nodeType!==Node.ELEMENT_NODE)return;let s=[...t.attributes].find(a=>a.name===e||a.name.startsWith(`${e}.`));if(!s)return;let r={};return o&&(r=o(s,t)),{type:e,node:t,expr:s.value,modifiers:s.name.split(".").slice(1),...r}};var me=null,Le=e=>{me=e},Z=[],ge=e=>{let t=Z.find(r=>r.regex.test(e));if(!t)return null;let o=e.match(t.regex).slice(1),s=t.paramNames?Object.fromEntries(t.paramNames.map((r,a)=>[r,o[a]])):{};return{match:t,params:s}},ce=async(e=null,t=null)=>{if(typeof window>"u")return;let o=window.location.pathname,s=ge(o);if(g.debug&&console.log("[Lego Trace] Matching route",o,s?.match),!s)return;let{match:r,params:a}=s,n=window.location.search;if(w.$route.url=o+n,w.$route.route=r.path,w.$route.params=a,w.$route.query=Object.fromEntries(new URLSearchParams(n)),r.middleware&&!await r.middleware({path:o,params:a}))return;let i=e&&e.length?e:["lego-router"],c=t||document;r.tagName&&i.flatMap(l=>ie(l,c)).forEach(l=>{if(!l)return;l.innerHTML="";let u=document.createElement(r.tagName);l.appendChild(u),me&&me(u)})},le=(e,...t)=>o=>{let s=async(r,a=null,n=!0,i={})=>{if(n&&typeof history<"u"){let d={legoTargets:t.filter(l=>typeof l=="string"),method:r,body:a};history.pushState(d,"",e)}await ce(t.length?t:null,o)};return{get:(r=!0,a={})=>s("GET",null,r,a),post:(r,a=!0,n={})=>s("POST",r,a,n),put:(r,a=!0,n={})=>s("PUT",r,a,n),patch:(r,a=!0,n={})=>s("PATCH",r,a,n),delete:(r=!0,a={})=>s("DELETE",null,r,a)}};var he=null,Ye=null,Ne=(e,t)=>{he=e,Ye=t},R=(e,t,o)=>{if(e!=null&&(e=String(e).toLowerCase(),!e.includes("-"))){console.warn(`[Lego] $mount: "${e}" is not a valid custom element name (must contain a hyphen).`);return}if(t===void 0){if(!e)return;let a=document.createElement(e);return o&&(a.$initialState=o),a}let s;if(t instanceof Element)s=[t];else if(Array.isArray(t))s=t;else if(typeof t=="string")s=ie(t);else{console.warn("[Lego] $mount: Invalid target",t);return}if(s.length===0){g.debug&&console.log(`[Lego] $mount: No targets found for "${t}"`);return}let r=[];return s.forEach(a=>{if(!a||(a.innerHTML="",!e))return;let n=document.createElement(e);o&&(n.$initialState=o),a.appendChild(n),he&&he(n),r.push(n)}),r.length===1?r[0]:r.length>0?r:void 0};var Te=new ae(1e3),S=(e,t,o=!0)=>{if(/\b(eval|import|class|module|constructor|__proto__|prototype)\b/.test(e)||/\[\s*['"`].*\+|\+.*['"`]\s*\]/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{let s=t.state||{},r=Te.get(e);r||(r=new Function("global","self","event","helpers",`
1
+ (()=>{var S={},Y=new WeakMap,A=new WeakMap,W=new WeakMap,ue=new WeakMap,C=new Set,U=new Set,I=new Map,q=new Map,ee=new Map;var j={locked:!1},M=e=>(A.has(e)||A.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null}),A.get(e));var wt=/^[a-zA-Z_$][\w$]*$/,J=new Map,vt=(e,t="<unknown>")=>{if(!e||typeof e!="string")return null;let r=e.trim();if(!r||r.startsWith("{")&&r.endsWith("}")&&(r=r.slice(1,-1).trim(),!r))return null;let o=r.split(",").map(i=>i.trim()).filter(Boolean);if(o.length===0)return null;let n=[];for(let i of o){if(!wt.test(i))return console.error(`[Lego] Invalid b-props on <${t}>: token "${i}" is not a bare identifier. b-props declares names only \u2014 use b-logic for values. Got: "${e}"`),null;n.push(i)}return n},z={register(e,t){if(!t){J.delete(e);return}let r=vt(t,e);r?J.set(e,r):J.delete(e)},unregister(e){J.delete(e)},get(e){return J.get(e)||null},validate({instanceLogic:e,state:t,tagName:r}){let o=J.get(r);if(o){if(e)for(let n of Object.keys(e))o.includes(n)||console.warn(`[Lego] <${r}> received b-logic key "${n}" not declared in b-props. Declared: { ${o.join(", ")} }.`);for(let n of o)t[n]===void 0&&console.warn(`[Lego] <${r}> is missing prop "${n}" (declared in b-props but not provided).`)}}};var _={},De=e=>{_=e};var te=class{constructor(t=1e3){this.limit=t,this.cache=new Map}get(t){if(!this.cache.has(t))return;let r=this.cache.get(t);return this.cache.delete(t),this.cache.set(t,r),r}set(t,r){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.limit){let o=this.cache.keys().next().value;this.cache.delete(o)}this.cache.set(t,r)}get size(){return this.cache.size}clear(){this.cache.clear()}};var V=(e,t)=>{if(!e)return;let r=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;r;){let o=r.tagName?r.tagName.toLowerCase():"";if(o&&(t==="*"&&S[o]||o===t.toLowerCase()))return r;r=r.parentElement||r.getRootNode&&r.getRootNode().host}},pe=(e,t)=>{if(typeof e=="function"){let o=Array.from(document.querySelectorAll("*")).filter(n=>n.tagName.includes("-"));return[].concat(e(o))}if(e.startsWith("#")){let o=document.getElementById(e.slice(1));return o?[o]:[]}let r=t?.querySelectorAll(e)||[];return r.length>0?[...r]:[...document.querySelectorAll(e)]},K=e=>e.attributes?[...e.attributes].find(t=>t.name==="b-sync"||t.name.startsWith("b-sync.")):null,St=new Set(["script","iframe","object","embed","link","meta","base","style"]),xt=new Set(["href","src","xlink:href","action","formaction","srcdoc","data"]),Re=e=>{if(typeof e!="string"||e===""||typeof document>"u")return e;let t=document.createElement("template");t.innerHTML=e;let r=document.createTreeWalker(t.content,NodeFilter.SHOW_ELEMENT),o=[],n;for(;n=r.nextNode();){if(St.has(n.tagName.toLowerCase())){o.push(n);continue}for(let i=n.attributes.length-1;i>=0;i--){let a=n.attributes[i],s=a.name.toLowerCase();if(s.startsWith("on")){n.removeAttribute(a.name);continue}if(xt.has(s)){let c=a.value.trim().toLowerCase();(c.startsWith("javascript:")||c.startsWith("data:text/html")||c.startsWith("vbscript:"))&&n.removeAttribute(a.name)}}}return o.forEach(i=>i.remove()),t.innerHTML},re=(e,t)=>{if(e.type==="checkbox")e.checked!==!!t&&(e.checked=!!t);else if(e.type==="radio"){let r=t!=null&&String(t)===e.value;e.checked!==r&&(e.checked=r)}else{let r=t==null?"":String(t);e.value!==r&&(e.value=r)}};var g={onError:(e,t,r)=>{console.error(`[Lego Error] [${t}]`,e,r)},metrics:{},debug:!1,syntax:"brackets",sanitize:null,loaderAllowlist:null},G=(e,t)=>{!e||!t||Object.getOwnPropertyNames(e).forEach(r=>{let o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o)})},oe=()=>g.syntax==="brackets"?["[[","]]"]:["{{","}}"],Ee=new Map,we=()=>{let[e,t]=oe(),r=e+t;if(Ee.has(r)){let a=Ee.get(r);return a.lastIndex=0,a}let o=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp(`${o}(.*?)${n}`,"g");return Ee.set(r,i),i},Pe=e=>{let r=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!r.includes("-"))throw new Error(`[Lego] Invalid block definition: "${e}". Block names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return r},D=(e,t)=>{if(!e)return"";let r=e.trim().split("."),o=t;for(let n of r){if(o==null)return"";o=o[n]}return o??""},ve=e=>typeof Node<"u"&&e instanceof Node,O=(e,t,r)=>{if(t.nodeType!==Node.ELEMENT_NODE)return;let o=[...t.attributes].find(i=>i.name===e||i.name.startsWith(`${e}.`));if(!o)return;let n={};return r&&(n=r(o,t)),{type:e,node:t,expr:o.value,modifiers:o.name.split(".").slice(1),...n}};var Se=null,Fe=e=>{Se=e},ne=[],ze=0,xe=e=>{let t=ne.find(n=>n.regex.test(e));if(!t)return null;let r=e.match(t.regex).slice(1),o=t.paramNames?Object.fromEntries(t.paramNames.map((n,i)=>[n,r[i]])):{};return{match:t,params:o}},me=async(e=null,t=null)=>{if(typeof window>"u")return;let r=++ze,o=()=>r===ze,n=window.location.pathname,i=xe(n);if(g.debug&&console.log("[Lego Trace] Matching route",n,i?.match),!i)return;let{match:a,params:s}=i,c=window.location.search;if(a.middleware){let u=await a.middleware({path:n,params:s});if(!o()||!u)return}_.$route.url=n+c,_.$route.route=a.path,_.$route.params=s,_.$route.query=Object.fromEntries(new URLSearchParams(c));let f=e&&e.length?e:["lego-router"],l=t||document;if(a.tagName){if(!o())return;f.flatMap(d=>pe(d,l)).forEach(d=>{if(!d||!o())return;d.innerHTML="";let p=document.createElement(a.tagName);d.appendChild(p),Se&&Se(p)})}},ge=(e,...t)=>r=>{let o=async(n,i=null,a=!0,s={})=>{if(a&&typeof history<"u"){let f={legoTargets:t.filter(l=>typeof l=="string"),method:n,body:i};history.pushState(f,"",e)}await me(t.length?t:null,r)};return{get:(n=!0,i={})=>o("GET",null,n,i),post:(n,i=!0,a={})=>o("POST",n,i,a),put:(n,i=!0,a={})=>o("PUT",n,i,a),patch:(n,i=!0,a={})=>o("PATCH",n,i,a),delete:(n=!0,i={})=>o("DELETE",null,n,i)}};var $e=null,$t=null,He=(e,t)=>{$e=e,$t=t},F=(e,t,r)=>{if(e!=null&&(e=String(e).toLowerCase(),!e.includes("-"))){console.warn(`[Lego] $mount: "${e}" is not a valid custom element name (must contain a hyphen).`);return}if(t===void 0){if(!e)return;let i=document.createElement(e);return r&&(i.$initialState=r),i}let o;if(t instanceof Element)o=[t];else if(Array.isArray(t))o=t;else if(typeof t=="string")o=pe(t);else{console.warn("[Lego] $mount: Invalid target",t);return}if(o.length===0){g.debug&&console.log(`[Lego] $mount: No targets found for "${t}"`);return}let n=[];return o.forEach(i=>{if(!i||(i.innerHTML="",!e))return;let a=document.createElement(e);r&&(a.$initialState=r),i.appendChild(a),$e&&$e(a),n.push(a)}),n.length===1?n[0]:n.length>0?n:void 0};var We=new te(1e3),Ie=new te(500),_t=/\b(eval|import|constructor|__proto__)\b/,Lt=/(?<![\w.$])(class|module|prototype)(?![\w$])/,L=(e,t,r=!0)=>{if(_t.test(e)||Lt.test(e)||/\[\s*['"`].*\+|\+.*['"`]\s*\]/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{let o=t.state||{},n=We.get(e);n||(n=new Function("global","self","event","helpers",`
2
2
  with(this) {
3
3
  with(helpers) {
4
4
  return ${e}
5
5
  }
6
6
  }
7
- `),Te.set(e,r));let a={$ancestors:i=>U(t.self,i),$registry:i=>ne.get(i.toLowerCase()),$element:t.self,$route:w.$route,$params:w.$route?.params||{},$go:(i,...c)=>le(i,...c)(t.self),$db:w.$db,$mount:(i,c,d)=>R(i,c,d),$emit:(i,c)=>{t.self.dispatchEvent(new CustomEvent(i,{detail:c,bubbles:!0,composed:!0}))}},n=r.call(s,t.global,t.self,t.event,a);return typeof n=="function"?n.call(s,t.event):n}catch(s){if(o)throw s;if(s instanceof ReferenceError)return;throw s}},be=(e,t={})=>{if(!e||e.trim()==="{}")return{};let o=s=>new Function("scope","global",`with(global) { with(scope) { return (${s}); } }`)(t,w);try{return o(e)}catch(s){let r=e.trim();if(!r.startsWith("{")&&r.includes(":"))try{return o(`{${e}}`)}catch{}return console.error(`[Lego] Error parsing b-logic: "${e.length>80?e.slice(0,80)+"...":e}"`,s),{}}};var Ae={name:"b-if",scan:(e,{checkGlobal:t,getPrivateData:o})=>k("b-if",e,(s,r)=>{t(s.value);let a=document.createComment(`b-if: ${s.value}`),n=o(r);return n.anchor=a,{anchor:a}}),execute({binding:e,state:t,global:o}){let{node:s,anchor:r,expr:a}=e,n=!!S(a,{state:t,global:o,self:s}),i=!!s.parentNode;n&&!i?r.parentNode&&r.parentNode.replaceChild(s,r):!n&&i&&s.parentNode.replaceChild(r,s)},destroy({binding:e}){e.anchor&&e.anchor.parentNode&&e.anchor.remove()}};var Ce={name:"b-show",scan(e,{checkGlobal:t}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-show")){let o=e.getAttribute("b-show");return t(o),{type:"b-show",node:e,expr:o}}},execute({binding:e,state:t,global:o}){let{node:s,expr:r}=e;s.style.display=S(r,{state:t,global:o,self:s})?"":"none"}};var ke={name:"b-text",scan(e,{checkGlobal:t}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-text")){let o=e.getAttribute("b-text");return t(o),{type:"b-text",node:e,path:o}}},execute({binding:e,state:t,global:o}){let{node:s,path:r}=e;r.startsWith("global.")?s.textContent=D(r.slice(7),o)??"":s.textContent=D(r,t)??""}};var Me={name:"b-html",scan:e=>k("b-html",e),execute:({binding:e,state:t,global:o})=>{let{node:s,expr:r}=e,a=S(r,{state:t,global:o,self:s})??"";s._bHtmlPrev!==a&&(s._bHtmlPrev=a,s.innerHTML=a)},destroy({binding:e}){let{node:t}=e;t&&(delete t._bHtmlPrev,t.innerHTML="")}};var Oe={name:"b-sync",scan(e,{checkGlobal:t}){if(e.nodeType!==Node.ELEMENT_NODE)return;let o=z(e);if(!o)return;t(o.value);let s=o.name.split(".").slice(1);return{type:"b-sync",node:e,expr:o.value,modifiers:s}},execute({binding:e,state:t,global:o}){let{node:s,expr:r}=e;r.startsWith("global.")?V(s,D(r.slice(7),o)??""):V(s,D(r,t)??"")},destroy({binding:e}){let{node:t}=e;t&&t._bSyncHandler&&(t.removeEventListener("input",t._bSyncHandler),t.removeEventListener("change",t._bSyncHandler),delete t._bSyncHandler)}};var De={name:"b-for",scan(e,{checkGlobal:t,pendingOperations:o}){if(e.nodeType!==Node.ELEMENT_NODE)return;let s=e.getAttribute("b-for")?.match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);if(s){t(s[2]);let r=document.createComment(`b-for: ${s[1]} in ${s[2].trim()}`);return o.push(()=>{e.parentNode&&(e.parentNode.insertBefore(r,e),e.remove())}),{type:"b-for",anchor:r,itemName:s[1],listName:s[2].trim(),keyPath:e.getAttribute("b-key")||null,template:e.cloneNode(!0),terminal:!0}}},execute({binding:e,state:t,global:o,helpers:s}){let{bind:r,updateNodeBindings:a}=s;if(!r||!a){console.error("[Lego] b-for directive missing required helpers: bind, updateNodeBindings");return}let{anchor:n,listName:i,itemName:c,keyPath:d,template:l}=e,{contextEl:u}=s,f=S(i,{state:t,global:o,self:u})||[];F.has(n)||F.set(n,new Map);let m=F.get(n),x=new Set,E=[];f.forEach((p,$)=>{let h;d?(h=D(d,p),(h==null||h==="")&&(console.warn(`[Lego] b-key="${d}" could not resolve a value for item at index ${$}. Falling back to index-based key.`),h=`__bfor_${$}`)):p&&typeof p=="object"?(h=p.id||p._id||p.uuid||p.key,h===void 0&&(se.has(p)||se.set(p,Math.random()),h=se.get(p))):h=`${$}-${p}`,x.add(h);let v=m.get(h);v?v._loopCtx.index=$:(v=l.cloneNode(!0),v.removeAttribute("b-for"),v.removeAttribute("b-key"),m.set(h,v),v._loopCtx={name:c,listName:i,index:$},r(v,u,v._loopCtx));let _=Object.assign(Object.create(t),{[c]:p,$index:$});a(v,_),[v,...v.querySelectorAll("*")].filter(I=>z(I)).forEach(I=>{let Se=z(I).value;Se.startsWith(`${c}.`)&&V(I,D(Se.split(".").slice(1).join("."),f[$]))}),E.push(v)});let L=n.nextSibling;E.forEach(p=>{p!==L?n.parentNode.insertBefore(p,L):L=L.nextSibling});for(let[p,$]of m.entries())x.has(p)||($.remove(),m.delete(p))},destroy({binding:e}){let{anchor:t}=e;if(t&&F.has(t)){let o=F.get(t);o.forEach(s=>{[s,...s.querySelectorAll("*")].forEach(a=>{let n=O.get(a);n&&(n.listeners&&(n.listeners.forEach(({eventName:i,handler:c})=>{a.removeEventListener(i,c)}),n.listeners=null),n.bindings&&(n.bindings.forEach(i=>{i.observer&&(i.observer.disconnect(),i.observer=null)}),n.bindings=null))}),s.remove()}),o.clear(),F.delete(t)}t&&t.parentNode&&t.remove()}};var Be={scan:e=>{if(e.hasAttribute("b-init"))return{type:"b-init",node:e,expr:e.getAttribute("b-init")}},execute:({binding:e,state:t,global:o})=>{e.initialized||(e.initialized=!0,S(e.expr,{state:t,global:o,self:e.node}))}};var Re={name:"b-enter",scan:e=>k("b-enter",e,(t,o)=>({modifiers:t.name.split(".").slice(1)})),execute:({binding:e,state:t,global:o})=>{if(e.observer||e.done)return;let s=new IntersectionObserver((r,a)=>{if(r[0].isIntersecting){try{S(e.expr,{state:t,global:o,self:e.node})}catch(i){console.error("[Lego] Error in b-enter handler:",i)}e.modifiers.includes("once")&&(a.disconnect(),e.observer=null,e.done=!0)}});s.observe(e.node),e.observer=s},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Pe={name:"b-leave",scan:e=>k("b-leave",e),execute:({binding:e,state:t,global:o})=>{if(e.observer||e.done)return;let s=new IntersectionObserver((r,a)=>{let n=r[0];if(n.isIntersecting&&(e.activated=!0),!n.isIntersecting&&e.activated){try{S(e.expr,{state:t,global:o,self:e.node})}catch(i){console.error("[Lego] Error in b-leave handler:",i)}e.modifiers.includes("once")&&(a.disconnect(),e.observer=null,e.done=!0)}});s.observe(e.node),e.observer=s},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Fe={name:"b-mount",scan:(e,{checkGlobal:t})=>k("b-mount",e,o=>(t(o.value),{_lastTag:null})),execute({binding:e,state:t,global:o}){let{node:s,expr:r}=e,a=S(r,{state:t,global:o,self:s},!1),n=a?String(a).toLowerCase():null;n!==e._lastTag&&(e._lastTag=n,R(n,s))},destroy({binding:e}){e.node&&R(null,e.node),e._lastTag=null}};var Y={"b-if":Ae,"b-show":Ce,"b-text":ke,"b-html":Me,"b-sync":Oe,"b-for":De,"b-init":Be,"b-enter":Re,"b-leave":Pe,"b-mount":Fe};var et=(e=null)=>{let t=!1,o=new Set,s=!1,r=e,a=new Set,n=null,i=new Set,c=f=>{r=f},d=()=>{n&&clearTimeout(n),n=setTimeout(()=>{i.forEach(f=>{let m=f._studs;if(m&&typeof m.updated=="function")try{m.updated.call(m)}catch(x){console.error("[Lego] Error in updated hook:",x)}}),i.clear(),n=null},50)},l=()=>{a.size>0&&(a.forEach(f=>o.add(f)),a.clear(),!t&&o.size>0&&(t=!0,requestAnimationFrame(u)))},u=()=>{s=!0;let f=Array.from(o);o.clear(),t=!1,f.forEach(m=>{m.isConnected&&r&&r(m)}),f.forEach(m=>i.add(m)),d(),s=!1,l()};return{add:f=>{if(f){if(s){a.add(f);return}o.add(f),!t&&(t=!0,requestAnimationFrame(u))}},setHandler:c}},ee=et();var T=new Map,fe=new Map,te=new WeakMap,re=new Map,tt=e=>{let t=Array.from(re.entries()).filter(([r])=>r.startsWith("lego:")).sort((r,a)=>r[1].timestamp-a[1].timestamp),o=0,s=[];for(let[r,a]of t){if(o>=e)break;try{localStorage.removeItem(r),o+=a.size,s.push(r),re.delete(r)}catch(n){console.error(`[Lego] Failed to evict ${r}:`,n)}}return s},He=(e,t,o)=>{g.debug&&console.log("[Lego Trace] scheduleSave",e,t,o),fe.has(e)&&clearTimeout(fe.get(e));let s=()=>{try{let r=JSON.stringify(t),a=new Blob([r]).size;localStorage.setItem(e,r);let n=e.startsWith("lego:")?e:`lego:${e}`;re.set(n,{timestamp:Date.now(),size:a}),fe.delete(e)}catch(r){if(r.name==="QuotaExceededError"){console.warn(`[Lego] Storage quota exceeded for key: ${e}`);try{let a=JSON.stringify(t),n=new Blob([a]).size,i=tt(n*2);if(i.length>0){g.debug&&console.log(`[Lego] Evicted ${i.length} old keys, retrying save`),localStorage.setItem(e,a);let c=e.startsWith("lego:")?e:`lego:${e}`;re.set(c,{timestamp:Date.now(),size:n})}else g.onError(new Error("Storage quota exceeded and no keys available for eviction"),"quota",e)}catch{g.onError(new Error(`Critical: Could not save ${e} even after eviction`),"quota-critical",e)}}else console.error(`[Lego] Storage Error (${e}):`,r)}};o>0?fe.set(e,setTimeout(s,o)):s()},ye=e=>({__type:"lego-db",key:e,_default:void 0,_debounce:0,default(o){return this._default=o,this},debounce(o){return this._debounce=o,this},set(o,s=0){return He(e,o,s),T.has(e)&&T.get(e).forEach(({target:r,prop:a,el:n,batcher:i})=>{r[a]=o,n&&i&&i.add(n)}),o},get(){try{let o=localStorage.getItem(e);return o!==null?JSON.parse(o):null}catch(o){return console.warn(`[Lego] Failed to get localStorage value for key "${e}":`,o),null}},delete(){try{return localStorage.removeItem(e),re.delete(e.startsWith("lego:")?e:`lego:${e}`),T.has(e)&&T.get(e).forEach(({target:o,prop:s,el:r,batcher:a})=>{o[s]=null,r&&a&&a.add(r)}),!0}catch(o){return console.error(`[Lego] Failed to delete localStorage key "${e}":`,o),!1}}}),ze=e=>e&&e.__type==="lego-db",We=(e,t,o,s,r)=>{g.debug&&console.log("[Lego Trace] Reactive DB Init:",t,o);let a=o._default;try{let n=localStorage.getItem(o.key);n!==null&&(a=JSON.parse(n))}catch(n){console.warn(`[Lego] Failed to parse localStorage value for key "${o.key}":`,n)}e[t]=a,te.has(e)||te.set(e,{}),te.get(e)[t]={key:o.key,debounce:o._debounce},g.debug&&console.log("[Lego Trace] DB Metadata Set:",t,te.get(e)[t]),T.has(o.key)||T.set(o.key,new Set),T.get(o.key).add({target:e,prop:t,el:s,batcher:r})},Ie=(e,t,o)=>{let s=te.get(e);if(s&&s[t]){let r=s[t].key;He(r,o,s[t].debounce),T.has(r)&&T.get(r).forEach(({target:a,prop:n,el:i,batcher:c})=>{a!==e&&(a[n]=o,i&&c&&c.add(i))})}},qe=e=>{T.forEach(t=>{t.forEach(o=>{o.el===e&&t.delete(o)})})},je=()=>{typeof window<"u"&&window.addEventListener("storage",e=>{if(!(!e.key||!T.has(e.key)))try{let t=JSON.parse(e.newValue);T.get(e.key).forEach(({target:o,prop:s,el:r,batcher:a})=>{o[s]=t,r&&a&&a.add(r)})}catch(t){console.warn("[Lego] Cross-tab sync error:",t)}})};var K=(e,t,o=ee)=>{if(e===null||typeof e!="object"||pe(e))return e;if(J.has(e))return J.get(e);for(let a in e){let n=Object.getOwnPropertyDescriptor(e,a);if(n&&n.get)continue;let i=e[a];ze(i)&&We(e,a,i,t,o)}let s={get:(a,n)=>{let i=Reflect.get(a,n);return i!==null&&typeof i=="object"&&!pe(i)?K(i,t,o):i},set:(a,n,i,c)=>{if(n==="__proto__"||n==="constructor"||n==="prototype")return console.warn(`[Lego] Blocked setting dangerous property: "${n}"`),!0;let d=a[n];g.debug&&d!==i&&console.log("[Lego Trace] Reactive SET:",n,"Old:",d,"New:",i,"Target:",a);let l=c===J.get(a),u=Object.prototype.hasOwnProperty.call(a,n),f=!l&&u?Reflect.set(a,n,i):Reflect.set(a,n,i,c);return(l||u)&&d!==i&&(o.add(t),Ie(a,n,i)),f},deleteProperty:(a,n)=>{let i=Reflect.deleteProperty(a,n);return o.add(t),i}},r=new Proxy(e,s);return J.set(e,r),r};var rt=e=>{let t=e;for(;t;){let o=t.getAttribute&&t.getAttribute("b-error");if(o&&o.toLowerCase()!==e.tagName.toLowerCase())return{errorTag:o,targetElement:t};let s=t.tagName?t.tagName.toLowerCase():"",r=y[s];if(r){let a=r.getAttribute("b-error");if(a&&a.toLowerCase()!==e.tagName.toLowerCase())return{errorTag:a,targetElement:t}}t=t.parentElement||t.getRootNode&&t.getRootNode().host}return null},we=null,Ue=null,Ke=(e,t)=>{we=e,Ue=t},ot=(e,t,o)=>{if(!we||!Ue){console.error("[Lego] Error boundary dependencies not loaded",o);return}try{t.shadowRoot?t.shadowRoot.innerHTML="":t.innerHTML="";let s=document.createElement(e);s.$initialState={$error:{message:o.message,stack:o.stack,component:t.tagName.toLowerCase()}},(t.shadowRoot||t).appendChild(s),we(s)}catch(s){console.error("[Lego] Error boundary failed to render:",s),console.error("[Lego] Original error:",o)}},Ee=0,st=3,G=(e,t,o)=>{if(Ee>=st){console.error("[Lego] Error boundary recursion limit reached:",e),g.onError(e,o,t);return}let s=rt(t);if(s){Ee++;try{ot(s.errorTag,s.targetElement,e)}finally{Ee--}}else g.onError(e,o,t)};var de=(e,t,o=null)=>{let s=t._studs,r=i=>{let c=C(i);if(!c.bound){if(i.hasAttributes()){let d=i.attributes;for(let u=0;u<d.length;u++){let f=d[u];if(f.name.startsWith("@")){let m=f.name.slice(1).split("."),x=m[0],E=m.slice(1),L=p=>{if(E.includes("prevent")&&p.preventDefault(),E.includes("stop")&&p.stopPropagation(),!(E.includes("self")&&p.target!==p.currentTarget)){if(typeof KeyboardEvent<"u"&&p instanceof KeyboardEvent){if(E.includes("ctrl")&&!p.ctrlKey||E.includes("alt")&&!p.altKey||E.includes("shift")&&!p.shiftKey||E.includes("meta")&&!p.metaKey)return;let $=E.filter(h=>!["prevent","stop","self","ctrl","alt","shift","meta","capture","once","passive"].includes(h));if($.length>0){let h=p.key.toLowerCase();if(!$.some(_=>_==="enter"?h==="enter":_==="esc"||_==="escape"?h==="escape":_==="space"?h===" ":_==="tab"?h==="tab":_==="delete"?h==="delete":_==="backspace"?h==="backspace":_==="up"?h==="arrowup":_==="down"?h==="arrowdown":_==="left"?h==="arrowleft":_==="right"?h==="arrowright":_==="alpha"?/^[a-z]$/.test(h):_==="numbers"?/^[0-9]$/.test(h):_===h))return}}try{let $=s;if(o){let v=S(o.listName,{state:s,global:w,self:t})[o.index];$=Object.assign(Object.create(s),{[o.name]:v})}S(f.value,{state:$,global:w,self:i,event:p,$event:p},!0)}catch($){G($,t,"event-handler")}}};i.addEventListener(x,L),c.listeners||(c.listeners=[]),c.listeners.push({eventName:x,handler:L})}}let l=z(i);if(l){let u=l.value,f=l.name.split(".").slice(1),m=f.includes("lazy"),x=f.includes("number"),E=f.includes("trim"),L=()=>{try{let p,$;if(u.startsWith("global.")){let v=u.slice(7).split(".");$=v.pop(),p=v.reduce((_,P)=>_[P],w)}else if(o&&u.startsWith(`${o.name}.`)){let _=S(o.listName,{state:s,global:w,self:t})[o.index];if(!_)return;let P=u.split(".").slice(1);$=P.pop(),p=P.reduce((I,xe)=>I[xe],_)}else{let v=u.split(".");$=v.pop(),p=v.reduce((_,P)=>_[P],s)}let h=i.type==="checkbox"?i.checked:i.value;if(E&&typeof h=="string"&&(h=h.trim()),x){let v=parseFloat(h);isNaN(v)||(h=v)}p&&p[$]!==h&&(p[$]=h)}catch(p){g.onError(p,"sync-update",i)}};i._bSyncHandler=L,c.listeners||(c.listeners=[]),m||(i.addEventListener("input",L),c.listeners.push({eventName:"input",handler:L})),i.addEventListener("change",L),c.listeners.push({eventName:"change",handler:L})}if(i.hasAttribute("b-var")){let u=i.getAttribute("b-var");s.$vars&&(s.$vars[u]=i)}}c.bound=!0}};e instanceof Element&&r(e);let a=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),n;for(;n=a.nextNode();)r(n)},nt=e=>{let t=[],o=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),s,r=[];for(;s=o.nextNode();){let a=s;if((c=>{let d=c.parentNode;for(;d&&d!==e;){if(d.hasAttribute&&d.hasAttribute("b-for"))return!0;d=d.parentNode}return!1})(s))continue;let i=c=>{if(/\bglobal\b/.test(c)){let d=e.host||e;q.add(d)}};if(s.nodeType===Node.ELEMENT_NODE){let c=!1;for(let[l,u]of Object.entries(Y))if(u.scan){let f=u.scan(s,{checkGlobal:i,getPrivateData:C,pendingOperations:r,current:a});f&&(t.push(f),f.terminal&&(c=!0))}if(c)continue;let[d]=X();[...s.attributes].forEach(l=>{l.value.includes(d)&&(i(l.value),t.push({type:"attr",node:s,attrName:l.name,template:l.value}))})}else if(s.nodeType===Node.TEXT_NODE){let[c]=X();s.textContent.includes(c)&&(i(s.textContent),t.push({type:"text",node:s,template:s.textContent}))}}return r.forEach(a=>a()),t},at=(e,t)=>{let o=a=>{if(a.nodeType===Node.TEXT_NODE){a._tpl===void 0&&(a._tpl=a.textContent);let n=a._tpl.replace(Q(),(i,c)=>S(c.trim(),{state:t,global:w,self:a},!1)??"");a.textContent!==n&&(a.textContent=n)}else if(a.nodeType===Node.ELEMENT_NODE){let[n]=X();[...a.attributes].forEach(i=>{if(i._tpl===void 0&&(i._tpl=i.value),i._tpl.includes(n)){let c=i._tpl.replace(Q(),(d,l)=>S(l.trim(),{state:t,global:w,self:a},!1)??"");i.value!==c&&(i.value=c,i.name==="class"&&(a.className=c))}})}};o(e);let s=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),r;for(;r=s.nextNode();)o(r)},oe=e=>{g.debug&&console.log("[Lego Trace] render() called for:",e.tagName);let t=e._studs;if(!t)return;let o=C(e);if(!o.rendering){o.rendering=!0,g.metrics&&g.metrics.onRenderStart&&g.metrics.onRenderStart(e);try{let s=e.shadowRoot||e;o.bindings||(o.bindings=nt(s)),o.bindings.forEach(r=>{let a=Y[r.type];if(a){a.execute({binding:r,state:t,global:w,helpers:{bind:de,updateNodeBindings:at,contextEl:e}});return}if(r.type==="text"){let n=r.template.replace(Q(),(i,c)=>S(c.trim(),{state:t,global:w,self:r.node},!1)??"");r.node.textContent!==n&&(r.node.textContent=n)}if(r.type==="attr"){let n=r.template.replace(Q(),(i,c)=>S(c.trim(),{state:t,global:w,self:r.node},!1)??"");r.node.getAttribute(r.attrName)!==n&&(r.node.setAttribute(r.attrName,n),r.attrName==="class"&&(r.node.className=n))}})}catch(s){G(s,e,"render")}finally{g.metrics&&g.metrics.onRenderEnd&&g.metrics.onRenderEnd(e),o.rendering=!1}}};var Ge=new Map,Je={},Ve=e=>{Je=e},Xe=async()=>{let e=Object.entries(Je).map(async([t,o])=>{let s=await Promise.all(o.map(async r=>{try{if(r instanceof CSSStyleSheet)return r;let a=await fetch(r);if(!a.ok)throw new Error(`Status ${a.status}`);let n=await a.text(),i=new CSSStyleSheet;return await i.replace(n),i}catch(a){return console.error(`[Lego] Failed to load stylesheet: ${r}`,a),null}}));Ge.set(t,s.filter(r=>r!==null))});await Promise.all(e),g.debug&&console.log("[Lego Debug] Re-applying stylesheets to",A.size,"blocks"),A.forEach(t=>{ve(t)})},ve=e=>{if(!e.shadowRoot&&!e._legoShadow)return;let t=e.shadowRoot||e._legoShadow,o=e.tagName.toLowerCase(),s=y[o],r=(s&&s.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),a=(e.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),n=[],i=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;i;){let u=(i.getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);u.length&&n.push(...u);let f=i.tagName?i.tagName.toLowerCase():"";if(y[f]){let m=(y[f].getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);m.length&&n.push(...m)}i=i.parentElement||i.getRootNode&&i.getRootNode().host}let c=[...new Set([...r,...a])],d=[...new Set(n)],l=[...new Set([...d,...c])];if(l.length>0){let u=l.flatMap(f=>Ge.get(f)||[]);if(u.length>0&&g.debug&&console.log("[Lego Debug] Applying styles to",e.tagName,"- Names:",l,"- Sheets:",u.length),u.length>0){let f=t.adoptedStyleSheets.filter(m=>!u.includes(m));t.adoptedStyleSheets=[...f,...u]}}e._studsMeta={stylesheets:{explicit:c,inherited:d,applied:l}}};var N=e=>{if(g.debug&&console.log("[Lego Trace] snap() called for:",e.tagName),!e||e.nodeType!==Node.ELEMENT_NODE)return;let t=C(e),o=e.tagName.toLowerCase(),s=y[o];if(s&&!t.snapped){t.snapped=!0;let a=s.content.cloneNode(!0),n=e.shadowRoot;n?n.innerHTML="":n=e.attachShadow({mode:"open"}),ve(e);let i=U(e,"*")||U(e.getRootNode().host,"*"),c=i&&i.state?i.state:{},d=j.get(o)||{},l=be(s.getAttribute("b-logic")||s.getAttribute("b-data")||"{}"),u=be(e.getAttribute("b-logic")||e.getAttribute("b-data")||"{}",c),f={$vars:{},$element:e,get $parent(){return U(e,"*")},$emit:(E,L)=>{e.dispatchEvent(new CustomEvent(E,{detail:L,bubbles:!0,composed:!0}))},get $route(){return w.$route},get $go(){return w.$go},get $mount(){return w.$mount}};W(d,f),W(l,f),W(u,f),e.$initialState&&(W(e.$initialState,f),delete e.$initialState),e._studs=K(f,e),Object.defineProperty(e,"state",{get(){return this._studs},set(E){Object.assign(this._studs,E)},configurable:!0,enumerable:!1}),H.locked=!0;try{n.appendChild(a)}finally{H.locked=!1}let m=n.querySelector("style");if(m&&(m.textContent=m.textContent.replace(/(?<![-\w])self(?![-\w])/g,":host")),de(n,e),A.add(e),oe(e),e.setAttribute("b-id",o),e._legoShadow||(e._legoShadow=n),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(E){G(E,e,"mounted")}let x=n.querySelectorAll("*");g.debug&&console.log("[Lego Debug] Nested scan in",e.tagName,"- Found elements:",x.length),x.forEach(E=>{let L=E.tagName.toLowerCase(),p=!!y[L];p&&g.debug&&console.log("[Lego Debug] Checking",L,"- Registered:",p),p&&N(E)})}let r=e.parentElement;for(;r&&!r._studs;)r=r.parentElement;r&&r._studs&&de(e,r),[...e.children].forEach(N)},M=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(o){G(o,e,"unmounted")}if(e.shadowRoot){let o=document.createTreeWalker(e.shadowRoot,NodeFilter.SHOW_ELEMENT),s;for(;s=o.nextNode();){let r=O.get(s);r&&r.listeners&&(r.listeners.forEach(({eventName:a,handler:n})=>{s.removeEventListener(a,n)}),r.listeners=null)}[...e.shadowRoot.children].forEach(M)}qe(e),A.delete(e),q.delete(e),e._studs&&(e._studs.$element=null,e._studs.$vars&&(Object.keys(e._studs.$vars).forEach(o=>{e._studs.$vars[o]=null}),e._studs.$vars=null),e._studs.$emit&&(e._studs.$emit=null),delete e._studs.$parent,delete e._studs.$route,delete e._studs.$go,delete e._studs.$mount,e._studs=null),e.hasOwnProperty("state")&&delete e.state;let t=O.get(e);t&&(t.bindings&&(t.bindings.forEach(o=>{let s=Y[o.type];if(s&&s.destroy)try{s.destroy({binding:o})}catch(r){console.error(`[Lego] Error in directive cleanup (${o.type}):`,r)}o.node=null,o.anchor=null}),t.bindings=null),t.anchor=null,O.delete(e)),[...e.children].forEach(M)};function Qe(e,t="block.lego"){let o={template:"",script:"",style:"",stylesAttr:"",cascadeAttr:"",errorAttr:"",blockName:_e(t),hasTemplate:!1,hasScript:!1,hasStyle:!1},s=e,r=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;s;){let a=s.match(r);if(!a)break;let n=a[1].toLowerCase(),i=a[2],c=a[0],d=a.index,l=`</${n}>`,u=d+c.length,f=s.indexOf(l,u);if(f===-1){console.warn(`[Lego] Unclosed <${n}> tag in ${t}`);break}let m=s.slice(u,f);if(n==="template"){o.hasTemplate=!0,o.template=m.trim();let x=i.match(/b-stylesheets=["']([^"']+)["']/);x&&(o.stylesAttr=x[1]);let E=i.match(/b-cascade=["']([^"']+)["']/);E&&(o.cascadeAttr=E[1]);let L=i.match(/b-error=["']([^"']+)["']/);L&&(o.errorAttr=L[1])}else if(n==="script"){o.hasScript=!0,o.script=m.trim();let x=i.match(/lang=["']([^"']+)["']/);x&&(o.scriptLang=x[1])}else n==="style"&&(o.hasStyle=!0,o.style=m.trim());s=s.slice(f+l.length)}return o}var Ze=(e,t,o="block.lego")=>{let s=Qe(t,o),{blockName:r,template:a,script:n,style:i,stylesAttr:c,cascadeAttr:d,errorAttr:l}=s,u={};if(n)try{let m=n.trim(),x=m.match(/export\s+default\s+(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*({[\s\S]*})/),E=x?x[1]:m;u=new Function("Lego","$db",`return ${E}`)(e,e.globals.$db)}catch(m){g.onError(m,"script",r)}let f=a;i&&(f=`<style>${i}</style>`+f),y[r]=document.createElement("template"),y[r].innerHTML=f,c&&y[r].setAttribute("b-stylesheets",c),d&&y[r].setAttribute("b-cascade",d),l&&y[r].setAttribute("b-error",l),j.set(r,u),document.querySelectorAll(r).forEach(m=>!C(m).snapped&&N(m))};ee.setHandler(oe);Ke(N,oe);Le(N);Ne(N,M);var it={url:typeof window<"u"?window.location.pathname:"/",route:"",params:{},query:{},method:"GET",body:null},ct={add(){q.forEach(e=>ee.add(e))}},B=K({$route:it,$go:(e,...t)=>le(e,...t)(document.body),$mount:(e,t,o)=>R(e,t,o),$db:ye},typeof document<"u"?document.body:null,ct);$e(B);var b={db:ye,snap:N,unsnap:M,mount:R,defineLegoFile:(e,t)=>Ze(b,e,t),block:(e,t,o={},s="",r="",a="")=>{let n=document.createElement("template");n.setAttribute("b-id",e),n.setAttribute("b-stylesheets",s),r&&n.setAttribute("b-cascade",r),a&&n.setAttribute("b-error",a),n.innerHTML=t,y[e]=n,j.set(e,o);try{let i={};W(o,i),ne.set(e.toLowerCase(),K(i,document.body))}catch(i){g.onError(i,"define",e)}if(customElements.get(e))document.querySelectorAll(e).forEach(i=>{M(i),N(i)}),A.forEach(i=>{i._legoShadow&&i._legoShadow.querySelectorAll(e).forEach(c=>{M(c),N(c)})});else try{customElements.define(e,class extends HTMLElement{connectedCallback(){H.locked||y[e]&&N(this)}disconnectedCallback(){M(this)}})}catch(i){console.warn(`[Lego] Failed to register web component ${e}:`,i)}},getActiveBlocksCount:()=>A.size,getLegos:()=>Object.keys(y),config:g,globals:B,route:(e,t,o=null)=>{let s=[],r=e==="*"?".*":e;r=r.replace(/:([^\/]+)|[.*+?^${}()|[\]\\]/g,(a,n)=>n?(s.push(n),"([^/]+)"):"\\"+a),Z.push({path:e,regex:new RegExp(`^${r}$`),tagName:t,paramNames:s,middleware:o})},debug:{stylesheets:e=>!e||!e._studsMeta?null:e._studsMeta.stylesheets},init:async(e=document.body,t={})=>{if((!e||typeof e.nodeType!="number")&&(e=document.body),Ve(t.styles||{}),g.loader=t.loader,g.debug=t.debug===!0,await Xe(),Z.length>0){let r=window.location.pathname,a=window.location.search,n=ge(r);if(n){let{match:i,params:c}=n,d=Object.fromEntries(new URLSearchParams(a));B.$route.url=r+a,B.$route.route=i.path,B.$route.params=c,B.$route.query=d,B.$route.method="GET",B.$route.body=null}}document.querySelectorAll("template[b-id]").forEach(r=>{let a=r.getAttribute("b-id");y[a]=r,customElements.get(a)||customElements.define(a,class extends HTMLElement{connectedCallback(){H.locked||y[a]&&N(this)}disconnectedCallback(){M(this)}})});let o=r=>{if(!r)return{};let a={};return Object.entries(r).forEach(([n,i])=>{if(typeof i=="function")a[n]=i();else if(typeof i=="string"&&i.startsWith("$db.")){let c=i.slice(4);a[n]=b.db(c).get()}else if(typeof i=="string"&&i.startsWith("$globals.")){let c=i.slice(9);a[n]=w[c]}else a[n]=i}),a},s=(r,a,n={})=>{customElements.get(r)||customElements.define(r,class extends HTMLElement{async connectedCallback(){if(y[r]){H.locked||N(this);return}if(b._fetching||(b._fetching=new Set),b._pendingLazy||(b._pendingLazy={}),b._fetching.has(r)){b._pendingLazy[r]||(b._pendingLazy[r]=new Set),b._pendingLazy[r].add(this);return}b._fetching.add(r);try{let i=a.startsWith("POST:")?"POST":"GET",c=a.replace(/^POST:/,""),d=o(n.headers),l={method:i,headers:d,credentials:n.credentials},u=await fetch(c,l);if(!u.ok)throw new Error(`HTTP ${u.status} loading block "${r}" from ${c}`);let f=await u.text();b.defineLegoFile(f,`${r}.lego`),y[r]&&N(this);let m=b._pendingLazy[r];m&&(m.forEach(x=>{x.isConnected&&y[r]&&!C(x).snapped&&N(x)}),delete b._pendingLazy[r])}catch(i){console.error(`[Lego] Failed to load manifest block ${r}:`,i)}finally{b._fetching.delete(r)}}disconnectedCallback(){M(this)}})};if(t.manifest){let r=t.manifest;if(r.url&&typeof r.url=="string")try{let n=o(r.headers);r=await(await fetch(r.url,{headers:n,credentials:r.credentials})).json()}catch(n){console.error("[Lego] Failed to load manifest:",n),r=[]}else if(typeof r=="string")try{r=await(await fetch(r)).json()}catch(n){console.error("[Lego] Failed to load manifest:",n),r=[]}let a=Array.isArray(r)?r:[r];for(let n of a){let i=n.base||"",c=n.suffix===!0?".lego":n.suffix||"",d={headers:n.headers||{},credentials:n.credentials};n.legos&&n.legos.forEach(l=>{s(l,`${i}${l}${c}`,d)}),n.map&&Object.entries(n.map).forEach(([l,u])=>{let f=u.match(/^https?:|^\//)?u:`${i}${u}`;s(l,f,d)})}}if(g.loader){let r=n=>{if(n.nodeType!==Node.ELEMENT_NODE)return;let i=n.tagName.toLowerCase();if(i.includes("-")&&!y[i]&&!A.has(n)){if(b._fetching&&b._fetching.has(i))return;b._fetching||(b._fetching=new Set),b._fetching.add(i);let c=g.loader(i);if(c){let d=typeof c=="string"?fetch(c).then(l=>l.text()):c;Promise.resolve(d).then(l=>{b.defineLegoFile(l,`${i}.lego`),b._fetching.delete(i)}).catch(l=>{console.error(`[Lego] Failed to load ${i}:`,l),b._fetching.delete(i)})}}if(n.children.length>0){let c=n.firstElementChild;for(;c;)r(c),c=c.nextElementSibling}};b._discoveryObserver&&b._discoveryObserver.disconnect(),b._discoveryObserver=new MutationObserver(n=>n.forEach(i=>{i.addedNodes.forEach(r)})),b._discoveryObserver.observe(e,{childList:!0,subtree:!0});let a=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;a.nextNode();)r(a.currentNode)}if(t.studio){if(!y["lego-studio"]){let r=document.createElement("script");r.src="https://unpkg.com/@legodom/studio@0.0.2/dist/lego-studio.js",r.onerror=()=>console.warn("[Lego] Failed to load Studio from CDN"),document.head.appendChild(r)}b.route("/_/studio","lego-studio"),b.route("/_/studio/:block","lego-studio")}Z.length>0&&(window.addEventListener("popstate",r=>{let a=r.state?.legoTargets||null;ce(a)}),document.addEventListener("submit",r=>{r.target.hasAttribute("b-action")&&r.preventDefault()}),document.addEventListener("click",r=>{let n=r.composedPath().find(i=>i.tagName==="A"&&(i.hasAttribute("b-target")||i.hasAttribute("b-link")));if(n){r.preventDefault();let i=n.getAttribute("href"),c=n.getAttribute("b-target"),d=c?c.split(/\s+/).filter(Boolean):[],l=n.getAttribute("b-link")!=="false";B.$go(i,...d).get(l)}}),ce()),je()}};typeof window<"u"?window.Lego=b:typeof global<"u"&&(global.Lego=b);var Ho=b;})();
7
+ `),We.set(e,n));let i={$ancestors:s=>V(t.self,s),$registry:s=>ee.get(s.toLowerCase()),$element:t.self,$route:_.$route,$params:_.$route?.params||{},$go:(s,...c)=>ge(s,...c)(t.self),$db:_.$db,$mount:(s,c,f)=>F(s,c,f),$emit:(s,c)=>{t.self.dispatchEvent(new CustomEvent(s,{detail:c,bubbles:!0,composed:!0}))}},a=n.call(o,t.global,t.self,t.event,i);return typeof a=="function"&&t.event!==void 0?a.call(o,t.event):a}catch(o){if(r)throw o;if(o instanceof ReferenceError&&!g.strict)return;throw o}},_e=(e,t={})=>{if(!e||e.trim()==="{}")return{};let[r,o]=oe();if(e.includes(r)&&e.includes(o))return console.error(`[Lego] Refusing to parse b-logic containing template delimiters ("${r}...${o}"). b-logic is evaluated as JavaScript; templating user data into it is unsafe. Pass values through state instead. Got: "${e.length>80?e.slice(0,80)+"...":e}"`),{};let n=a=>{let s=Ie.get(a);return s||(s=new Function("scope","global",`with(global) { with(scope) { return (${a}); } }`),Ie.set(a,s)),s},i=a=>n(a)(t,_);try{return i(e)}catch(a){let s=e.trim();if(!s.startsWith("{")&&s.includes(":"))try{return i(`{${e}}`)}catch{}return console.error(`[Lego] Error parsing b-logic: "${e.length>80?e.slice(0,80)+"...":e}"`,a),{}}};var qe={name:"b-if",scan:(e,{checkGlobal:t,getPrivateData:r})=>O("b-if",e,(o,n)=>{t(o.value);let i=document.createComment(`b-if: ${o.value}`),a=r(n);return a.anchor=i,{anchor:i}}),execute({binding:e,state:t,global:r}){let{node:o,anchor:n,expr:i}=e,a=!!L(i,{state:t,global:r,self:o}),s=!!o.parentNode;a&&!s?n.parentNode&&n.parentNode.replaceChild(o,n):!a&&s&&o.parentNode.replaceChild(n,o)},destroy({binding:e}){e.anchor&&e.anchor.parentNode&&e.anchor.remove()}};var je={name:"b-show",scan(e,{checkGlobal:t}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-show")){let r=e.getAttribute("b-show");return t(r),{type:"b-show",node:e,expr:r}}},execute({binding:e,state:t,global:r}){let{node:o,expr:n}=e;o._bShowOriginal===void 0&&(o._bShowOriginal=o.style.display);let i=!!L(n,{state:t,global:r,self:o});o.style.display=i?o._bShowOriginal:"none"}};var Ke={name:"b-text",scan(e,{checkGlobal:t}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-text")){let r=e.getAttribute("b-text");return t(r),{type:"b-text",node:e,path:r}}},execute({binding:e,state:t,global:r}){let{node:o,path:n}=e;n.startsWith("global.")?o.textContent=D(n.slice(7),r)??"":o.textContent=D(n,t)??""}};var Ge={name:"b-html",scan:e=>O("b-html",e),execute:({binding:e,state:t,global:r,helpers:o})=>{let{node:n,expr:i,modifiers:a}=e,s=L(i,{state:t,global:r,self:n})??"";if(a&&a.includes("safe")&&(s=(typeof g.sanitize=="function"?g.sanitize:Re)(s)),n._bHtmlPrev!==s){n._bHtmlPrev=s;let c=o&&o.contextEl;if(c){let f=A.get(c);if(f&&f.bindings&&f.bindings.length){for(let l of f.bindings)l!==e&&l.node&&l.node!==n&&n.contains(l.node)&&(l.dead=!0,l.node=null);f.bindings.some(l=>l.dead)&&(f.bindings=f.bindings.filter(l=>!l.dead))}}n.innerHTML=s}},destroy({binding:e}){let{node:t}=e;t&&(delete t._bHtmlPrev,t.innerHTML="")}};var Ue={name:"b-sync",scan(e,{checkGlobal:t}){if(e.nodeType!==Node.ELEMENT_NODE)return;let r=K(e);if(!r)return;t(r.value);let o=r.name.split(".").slice(1);return{type:"b-sync",node:e,expr:r.value,modifiers:o}},execute({binding:e,state:t,global:r}){let{node:o,expr:n}=e;n.startsWith("global.")?re(o,D(n.slice(7),r)??""):re(o,D(n,t)??"")},destroy({binding:e}){let{node:t}=e;t&&t._bSyncHandler&&(t.removeEventListener("input",t._bSyncHandler),t.removeEventListener("change",t._bSyncHandler),delete t._bSyncHandler)}};var Tt=0,Je={name:"b-for",scan(e,{checkGlobal:t,pendingOperations:r}){if(e.nodeType!==Node.ELEMENT_NODE)return;let o=e.getAttribute("b-for")?.match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);if(o){t(o[2]);let n=document.createComment(`b-for: ${o[1]} in ${o[2].trim()}`);return r.push(()=>{e.parentNode&&(e.parentNode.insertBefore(n,e),e.remove())}),{type:"b-for",anchor:n,itemName:o[1],listName:o[2].trim(),keyPath:e.getAttribute("b-key")||null,template:e.cloneNode(!0),terminal:!0}}},execute({binding:e,state:t,global:r,helpers:o}){let{bind:n,scanForBindings:i,runBinding:a}=o;if(!n||!a){console.error("[Lego] b-for directive missing required helpers: bind, runBinding");return}let{anchor:s,listName:c,itemName:f,keyPath:l,template:u}=e,{contextEl:d}=o,p=L(c,{state:t,global:r,self:d})||[];W.has(s)||W.set(s,new Map);let m=W.get(s),h=new Set,x=[];p.forEach((w,E)=>{let $;l?($=D(l,w),($==null||$==="")&&(console.warn(`[Lego] b-key="${l}" could not resolve a value for item at index ${E}. Falling back to index-based key.`),$=`__bfor_${E}`)):w&&typeof w=="object"?($=w.id||w._id||w.uuid||w.key,$===void 0&&(ue.has(w)||ue.set(w,++Tt),$=ue.get(w))):$=`${E}-${w}`,h.add($);let b=m.get($);b?b._loopCtx.index=E:(b=u.cloneNode(!0),b.removeAttribute("b-for"),b.removeAttribute("b-key"),m.set($,b),b._loopCtx={name:f,listName:c,index:E},n(b,d,b._loopCtx),i&&(b._loopBindings=i(b,d)));let k=b._loopScope;if(k||(b._loopScope=k=Object.create(t)),k[f]=w,k.$index=E,b._loopBindings)for(let P of b._loopBindings)try{a(P,k,d,!1)}catch(Oe){console.error("[Lego] Error in b-for inner binding:",Oe)}[b,...b.querySelectorAll("*")].filter(P=>K(P)).forEach(P=>{let Be=K(P).value;Be.startsWith(`${f}.`)&&re(P,D(Be.split(".").slice(1).join("."),p[E]))}),x.push(b)});let y=s.nextSibling;x.forEach(w=>{w!==y?s.parentNode.insertBefore(w,y):y=y.nextSibling});for(let[w,E]of m.entries())h.has(w)||(E.remove(),m.delete(w))},destroy({binding:e}){let{anchor:t}=e;if(t&&W.has(t)){let r=W.get(t);r.forEach(o=>{[o,...o.querySelectorAll("*")].forEach(i=>{let a=A.get(i);a&&(a.listeners&&(a.listeners.forEach(({eventName:s,handler:c})=>{i.removeEventListener(s,c)}),a.listeners=null),a.bindings&&(a.bindings.forEach(s=>{s.observer&&(s.observer.disconnect(),s.observer=null)}),a.bindings=null))}),o.remove()}),r.clear(),W.delete(t)}t&&t.parentNode&&t.remove()}};var Ve={scan:e=>{if(e.hasAttribute("b-init"))return{type:"b-init",node:e,expr:e.getAttribute("b-init")}},execute:({binding:e,state:t,global:r})=>{e.initialized||(e.initialized=!0,L(e.expr,{state:t,global:r,self:e.node}))}};var Xe={name:"b-enter",scan:e=>O("b-enter",e,(t,r)=>({modifiers:t.name.split(".").slice(1)})),execute:({binding:e,state:t,global:r})=>{if(e.observer||e.done)return;let o=new IntersectionObserver((n,i)=>{if(n[0].isIntersecting){try{L(e.expr,{state:t,global:r,self:e.node})}catch(s){console.error("[Lego] Error in b-enter handler:",s)}e.modifiers.includes("once")&&(i.disconnect(),e.observer=null,e.done=!0)}});o.observe(e.node),e.observer=o},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Ze={name:"b-leave",scan:e=>O("b-leave",e),execute:({binding:e,state:t,global:r})=>{if(e.observer||e.done)return;let o=new IntersectionObserver((n,i)=>{let a=n[0];if(a.isIntersecting&&(e.activated=!0),!a.isIntersecting&&e.activated){try{L(e.expr,{state:t,global:r,self:e.node})}catch(s){console.error("[Lego] Error in b-leave handler:",s)}e.modifiers.includes("once")&&(i.disconnect(),e.observer=null,e.done=!0)}});o.observe(e.node),e.observer=o},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Qe={name:"b-mount",scan:(e,{checkGlobal:t})=>O("b-mount",e,r=>(t(r.value),{_lastTag:null})),execute({binding:e,state:t,global:r}){let{node:o,expr:n}=e,i=L(n,{state:t,global:r,self:o},!1),a=i?String(i).toLowerCase():null;a!==e._lastTag&&(e._lastTag=a,F(a,o))},destroy({binding:e}){e.node&&F(null,e.node),e._lastTag=null}};var se={"b-if":qe,"b-show":je,"b-text":Ke,"b-html":Ge,"b-sync":Ue,"b-for":Je,"b-init":Ve,"b-enter":Xe,"b-leave":Ze,"b-mount":Qe};var At=(e=null)=>{let t=!1,r=new Set,o=!1,n=e,i=new Set,a=null,s=new Set,c=d=>{n=d},f=()=>{a||(a=setTimeout(()=>{s.forEach(d=>{let p=d._studs;if(p&&typeof p.updated=="function")try{p.updated.call(p)}catch(m){console.error("[Lego] Error in updated hook:",m)}}),s.clear(),a=null},50))},l=()=>{i.size>0&&(i.forEach(d=>r.add(d)),i.clear(),!t&&r.size>0&&(t=!0,requestAnimationFrame(u)))},u=()=>{o=!0;let d=Array.from(r);r.clear(),t=!1,d.forEach(p=>{p.isConnected&&n&&n(p)}),d.forEach(p=>s.add(p)),f(),o=!1,l()};return{add:d=>{if(d){if(o){i.add(d);return}r.add(d),!t&&(t=!0,requestAnimationFrame(u))}},setHandler:c}},X=At();var N=new Map,he=new Map,ie=new WeakMap,le=new Map,ae=new WeakMap,ce=!1,kt=e=>{let t=Array.from(le.entries()).sort((n,i)=>n[1].timestamp-i[1].timestamp),r=0,o=[];for(let[n,i]of t){if(r>=e)break;try{localStorage.removeItem(n),r+=i.size,o.push(n),le.delete(n)}catch(a){console.error(`[Lego] Failed to evict ${n}:`,a)}}return o},et=(e,t,r)=>{g.debug&&console.log("[Lego Trace] scheduleSave",e,t,r),he.has(e)&&clearTimeout(he.get(e));let o=()=>{try{let n=JSON.stringify(t),i=new Blob([n]).size;localStorage.setItem(e,n),le.set(e,{timestamp:Date.now(),size:i}),he.delete(e)}catch(n){if(n.name==="QuotaExceededError"){console.warn(`[Lego] Storage quota exceeded for key: ${e}`);try{let i=JSON.stringify(t),a=new Blob([i]).size,s=kt(a*2);s.length>0?(g.debug&&console.log(`[Lego] Evicted ${s.length} old keys, retrying save`),localStorage.setItem(e,i),le.set(e,{timestamp:Date.now(),size:a})):g.onError(new Error("Storage quota exceeded and no keys available for eviction"),"quota",e)}catch{g.onError(new Error(`Critical: Could not save ${e} even after eviction`),"quota-critical",e)}}else console.error(`[Lego] Storage Error (${e}):`,n)}};r>0?he.set(e,setTimeout(o,r)):o()},Le=e=>({__type:"lego-db",key:e,_default:void 0,_debounce:0,default(r){return this._default=r,this},debounce(r){return this._debounce=r,this},set(r,o=0){return et(e,r,o),N.has(e)&&N.get(e).forEach(({target:n,prop:i,el:a,batcher:s})=>{n[i]=r,a&&s&&s.add(a)}),r},get(){try{let r=localStorage.getItem(e);return r!==null?JSON.parse(r):null}catch(r){return console.warn(`[Lego] Failed to get localStorage value for key "${e}":`,r),null}},delete(){try{return localStorage.removeItem(e),le.delete(e),N.has(e)&&N.get(e).forEach(({target:r,prop:o,el:n,batcher:i})=>{r[o]=null,n&&i&&i.add(n)}),!0}catch(r){return console.error(`[Lego] Failed to delete localStorage key "${e}":`,r),!1}}}),tt=e=>e&&e.__type==="lego-db",rt=(e,t,r,o,n)=>{g.debug&&console.log("[Lego Trace] Reactive DB Init:",t,r);let i=r._default;try{let s=localStorage.getItem(r.key);s!==null&&(i=JSON.parse(s))}catch(s){console.warn(`[Lego] Failed to parse localStorage value for key "${r.key}":`,s)}e[t]=i,ie.has(e)||ie.set(e,{}),ie.get(e)[t]={key:r.key,debounce:r._debounce},g.debug&&console.log("[Lego Trace] DB Metadata Set:",t,ie.get(e)[t]),N.has(r.key)||N.set(r.key,new Set);let a={target:e,prop:t,el:o,batcher:n};N.get(r.key).add(a),o&&(ae.has(o)||ae.set(o,new Set),ae.get(o).add({key:r.key,entry:a}))},ot=(e,t,r)=>{if(ce)return;let o=ie.get(e);if(o&&o[t]){let n=o[t].key;if(et(n,r,o[t].debounce),N.has(n)){ce=!0;try{N.get(n).forEach(({target:i,prop:a,el:s,batcher:c})=>{i!==e&&(i[a]=r,s&&c&&c.add(s))})}finally{ce=!1}}}},nt=e=>{let t=ae.get(e);t&&(t.forEach(({key:r,entry:o})=>{let n=N.get(r);n&&n.delete(o)}),ae.delete(e))},Ye=!1,st=()=>{typeof window>"u"||Ye||(Ye=!0,window.addEventListener("storage",e=>{if(!(!e.key||!N.has(e.key)))try{let t=e.newValue===null?null:JSON.parse(e.newValue);ce=!0;try{N.get(e.key).forEach(({target:r,prop:o,el:n,batcher:i})=>{r[o]=t,n&&i&&i.add(n)})}finally{ce=!1}}catch(t){console.warn("[Lego] Cross-tab sync error:",t)}}))};var Te=new WeakMap,be=null,Ae=null,it=(e,t)=>{be=e,Ae=t},at=()=>{be=null,Ae=null},ct=(e,t,r)=>{if(!be||Ae!==e)return;let o=Te.get(e);o||(o=new Map,Te.set(e,o));let n=o.get(t);n||(n=new Map,o.set(t,n));let i=n.get(r);i||(i=new Set,n.set(r,i)),i.add(be)},lt=(e,t,r)=>{let o=Te.get(e);if(!o)return null;let n=o.get(t);return n&&n.get(r)||null};var Z=(e,t,r=X)=>{if(e===null||typeof e!="object"||ve(e))return e;if(Y.has(e))return Y.get(e);for(let i in e){let a=Object.getOwnPropertyDescriptor(e,i);if(a&&a.get)continue;let s=e[i];tt(s)&&rt(e,i,s,t,r)}let o={get:(i,a,s)=>{ct(t,i,a);let c=Reflect.get(i,a,s);return c!==null&&typeof c=="object"&&!ve(c)?Z(c,t,r):c},set:(i,a,s,c)=>{if(a==="__proto__"||a==="constructor"||a==="prototype")return console.warn(`[Lego] Blocked setting dangerous property: "${a}"`),!0;let f=i[a];g.debug&&f!==s&&console.log("[Lego Trace] Reactive SET:",a,"Old:",f,"New:",s,"Target:",i);let l=c===Y.get(i),u=Object.prototype.hasOwnProperty.call(i,a),d=!l&&u?Reflect.set(i,a,s):Reflect.set(i,a,s,c);if((l||u)&&f!==s){let p=lt(t,i,a);if(p&&p.size>0){let m=A.get(t);m&&(m.dirtyBindings||(m.dirtyBindings=new Set),p.forEach(h=>m.dirtyBindings.add(h)))}r.add(t,a),ot(i,a,s)}return d},deleteProperty:(i,a)=>{let s=Reflect.deleteProperty(i,a),c=A.get(t);return c&&(c.dirtyBindings=null),r.add(t),s}},n=new Proxy(e,o);return Y.set(e,n),n};var Nt=e=>{let t=e;for(;t;){let r=t.getAttribute&&t.getAttribute("b-error");if(r&&r.toLowerCase()!==e.tagName.toLowerCase())return{errorTag:r,targetElement:t};let o=t.tagName?t.tagName.toLowerCase():"",n=S[o];if(n){let i=n.getAttribute("b-error");if(i&&i.toLowerCase()!==e.tagName.toLowerCase())return{errorTag:i,targetElement:t}}t=t.parentElement||t.getRootNode&&t.getRootNode().host}return null},ke=null,ft=null,dt=(e,t)=>{ke=e,ft=t},Ct=(e,t,r)=>{if(!ke||!ft){console.error("[Lego] Error boundary dependencies not loaded",r);return}try{t.shadowRoot?t.shadowRoot.innerHTML="":t.innerHTML="";let o=document.createElement(e);o.$initialState={$error:{message:r.message,stack:r.stack,component:t.tagName.toLowerCase()}},(t.shadowRoot||t).appendChild(o),ke(o)}catch(o){console.error("[Lego] Error boundary failed to render:",o),console.error("[Lego] Original error:",r)}},fe=new WeakMap,Mt=3,Q=(e,t,r)=>{let o=Nt(t);if(!o){g.onError(e,r,t);return}let n=o.targetElement,i=fe.get(n)||0;if(i>=Mt){console.error("[Lego] Error boundary recursion limit reached:",e),g.onError(e,r,t);return}fe.set(n,i+1);try{Ct(o.errorTag,n,e)}finally{let a=(fe.get(n)||0)-1;a<=0?fe.delete(n):fe.set(n,a)}};var ye=(e,t,r=null)=>{let o=t._studs,n=s=>{let c=M(s);if(!c.bound){if(s.hasAttributes()){let f=s.attributes;for(let u=0;u<f.length;u++){let d=f[u];if(d.name.startsWith("@")){let p=d.name.slice(1).split("."),m=p[0],h=p.slice(1),x=y=>{if(h.includes("prevent")&&y.preventDefault(),h.includes("stop")&&y.stopPropagation(),!(h.includes("self")&&y.target!==y.currentTarget)){if(typeof KeyboardEvent<"u"&&y instanceof KeyboardEvent){if(h.includes("ctrl")&&!y.ctrlKey||h.includes("alt")&&!y.altKey||h.includes("shift")&&!y.shiftKey||h.includes("meta")&&!y.metaKey)return;let w=h.filter(E=>!["prevent","stop","self","ctrl","alt","shift","meta","capture","once","passive"].includes(E));if(w.length>0){let E=y.key.toLowerCase();if(!w.some(b=>b==="enter"?E==="enter":b==="esc"||b==="escape"?E==="escape":b==="space"?E===" ":b==="tab"?E==="tab":b==="delete"?E==="delete":b==="backspace"?E==="backspace":b==="up"?E==="arrowup":b==="down"?E==="arrowdown":b==="left"?E==="arrowleft":b==="right"?E==="arrowright":b==="alpha"?/^[a-z]$/.test(E):b==="numbers"?/^[0-9]$/.test(E):b===E))return}}try{let w=o;if(r){let $=L(r.listName,{state:o,global:_,self:t})[r.index];w=Object.assign(Object.create(o),{[r.name]:$})}L(d.value,{state:w,global:_,self:s,event:y,$event:y},!0)}catch(w){Q(w,t,"event-handler")}}};s.addEventListener(m,x),c.listeners||(c.listeners=[]),c.listeners.push({eventName:m,handler:x})}}let l=K(s);if(l){let u=l.value,d=l.name.split(".").slice(1),p=d.includes("lazy"),m=d.includes("number"),h=d.includes("trim"),x=()=>{try{let y,w;if(u.startsWith("global.")){let $=u.slice(7).split(".");w=$.pop(),y=$.reduce((b,k)=>b[k],_)}else if(r&&u.startsWith(`${r.name}.`)){let b=L(r.listName,{state:o,global:_,self:t})[r.index];if(!b)return;let k=u.split(".").slice(1);w=k.pop(),y=k.reduce((Me,P)=>Me[P],b)}else{let $=u.split(".");w=$.pop(),y=$.reduce((b,k)=>b[k],o)}let E=s.type==="checkbox"?s.checked:s.value;if(h&&typeof E=="string"&&(E=E.trim()),m){let $=parseFloat(E);isNaN($)||(E=$)}y&&y[w]!==E&&(y[w]=E)}catch(y){g.onError(y,"sync-update",s)}};s._bSyncHandler=x,c.listeners||(c.listeners=[]),p||(s.addEventListener("input",x),c.listeners.push({eventName:"input",handler:x})),s.addEventListener("change",x),c.listeners.push({eventName:"change",handler:x})}if(s.hasAttribute("b-var")){let u=s.getAttribute("b-var");o.$vars&&(o.$vars[u]=s)}}c.bound=!0}};e instanceof Element&&n(e);let i=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),a;for(;a=i.nextNode();)n(a)},ut=(e,t=null)=>{let r=[],o=[],[n]=oe(),i=t||e.host||e,a=Object.entries(se),s=/\bglobal\.([\w$]+)([\w$.]*)/g,c=l=>{if(!/\bglobal\b/.test(l))return;let u=!1,d=new Set,p;for(s.lastIndex=0;(p=s.exec(l))!==null;){if((p[2]||"").includes(".")){u=!0;break}d.add(p[1])}if(d.size===0&&(u=!0),u){U.add(i);return}d.forEach(m=>{let h=I.get(m);h||(h=new Set,I.set(m,h)),h.add(i)})},f=l=>{if(l.nodeType===Node.ELEMENT_NODE){let u=!1;for(let[,d]of a){if(!d.scan)continue;let p=d.scan(l,{checkGlobal:c,getPrivateData:M,pendingOperations:o,current:l});p&&(r.push(p),p.terminal&&(u=!0))}if(u)return;for(let d of l.attributes)d.value.includes(n)&&(c(d.value),r.push({type:"attr",node:l,attrName:d.name,template:d.value}));for(let d=l.firstChild;d;d=d.nextSibling)f(d)}else l.nodeType===Node.TEXT_NODE&&l.textContent.includes(n)&&(c(l.textContent),r.push({type:"text",node:l,template:l.textContent}))};if(e.nodeType===Node.ELEMENT_NODE)for(let l of e.attributes)l.value.includes(n)&&(c(l.value),r.push({type:"attr",node:e,attrName:l.name,template:l.value}));else e.nodeType===Node.TEXT_NODE&&e.textContent.includes(n)&&(c(e.textContent),r.push({type:"text",node:e,template:e.textContent}));for(let l=e.firstChild;l;l=l.nextSibling)f(l);return o.forEach(l=>l()),r},Ne=(e,t,r,o=!0)=>{if(!e.dead){o&&it(e,r);try{let n=se[e.type];if(n){n.execute({binding:e,state:t,global:_,helpers:{bind:ye,scanForBindings:ut,runBinding:Ne,contextEl:r}});return}if(e.type==="text"){let i=e.template.replace(we(),(a,s)=>L(s.trim(),{state:t,global:_,self:e.node},!1)??"");e.node.textContent!==i&&(e.node.textContent=i)}else if(e.type==="attr"){let i=e.template.replace(we(),(a,s)=>L(s.trim(),{state:t,global:_,self:e.node},!1)??"");e.node.getAttribute(e.attrName)!==i&&(e.node.setAttribute(e.attrName,i),e.attrName==="class"&&(e.node.className=i))}}finally{o&&at()}}},de=e=>{g.debug&&console.log("[Lego Trace] render() called for:",e.tagName);let t=e._studs;if(!t)return;let r=M(e);if(!r.rendering){r.rendering=!0,g.metrics&&g.metrics.onRenderStart&&g.metrics.onRenderStart(e);try{let o=e.shadowRoot||e;if(r.bindings||(r.bindings=ut(o)),r.dirtyBindings&&r.dirtyBindings.size>0){let n=r.dirtyBindings;r.dirtyBindings=null,n.forEach(i=>Ne(i,t,e))}else r.bindings.forEach(n=>Ne(n,t,e))}catch(o){Q(o,e,"render")}finally{g.metrics&&g.metrics.onRenderEnd&&g.metrics.onRenderEnd(e),r.rendering=!1}}};var pt=new Map,H=new Map,mt={},gt=e=>{mt=e},ht=async()=>{let e=Object.entries(mt).map(async([t,r])=>{let o=await Promise.all(r.map(async n=>{try{if(n instanceof CSSStyleSheet)return n;let i=await fetch(n);if(!i.ok)throw new Error(`Status ${i.status}`);let a=await i.text(),s=new CSSStyleSheet;return await s.replace(a),s}catch(i){return console.error(`[Lego] Failed to load stylesheet: ${n}`,i),null}}));pt.set(t,o.filter(n=>n!==null))});await Promise.all(e),g.debug&&console.log("[Lego Debug] Re-applying stylesheets to",C.size,"blocks"),C.forEach(t=>{Ce(t)})},Ce=e=>{if(!e.shadowRoot&&!e._legoShadow)return;let t=e.shadowRoot||e._legoShadow,r=e.tagName.toLowerCase(),o=S[r],n=(o&&o.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),i=(e.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),a=[],s=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;s;){let u=(s.getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);u.length&&a.push(...u);let d=s.tagName?s.tagName.toLowerCase():"",p=H.get(d);p&&p.length&&a.push(...p),s=s.parentElement||s.getRootNode&&s.getRootNode().host}let c=[...new Set([...n,...i])],f=[...new Set(a)],l=[...new Set([...f,...c])];if(l.length>0){let u=l.flatMap(d=>pt.get(d)||[]);if(u.length>0&&g.debug&&console.log("[Lego Debug] Applying styles to",e.tagName,"- Names:",l,"- Sheets:",u.length),u.length>0){let d=t.adoptedStyleSheets.filter(p=>!u.includes(p));t.adoptedStyleSheets=[...d,...u]}}e._studsMeta={stylesheets:{explicit:c,inherited:f,applied:l}}};var bt=!1,T=e=>{if(g.debug&&console.log("[Lego Trace] snap() called for:",e.tagName),!e||e.nodeType!==Node.ELEMENT_NODE)return;let t=M(e),r=e.tagName.toLowerCase(),o=S[r];if(o&&!t.snapped){t.snapped=!0;let i=o.content.cloneNode(!0),a=e.shadowRoot;a?a.innerHTML="":a=e.attachShadow({mode:"open"}),Ce(e);let s=V(e,"*")||V(e.getRootNode().host,"*"),c=s&&s.state?s.state:{},f=q.get(r)||{},l=_e(o.getAttribute("b-logic")||o.getAttribute("b-data")||"{}"),u=_e(e.getAttribute("b-logic")||e.getAttribute("b-data")||"{}",c),d={$vars:{},$element:e,get $parent(){return V(e,"*")},$emit:(h,x)=>{e.dispatchEvent(new CustomEvent(h,{detail:x,bubbles:!0,composed:!0}))},get $route(){return _.$route},get $go(){return _.$go},get $mount(){return _.$mount}};G(f,d),G(l,d),G(u,d),e.$initialState&&(G(e.$initialState,d),delete e.$initialState),z.validate({instanceLogic:u,state:d,tagName:r}),e._studs=Z(d,e),Object.defineProperty(e,"state",{get(){return this._studs},set(h){bt||(bt=!0,console.warn("[Lego] `el.state = X` performs a shallow merge (Object.assign), not a replacement. Keys present on state but absent from X are preserved. Mutate state keys directly if you want this behaviour or remount the element to start fresh.")),Object.assign(this._studs,h)},configurable:!0,enumerable:!1}),j.locked=!0;try{a.appendChild(i)}finally{j.locked=!1}let p=a.querySelector("style");if(p){let h=[],x="__LEGO_SEG_",w=p.textContent.replace(/\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g,E=>(h.push(E),`${x}${h.length-1}__`)).replace(/(?<![-\w])self(?![-\w])/g,":host");p.textContent=w.replace(/__LEGO_SEG_(\d+)__/g,(E,$)=>h[+$])}if(ye(a,e),C.add(e),de(e),e.setAttribute("b-id",r),e._legoShadow||(e._legoShadow=a),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(h){Q(h,e,"mounted")}let m=a.querySelectorAll("*");g.debug&&console.log("[Lego Debug] Nested scan in",e.tagName,"- Found elements:",m.length),m.forEach(h=>{let x=h.tagName.toLowerCase(),y=!!S[x];y&&g.debug&&console.log("[Lego Debug] Checking",x,"- Registered:",y),y&&T(h)})}let n=e.parentElement;for(;n&&!n._studs;)n=n.parentElement;n&&n._studs&&ye(e,n),[...e.children].forEach(T)},B=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(r){Q(r,e,"unmounted")}if(e.shadowRoot){let r=document.createTreeWalker(e.shadowRoot,NodeFilter.SHOW_ELEMENT),o;for(;o=r.nextNode();){let n=A.get(o);n&&n.listeners&&(n.listeners.forEach(({eventName:i,handler:a})=>{o.removeEventListener(i,a)}),n.listeners=null)}[...e.shadowRoot.children].forEach(B)}nt(e),C.delete(e),U.delete(e),I.forEach(r=>r.delete(e)),e._studs&&(e._studs.$element=null,e._studs.$vars&&(Object.keys(e._studs.$vars).forEach(r=>{e._studs.$vars[r]=null}),e._studs.$vars=null),e._studs.$emit&&(e._studs.$emit=null),delete e._studs.$parent,delete e._studs.$route,delete e._studs.$go,delete e._studs.$mount,e._studs=null),e.hasOwnProperty("state")&&delete e.state;let t=A.get(e);t&&(t.bindings&&(t.bindings.forEach(r=>{let o=se[r.type];if(o&&o.destroy)try{o.destroy({binding:r})}catch(n){console.error(`[Lego] Error in directive cleanup (${r.type}):`,n)}r.node=null,r.anchor=null}),t.bindings=null),t.anchor=null,A.delete(e)),[...e.children].forEach(B)};function yt(e,t="block.lego"){let r={template:"",script:"",style:"",stylesAttr:"",cascadeAttr:"",errorAttr:"",propsAttr:"",blockName:Pe(t),hasTemplate:!1,hasScript:!1,hasStyle:!1},o=e,n=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;o;){let i=o.match(n);if(!i)break;let a=i[1].toLowerCase(),s=i[2],c=i[0],f=i.index,l=`</${a}>`,u=f+c.length,d=o.indexOf(l,u);if(d===-1){console.warn(`[Lego] Unclosed <${a}> tag in ${t}`);break}let p=o.slice(u,d);if(a==="template"){r.hasTemplate=!0,r.template=p.trim();let m=s.match(/b-stylesheets=["']([^"']+)["']/);m&&(r.stylesAttr=m[1]);let h=s.match(/b-cascade=["']([^"']+)["']/);h&&(r.cascadeAttr=h[1]);let x=s.match(/b-error=["']([^"']+)["']/);x&&(r.errorAttr=x[1]);let y=s.match(/b-props=["']([^"']+)["']/);y&&(r.propsAttr=y[1])}else if(a==="script"){r.hasScript=!0,r.script=p.trim();let m=s.match(/lang=["']([^"']+)["']/);m&&(r.scriptLang=m[1])}else a==="style"&&(r.hasStyle=!0,r.style=p.trim());o=o.slice(d+l.length)}return r}var Et=(e,t,r="block.lego")=>{let o=yt(t,r),{blockName:n,template:i,script:a,style:s,stylesAttr:c,cascadeAttr:f,errorAttr:l,propsAttr:u}=o,d={};if(a)try{let m=a.trim(),h=m.match(/export\s+default\s+(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*({[\s\S]*})/),x=h?h[1]:m;d=new Function("Lego","$db",`return ${x}`)(e,e.globals.$db)}catch(m){g.onError(m,"script",n)}let p=i;s&&(p=`<style>${s}</style>`+p),S[n]=document.createElement("template"),S[n].innerHTML=p,c&&S[n].setAttribute("b-stylesheets",c),f&&(S[n].setAttribute("b-cascade",f),H.set(n,f.split(/\s+/).filter(Boolean))),l&&S[n].setAttribute("b-error",l),u&&S[n].setAttribute("b-props",u),z.register(n,u),q.set(n,d),document.querySelectorAll(n).forEach(m=>!M(m).snapped&&T(m))};X.setHandler(de);dt(T,de);Fe(T);He(T,B);var Ot={url:typeof window<"u"?window.location.pathname:"/",route:"",params:{},query:{},method:"GET",body:null},Bt={add(e,t){if(t!==void 0){let r=I.get(t);r&&r.forEach(o=>X.add(o))}U.forEach(r=>X.add(r))}},R=Z({$route:Ot,$go:(e,...t)=>ge(e,...t)(document.body),$mount:(e,t,r)=>F(e,t,r),$db:Le},typeof document<"u"?document.body:null,Bt);De(R);var v={db:Le,snap:T,unsnap:B,mount:F,defineLegoFile:(e,t)=>Et(v,e,t),block:(e,t,r={},o="",n="",i="",a="")=>{let s=document.createElement("template");s.setAttribute("b-id",e),s.setAttribute("b-stylesheets",o),n&&s.setAttribute("b-cascade",n),i&&s.setAttribute("b-error",i),a&&s.setAttribute("b-props",a),s.innerHTML=t,S[e]=s,q.set(e,r),z.register(e,a),n?H.set(e,n.split(/\s+/).filter(Boolean)):H.delete(e);try{let c={};G(r,c),ee.set(e.toLowerCase(),Z(c,document.body))}catch(c){g.onError(c,"define",e)}if(customElements.get(e))document.querySelectorAll(e).forEach(c=>{B(c),T(c)}),C.forEach(c=>{c._legoShadow&&c._legoShadow.querySelectorAll(e).forEach(f=>{B(f),T(f)})});else try{customElements.define(e,class extends HTMLElement{connectedCallback(){j.locked||S[e]&&T(this)}disconnectedCallback(){B(this)}})}catch(c){console.warn(`[Lego] Failed to register web component ${e}:`,c),delete S[e],q.delete(e),z.unregister(e),ee.delete(e.toLowerCase()),H.delete(e);return}},getActiveBlocksCount:()=>C.size,getLegos:()=>Object.keys(S),config:g,globals:R,route:(e,t,r=null)=>{let o=[],n=e.replace(/:([^\/]+)|\*|[.+?^${}()|[\]\\]/g,(i,a)=>a?(o.push(a),"([^/]+)"):i==="*"?".*":"\\"+i);ne.push({path:e,regex:new RegExp(`^${n}$`),tagName:t,paramNames:o,middleware:r})},debug:{stylesheets:e=>!e||!e._studsMeta?null:e._studsMeta.stylesheets},init:async(e=document.body,t={})=>{if((!e||typeof e.nodeType!="number")&&(e=document.body),gt(t.styles||{}),g.loader=t.loader,g.debug=t.debug===!0,await ht(),ne.length>0){let s=window.location.pathname,c=window.location.search,f=xe(s);if(f){let{match:l,params:u}=f,d=Object.fromEntries(new URLSearchParams(c));R.$route.url=s+c,R.$route.route=l.path,R.$route.params=u,R.$route.query=d,R.$route.method="GET",R.$route.body=null}}document.querySelectorAll("template[b-id]").forEach(s=>{let c=s.getAttribute("b-id");S[c]=s,z.register(c,s.getAttribute("b-props"));let f=s.getAttribute("b-cascade")||"";f&&H.set(c,f.split(/\s+/).filter(Boolean)),customElements.get(c)||customElements.define(c,class extends HTMLElement{connectedCallback(){j.locked||S[c]&&T(this)}disconnectedCallback(){B(this)}})});let r=/^[a-z][a-z0-9]*(-[a-z0-9]+)+$/,o=g.loaderAllowlist,n=s=>o?(Array.isArray(o)?o:[o]).some(f=>typeof f=="string"?f===s:typeof f=="function"?!!f(s):f&&typeof f.test=="function"?!!f.test(s):!1):!0,i=s=>{if(!s)return{};let c={};return Object.entries(s).forEach(([f,l])=>{if(typeof l=="function")c[f]=l();else if(typeof l=="string"&&l.startsWith("$db.")){let u=l.slice(4);c[f]=v.db(u).get()}else if(typeof l=="string"&&l.startsWith("$globals.")){let u=l.slice(9);c[f]=_[u]}else c[f]=l}),c},a=(s,c,f={})=>{if(!customElements.get(s)){if(!r.test(s)){console.warn(`[Lego] Manifest skipped malformed tag "${s}"`);return}if(!n(s)){console.warn(`[Lego] Manifest skipped "${s}": not in loaderAllowlist`);return}customElements.define(s,class extends HTMLElement{async connectedCallback(){if(S[s]){j.locked||T(this);return}if(v._fetching||(v._fetching=new Set),v._pendingLazy||(v._pendingLazy={}),v._fetching.has(s)){v._pendingLazy[s]||(v._pendingLazy[s]=new Set),v._pendingLazy[s].add(this);return}v._fetching.add(s);try{let l=c.startsWith("POST:")?"POST":"GET",u=c.replace(/^POST:/,""),d=i(f.headers),p={method:l,headers:d,credentials:f.credentials},m=await fetch(u,p);if(!m.ok)throw new Error(`HTTP ${m.status} loading block "${s}" from ${u}`);let h=await m.text();v.defineLegoFile(h,`${s}.lego`),S[s]&&T(this);let x=v._pendingLazy[s];x&&(x.forEach(y=>{y.isConnected&&S[s]&&!M(y).snapped&&T(y)}),delete v._pendingLazy[s])}catch(l){console.error(`[Lego] Failed to load manifest block ${s}:`,l)}finally{v._fetching.delete(s)}}disconnectedCallback(){B(this)}})}};if(t.manifest){let s=t.manifest;if(s.url&&typeof s.url=="string")try{let f=i(s.headers);s=await(await fetch(s.url,{headers:f,credentials:s.credentials})).json()}catch(f){console.error("[Lego] Failed to load manifest:",f),s=[]}else if(typeof s=="string")try{s=await(await fetch(s)).json()}catch(f){console.error("[Lego] Failed to load manifest:",f),s=[]}let c=Array.isArray(s)?s:[s];for(let f of c){let l=f.base||"",u=f.suffix===!0?".lego":f.suffix||"",d={headers:f.headers||{},credentials:f.credentials};f.legos&&f.legos.forEach(p=>{a(p,`${l}${p}${u}`,d)}),f.map&&Object.entries(f.map).forEach(([p,m])=>{let h=m.match(/^https?:|^\//)?m:`${l}${m}`;a(p,h,d)})}}if(g.loader){let s=!1,c=l=>{if(l.nodeType!==Node.ELEMENT_NODE)return;let u=l.tagName.toLowerCase();if(u.includes("-")&&!S[u]&&!C.has(l)){if(v._fetching&&v._fetching.has(u))return;if(!r.test(u)){g.debug&&console.warn(`[Lego] Loader skipped malformed tag "${u}"`);return}if(!n(u)){g.debug&&console.warn(`[Lego] Loader skipped "${u}": not in loaderAllowlist`);return}!o&&!s&&(s=!0,console.warn("[Lego] config.loader is set without config.loaderAllowlist. Any unknown hyphenated tag inserted into the page will trigger a fetch. Set Lego.config.loaderAllowlist to restrict this.")),v._fetching||(v._fetching=new Set),v._fetching.add(u);let d=g.loader(u);if(d){let p=typeof d=="string"?fetch(d).then(m=>m.text()):d;Promise.resolve(p).then(m=>{v.defineLegoFile(m,`${u}.lego`),v._fetching.delete(u)}).catch(m=>{console.error(`[Lego] Failed to load ${u}:`,m),v._fetching.delete(u)})}}if(l.children.length>0){let d=l.firstElementChild;for(;d;)c(d),d=d.nextElementSibling}};v._discoveryObserver&&v._discoveryObserver.disconnect(),v._discoveryObserver=new MutationObserver(l=>l.forEach(u=>{u.addedNodes.forEach(c)})),v._discoveryObserver.observe(e,{childList:!0,subtree:!0});let f=e.firstElementChild;for(;f;)c(f),f=f.nextElementSibling}if(t.studio){if(!S["lego-studio"]){let s=document.createElement("script");s.src="https://unpkg.com/@legodom/studio@0.0.2/dist/lego-studio.js",s.onerror=()=>console.warn("[Lego] Failed to load Studio from CDN"),document.head.appendChild(s)}v.route("/_/studio","lego-studio"),v.route("/_/studio/:block","lego-studio")}ne.length>0&&(window.addEventListener("popstate",s=>{let c=s.state?.legoTargets||null;me(c)}),document.addEventListener("submit",s=>{s.target.hasAttribute("b-action")&&s.preventDefault()}),document.addEventListener("click",s=>{let f=s.composedPath().find(l=>l.tagName==="A"&&(l.hasAttribute("b-target")||l.hasAttribute("b-link")));if(f){s.preventDefault();let l=f.getAttribute("href"),u=f.getAttribute("b-target"),d=u?u.split(/\s+/).filter(Boolean):[],p=f.getAttribute("b-link")!=="false";R.$go(l,...d).get(p)}}),me()),st()}};typeof window<"u"?window.Lego=v:typeof global<"u"&&(global.Lego=v);var xn=v;})();
package/dist/lego.mjs CHANGED
@@ -1,7 +1,7 @@
1
- var y={},J=new WeakMap,O=new WeakMap,F=new WeakMap,se=new WeakMap,A=new Set,q=new Set,j=new Map,ne=new Map;var H={locked:!1},C=e=>(O.has(e)||O.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null}),O.get(e));var w={},$e=e=>{w=e};var ae=class{constructor(t=1e3){this.limit=t,this.cache=new Map}get(t){if(!this.cache.has(t))return;let o=this.cache.get(t);return this.cache.delete(t),this.cache.set(t,o),o}set(t,o){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.limit){let s=this.cache.keys().next().value;this.cache.delete(s)}this.cache.set(t,o)}get size(){return this.cache.size}clear(){this.cache.clear()}};var U=(e,t)=>{if(!e)return;let o=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;o;){let s=o.tagName?o.tagName.toLowerCase():"";if(s&&(t==="*"&&y[s]||s===t.toLowerCase()))return o;o=o.parentElement||o.getRootNode&&o.getRootNode().host}},ie=(e,t)=>{if(typeof e=="function"){let s=Array.from(document.querySelectorAll("*")).filter(r=>r.tagName.includes("-"));return[].concat(e(s))}if(e.startsWith("#")){let s=document.getElementById(e.slice(1));return s?[s]:[]}let o=t?.querySelectorAll(e)||[];return o.length>0?[...o]:[...document.querySelectorAll(e)]},z=e=>e.attributes?[...e.attributes].find(t=>t.name==="b-sync"||t.name.startsWith("b-sync.")):null,V=(e,t)=>{if(e.type==="checkbox")e.checked!==!!t&&(e.checked=!!t);else{let o=t==null?"":String(t);e.value!==o&&(e.value=o)}};var g={onError:(e,t,o)=>{console.error(`[Lego Error] [${t}]`,e,o)},metrics:{},debug:!1,syntax:"brackets"},W=(e,t)=>{!e||!t||Object.getOwnPropertyNames(e).forEach(o=>{let s=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,s)})},X=()=>g.syntax==="brackets"?["[[","]]"]:["{{","}}"],ue=new Map,Q=()=>{let[e,t]=X(),o=e+t;if(ue.has(o)){let n=ue.get(o);return n.lastIndex=0,n}let s=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`${s}(.*?)${r}`,"g");return ue.set(o,a),a},_e=e=>{let o=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!o.includes("-"))throw new Error(`[Lego] Invalid block definition: "${e}". Block names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return o},D=(e,t)=>{if(!e)return"";let o=e.trim().split("."),s=t;for(let r of o){if(s==null)return"";s=s[r]}return s??""},pe=e=>typeof Node<"u"&&e instanceof Node,k=(e,t,o)=>{if(t.nodeType!==Node.ELEMENT_NODE)return;let s=[...t.attributes].find(a=>a.name===e||a.name.startsWith(`${e}.`));if(!s)return;let r={};return o&&(r=o(s,t)),{type:e,node:t,expr:s.value,modifiers:s.name.split(".").slice(1),...r}};var me=null,Le=e=>{me=e},Z=[],ge=e=>{let t=Z.find(r=>r.regex.test(e));if(!t)return null;let o=e.match(t.regex).slice(1),s=t.paramNames?Object.fromEntries(t.paramNames.map((r,a)=>[r,o[a]])):{};return{match:t,params:s}},ce=async(e=null,t=null)=>{if(typeof window>"u")return;let o=window.location.pathname,s=ge(o);if(g.debug&&console.log("[Lego Trace] Matching route",o,s?.match),!s)return;let{match:r,params:a}=s,n=window.location.search;if(w.$route.url=o+n,w.$route.route=r.path,w.$route.params=a,w.$route.query=Object.fromEntries(new URLSearchParams(n)),r.middleware&&!await r.middleware({path:o,params:a}))return;let i=e&&e.length?e:["lego-router"],c=t||document;r.tagName&&i.flatMap(l=>ie(l,c)).forEach(l=>{if(!l)return;l.innerHTML="";let u=document.createElement(r.tagName);l.appendChild(u),me&&me(u)})},le=(e,...t)=>o=>{let s=async(r,a=null,n=!0,i={})=>{if(n&&typeof history<"u"){let d={legoTargets:t.filter(l=>typeof l=="string"),method:r,body:a};history.pushState(d,"",e)}await ce(t.length?t:null,o)};return{get:(r=!0,a={})=>s("GET",null,r,a),post:(r,a=!0,n={})=>s("POST",r,a,n),put:(r,a=!0,n={})=>s("PUT",r,a,n),patch:(r,a=!0,n={})=>s("PATCH",r,a,n),delete:(r=!0,a={})=>s("DELETE",null,r,a)}};var he=null,Ye=null,Ne=(e,t)=>{he=e,Ye=t},R=(e,t,o)=>{if(e!=null&&(e=String(e).toLowerCase(),!e.includes("-"))){console.warn(`[Lego] $mount: "${e}" is not a valid custom element name (must contain a hyphen).`);return}if(t===void 0){if(!e)return;let a=document.createElement(e);return o&&(a.$initialState=o),a}let s;if(t instanceof Element)s=[t];else if(Array.isArray(t))s=t;else if(typeof t=="string")s=ie(t);else{console.warn("[Lego] $mount: Invalid target",t);return}if(s.length===0){g.debug&&console.log(`[Lego] $mount: No targets found for "${t}"`);return}let r=[];return s.forEach(a=>{if(!a||(a.innerHTML="",!e))return;let n=document.createElement(e);o&&(n.$initialState=o),a.appendChild(n),he&&he(n),r.push(n)}),r.length===1?r[0]:r.length>0?r:void 0};var Te=new ae(1e3),S=(e,t,o=!0)=>{if(/\b(eval|import|class|module|constructor|__proto__|prototype)\b/.test(e)||/\[\s*['"`].*\+|\+.*['"`]\s*\]/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{let s=t.state||{},r=Te.get(e);r||(r=new Function("global","self","event","helpers",`
1
+ var S={},Y=new WeakMap,A=new WeakMap,W=new WeakMap,ue=new WeakMap,C=new Set,U=new Set,I=new Map,q=new Map,ee=new Map;var j={locked:!1},M=e=>(A.has(e)||A.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null}),A.get(e));var wt=/^[a-zA-Z_$][\w$]*$/,J=new Map,vt=(e,t="<unknown>")=>{if(!e||typeof e!="string")return null;let r=e.trim();if(!r||r.startsWith("{")&&r.endsWith("}")&&(r=r.slice(1,-1).trim(),!r))return null;let o=r.split(",").map(i=>i.trim()).filter(Boolean);if(o.length===0)return null;let n=[];for(let i of o){if(!wt.test(i))return console.error(`[Lego] Invalid b-props on <${t}>: token "${i}" is not a bare identifier. b-props declares names only \u2014 use b-logic for values. Got: "${e}"`),null;n.push(i)}return n},z={register(e,t){if(!t){J.delete(e);return}let r=vt(t,e);r?J.set(e,r):J.delete(e)},unregister(e){J.delete(e)},get(e){return J.get(e)||null},validate({instanceLogic:e,state:t,tagName:r}){let o=J.get(r);if(o){if(e)for(let n of Object.keys(e))o.includes(n)||console.warn(`[Lego] <${r}> received b-logic key "${n}" not declared in b-props. Declared: { ${o.join(", ")} }.`);for(let n of o)t[n]===void 0&&console.warn(`[Lego] <${r}> is missing prop "${n}" (declared in b-props but not provided).`)}}};var _={},De=e=>{_=e};var te=class{constructor(t=1e3){this.limit=t,this.cache=new Map}get(t){if(!this.cache.has(t))return;let r=this.cache.get(t);return this.cache.delete(t),this.cache.set(t,r),r}set(t,r){if(this.cache.has(t))this.cache.delete(t);else if(this.cache.size>=this.limit){let o=this.cache.keys().next().value;this.cache.delete(o)}this.cache.set(t,r)}get size(){return this.cache.size}clear(){this.cache.clear()}};var V=(e,t)=>{if(!e)return;let r=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;r;){let o=r.tagName?r.tagName.toLowerCase():"";if(o&&(t==="*"&&S[o]||o===t.toLowerCase()))return r;r=r.parentElement||r.getRootNode&&r.getRootNode().host}},pe=(e,t)=>{if(typeof e=="function"){let o=Array.from(document.querySelectorAll("*")).filter(n=>n.tagName.includes("-"));return[].concat(e(o))}if(e.startsWith("#")){let o=document.getElementById(e.slice(1));return o?[o]:[]}let r=t?.querySelectorAll(e)||[];return r.length>0?[...r]:[...document.querySelectorAll(e)]},K=e=>e.attributes?[...e.attributes].find(t=>t.name==="b-sync"||t.name.startsWith("b-sync.")):null,St=new Set(["script","iframe","object","embed","link","meta","base","style"]),xt=new Set(["href","src","xlink:href","action","formaction","srcdoc","data"]),Re=e=>{if(typeof e!="string"||e===""||typeof document>"u")return e;let t=document.createElement("template");t.innerHTML=e;let r=document.createTreeWalker(t.content,NodeFilter.SHOW_ELEMENT),o=[],n;for(;n=r.nextNode();){if(St.has(n.tagName.toLowerCase())){o.push(n);continue}for(let i=n.attributes.length-1;i>=0;i--){let a=n.attributes[i],s=a.name.toLowerCase();if(s.startsWith("on")){n.removeAttribute(a.name);continue}if(xt.has(s)){let c=a.value.trim().toLowerCase();(c.startsWith("javascript:")||c.startsWith("data:text/html")||c.startsWith("vbscript:"))&&n.removeAttribute(a.name)}}}return o.forEach(i=>i.remove()),t.innerHTML},re=(e,t)=>{if(e.type==="checkbox")e.checked!==!!t&&(e.checked=!!t);else if(e.type==="radio"){let r=t!=null&&String(t)===e.value;e.checked!==r&&(e.checked=r)}else{let r=t==null?"":String(t);e.value!==r&&(e.value=r)}};var g={onError:(e,t,r)=>{console.error(`[Lego Error] [${t}]`,e,r)},metrics:{},debug:!1,syntax:"brackets",sanitize:null,loaderAllowlist:null},G=(e,t)=>{!e||!t||Object.getOwnPropertyNames(e).forEach(r=>{let o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o)})},oe=()=>g.syntax==="brackets"?["[[","]]"]:["{{","}}"],Ee=new Map,we=()=>{let[e,t]=oe(),r=e+t;if(Ee.has(r)){let a=Ee.get(r);return a.lastIndex=0,a}let o=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp(`${o}(.*?)${n}`,"g");return Ee.set(r,i),i},Pe=e=>{let r=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!r.includes("-"))throw new Error(`[Lego] Invalid block definition: "${e}". Block names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return r},D=(e,t)=>{if(!e)return"";let r=e.trim().split("."),o=t;for(let n of r){if(o==null)return"";o=o[n]}return o??""},ve=e=>typeof Node<"u"&&e instanceof Node,O=(e,t,r)=>{if(t.nodeType!==Node.ELEMENT_NODE)return;let o=[...t.attributes].find(i=>i.name===e||i.name.startsWith(`${e}.`));if(!o)return;let n={};return r&&(n=r(o,t)),{type:e,node:t,expr:o.value,modifiers:o.name.split(".").slice(1),...n}};var Se=null,Fe=e=>{Se=e},ne=[],ze=0,xe=e=>{let t=ne.find(n=>n.regex.test(e));if(!t)return null;let r=e.match(t.regex).slice(1),o=t.paramNames?Object.fromEntries(t.paramNames.map((n,i)=>[n,r[i]])):{};return{match:t,params:o}},me=async(e=null,t=null)=>{if(typeof window>"u")return;let r=++ze,o=()=>r===ze,n=window.location.pathname,i=xe(n);if(g.debug&&console.log("[Lego Trace] Matching route",n,i?.match),!i)return;let{match:a,params:s}=i,c=window.location.search;if(a.middleware){let u=await a.middleware({path:n,params:s});if(!o()||!u)return}_.$route.url=n+c,_.$route.route=a.path,_.$route.params=s,_.$route.query=Object.fromEntries(new URLSearchParams(c));let f=e&&e.length?e:["lego-router"],l=t||document;if(a.tagName){if(!o())return;f.flatMap(d=>pe(d,l)).forEach(d=>{if(!d||!o())return;d.innerHTML="";let p=document.createElement(a.tagName);d.appendChild(p),Se&&Se(p)})}},ge=(e,...t)=>r=>{let o=async(n,i=null,a=!0,s={})=>{if(a&&typeof history<"u"){let f={legoTargets:t.filter(l=>typeof l=="string"),method:n,body:i};history.pushState(f,"",e)}await me(t.length?t:null,r)};return{get:(n=!0,i={})=>o("GET",null,n,i),post:(n,i=!0,a={})=>o("POST",n,i,a),put:(n,i=!0,a={})=>o("PUT",n,i,a),patch:(n,i=!0,a={})=>o("PATCH",n,i,a),delete:(n=!0,i={})=>o("DELETE",null,n,i)}};var $e=null,$t=null,He=(e,t)=>{$e=e,$t=t},F=(e,t,r)=>{if(e!=null&&(e=String(e).toLowerCase(),!e.includes("-"))){console.warn(`[Lego] $mount: "${e}" is not a valid custom element name (must contain a hyphen).`);return}if(t===void 0){if(!e)return;let i=document.createElement(e);return r&&(i.$initialState=r),i}let o;if(t instanceof Element)o=[t];else if(Array.isArray(t))o=t;else if(typeof t=="string")o=pe(t);else{console.warn("[Lego] $mount: Invalid target",t);return}if(o.length===0){g.debug&&console.log(`[Lego] $mount: No targets found for "${t}"`);return}let n=[];return o.forEach(i=>{if(!i||(i.innerHTML="",!e))return;let a=document.createElement(e);r&&(a.$initialState=r),i.appendChild(a),$e&&$e(a),n.push(a)}),n.length===1?n[0]:n.length>0?n:void 0};var We=new te(1e3),Ie=new te(500),_t=/\b(eval|import|constructor|__proto__)\b/,Lt=/(?<![\w.$])(class|module|prototype)(?![\w$])/,L=(e,t,r=!0)=>{if(_t.test(e)||Lt.test(e)||/\[\s*['"`].*\+|\+.*['"`]\s*\]/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{let o=t.state||{},n=We.get(e);n||(n=new Function("global","self","event","helpers",`
2
2
  with(this) {
3
3
  with(helpers) {
4
4
  return ${e}
5
5
  }
6
6
  }
7
- `),Te.set(e,r));let a={$ancestors:i=>U(t.self,i),$registry:i=>ne.get(i.toLowerCase()),$element:t.self,$route:w.$route,$params:w.$route?.params||{},$go:(i,...c)=>le(i,...c)(t.self),$db:w.$db,$mount:(i,c,d)=>R(i,c,d),$emit:(i,c)=>{t.self.dispatchEvent(new CustomEvent(i,{detail:c,bubbles:!0,composed:!0}))}},n=r.call(s,t.global,t.self,t.event,a);return typeof n=="function"?n.call(s,t.event):n}catch(s){if(o)throw s;if(s instanceof ReferenceError)return;throw s}},be=(e,t={})=>{if(!e||e.trim()==="{}")return{};let o=s=>new Function("scope","global",`with(global) { with(scope) { return (${s}); } }`)(t,w);try{return o(e)}catch(s){let r=e.trim();if(!r.startsWith("{")&&r.includes(":"))try{return o(`{${e}}`)}catch{}return console.error(`[Lego] Error parsing b-logic: "${e.length>80?e.slice(0,80)+"...":e}"`,s),{}}};var Ae={name:"b-if",scan:(e,{checkGlobal:t,getPrivateData:o})=>k("b-if",e,(s,r)=>{t(s.value);let a=document.createComment(`b-if: ${s.value}`),n=o(r);return n.anchor=a,{anchor:a}}),execute({binding:e,state:t,global:o}){let{node:s,anchor:r,expr:a}=e,n=!!S(a,{state:t,global:o,self:s}),i=!!s.parentNode;n&&!i?r.parentNode&&r.parentNode.replaceChild(s,r):!n&&i&&s.parentNode.replaceChild(r,s)},destroy({binding:e}){e.anchor&&e.anchor.parentNode&&e.anchor.remove()}};var Ce={name:"b-show",scan(e,{checkGlobal:t}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-show")){let o=e.getAttribute("b-show");return t(o),{type:"b-show",node:e,expr:o}}},execute({binding:e,state:t,global:o}){let{node:s,expr:r}=e;s.style.display=S(r,{state:t,global:o,self:s})?"":"none"}};var ke={name:"b-text",scan(e,{checkGlobal:t}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-text")){let o=e.getAttribute("b-text");return t(o),{type:"b-text",node:e,path:o}}},execute({binding:e,state:t,global:o}){let{node:s,path:r}=e;r.startsWith("global.")?s.textContent=D(r.slice(7),o)??"":s.textContent=D(r,t)??""}};var Me={name:"b-html",scan:e=>k("b-html",e),execute:({binding:e,state:t,global:o})=>{let{node:s,expr:r}=e,a=S(r,{state:t,global:o,self:s})??"";s._bHtmlPrev!==a&&(s._bHtmlPrev=a,s.innerHTML=a)},destroy({binding:e}){let{node:t}=e;t&&(delete t._bHtmlPrev,t.innerHTML="")}};var Oe={name:"b-sync",scan(e,{checkGlobal:t}){if(e.nodeType!==Node.ELEMENT_NODE)return;let o=z(e);if(!o)return;t(o.value);let s=o.name.split(".").slice(1);return{type:"b-sync",node:e,expr:o.value,modifiers:s}},execute({binding:e,state:t,global:o}){let{node:s,expr:r}=e;r.startsWith("global.")?V(s,D(r.slice(7),o)??""):V(s,D(r,t)??"")},destroy({binding:e}){let{node:t}=e;t&&t._bSyncHandler&&(t.removeEventListener("input",t._bSyncHandler),t.removeEventListener("change",t._bSyncHandler),delete t._bSyncHandler)}};var De={name:"b-for",scan(e,{checkGlobal:t,pendingOperations:o}){if(e.nodeType!==Node.ELEMENT_NODE)return;let s=e.getAttribute("b-for")?.match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);if(s){t(s[2]);let r=document.createComment(`b-for: ${s[1]} in ${s[2].trim()}`);return o.push(()=>{e.parentNode&&(e.parentNode.insertBefore(r,e),e.remove())}),{type:"b-for",anchor:r,itemName:s[1],listName:s[2].trim(),keyPath:e.getAttribute("b-key")||null,template:e.cloneNode(!0),terminal:!0}}},execute({binding:e,state:t,global:o,helpers:s}){let{bind:r,updateNodeBindings:a}=s;if(!r||!a){console.error("[Lego] b-for directive missing required helpers: bind, updateNodeBindings");return}let{anchor:n,listName:i,itemName:c,keyPath:d,template:l}=e,{contextEl:u}=s,f=S(i,{state:t,global:o,self:u})||[];F.has(n)||F.set(n,new Map);let m=F.get(n),x=new Set,E=[];f.forEach((p,$)=>{let h;d?(h=D(d,p),(h==null||h==="")&&(console.warn(`[Lego] b-key="${d}" could not resolve a value for item at index ${$}. Falling back to index-based key.`),h=`__bfor_${$}`)):p&&typeof p=="object"?(h=p.id||p._id||p.uuid||p.key,h===void 0&&(se.has(p)||se.set(p,Math.random()),h=se.get(p))):h=`${$}-${p}`,x.add(h);let v=m.get(h);v?v._loopCtx.index=$:(v=l.cloneNode(!0),v.removeAttribute("b-for"),v.removeAttribute("b-key"),m.set(h,v),v._loopCtx={name:c,listName:i,index:$},r(v,u,v._loopCtx));let _=Object.assign(Object.create(t),{[c]:p,$index:$});a(v,_),[v,...v.querySelectorAll("*")].filter(I=>z(I)).forEach(I=>{let Se=z(I).value;Se.startsWith(`${c}.`)&&V(I,D(Se.split(".").slice(1).join("."),f[$]))}),E.push(v)});let L=n.nextSibling;E.forEach(p=>{p!==L?n.parentNode.insertBefore(p,L):L=L.nextSibling});for(let[p,$]of m.entries())x.has(p)||($.remove(),m.delete(p))},destroy({binding:e}){let{anchor:t}=e;if(t&&F.has(t)){let o=F.get(t);o.forEach(s=>{[s,...s.querySelectorAll("*")].forEach(a=>{let n=O.get(a);n&&(n.listeners&&(n.listeners.forEach(({eventName:i,handler:c})=>{a.removeEventListener(i,c)}),n.listeners=null),n.bindings&&(n.bindings.forEach(i=>{i.observer&&(i.observer.disconnect(),i.observer=null)}),n.bindings=null))}),s.remove()}),o.clear(),F.delete(t)}t&&t.parentNode&&t.remove()}};var Be={scan:e=>{if(e.hasAttribute("b-init"))return{type:"b-init",node:e,expr:e.getAttribute("b-init")}},execute:({binding:e,state:t,global:o})=>{e.initialized||(e.initialized=!0,S(e.expr,{state:t,global:o,self:e.node}))}};var Re={name:"b-enter",scan:e=>k("b-enter",e,(t,o)=>({modifiers:t.name.split(".").slice(1)})),execute:({binding:e,state:t,global:o})=>{if(e.observer||e.done)return;let s=new IntersectionObserver((r,a)=>{if(r[0].isIntersecting){try{S(e.expr,{state:t,global:o,self:e.node})}catch(i){console.error("[Lego] Error in b-enter handler:",i)}e.modifiers.includes("once")&&(a.disconnect(),e.observer=null,e.done=!0)}});s.observe(e.node),e.observer=s},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Pe={name:"b-leave",scan:e=>k("b-leave",e),execute:({binding:e,state:t,global:o})=>{if(e.observer||e.done)return;let s=new IntersectionObserver((r,a)=>{let n=r[0];if(n.isIntersecting&&(e.activated=!0),!n.isIntersecting&&e.activated){try{S(e.expr,{state:t,global:o,self:e.node})}catch(i){console.error("[Lego] Error in b-leave handler:",i)}e.modifiers.includes("once")&&(a.disconnect(),e.observer=null,e.done=!0)}});s.observe(e.node),e.observer=s},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Fe={name:"b-mount",scan:(e,{checkGlobal:t})=>k("b-mount",e,o=>(t(o.value),{_lastTag:null})),execute({binding:e,state:t,global:o}){let{node:s,expr:r}=e,a=S(r,{state:t,global:o,self:s},!1),n=a?String(a).toLowerCase():null;n!==e._lastTag&&(e._lastTag=n,R(n,s))},destroy({binding:e}){e.node&&R(null,e.node),e._lastTag=null}};var Y={"b-if":Ae,"b-show":Ce,"b-text":ke,"b-html":Me,"b-sync":Oe,"b-for":De,"b-init":Be,"b-enter":Re,"b-leave":Pe,"b-mount":Fe};var et=(e=null)=>{let t=!1,o=new Set,s=!1,r=e,a=new Set,n=null,i=new Set,c=f=>{r=f},d=()=>{n&&clearTimeout(n),n=setTimeout(()=>{i.forEach(f=>{let m=f._studs;if(m&&typeof m.updated=="function")try{m.updated.call(m)}catch(x){console.error("[Lego] Error in updated hook:",x)}}),i.clear(),n=null},50)},l=()=>{a.size>0&&(a.forEach(f=>o.add(f)),a.clear(),!t&&o.size>0&&(t=!0,requestAnimationFrame(u)))},u=()=>{s=!0;let f=Array.from(o);o.clear(),t=!1,f.forEach(m=>{m.isConnected&&r&&r(m)}),f.forEach(m=>i.add(m)),d(),s=!1,l()};return{add:f=>{if(f){if(s){a.add(f);return}o.add(f),!t&&(t=!0,requestAnimationFrame(u))}},setHandler:c}},ee=et();var T=new Map,fe=new Map,te=new WeakMap,re=new Map,tt=e=>{let t=Array.from(re.entries()).filter(([r])=>r.startsWith("lego:")).sort((r,a)=>r[1].timestamp-a[1].timestamp),o=0,s=[];for(let[r,a]of t){if(o>=e)break;try{localStorage.removeItem(r),o+=a.size,s.push(r),re.delete(r)}catch(n){console.error(`[Lego] Failed to evict ${r}:`,n)}}return s},He=(e,t,o)=>{g.debug&&console.log("[Lego Trace] scheduleSave",e,t,o),fe.has(e)&&clearTimeout(fe.get(e));let s=()=>{try{let r=JSON.stringify(t),a=new Blob([r]).size;localStorage.setItem(e,r);let n=e.startsWith("lego:")?e:`lego:${e}`;re.set(n,{timestamp:Date.now(),size:a}),fe.delete(e)}catch(r){if(r.name==="QuotaExceededError"){console.warn(`[Lego] Storage quota exceeded for key: ${e}`);try{let a=JSON.stringify(t),n=new Blob([a]).size,i=tt(n*2);if(i.length>0){g.debug&&console.log(`[Lego] Evicted ${i.length} old keys, retrying save`),localStorage.setItem(e,a);let c=e.startsWith("lego:")?e:`lego:${e}`;re.set(c,{timestamp:Date.now(),size:n})}else g.onError(new Error("Storage quota exceeded and no keys available for eviction"),"quota",e)}catch{g.onError(new Error(`Critical: Could not save ${e} even after eviction`),"quota-critical",e)}}else console.error(`[Lego] Storage Error (${e}):`,r)}};o>0?fe.set(e,setTimeout(s,o)):s()},ye=e=>({__type:"lego-db",key:e,_default:void 0,_debounce:0,default(o){return this._default=o,this},debounce(o){return this._debounce=o,this},set(o,s=0){return He(e,o,s),T.has(e)&&T.get(e).forEach(({target:r,prop:a,el:n,batcher:i})=>{r[a]=o,n&&i&&i.add(n)}),o},get(){try{let o=localStorage.getItem(e);return o!==null?JSON.parse(o):null}catch(o){return console.warn(`[Lego] Failed to get localStorage value for key "${e}":`,o),null}},delete(){try{return localStorage.removeItem(e),re.delete(e.startsWith("lego:")?e:`lego:${e}`),T.has(e)&&T.get(e).forEach(({target:o,prop:s,el:r,batcher:a})=>{o[s]=null,r&&a&&a.add(r)}),!0}catch(o){return console.error(`[Lego] Failed to delete localStorage key "${e}":`,o),!1}}}),ze=e=>e&&e.__type==="lego-db",We=(e,t,o,s,r)=>{g.debug&&console.log("[Lego Trace] Reactive DB Init:",t,o);let a=o._default;try{let n=localStorage.getItem(o.key);n!==null&&(a=JSON.parse(n))}catch(n){console.warn(`[Lego] Failed to parse localStorage value for key "${o.key}":`,n)}e[t]=a,te.has(e)||te.set(e,{}),te.get(e)[t]={key:o.key,debounce:o._debounce},g.debug&&console.log("[Lego Trace] DB Metadata Set:",t,te.get(e)[t]),T.has(o.key)||T.set(o.key,new Set),T.get(o.key).add({target:e,prop:t,el:s,batcher:r})},Ie=(e,t,o)=>{let s=te.get(e);if(s&&s[t]){let r=s[t].key;He(r,o,s[t].debounce),T.has(r)&&T.get(r).forEach(({target:a,prop:n,el:i,batcher:c})=>{a!==e&&(a[n]=o,i&&c&&c.add(i))})}},qe=e=>{T.forEach(t=>{t.forEach(o=>{o.el===e&&t.delete(o)})})},je=()=>{typeof window<"u"&&window.addEventListener("storage",e=>{if(!(!e.key||!T.has(e.key)))try{let t=JSON.parse(e.newValue);T.get(e.key).forEach(({target:o,prop:s,el:r,batcher:a})=>{o[s]=t,r&&a&&a.add(r)})}catch(t){console.warn("[Lego] Cross-tab sync error:",t)}})};var K=(e,t,o=ee)=>{if(e===null||typeof e!="object"||pe(e))return e;if(J.has(e))return J.get(e);for(let a in e){let n=Object.getOwnPropertyDescriptor(e,a);if(n&&n.get)continue;let i=e[a];ze(i)&&We(e,a,i,t,o)}let s={get:(a,n)=>{let i=Reflect.get(a,n);return i!==null&&typeof i=="object"&&!pe(i)?K(i,t,o):i},set:(a,n,i,c)=>{if(n==="__proto__"||n==="constructor"||n==="prototype")return console.warn(`[Lego] Blocked setting dangerous property: "${n}"`),!0;let d=a[n];g.debug&&d!==i&&console.log("[Lego Trace] Reactive SET:",n,"Old:",d,"New:",i,"Target:",a);let l=c===J.get(a),u=Object.prototype.hasOwnProperty.call(a,n),f=!l&&u?Reflect.set(a,n,i):Reflect.set(a,n,i,c);return(l||u)&&d!==i&&(o.add(t),Ie(a,n,i)),f},deleteProperty:(a,n)=>{let i=Reflect.deleteProperty(a,n);return o.add(t),i}},r=new Proxy(e,s);return J.set(e,r),r};var rt=e=>{let t=e;for(;t;){let o=t.getAttribute&&t.getAttribute("b-error");if(o&&o.toLowerCase()!==e.tagName.toLowerCase())return{errorTag:o,targetElement:t};let s=t.tagName?t.tagName.toLowerCase():"",r=y[s];if(r){let a=r.getAttribute("b-error");if(a&&a.toLowerCase()!==e.tagName.toLowerCase())return{errorTag:a,targetElement:t}}t=t.parentElement||t.getRootNode&&t.getRootNode().host}return null},we=null,Ue=null,Ke=(e,t)=>{we=e,Ue=t},ot=(e,t,o)=>{if(!we||!Ue){console.error("[Lego] Error boundary dependencies not loaded",o);return}try{t.shadowRoot?t.shadowRoot.innerHTML="":t.innerHTML="";let s=document.createElement(e);s.$initialState={$error:{message:o.message,stack:o.stack,component:t.tagName.toLowerCase()}},(t.shadowRoot||t).appendChild(s),we(s)}catch(s){console.error("[Lego] Error boundary failed to render:",s),console.error("[Lego] Original error:",o)}},Ee=0,st=3,G=(e,t,o)=>{if(Ee>=st){console.error("[Lego] Error boundary recursion limit reached:",e),g.onError(e,o,t);return}let s=rt(t);if(s){Ee++;try{ot(s.errorTag,s.targetElement,e)}finally{Ee--}}else g.onError(e,o,t)};var de=(e,t,o=null)=>{let s=t._studs,r=i=>{let c=C(i);if(!c.bound){if(i.hasAttributes()){let d=i.attributes;for(let u=0;u<d.length;u++){let f=d[u];if(f.name.startsWith("@")){let m=f.name.slice(1).split("."),x=m[0],E=m.slice(1),L=p=>{if(E.includes("prevent")&&p.preventDefault(),E.includes("stop")&&p.stopPropagation(),!(E.includes("self")&&p.target!==p.currentTarget)){if(typeof KeyboardEvent<"u"&&p instanceof KeyboardEvent){if(E.includes("ctrl")&&!p.ctrlKey||E.includes("alt")&&!p.altKey||E.includes("shift")&&!p.shiftKey||E.includes("meta")&&!p.metaKey)return;let $=E.filter(h=>!["prevent","stop","self","ctrl","alt","shift","meta","capture","once","passive"].includes(h));if($.length>0){let h=p.key.toLowerCase();if(!$.some(_=>_==="enter"?h==="enter":_==="esc"||_==="escape"?h==="escape":_==="space"?h===" ":_==="tab"?h==="tab":_==="delete"?h==="delete":_==="backspace"?h==="backspace":_==="up"?h==="arrowup":_==="down"?h==="arrowdown":_==="left"?h==="arrowleft":_==="right"?h==="arrowright":_==="alpha"?/^[a-z]$/.test(h):_==="numbers"?/^[0-9]$/.test(h):_===h))return}}try{let $=s;if(o){let v=S(o.listName,{state:s,global:w,self:t})[o.index];$=Object.assign(Object.create(s),{[o.name]:v})}S(f.value,{state:$,global:w,self:i,event:p,$event:p},!0)}catch($){G($,t,"event-handler")}}};i.addEventListener(x,L),c.listeners||(c.listeners=[]),c.listeners.push({eventName:x,handler:L})}}let l=z(i);if(l){let u=l.value,f=l.name.split(".").slice(1),m=f.includes("lazy"),x=f.includes("number"),E=f.includes("trim"),L=()=>{try{let p,$;if(u.startsWith("global.")){let v=u.slice(7).split(".");$=v.pop(),p=v.reduce((_,P)=>_[P],w)}else if(o&&u.startsWith(`${o.name}.`)){let _=S(o.listName,{state:s,global:w,self:t})[o.index];if(!_)return;let P=u.split(".").slice(1);$=P.pop(),p=P.reduce((I,xe)=>I[xe],_)}else{let v=u.split(".");$=v.pop(),p=v.reduce((_,P)=>_[P],s)}let h=i.type==="checkbox"?i.checked:i.value;if(E&&typeof h=="string"&&(h=h.trim()),x){let v=parseFloat(h);isNaN(v)||(h=v)}p&&p[$]!==h&&(p[$]=h)}catch(p){g.onError(p,"sync-update",i)}};i._bSyncHandler=L,c.listeners||(c.listeners=[]),m||(i.addEventListener("input",L),c.listeners.push({eventName:"input",handler:L})),i.addEventListener("change",L),c.listeners.push({eventName:"change",handler:L})}if(i.hasAttribute("b-var")){let u=i.getAttribute("b-var");s.$vars&&(s.$vars[u]=i)}}c.bound=!0}};e instanceof Element&&r(e);let a=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),n;for(;n=a.nextNode();)r(n)},nt=e=>{let t=[],o=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),s,r=[];for(;s=o.nextNode();){let a=s;if((c=>{let d=c.parentNode;for(;d&&d!==e;){if(d.hasAttribute&&d.hasAttribute("b-for"))return!0;d=d.parentNode}return!1})(s))continue;let i=c=>{if(/\bglobal\b/.test(c)){let d=e.host||e;q.add(d)}};if(s.nodeType===Node.ELEMENT_NODE){let c=!1;for(let[l,u]of Object.entries(Y))if(u.scan){let f=u.scan(s,{checkGlobal:i,getPrivateData:C,pendingOperations:r,current:a});f&&(t.push(f),f.terminal&&(c=!0))}if(c)continue;let[d]=X();[...s.attributes].forEach(l=>{l.value.includes(d)&&(i(l.value),t.push({type:"attr",node:s,attrName:l.name,template:l.value}))})}else if(s.nodeType===Node.TEXT_NODE){let[c]=X();s.textContent.includes(c)&&(i(s.textContent),t.push({type:"text",node:s,template:s.textContent}))}}return r.forEach(a=>a()),t},at=(e,t)=>{let o=a=>{if(a.nodeType===Node.TEXT_NODE){a._tpl===void 0&&(a._tpl=a.textContent);let n=a._tpl.replace(Q(),(i,c)=>S(c.trim(),{state:t,global:w,self:a},!1)??"");a.textContent!==n&&(a.textContent=n)}else if(a.nodeType===Node.ELEMENT_NODE){let[n]=X();[...a.attributes].forEach(i=>{if(i._tpl===void 0&&(i._tpl=i.value),i._tpl.includes(n)){let c=i._tpl.replace(Q(),(d,l)=>S(l.trim(),{state:t,global:w,self:a},!1)??"");i.value!==c&&(i.value=c,i.name==="class"&&(a.className=c))}})}};o(e);let s=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),r;for(;r=s.nextNode();)o(r)},oe=e=>{g.debug&&console.log("[Lego Trace] render() called for:",e.tagName);let t=e._studs;if(!t)return;let o=C(e);if(!o.rendering){o.rendering=!0,g.metrics&&g.metrics.onRenderStart&&g.metrics.onRenderStart(e);try{let s=e.shadowRoot||e;o.bindings||(o.bindings=nt(s)),o.bindings.forEach(r=>{let a=Y[r.type];if(a){a.execute({binding:r,state:t,global:w,helpers:{bind:de,updateNodeBindings:at,contextEl:e}});return}if(r.type==="text"){let n=r.template.replace(Q(),(i,c)=>S(c.trim(),{state:t,global:w,self:r.node},!1)??"");r.node.textContent!==n&&(r.node.textContent=n)}if(r.type==="attr"){let n=r.template.replace(Q(),(i,c)=>S(c.trim(),{state:t,global:w,self:r.node},!1)??"");r.node.getAttribute(r.attrName)!==n&&(r.node.setAttribute(r.attrName,n),r.attrName==="class"&&(r.node.className=n))}})}catch(s){G(s,e,"render")}finally{g.metrics&&g.metrics.onRenderEnd&&g.metrics.onRenderEnd(e),o.rendering=!1}}};var Ge=new Map,Je={},Ve=e=>{Je=e},Xe=async()=>{let e=Object.entries(Je).map(async([t,o])=>{let s=await Promise.all(o.map(async r=>{try{if(r instanceof CSSStyleSheet)return r;let a=await fetch(r);if(!a.ok)throw new Error(`Status ${a.status}`);let n=await a.text(),i=new CSSStyleSheet;return await i.replace(n),i}catch(a){return console.error(`[Lego] Failed to load stylesheet: ${r}`,a),null}}));Ge.set(t,s.filter(r=>r!==null))});await Promise.all(e),g.debug&&console.log("[Lego Debug] Re-applying stylesheets to",A.size,"blocks"),A.forEach(t=>{ve(t)})},ve=e=>{if(!e.shadowRoot&&!e._legoShadow)return;let t=e.shadowRoot||e._legoShadow,o=e.tagName.toLowerCase(),s=y[o],r=(s&&s.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),a=(e.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),n=[],i=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;i;){let u=(i.getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);u.length&&n.push(...u);let f=i.tagName?i.tagName.toLowerCase():"";if(y[f]){let m=(y[f].getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);m.length&&n.push(...m)}i=i.parentElement||i.getRootNode&&i.getRootNode().host}let c=[...new Set([...r,...a])],d=[...new Set(n)],l=[...new Set([...d,...c])];if(l.length>0){let u=l.flatMap(f=>Ge.get(f)||[]);if(u.length>0&&g.debug&&console.log("[Lego Debug] Applying styles to",e.tagName,"- Names:",l,"- Sheets:",u.length),u.length>0){let f=t.adoptedStyleSheets.filter(m=>!u.includes(m));t.adoptedStyleSheets=[...f,...u]}}e._studsMeta={stylesheets:{explicit:c,inherited:d,applied:l}}};var N=e=>{if(g.debug&&console.log("[Lego Trace] snap() called for:",e.tagName),!e||e.nodeType!==Node.ELEMENT_NODE)return;let t=C(e),o=e.tagName.toLowerCase(),s=y[o];if(s&&!t.snapped){t.snapped=!0;let a=s.content.cloneNode(!0),n=e.shadowRoot;n?n.innerHTML="":n=e.attachShadow({mode:"open"}),ve(e);let i=U(e,"*")||U(e.getRootNode().host,"*"),c=i&&i.state?i.state:{},d=j.get(o)||{},l=be(s.getAttribute("b-logic")||s.getAttribute("b-data")||"{}"),u=be(e.getAttribute("b-logic")||e.getAttribute("b-data")||"{}",c),f={$vars:{},$element:e,get $parent(){return U(e,"*")},$emit:(E,L)=>{e.dispatchEvent(new CustomEvent(E,{detail:L,bubbles:!0,composed:!0}))},get $route(){return w.$route},get $go(){return w.$go},get $mount(){return w.$mount}};W(d,f),W(l,f),W(u,f),e.$initialState&&(W(e.$initialState,f),delete e.$initialState),e._studs=K(f,e),Object.defineProperty(e,"state",{get(){return this._studs},set(E){Object.assign(this._studs,E)},configurable:!0,enumerable:!1}),H.locked=!0;try{n.appendChild(a)}finally{H.locked=!1}let m=n.querySelector("style");if(m&&(m.textContent=m.textContent.replace(/(?<![-\w])self(?![-\w])/g,":host")),de(n,e),A.add(e),oe(e),e.setAttribute("b-id",o),e._legoShadow||(e._legoShadow=n),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(E){G(E,e,"mounted")}let x=n.querySelectorAll("*");g.debug&&console.log("[Lego Debug] Nested scan in",e.tagName,"- Found elements:",x.length),x.forEach(E=>{let L=E.tagName.toLowerCase(),p=!!y[L];p&&g.debug&&console.log("[Lego Debug] Checking",L,"- Registered:",p),p&&N(E)})}let r=e.parentElement;for(;r&&!r._studs;)r=r.parentElement;r&&r._studs&&de(e,r),[...e.children].forEach(N)},M=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(o){G(o,e,"unmounted")}if(e.shadowRoot){let o=document.createTreeWalker(e.shadowRoot,NodeFilter.SHOW_ELEMENT),s;for(;s=o.nextNode();){let r=O.get(s);r&&r.listeners&&(r.listeners.forEach(({eventName:a,handler:n})=>{s.removeEventListener(a,n)}),r.listeners=null)}[...e.shadowRoot.children].forEach(M)}qe(e),A.delete(e),q.delete(e),e._studs&&(e._studs.$element=null,e._studs.$vars&&(Object.keys(e._studs.$vars).forEach(o=>{e._studs.$vars[o]=null}),e._studs.$vars=null),e._studs.$emit&&(e._studs.$emit=null),delete e._studs.$parent,delete e._studs.$route,delete e._studs.$go,delete e._studs.$mount,e._studs=null),e.hasOwnProperty("state")&&delete e.state;let t=O.get(e);t&&(t.bindings&&(t.bindings.forEach(o=>{let s=Y[o.type];if(s&&s.destroy)try{s.destroy({binding:o})}catch(r){console.error(`[Lego] Error in directive cleanup (${o.type}):`,r)}o.node=null,o.anchor=null}),t.bindings=null),t.anchor=null,O.delete(e)),[...e.children].forEach(M)};function Qe(e,t="block.lego"){let o={template:"",script:"",style:"",stylesAttr:"",cascadeAttr:"",errorAttr:"",blockName:_e(t),hasTemplate:!1,hasScript:!1,hasStyle:!1},s=e,r=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;s;){let a=s.match(r);if(!a)break;let n=a[1].toLowerCase(),i=a[2],c=a[0],d=a.index,l=`</${n}>`,u=d+c.length,f=s.indexOf(l,u);if(f===-1){console.warn(`[Lego] Unclosed <${n}> tag in ${t}`);break}let m=s.slice(u,f);if(n==="template"){o.hasTemplate=!0,o.template=m.trim();let x=i.match(/b-stylesheets=["']([^"']+)["']/);x&&(o.stylesAttr=x[1]);let E=i.match(/b-cascade=["']([^"']+)["']/);E&&(o.cascadeAttr=E[1]);let L=i.match(/b-error=["']([^"']+)["']/);L&&(o.errorAttr=L[1])}else if(n==="script"){o.hasScript=!0,o.script=m.trim();let x=i.match(/lang=["']([^"']+)["']/);x&&(o.scriptLang=x[1])}else n==="style"&&(o.hasStyle=!0,o.style=m.trim());s=s.slice(f+l.length)}return o}var Ze=(e,t,o="block.lego")=>{let s=Qe(t,o),{blockName:r,template:a,script:n,style:i,stylesAttr:c,cascadeAttr:d,errorAttr:l}=s,u={};if(n)try{let m=n.trim(),x=m.match(/export\s+default\s+(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*({[\s\S]*})/),E=x?x[1]:m;u=new Function("Lego","$db",`return ${E}`)(e,e.globals.$db)}catch(m){g.onError(m,"script",r)}let f=a;i&&(f=`<style>${i}</style>`+f),y[r]=document.createElement("template"),y[r].innerHTML=f,c&&y[r].setAttribute("b-stylesheets",c),d&&y[r].setAttribute("b-cascade",d),l&&y[r].setAttribute("b-error",l),j.set(r,u),document.querySelectorAll(r).forEach(m=>!C(m).snapped&&N(m))};ee.setHandler(oe);Ke(N,oe);Le(N);Ne(N,M);var it={url:typeof window<"u"?window.location.pathname:"/",route:"",params:{},query:{},method:"GET",body:null},ct={add(){q.forEach(e=>ee.add(e))}},B=K({$route:it,$go:(e,...t)=>le(e,...t)(document.body),$mount:(e,t,o)=>R(e,t,o),$db:ye},typeof document<"u"?document.body:null,ct);$e(B);var b={db:ye,snap:N,unsnap:M,mount:R,defineLegoFile:(e,t)=>Ze(b,e,t),block:(e,t,o={},s="",r="",a="")=>{let n=document.createElement("template");n.setAttribute("b-id",e),n.setAttribute("b-stylesheets",s),r&&n.setAttribute("b-cascade",r),a&&n.setAttribute("b-error",a),n.innerHTML=t,y[e]=n,j.set(e,o);try{let i={};W(o,i),ne.set(e.toLowerCase(),K(i,document.body))}catch(i){g.onError(i,"define",e)}if(customElements.get(e))document.querySelectorAll(e).forEach(i=>{M(i),N(i)}),A.forEach(i=>{i._legoShadow&&i._legoShadow.querySelectorAll(e).forEach(c=>{M(c),N(c)})});else try{customElements.define(e,class extends HTMLElement{connectedCallback(){H.locked||y[e]&&N(this)}disconnectedCallback(){M(this)}})}catch(i){console.warn(`[Lego] Failed to register web component ${e}:`,i)}},getActiveBlocksCount:()=>A.size,getLegos:()=>Object.keys(y),config:g,globals:B,route:(e,t,o=null)=>{let s=[],r=e==="*"?".*":e;r=r.replace(/:([^\/]+)|[.*+?^${}()|[\]\\]/g,(a,n)=>n?(s.push(n),"([^/]+)"):"\\"+a),Z.push({path:e,regex:new RegExp(`^${r}$`),tagName:t,paramNames:s,middleware:o})},debug:{stylesheets:e=>!e||!e._studsMeta?null:e._studsMeta.stylesheets},init:async(e=document.body,t={})=>{if((!e||typeof e.nodeType!="number")&&(e=document.body),Ve(t.styles||{}),g.loader=t.loader,g.debug=t.debug===!0,await Xe(),Z.length>0){let r=window.location.pathname,a=window.location.search,n=ge(r);if(n){let{match:i,params:c}=n,d=Object.fromEntries(new URLSearchParams(a));B.$route.url=r+a,B.$route.route=i.path,B.$route.params=c,B.$route.query=d,B.$route.method="GET",B.$route.body=null}}document.querySelectorAll("template[b-id]").forEach(r=>{let a=r.getAttribute("b-id");y[a]=r,customElements.get(a)||customElements.define(a,class extends HTMLElement{connectedCallback(){H.locked||y[a]&&N(this)}disconnectedCallback(){M(this)}})});let o=r=>{if(!r)return{};let a={};return Object.entries(r).forEach(([n,i])=>{if(typeof i=="function")a[n]=i();else if(typeof i=="string"&&i.startsWith("$db.")){let c=i.slice(4);a[n]=b.db(c).get()}else if(typeof i=="string"&&i.startsWith("$globals.")){let c=i.slice(9);a[n]=w[c]}else a[n]=i}),a},s=(r,a,n={})=>{customElements.get(r)||customElements.define(r,class extends HTMLElement{async connectedCallback(){if(y[r]){H.locked||N(this);return}if(b._fetching||(b._fetching=new Set),b._pendingLazy||(b._pendingLazy={}),b._fetching.has(r)){b._pendingLazy[r]||(b._pendingLazy[r]=new Set),b._pendingLazy[r].add(this);return}b._fetching.add(r);try{let i=a.startsWith("POST:")?"POST":"GET",c=a.replace(/^POST:/,""),d=o(n.headers),l={method:i,headers:d,credentials:n.credentials},u=await fetch(c,l);if(!u.ok)throw new Error(`HTTP ${u.status} loading block "${r}" from ${c}`);let f=await u.text();b.defineLegoFile(f,`${r}.lego`),y[r]&&N(this);let m=b._pendingLazy[r];m&&(m.forEach(x=>{x.isConnected&&y[r]&&!C(x).snapped&&N(x)}),delete b._pendingLazy[r])}catch(i){console.error(`[Lego] Failed to load manifest block ${r}:`,i)}finally{b._fetching.delete(r)}}disconnectedCallback(){M(this)}})};if(t.manifest){let r=t.manifest;if(r.url&&typeof r.url=="string")try{let n=o(r.headers);r=await(await fetch(r.url,{headers:n,credentials:r.credentials})).json()}catch(n){console.error("[Lego] Failed to load manifest:",n),r=[]}else if(typeof r=="string")try{r=await(await fetch(r)).json()}catch(n){console.error("[Lego] Failed to load manifest:",n),r=[]}let a=Array.isArray(r)?r:[r];for(let n of a){let i=n.base||"",c=n.suffix===!0?".lego":n.suffix||"",d={headers:n.headers||{},credentials:n.credentials};n.legos&&n.legos.forEach(l=>{s(l,`${i}${l}${c}`,d)}),n.map&&Object.entries(n.map).forEach(([l,u])=>{let f=u.match(/^https?:|^\//)?u:`${i}${u}`;s(l,f,d)})}}if(g.loader){let r=n=>{if(n.nodeType!==Node.ELEMENT_NODE)return;let i=n.tagName.toLowerCase();if(i.includes("-")&&!y[i]&&!A.has(n)){if(b._fetching&&b._fetching.has(i))return;b._fetching||(b._fetching=new Set),b._fetching.add(i);let c=g.loader(i);if(c){let d=typeof c=="string"?fetch(c).then(l=>l.text()):c;Promise.resolve(d).then(l=>{b.defineLegoFile(l,`${i}.lego`),b._fetching.delete(i)}).catch(l=>{console.error(`[Lego] Failed to load ${i}:`,l),b._fetching.delete(i)})}}if(n.children.length>0){let c=n.firstElementChild;for(;c;)r(c),c=c.nextElementSibling}};b._discoveryObserver&&b._discoveryObserver.disconnect(),b._discoveryObserver=new MutationObserver(n=>n.forEach(i=>{i.addedNodes.forEach(r)})),b._discoveryObserver.observe(e,{childList:!0,subtree:!0});let a=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;a.nextNode();)r(a.currentNode)}if(t.studio){if(!y["lego-studio"]){let r=document.createElement("script");r.src="https://unpkg.com/@legodom/studio@0.0.2/dist/lego-studio.js",r.onerror=()=>console.warn("[Lego] Failed to load Studio from CDN"),document.head.appendChild(r)}b.route("/_/studio","lego-studio"),b.route("/_/studio/:block","lego-studio")}Z.length>0&&(window.addEventListener("popstate",r=>{let a=r.state?.legoTargets||null;ce(a)}),document.addEventListener("submit",r=>{r.target.hasAttribute("b-action")&&r.preventDefault()}),document.addEventListener("click",r=>{let n=r.composedPath().find(i=>i.tagName==="A"&&(i.hasAttribute("b-target")||i.hasAttribute("b-link")));if(n){r.preventDefault();let i=n.getAttribute("href"),c=n.getAttribute("b-target"),d=c?c.split(/\s+/).filter(Boolean):[],l=n.getAttribute("b-link")!=="false";B.$go(i,...d).get(l)}}),ce()),je()}};typeof window<"u"?window.Lego=b:typeof global<"u"&&(global.Lego=b);var Ho=b;export{b as Lego,Ho as default};
7
+ `),We.set(e,n));let i={$ancestors:s=>V(t.self,s),$registry:s=>ee.get(s.toLowerCase()),$element:t.self,$route:_.$route,$params:_.$route?.params||{},$go:(s,...c)=>ge(s,...c)(t.self),$db:_.$db,$mount:(s,c,f)=>F(s,c,f),$emit:(s,c)=>{t.self.dispatchEvent(new CustomEvent(s,{detail:c,bubbles:!0,composed:!0}))}},a=n.call(o,t.global,t.self,t.event,i);return typeof a=="function"&&t.event!==void 0?a.call(o,t.event):a}catch(o){if(r)throw o;if(o instanceof ReferenceError&&!g.strict)return;throw o}},_e=(e,t={})=>{if(!e||e.trim()==="{}")return{};let[r,o]=oe();if(e.includes(r)&&e.includes(o))return console.error(`[Lego] Refusing to parse b-logic containing template delimiters ("${r}...${o}"). b-logic is evaluated as JavaScript; templating user data into it is unsafe. Pass values through state instead. Got: "${e.length>80?e.slice(0,80)+"...":e}"`),{};let n=a=>{let s=Ie.get(a);return s||(s=new Function("scope","global",`with(global) { with(scope) { return (${a}); } }`),Ie.set(a,s)),s},i=a=>n(a)(t,_);try{return i(e)}catch(a){let s=e.trim();if(!s.startsWith("{")&&s.includes(":"))try{return i(`{${e}}`)}catch{}return console.error(`[Lego] Error parsing b-logic: "${e.length>80?e.slice(0,80)+"...":e}"`,a),{}}};var qe={name:"b-if",scan:(e,{checkGlobal:t,getPrivateData:r})=>O("b-if",e,(o,n)=>{t(o.value);let i=document.createComment(`b-if: ${o.value}`),a=r(n);return a.anchor=i,{anchor:i}}),execute({binding:e,state:t,global:r}){let{node:o,anchor:n,expr:i}=e,a=!!L(i,{state:t,global:r,self:o}),s=!!o.parentNode;a&&!s?n.parentNode&&n.parentNode.replaceChild(o,n):!a&&s&&o.parentNode.replaceChild(n,o)},destroy({binding:e}){e.anchor&&e.anchor.parentNode&&e.anchor.remove()}};var je={name:"b-show",scan(e,{checkGlobal:t}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-show")){let r=e.getAttribute("b-show");return t(r),{type:"b-show",node:e,expr:r}}},execute({binding:e,state:t,global:r}){let{node:o,expr:n}=e;o._bShowOriginal===void 0&&(o._bShowOriginal=o.style.display);let i=!!L(n,{state:t,global:r,self:o});o.style.display=i?o._bShowOriginal:"none"}};var Ke={name:"b-text",scan(e,{checkGlobal:t}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-text")){let r=e.getAttribute("b-text");return t(r),{type:"b-text",node:e,path:r}}},execute({binding:e,state:t,global:r}){let{node:o,path:n}=e;n.startsWith("global.")?o.textContent=D(n.slice(7),r)??"":o.textContent=D(n,t)??""}};var Ge={name:"b-html",scan:e=>O("b-html",e),execute:({binding:e,state:t,global:r,helpers:o})=>{let{node:n,expr:i,modifiers:a}=e,s=L(i,{state:t,global:r,self:n})??"";if(a&&a.includes("safe")&&(s=(typeof g.sanitize=="function"?g.sanitize:Re)(s)),n._bHtmlPrev!==s){n._bHtmlPrev=s;let c=o&&o.contextEl;if(c){let f=A.get(c);if(f&&f.bindings&&f.bindings.length){for(let l of f.bindings)l!==e&&l.node&&l.node!==n&&n.contains(l.node)&&(l.dead=!0,l.node=null);f.bindings.some(l=>l.dead)&&(f.bindings=f.bindings.filter(l=>!l.dead))}}n.innerHTML=s}},destroy({binding:e}){let{node:t}=e;t&&(delete t._bHtmlPrev,t.innerHTML="")}};var Ue={name:"b-sync",scan(e,{checkGlobal:t}){if(e.nodeType!==Node.ELEMENT_NODE)return;let r=K(e);if(!r)return;t(r.value);let o=r.name.split(".").slice(1);return{type:"b-sync",node:e,expr:r.value,modifiers:o}},execute({binding:e,state:t,global:r}){let{node:o,expr:n}=e;n.startsWith("global.")?re(o,D(n.slice(7),r)??""):re(o,D(n,t)??"")},destroy({binding:e}){let{node:t}=e;t&&t._bSyncHandler&&(t.removeEventListener("input",t._bSyncHandler),t.removeEventListener("change",t._bSyncHandler),delete t._bSyncHandler)}};var Tt=0,Je={name:"b-for",scan(e,{checkGlobal:t,pendingOperations:r}){if(e.nodeType!==Node.ELEMENT_NODE)return;let o=e.getAttribute("b-for")?.match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);if(o){t(o[2]);let n=document.createComment(`b-for: ${o[1]} in ${o[2].trim()}`);return r.push(()=>{e.parentNode&&(e.parentNode.insertBefore(n,e),e.remove())}),{type:"b-for",anchor:n,itemName:o[1],listName:o[2].trim(),keyPath:e.getAttribute("b-key")||null,template:e.cloneNode(!0),terminal:!0}}},execute({binding:e,state:t,global:r,helpers:o}){let{bind:n,scanForBindings:i,runBinding:a}=o;if(!n||!a){console.error("[Lego] b-for directive missing required helpers: bind, runBinding");return}let{anchor:s,listName:c,itemName:f,keyPath:l,template:u}=e,{contextEl:d}=o,p=L(c,{state:t,global:r,self:d})||[];W.has(s)||W.set(s,new Map);let m=W.get(s),h=new Set,x=[];p.forEach((w,E)=>{let $;l?($=D(l,w),($==null||$==="")&&(console.warn(`[Lego] b-key="${l}" could not resolve a value for item at index ${E}. Falling back to index-based key.`),$=`__bfor_${E}`)):w&&typeof w=="object"?($=w.id||w._id||w.uuid||w.key,$===void 0&&(ue.has(w)||ue.set(w,++Tt),$=ue.get(w))):$=`${E}-${w}`,h.add($);let b=m.get($);b?b._loopCtx.index=E:(b=u.cloneNode(!0),b.removeAttribute("b-for"),b.removeAttribute("b-key"),m.set($,b),b._loopCtx={name:f,listName:c,index:E},n(b,d,b._loopCtx),i&&(b._loopBindings=i(b,d)));let k=b._loopScope;if(k||(b._loopScope=k=Object.create(t)),k[f]=w,k.$index=E,b._loopBindings)for(let P of b._loopBindings)try{a(P,k,d,!1)}catch(Oe){console.error("[Lego] Error in b-for inner binding:",Oe)}[b,...b.querySelectorAll("*")].filter(P=>K(P)).forEach(P=>{let Be=K(P).value;Be.startsWith(`${f}.`)&&re(P,D(Be.split(".").slice(1).join("."),p[E]))}),x.push(b)});let y=s.nextSibling;x.forEach(w=>{w!==y?s.parentNode.insertBefore(w,y):y=y.nextSibling});for(let[w,E]of m.entries())h.has(w)||(E.remove(),m.delete(w))},destroy({binding:e}){let{anchor:t}=e;if(t&&W.has(t)){let r=W.get(t);r.forEach(o=>{[o,...o.querySelectorAll("*")].forEach(i=>{let a=A.get(i);a&&(a.listeners&&(a.listeners.forEach(({eventName:s,handler:c})=>{i.removeEventListener(s,c)}),a.listeners=null),a.bindings&&(a.bindings.forEach(s=>{s.observer&&(s.observer.disconnect(),s.observer=null)}),a.bindings=null))}),o.remove()}),r.clear(),W.delete(t)}t&&t.parentNode&&t.remove()}};var Ve={scan:e=>{if(e.hasAttribute("b-init"))return{type:"b-init",node:e,expr:e.getAttribute("b-init")}},execute:({binding:e,state:t,global:r})=>{e.initialized||(e.initialized=!0,L(e.expr,{state:t,global:r,self:e.node}))}};var Xe={name:"b-enter",scan:e=>O("b-enter",e,(t,r)=>({modifiers:t.name.split(".").slice(1)})),execute:({binding:e,state:t,global:r})=>{if(e.observer||e.done)return;let o=new IntersectionObserver((n,i)=>{if(n[0].isIntersecting){try{L(e.expr,{state:t,global:r,self:e.node})}catch(s){console.error("[Lego] Error in b-enter handler:",s)}e.modifiers.includes("once")&&(i.disconnect(),e.observer=null,e.done=!0)}});o.observe(e.node),e.observer=o},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Ze={name:"b-leave",scan:e=>O("b-leave",e),execute:({binding:e,state:t,global:r})=>{if(e.observer||e.done)return;let o=new IntersectionObserver((n,i)=>{let a=n[0];if(a.isIntersecting&&(e.activated=!0),!a.isIntersecting&&e.activated){try{L(e.expr,{state:t,global:r,self:e.node})}catch(s){console.error("[Lego] Error in b-leave handler:",s)}e.modifiers.includes("once")&&(i.disconnect(),e.observer=null,e.done=!0)}});o.observe(e.node),e.observer=o},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Qe={name:"b-mount",scan:(e,{checkGlobal:t})=>O("b-mount",e,r=>(t(r.value),{_lastTag:null})),execute({binding:e,state:t,global:r}){let{node:o,expr:n}=e,i=L(n,{state:t,global:r,self:o},!1),a=i?String(i).toLowerCase():null;a!==e._lastTag&&(e._lastTag=a,F(a,o))},destroy({binding:e}){e.node&&F(null,e.node),e._lastTag=null}};var se={"b-if":qe,"b-show":je,"b-text":Ke,"b-html":Ge,"b-sync":Ue,"b-for":Je,"b-init":Ve,"b-enter":Xe,"b-leave":Ze,"b-mount":Qe};var At=(e=null)=>{let t=!1,r=new Set,o=!1,n=e,i=new Set,a=null,s=new Set,c=d=>{n=d},f=()=>{a||(a=setTimeout(()=>{s.forEach(d=>{let p=d._studs;if(p&&typeof p.updated=="function")try{p.updated.call(p)}catch(m){console.error("[Lego] Error in updated hook:",m)}}),s.clear(),a=null},50))},l=()=>{i.size>0&&(i.forEach(d=>r.add(d)),i.clear(),!t&&r.size>0&&(t=!0,requestAnimationFrame(u)))},u=()=>{o=!0;let d=Array.from(r);r.clear(),t=!1,d.forEach(p=>{p.isConnected&&n&&n(p)}),d.forEach(p=>s.add(p)),f(),o=!1,l()};return{add:d=>{if(d){if(o){i.add(d);return}r.add(d),!t&&(t=!0,requestAnimationFrame(u))}},setHandler:c}},X=At();var N=new Map,he=new Map,ie=new WeakMap,le=new Map,ae=new WeakMap,ce=!1,kt=e=>{let t=Array.from(le.entries()).sort((n,i)=>n[1].timestamp-i[1].timestamp),r=0,o=[];for(let[n,i]of t){if(r>=e)break;try{localStorage.removeItem(n),r+=i.size,o.push(n),le.delete(n)}catch(a){console.error(`[Lego] Failed to evict ${n}:`,a)}}return o},et=(e,t,r)=>{g.debug&&console.log("[Lego Trace] scheduleSave",e,t,r),he.has(e)&&clearTimeout(he.get(e));let o=()=>{try{let n=JSON.stringify(t),i=new Blob([n]).size;localStorage.setItem(e,n),le.set(e,{timestamp:Date.now(),size:i}),he.delete(e)}catch(n){if(n.name==="QuotaExceededError"){console.warn(`[Lego] Storage quota exceeded for key: ${e}`);try{let i=JSON.stringify(t),a=new Blob([i]).size,s=kt(a*2);s.length>0?(g.debug&&console.log(`[Lego] Evicted ${s.length} old keys, retrying save`),localStorage.setItem(e,i),le.set(e,{timestamp:Date.now(),size:a})):g.onError(new Error("Storage quota exceeded and no keys available for eviction"),"quota",e)}catch{g.onError(new Error(`Critical: Could not save ${e} even after eviction`),"quota-critical",e)}}else console.error(`[Lego] Storage Error (${e}):`,n)}};r>0?he.set(e,setTimeout(o,r)):o()},Le=e=>({__type:"lego-db",key:e,_default:void 0,_debounce:0,default(r){return this._default=r,this},debounce(r){return this._debounce=r,this},set(r,o=0){return et(e,r,o),N.has(e)&&N.get(e).forEach(({target:n,prop:i,el:a,batcher:s})=>{n[i]=r,a&&s&&s.add(a)}),r},get(){try{let r=localStorage.getItem(e);return r!==null?JSON.parse(r):null}catch(r){return console.warn(`[Lego] Failed to get localStorage value for key "${e}":`,r),null}},delete(){try{return localStorage.removeItem(e),le.delete(e),N.has(e)&&N.get(e).forEach(({target:r,prop:o,el:n,batcher:i})=>{r[o]=null,n&&i&&i.add(n)}),!0}catch(r){return console.error(`[Lego] Failed to delete localStorage key "${e}":`,r),!1}}}),tt=e=>e&&e.__type==="lego-db",rt=(e,t,r,o,n)=>{g.debug&&console.log("[Lego Trace] Reactive DB Init:",t,r);let i=r._default;try{let s=localStorage.getItem(r.key);s!==null&&(i=JSON.parse(s))}catch(s){console.warn(`[Lego] Failed to parse localStorage value for key "${r.key}":`,s)}e[t]=i,ie.has(e)||ie.set(e,{}),ie.get(e)[t]={key:r.key,debounce:r._debounce},g.debug&&console.log("[Lego Trace] DB Metadata Set:",t,ie.get(e)[t]),N.has(r.key)||N.set(r.key,new Set);let a={target:e,prop:t,el:o,batcher:n};N.get(r.key).add(a),o&&(ae.has(o)||ae.set(o,new Set),ae.get(o).add({key:r.key,entry:a}))},ot=(e,t,r)=>{if(ce)return;let o=ie.get(e);if(o&&o[t]){let n=o[t].key;if(et(n,r,o[t].debounce),N.has(n)){ce=!0;try{N.get(n).forEach(({target:i,prop:a,el:s,batcher:c})=>{i!==e&&(i[a]=r,s&&c&&c.add(s))})}finally{ce=!1}}}},nt=e=>{let t=ae.get(e);t&&(t.forEach(({key:r,entry:o})=>{let n=N.get(r);n&&n.delete(o)}),ae.delete(e))},Ye=!1,st=()=>{typeof window>"u"||Ye||(Ye=!0,window.addEventListener("storage",e=>{if(!(!e.key||!N.has(e.key)))try{let t=e.newValue===null?null:JSON.parse(e.newValue);ce=!0;try{N.get(e.key).forEach(({target:r,prop:o,el:n,batcher:i})=>{r[o]=t,n&&i&&i.add(n)})}finally{ce=!1}}catch(t){console.warn("[Lego] Cross-tab sync error:",t)}}))};var Te=new WeakMap,be=null,Ae=null,it=(e,t)=>{be=e,Ae=t},at=()=>{be=null,Ae=null},ct=(e,t,r)=>{if(!be||Ae!==e)return;let o=Te.get(e);o||(o=new Map,Te.set(e,o));let n=o.get(t);n||(n=new Map,o.set(t,n));let i=n.get(r);i||(i=new Set,n.set(r,i)),i.add(be)},lt=(e,t,r)=>{let o=Te.get(e);if(!o)return null;let n=o.get(t);return n&&n.get(r)||null};var Z=(e,t,r=X)=>{if(e===null||typeof e!="object"||ve(e))return e;if(Y.has(e))return Y.get(e);for(let i in e){let a=Object.getOwnPropertyDescriptor(e,i);if(a&&a.get)continue;let s=e[i];tt(s)&&rt(e,i,s,t,r)}let o={get:(i,a,s)=>{ct(t,i,a);let c=Reflect.get(i,a,s);return c!==null&&typeof c=="object"&&!ve(c)?Z(c,t,r):c},set:(i,a,s,c)=>{if(a==="__proto__"||a==="constructor"||a==="prototype")return console.warn(`[Lego] Blocked setting dangerous property: "${a}"`),!0;let f=i[a];g.debug&&f!==s&&console.log("[Lego Trace] Reactive SET:",a,"Old:",f,"New:",s,"Target:",i);let l=c===Y.get(i),u=Object.prototype.hasOwnProperty.call(i,a),d=!l&&u?Reflect.set(i,a,s):Reflect.set(i,a,s,c);if((l||u)&&f!==s){let p=lt(t,i,a);if(p&&p.size>0){let m=A.get(t);m&&(m.dirtyBindings||(m.dirtyBindings=new Set),p.forEach(h=>m.dirtyBindings.add(h)))}r.add(t,a),ot(i,a,s)}return d},deleteProperty:(i,a)=>{let s=Reflect.deleteProperty(i,a),c=A.get(t);return c&&(c.dirtyBindings=null),r.add(t),s}},n=new Proxy(e,o);return Y.set(e,n),n};var Nt=e=>{let t=e;for(;t;){let r=t.getAttribute&&t.getAttribute("b-error");if(r&&r.toLowerCase()!==e.tagName.toLowerCase())return{errorTag:r,targetElement:t};let o=t.tagName?t.tagName.toLowerCase():"",n=S[o];if(n){let i=n.getAttribute("b-error");if(i&&i.toLowerCase()!==e.tagName.toLowerCase())return{errorTag:i,targetElement:t}}t=t.parentElement||t.getRootNode&&t.getRootNode().host}return null},ke=null,ft=null,dt=(e,t)=>{ke=e,ft=t},Ct=(e,t,r)=>{if(!ke||!ft){console.error("[Lego] Error boundary dependencies not loaded",r);return}try{t.shadowRoot?t.shadowRoot.innerHTML="":t.innerHTML="";let o=document.createElement(e);o.$initialState={$error:{message:r.message,stack:r.stack,component:t.tagName.toLowerCase()}},(t.shadowRoot||t).appendChild(o),ke(o)}catch(o){console.error("[Lego] Error boundary failed to render:",o),console.error("[Lego] Original error:",r)}},fe=new WeakMap,Mt=3,Q=(e,t,r)=>{let o=Nt(t);if(!o){g.onError(e,r,t);return}let n=o.targetElement,i=fe.get(n)||0;if(i>=Mt){console.error("[Lego] Error boundary recursion limit reached:",e),g.onError(e,r,t);return}fe.set(n,i+1);try{Ct(o.errorTag,n,e)}finally{let a=(fe.get(n)||0)-1;a<=0?fe.delete(n):fe.set(n,a)}};var ye=(e,t,r=null)=>{let o=t._studs,n=s=>{let c=M(s);if(!c.bound){if(s.hasAttributes()){let f=s.attributes;for(let u=0;u<f.length;u++){let d=f[u];if(d.name.startsWith("@")){let p=d.name.slice(1).split("."),m=p[0],h=p.slice(1),x=y=>{if(h.includes("prevent")&&y.preventDefault(),h.includes("stop")&&y.stopPropagation(),!(h.includes("self")&&y.target!==y.currentTarget)){if(typeof KeyboardEvent<"u"&&y instanceof KeyboardEvent){if(h.includes("ctrl")&&!y.ctrlKey||h.includes("alt")&&!y.altKey||h.includes("shift")&&!y.shiftKey||h.includes("meta")&&!y.metaKey)return;let w=h.filter(E=>!["prevent","stop","self","ctrl","alt","shift","meta","capture","once","passive"].includes(E));if(w.length>0){let E=y.key.toLowerCase();if(!w.some(b=>b==="enter"?E==="enter":b==="esc"||b==="escape"?E==="escape":b==="space"?E===" ":b==="tab"?E==="tab":b==="delete"?E==="delete":b==="backspace"?E==="backspace":b==="up"?E==="arrowup":b==="down"?E==="arrowdown":b==="left"?E==="arrowleft":b==="right"?E==="arrowright":b==="alpha"?/^[a-z]$/.test(E):b==="numbers"?/^[0-9]$/.test(E):b===E))return}}try{let w=o;if(r){let $=L(r.listName,{state:o,global:_,self:t})[r.index];w=Object.assign(Object.create(o),{[r.name]:$})}L(d.value,{state:w,global:_,self:s,event:y,$event:y},!0)}catch(w){Q(w,t,"event-handler")}}};s.addEventListener(m,x),c.listeners||(c.listeners=[]),c.listeners.push({eventName:m,handler:x})}}let l=K(s);if(l){let u=l.value,d=l.name.split(".").slice(1),p=d.includes("lazy"),m=d.includes("number"),h=d.includes("trim"),x=()=>{try{let y,w;if(u.startsWith("global.")){let $=u.slice(7).split(".");w=$.pop(),y=$.reduce((b,k)=>b[k],_)}else if(r&&u.startsWith(`${r.name}.`)){let b=L(r.listName,{state:o,global:_,self:t})[r.index];if(!b)return;let k=u.split(".").slice(1);w=k.pop(),y=k.reduce((Me,P)=>Me[P],b)}else{let $=u.split(".");w=$.pop(),y=$.reduce((b,k)=>b[k],o)}let E=s.type==="checkbox"?s.checked:s.value;if(h&&typeof E=="string"&&(E=E.trim()),m){let $=parseFloat(E);isNaN($)||(E=$)}y&&y[w]!==E&&(y[w]=E)}catch(y){g.onError(y,"sync-update",s)}};s._bSyncHandler=x,c.listeners||(c.listeners=[]),p||(s.addEventListener("input",x),c.listeners.push({eventName:"input",handler:x})),s.addEventListener("change",x),c.listeners.push({eventName:"change",handler:x})}if(s.hasAttribute("b-var")){let u=s.getAttribute("b-var");o.$vars&&(o.$vars[u]=s)}}c.bound=!0}};e instanceof Element&&n(e);let i=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),a;for(;a=i.nextNode();)n(a)},ut=(e,t=null)=>{let r=[],o=[],[n]=oe(),i=t||e.host||e,a=Object.entries(se),s=/\bglobal\.([\w$]+)([\w$.]*)/g,c=l=>{if(!/\bglobal\b/.test(l))return;let u=!1,d=new Set,p;for(s.lastIndex=0;(p=s.exec(l))!==null;){if((p[2]||"").includes(".")){u=!0;break}d.add(p[1])}if(d.size===0&&(u=!0),u){U.add(i);return}d.forEach(m=>{let h=I.get(m);h||(h=new Set,I.set(m,h)),h.add(i)})},f=l=>{if(l.nodeType===Node.ELEMENT_NODE){let u=!1;for(let[,d]of a){if(!d.scan)continue;let p=d.scan(l,{checkGlobal:c,getPrivateData:M,pendingOperations:o,current:l});p&&(r.push(p),p.terminal&&(u=!0))}if(u)return;for(let d of l.attributes)d.value.includes(n)&&(c(d.value),r.push({type:"attr",node:l,attrName:d.name,template:d.value}));for(let d=l.firstChild;d;d=d.nextSibling)f(d)}else l.nodeType===Node.TEXT_NODE&&l.textContent.includes(n)&&(c(l.textContent),r.push({type:"text",node:l,template:l.textContent}))};if(e.nodeType===Node.ELEMENT_NODE)for(let l of e.attributes)l.value.includes(n)&&(c(l.value),r.push({type:"attr",node:e,attrName:l.name,template:l.value}));else e.nodeType===Node.TEXT_NODE&&e.textContent.includes(n)&&(c(e.textContent),r.push({type:"text",node:e,template:e.textContent}));for(let l=e.firstChild;l;l=l.nextSibling)f(l);return o.forEach(l=>l()),r},Ne=(e,t,r,o=!0)=>{if(!e.dead){o&&it(e,r);try{let n=se[e.type];if(n){n.execute({binding:e,state:t,global:_,helpers:{bind:ye,scanForBindings:ut,runBinding:Ne,contextEl:r}});return}if(e.type==="text"){let i=e.template.replace(we(),(a,s)=>L(s.trim(),{state:t,global:_,self:e.node},!1)??"");e.node.textContent!==i&&(e.node.textContent=i)}else if(e.type==="attr"){let i=e.template.replace(we(),(a,s)=>L(s.trim(),{state:t,global:_,self:e.node},!1)??"");e.node.getAttribute(e.attrName)!==i&&(e.node.setAttribute(e.attrName,i),e.attrName==="class"&&(e.node.className=i))}}finally{o&&at()}}},de=e=>{g.debug&&console.log("[Lego Trace] render() called for:",e.tagName);let t=e._studs;if(!t)return;let r=M(e);if(!r.rendering){r.rendering=!0,g.metrics&&g.metrics.onRenderStart&&g.metrics.onRenderStart(e);try{let o=e.shadowRoot||e;if(r.bindings||(r.bindings=ut(o)),r.dirtyBindings&&r.dirtyBindings.size>0){let n=r.dirtyBindings;r.dirtyBindings=null,n.forEach(i=>Ne(i,t,e))}else r.bindings.forEach(n=>Ne(n,t,e))}catch(o){Q(o,e,"render")}finally{g.metrics&&g.metrics.onRenderEnd&&g.metrics.onRenderEnd(e),r.rendering=!1}}};var pt=new Map,H=new Map,mt={},gt=e=>{mt=e},ht=async()=>{let e=Object.entries(mt).map(async([t,r])=>{let o=await Promise.all(r.map(async n=>{try{if(n instanceof CSSStyleSheet)return n;let i=await fetch(n);if(!i.ok)throw new Error(`Status ${i.status}`);let a=await i.text(),s=new CSSStyleSheet;return await s.replace(a),s}catch(i){return console.error(`[Lego] Failed to load stylesheet: ${n}`,i),null}}));pt.set(t,o.filter(n=>n!==null))});await Promise.all(e),g.debug&&console.log("[Lego Debug] Re-applying stylesheets to",C.size,"blocks"),C.forEach(t=>{Ce(t)})},Ce=e=>{if(!e.shadowRoot&&!e._legoShadow)return;let t=e.shadowRoot||e._legoShadow,r=e.tagName.toLowerCase(),o=S[r],n=(o&&o.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),i=(e.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),a=[],s=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;s;){let u=(s.getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);u.length&&a.push(...u);let d=s.tagName?s.tagName.toLowerCase():"",p=H.get(d);p&&p.length&&a.push(...p),s=s.parentElement||s.getRootNode&&s.getRootNode().host}let c=[...new Set([...n,...i])],f=[...new Set(a)],l=[...new Set([...f,...c])];if(l.length>0){let u=l.flatMap(d=>pt.get(d)||[]);if(u.length>0&&g.debug&&console.log("[Lego Debug] Applying styles to",e.tagName,"- Names:",l,"- Sheets:",u.length),u.length>0){let d=t.adoptedStyleSheets.filter(p=>!u.includes(p));t.adoptedStyleSheets=[...d,...u]}}e._studsMeta={stylesheets:{explicit:c,inherited:f,applied:l}}};var bt=!1,T=e=>{if(g.debug&&console.log("[Lego Trace] snap() called for:",e.tagName),!e||e.nodeType!==Node.ELEMENT_NODE)return;let t=M(e),r=e.tagName.toLowerCase(),o=S[r];if(o&&!t.snapped){t.snapped=!0;let i=o.content.cloneNode(!0),a=e.shadowRoot;a?a.innerHTML="":a=e.attachShadow({mode:"open"}),Ce(e);let s=V(e,"*")||V(e.getRootNode().host,"*"),c=s&&s.state?s.state:{},f=q.get(r)||{},l=_e(o.getAttribute("b-logic")||o.getAttribute("b-data")||"{}"),u=_e(e.getAttribute("b-logic")||e.getAttribute("b-data")||"{}",c),d={$vars:{},$element:e,get $parent(){return V(e,"*")},$emit:(h,x)=>{e.dispatchEvent(new CustomEvent(h,{detail:x,bubbles:!0,composed:!0}))},get $route(){return _.$route},get $go(){return _.$go},get $mount(){return _.$mount}};G(f,d),G(l,d),G(u,d),e.$initialState&&(G(e.$initialState,d),delete e.$initialState),z.validate({instanceLogic:u,state:d,tagName:r}),e._studs=Z(d,e),Object.defineProperty(e,"state",{get(){return this._studs},set(h){bt||(bt=!0,console.warn("[Lego] `el.state = X` performs a shallow merge (Object.assign), not a replacement. Keys present on state but absent from X are preserved. Mutate state keys directly if you want this behaviour or remount the element to start fresh.")),Object.assign(this._studs,h)},configurable:!0,enumerable:!1}),j.locked=!0;try{a.appendChild(i)}finally{j.locked=!1}let p=a.querySelector("style");if(p){let h=[],x="__LEGO_SEG_",w=p.textContent.replace(/\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g,E=>(h.push(E),`${x}${h.length-1}__`)).replace(/(?<![-\w])self(?![-\w])/g,":host");p.textContent=w.replace(/__LEGO_SEG_(\d+)__/g,(E,$)=>h[+$])}if(ye(a,e),C.add(e),de(e),e.setAttribute("b-id",r),e._legoShadow||(e._legoShadow=a),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(h){Q(h,e,"mounted")}let m=a.querySelectorAll("*");g.debug&&console.log("[Lego Debug] Nested scan in",e.tagName,"- Found elements:",m.length),m.forEach(h=>{let x=h.tagName.toLowerCase(),y=!!S[x];y&&g.debug&&console.log("[Lego Debug] Checking",x,"- Registered:",y),y&&T(h)})}let n=e.parentElement;for(;n&&!n._studs;)n=n.parentElement;n&&n._studs&&ye(e,n),[...e.children].forEach(T)},B=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(r){Q(r,e,"unmounted")}if(e.shadowRoot){let r=document.createTreeWalker(e.shadowRoot,NodeFilter.SHOW_ELEMENT),o;for(;o=r.nextNode();){let n=A.get(o);n&&n.listeners&&(n.listeners.forEach(({eventName:i,handler:a})=>{o.removeEventListener(i,a)}),n.listeners=null)}[...e.shadowRoot.children].forEach(B)}nt(e),C.delete(e),U.delete(e),I.forEach(r=>r.delete(e)),e._studs&&(e._studs.$element=null,e._studs.$vars&&(Object.keys(e._studs.$vars).forEach(r=>{e._studs.$vars[r]=null}),e._studs.$vars=null),e._studs.$emit&&(e._studs.$emit=null),delete e._studs.$parent,delete e._studs.$route,delete e._studs.$go,delete e._studs.$mount,e._studs=null),e.hasOwnProperty("state")&&delete e.state;let t=A.get(e);t&&(t.bindings&&(t.bindings.forEach(r=>{let o=se[r.type];if(o&&o.destroy)try{o.destroy({binding:r})}catch(n){console.error(`[Lego] Error in directive cleanup (${r.type}):`,n)}r.node=null,r.anchor=null}),t.bindings=null),t.anchor=null,A.delete(e)),[...e.children].forEach(B)};function yt(e,t="block.lego"){let r={template:"",script:"",style:"",stylesAttr:"",cascadeAttr:"",errorAttr:"",propsAttr:"",blockName:Pe(t),hasTemplate:!1,hasScript:!1,hasStyle:!1},o=e,n=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;o;){let i=o.match(n);if(!i)break;let a=i[1].toLowerCase(),s=i[2],c=i[0],f=i.index,l=`</${a}>`,u=f+c.length,d=o.indexOf(l,u);if(d===-1){console.warn(`[Lego] Unclosed <${a}> tag in ${t}`);break}let p=o.slice(u,d);if(a==="template"){r.hasTemplate=!0,r.template=p.trim();let m=s.match(/b-stylesheets=["']([^"']+)["']/);m&&(r.stylesAttr=m[1]);let h=s.match(/b-cascade=["']([^"']+)["']/);h&&(r.cascadeAttr=h[1]);let x=s.match(/b-error=["']([^"']+)["']/);x&&(r.errorAttr=x[1]);let y=s.match(/b-props=["']([^"']+)["']/);y&&(r.propsAttr=y[1])}else if(a==="script"){r.hasScript=!0,r.script=p.trim();let m=s.match(/lang=["']([^"']+)["']/);m&&(r.scriptLang=m[1])}else a==="style"&&(r.hasStyle=!0,r.style=p.trim());o=o.slice(d+l.length)}return r}var Et=(e,t,r="block.lego")=>{let o=yt(t,r),{blockName:n,template:i,script:a,style:s,stylesAttr:c,cascadeAttr:f,errorAttr:l,propsAttr:u}=o,d={};if(a)try{let m=a.trim(),h=m.match(/export\s+default\s+(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*({[\s\S]*})/),x=h?h[1]:m;d=new Function("Lego","$db",`return ${x}`)(e,e.globals.$db)}catch(m){g.onError(m,"script",n)}let p=i;s&&(p=`<style>${s}</style>`+p),S[n]=document.createElement("template"),S[n].innerHTML=p,c&&S[n].setAttribute("b-stylesheets",c),f&&(S[n].setAttribute("b-cascade",f),H.set(n,f.split(/\s+/).filter(Boolean))),l&&S[n].setAttribute("b-error",l),u&&S[n].setAttribute("b-props",u),z.register(n,u),q.set(n,d),document.querySelectorAll(n).forEach(m=>!M(m).snapped&&T(m))};X.setHandler(de);dt(T,de);Fe(T);He(T,B);var Ot={url:typeof window<"u"?window.location.pathname:"/",route:"",params:{},query:{},method:"GET",body:null},Bt={add(e,t){if(t!==void 0){let r=I.get(t);r&&r.forEach(o=>X.add(o))}U.forEach(r=>X.add(r))}},R=Z({$route:Ot,$go:(e,...t)=>ge(e,...t)(document.body),$mount:(e,t,r)=>F(e,t,r),$db:Le},typeof document<"u"?document.body:null,Bt);De(R);var v={db:Le,snap:T,unsnap:B,mount:F,defineLegoFile:(e,t)=>Et(v,e,t),block:(e,t,r={},o="",n="",i="",a="")=>{let s=document.createElement("template");s.setAttribute("b-id",e),s.setAttribute("b-stylesheets",o),n&&s.setAttribute("b-cascade",n),i&&s.setAttribute("b-error",i),a&&s.setAttribute("b-props",a),s.innerHTML=t,S[e]=s,q.set(e,r),z.register(e,a),n?H.set(e,n.split(/\s+/).filter(Boolean)):H.delete(e);try{let c={};G(r,c),ee.set(e.toLowerCase(),Z(c,document.body))}catch(c){g.onError(c,"define",e)}if(customElements.get(e))document.querySelectorAll(e).forEach(c=>{B(c),T(c)}),C.forEach(c=>{c._legoShadow&&c._legoShadow.querySelectorAll(e).forEach(f=>{B(f),T(f)})});else try{customElements.define(e,class extends HTMLElement{connectedCallback(){j.locked||S[e]&&T(this)}disconnectedCallback(){B(this)}})}catch(c){console.warn(`[Lego] Failed to register web component ${e}:`,c),delete S[e],q.delete(e),z.unregister(e),ee.delete(e.toLowerCase()),H.delete(e);return}},getActiveBlocksCount:()=>C.size,getLegos:()=>Object.keys(S),config:g,globals:R,route:(e,t,r=null)=>{let o=[],n=e.replace(/:([^\/]+)|\*|[.+?^${}()|[\]\\]/g,(i,a)=>a?(o.push(a),"([^/]+)"):i==="*"?".*":"\\"+i);ne.push({path:e,regex:new RegExp(`^${n}$`),tagName:t,paramNames:o,middleware:r})},debug:{stylesheets:e=>!e||!e._studsMeta?null:e._studsMeta.stylesheets},init:async(e=document.body,t={})=>{if((!e||typeof e.nodeType!="number")&&(e=document.body),gt(t.styles||{}),g.loader=t.loader,g.debug=t.debug===!0,await ht(),ne.length>0){let s=window.location.pathname,c=window.location.search,f=xe(s);if(f){let{match:l,params:u}=f,d=Object.fromEntries(new URLSearchParams(c));R.$route.url=s+c,R.$route.route=l.path,R.$route.params=u,R.$route.query=d,R.$route.method="GET",R.$route.body=null}}document.querySelectorAll("template[b-id]").forEach(s=>{let c=s.getAttribute("b-id");S[c]=s,z.register(c,s.getAttribute("b-props"));let f=s.getAttribute("b-cascade")||"";f&&H.set(c,f.split(/\s+/).filter(Boolean)),customElements.get(c)||customElements.define(c,class extends HTMLElement{connectedCallback(){j.locked||S[c]&&T(this)}disconnectedCallback(){B(this)}})});let r=/^[a-z][a-z0-9]*(-[a-z0-9]+)+$/,o=g.loaderAllowlist,n=s=>o?(Array.isArray(o)?o:[o]).some(f=>typeof f=="string"?f===s:typeof f=="function"?!!f(s):f&&typeof f.test=="function"?!!f.test(s):!1):!0,i=s=>{if(!s)return{};let c={};return Object.entries(s).forEach(([f,l])=>{if(typeof l=="function")c[f]=l();else if(typeof l=="string"&&l.startsWith("$db.")){let u=l.slice(4);c[f]=v.db(u).get()}else if(typeof l=="string"&&l.startsWith("$globals.")){let u=l.slice(9);c[f]=_[u]}else c[f]=l}),c},a=(s,c,f={})=>{if(!customElements.get(s)){if(!r.test(s)){console.warn(`[Lego] Manifest skipped malformed tag "${s}"`);return}if(!n(s)){console.warn(`[Lego] Manifest skipped "${s}": not in loaderAllowlist`);return}customElements.define(s,class extends HTMLElement{async connectedCallback(){if(S[s]){j.locked||T(this);return}if(v._fetching||(v._fetching=new Set),v._pendingLazy||(v._pendingLazy={}),v._fetching.has(s)){v._pendingLazy[s]||(v._pendingLazy[s]=new Set),v._pendingLazy[s].add(this);return}v._fetching.add(s);try{let l=c.startsWith("POST:")?"POST":"GET",u=c.replace(/^POST:/,""),d=i(f.headers),p={method:l,headers:d,credentials:f.credentials},m=await fetch(u,p);if(!m.ok)throw new Error(`HTTP ${m.status} loading block "${s}" from ${u}`);let h=await m.text();v.defineLegoFile(h,`${s}.lego`),S[s]&&T(this);let x=v._pendingLazy[s];x&&(x.forEach(y=>{y.isConnected&&S[s]&&!M(y).snapped&&T(y)}),delete v._pendingLazy[s])}catch(l){console.error(`[Lego] Failed to load manifest block ${s}:`,l)}finally{v._fetching.delete(s)}}disconnectedCallback(){B(this)}})}};if(t.manifest){let s=t.manifest;if(s.url&&typeof s.url=="string")try{let f=i(s.headers);s=await(await fetch(s.url,{headers:f,credentials:s.credentials})).json()}catch(f){console.error("[Lego] Failed to load manifest:",f),s=[]}else if(typeof s=="string")try{s=await(await fetch(s)).json()}catch(f){console.error("[Lego] Failed to load manifest:",f),s=[]}let c=Array.isArray(s)?s:[s];for(let f of c){let l=f.base||"",u=f.suffix===!0?".lego":f.suffix||"",d={headers:f.headers||{},credentials:f.credentials};f.legos&&f.legos.forEach(p=>{a(p,`${l}${p}${u}`,d)}),f.map&&Object.entries(f.map).forEach(([p,m])=>{let h=m.match(/^https?:|^\//)?m:`${l}${m}`;a(p,h,d)})}}if(g.loader){let s=!1,c=l=>{if(l.nodeType!==Node.ELEMENT_NODE)return;let u=l.tagName.toLowerCase();if(u.includes("-")&&!S[u]&&!C.has(l)){if(v._fetching&&v._fetching.has(u))return;if(!r.test(u)){g.debug&&console.warn(`[Lego] Loader skipped malformed tag "${u}"`);return}if(!n(u)){g.debug&&console.warn(`[Lego] Loader skipped "${u}": not in loaderAllowlist`);return}!o&&!s&&(s=!0,console.warn("[Lego] config.loader is set without config.loaderAllowlist. Any unknown hyphenated tag inserted into the page will trigger a fetch. Set Lego.config.loaderAllowlist to restrict this.")),v._fetching||(v._fetching=new Set),v._fetching.add(u);let d=g.loader(u);if(d){let p=typeof d=="string"?fetch(d).then(m=>m.text()):d;Promise.resolve(p).then(m=>{v.defineLegoFile(m,`${u}.lego`),v._fetching.delete(u)}).catch(m=>{console.error(`[Lego] Failed to load ${u}:`,m),v._fetching.delete(u)})}}if(l.children.length>0){let d=l.firstElementChild;for(;d;)c(d),d=d.nextElementSibling}};v._discoveryObserver&&v._discoveryObserver.disconnect(),v._discoveryObserver=new MutationObserver(l=>l.forEach(u=>{u.addedNodes.forEach(c)})),v._discoveryObserver.observe(e,{childList:!0,subtree:!0});let f=e.firstElementChild;for(;f;)c(f),f=f.nextElementSibling}if(t.studio){if(!S["lego-studio"]){let s=document.createElement("script");s.src="https://unpkg.com/@legodom/studio@0.0.2/dist/lego-studio.js",s.onerror=()=>console.warn("[Lego] Failed to load Studio from CDN"),document.head.appendChild(s)}v.route("/_/studio","lego-studio"),v.route("/_/studio/:block","lego-studio")}ne.length>0&&(window.addEventListener("popstate",s=>{let c=s.state?.legoTargets||null;me(c)}),document.addEventListener("submit",s=>{s.target.hasAttribute("b-action")&&s.preventDefault()}),document.addEventListener("click",s=>{let f=s.composedPath().find(l=>l.tagName==="A"&&(l.hasAttribute("b-target")||l.hasAttribute("b-link")));if(f){s.preventDefault();let l=f.getAttribute("href"),u=f.getAttribute("b-target"),d=u?u.split(/\s+/).filter(Boolean):[],p=f.getAttribute("b-link")!=="false";R.$go(l,...d).get(p)}}),me()),st()}};typeof window<"u"?window.Lego=v:typeof global<"u"&&(global.Lego=v);var xn=v;export{v as Lego,xn as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lego-dom",
3
- "version": "2.1.6",
3
+ "version": "2.1.8",
4
4
  "license": "MIT",
5
5
  "description": "A feature-rich web components + SFC frontend framework",
6
6
  "main": "dist/lego.min.js",
@@ -14,7 +14,12 @@ export const createBatcher = (renderHandler = null) => {
14
14
  const setHandler = (fn) => { _render = fn; };
15
15
 
16
16
  const scheduleUpdatedHooks = () => {
17
- if (updatedTimer) clearTimeout(updatedTimer);
17
+ // Trailing-only debounce: do NOT reset the timer if it's already pending.
18
+ // Resetting on every batch lets sustained mutation (animations, websockets)
19
+ // starve the hook indefinitely. With this guard, the first batch arms the
20
+ // timer; subsequent batches within the window add to pendingUpdated but
21
+ // the hook still fires within ~50ms of the first update.
22
+ if (updatedTimer) return;
18
23
  updatedTimer = setTimeout(() => {
19
24
  pendingUpdated.forEach(el => {
20
25
  const state = el._studs;
@@ -24,7 +29,7 @@ export const createBatcher = (renderHandler = null) => {
24
29
  });
25
30
  pendingUpdated.clear();
26
31
  updatedTimer = null;
27
- }, 50); // Global debounce
32
+ }, 50);
28
33
  };
29
34
 
30
35
  const processPendingQueue = () => {
@@ -1,4 +1,5 @@
1
- import { registry, legoFileLogic, sharedStates, activeBlocks, getPrivateData, globalSubscribers, privateData, snapState } from './registry.js';
1
+ import { registry, legoFileLogic, sharedStates, activeBlocks, getPrivateData, globalSubscribers, globalKeySubscribers, privateData, snapState } from './registry.js';
2
+ import { bProps } from '../directives/b-props.js';
2
3
  import { globals } from './globals.js';
3
4
  import { directives } from '../directives/index.js';
4
5
  import { config, mergeDescriptors, resolve, isNode } from '../utils/helpers.js';
@@ -11,6 +12,12 @@ import { applyStyles } from './stylesheets.js';
11
12
  import { findErrorBoundary, renderErrorBlock, handleError } from '../features/error.js';
12
13
  import { _go } from '../features/router.js';
13
14
 
15
+ // Audit fix #24: `el.state = X` performs a shallow merge (Object.assign),
16
+ // not a replacement. Warn once per session so authors who expect
17
+ // assignment semantics (`=` looks like assignment, after all) discover
18
+ // the actual behaviour without flooding logs in steady-state apps.
19
+ let _stateAssignWarned = false;
20
+
14
21
  export const snap = (el) => {
15
22
  if (config.debug) console.log('[Lego Trace] snap() called for:', el.tagName);
16
23
  if (!el || el.nodeType !== Node.ELEMENT_NODE) return;
@@ -65,11 +72,24 @@ export const snap = (el) => {
65
72
  delete el.$initialState; // Cleanup
66
73
  }
67
74
 
75
+ bProps.validate({ instanceLogic, state: baseState, tagName: name });
76
+
68
77
  el._studs = reactive(baseState, el);
69
78
 
70
79
  Object.defineProperty(el, 'state', {
71
80
  get() { return this._studs },
72
- set(v) { Object.assign(this._studs, v) },
81
+ set(v) {
82
+ if (!_stateAssignWarned) {
83
+ _stateAssignWarned = true;
84
+ console.warn(
85
+ '[Lego] `el.state = X` performs a shallow merge (Object.assign), ' +
86
+ 'not a replacement. Keys present on state but absent from X are ' +
87
+ 'preserved. Mutate state keys directly if you want this behaviour ' +
88
+ 'or remount the element to start fresh.'
89
+ );
90
+ }
91
+ Object.assign(this._studs, v);
92
+ },
73
93
  configurable: true,
74
94
  enumerable: false
75
95
  });
@@ -85,7 +105,28 @@ export const snap = (el) => {
85
105
 
86
106
  const style = shadow.querySelector('style');
87
107
  if (style) {
88
- style.textContent = style.textContent.replace(/(?<![-\w])self(?![-\w])/g, ':host');
108
+ // Audit fix #38: don't reach into strings or comments. Previously the
109
+ // raw substitution turned `content: "self"` into `content: ":host"`
110
+ // and similarly mangled custom-property values that legitimately
111
+ // contained the bareword `self`. Stash strings + comments behind
112
+ // sentinel placeholders, run the rewrite, then restore. Doesn't
113
+ // attempt to distinguish selector context from value context — that
114
+ // would require a real CSS parser — but covers the common foot-guns.
115
+ const segments = [];
116
+ // Multi-char sentinel that never appears in normal CSS source.
117
+ const SENTINEL = '__LEGO_SEG_';
118
+ const protectedCss = style.textContent.replace(
119
+ /\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g,
120
+ (m) => {
121
+ segments.push(m);
122
+ return `${SENTINEL}${segments.length - 1}__`;
123
+ }
124
+ );
125
+ const rewritten = protectedCss.replace(/(?<![-\w])self(?![-\w])/g, ':host');
126
+ style.textContent = rewritten.replace(
127
+ /__LEGO_SEG_(\d+)__/g,
128
+ (_, idx) => segments[+idx]
129
+ );
89
130
  }
90
131
 
91
132
  bind(shadow, el);
@@ -159,8 +200,12 @@ export const unsnap = (el) => {
159
200
  // 4. Remove from active blocks tracking
160
201
  activeBlocks.delete(el);
161
202
  globalSubscribers.delete(el);
203
+ // Audit fix #20: also drop el from each per-key subscriber set.
204
+ // Iterating the map is bounded by the number of distinct global keys
205
+ // ever subscribed (small in practice).
206
+ globalKeySubscribers.forEach(set => set.delete(el));
162
207
 
163
- // 4. Break circular references
208
+ // 5. Break circular references
164
209
  if (el._studs) {
165
210
  // Clear element references in state object
166
211
  el._studs.$element = null;
@@ -2,6 +2,8 @@ import { registry, legoFileLogic, getPrivateData } from './registry.js';
2
2
  import { config, deriveBlockName } from '../utils/helpers.js';
3
3
  import { parseLego } from '../utils/parser-utils.js';
4
4
  import { snap } from './lifecycle.js';
5
+ import { bProps } from '../directives/b-props.js';
6
+ import { definitionCascades } from './stylesheets.js';
5
7
 
6
8
  /**
7
9
  * Define a Lego block from a .lego file
@@ -11,7 +13,7 @@ import { snap } from './lifecycle.js';
11
13
  */
12
14
  export const defineLegoFile = (Lego, content, filename = 'block.lego') => {
13
15
  const parsed = parseLego(content, filename);
14
- const { blockName, template, script, style, stylesAttr, cascadeAttr, errorAttr } = parsed;
16
+ const { blockName, template, script, style, stylesAttr, cascadeAttr, errorAttr, propsAttr } = parsed;
15
17
 
16
18
  let logicObj = {};
17
19
  if (script) {
@@ -36,8 +38,13 @@ export const defineLegoFile = (Lego, content, filename = 'block.lego') => {
36
38
  registry[blockName].innerHTML = finalTemplate;
37
39
 
38
40
  if (stylesAttr) registry[blockName].setAttribute('b-stylesheets', stylesAttr);
39
- if (cascadeAttr) registry[blockName].setAttribute('b-cascade', cascadeAttr);
41
+ if (cascadeAttr) {
42
+ registry[blockName].setAttribute('b-cascade', cascadeAttr);
43
+ definitionCascades.set(blockName, cascadeAttr.split(/\s+/).filter(Boolean));
44
+ }
40
45
  if (errorAttr) registry[blockName].setAttribute('b-error', errorAttr);
46
+ if (propsAttr) registry[blockName].setAttribute('b-props', propsAttr);
47
+ bProps.register(blockName, propsAttr);
41
48
 
42
49
  legoFileLogic.set(blockName, logicObj);
43
50