aktion-runtime 0.5.0 → 0.5.1

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.
@@ -1,4 +1,4 @@
1
- var Aktion=function(I){"use strict";var sp=Object.defineProperty;var lp=(I,ge,Pe)=>ge in I?sp(I,ge,{enumerable:!0,configurable:!0,writable:!0,value:Pe}):I[ge]=Pe;var j=(I,ge,Pe)=>lp(I,typeof ge!="symbol"?ge+"":ge,Pe);const ge=new Set(["component","effect","action","if","else","match","for","in","await","return","cleanup","optimistic","on","emit","bind","default"]),Pe=new Set(["(",")","[","]","{","}",",",":","?","."]),wi={true:"Boolean",false:"Boolean",null:"Null"};function rr(t){const e=[];let r=0,a=1,i=1;const n=(c=0)=>t[r+c],s=(c,u,p,m)=>{e.push({type:c,value:u,line:p,column:m})},l=()=>{const c=t[r];return r+=1,c===`
1
+ var Aktion=function(I){"use strict";var lp=Object.defineProperty;var cp=(I,ge,Pe)=>ge in I?lp(I,ge,{enumerable:!0,configurable:!0,writable:!0,value:Pe}):I[ge]=Pe;var j=(I,ge,Pe)=>cp(I,typeof ge!="symbol"?ge+"":ge,Pe);const ge=new Set(["component","effect","action","if","else","match","for","in","await","return","cleanup","optimistic","on","emit","bind","default"]),Pe=new Set(["(",")","[","]","{","}",",",":","?","."]),ki={true:"Boolean",false:"Boolean",null:"Null"};function ir(t){const e=[];let r=0,a=1,i=1;const n=(c=0)=>t[r+c],s=(c,u,p,m)=>{e.push({type:c,value:u,line:p,column:m})},l=()=>{const c=t[r];return r+=1,c===`
2
2
  `?(a+=1,i=1):i+=1,c};for(;r<t.length;){const c=n();if(c===void 0)break;if(c===`
3
3
  `){const f=a,h=i;l(),s("Newline",`
4
4
  `,f,h);continue}if(c===" "||c===" "||c==="\r"){l();continue}if(c==="/"&&n(1)==="/"){for(;r<t.length&&n()!==`
@@ -6,28 +6,28 @@ var Aktion=function(I){"use strict";var sp=Object.defineProperty;var lp=(I,ge,Pe
6
6
  `;)l();continue}if(c==="/"&&n(1)==="*"){for(l(),l();r<t.length&&!(n()==="*"&&n(1)==="/");)l();r<t.length&&(l(),l());continue}if(c==='"'||c==="'"){const f=c,h=a,b=i;l();let v="";for(;r<t.length&&n()!==f;){if(n()==="\\"&&n(1)!==void 0){l();const y=l();switch(y){case"n":v+=`
7
7
  `;break;case"t":v+=" ";break;case"r":v+="\r";break;case"\\":v+="\\";break;case'"':v+='"';break;case"'":v+="'";break;case"`":v+="`";break;default:v+=y??""}continue}if(n()===`
8
8
  `)break;v+=l()}n()===f&&l(),s("String",v,h,b);continue}if(c==="`"){const f=a,h=i;l();const b=[];let v="",y=!1;for(;r<t.length&&n()!=="`";){if(n()==="\\"&&n(1)!==void 0){l();const x=l();switch(x){case"n":v+=`
9
- `;break;case"t":v+=" ";break;case"r":v+="\r";break;case"\\":v+="\\";break;case'"':v+='"';break;case"'":v+="'";break;case"`":v+="`";break;case"$":v+="$";break;default:v+=x??""}continue}if(n()==="$"&&n(1)==="{"){b.push({kind:"str",text:v}),v="";const x=a,w=i;l(),l();let T=1,S="";for(;r<t.length&&T>0;){const $=n();if($===void 0)break;if($==="`"){for(S+=l();r<t.length&&n()!=="`";){if(n()==="\\"&&n(1)!==void 0){S+=l(),S+=l();continue}S+=l()}n()==="`"&&(S+=l());continue}if($==='"'||$==="'"){const N=$;for(S+=l();r<t.length&&n()!==N;){if(n()==="\\"&&n(1)!==void 0){S+=l(),S+=l();continue}if(n()===`
10
- `)break;S+=l()}n()===N&&(S+=l());continue}if($==="{"){T+=1,S+=l();continue}if($==="}"){if(T-=1,T===0){l();break}S+=l();continue}S+=l()}b.push({kind:"expr",source:S,line:x,column:w}),y=!0;continue}v+=l()}if(n()==="`"&&l(),b.push({kind:"str",text:v}),!y){s("String",v,f,h);continue}e.push({type:"TemplateString",value:"",line:f,column:h,parts:b});continue}const u=e[e.length-1],p=!u||u.type==="Newline"||u.type==="Operator"||u.type==="Punctuation"&&(u.value==="("||u.value==="["||u.value===","||u.value===":"||u.value==="?"||u.value==="{");if(De(c)||c==="-"&&De(n(1)??"")&&p){const f=a,h=i;let b="";c==="-"&&(b+=l());let v=!1;for(;r<t.length;){const y=n()??"";if(De(y)){b+=l();continue}if(y==="."&&!v&&De(n(1)??"")){v=!0,b+=l();continue}break}s("Number",b,f,h);continue}if(c==="@"){const f=a,h=i;l();let b="";for(;r<t.length&&wt(n()??"");)b+=l();s("BuiltinIdentifier",b,f,h);continue}if(c==="$"){const f=a,h=i;if(l(),n()==="$"){const v=new Error('Legacy "$$x" persistent reference is removed. Reactive state is declared with "$x = value" and referenced as "$x".');throw v.line=f,v.column=h,v}let b="";for(;r<t.length&&wt(n()??"");)b+=l();s("StateIdentifier",b,f,h);continue}if(ar(c)){const f=a,h=i;let b="";for(;r<t.length&&wt(n()??"");)b+=l();if(b==="js"){let y=0;for(;n(y)===" "||n(y)===" ";)y+=1;if(n(y)==="{")for(let x=0;x<y;x+=1)l()}if(b==="js"&&n()==="{"){l();let y="",x=1;for(;r<t.length&&x>0;){const w=n();if(w===void 0)break;if(w==="\\"&&n(1)!==void 0){y+=l(),y+=l();continue}if(w==='"'||w==="'"){const T=w;for(y+=l();r<t.length&&n()!==T;){if(n()==="\\"&&n(1)!==void 0){y+=l(),y+=l();continue}if(n()===`
11
- `)break;y+=l()}n()===T&&(y+=l());continue}if(w==="`"){for(y+=l();r<t.length&&n()!=="`";){if(n()==="\\"&&n(1)!==void 0){y+=l(),y+=l();continue}y+=l()}n()==="`"&&(y+=l());continue}if(w==="{"){x+=1,y+=l();continue}if(w==="}"){if(x-=1,x===0){l();break}y+=l();continue}y+=l()}s("JsBlock",y,f,h);continue}const v=wi[b];v==="Boolean"?s("Boolean",b,f,h):v==="Null"?s("Null",b,f,h):ge.has(b)?s("Keyword",b,f,h):s("Identifier",b,f,h);continue}if(c==="."&&n(1)==="."&&n(2)==="."){const f=a,h=i;l(),l(),l(),s("Operator","...",f,h);continue}const m=c+(n(1)??"");if(m+(n(2)??"")==="??="){const f=a,h=i;l(),l(),l(),s("Operator","??=",f,h);continue}if(m==="=="||m==="!="||m===">="||m==="<="||m==="&&"||m==="||"||m==="??"||m==="?."||m==="->"||m==="=>"||m==="+="||m==="-="||m==="*="||m==="/="||m==="++"||m==="--"){const f=a,h=i;l(),l(),s("Operator",m,f,h);continue}if("+-*/%!=<>".includes(c)){const f=a,h=i;l(),s("Operator",c,f,h);continue}if(Pe.has(c)){const f=a,h=i;l(),s("Punctuation",c,f,h);continue}l()}return e.push({type:"EOF",value:"",line:a,column:i}),e}function De(t){return t>="0"&&t<="9"}function ar(t){return t>="a"&&t<="z"||t>="A"&&t<="Z"||t==="_"}function wt(t){return ar(t)||De(t)}function fe(t){const e=rr(t),r=new Ri(e),a=[],i=[];for(;!r.isEnd();)if(!r.match("Newline"))try{const n=ir(r,!0);n&&a.push(n)}catch(n){const s=n;i.push(s),r.recoverToNextLine()}return{statements:a,errors:i}}function ir(t,e){const r=t.peek();if(r.type==="Keyword")switch(r.value){case"component":return Ci(t);case"effect":return Ti(t);case"action":return $i(t);case"emit":return Mi(t);case"cleanup":return Pi(t);case"await":return Ii(t);case"return":return zi(t)}const a=t.snapshot();if(ki(t))try{return Li(t)}catch(i){if(i&&typeof i=="object"&&i.__definitive)throw i;t.restore(a)}return Si(t)}function ki(t){const e=t.peek();if(e.type==="StateIdentifier"){const a=t.peek(1);return a.type==="Operator"&&a.value==="="}if(e.type!=="Identifier")return!1;const r=t.peek(1);return r.type==="Operator"&&r.value==="="||r.type==="Punctuation"&&r.value==="("}function Si(t){const e=t.peek(),r=W(t);return t.isEnd()||t.match("Newline"),{kind:"ExpressionStatement",expression:r,loc:{line:e.line,column:e.column}}}function Ci(t){const e=t.expect("Keyword","component"),r=t.expect("Identifier"),{params:a,slots:i}=nr(t),n=ye(t);if(t.isEnd()||t.match("Newline"),!n.body.some(l=>l.kind==="Return")){const l={message:`component "${r.value}" must end with an explicit \`return\` statement.`,line:e.line,column:e.column};throw l.__definitive=!0,l}return{kind:"ComponentDeclaration",name:r.value,params:a,slots:i,body:n,loc:{line:e.line,column:e.column}}}function nr(t){t.expect("Punctuation","(");const e=[],r=[];for(;t.match("Newline"););if(!(t.peek().type==="Punctuation"&&t.peek().value===")"))for(;;){for(;t.match("Newline"););const a=t.peek();if(a.type==="Identifier"&&a.value==="slots"){for(t.consume(),t.expect("Punctuation",":"),t.expect("Punctuation","{");t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");){const i=t.expect("Identifier");for(r.push(i.value),t.peek().type==="Punctuation"&&t.peek().value==="?"&&t.consume();t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===",")for(t.consume();t.match("Newline"););}t.expect("Punctuation","}")}else if(a.type==="Identifier"||a.type==="Keyword"){const i=t.consume();let n;t.peek().type==="Punctuation"&&t.peek().value===":"&&(t.consume(),n=W(t)),e.push({name:i.value,defaultValue:n})}else throw{message:`Expected parameter name, got ${a.type} "${a.value}"`,line:a.line,column:a.column};for(;t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){t.consume();continue}break}return t.expect("Punctuation",")"),{params:e,slots:r}}function Ti(t){const e=t.expect("Keyword","effect"),r=[];let a;if(t.peek().type==="Punctuation"&&t.peek().value==="["){for(t.consume();t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="]");){for(Ni(t,r,s=>{a=s});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===",")for(t.consume();t.match("Newline"););}t.expect("Punctuation","]")}const i=ye(t);t.isEnd()||t.match("Newline");const n={kind:"EffectDeclaration",name:`__effect_L${e.line}_C${e.column}`,triggers:r,body:i,loc:{line:e.line,column:e.column}};return a&&(n.rateLimit=a),n}function Ni(t,e,r){const a=t.peek();if(a.type==="StateIdentifier"){t.consume(),e.push({kind:"state",name:a.value});return}if(a.type==="Keyword"&&a.value==="on"){t.consume(),t.expect("Punctuation",":");const i=t.expect("Identifier").value;if(i==="mount"||i==="unmount"){e.push({kind:"lifecycle",name:i});return}if(i==="every"){t.expect("Punctuation","(");const n=t.expect("Number");t.expect("Punctuation",")"),e.push({kind:"every",intervalMs:Number(n.value)});return}throw{message:`Unknown lifecycle trigger "on:${i}" inside effect dependency list`,line:a.line,column:a.column}}if(a.type==="Identifier"&&(a.value==="debounce"||a.value==="throttle")){const i=t.consume().value;t.expect("Punctuation","(");const n=t.expect("Number");t.expect("Punctuation",")"),r({kind:i,ms:Number(n.value)});return}throw{message:`Unexpected ${a.type} "${a.value}" inside effect dependency list. Expected $state, on:mount, on:unmount, on:every(N), debounce(N), or throttle(N).`,line:a.line,column:a.column}}function $i(t){const e=t.expect("Keyword","action"),r=t.expect("Identifier");let a=[];t.peek().type==="Punctuation"&&t.peek().value==="("&&(a=nr(t).params),Ai(t);let i=!1;t.peek().type==="Keyword"&&t.peek().value==="optimistic"&&(t.consume(),i=!0);const n=ye(t);return t.isEnd()||t.match("Newline"),{kind:"ActionDeclaration",name:r.value,params:a,optimistic:i,body:n,loc:{line:e.line,column:e.column}}}function Ai(t){const e=t.peek();if(e.type!=="Identifier"||e.value!=="uses")return;t.consume(),t.expect("Punctuation","{");let r;for(;t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");){const a=t.peek();if(a.type!=="Identifier"&&a.type!=="Keyword")throw{message:`Expected capability name inside legacy "uses { … }" clause, got ${a.type} "${a.value}"`,line:a.line,column:a.column};let i=t.consume().value;for(;t.peek().type==="Punctuation"&&t.peek().value===".";)t.consume(),i+=`.${t.expect("Identifier").value}`;let n;if(t.peek().type==="Punctuation"&&t.peek().value==="(")if(t.consume(),t.peek().type==="Punctuation"&&t.peek().value===")")t.expect("Punctuation",")");else{const s=t.peek();s.type==="Number"&&(n=Number(s.value));let l=1;for(;!t.isEnd()&&l>0;){const c=t.consume();c.type==="Punctuation"&&c.value==="("?l+=1:c.type==="Punctuation"&&c.value===")"&&(l-=1)}}for((i==="debounce"||i==="throttle")&&n!==void 0&&(r={kind:i,ms:n});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===",")for(t.consume();t.match("Newline"););}return t.expect("Punctuation","}"),r}function ye(t){const e=t.expect("Punctuation","{"),r=[];for(;t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");){const a=ir(t);for(a&&r.push(a);t.match("Newline"););}return t.expect("Punctuation","}"),{kind:"Block",body:r,loc:{line:e.line,column:e.column}}}function Mi(t){const e=t.expect("Keyword","emit"),r=t.expect("String");let a={kind:"Object",properties:[]};if(t.peek().type==="Punctuation"&&t.peek().value==="{"){t.consume();const i=gr(t);t.expect("Punctuation","}"),a={kind:"Object",properties:i}}return t.isEnd()||t.match("Newline"),{kind:"Emit",eventName:r.value,detail:a,loc:{line:e.line,column:e.column}}}function Pi(t){const e=t.expect("Keyword","cleanup");t.expect("Punctuation","(");const r=W(t);return t.expect("Punctuation",")"),t.isEnd()||t.match("Newline"),{kind:"Cleanup",callback:r,loc:{line:e.line,column:e.column}}}function Ii(t){const e=t.expect("Keyword","await"),r=W(t);return t.isEnd()||t.match("Newline"),{kind:"Await",argument:r,loc:{line:e.line,column:e.column}}}function zi(t){const e=t.expect("Keyword","return");let r;const a=t.peek();return a.type!=="Newline"&&!(a.type==="Punctuation"&&a.value==="}")&&(r=W(t)),t.isEnd()||t.match("Newline"),{kind:"Return",argument:r,loc:{line:e.line,column:e.column}}}class Ri{constructor(e){j(this,"index",0);this.tokens=e}isEnd(){return this.peek().type==="EOF"}peek(e=0){return this.tokens[this.index+e]??{type:"EOF",value:"",line:0,column:0}}consume(){const e=this.tokens[this.index]??{type:"EOF",value:"",line:0,column:0};return this.index+=1,e}match(e,r){const a=this.peek();return a.type!==e||r!==void 0&&a.value!==r?!1:(this.consume(),!0)}expect(e,r){const a=this.peek();if(a.type!==e||r!==void 0&&a.value!==r)throw{message:`Expected ${e}${r!==void 0?` "${r}"`:""} but got ${a.type} "${a.value}"`,line:a.line,column:a.column};return this.consume()}recoverToNextLine(){for(;!this.isEnd()&&this.peek().type!=="Newline";)this.consume();this.peek().type==="Newline"&&this.consume()}snapshot(){return this.index}restore(e){this.index=e}}function Li(t){const e=t.peek();let r="",a=!1;if(e.type==="Identifier"){if(r=t.consume().value,t.peek().type==="Punctuation"&&t.peek().value==="("){const s=t.snapshot();t.consume();const l=[];let c=!0;for(;t.match("Newline"););if(!(t.peek().type==="Punctuation"&&t.peek().value===")"))for(;;){for(;t.match("Newline"););if(t.peek().type!=="Identifier"){c=!1;break}for(l.push(t.consume().value);t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){t.consume();continue}break}if(c&&t.peek().type==="Punctuation"&&t.peek().value===")"){if(t.consume(),t.peek().type==="Operator"&&t.peek().value==="="){const u={message:`Legacy "${r}(...) = expr" macro shorthand is removed in Aktion 0.5. Use "component ${r}(${l.join(", ")}) { ... }" for reusables, or "${r} = (${l.join(", ")}) => ..." for local helpers.`,line:e.line,column:e.column};throw u.__definitive=!0,u}t.restore(s)}else t.restore(s)}}else if(e.type==="StateIdentifier")r=t.consume().value,a=!0;else throw{message:`Expected identifier at start of statement, got ${e.type} "${e.value}"`,line:e.line,column:e.column};const i=t.expect("Operator","="),n=W(t);return t.isEnd()||t.match("Newline"),{kind:"Assignment",identifier:r,isState:a,expression:n,loc:{line:i.line,column:i.column}}}function W(t){return Ei(t)}function Ei(t){const e=_i(t);if(t.peek().type==="Punctuation"&&t.peek().value==="?"){t.consume();const r=W(t);t.expect("Punctuation",":");const a=W(t);return{kind:"Ternary",test:e,consequent:r,alternate:a}}return e}function _i(t){let e=or(t);for(;t.peek().type==="Operator"&&(t.peek().value==="||"||t.peek().value==="??");){const r=t.consume().value,a=or(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function or(t){let e=sr(t);for(;t.peek().type==="Operator"&&t.peek().value==="&&";){t.consume();const r=sr(t);e={kind:"Binary",operator:"&&",left:e,right:r}}return e}function sr(t){let e=lr(t);for(;t.peek().type==="Operator"&&(t.peek().value==="=="||t.peek().value==="!=");){const r=t.consume().value,a=lr(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function lr(t){let e=cr(t);for(;t.peek().type==="Operator"&&[">","<",">=","<="].includes(t.peek().value);){const r=t.consume().value,a=cr(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function cr(t){let e=ur(t);for(;t.peek().type==="Operator"&&(t.peek().value==="+"||t.peek().value==="-");){const r=t.consume().value,a=ur(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function ur(t){let e=kt(t);for(;t.peek().type==="Operator"&&(t.peek().value==="*"||t.peek().value==="/"||t.peek().value==="%");){const r=t.consume().value,a=kt(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function kt(t){const e=t.peek();if(e.type==="Operator"&&(e.value==="!"||e.value==="-")){t.consume();const r=kt(t);return{kind:"Unary",operator:e.value,argument:r}}return ji(t)}function ji(t){let e=Bi(t);for(;;){const r=t.peek();if(r.type==="Punctuation"&&r.value==="."){t.consume();const a=t.consume();if(a.type!=="Identifier"&&a.type!=="Keyword")throw{message:`Expected Identifier but got ${a.type} "${a.value}"`,line:a.line,column:a.column};const i=t.peek();if(i.type==="Punctuation"&&i.value==="("){t.consume();const n=Fe(t,{named:!0});t.expect("Punctuation",")"),e={kind:"MethodCall",object:e,method:a.value,arguments:n,loc:{line:a.line,column:a.column}};continue}e={kind:"Member",object:e,property:a.value};continue}if(r.type==="Operator"&&r.value==="?."){if(t.consume(),t.peek().type==="Punctuation"&&t.peek().value==="["){t.consume();const a=W(t);t.expect("Punctuation","]"),e={kind:"Member",object:e,computed:a,optional:!0}}else{const a=t.consume();if(a.type!=="Identifier"&&a.type!=="Keyword")throw{message:`Expected Identifier but got ${a.type} "${a.value}"`,line:a.line,column:a.column};const i=t.peek();if(i.type==="Punctuation"&&i.value==="("){t.consume();const n=Fe(t,{named:!0});t.expect("Punctuation",")"),e={kind:"MethodCall",object:e,method:a.value,arguments:n,optional:!0,loc:{line:a.line,column:a.column}};continue}e={kind:"Member",object:e,property:a.value,optional:!0}}continue}if(r.type==="Punctuation"&&r.value==="["){t.consume();const a=W(t);t.expect("Punctuation","]"),e={kind:"Member",object:e,computed:a};continue}break}return e}function Bi(t){const e=t.peek();if(e.type==="Keyword"){if(e.value==="if")return mr(t);if(e.value==="match")return Di(t);if(e.value==="for")return Fi(t);if(e.value==="action"||e.value==="effect"){const r=t.peek(1);if(!(r&&r.type==="Identifier"))return t.consume(),{kind:"Identifier",name:e.value,loc:{line:e.line,column:e.column}}}}if(e.type==="JsBlock")return t.consume(),{kind:"JsBlock",body:e.value,loc:{line:e.line,column:e.column}};if(e.type==="Number")return t.consume(),{kind:"Literal",value:Number(e.value)};if(e.type==="String")return t.consume(),{kind:"Literal",value:e.value};if(e.type==="TemplateString"){t.consume();const r=e.parts??[],a=[],i=[];let n="",s=!1;const l=()=>{a.push(n),n="",s=!1};for(const c of r){if(c.kind==="str"){n+=c.text,s=!0;continue}s?l():a.push("");const p=fe(`__rui_tmpl__ = ${c.source}`).statements[0];p&&p.kind==="Assignment"?i.push(p.expression):i.push({kind:"Literal",value:""})}for((s||a.length===0)&&a.push(n);a.length<=i.length;)a.push("");return{kind:"Template",quasis:a,expressions:i,loc:{line:e.line,column:e.column}}}if(e.type==="Boolean")return t.consume(),{kind:"Literal",value:e.value==="true"};if(e.type==="Null")return t.consume(),{kind:"Literal",value:null};if(e.type==="StateIdentifier")return t.consume(),{kind:"StateRef",name:e.value};if(e.type==="BuiltinIdentifier"){t.consume(),t.expect("Punctuation","(");const r=Fe(t,{named:!0});return t.expect("Punctuation",")"),{kind:"BuiltinCall",name:e.value,arguments:r,loc:{line:e.line,column:e.column}}}if(e.type==="Identifier"){if(t.consume(),t.peek().type==="Punctuation"&&t.peek().value==="("){t.consume();const r=Fe(t,{named:!0});return t.expect("Punctuation",")"),{kind:"Call",callee:e.value,arguments:r,loc:{line:e.line,column:e.column}}}return{kind:"Identifier",name:e.value,loc:{line:e.line,column:e.column}}}if(e.type==="Punctuation"&&e.value==="["){t.consume();const r=Fe(t);return t.expect("Punctuation","]"),{kind:"Array",elements:r}}if(e.type==="Punctuation"&&e.value==="{"){t.consume();const r=gr(t);return t.expect("Punctuation","}"),{kind:"Object",properties:r}}if(e.type==="Punctuation"&&e.value==="("){const r=t.snapshot(),a=Oi(t);if(a)return a;t.restore(r),t.consume();const i=W(t);return t.expect("Punctuation",")"),i}throw{message:`Unexpected token ${e.type} "${e.value}"`,line:e.line,column:e.column}}function Fe(t,e){const r=[],a=e?.named===!0;for(;t.match("Newline"););if(t.peek().type==="Punctuation"&&(t.peek().value===")"||t.peek().value==="]"))return r;for(r.push(a?pr(t):dr(t));t.match("Newline"););for(;t.peek().type==="Punctuation"&&t.peek().value===",";){for(t.consume();t.match("Newline"););if(t.peek().type==="Punctuation"&&(t.peek().value===")"||t.peek().value==="]"))break;for(r.push(a?pr(t):dr(t));t.match("Newline"););}for(;t.match("Newline"););return r}function dr(t){if(t.peek().type==="Operator"&&t.peek().value==="..."){const e=t.consume();return{kind:"Spread",argument:W(t),loc:{line:e.line,column:e.column}}}return W(t)}function pr(t){if(t.peek().type==="Operator"&&t.peek().value==="..."){const r=t.consume();return{kind:"Spread",argument:W(t),loc:{line:r.line,column:r.column}}}if(t.peek().type==="Keyword"&&t.peek().value==="bind"){const r=t.consume();t.expect("Punctuation",":");const a=t.expect("Identifier");t.expect("Punctuation",":");const i=W(t);return{kind:"Bind",prop:a.value,target:i,loc:{line:r.line,column:r.column}}}if(t.peek().type==="Identifier"&&t.peek(1).type==="Operator"&&t.peek(1).value==="="){const r=t.peek(),a={message:`Legacy "name=value" named-arg form is removed in Aktion 0.5. Use "${r.value}: value" instead.`,line:r.line,column:r.column};throw a.__definitive=!0,a}const e=t.peek();if((e.type==="Identifier"||e.type==="Keyword")&&t.peek(1).type==="Punctuation"&&t.peek(1).value===":"){const r=t.consume();t.consume();const a=W(t);return{kind:"NamedArg",name:r.value,value:a,loc:{line:r.line,column:r.column}}}return W(t)}function mr(t){const e=t.expect("Keyword","if"),r=W(t),a=ye(t);let i;for(;t.match("Newline"););return t.peek().type==="Keyword"&&t.peek().value==="else"&&(t.consume(),t.peek().type==="Keyword"&&t.peek().value==="if"?i=mr(t):i=ye(t)),{kind:"If",test:r,consequent:a,alternate:i,loc:{line:e.line,column:e.column}}}function Di(t){const e=t.expect("Keyword","match"),r=W(t);t.expect("Punctuation","{");const a=[];for(;t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");){let i;const n=t.peek();n.type==="Keyword"&&n.value==="default"?(t.consume(),i="_"):i=W(t),t.expect("Punctuation",":");const s=W(t);for(a.push({pattern:i,body:s});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===",")for(t.consume();t.match("Newline"););}return t.expect("Punctuation","}"),{kind:"Match",discriminant:r,arms:a,loc:{line:e.line,column:e.column}}}function Fi(t){const e=t.expect("Keyword","for");let r,a,i;if(t.peek().type==="Punctuation"&&t.peek().value==="(")t.consume(),r=t.expect("Identifier").value,t.expect("Punctuation",","),a=t.expect("Identifier").value,t.expect("Punctuation",")");else if(t.peek().type==="Punctuation"&&t.peek().value==="{"){t.consume();const l=[];for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");)l.push(t.expect("Identifier").value),t.peek().type==="Punctuation"&&t.peek().value===","&&t.consume();t.expect("Punctuation","}"),r="__row",i=l}else r=t.expect("Identifier").value;t.expect("Keyword","in");const n=W(t),s=ye(t);return{kind:"For",item:r,index:a,destructure:i,iterable:n,body:s,loc:{line:e.line,column:e.column}}}function Oi(t){const e=t.peek();if(e.type!=="Punctuation"||e.value!=="(")return null;t.consume();const r=[];for(;t.match("Newline"););if(!(t.peek().type==="Punctuation"&&t.peek().value===")"))for(;;){for(;t.match("Newline"););const i=t.peek();if(i.type!=="Identifier")return null;t.consume();const n={name:i.value};if(t.peek().type==="Punctuation"&&t.peek().value===":"){t.consume();try{n.defaultValue=W(t)}catch{return null}}for(r.push(n);t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){t.consume();continue}break}for(;t.match("Newline"););if(!(t.peek().type==="Punctuation"&&t.peek().value===")")||(t.consume(),!(t.peek().type==="Operator"&&t.peek().value==="=>")))return null;t.consume();let a;if(t.peek().type==="JsBlock"){const i=t.consume();a={kind:"JsBlock",body:i.value,loc:{line:i.line,column:i.column}}}else t.peek().type==="Punctuation"&&t.peek().value==="{"?a=ye(t):a=Ui(t);return{kind:"Lambda",params:r,body:a,loc:{line:e.line,column:e.column}}}function Ui(t){const e=W(t),r=t.peek();if(r.type==="Operator"){if(["=","+=","-=","*=","/=","??="].includes(r.value)){t.consume();const i=W(t);return{kind:"BuiltinCall",name:"__rui_assign__",arguments:[e,i,{kind:"Literal",value:r.value}],loc:{line:r.line,column:r.column}}}if(r.value==="++"||r.value==="--")return t.consume(),{kind:"BuiltinCall",name:"__rui_postfix__",arguments:[e,{kind:"Literal",value:r.value}],loc:{line:r.line,column:r.column}}}return e}function gr(t){const e=[];for(;t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value==="}")return e;for(;;){for(;t.match("Newline"););const r=t.peek();if(r.type==="Operator"&&r.value==="..."){t.consume();const s=W(t);for(e.push({key:"",value:s,spread:!0});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){for(t.consume();t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value==="}")break;continue}break}let a;if(r.type==="Identifier"||r.type==="String"||r.type==="Keyword")a=t.consume().value;else throw{message:`Expected object key, got ${r.type} "${r.value}"`,line:r.line,column:r.column};const i=t.peek();let n;for(r.type==="Identifier"&&i.type==="Punctuation"&&(i.value===","||i.value==="}")?n={kind:"Identifier",name:a,loc:{line:r.line,column:r.column}}:(t.expect("Punctuation",":"),n=W(t)),e.push({key:a,value:n});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){for(t.consume();t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value==="}")break;continue}break}for(;t.match("Newline"););return e}function qi(t){const e=fe(t);return fr(t,e)}function fr(t,e){const r=new Set(e.errors.map(l=>l.line)),a=[],i=[];for(const l of e.statements){const c=l.loc?.line??0;if(r.has(c)){i.push(l);continue}a.push(l)}let n=t,s="";if(e.errors.length>0){const l=Math.min(...e.errors.map(p=>p.line)),c=Vi(t,l);n=c.before,s=c.after;const u=a.findIndex(p=>(p.loc?.line??0)>=l);if(u>=0)for(const p of a.splice(u))i.push(p)}return{committedSource:n,draftingSource:s,committedBindings:a.map(hr).filter(l=>l!==null),uncommittedBindings:i.map(hr).filter(l=>l!==null),committedStatements:a,errors:e.errors}}function Hi(t,e){if(e.length===0)return!0;const r=new Set(t.committedBindings);for(const a of e)if(!r.has(a))return!1;return!0}function hr(t){switch(t.kind){case"Assignment":return t.identifier;case"ComponentDeclaration":case"EffectDeclaration":case"ActionDeclaration":return t.name;default:return null}}function Vi(t,e){if(e<=1)return{before:"",after:t};let r=0,a=1;for(;r<t.length&&a<e;)t[r]===`
12
- `&&(a+=1),r+=1;return{before:t.slice(0,r),after:t.slice(r)}}function Wi(t,e){const r=[],a={};let i=t;for(const n of e){if(n.kind==="patch"){a[n.target]=n.value;continue}const s=Gi(i,n);i=s.programText,s.warning&&r.push(s.warning)}return{programText:i,stateUpdates:a,warnings:r}}function Gi(t,e){const r=fe(t);if(r.errors.length>0)return{programText:t,warning:`delta(${e.kind}): source did not parse cleanly (${r.errors[0].message}); op skipped`};switch(e.kind){case"new":{const a=fe(e.source);if(a.errors.length>0||a.statements.length===0)return{programText:t,warning:`delta(new): could not parse "${br(e.source)}" — op skipped`};const i=t.endsWith(`
9
+ `;break;case"t":v+=" ";break;case"r":v+="\r";break;case"\\":v+="\\";break;case'"':v+='"';break;case"'":v+="'";break;case"`":v+="`";break;case"$":v+="$";break;default:v+=x??""}continue}if(n()==="$"&&n(1)==="{"){b.push({kind:"str",text:v}),v="";const x=a,w=i;l(),l();let T=1,S="";for(;r<t.length&&T>0;){const N=n();if(N===void 0)break;if(N==="`"){for(S+=l();r<t.length&&n()!=="`";){if(n()==="\\"&&n(1)!==void 0){S+=l(),S+=l();continue}S+=l()}n()==="`"&&(S+=l());continue}if(N==='"'||N==="'"){const $=N;for(S+=l();r<t.length&&n()!==$;){if(n()==="\\"&&n(1)!==void 0){S+=l(),S+=l();continue}if(n()===`
10
+ `)break;S+=l()}n()===$&&(S+=l());continue}if(N==="{"){T+=1,S+=l();continue}if(N==="}"){if(T-=1,T===0){l();break}S+=l();continue}S+=l()}b.push({kind:"expr",source:S,line:x,column:w}),y=!0;continue}v+=l()}if(n()==="`"&&l(),b.push({kind:"str",text:v}),!y){s("String",v,f,h);continue}e.push({type:"TemplateString",value:"",line:f,column:h,parts:b});continue}const u=e[e.length-1],p=!u||u.type==="Newline"||u.type==="Operator"||u.type==="Punctuation"&&(u.value==="("||u.value==="["||u.value===","||u.value===":"||u.value==="?"||u.value==="{");if(De(c)||c==="-"&&De(n(1)??"")&&p){const f=a,h=i;let b="";c==="-"&&(b+=l());let v=!1;for(;r<t.length;){const y=n()??"";if(De(y)){b+=l();continue}if(y==="."&&!v&&De(n(1)??"")){v=!0,b+=l();continue}break}s("Number",b,f,h);continue}if(c==="@"){const f=a,h=i;l();let b="";for(;r<t.length&&wt(n()??"");)b+=l();s("BuiltinIdentifier",b,f,h);continue}if(c==="$"){const f=a,h=i;if(l(),n()==="$"){const v=new Error('Legacy "$$x" persistent reference is removed. Reactive state is declared with "$x = value" and referenced as "$x".');throw v.line=f,v.column=h,v}let b="";for(;r<t.length&&wt(n()??"");)b+=l();s("StateIdentifier",b,f,h);continue}if(nr(c)){const f=a,h=i;let b="";for(;r<t.length&&wt(n()??"");)b+=l();if(b==="js"){let y=0;for(;n(y)===" "||n(y)===" ";)y+=1;if(n(y)==="{")for(let x=0;x<y;x+=1)l()}if(b==="js"&&n()==="{"){l();let y="",x=1;for(;r<t.length&&x>0;){const w=n();if(w===void 0)break;if(w==="\\"&&n(1)!==void 0){y+=l(),y+=l();continue}if(w==='"'||w==="'"){const T=w;for(y+=l();r<t.length&&n()!==T;){if(n()==="\\"&&n(1)!==void 0){y+=l(),y+=l();continue}if(n()===`
11
+ `)break;y+=l()}n()===T&&(y+=l());continue}if(w==="`"){for(y+=l();r<t.length&&n()!=="`";){if(n()==="\\"&&n(1)!==void 0){y+=l(),y+=l();continue}y+=l()}n()==="`"&&(y+=l());continue}if(w==="{"){x+=1,y+=l();continue}if(w==="}"){if(x-=1,x===0){l();break}y+=l();continue}y+=l()}s("JsBlock",y,f,h);continue}const v=ki[b];v==="Boolean"?s("Boolean",b,f,h):v==="Null"?s("Null",b,f,h):ge.has(b)?s("Keyword",b,f,h):s("Identifier",b,f,h);continue}if(c==="."&&n(1)==="."&&n(2)==="."){const f=a,h=i;l(),l(),l(),s("Operator","...",f,h);continue}const m=c+(n(1)??"");if(m+(n(2)??"")==="??="){const f=a,h=i;l(),l(),l(),s("Operator","??=",f,h);continue}if(m==="=="||m==="!="||m===">="||m==="<="||m==="&&"||m==="||"||m==="??"||m==="?."||m==="->"||m==="=>"||m==="+="||m==="-="||m==="*="||m==="/="||m==="++"||m==="--"){const f=a,h=i;l(),l(),s("Operator",m,f,h);continue}if("+-*/%!=<>".includes(c)){const f=a,h=i;l(),s("Operator",c,f,h);continue}if(Pe.has(c)){const f=a,h=i;l(),s("Punctuation",c,f,h);continue}l()}return e.push({type:"EOF",value:"",line:a,column:i}),e}function De(t){return t>="0"&&t<="9"}function nr(t){return t>="a"&&t<="z"||t>="A"&&t<="Z"||t==="_"}function wt(t){return nr(t)||De(t)}function fe(t){const e=ir(t),r=new Li(e),a=[],i=[];for(;!r.isEnd();)if(!r.match("Newline"))try{const n=or(r,!0);n&&a.push(n)}catch(n){const s=n;i.push(s),r.recoverToNextLine()}return{statements:a,errors:i}}function or(t,e){const r=t.peek();if(r.type==="Keyword")switch(r.value){case"component":return Ti(t);case"effect":return $i(t);case"action":return Ai(t);case"emit":return Pi(t);case"cleanup":return Ii(t);case"await":return zi(t);case"return":return Ri(t)}const a=t.snapshot();if(Si(t))try{return Ei(t)}catch(i){if(i&&typeof i=="object"&&i.__definitive)throw i;t.restore(a)}return Ci(t)}function Si(t){const e=t.peek();if(e.type==="StateIdentifier"){const a=t.peek(1);return a.type==="Operator"&&a.value==="="}if(e.type!=="Identifier")return!1;const r=t.peek(1);return r.type==="Operator"&&r.value==="="||r.type==="Punctuation"&&r.value==="("}function Ci(t){const e=t.peek(),r=W(t);return t.isEnd()||t.match("Newline"),{kind:"ExpressionStatement",expression:r,loc:{line:e.line,column:e.column}}}function Ti(t){const e=t.expect("Keyword","component"),r=t.expect("Identifier"),{params:a,slots:i}=sr(t),n=ye(t);if(t.isEnd()||t.match("Newline"),!n.body.some(l=>l.kind==="Return")){const l={message:`component "${r.value}" must end with an explicit \`return\` statement.`,line:e.line,column:e.column};throw l.__definitive=!0,l}return{kind:"ComponentDeclaration",name:r.value,params:a,slots:i,body:n,loc:{line:e.line,column:e.column}}}function sr(t){t.expect("Punctuation","(");const e=[],r=[];for(;t.match("Newline"););if(!(t.peek().type==="Punctuation"&&t.peek().value===")"))for(;;){for(;t.match("Newline"););const a=t.peek();if(a.type==="Identifier"&&a.value==="slots"){for(t.consume(),t.expect("Punctuation",":"),t.expect("Punctuation","{");t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");){const i=t.expect("Identifier");for(r.push(i.value),t.peek().type==="Punctuation"&&t.peek().value==="?"&&t.consume();t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===",")for(t.consume();t.match("Newline"););}t.expect("Punctuation","}")}else if(a.type==="Identifier"||a.type==="Keyword"){const i=t.consume();let n;t.peek().type==="Punctuation"&&t.peek().value===":"&&(t.consume(),n=W(t)),e.push({name:i.value,defaultValue:n})}else throw{message:`Expected parameter name, got ${a.type} "${a.value}"`,line:a.line,column:a.column};for(;t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){t.consume();continue}break}return t.expect("Punctuation",")"),{params:e,slots:r}}function $i(t){const e=t.expect("Keyword","effect"),r=[];let a;if(t.peek().type==="Punctuation"&&t.peek().value==="["){for(t.consume();t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="]");){for(Ni(t,r,s=>{a=s});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===",")for(t.consume();t.match("Newline"););}t.expect("Punctuation","]")}const i=ye(t);t.isEnd()||t.match("Newline");const n={kind:"EffectDeclaration",name:`__effect_L${e.line}_C${e.column}`,triggers:r,body:i,loc:{line:e.line,column:e.column}};return a&&(n.rateLimit=a),n}function Ni(t,e,r){const a=t.peek();if(a.type==="StateIdentifier"){t.consume(),e.push({kind:"state",name:a.value});return}if(a.type==="Keyword"&&a.value==="on"){t.consume(),t.expect("Punctuation",":");const i=t.expect("Identifier").value;if(i==="mount"||i==="unmount"){e.push({kind:"lifecycle",name:i});return}if(i==="every"){t.expect("Punctuation","(");const n=t.expect("Number");t.expect("Punctuation",")"),e.push({kind:"every",intervalMs:Number(n.value)});return}throw{message:`Unknown lifecycle trigger "on:${i}" inside effect dependency list`,line:a.line,column:a.column}}if(a.type==="Identifier"&&(a.value==="debounce"||a.value==="throttle")){const i=t.consume().value;t.expect("Punctuation","(");const n=t.expect("Number");t.expect("Punctuation",")"),r({kind:i,ms:Number(n.value)});return}throw{message:`Unexpected ${a.type} "${a.value}" inside effect dependency list. Expected $state, on:mount, on:unmount, on:every(N), debounce(N), or throttle(N).`,line:a.line,column:a.column}}function Ai(t){const e=t.expect("Keyword","action"),r=t.expect("Identifier");let a=[];t.peek().type==="Punctuation"&&t.peek().value==="("&&(a=sr(t).params),Mi(t);let i=!1;t.peek().type==="Keyword"&&t.peek().value==="optimistic"&&(t.consume(),i=!0);const n=ye(t);return t.isEnd()||t.match("Newline"),{kind:"ActionDeclaration",name:r.value,params:a,optimistic:i,body:n,loc:{line:e.line,column:e.column}}}function Mi(t){const e=t.peek();if(e.type!=="Identifier"||e.value!=="uses")return;t.consume(),t.expect("Punctuation","{");let r;for(;t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");){const a=t.peek();if(a.type!=="Identifier"&&a.type!=="Keyword")throw{message:`Expected capability name inside legacy "uses { … }" clause, got ${a.type} "${a.value}"`,line:a.line,column:a.column};let i=t.consume().value;for(;t.peek().type==="Punctuation"&&t.peek().value===".";)t.consume(),i+=`.${t.expect("Identifier").value}`;let n;if(t.peek().type==="Punctuation"&&t.peek().value==="(")if(t.consume(),t.peek().type==="Punctuation"&&t.peek().value===")")t.expect("Punctuation",")");else{const s=t.peek();s.type==="Number"&&(n=Number(s.value));let l=1;for(;!t.isEnd()&&l>0;){const c=t.consume();c.type==="Punctuation"&&c.value==="("?l+=1:c.type==="Punctuation"&&c.value===")"&&(l-=1)}}for((i==="debounce"||i==="throttle")&&n!==void 0&&(r={kind:i,ms:n});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===",")for(t.consume();t.match("Newline"););}return t.expect("Punctuation","}"),r}function ye(t){const e=t.expect("Punctuation","{"),r=[];for(;t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");){const a=or(t);for(a&&r.push(a);t.match("Newline"););}return t.expect("Punctuation","}"),{kind:"Block",body:r,loc:{line:e.line,column:e.column}}}function Pi(t){const e=t.expect("Keyword","emit"),r=t.expect("String");let a={kind:"Object",properties:[]};if(t.peek().type==="Punctuation"&&t.peek().value==="{"){t.consume();const i=hr(t);t.expect("Punctuation","}"),a={kind:"Object",properties:i}}return t.isEnd()||t.match("Newline"),{kind:"Emit",eventName:r.value,detail:a,loc:{line:e.line,column:e.column}}}function Ii(t){const e=t.expect("Keyword","cleanup");t.expect("Punctuation","(");const r=W(t);return t.expect("Punctuation",")"),t.isEnd()||t.match("Newline"),{kind:"Cleanup",callback:r,loc:{line:e.line,column:e.column}}}function zi(t){const e=t.expect("Keyword","await"),r=W(t);return t.isEnd()||t.match("Newline"),{kind:"Await",argument:r,loc:{line:e.line,column:e.column}}}function Ri(t){const e=t.expect("Keyword","return");let r;const a=t.peek();return a.type!=="Newline"&&!(a.type==="Punctuation"&&a.value==="}")&&(r=W(t)),t.isEnd()||t.match("Newline"),{kind:"Return",argument:r,loc:{line:e.line,column:e.column}}}class Li{constructor(e){j(this,"index",0);this.tokens=e}isEnd(){return this.peek().type==="EOF"}peek(e=0){return this.tokens[this.index+e]??{type:"EOF",value:"",line:0,column:0}}consume(){const e=this.tokens[this.index]??{type:"EOF",value:"",line:0,column:0};return this.index+=1,e}match(e,r){const a=this.peek();return a.type!==e||r!==void 0&&a.value!==r?!1:(this.consume(),!0)}expect(e,r){const a=this.peek();if(a.type!==e||r!==void 0&&a.value!==r)throw{message:`Expected ${e}${r!==void 0?` "${r}"`:""} but got ${a.type} "${a.value}"`,line:a.line,column:a.column};return this.consume()}recoverToNextLine(){for(;!this.isEnd()&&this.peek().type!=="Newline";)this.consume();this.peek().type==="Newline"&&this.consume()}snapshot(){return this.index}restore(e){this.index=e}}function Ei(t){const e=t.peek();let r="",a=!1;if(e.type==="Identifier"){if(r=t.consume().value,t.peek().type==="Punctuation"&&t.peek().value==="("){const s=t.snapshot();t.consume();const l=[];let c=!0;for(;t.match("Newline"););if(!(t.peek().type==="Punctuation"&&t.peek().value===")"))for(;;){for(;t.match("Newline"););if(t.peek().type!=="Identifier"){c=!1;break}for(l.push(t.consume().value);t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){t.consume();continue}break}if(c&&t.peek().type==="Punctuation"&&t.peek().value===")"){if(t.consume(),t.peek().type==="Operator"&&t.peek().value==="="){const u={message:`Legacy "${r}(...) = expr" macro shorthand is removed in Aktion 0.5. Use "component ${r}(${l.join(", ")}) { ... }" for reusables, or "${r} = (${l.join(", ")}) => ..." for local helpers.`,line:e.line,column:e.column};throw u.__definitive=!0,u}t.restore(s)}else t.restore(s)}}else if(e.type==="StateIdentifier")r=t.consume().value,a=!0;else throw{message:`Expected identifier at start of statement, got ${e.type} "${e.value}"`,line:e.line,column:e.column};const i=t.expect("Operator","="),n=W(t);return t.isEnd()||t.match("Newline"),{kind:"Assignment",identifier:r,isState:a,expression:n,loc:{line:i.line,column:i.column}}}function W(t){return _i(t)}function _i(t){const e=ji(t);if(t.peek().type==="Punctuation"&&t.peek().value==="?"){t.consume();const r=W(t);t.expect("Punctuation",":");const a=W(t);return{kind:"Ternary",test:e,consequent:r,alternate:a}}return e}function ji(t){let e=lr(t);for(;t.peek().type==="Operator"&&(t.peek().value==="||"||t.peek().value==="??");){const r=t.consume().value,a=lr(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function lr(t){let e=cr(t);for(;t.peek().type==="Operator"&&t.peek().value==="&&";){t.consume();const r=cr(t);e={kind:"Binary",operator:"&&",left:e,right:r}}return e}function cr(t){let e=ur(t);for(;t.peek().type==="Operator"&&(t.peek().value==="=="||t.peek().value==="!=");){const r=t.consume().value,a=ur(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function ur(t){let e=dr(t);for(;t.peek().type==="Operator"&&[">","<",">=","<="].includes(t.peek().value);){const r=t.consume().value,a=dr(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function dr(t){let e=pr(t);for(;t.peek().type==="Operator"&&(t.peek().value==="+"||t.peek().value==="-");){const r=t.consume().value,a=pr(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function pr(t){let e=kt(t);for(;t.peek().type==="Operator"&&(t.peek().value==="*"||t.peek().value==="/"||t.peek().value==="%");){const r=t.consume().value,a=kt(t);e={kind:"Binary",operator:r,left:e,right:a}}return e}function kt(t){const e=t.peek();if(e.type==="Operator"&&(e.value==="!"||e.value==="-")){t.consume();const r=kt(t);return{kind:"Unary",operator:e.value,argument:r}}return Bi(t)}function Bi(t){let e=Di(t);for(;;){const r=t.peek();if(r.type==="Punctuation"&&r.value==="."){t.consume();const a=t.consume();if(a.type!=="Identifier"&&a.type!=="Keyword")throw{message:`Expected Identifier but got ${a.type} "${a.value}"`,line:a.line,column:a.column};const i=t.peek();if(i.type==="Punctuation"&&i.value==="("){t.consume();const n=Fe(t,{named:!0});t.expect("Punctuation",")"),e={kind:"MethodCall",object:e,method:a.value,arguments:n,loc:{line:a.line,column:a.column}};continue}e={kind:"Member",object:e,property:a.value};continue}if(r.type==="Operator"&&r.value==="?."){if(t.consume(),t.peek().type==="Punctuation"&&t.peek().value==="["){t.consume();const a=W(t);t.expect("Punctuation","]"),e={kind:"Member",object:e,computed:a,optional:!0}}else{const a=t.consume();if(a.type!=="Identifier"&&a.type!=="Keyword")throw{message:`Expected Identifier but got ${a.type} "${a.value}"`,line:a.line,column:a.column};const i=t.peek();if(i.type==="Punctuation"&&i.value==="("){t.consume();const n=Fe(t,{named:!0});t.expect("Punctuation",")"),e={kind:"MethodCall",object:e,method:a.value,arguments:n,optional:!0,loc:{line:a.line,column:a.column}};continue}e={kind:"Member",object:e,property:a.value,optional:!0}}continue}if(r.type==="Punctuation"&&r.value==="["){t.consume();const a=W(t);t.expect("Punctuation","]"),e={kind:"Member",object:e,computed:a};continue}break}return e}function Di(t){const e=t.peek();if(e.type==="Keyword"){if(e.value==="if")return fr(t);if(e.value==="match")return Fi(t);if(e.value==="for")return Oi(t);if(e.value==="action"||e.value==="effect"){const r=t.peek(1);if(!(r&&r.type==="Identifier"))return t.consume(),{kind:"Identifier",name:e.value,loc:{line:e.line,column:e.column}}}}if(e.type==="JsBlock")return t.consume(),{kind:"JsBlock",body:e.value,loc:{line:e.line,column:e.column}};if(e.type==="Number")return t.consume(),{kind:"Literal",value:Number(e.value)};if(e.type==="String")return t.consume(),{kind:"Literal",value:e.value};if(e.type==="TemplateString"){t.consume();const r=e.parts??[],a=[],i=[];let n="",s=!1;const l=()=>{a.push(n),n="",s=!1};for(const c of r){if(c.kind==="str"){n+=c.text,s=!0;continue}s?l():a.push("");const p=fe(`__rui_tmpl__ = ${c.source}`).statements[0];p&&p.kind==="Assignment"?i.push(p.expression):i.push({kind:"Literal",value:""})}for((s||a.length===0)&&a.push(n);a.length<=i.length;)a.push("");return{kind:"Template",quasis:a,expressions:i,loc:{line:e.line,column:e.column}}}if(e.type==="Boolean")return t.consume(),{kind:"Literal",value:e.value==="true"};if(e.type==="Null")return t.consume(),{kind:"Literal",value:null};if(e.type==="StateIdentifier")return t.consume(),{kind:"StateRef",name:e.value};if(e.type==="BuiltinIdentifier"){t.consume(),t.expect("Punctuation","(");const r=Fe(t,{named:!0});return t.expect("Punctuation",")"),{kind:"BuiltinCall",name:e.value,arguments:r,loc:{line:e.line,column:e.column}}}if(e.type==="Identifier"){if(t.consume(),t.peek().type==="Punctuation"&&t.peek().value==="("){t.consume();const r=Fe(t,{named:!0});return t.expect("Punctuation",")"),{kind:"Call",callee:e.value,arguments:r,loc:{line:e.line,column:e.column}}}return{kind:"Identifier",name:e.value,loc:{line:e.line,column:e.column}}}if(e.type==="Punctuation"&&e.value==="["){t.consume();const r=Fe(t);return t.expect("Punctuation","]"),{kind:"Array",elements:r}}if(e.type==="Punctuation"&&e.value==="{"){t.consume();const r=hr(t);return t.expect("Punctuation","}"),{kind:"Object",properties:r}}if(e.type==="Punctuation"&&e.value==="("){const r=t.snapshot(),a=Ui(t);if(a)return a;t.restore(r),t.consume();const i=W(t);return t.expect("Punctuation",")"),i}throw{message:`Unexpected token ${e.type} "${e.value}"`,line:e.line,column:e.column}}function Fe(t,e){const r=[],a=e?.named===!0;for(;t.match("Newline"););if(t.peek().type==="Punctuation"&&(t.peek().value===")"||t.peek().value==="]"))return r;for(r.push(a?gr(t):mr(t));t.match("Newline"););for(;t.peek().type==="Punctuation"&&t.peek().value===",";){for(t.consume();t.match("Newline"););if(t.peek().type==="Punctuation"&&(t.peek().value===")"||t.peek().value==="]"))break;for(r.push(a?gr(t):mr(t));t.match("Newline"););}for(;t.match("Newline"););return r}function mr(t){if(t.peek().type==="Operator"&&t.peek().value==="..."){const e=t.consume();return{kind:"Spread",argument:W(t),loc:{line:e.line,column:e.column}}}return W(t)}function gr(t){if(t.peek().type==="Operator"&&t.peek().value==="..."){const r=t.consume();return{kind:"Spread",argument:W(t),loc:{line:r.line,column:r.column}}}if(t.peek().type==="Keyword"&&t.peek().value==="bind"){const r=t.consume();t.expect("Punctuation",":");const a=t.expect("Identifier");t.expect("Punctuation",":");const i=W(t);return{kind:"Bind",prop:a.value,target:i,loc:{line:r.line,column:r.column}}}if(t.peek().type==="Identifier"&&t.peek(1).type==="Operator"&&t.peek(1).value==="="){const r=t.peek(),a={message:`Legacy "name=value" named-arg form is removed in Aktion 0.5. Use "${r.value}: value" instead.`,line:r.line,column:r.column};throw a.__definitive=!0,a}const e=t.peek();if((e.type==="Identifier"||e.type==="Keyword")&&t.peek(1).type==="Punctuation"&&t.peek(1).value===":"){const r=t.consume();t.consume();const a=W(t);return{kind:"NamedArg",name:r.value,value:a,loc:{line:r.line,column:r.column}}}return W(t)}function fr(t){const e=t.expect("Keyword","if"),r=W(t),a=ye(t);let i;for(;t.match("Newline"););return t.peek().type==="Keyword"&&t.peek().value==="else"&&(t.consume(),t.peek().type==="Keyword"&&t.peek().value==="if"?i=fr(t):i=ye(t)),{kind:"If",test:r,consequent:a,alternate:i,loc:{line:e.line,column:e.column}}}function Fi(t){const e=t.expect("Keyword","match"),r=W(t);t.expect("Punctuation","{");const a=[];for(;t.match("Newline"););for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");){let i;const n=t.peek();n.type==="Keyword"&&n.value==="default"?(t.consume(),i="_"):i=W(t),t.expect("Punctuation",":");const s=W(t);for(a.push({pattern:i,body:s});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===",")for(t.consume();t.match("Newline"););}return t.expect("Punctuation","}"),{kind:"Match",discriminant:r,arms:a,loc:{line:e.line,column:e.column}}}function Oi(t){const e=t.expect("Keyword","for");let r,a,i;if(t.peek().type==="Punctuation"&&t.peek().value==="(")t.consume(),r=t.expect("Identifier").value,t.expect("Punctuation",","),a=t.expect("Identifier").value,t.expect("Punctuation",")");else if(t.peek().type==="Punctuation"&&t.peek().value==="{"){t.consume();const l=[];for(;!(t.peek().type==="Punctuation"&&t.peek().value==="}");)l.push(t.expect("Identifier").value),t.peek().type==="Punctuation"&&t.peek().value===","&&t.consume();t.expect("Punctuation","}"),r="__row",i=l}else r=t.expect("Identifier").value;t.expect("Keyword","in");const n=W(t),s=ye(t);return{kind:"For",item:r,index:a,destructure:i,iterable:n,body:s,loc:{line:e.line,column:e.column}}}function Ui(t){const e=t.peek();if(e.type!=="Punctuation"||e.value!=="(")return null;t.consume();const r=[];for(;t.match("Newline"););if(!(t.peek().type==="Punctuation"&&t.peek().value===")"))for(;;){for(;t.match("Newline"););const i=t.peek();if(i.type!=="Identifier")return null;t.consume();const n={name:i.value};if(t.peek().type==="Punctuation"&&t.peek().value===":"){t.consume();try{n.defaultValue=W(t)}catch{return null}}for(r.push(n);t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){t.consume();continue}break}for(;t.match("Newline"););if(!(t.peek().type==="Punctuation"&&t.peek().value===")")||(t.consume(),!(t.peek().type==="Operator"&&t.peek().value==="=>")))return null;t.consume();let a;if(t.peek().type==="JsBlock"){const i=t.consume();a={kind:"JsBlock",body:i.value,loc:{line:i.line,column:i.column}}}else t.peek().type==="Punctuation"&&t.peek().value==="{"?a=ye(t):a=qi(t);return{kind:"Lambda",params:r,body:a,loc:{line:e.line,column:e.column}}}function qi(t){const e=W(t),r=t.peek();if(r.type==="Operator"){if(["=","+=","-=","*=","/=","??="].includes(r.value)){t.consume();const i=W(t);return{kind:"BuiltinCall",name:"__rui_assign__",arguments:[e,i,{kind:"Literal",value:r.value}],loc:{line:r.line,column:r.column}}}if(r.value==="++"||r.value==="--")return t.consume(),{kind:"BuiltinCall",name:"__rui_postfix__",arguments:[e,{kind:"Literal",value:r.value}],loc:{line:r.line,column:r.column}}}return e}function hr(t){const e=[];for(;t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value==="}")return e;for(;;){for(;t.match("Newline"););const r=t.peek();if(r.type==="Operator"&&r.value==="..."){t.consume();const s=W(t);for(e.push({key:"",value:s,spread:!0});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){for(t.consume();t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value==="}")break;continue}break}let a;if(r.type==="Identifier"||r.type==="String"||r.type==="Keyword")a=t.consume().value;else throw{message:`Expected object key, got ${r.type} "${r.value}"`,line:r.line,column:r.column};const i=t.peek();let n;for(r.type==="Identifier"&&i.type==="Punctuation"&&(i.value===","||i.value==="}")?n={kind:"Identifier",name:a,loc:{line:r.line,column:r.column}}:(t.expect("Punctuation",":"),n=W(t)),e.push({key:a,value:n});t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value===","){for(t.consume();t.match("Newline"););if(t.peek().type==="Punctuation"&&t.peek().value==="}")break;continue}break}for(;t.match("Newline"););return e}function Hi(t){const e=fe(t);return br(t,e)}function br(t,e){const r=new Set(e.errors.map(l=>l.line)),a=[],i=[];for(const l of e.statements){const c=l.loc?.line??0;if(r.has(c)){i.push(l);continue}a.push(l)}let n=t,s="";if(e.errors.length>0){const l=Math.min(...e.errors.map(p=>p.line)),c=Wi(t,l);n=c.before,s=c.after;const u=a.findIndex(p=>(p.loc?.line??0)>=l);if(u>=0)for(const p of a.splice(u))i.push(p)}return{committedSource:n,draftingSource:s,committedBindings:a.map(vr).filter(l=>l!==null),uncommittedBindings:i.map(vr).filter(l=>l!==null),committedStatements:a,errors:e.errors}}function Vi(t,e){if(e.length===0)return!0;const r=new Set(t.committedBindings);for(const a of e)if(!r.has(a))return!1;return!0}function vr(t){switch(t.kind){case"Assignment":return t.identifier;case"ComponentDeclaration":case"EffectDeclaration":case"ActionDeclaration":return t.name;default:return null}}function Wi(t,e){if(e<=1)return{before:"",after:t};let r=0,a=1;for(;r<t.length&&a<e;)t[r]===`
12
+ `&&(a+=1),r+=1;return{before:t.slice(0,r),after:t.slice(r)}}function Gi(t,e){const r=[],a={};let i=t;for(const n of e){if(n.kind==="patch"){a[n.target]=n.value;continue}const s=Ki(i,n);i=s.programText,s.warning&&r.push(s.warning)}return{programText:i,stateUpdates:a,warnings:r}}function Ki(t,e){const r=fe(t);if(r.errors.length>0)return{programText:t,warning:`delta(${e.kind}): source did not parse cleanly (${r.errors[0].message}); op skipped`};switch(e.kind){case"new":{const a=fe(e.source);if(a.errors.length>0||a.statements.length===0)return{programText:t,warning:`delta(new): could not parse "${yr(e.source)}" — op skipped`};const i=t.endsWith(`
13
13
  `)?"":`
14
14
  `;return{programText:t+i+e.source.trim()+`
15
- `}}case"delete":{const a=St(r,e.binding);return a<0?{programText:t,warning:`delta(delete): binding "${e.binding}" not found — op skipped`}:{programText:Ct(t,r,a,null)}}case"replace":{const a=St(r,e.binding);return a<0?{programText:t,warning:`delta(replace): binding "${e.binding}" not found — op skipped`}:fe(`${e.binding} = ${e.source}`).errors.length>0?{programText:t,warning:`delta(replace): could not parse new source for "${e.binding}" — op skipped`}:{programText:Ct(t,r,a,`${e.binding} = ${e.source.trim()}`)}}case"append":{const a=St(r,e.binding);if(a<0)return{programText:t,warning:`delta(append): binding "${e.binding}" not found — op skipped`};const i=r.statements[a];if(i.kind!=="Assignment"||i.expression.kind!=="Array")return{programText:t,warning:`delta(append): binding "${e.binding}" is not an array literal — op skipped`};const n=fe(`__rui_delta_item__ = ${e.item}`),s=n.statements[0];if(n.errors.length>0||!s||s.kind!=="Assignment")return{programText:t,warning:`delta(append): could not parse item "${br(e.item)}" — op skipped`};const l=i.expression.elements,c=`${e.binding} = [${[...l.map(oe),e.item.trim()].join(", ")}]`;return{programText:Ct(t,r,a,c)}}}}function St(t,e){return t.statements.findIndex(r=>Ki(r)===e)}function Ki(t){switch(t.kind){case"Assignment":return t.identifier;case"ComponentDeclaration":case"EffectDeclaration":case"ActionDeclaration":return t.name;default:return null}}function Ct(t,e,r,a){const i=t.split(`
15
+ `}}case"delete":{const a=St(r,e.binding);return a<0?{programText:t,warning:`delta(delete): binding "${e.binding}" not found — op skipped`}:{programText:Ct(t,r,a,null)}}case"replace":{const a=St(r,e.binding);return a<0?{programText:t,warning:`delta(replace): binding "${e.binding}" not found — op skipped`}:fe(`${e.binding} = ${e.source}`).errors.length>0?{programText:t,warning:`delta(replace): could not parse new source for "${e.binding}" — op skipped`}:{programText:Ct(t,r,a,`${e.binding} = ${e.source.trim()}`)}}case"append":{const a=St(r,e.binding);if(a<0)return{programText:t,warning:`delta(append): binding "${e.binding}" not found — op skipped`};const i=r.statements[a];if(i.kind!=="Assignment"||i.expression.kind!=="Array")return{programText:t,warning:`delta(append): binding "${e.binding}" is not an array literal — op skipped`};const n=fe(`__rui_delta_item__ = ${e.item}`),s=n.statements[0];if(n.errors.length>0||!s||s.kind!=="Assignment")return{programText:t,warning:`delta(append): could not parse item "${yr(e.item)}" — op skipped`};const l=i.expression.elements,c=`${e.binding} = [${[...l.map(oe),e.item.trim()].join(", ")}]`;return{programText:Ct(t,r,a,c)}}}}function St(t,e){return t.statements.findIndex(r=>Yi(r)===e)}function Yi(t){switch(t.kind){case"Assignment":return t.identifier;case"ComponentDeclaration":case"EffectDeclaration":case"ActionDeclaration":return t.name;default:return null}}function Ct(t,e,r,a){const i=t.split(`
16
16
  `),n=e.statements[r],s=e.statements[r+1],l=(n.loc?.line??1)-1,c=s?(s.loc?.line??i.length+1)-1:i.length,u=i.slice(0,l),p=i.slice(c);return a===null?[...u,...p].join(`
17
17
  `):[...u,a,...p].join(`
18
- `)}function oe(t){switch(t.kind){case"Literal":return typeof t.value=="string"?`"${t.value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:String(t.value);case"Identifier":return t.name;case"StateRef":return`$${t.name}`;case"Call":return`${t.callee}(${t.arguments.map(oe).join(", ")})`;case"MethodCall":return`${oe(t.object)}${t.optional?"?.":"."}${t.method}(${t.arguments.map(oe).join(", ")})`;case"NamedArg":return`${t.name}: ${oe(t.value)}`;case"Array":return`[${t.elements.map(oe).join(", ")}]`;case"Object":return`{ ${t.properties.map(e=>e.spread?`...${oe(e.value)}`:`${e.key}: ${oe(e.value)}`).join(", ")} }`;case"Member":{const e=oe(t.object);return t.property?`${e}${t.optional?"?.":"."}${t.property}`:t.computed?`${e}${t.optional?"?.":""}[${oe(t.computed)}]`:e}case"Binary":return`${oe(t.left)} ${t.operator} ${oe(t.right)}`;case"Template":{const e=[];for(let r=0;r<t.quasis.length;r+=1)e.push(t.quasis[r]??""),r<t.expressions.length&&(e.push("${"),e.push(oe(t.expressions[r])),e.push("}"));return`\`${e.join("")}\``}default:return"/* unprintable */"}}function br(t){return t.length>40?`${t.slice(0,37)}...`:t}const vr=new WeakMap;function Yi(t){let e=vr.get(t.components);if(!e){e=new Map;for(const r of t.components)r?.name&&e.set(r.name,r);vr.set(t.components,e)}return e}function yr(t,e){const r=new Map;for(const a of t.components)r.set(a.name,a);for(const a of e.components)r.set(a.name,a);return{root:e.root??t.root,components:[...r.values()],componentGroups:t.componentGroups}}function Ie(t,e){return Yi(t).get(e)}function Tt(t){const e=t.props.findIndex(r=>r.positional===!0);return e>=0?e:t.props.length>0?0:-1}function Nt(t){const e=Tt(t);return e>=0?t.props[e]:void 0}function xr(t){for(const e of t){const r=e.props.filter(a=>a.positional===!0);if(r.length>1){const a=r.map(i=>i.name).join(", ");throw new SyntaxError(`Component "${e.name}" declares ${r.length} positional props (${a}). Aktion 0.5 §19.1 allows at most one.`)}}}function wr(t,e){const r={};return t.props.forEach((a,i)=>{i<e.length&&(r[a.name]=e[i])}),r}function Ji(t,e){const r=fe(t),a=$t(r,e);return a.length>0&&(r.errors=[...r.errors,...a]),r}function $t(t,e){const r=[];for(const a of t.statements)Oe(a,e,r);return r}function Oe(t,e,r){switch(t.kind){case"Assignment":G(t.expression,e,r);return;case"ExpressionStatement":G(t.expression,e,r);return;case"ComponentDeclaration":case"ActionDeclaration":case"EffectDeclaration":for(const a of t.body.body)Oe(a,e,r);return;case"Return":t.argument&&G(t.argument,e,r);return;default:return}}function G(t,e,r){if(t)switch(t.kind){case"Call":{Zi(t,e,r);for(const a of t.arguments)G(a,e,r);return}case"MethodCall":{G(t.object,e,r);for(const a of t.arguments)G(a,e,r);return}case"BuiltinCall":{an(t,r);for(const a of t.arguments)G(a,e,r);return}case"Array":for(const a of t.elements)G(a,e,r);return;case"Object":for(const a of t.properties)G(a.value,e,r);return;case"Template":for(const a of t.expressions)G(a,e,r);return;case"Binary":G(t.left,e,r),G(t.right,e,r);return;case"Unary":G(t.argument,e,r);return;case"Ternary":G(t.test,e,r),G(t.consequent,e,r),G(t.alternate,e,r);return;case"Member":G(t.object,e,r),t.computed&&G(t.computed,e,r);return;case"Spread":G(t.argument,e,r);return;case"NamedArg":G(t.value,e,r);return;case"If":G(t.test,e,r);for(const a of t.consequent.body)Oe(a,e,r);if(t.alternate)if(t.alternate.kind==="If")G(t.alternate,e,r);else for(const a of t.alternate.body)Oe(a,e,r);return;case"Match":G(t.discriminant,e,r);for(const a of t.arms)G(a.body,e,r);return;case"For":G(t.iterable,e,r);for(const a of t.body.body)Oe(a,e,r);return;case"Lambda":t.body.kind!=="JsBlock"&&G(t.body,e,r);return;case"Bind":G(t.target,e,r);return;default:return}}const Xi={Script:'Script("id", body, deps?) is not supported. Use an `effect [$deps] { js{ … } }` block (see §9 — effect declarations).',Action:'Action([@Set, @Run, …]) payloads are removed in 0.5. Use `action <Name>() { … }` declarations and reference them by name (e.g. `Button("Save", action: save)`) — see §10.',Routes:'Routes(items, default?) is removed in 0.5. Use `pages = _router_({ "/": Home(), default: NotFound() })` (see §12 — outlet-first router).',Route:'Route(path, content) is only valid inside a v1 `Routes(...)` outlet, which has been removed. Use `"/path": content` arms inside a `_router_({ … })` call (see §12).',Query:'Query("name", args, placeholder, refreshSec?) is removed in 0.5. Declare a top-level `query <Name>(args) { url, method, … }` block and bind it with `$query foo = <Name>(args)` (see §11.2).',Mutation:'Mutation("name", args) is removed in 0.5. Declare a top-level `mutation <Name>(args) { url, method, body, … }` block and bind it with `$mutation save = <Name>` (see §11.3).',NavLinkRoute:'NavLinkRoute is removed in 0.5. Use `NavLink(label, to: "/path")` (see §12 — Outlet-first router).',useInstanceState:"useInstanceState(...) is removed in 0.5. Declare per-instance state inside the component body with `$state name = init` — identity is content-addressed (§13)."};function Zi(t,e,r){const a=Xi[t.callee];if(a){r.push({message:`${t.callee}(...) — ${a}`,line:t.loc?.line??0,column:t.loc?.column??0});return}if(t.callee==="Theme"){tn(t,r);return}const i=Ie(e,t.callee);if(!i)return;const n=new Set;for(const l of i.props)if(n.add(l.name),l.aliases)for(const c of l.aliases)n.add(c);n.add("key");const s=[];for(const l of t.arguments)l.kind!=="NamedArg"&&s.push(l);if(s.length>1){const c=Nt(i)?.name??"(none)",u=new Set(t.arguments.filter(g=>g.kind==="NamedArg").map(g=>g.name)),p=i.props.filter(g=>g.name!==c&&!u.has(g.name)).slice(0,s.length-1).map(g=>g.name),m=p.length>0?p.map(g=>`${g}: …`).join(", "):"use named arguments";r.push({message:`${t.callee}(...) — Aktion 0.5 §19.1 allows at most one positional argument (the "${c}" prop). The extra ${s.length-1} positional argument(s) must be passed as named arguments: ${m}. Multi-positional calls are removed.`,line:t.loc?.line??0,column:t.loc?.column??0})}for(const l of t.arguments){if(l.kind!=="NamedArg")continue;if(!n.has(l.name)){r.push({message:`Unknown prop "${l.name}" on <${t.callee}>. Known props: ${i.props.map(u=>u.name).join(", ")}.`,line:l.loc?.line??t.loc?.line??0,column:l.loc?.column??t.loc?.column??0});continue}const c=i.props.find(u=>u.name===l.name||(u.aliases?.includes(l.name)??!1));if(c?.enum&&l.value.kind==="Literal"&&typeof l.value.value=="string"){const u=l.value.value;c.enum.includes(u)||r.push({message:`<${t.callee}> ${l.name}="${u}" — must be one of ${c.enum.map(p=>`"${p}"`).join(", ")}.`,line:l.loc?.line??t.loc?.line??0,column:l.loc?.column??t.loc?.column??0})}}}const Qi=new Set(["colors","radius","font","motion","elevation"]),en=new Set(["name","direction"]);function tn(t,e){const r=t.arguments[0];if(!(!r||r.kind!=="Object"))for(const a of r.properties){if(a.spread||Qi.has(a.key)||en.has(a.key))continue;const i=nn(a.key),n=a.key.startsWith("--")?`Theme({"${a.key}": ...}) — free-form CSS variable keys are removed in Aktion 0.5. Use the structured form: Theme({ colors: {...}, radius: {...}, font: {...} }).`:`Theme({${a.key}: ...}) — legacy flat-shape token is removed in Aktion 0.5. Use ${i}.`;e.push({message:n,line:t.loc?.line??0,column:t.loc?.column??0})}}const rn={Set:"@Set($x, value) is removed in 0.5. Inside an `action Name() { … }` body, assign directly: `$x = value`.",Reset:"@Reset($x) is removed in 0.5. Inside an `action Name() { … }` body, assign the default explicitly: `$x = defaultValue`.",Run:"@Run(name) is removed in 0.5. Inside an `action Name() { … }` body, call the mutation: `await $mutation.foo.call(args)` (see §11.3).",ToAssistant:'@ToAssistant("text") is removed in 0.5. Use `emit "assistant-message" { message: "..." }` inside an `action Name() { … }` body (see §22.2).',OpenUrl:'@OpenUrl("https://…") is removed in 0.5. Inside an `action Name() { js{ … } }` body, call `window.open(url, "_blank", "noopener,noreferrer")`.',Navigate:'@Navigate("/path") is removed in 0.5. Use `pages = _router_({ … })` (see §12) and navigate via the host (`el.navigate("/path")`), `_route_.navigate("/path")` from inside an action, or by linking to the path with `NavLink(label, "/path")`.',Js:"@Js(body, args?) is removed in 0.5. Use `effect <id> on $deps { js{ … } }` or `action Name() { js{ … } }` (see §9, §10).",Const:"@Const(expr) is removed in 0.5. Use `$computed name = expr` (see §4 — state tiers).",Memo:"@Memo(expr) is removed in 0.5. Use `$computed name = expr` (see §4 — state tiers).",Push:"@Push(arr, value) is removed in 0.5. Use spread: `[...arr, value]`.",Concat:"@Concat(a, b) is removed in 0.5. Use spread: `[...a, ...b]`.",Map:'@Map(arr, "field") is removed in 0.5. Use array pluck shorthand: `arr.field` (yields `[arr[0].field, arr[1].field, …]`).',Take:"@Take(arr, n) is removed in 0.5. Use @Slice(arr, 0, n) or array shortcuts like `arr.first` / `arr.last`.",FormatCurrency:'@FormatCurrency(value, opts?) is removed in 0.5. Use `@Format(value, "currency", opts?)`.',FormatNumber:'@FormatNumber(value, opts?) is removed in 0.5. Use `@Format(value, "number", opts?)`.',Each:'@Each(items, "x", template) is removed in 0.5. Use the expression-form loop: `for x in items { template }` (see §8.3).',If:"@If(cond, then, else?) is removed in 0.5. Use the expression-form conditional: `if cond { then } else { else }` (see §8.1).",Switch:'@Switch(value, cases, default?) is removed in 0.5. Use the expression-form match: `match value { "a" -> A() _ -> Default() }` (see §8.2).'};function an(t,e){const r=rn[t.name];r&&e.push({message:`@${t.name}(...) — ${r}`,line:t.loc?.line??0,column:t.loc?.column??0})}function nn(t){const e=[{prefix:"color",group:"colors"},{prefix:"radius",group:"radius"},{prefix:"font",group:"font"},{prefix:"motion",group:"motion"},{prefix:"elevation",group:"elevation"}];for(const{prefix:r,group:a}of e)if(t!==r&&t.startsWith(r)&&t.length>r.length){const i=t.slice(r.length),n=i.charAt(0).toLowerCase()+i.slice(1);return`Theme({ ${a}: { ${n}: ... } })`}return"Theme({ colors: {...}, radius: {...}, font: {...}, motion: {...}, elevation: {...} })"}const F=t=>typeof t=="number"?t:typeof t=="string"&&t.trim()!==""&&!Number.isNaN(Number(t))?Number(t):0,ae=t=>Array.isArray(t)?t:[],kr=(t,e,r)=>{switch(t){case"==":return e===r;case"!=":return e!==r;case">":return F(e)>F(r);case"<":return F(e)<F(r);case">=":return F(e)>=F(r);case"<=":return F(e)<=F(r);case"contains":{const a=String(e??"").toLowerCase(),i=String(r??"").toLowerCase();return a.includes(i)}default:return!1}},ze=(t,e)=>{if(e==="")return t;if(t&&typeof t=="object"){if(e.includes(".")){const r=e.split(".");let a=t;for(const i of r)if(a&&typeof a=="object")a=a[i];else return;return a}return t[e]}},Sr=t=>{const e=ae(t[0]),r=String(t[1]??""),a=String(t[2]??"=="),i=t[3];return e.filter(n=>kr(a,ze(n,r),i))},on=t=>!!t&&typeof t=="object"&&!Array.isArray(t),xe=t=>{if(t instanceof Date)return t;if(typeof t=="number")return new Date(t);if(typeof t=="string"&&t.trim()!==""){if(!Number.isNaN(Number(t))&&/^-?\d+$/.test(t.trim()))return new Date(Number(t));const e=new Date(t);if(!Number.isNaN(e.getTime()))return e}return new Date},sn=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],ln=["January","February","March","April","May","June","July","August","September","October","November","December"],cn=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],un=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dn=(t,e)=>{const r=(l,c=2)=>String(l).padStart(c,"0"),a=t.getHours(),i=(a+11)%12+1,n=[[/YYYY/g,String(t.getFullYear())],[/YY/g,String(t.getFullYear()).slice(-2)],[/MMMM/g,ln[t.getMonth()]],[/MMM/g,sn[t.getMonth()]],[/MM/g,r(t.getMonth()+1)],[/dddd/g,un[t.getDay()]],[/ddd/g,cn[t.getDay()]],[/DD/g,r(t.getDate())],[/HH/g,r(a)],[/hh/g,r(i)],[/mm/g,r(t.getMinutes())],[/ss/g,r(t.getSeconds())],[/\bM\b/g,String(t.getMonth()+1)],[/\bD\b/g,String(t.getDate())],[/\bH\b/g,String(a)],[/\bh\b/g,String(i)],[/\bm\b/g,String(t.getMinutes())],[/\bs\b/g,String(t.getSeconds())],[/A/g,a>=12?"PM":"AM"],[/a/g,a>=12?"pm":"am"]];let s=e;for(const[l,c]of n)s=s.replace(l,c);return s},pn=(t,e=Date.now())=>{const r=e-t.getTime(),a=Math.abs(r),i=r<0,n=6e4,s=60*n,l=24*s,c=7*l,u=30*l,p=365*l;let m,g;return a<n?i?"in a moment":"just now":(a<s?(m=Math.round(a/n),g="m"):a<l?(m=Math.round(a/s),g="h"):a<c?(m=Math.round(a/l),g="d"):a<u?(m=Math.round(a/c),g="w"):a<p?(m=Math.round(a/u),g="mo"):(m=Math.round(a/p),g="y"),i?`in ${m}${g}`:`${m}${g} ago`)},Cr=(t,e)=>{const a=String(t??"").replace(/([a-z0-9])([A-Z])/g,"$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map(n=>n.toLowerCase());if(a.length===0)return"";if(e==="snake")return a.join("_");if(e==="kebab")return a.join("-");const i=n=>n.charAt(0).toUpperCase()+n.slice(1);return e==="pascal"?a.map(i).join(""):a[0]+a.slice(1).map(i).join("")},At={Count:t=>ae(t[0]).length,Sum:t=>ae(t[0]).reduce((e,r)=>e+F(r),0),Avg:t=>{const e=ae(t[0]);return e.length===0?0:e.reduce((r,a)=>r+F(a),0)/e.length},Min:t=>{const e=ae(t[0]).map(F);return e.length===0?0:Math.min(...e)},Max:t=>{const e=ae(t[0]).map(F);return e.length===0?0:Math.max(...e)},First:t=>ae(t[0])[0]??null,Last:t=>{const e=ae(t[0]);return e.length===0?null:e[e.length-1]},Filter:Sr,FilterBy:Sr,Sort:t=>{const e=[...ae(t[0])],r=String(t[1]??""),a=String(t[2]??"asc").toLowerCase()==="desc"?-1:1;return e.sort((i,n)=>{const s=ze(i,r),l=ze(n,r);return typeof s=="number"&&typeof l=="number"?(s-l)*a:String(s??"").localeCompare(String(l??""))*a}),e},Round:t=>{const e=F(t[0]),r=t[1]===void 0?0:F(t[1]),a=Math.pow(10,r);return Math.round(e*a)/a},Abs:t=>Math.abs(F(t[0])),Floor:t=>Math.floor(F(t[0])),Ceil:t=>Math.ceil(F(t[0])),Find:t=>{const e=ae(t[0]),r=String(t[1]??""),a=String(t[2]??"=="),i=t[3];return e.find(n=>kr(a,ze(n,r),i))??null},GroupBy:t=>{const e=ae(t[0]),r=String(t[1]??""),a={};for(const i of e){const n=String(ze(i,r)??"");(a[n]??(a[n]=[])).push(i)}return a},Slice:t=>{const e=ae(t[0]),r=t[1]===void 0?0:F(t[1]),a=t[2]===void 0?e.length:F(t[2]);return e.slice(r,a)},Unique:t=>{const e=ae(t[0]),r=t[1]===void 0?"":String(t[1]??"");if(!r)return Array.from(new Set(e));const a=new Set,i=[];for(const n of e){const s=ze(n,r);a.has(s)||(a.add(s),i.push(n))}return i},Reverse:t=>[...ae(t[0])].reverse(),Range:t=>{const e=F(t[0]),r=F(t[1]),a=t[2]===void 0?r>=e?1:-1:F(t[2]);if(a===0)return[e];const i=[];if(a>0)for(let n=e;n<=r;n+=a)i.push(n);else for(let n=e;n>=r;n+=a)i.push(n);return i},Repeat:t=>{const e=Math.max(0,F(t[1]));return Array.from({length:e},()=>t[0])},Pick:t=>{const e=t[0];if(!on(e))return{};const r=ae(t[1]).map(i=>String(i??"")),a={};for(const i of r)i in e&&(a[i]=e[i]);return a},Format:t=>{const e=F(t[0]),r=String(t[1]??"number"),a=t[2];if(r==="currency"){const n=String(a??"USD")||"USD",s=t[3]===void 0?void 0:String(t[3]??"");try{return new Intl.NumberFormat(s||void 0,{style:"currency",currency:n}).format(e)}catch{return e.toFixed(2)}}if(r==="percent"){const n=t[2]===void 0?void 0:String(t[2]??"");return new Intl.NumberFormat(n||void 0,{style:"percent",maximumFractionDigits:2}).format(e)}const i=t[2]===void 0?void 0:String(t[2]??"");return new Intl.NumberFormat(i||void 0).format(e)},FormatDate:t=>{const e=xe(t[0]),r=String(t[1]??"MMM D");switch(r){case"relative":return pn(e);case"date":return e.toLocaleDateString();case"time":return e.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});case"datetime":return e.toLocaleString();case"iso":return e.toISOString();default:return dn(e,r)}},Now:()=>Date.now(),Today:()=>{const t=new Date;return t.setHours(0,0,0,0),t.toISOString()},AddDays:t=>{const e=xe(t[0]),r=F(t[1]),a=new Date(e.getTime());return a.setDate(a.getDate()+r),a.toISOString()},AddHours:t=>{const e=xe(t[0]),r=F(t[1]),a=new Date(e.getTime());return a.setTime(a.getTime()+r*36e5),a.toISOString()},DiffDays:t=>{const e=xe(t[0]),r=xe(t[1]);return Math.round((r.getTime()-e.getTime())/864e5)},StartOfWeek:t=>{const e=xe(t[0]),r=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()));return r.setUTCDate(r.getUTCDate()-r.getUTCDay()),r.toISOString()},EndOfMonth:t=>{const e=xe(t[0]);return new Date(e.getFullYear(),e.getMonth()+1,0,23,59,59,999).toISOString()},Plural:t=>{const e=F(t[0]),r=String(t[1]??""),a=t[2]===void 0?r+"s":String(t[2]??"");return`${e} ${e===1?r:a}`},Capitalize:t=>{const e=String(t[0]??"");return e.length===0?"":e.charAt(0).toUpperCase()+e.slice(1)},Lowercase:t=>String(t[0]??"").toLowerCase(),Uppercase:t=>String(t[0]??"").toUpperCase(),Titlecase:t=>String(t[0]??"").split(/\s+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" "),Case:t=>{const e=String(t[1]??"camel").toLowerCase();return e==="snake"||e==="kebab"||e==="pascal"||e==="camel"?Cr(t[0],e):Cr(t[0],"camel")},Join:t=>{const e=ae(t[0]),r=t[1]===void 0?",":String(t[1]??"");return e.map(a=>a==null?"":String(a)).join(r)},Split:t=>{const e=String(t[0]??""),r=t[1]===void 0?",":String(t[1]??"");return e.split(r)},Trim:t=>String(t[0]??"").trim(),Replace:t=>{const e=String(t[0]??""),r=String(t[1]??""),a=t[2]===void 0?"":String(t[2]??"");return e.split(r).join(a)},Substring:t=>{const e=String(t[0]??""),r=F(t[1]),a=t[2]===void 0?e.length:F(t[2]);return e.substring(r,a)},StartsWith:t=>String(t[0]??"").startsWith(String(t[1]??"")),EndsWith:t=>String(t[0]??"").endsWith(String(t[1]??"")),Contains:t=>String(t[0]??"").includes(String(t[1]??"")),Match:t=>{const e=String(t[0]??""),r=String(t[1]??"");try{return new RegExp(r).test(e)}catch{return!1}},Clamp:t=>{const e=F(t[0]),r=F(t[1]),a=F(t[2]);return Math.min(Math.max(e,r),a)},Pow:t=>Math.pow(F(t[0]),F(t[1])),Sqrt:t=>Math.sqrt(F(t[0])),Random:()=>Math.random(),Log:t=>Math.log(F(t[0]))},Tr=t=>!!(t&&typeof t=="object"&&t.kind==="Theme");class Nr{constructor(){j(this,"values",new Map);j(this,"defaults",new Map);j(this,"persistent",new Set);j(this,"persistenceAdapter",null);j(this,"subscribers",new Set);j(this,"pendingChanges",new Set);j(this,"flushScheduled",!1)}setPersistenceAdapter(e){this.persistenceAdapter=e}declare(e,r){this.defaults.set(e,r),this.values.has(e)||this.values.set(e,r)}declarePersistent(e,r){this.persistent.add(e),this.defaults.set(e,r);const a=this.persistenceAdapter;let i=r;if(a){const n=a.load(e);n!==void 0&&(i=n)}this.values.set(e,i)}isPersistent(e){return this.persistent.has(e)}has(e){return this.values.has(e)}get(e){return this.values.get(e)}set(e,r){this.values.get(e)!==r&&(this.values.set(e,r),this.pendingChanges.add(e),this.persistent.has(e)&&this.persistenceAdapter?.save(e,r),this.scheduleFlush())}entries(){return this.values.entries()}snapshot(){const e={};return this.values.forEach((r,a)=>{e[a]=r}),e}hydrate(e){for(const[r,a]of Object.entries(e))this.values.set(r,a)}reset(...e){let r=!1;for(const a of e){if(!this.defaults.has(a))continue;const i=this.defaults.get(a);this.values.get(a)!==i&&(this.values.set(a,i),this.pendingChanges.add(a),this.persistent.has(a)&&this.persistenceAdapter?.save(a,i),r=!0)}r&&this.scheduleFlush()}resetAll(){let e=!1;for(const[r,a]of this.defaults.entries())this.values.get(r)!==a&&(this.values.set(r,a),this.pendingChanges.add(r),e=!0);e&&this.scheduleFlush()}rebind(e){this.values.clear(),this.defaults.clear(),this.persistent.clear(),this.pendingChanges.clear();for(const[r,a]of e)this.defaults.set(r,a),this.values.set(r,a)}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}scheduleFlush(){this.flushScheduled||(this.flushScheduled=!0,queueMicrotask(()=>this.flush()))}flush(){if(this.flushScheduled=!1,this.pendingChanges.size===0)return;const e=new Set(this.pendingChanges);this.pendingChanges.clear();for(const r of[...this.subscribers])r(e)}}function $r(t,e){if(!e)return null;const r=a=>`${t}::${a}`;return{load(a){try{const i=e.getItem(r(a));return i===null?void 0:JSON.parse(i)}catch{return}},save(a,i){try{e.setItem(r(a),JSON.stringify(i))}catch{}},remove(a){try{e.removeItem(r(a))}catch{}}}}class Ar{constructor(){j(this,"interceptors",{});j(this,"defaults",{})}setDefaults(e){this.defaults={...e}}registerInterceptors(e){this.interceptors={...this.interceptors,...e}}resolveUrl(e){const r=this.defaults.baseUrl;return!r||/^https?:\/\//i.test(e)||/^wss?:\/\//i.test(e)?e:e.startsWith("/")?r.replace(/\/$/,"")+e:r.replace(/\/$/,"")+"/"+e}async request(e){let r={...e,headers:{...this.defaults.headers,...e.headers}};if(this.interceptors.onRequest)try{r=await this.interceptors.onRequest(r)}catch(c){throw this.interceptors.onError?.(c,r),c}const a=async()=>{const c=new AbortController,u=this.defaults.timeoutMs??0;let p=null;u>0&&(p=setTimeout(()=>c.abort(),u));try{const m=typeof fetch=="function"?fetch:null;if(!m)throw new Error("`fetch` is not available in this environment");const g={method:r.method,headers:r.headers,signal:r.signal??c.signal};r.body!==void 0&&r.method!=="GET"&&r.method!=="HEAD"&&(g.body=mn(r.body,r.headers)),this.defaults.credentials&&(g.credentials=this.defaults.credentials);const f=await m(r.url,g),h={};f.headers.forEach((y,x)=>{h[x]=y});const b=h["content-type"]??"";let v;return f.status===204||r.method==="HEAD"?v=null:b.includes("application/json")?v=await f.json().catch(()=>null):v=await f.text().catch(()=>""),{status:f.status,headers:h,body:v}}finally{p&&clearTimeout(p)}},i=this.defaults.retry,n=Math.max(0,i?.count??0),s=i?.backoff??"exponential",l=async()=>{let c=null;for(let u=0;u<=n;u+=1)try{const p=await a();if(p.status>=500&&p.status<=599&&u<n){await Pr(Mr(s,u));continue}return p}catch(p){if(c=p,u<n){await Pr(Mr(s,u));continue}throw p}throw c??new Error("retry loop exhausted")};try{let c=await l();if(this.interceptors.onResponse){let u=!1;const p=async()=>u?c:(u=!0,l());c=await this.interceptors.onResponse(c,p)}return c}catch(c){throw this.interceptors.onError?.(c,r),c}}}function Mr(t,e){return t==="linear"?1e3*(e+1):Math.min(3e4,500*2**e)}function Pr(t){return new Promise(e=>setTimeout(e,t))}function mn(t,e){if(t==null)return"";if(typeof t=="string"||t instanceof Blob||t instanceof ArrayBuffer||typeof FormData<"u"&&t instanceof FormData||typeof URLSearchParams<"u"&&t instanceof URLSearchParams)return t;!e["content-type"]&&!e["Content-Type"]&&(e["Content-Type"]="application/json");try{return JSON.stringify(t)}catch{return String(t)}}function gn(t){const e=t&&typeof t=="object"&&!Array.isArray(t)?t:{},r=typeof e.url=="string"?e.url:"",a=typeof e.method=="string"?e.method.toUpperCase():"GET",i={};if(e.headers&&typeof e.headers=="object"&&!Array.isArray(e.headers))for(const[l,c]of Object.entries(e.headers))c!=null&&(i[l]=String(c));let n=r;if(e.query&&typeof e.query=="object"&&!Array.isArray(e.query)){const l=new URLSearchParams;for(const[u,p]of Object.entries(e.query))p!=null&&l.append(u,String(p));const c=l.toString();c&&(n+=(n.includes("?")?"&":"?")+c)}const s={url:n,method:a,headers:i,body:e.body};return e.signal instanceof AbortSignal&&(s.signal=e.signal),s}function Ir(t,e){const r={state:"loading",data:void 0,error:void 0,loading:!0,refetch:async()=>{await s()},cancel:()=>{a&&a.abort()}};let a=null,i=!1;const n=()=>e.notify?.(),s=async()=>{if(i&&a&&a.abort(),i=!0,a=new AbortController,r.state=r.data===void 0?"loading":"stale",r.loading=!0,n(),!e.http){r.error={message:"http runtime not available"},r.state="error",r.loading=!1,i=!1,n();return}try{const l=gn(t);l.url=e.http.resolveUrl(l.url),l.signal=a.signal;const c=await e.http.request(l);c.status>=200&&c.status<300?(r.data=c.body,r.state="data",r.error=void 0):(r.error={status:c.status,body:c.body},r.state="error"),r.status=c.status,r.headers=c.headers,r.lastUpdated=Date.now()}catch(l){if(l?.name==="AbortError")return;r.error=l,r.state="error"}finally{i=!1,r.loading=!1,n()}};return s(),r}function we(t){if(!t)return"/";let e=String(t);e.startsWith("#")&&(e=e.slice(1));const r=e.indexOf("?");return r>=0&&(e=e.slice(0,r)),e=e.replace(/\/{2,}/g,"/"),!e||e==="/"?"/":(e.startsWith("/")||(e="/"+e),e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e)}function zr(t,e){if(!t)return{matched:!1,params:{}};if(t==="*")return{matched:!0,params:{},wildcard:!0};const r=we(t),a=we(e),i=r==="/"?[]:r.slice(1).split("/"),n=a==="/"?[]:a.slice(1).split("/"),s={};let l=!1;for(let c=0;c<i.length;c+=1){const u=i[c];if(u==="*"){l=!0;const m=n.slice(c).join("/");return s._=m,{matched:!0,params:s,wildcard:l}}const p=n[c];if(p===void 0)return{matched:!1,params:{}};if(u.startsWith(":")){const m=u.slice(1);if(!m)return{matched:!1,params:{}};s[m]=decodeURIComponent(p);continue}if(u!==p)return{matched:!1,params:{}}}return!l&&n.length>i.length?{matched:!1,params:{}}:l?{matched:!0,params:s,wildcard:!0}:{matched:!0,params:s}}class Rr{constructor(e={}){j(this,"currentPath");j(this,"currentParams",{});j(this,"currentPattern",null);j(this,"enabled",!1);j(this,"hashListener",null);j(this,"listeners",new Set);j(this,"defaultPath");j(this,"settingHash",!1);this.defaultPath=we(e.defaultPath??"/"),this.currentPath=this.defaultPath}start(){if(this.enabled||(this.enabled=!0,typeof window>"u"))return;const e=a=>{if(this.settingHash)return;const i=we(window.location.hash);this.setPath(i,a)},r=()=>e("hashchange");window.addEventListener("hashchange",r),this.hashListener=r,e("init")}stop(){this.enabled&&(this.enabled=!1,typeof window<"u"&&this.hashListener&&window.removeEventListener("hashchange",this.hashListener),this.hashListener=null)}getPath(){return this.currentPath}getParams(){return this.currentParams}getActivePattern(){return this.currentPattern}setActiveMatch(e,r){this.currentPattern=e,fn(this.currentParams,r)||(this.currentParams=r)}navigate(e){const r=we(e);if(r!==this.currentPath){if(this.enabled&&typeof window<"u"){this.settingHash=!0;try{window.location.hash="#"+r}finally{queueMicrotask(()=>{this.settingHash=!1})}this.setPath(r,"navigate");return}this.setPath(r,"navigate")}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}setPath(e,r){const a=we(e);if(a===this.currentPath)return;const i=this.currentPath;this.currentPath=a,this.currentParams={},this.currentPattern=null;for(const n of[...this.listeners])try{n({path:a,previousPath:i,source:r})}catch(s){console.error("[aktion] router listener failed",s)}}}function fn(t,e){const r=Object.keys(t),a=Object.keys(e);if(r.length!==a.length)return!1;for(const i of r)if(t[i]!==e[i])return!1;return!0}const be=(t,e)=>{try{return t()}catch{return e}},Lr=t=>{if(typeof t=="string")return t;if(t===null)return"null";if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}},Er=t=>{if(t===null||t==="")return t;try{return JSON.parse(t)}catch{return t}},_r=t=>({set:(e,r)=>be(()=>{const a=t();return a?(a.setItem(String(e),Lr(r)),!0):!1},!1),get:e=>be(()=>{const r=t();return r?Er(r.getItem(String(e))):null},null),remove:e=>be(()=>{const r=t();return r?(r.removeItem(String(e)),!0):!1},!1),clear:()=>be(()=>{const e=t();return e?(e.clear(),!0):!1},!1)}),hn=()=>typeof globalThis>"u"?null:globalThis.localStorage??null,bn=()=>typeof globalThis>"u"?null:globalThis.sessionStorage??null,Qe=()=>typeof globalThis>"u"?null:globalThis.document??null,vn=t=>{if(t==null)return null;if(t instanceof Date)return t.toUTCString();if(typeof t=="string"){const e=new Date(t);return Number.isNaN(e.getTime())?null:e.toUTCString()}if(typeof t=="number"&&Number.isFinite(t)){const e=new Date;return e.setTime(e.getTime()+t*864e5),e.toUTCString()}return null},Mt=(t={})=>{const e=[],r=vn(t.expires);if(r&&e.push(`expires=${r}`),typeof t.maxAge=="number"&&Number.isFinite(t.maxAge)&&e.push(`max-age=${Math.floor(t.maxAge)}`),e.push(`path=${t.path??"/"}`),t.domain&&e.push(`domain=${t.domain}`),t.secure&&e.push("secure"),t.sameSite){const a=t.sameSite.charAt(0).toUpperCase()+t.sameSite.slice(1).toLowerCase();e.push(`samesite=${a}`)}return e.length===0?"":`; ${e.join("; ")}`},jr=()=>{const t=Qe();if(!t)return{};const e={},r=t.cookie??"";if(!r)return e;for(const a of r.split(";")){const i=a.trim();if(!i)continue;const n=i.indexOf("=");if(n<0){e[decodeURIComponent(i)]="";continue}const s=decodeURIComponent(i.slice(0,n)),l=decodeURIComponent(i.slice(n+1));e[s]=l}return e},yn={set:(t,e,r)=>be(()=>{const a=Qe();if(!a)return!1;const i=encodeURIComponent(String(t)),n=encodeURIComponent(Lr(e));return a.cookie=`${i}=${n}${Mt(r)}`,!0},!1),get:t=>be(()=>{const r=jr()[String(t)];return r===void 0?null:Er(r)},null),remove:(t,e)=>be(()=>{const r=Qe();if(!r)return!1;const a=encodeURIComponent(String(t)),i={...e,expires:new Date(0),maxAge:0};return r.cookie=`${a}=${Mt(i)}`,!0},!1),clear:()=>be(()=>{const t=Qe();if(!t)return!1;const e=jr();for(const r of Object.keys(e)){const a=encodeURIComponent(r);t.cookie=`${a}=${Mt({expires:new Date(0),maxAge:0})}`}return!0},!1)},Ue=_r(hn),xn=_r(bn),Br={set:Ue.set,get:Ue.get,remove:Ue.remove,clear:Ue.clear,local:Ue,session:xn,cookies:yn},wn=["log","error","warn","info","debug"],kn=()=>typeof globalThis>"u"?null:globalThis.console??null,Sn=t=>(...e)=>{const r=kn();if(!r)return;const a=r[t]??r.log;if(typeof a=="function")try{a(...e)}catch{}},Dr=wn.reduce((t,e)=>(t[e]=Sn(e),t),{}),Fr={storage:Br,console:Dr},Or=t=>!!(t&&typeof t=="object"&&t.__kind==="Component"),Ur=t=>!!(t&&typeof t=="object"&&t.__kind==="UserComponent");function Pt(t,e={}){return{state:t,bindings:new Map,expressions:new Map,trackedState:new Set,loopVars:new Map,stateAliases:[],router:e.router,library:e.library,componentDecls:new Map,effectDecls:new Map,actionDecls:new Map,http:e.http,i18n:e.i18n,actionRunner:e.actionRunner,notify:e.notify,jsBlockExecutor:e.jsBlockExecutor}}function qr(t,e){const r={};for(let a=0;a<t.length;a+=1)r[t[a].name]=e[a];return r}function ke(t,e){for(let r=t.stateAliases.length-1;r>=0;r-=1){const i=t.stateAliases[r].get(e);if(i!==void 0)return i}return e}function Hr(t,e){for(const r of t.statements)if(r.kind==="Assignment"&&r.isState){const a=et(r.expression);e.state.declare(r.identifier,a)}for(const r of t.statements){if(r.kind!=="Assignment"||!r.isState||r.expression.kind!=="Call"||r.expression.callee!=="http")continue;const a=M(r.expression,e);e.state.set(r.identifier,a)}for(const r of t.statements){if(r.kind!=="Assignment")continue;const a=r.expression;if(a.kind==="Call"){if((r.identifier==="http"||r.identifier==="$http")&&a.callee==="Http"){M(a,e);continue}if((r.identifier==="i18n"||r.identifier==="$i18n")&&a.callee==="i18n"){M(a,e);continue}}}for(const r of t.statements)Vr(r,e)}function Vr(t,e){switch(t.kind){case"ComponentDeclaration":e.componentDecls.set(t.name,t);return;case"EffectDeclaration":e.effectDecls.set(t.name,t);return;case"ActionDeclaration":e.actionDecls.set(t.name,t);return;case"Emit":case"Cleanup":case"Await":case"Return":case"ExpressionStatement":return;case"Assignment":{if(t.isState)return;e.expressions.set(t.identifier,t.expression);const r=t.expression;e.bindings.set(t.identifier,()=>M(r,e));return}}}function Cn(t,e,r){const a=t[0];if(!a||a.kind!=="Object")return console.error('[aktion] _router_ expects an object literal of route arms (e.g. `_router_({ "/": Home(), default: NotFound() })`).',r),e.router?.setActiveMatch(null,{}),null;const i=Bn(e);let n=null;for(const s of a.properties){if(s.spread)continue;const l=s.key;if(l==="default"||l==="*"){n=s;continue}const c=zr(l,i);if(c.matched)return Wr(l,s.value,c.params,e)}return n?Wr(null,n.value,{},e):(e.router?.setActiveMatch(null,{}),null)}function Wr(t,e,r,a){const i=a.loopVars.get("params"),n=a.loopVars.has("params");a.loopVars.set("params",r);try{const s=M(e,a);return a.router?.setActiveMatch(t,r),s}finally{n?a.loopVars.set("params",i):a.loopVars.delete("params")}}function et(t){switch(t.kind){case"Literal":return t.value;case"Array":{const e=[];for(const r of t.elements)r.kind!=="Spread"&&e.push(et(r));return e}case"Object":{const e={};for(const r of t.properties)r.spread||(e[r.key]=et(r.value));return e}case"Template":return t.expressions.length===0?t.quasis[0]??"":null;default:return null}}function M(t,e){switch(t.kind){case"Literal":return t.value;case"Identifier":{if(e.loopVars.has(t.name))return e.loopVars.get(t.name);if(t.name==="_route_")return e.trackedState.add("route"),e.router?Dn(e.router):{path:"/",params:{},pattern:null,query:{},navigate(){},toString(){return"/"}};const r=e.bindings.get(t.name);if(r)return r();const a=e.actionDecls.get(t.name);return a?Kr(a,e):Object.prototype.hasOwnProperty.call(Fr,t.name)?Fr[t.name]:null}case"StateRef":{const r=ke(e,t.name);return e.trackedState.add(r),e.state.get(r)}case"Array":{const r=[];for(const a of t.elements){if(a.kind==="Spread"){const i=M(a.argument,e);if(Array.isArray(i))for(const n of i)r.push(n);else if(i!=null&&typeof i=="string")for(const n of i)r.push(n);continue}r.push(M(a,e))}return r}case"Object":{const r={};for(const a of t.properties){if(a.spread){const i=M(a.value,e);if(i&&typeof i=="object"&&!Array.isArray(i))for(const[n,s]of Object.entries(i))r[n]=s;continue}r[a.key]=M(a.value,e)}return r}case"Member":{const r=M(t.object,e);if(t.optional&&r==null)return;if(t.computed){const a=M(t.computed,e);return Fn(r,a)}return On(r,t.property??"")}case"Unary":{const r=M(t.argument,e);return t.operator==="!"?!r:-U(r)}case"Binary":return Mn(t.operator,t.left,t.right,e);case"Ternary":{const r=M(t.test,e);return M(r?t.consequent:t.alternate,e)}case"Call":return In(t.callee,t.arguments,e,t.loc);case"MethodCall":return Pn(t,e);case"BuiltinCall":return Ln(t.name,t.arguments,e);case"Template":return An(t.quasis,t.expressions,e);case"Spread":return M(t.argument,e);case"If":return Tn(t,e);case"Match":return Nn(t,e);case"For":return $n(t,e);case"Block":return Re(t,e);case"Lambda":{const r=t.params,a=t.body,i=e.stateAliases.map(s=>new Map(s)),n=new Map(e.loopVars);return(...s)=>{const l=new Map(e.loopVars),c=e.stateAliases.slice();e.loopVars.clear();for(const[p,m]of n)e.loopVars.set(p,m);e.stateAliases.length=0;for(const p of i)e.stateAliases.push(p);const u=[];for(let p=0;p<r.length;p+=1){const m=r[p];let g=s[p];g===void 0&&m.defaultValue&&(g=M(m.defaultValue,e)),u.push({name:m.name,had:e.loopVars.has(m.name),prev:e.loopVars.get(m.name)}),e.loopVars.set(m.name,g)}try{if(a.kind==="JsBlock"){const m=a.body;return e.jsBlockExecutor?e.jsBlockExecutor(m,qr(r,s)):{__kind:"JsBlock",body:m}}const p=M(a,e);if(e.jsBlockExecutor&&p&&typeof p=="object"&&p.__kind==="JsBlock"){const m=p.body;return e.jsBlockExecutor(m,qr(r,s))}return p}finally{for(const p of u)p.had?e.loopVars.set(p.name,p.prev):e.loopVars.delete(p.name);e.loopVars.clear();for(const[p,m]of l)e.loopVars.set(p,m);e.stateAliases.length=0;for(const p of c)e.stateAliases.push(p)}}}case"JsBlock":return{__kind:"JsBlock",body:t.body};case"Bind":return{__kind:"Bind",prop:t.prop,target:M(t.target,e),targetExpr:t.target};case"NamedArg":return M(t.value,e);default:return null}}function Tn(t,e){return M(t.test,e)?Re(t.consequent,e):t.alternate?t.alternate.kind==="Block"?Re(t.alternate,e):M(t.alternate,e):null}function Nn(t,e){const r=M(t.discriminant,e);for(const a of t.arms)if(a.pattern==="_"||M(a.pattern,e)===r)return M(a.body,e);return null}function $n(t,e){const r=M(t.iterable,e);if(!Array.isArray(r))return[];const a=[],i=e.loopVars.has(t.item),n=e.loopVars.get(t.item),s=t.index,l=s?e.loopVars.has(s):!1,c=s?e.loopVars.get(s):void 0,u=t.destructure??[],p=u.map(m=>({name:m,had:e.loopVars.has(m),value:e.loopVars.get(m)}));try{for(let m=0;m<r.length;m+=1){const g=r[m];e.loopVars.set(t.item,g),s&&e.loopVars.set(s,m);for(const f of u){const h=g&&typeof g=="object"?g[f]:void 0;e.loopVars.set(f,h)}a.push(Re(t.body,e))}}finally{i?e.loopVars.set(t.item,n):e.loopVars.delete(t.item),s&&(l?e.loopVars.set(s,c):e.loopVars.delete(s));for(const m of p)m.had?e.loopVars.set(m.name,m.value):e.loopVars.delete(m.name)}return a}function Re(t,e){let r=null;const a=[];for(const i of t.body)switch(i.kind){case"ExpressionStatement":r=M(i.expression,e);continue;case"Assignment":{const n=M(i.expression,e);if(i.isState&&i.identifier){const s=ke(e,i.identifier);e.state.set(s,n)}else e.loopVars.has(i.identifier)||a.push(i.identifier),e.loopVars.set(i.identifier,n);r=n;continue}case"Return":return r=i.argument?M(i.argument,e):void 0,r;case"ComponentDeclaration":case"EffectDeclaration":case"ActionDeclaration":Vr(i,e);continue;case"Emit":case"Cleanup":case"Await":continue}for(const i of a)e.loopVars.delete(i);return r}function An(t,e,r){let a=t[0]??"";for(let i=0;i<e.length;i+=1)a+=tt(M(e[i],r)),a+=t[i+1]??"";return a}function Mn(t,e,r,a){if(t==="&&"){const s=M(e,a);return s&&M(r,a)}if(t==="||"){const s=M(e,a);return s||M(r,a)}if(t==="??"){const s=M(e,a);return s??M(r,a)}const i=M(e,a),n=M(r,a);switch(t){case"+":return typeof i=="string"||typeof n=="string"?tt(i)+tt(n):U(i)+U(n);case"-":return U(i)-U(n);case"*":return U(i)*U(n);case"/":{const s=U(n);return s===0?0:U(i)/s}case"%":{const s=U(n);return s===0?0:U(i)%s}case"==":return i===n;case"!=":return i!==n;case">":return U(i)>U(n);case"<":return U(i)<U(n);case">=":return U(i)>=U(n);case"<=":return U(i)<=U(n);default:return null}}function Pn(t,e){const r=M(t.object,e);if(r==null)return t.optional?void 0:null;const a=r[t.method];if(typeof a!="function")return null;const i=[],n={};let s=!1;for(const c of t.arguments){if(c.kind==="NamedArg"){n[c.name]=M(c.value,e),s=!0;continue}if(c.kind==="Spread"){const u=M(c.argument,e);if(Array.isArray(u))for(const p of u)i.push(p);continue}i.push(M(c,e))}const l=s?[...i,n]:i;try{return a.apply(r,l)}catch(c){return console.error(`[aktion] method "${t.method}" threw`,c),null}}function In(t,e,r,a){if(t==="_router_")return Cn(e,r,a);const i=r.componentDecls.get(t);if(i)return Rn(i,e,r,a);const n=r.actionDecls.get(t);if(n){if(e.length===0)return Kr(n,r);const f=e.map(h=>h.kind==="NamedArg"?M(h.value,r):M(h,r));return Yr(n,f,r)}if(t==="http"){const f=e[0],h=f?f.kind==="NamedArg"?M(f.value,r):M(f,r):{};return Ir(h,r)}const s=r.loopVars.get(t);if(typeof s=="function"){const f=e.map(h=>M(h,r));return s(...f)}const l=r.bindings.get(t);if(l){const f=l();if(typeof f=="function"){const h=e.map(b=>b.kind==="NamedArg"?M(b.value,r):M(b,r));return f(...h)}}if(t==="Theme"){const f=e[0];return{kind:"Theme",tokens:Hn(f?M(f,r):null)}}if(t==="Http"){const f=e[0],h=f?M(f,r):null;if(h&&typeof h=="object"&&!Array.isArray(h)&&r.http){const b=h;r.http.setDefaults({baseUrl:typeof b.baseUrl=="string"?b.baseUrl:void 0,headers:b.headers&&typeof b.headers=="object"&&!Array.isArray(b.headers)?Object.fromEntries(Object.entries(b.headers).map(([v,y])=>[v,String(y??"")])):void 0,timeoutMs:typeof b.timeout=="number"?b.timeout:void 0,retry:b.retry&&typeof b.retry=="object"&&!Array.isArray(b.retry)?{count:Number(b.retry.count??0)||0,backoff:b.retry.backoff==="linear"?"linear":"exponential"}:void 0,credentials:b.credentials==="omit"||b.credentials==="same-origin"||b.credentials==="include"?b.credentials:void 0})}return{__kind:"Http",config:h}}if(t==="i18n"){const f=e[0],h=f?M(f,r):null;if(h&&typeof h=="object"&&!Array.isArray(h)&&r.i18n){const b=h;r.i18n.configure({locale:typeof b.locale=="string"?b.locale:"en",messages:b.messages&&typeof b.messages=="object"&&!Array.isArray(b.messages)?b.messages:{},fallback:typeof b.fallback=="string"?b.fallback:"en",fallbackMessages:b.fallbackMessages&&typeof b.fallbackMessages=="object"&&!Array.isArray(b.fallbackMessages)?b.fallbackMessages:void 0})}return{__kind:"I18n",config:h}}if(r.library&&!Ie(r.library,t))return Ie(r.library,"Skeleton")?{__kind:"Component",name:"Skeleton",args:[],argMeta:[],source:a}:null;let c;const u=[];for(const f of e){if(f.kind==="NamedArg"&&f.name==="key"){c=M(f.value,r);continue}u.push(f)}const{args:p,argMeta:m}=zn(r,t,u);return{__kind:"Component",name:t,args:p,argMeta:m,explicitKey:c,source:a}}function zn(t,e,r){const a=t.library?Ie(t.library,e):void 0;if(!a){const m=r.map(f=>f.kind==="NamedArg"?M(f.value,t):f.kind==="Bind"?M(f.target,t):M(f,t)),g=r.map(f=>f.kind==="StateRef"?{stateRef:f.name}:f.kind==="Bind"&&f.target.kind==="StateRef"?{stateRef:f.target.name}:f.kind==="NamedArg"&&f.value.kind==="StateRef"?{stateRef:f.value.name}:{});return{args:m,argMeta:g}}const i=new Map;a.props.forEach((m,g)=>{if(i.set(m.name,g),m.aliases)for(const f of m.aliases)i.has(f)||i.set(f,g)});const n=Tt(a),s=a.props.map(()=>({value:void 0,meta:{},filled:!1})),l=[];for(const m of r){if(m.kind==="NamedArg"){const g=i.get(m.name);if(g===void 0)continue;const f=M(m.value,t);s[g].value=f,s[g].filled=!0,m.value.kind==="StateRef"&&(s[g].meta={stateRef:m.value.name});continue}if(m.kind==="Bind"){const g=i.get(m.prop);if(g===void 0)continue;const f=M(m.target,t);s[g].value=f,s[g].filled=!0,m.target.kind==="StateRef"&&(s[g].meta={stateRef:m.target.name});continue}l.push({expr:m,value:M(m,t)})}if(l.length>0&&n>=0&&!s[n].filled){const{expr:m,value:g}=l.shift();s[n].value=g,s[n].filled=!0,m.kind==="StateRef"&&(s[n].meta={stateRef:m.name})}let c=0;for(const{expr:m,value:g}of l){for(;c<a.props.length&&s[c].filled;)c+=1;if(c>=a.props.length)break;s[c].value=g,s[c].filled=!0,m.kind==="StateRef"&&(s[c].meta={stateRef:m.name}),c+=1}const u=s.map(m=>m.value),p=s.map(m=>m.meta);for(;u.length>0&&u[u.length-1]===void 0;)u.pop(),p.pop();return{args:u,argMeta:p}}function Rn(t,e,r,a){const i=[],n={};let s;for(const m of e)m.kind==="NamedArg"?m.name==="key"?s=m.value:n[m.name]=m.value:i.push(m);const l=i.map(m=>m.kind==="Spread"?M(m.argument,r):M(m,r)),c=[];for(let m=0;m<i.length;m+=1){const g=i[m],f=l[m];if(g.kind==="Spread"&&Array.isArray(f))for(const h of f)c.push(h);else c.push(f)}const u={};for(const[m,g]of Object.entries(n))u[m]=M(g,r);const p=s?M(s,r):void 0;return{__kind:"UserComponent",decl:t,positional:c,named:u,explicitKey:p,source:a}}function Gr(t,e,r){const{decl:a,positional:i,named:n}=t,s=[];for(let c=0;c<a.params.length;c+=1){const u=a.params[c];let p;n[u.name]!==void 0?p=n[u.name]:i[c]!==void 0?p=i[c]:u.defaultValue?p=M(u.defaultValue,e):p=void 0,s.push({name:u.name,had:e.loopVars.has(u.name),prev:e.loopVars.get(u.name)}),e.loopVars.set(u.name,p)}if(i.length>a.params.length){const c=i.slice(a.params.length),u=c.length===1?c[0]:c;s.push({name:"children",had:e.loopVars.has("children"),prev:e.loopVars.get("children")}),e.loopVars.set("children",u)}if(a.slots.length>0){const c={};for(const u of a.slots)n[u]!==void 0&&(c[u]=n[u]);s.push({name:"slots",had:e.loopVars.has("slots"),prev:e.loopVars.get("slots")}),e.loopVars.set("slots",c)}const l=new Map;for(const c of a.body.body)if(c.kind==="Assignment"&&c.isState){const u=`${r}:${c.identifier}`;l.set(c.identifier,u),e.state.declare(u,et(c.expression))}e.stateAliases.push(l);try{return Re(a.body,e)}finally{e.stateAliases.pop();for(const c of s)c.had?e.loopVars.set(c.name,c.prev):e.loopVars.delete(c.name)}}function Kr(t,e){const r=e.stateAliases.map(a=>new Map(a));return async(...a)=>{const i=e.stateAliases.slice();e.stateAliases.length=0;for(const n of r)e.stateAliases.push(n);try{return await Yr(t,a,e)}finally{e.stateAliases.length=0;for(const n of i)e.stateAliases.push(n)}}}function Yr(t,e,r){if(!r.actionRunner){const a=[];for(let i=0;i<t.params.length;i+=1){const n=t.params[i];a.push({name:n.name,had:r.loopVars.has(n.name),prev:r.loopVars.get(n.name)}),r.loopVars.set(n.name,e[i])}try{return Re(t.body,r)}finally{for(const i of a)i.had?r.loopVars.set(i.name,i.prev):r.loopVars.delete(i.name)}}return r.actionRunner.run(t,e,r)}function Ln(t,e,r){if(t==="__rui_assign__")return En(e,r);if(t==="__rui_postfix__")return _n(e,r);if(t==="Each"){const n=e[0],s=e[1],l=e[2];if(!n||!s||!l)return[];const c=M(n,r),u=Array.isArray(c)?c:[],p=s.kind==="Literal"?String(s.value??""):"",m=jn(p),g=[],f=m.bindings.map(h=>({name:h,had:r.loopVars.has(h),prev:r.loopVars.get(h)}));try{for(const h of u){m.scalarName&&r.loopVars.set(m.scalarName,h);for(const b of m.fields)h&&typeof h=="object"?r.loopVars.set(b,h[b]):r.loopVars.set(b,void 0);g.push(M(l,r))}}finally{for(const h of f)h.had?r.loopVars.set(h.name,h.prev):r.loopVars.delete(h.name)}return g}if(t==="If"){const n=e[0],s=e[1],l=e[2];return n?M(n,r)?s?M(s,r):null:l?M(l,r):null:null}if(t==="Switch"){const n=e[0],s=e[1],l=e[2];if(!n||!s)return null;const c=M(n,r),u=tt(c);if(s.kind==="Object"){for(const p of s.properties)if(!p.spread&&p.key===u)return M(p.value,r)}return l?M(l,r):null}if(t==="T"||t==="t"){const n=e[0],s=e[1],l=n?String(M(n,r)??""):"";if(!r.i18n)return l;let c;if(s){const u=M(s,r);u&&typeof u=="object"&&!Array.isArray(u)&&(c=u)}return r.i18n.t(l,c)}if(t==="Locale")return r.i18n?.getLocale()??"";const a=At[t];if(!a)return null;const i=e.map(n=>M(n,r));return a(i)}function Jr(t,e,r){switch(t){case"=":return r;case"+=":return typeof e=="string"||typeof r=="string"?`${e??""}${r??""}`:U(e)+U(r);case"-=":return U(e)-U(r);case"*=":return U(e)*U(r);case"/=":{const a=U(r);return a===0?0:U(e)/a}case"??=":return e??r;default:return r}}function En(t,e){const[r,a,i]=t;if(!r||!a)return null;const n=i&&i.kind==="Literal"?String(i.value??"="):"=",s=M(a,e);if(r.kind==="StateRef"){const l=ke(e,r.name),c=e.state.get(l),u=Jr(n,c,s);return e.state.set(l,u),u}if(r.kind==="Identifier"){const l=e.loopVars.get(r.name),c=Jr(n,l,s);return e.loopVars.set(r.name,c),c}return s}function _n(t,e){const[r,a]=t;if(!r)return null;const n=(a&&a.kind==="Literal"?String(a.value??"++"):"++")==="--"?-1:1;if(r.kind==="StateRef"){const s=ke(e,r.name),l=U(e.state.get(s))+n;return e.state.set(s,l),l}if(r.kind==="Identifier"){const s=U(e.loopVars.get(r.name))+n;return e.loopVars.set(r.name,s),s}return null}function jn(t){const e=t.trim();if(!e)return{scalarName:"",fields:[],bindings:[]};if(e.startsWith("{")&&e.endsWith("}")){const a=e.slice(1,-1).split(",").map(i=>i.trim()).filter(Boolean);return{scalarName:"",fields:a,bindings:a}}const r=e.indexOf("{");if(r>0){const i=e.slice(0,r).trim().replace(/,\s*$/,"").trim(),n=e.indexOf("}",r),s=n>r?e.slice(r+1,n).split(",").map(l=>l.trim()).filter(Boolean):[];return{scalarName:i,fields:s,bindings:i?[i,...s]:s}}return{scalarName:e,fields:[],bindings:[e]}}function Bn(t){if(t.router)return t.router.getPath();if(t.state.has("route")){t.trackedState.add("route");const e=t.state.get("route");if(typeof e=="string"&&e)return e;if(e&&typeof e=="object"&&"path"in e){const r=e.path;if(typeof r=="string"&&r)return r}}return"/"}function Dn(t){const e=t.getPath(),r={...t.getParams()},a=t.getActivePattern(),i={};if(typeof globalThis<"u"&&globalThis.location){const n=globalThis.location?.search??"";if(n){const s=new URLSearchParams(n.startsWith("?")?n.slice(1):n);for(const[l,c]of s)i[l]=c}}return{path:e,params:r,pattern:a,query:i,navigate(n){typeof n!="string"||!n||t.navigate(n)},toString(){return e}}}function Fn(t,e){if(t!=null){if(Array.isArray(t)){const r=Xr(e,t.length);return r===null?void 0:t[r]}if(typeof t=="string"){const r=Xr(e,t.length);return r===null?void 0:t[r]}if(typeof t=="object")return t[String(e??"")]}}function Xr(t,e){let r;if(typeof t=="number")r=t;else if(typeof t=="string"&&t.trim()!==""&&!Number.isNaN(Number(t)))r=Number(t);else return null;return r<0&&(r=e+r),r<0||r>=e?null:r}function On(t,e){if(t!=null){if(Array.isArray(t)){switch(e){case"length":return t.length;case"first":return t[0]??null;case"last":return t.length===0?null:t[t.length-1]}return t.map(r=>{if(r&&typeof r=="object")return r[e]})}if(typeof t=="string"&&e==="length")return t.length;if(typeof t=="object")return t[e]}}function U(t){if(typeof t=="number")return t;if(typeof t=="string"){if(t.trim()==="")return 0;const e=Number(t);return Number.isNaN(e)?0:e}return typeof t=="boolean"&&t?1:0}const Un=new Set(["colors","radius","font","motion","elevation"]),qn=new Set(["name","direction"]);function Hn(t){const e={};if(!t||typeof t!="object"||Array.isArray(t))return e;const r=t;for(const[a,i]of Object.entries(r))if(i!=null&&!qn.has(a)&&Un.has(a)&&i&&typeof i=="object"&&!Array.isArray(i)){const n=a==="colors"?"color":a;for(const[s,l]of Object.entries(i)){if(l==null)continue;const c=n+Vn(s);e[c]=Wn(l)}}return e}function Vn(t){return t?t.charAt(0).toUpperCase()+t.slice(1):""}function Wn(t){return typeof t=="string"?t:typeof t=="number"?String(t):""}function tt(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);if(typeof t=="object"&&t!==null){const e=t.toString;if(typeof e=="function"&&e!==Object.prototype.toString){const r=e.call(t);if(typeof r=="string")return r}}try{return JSON.stringify(t)}catch{return String(t)}}class Zr{constructor(){j(this,"locale","en");j(this,"fallback","en");j(this,"messages",{});j(this,"fallbackMessages",{})}configure(e){this.locale=e.locale||"en",this.fallback=e.fallback??"en",this.messages=Qr(e.messages),this.fallbackMessages=Qr(e.fallbackMessages??{})}getLocale(){return this.locale}getFallback(){return this.fallback}t(e,r){const a=ea(this.messages,e)??ea(this.fallbackMessages,e)??e;return typeof a!="string"?e:Gn(a,r)}}function Qr(t){return!t||typeof t!="object"||Array.isArray(t)?{}:t}function ea(t,e){if(!e)return;if(e.indexOf(".")===-1)return t[e];let r=t;for(const a of e.split(".")){if(!r||typeof r!="object")return;r=r[a]}return r}function Gn(t,e){return e?t.replace(/\$\{([^}]+)\}/g,(r,a)=>{const i=e[a.trim()];return i==null?"":String(i)}):t}class ta{constructor(e){j(this,"mounted",new Map);j(this,"errors",[]);this.options=e}getErrors(){return this.errors}syncEffects(e,r){this.errors=[];const a=new Set(e.map(i=>i.name));for(const i of[...this.mounted.keys()])a.has(i)||this.unmount(i);for(const i of e)this.mounted.has(i.name)||this.mount(i,r)}reset(){for(const e of[...this.mounted.keys()])this.unmount(e);this.errors=[]}mount(e,r){const a={decl:e,cleanups:[],intervals:[],unsubscribers:[],ctxRef:r};this.mounted.set(e.name,a);const n=Kn(()=>{for(const u of a.cleanups.splice(0))try{u()}catch(p){aa(e.name,p)}try{ra(e,r(),a,this.options)}catch(u){console.error(`[aktion] effect "${e.name}" failed`,u)}finally{this.options.notify()}},e.rateLimit,a);let s=!1,l=!1,c=!1;for(const u of e.triggers)switch(u.kind){case"lifecycle":u.name==="mount"&&(s=!0),u.name==="unmount"&&(l=!0);break;case"every":{c=!0;const p=setInterval(n,u.intervalMs);a.intervals.push(p);break}case"state":{const p=u.name,m=this.options.state.subscribe(g=>{g.has(p)&&n()});a.unsubscribers.push(m);break}}(e.triggers.length===0||s||!c&&!l&&e.triggers.every(u=>u.kind==="state"))&&n()}unmount(e){const r=this.mounted.get(e);if(!r)return;this.mounted.delete(e);for(const i of r.intervals)clearInterval(i);for(const i of r.unsubscribers)try{i()}catch{}for(const i of r.cleanups)try{i()}catch(n){aa(e,n)}if(r.decl.triggers.some(i=>i.kind==="lifecycle"&&i.name==="unmount"))try{ra(r.decl,r.ctxRef(),r,this.options)}catch(i){console.error(`[aktion] effect "${e}" unmount body threw`,i)}}}function Kn(t,e,r){if(!e||e.ms<=0)return t;if(e.kind==="debounce"){let n=null;const s=()=>{n&&(clearTimeout(n),n=null)};return r.cleanups.push(s),()=>{n&&clearTimeout(n),n=setTimeout(()=>{n=null,t()},e.ms)}}let a=0,i=null;return r.cleanups.push(()=>{i&&(clearTimeout(i),i=null)}),()=>{const n=Date.now(),s=n-a;s>=e.ms?(a=n,t()):i||(i=setTimeout(()=>{i=null,a=Date.now(),t()},e.ms-s))}}function ra(t,e,r,a){for(const i of t.body.body)Yn(i,e,r,a)}function Yn(t,e,r,a){switch(t.kind){case"ExpressionStatement":{const i=t.expression;if(i.kind==="Call"&&i.callee==="cleanup"){const n=i.arguments[0]?M(i.arguments[0],e):null;typeof n=="function"&&r.cleanups.push(n);return}return i.kind==="JsBlock"?It(i.body,r.decl.name,e,a,r):M(i,e)}case"Assignment":{const i=M(t.expression,e);if(t.identifier&&t.identifier!==""){const n=ke(e,t.identifier);e.state.set(n,i)}return i}case"Cleanup":{const i=t.callback?M(t.callback,e):null;typeof i=="function"&&r.cleanups.push(i);return}case"Emit":{const i=M(t.detail,e);a.onEmit?.(t.eventName,i);return}default:return}}function aa(t,e){console.error(`[aktion] cleanup for effect "${t}" threw`,e)}function ia(t){return(e,r={})=>It(e,"<inline>",void 0,t,void 0,r)}function It(t,e,r,a,i,n={}){const s={state:{get:l=>a.state.get(l),set:(l,c)=>a.state.set(l,c)},cleanup:l=>{typeof l=="function"&&i&&i.cleanups.push(l)},host:a.host,tools:a.tools??{},args:n};try{const c=new Function("ctx",`return (async () => { ${t}
19
- })()`)(s);return c&&typeof c.then=="function"&&c.catch(u=>{console.error(`[aktion] js{} body in "${e}" rejected`,u)}),c}catch(l){console.error(`[aktion] js{} body in "${e}" threw`,l);return}}class na{constructor(e){this.options=e}async run(e,r,a){const i=[],n={};for(let l=0;l<e.params.length;l+=1){const c=e.params[l],u=r[l];i.push({name:c.name,had:a.loopVars.has(c.name),prev:a.loopVars.get(c.name)}),a.loopVars.set(c.name,u),n[c.name]=u}const s=e.optimistic?Jn(this.options.state):null;try{let l;for(const c of e.body.body)l=await this.runStatement(c,a,e,n);return this.options.notify(),l}catch(l){throw s&&(Xn(this.options.state,s),this.options.notify()),console.error(`[aktion] action "${e.name}" failed`,l),l}finally{for(const l of i)l.had?a.loopVars.set(l.name,l.prev):a.loopVars.delete(l.name)}}async runStatement(e,r,a,i){switch(e.kind){case"ExpressionStatement":{const n=e.expression;if(n.kind==="JsBlock"){const l=It(n.body,a.name,r,this.options,void 0,i);return await qe(l)}const s=M(n,r);return await qe(s)}case"Await":{const n=M(e.argument,r);return await qe(n)}case"Assignment":{const n=await qe(M(e.expression,r));if(e.identifier){const s=ke(r,e.identifier);this.options.state.set(s,n)}return n}case"Return":return e.argument?await qe(M(e.argument,r)):void 0;case"Emit":{const n=M(e.detail,r);this.options.onEmit?.(e.eventName,n);return}default:return}}}async function qe(t){return t&&typeof t.then=="function"?await t:t}function Jn(t){const e=new Map;for(const[r,a]of t.entries())e.set(r,a);return e}function Xn(t,e){for(const[r,a]of e)t.set(r,a)}const Zn="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css",oa="6.7.2",sa="data-rui-font-awesome",Qn=new Set(["solid","regular","brands"]),la="solid";function eo(t){typeof document<"u"&&ca(document.head,document),ca(t,t.ownerDocument??document)}function ca(t,e){if(to()||t.querySelector(`link[${sa}="${oa}"]`))return;const a=e.createElement("link");a.rel="stylesheet",a.href=Zn,a.setAttribute(sa,oa);try{t.appendChild(a)}catch{}}function to(){return typeof globalThis.happyDOM<"u"}function zt(t){if(typeof t!="string")return[];const e=ao(t).trim();if(!e)return[];if(!no(e))return[];const[r,a]=io(e);return a?[`fa-${r}`,`fa-${a}`]:[]}const ro=/[\uFE0E\uFE0F\u200D\u200C\uFEFF]/g;function ao(t){return t.replace(ro,"")}function io(t){const e=t.indexOf(":");if(e===-1)return[la,t];const r=t.slice(0,e).trim().toLowerCase(),a=t.slice(e+1).trim();return Qn.has(r)?[r,a]:[la,a||t]}function no(t){return/^[a-zA-Z0-9:_-]+$/.test(t)}const oo=["xs","sm","md","lg","xl"];function o(t,e,r){const a=document.createElement(t);if(e)for(const[i,n]of Object.entries(e))n==null||n===!1||(i==="class"?a.setAttribute("class",String(n)):i==="html"?a.innerHTML=String(n):n===!0?a.setAttribute(i,""):a.setAttribute(i,String(n)));if(r)for(const i of r)i!=null&&a.append(typeof i=="string"?document.createTextNode(i):i);return a}function k(t){return Array.isArray(t)?t:t==null?[]:[t]}function d(t,e=""){return t==null?e:typeof t=="string"?t:String(t)}function C(t,e=!1){return typeof t=="boolean"?t:t==="true"?!0:t==="false"?!1:t==null?e:!!t}function P(t,e=0){if(typeof t=="number")return t;if(typeof t=="string"&&t.trim()!==""){const r=Number(t);if(!Number.isNaN(r))return r}return e}const Le=["base","sm","md","lg","xl"];function se(t){if(t==null||typeof t!="object"||Array.isArray(t))return{kind:"single",value:t??null};const e=Object.entries(t),r={};let a=!1;for(const[i,n]of e)Le.includes(i)&&(r[i]=n,a=!0);return a?{kind:"responsive",values:r}:{kind:"single",value:t}}const so=/["'\\\n\r<>;{}]/g;function lo(t){return t?t.replace(so,"").trim():""}const co=/^[a-zA-Z0-9.%+\-*/\s(),]+$/;function ee(t,e){const r=(d(t)??"").trim();return!r||r.length>64||!co.test(r)?e:r}const uo=new Set(["http","https","mailto","tel"]);function rt(t,e="#"){const r=d(t).trim();if(!r)return e;const a=r.replace(/[\u0000-\u001F\u007F]/g,"");if(!a||a.startsWith("//"))return e;if(a.startsWith("#")||a.startsWith("/")||a.startsWith("?")||a.startsWith("."))return a;const i=/^([a-zA-Z][a-zA-Z0-9+.\-]*):/.exec(a);if(!i)return a;const n=i[1].toLowerCase();return uo.has(n)?a:e}const po=new Set(["http","https","data","blob"]);function re(t){const e=d(t).trim();if(!e)return"";const r=e.replace(/[\u0000-\u001F\u007F]/g,"");if(!r||r.startsWith("//"))return"";if(r.startsWith("/")||r.startsWith(".")||r.startsWith("?")||r.startsWith("#"))return r;const a=/^([a-zA-Z][a-zA-Z0-9+.\-]*):/.exec(r);if(!a)return r;const i=a[1].toLowerCase();return!po.has(i)||i==="data"&&!/^data:image\//i.test(r)?"":r}function L(t,e={}){const r=d(t);if(!r)return null;const a=zt(r),i=["rui-icon",e.className].filter(Boolean).join(" ");return a.length===0?o("span",{class:i,"data-icon-size":e.size??null},[r]):o("i",{class:`${i} ${a.join(" ")}`,"data-icon-size":e.size??null,"aria-hidden":"true"})}const He=12,mo={start:"flex-start",center:"center",end:"flex-end",stretch:"stretch"},go={start:"flex-start",center:"center",end:"flex-end",between:"space-between",around:"space-around",evenly:"space-evenly"};function fo(t){return mo[t]??"stretch"}function ho(t){return go[t]??"flex-start"}function ua(t,e){return e?t==="row"?"row-reverse":t==="column"?"column-reverse":t.endsWith("-reverse")?t:`${t}-reverse`:t}function Se(t,e,r){for(const a of Le){const i=e.values[a];i&&t.push(`${r}-${a}:var(--rui-spacing-${i}, ${i})`)}}function bo(t,e,r,a){for(const i of Le){const n=e.values[i];n&&t.push(`${r}-${i}:${a(String(n))}`)}}function da(t,e,r,a){const i=se(t);if(i.kind==="single"){const n=i.value?String(i.value):a.defaultToken;r[a.attrName]=n;return}r[a.attrName]="responsive",r[a.responsiveFlag]="true",bo(e,i,a.cssVarPrefix,a.mapper)}function vo(t,e){return!!(t&&typeof t=="object"&&t.__kind==="Component"&&t.name===e)}function yo(t){const e=se(t.direction);return e.kind==="single"?e.value?String(e.value):"column":e.values.base?String(e.values.base):"column"}const xo={name:"StackItem",description:"Wraps a single child in a flex item with explicit grow/shrink/basis, alignment, and order. Use inside `Stack` when the default row flex growth would stretch toolbars, chips, or asymmetric layouts.",props:[{name:"child",type:"Node",description:"Child node to wrap"},{name:"grow",type:"number",optional:!0,description:"flex-grow (0 or 1 typical)"},{name:"shrink",type:"number",optional:!0,description:"flex-shrink (0 or 1 typical)"},{name:"basis",type:"string",optional:!0,description:"flex-basis (`auto`, `0`, or CSS length)"},{name:"alignSelf",type:"string",optional:!0,enum:["start","center","end","stretch"],description:"Per-item cross-axis alignment"},{name:"order",type:"number",optional:!0,description:"Visual order override"},{name:"minWidth",type:"string",optional:!0,description:"CSS min-width"},{name:"maxWidth",type:"string",optional:!0,description:"CSS max-width"}],render:(t,e,r)=>{const a={class:"rui-stack-item"},i=[];e.grow!==void 0&&e.grow!==null&&(a["data-grow"]=String(P(e.grow,0))),e.shrink!==void 0&&e.shrink!==null&&(a["data-shrink"]=String(P(e.shrink,1)));const n=d(e.basis);n==="auto"||n==="0"?a["data-basis"]=n:n&&i.push(`flex-basis:${ee(n,n)}`);const s=d(e.alignSelf);if(s&&(a["data-align-self"]=s),e.order!==void 0&&e.order!==null){const p=P(e.order,0);a["data-order"]=String(p),i.push(`order:${p}`)}const l=d(e.minWidth);l&&i.push(`min-width:${ee(l,l)}`);const c=d(e.maxWidth);c&&i.push(`max-width:${ee(c,c)}`),i.length>0&&(a.style=i.join(";"));const u=o("div",a);return u.append(r.renderNode(e.child)),u}},wo={name:"Stack",description:'Flex container that arranges children in a row or column. `direction`, `gap`, `align`, `justify`, and `padding` accept either a single value OR a responsive map like `{sm: "column", md: "row"}`. Row stacks grow children uniformly by default (`uniform=true`); set `uniform=false` or wrap children in `StackItem` for toolbars and asymmetric rows. Use `reverse` for chat-style column-reverse timelines.',props:[{name:"children",type:"Node[]",description:"Child components to stack"},{name:"direction",type:"string | object",optional:!0,enum:["column","row"],description:"Layout direction (default column). May be a responsive map."},{name:"gap",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Spacing between children. May be a responsive map."},{name:"align",type:"string | object",optional:!0,enum:["start","center","end","stretch"],description:"Cross-axis alignment. May be a responsive map."},{name:"justify",type:"string | object",optional:!0,enum:["start","center","end","between","around","evenly"],description:"Main-axis alignment. May be a responsive map."},{name:"alignContent",type:"string",optional:!0,enum:["start","center","end","between","around","stretch"],description:"Multi-line wrap alignment"},{name:"wrap",type:"boolean",optional:!0,description:"Allow wrapping"},{name:"reverse",type:"boolean",optional:!0,description:"Reverse main-axis order (column-reverse / row-reverse)"},{name:"uniform",type:"boolean",optional:!0,description:"Row children share space equally (default true for row stacks)"},{name:"inline",type:"boolean",optional:!0,description:"Use inline-flex instead of flex"},{name:"padding",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Inner padding token. May be a responsive map."}],render:(t,e,r)=>{const a=se(e.direction),i=se(e.gap),n=se(e.padding),s=C(e.reverse),c=yo(e)==="row",u=e.uniform===void 0?c:C(e.uniform,c),p={class:"rui-stack","data-wrap":C(e.wrap)?"true":null,"data-reverse":s?"true":null,"data-uniform":u?"true":"false","data-inline":C(e.inline)?"true":null},m=[];if(a.kind==="single"){const h=a.value?String(a.value):"column";p["data-direction"]=ua(h,s)}else{p["data-direction"]="responsive",p["data-responsive-dir"]="true";for(const h of Le){const b=a.values[h];b&&m.push(`--rui-stack-dir-${h}:${ua(String(b),s)}`)}}i.kind==="single"?p["data-gap"]=i.value?String(i.value):"m":(p["data-gap"]="responsive",p["data-responsive-gap"]="true",Se(m,i,"--rui-stack-gap")),da(e.align,m,p,{attrName:"data-align",responsiveFlag:"data-responsive-align",cssVarPrefix:"--rui-stack-align",defaultToken:"stretch",mapper:fo}),da(e.justify,m,p,{attrName:"data-justify",responsiveFlag:"data-responsive-justify",cssVarPrefix:"--rui-stack-justify",defaultToken:"start",mapper:ho});const g=d(e.alignContent);if(g&&(p["data-align-content"]=g),n.kind==="single"){const h=n.value?String(n.value):null;h&&(p["data-padding"]=h)}else p["data-padding"]="responsive",p["data-responsive-padding"]="true",Se(m,n,"--rui-stack-padding");m.length>0&&(p.style=m.join(";"));const f=o("div",p);for(const h of k(e.children))f.append(r.renderNode(h));return f}},ko={name:"Card",description:"Vertical card container.",props:[{name:"children",type:"Node[]",description:"Card contents"},{name:"variant",type:"string",optional:!0,enum:["default","outlined","elevated"]}],render:(t,e,r)=>{const a=o("div",{class:"rui-card","data-variant":d(e.variant,"default")});for(const i of k(e.children))a.append(r.renderNode(i));return a}},So={name:"CardHeader",description:"Card header with title and optional subtitle.",props:[{name:"title",type:"string"},{name:"subtitle",type:"string",optional:!0}],render:(t,e)=>{const r=o("header",{class:"rui-card-header"});r.append(o("h3",{class:"rui-card-title"},[d(e.title)]));const a=d(e.subtitle);return a&&r.append(o("p",{class:"rui-card-subtitle"},[a])),r}},Co={name:"CardFooter",description:"Card footer for actions.",props:[{name:"children",type:"Node[]"}],render:(t,e,r)=>{const a=o("footer",{class:"rui-card-footer"});for(const i of k(e.children))a.append(r.renderNode(i));return a}},To={name:"Separator",description:"Visual divider between content sections. Supports horizontal or vertical orientation, and an optional center `label` (lifted from the legacy `Divider`). Use `decorative=false` to expose the separator to assistive tech.",props:[{name:"orientation",type:"string",optional:!0,enum:["horizontal","vertical"]},{name:"label",type:"string",optional:!0,description:"Optional label rendered in the middle (horizontal only)"},{name:"decorative",type:"boolean",optional:!0,description:"Hides the separator from assistive tech when true (default)"}],render:(t,e)=>{const r=d(e.orientation,"horizontal"),a=C(e.decorative,!0),i=d(e.label);return i&&r==="horizontal"?o("div",{class:"rui-separator rui-separator-with-label","data-orientation":r,role:a?"presentation":"separator","aria-orientation":a?null:r},[o("span",{class:"rui-separator-line"}),o("span",{class:"rui-separator-label"},[i]),o("span",{class:"rui-separator-line"})]):o("div",{class:"rui-separator","data-orientation":r,role:a?"presentation":"separator","aria-orientation":a?null:r})}},pa=(t,e,r=!1)=>{const a=o("li",{class:"rui-steps-item","data-active":r?"true":"false"});return a.append(o("div",{class:"rui-steps-title"},[t])),e&&a.append(o("div",{class:"rui-steps-details"},[e])),a},No={name:"Steps",description:"Numbered step-by-step guide. Pass items as `{title, details?, active?}` objects. Use `active` to mark the current step in a multi-step flow.",props:[{name:"items",type:"object[]"}],render:(t,e,r)=>{const a=o("ol",{class:"rui-steps"});for(const i of k(e.items)){if(i&&typeof i=="object"&&i.__kind==="Component"){a.append(r.renderNode(i));continue}if(i&&typeof i=="object"){const n=i;a.append(pa(d(n.title),d(n.details),C(n.active)));continue}a.append(pa(d(i),""))}return a}},$o={name:"TabItem",description:"Single tab definition (used inside Tabs). Add `badge` for a count chip in the tab trigger, and `icon` for a leading Font Awesome icon.",props:[{name:"value",type:"string",description:"Stable identifier for the tab"},{name:"label",type:"string",description:"Display label"},{name:"children",type:"Node[]",description:"Tab content"},{name:"badge",type:"string",optional:!0,description:"Trailing chip rendered in the tab trigger (count / status)"},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name shown before the label"}],render:(t,e,r)=>{const a=o("div",{class:"rui-tab-content",role:"tabpanel","data-value":d(e.value),"data-active":"false"});for(const i of k(e.children))a.append(r.renderNode(i));return a}},Ao={name:"Tabs",description:'Tabbed container. Children must be TabItem components. Supports `orientation="vertical"` for sidebar-style tabs and built-in keyboard navigation (←/→ or ↑/↓, Home, End).',props:[{name:"items",type:"TabItem[]",description:"Tab definitions"},{name:"defaultValue",type:"string",optional:!0,description:"Initially active tab value"},{name:"orientation",type:"string",optional:!0,enum:["horizontal","vertical"],description:"Layout direction (default `horizontal`)"}],render:(t,e,r)=>{const a=k(e.items),i=d(e.orientation,"horizontal"),n=o("div",{class:"rui-tabs","data-orientation":i}),s=o("div",{class:"rui-tab-list",role:"tablist","aria-orientation":i}),l=o("div",{class:"rui-tab-panels"});let c=d(e.defaultValue);if(!c&&a.length>0){const g=a[0];c=d(g?.args?.[0],"tab-0")}const u=r.useInstanceState("activeTab",c);d(e.defaultValue)&&d(e.defaultValue)!==c&&u.set(d(e.defaultValue)),new Set(a.map((g,f)=>d(g.args?.[0],`tab-${f}`))).has(u.get())||u.set(c);const m=(g,f)=>{u.set(g);const h=f.closest(".rui-tabs");h&&(h.querySelectorAll(".rui-tab-trigger").forEach(b=>{const v=b.getAttribute("data-value")===g;b.setAttribute("aria-selected",v?"true":"false"),b.tabIndex=v?0:-1}),h.querySelectorAll(".rui-tab-content").forEach(b=>{b.setAttribute("data-active",b.getAttribute("data-value")===g?"true":"false")}))};return a.forEach((g,f)=>{const h=g,b=d(h.args?.[0],`tab-${f}`),v=d(h.args?.[1],`Tab ${f+1}`),y=d(h.args?.[3]),x=d(h.args?.[4]),w=b===u.get(),T=o("button",{class:"rui-tab-trigger",role:"tab",type:"button","data-value":b,"aria-selected":w?"true":"false",tabindex:w?"0":"-1"}),S=x?Mo(x):null;S&&T.append(S),T.append(o("span",{class:"rui-tab-trigger-label"},[v])),y&&T.append(o("span",{class:"rui-tab-trigger-badge"},[y])),T.onclick=N=>{const A=N.currentTarget??N.target;m(b,A)},T.onkeydown=N=>{const A=N,z=i!=="vertical",R=z?A.key==="ArrowRight":A.key==="ArrowDown",_=z?A.key==="ArrowLeft":A.key==="ArrowUp";if(!R&&!_&&A.key!=="Home"&&A.key!=="End")return;A.preventDefault();const Q=A.currentTarget??A.target,B=Q.closest(".rui-tab-list");if(!B)return;const O=Array.from(B.querySelectorAll(".rui-tab-trigger"));if(O.length===0)return;const J=O.indexOf(Q);let X=J;A.key==="Home"?X=0:A.key==="End"?X=O.length-1:R?X=(J+1)%O.length:_&&(X=(J-1+O.length)%O.length);const ue=O[X];if(!ue)return;ue.focus();const me=ue.getAttribute("data-value")??"";me&&m(me,ue)},s.append(T);const $=r.renderNode(g);$.setAttribute("data-value",b),$.setAttribute("data-active",w?"true":"false"),l.append($)}),n.append(s,l),n}};function Mo(t){return L(t,{className:"rui-tab-trigger-icon"})}const Po={name:"AccordionItem",description:"Single accordion section.",props:[{name:"title",type:"string"},{name:"children",type:"Node[]"},{name:"open",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=o("details",{class:"rui-accordion-item"});C(e.open)&&a.setAttribute("open","");const i=o("summary",{class:"rui-accordion-trigger"},[d(e.title)]);a.append(i);const n=o("div",{class:"rui-accordion-body"});for(const s of k(e.children))n.append(r.renderNode(s));return a.append(n),a}},Io={name:"Accordion",description:"Accordion container. Children must be AccordionItem components.",props:[{name:"items",type:"AccordionItem[]"}],render:(t,e,r)=>{const a=o("div",{class:"rui-accordion"});for(const i of k(e.items))a.append(r.renderNode(i));return a}},at=t=>Math.max(1,Math.min(He,Math.round(t)));function Rt(t){if(t==null||t==="")return 12;const e=String(t).trim();if(e.includes("/")){const[r,a]=e.split("/"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n>0)return at(Math.round(He*i/n))}return e==="auto"||e==="fit"||e==="auto-fit"||e==="full"||e==="100%"?12:at(P(t,12))}function zo(t){const e=d(t.minChildWidth)||d(t.minItemWidth);return ee(e||"220px","220px")}const Ro={name:"GridItem",description:'Wraps a child in a 12-column grid cell with `span`, `offset`, and responsive `spanAt` maps. Parent `Grid` auto-enables 12-column mode when any child is a `GridItem`. Fraction spans like `"1/3"` resolve against the 12-column track.',props:[{name:"child",type:"Node",description:"Child node to place in the grid"},{name:"span",type:"number | string",optional:!0,description:'Columns to span (1–12) or fraction like "1/2", "1/3"'},{name:"offset",type:"number",optional:!0,description:"Empty columns before this item (0–11)"},{name:"spanAt",type:"object",optional:!0,description:"Responsive span map `{sm: 12, md: 6, lg: 4}`"}],render:(t,e,r)=>{const a=Rt(e.span??12),i=se(e.spanAt),n=e.offset===void 0||e.offset===null?0:Math.max(0,Math.min(He-1,Math.round(P(e.offset,0)))),s={class:"rui-grid-item","data-span":String(a)},l=[`--rui-grid-item-span:${a}`];if(n>0&&(s["data-offset"]=String(n),l.push(`--rui-grid-item-offset:${n}`)),i.kind==="responsive"){s["data-responsive-span"]="true";for(const u of Le){const p=i.values[u];if(p!==void 0){const m=Rt(p);l.push(`--rui-grid-item-span-${u}:${m}`)}}}else if(i.kind==="single"&&i.value!=null){const u=Rt(i.value);l.push(`--rui-grid-item-span:${u}`),s["data-span"]=String(u)}s.style=l.join(";");const c=o("div",s);return c.append(r.renderNode(e.child)),c}},Lo={name:"Box",description:"Spacing and surface wrapper for padding, margin, borders, semantic backgrounds, and max-width constraints. Use when a `Card` is too heavy but the content needs a subtle surface or inset.",props:[{name:"children",type:"Node[]"},{name:"padding",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Inner padding. May be a responsive map."},{name:"margin",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Outer margin. May be a responsive map."},{name:"border",type:"string",optional:!0,enum:["none","subtle","default"],description:"Border preset (default none)"},{name:"background",type:"string",optional:!0,enum:["none","surface","muted","primary","success","warning","danger","info"],description:"Semantic background token"},{name:"maxWidth",type:"string",optional:!0,description:"CSS max-width"}],render:(t,e,r)=>{const a=se(e.padding),i=se(e.margin),n={class:"rui-box","data-border":d(e.border,"none"),"data-background":d(e.background,"none")},s=[],l=d(e.maxWidth);if(l&&s.push(`max-width:${ee(l,l)}`),a.kind==="single"){const u=a.value?String(a.value):null;u&&(n["data-padding"]=u)}else n["data-padding"]="responsive",n["data-responsive-padding"]="true",Se(s,a,"--rui-box-padding");if(i.kind==="single"){const u=i.value?String(i.value):null;u&&(n["data-margin"]=u)}else n["data-margin"]="responsive",n["data-responsive-margin"]="true",Se(s,i,"--rui-box-margin");s.length>0&&(n.style=s.join(";"));const c=o("div",n);for(const u of k(e.children))c.append(r.renderNode(u));return c}},ma={name:"Grid",description:'Responsive CSS grid. Use for KPI strips, feature blocks, card grids, and asymmetric layouts with `GridItem` spans. Set `columns: 12` (or include `GridItem` children) for a 12-column track system with fractional spans like `"1/3"`. `columns` and `gap` accept responsive maps like `{sm: 1, md: 2, lg: 4}`.',props:[{name:"children",type:"Node[]"},{name:"columns",type:"number | object",optional:!0,description:"Target column count 1–12 (default auto-fit). `12` enables 12-column mode. May be a responsive map."},{name:"gap",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Gap size (both axes). May be a responsive map."},{name:"rowGap",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Row gap override. May be a responsive map."},{name:"columnGap",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Column gap override. May be a responsive map."},{name:"minItemWidth",type:"string",optional:!0,description:"CSS min width for auto-fit fallback (alias: minChildWidth)"},{name:"minChildWidth",type:"string",optional:!0,description:"CSS min child width; also applies when `columns` is set"},{name:"alignItems",type:"string",optional:!0,enum:["start","center","end","stretch"],description:"Align items inside grid cells"},{name:"justifyItems",type:"string",optional:!0,enum:["start","center","end","stretch"],description:"Justify items inside grid cells"},{name:"dense",type:"boolean",optional:!0,description:"Use dense auto-flow packing"}],render:(t,e,r)=>{const a=k(e.children),i=a.some(v=>vo(v,"GridItem")),n=se(e.columns),s=se(e.gap),l=se(e.rowGap),c=se(e.columnGap),u={class:"rui-grid"},p=[];let m=!1,g=!1;if(n.kind==="single"){const v=n.value===null?0:P(n.value,0),y=v>0?at(v):0;if(y===He?m=!0:y>0&&(g=!0),y>0){u["data-columns"]=String(y);const x=d(e.minChildWidth)||d(e.minItemWidth);x&&(u["data-min-child-width"]="true",p.push(`--rui-grid-min-child:${ee(x,"220px")}`))}else p.push(`--rui-grid-min-item:${zo(e)}`)}else{u["data-responsive-cols"]="true";for(const v of Le){const y=n.values[v];if(y===void 0)continue;const x=at(P(y,0));x===He?m=!0:x>0&&(g=!0),p.push(`--rui-grid-cols-${v}:${x}`)}}i&&!g&&(m=!0),m&&(u["data-grid-mode"]="12"),s.kind==="single"?u["data-gap"]=s.value?String(s.value):"m":(u["data-gap"]="responsive",u["data-responsive-gap"]="true",Se(p,s,"--rui-grid-gap")),l.kind==="single"&&l.value?u["data-row-gap"]=String(l.value):l.kind==="responsive"&&(u["data-row-gap"]="responsive",u["data-responsive-row-gap"]="true",Se(p,l,"--rui-grid-row-gap")),c.kind==="single"&&c.value?u["data-column-gap"]=String(c.value):c.kind==="responsive"&&(u["data-column-gap"]="responsive",u["data-responsive-column-gap"]="true",Se(p,c,"--rui-grid-column-gap"));const f=d(e.alignItems);f&&(u["data-align-items"]=f);const h=d(e.justifyItems);h&&(u["data-justify-items"]=h),C(e.dense)&&(u["data-dense"]="true"),p.length>0&&(u.style=p.join(";"));const b=o("div",u);for(const v of a)b.append(r.renderNode(v));return b}},Eo={name:"AspectRatio",description:"Container that constrains its child to a fixed aspect ratio (e.g. 16:9 for video embeds, 1:1 for thumbnails). The child fills the box.",props:[{name:"ratio",type:"string",description:"`width:height` (e.g. `16:9`, `4:3`) or a decimal like `1.78`"},{name:"children",type:"Node[]"}],render:(t,e,r)=>{const a=_o(d(e.ratio,"16:9")),i=o("div",{class:"rui-aspect-ratio",style:`aspect-ratio:${a};`});for(const n of k(e.children))i.append(r.renderNode(n));return i}};function _o(t){if(t.includes(":")){const[r,a]=t.split(":"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n!==0)return`${i} / ${n}`}const e=Number(t);return Number.isFinite(e)&&e>0?`${e} / 1`:"16 / 9"}const jo={name:"ScrollArea",description:"Bounded scroll container. Use to clip long lists / logs / chat panels to a fixed max height with a clean scrollbar.",props:[{name:"children",type:"Node[]"},{name:"maxHeight",type:"string",optional:!0,aliases:["height"],description:"CSS height (default 320px)"},{name:"direction",type:"string",optional:!0,enum:["vertical","horizontal","both"]}],render:(t,e,r)=>{const a=o("div",{class:"rui-scroll-area","data-direction":d(e.direction,"vertical"),style:`max-height:${ee(e.maxHeight,"320px")};`});for(const i of k(e.children))a.append(r.renderNode(i));return a}},Bo={name:"Modal",description:"Dialog overlay shown when `open` is true. Pass a `$variable` as `open` to control it. The header always renders a × close button (disable via `closable: false`); the optional `footer` slot is the canonical place for action buttons. `closeOnBackdrop=true` opts in to backdrop-click dismissal.",props:[{name:"title",type:"string"},{name:"open",type:"boolean",description:"Open/closed state — usually a $variable"},{name:"children",type:"Node[]"},{name:"size",type:"string",optional:!0,enum:["sm","md","lg","xl","full"],description:"Width preset (default `md`)"},{name:"footer",type:"Node[]",optional:!0,description:"Footer slot — typically a row of action Buttons"},{name:"closable",type:"boolean",optional:!0,description:"Render the header × button (default true)"},{name:"closeOnBackdrop",type:"boolean",optional:!0,description:"Close when the overlay is clicked (default false)"}],render:(t,e,r)=>{const a=d(e.size,"md"),i=e.closable===void 0?!0:C(e.closable),n=o("div",{class:"rui-modal-overlay","data-open":C(e.open)?"true":"false"}),s=o("div",{class:"rui-modal",role:"dialog","aria-modal":"true","data-size":a}),l=o("header",{class:"rui-modal-header"});l.append(o("h3",{class:"rui-modal-title"},[d(e.title)]));const c=t.argMeta?.[1]?.stateRef,u=()=>{c&&r.setState(c,!1)};if(i){const g=o("button",{type:"button",class:"rui-modal-close","aria-label":"Close dialog"},["×"]);g.onclick=f=>{f.stopPropagation(),u()},l.append(g)}s.append(l);const p=o("div",{class:"rui-modal-body"});for(const g of k(e.children))p.append(r.renderNode(g));s.append(p);const m=k(e.footer);if(m.length>0){const g=o("footer",{class:"rui-modal-footer"});for(const f of m)g.append(r.renderNode(f));s.append(g)}return n.append(s),C(e.closeOnBackdrop)&&c&&(n.onclick=g=>{g.target===n&&u()}),n}},Do=["solid","regular","brands"],it=["xs","sm","md","lg","xl"],Fo=["default","neutral","primary","success","warning","danger","info"];function Lt(t,e="md"){const r=d(t).trim().toLowerCase();return r?r==="small"?"sm":r==="normal"?"md":r==="large"?"lg":it.includes(r)?r:e:e}const Oo={name:"Icon",description:'Single Font Awesome icon. `name` is the FA name without the `fa-` prefix (e.g. `"house"`, `"chart-line"`). Use `variant` for non-solid styles (`regular`/`brands`) or prefix the name (`"regular:star"`).',props:[{name:"name",type:"string",description:"FA name without the fa- prefix"},{name:"variant",type:"string",optional:!0,enum:Do},{name:"size",type:"string",optional:!0,enum:oo}],render:(t,e)=>{const r=d(e.name),a=d(e.variant,""),i=d(e.size,"md"),n=a?`${a}:${r}`:r,s=L(n,{size:i});return s||o("span",{class:"rui-icon","data-icon-size":i},[r])}},Uo=["small","small-heavy","body","body-heavy","large","large-heavy","heading","title"];function qo(t){const e=d(t).trim();return!e||/[<>]/.test(e)||/\bexpression\s*\(|\bjavascript\s*:|\bbehavior\s*:|@import\b/i.test(e)?"":e}const ga=[{name:"value",type:"string"},{name:"variant",type:"string",optional:!0,enum:Uo},{name:"tone",type:"string",optional:!0,enum:["default","muted","primary","success","warning","danger"],description:"Visual accent"},{name:"style",type:"string",optional:!0,description:'Inline CSS declarations applied to the rendered element (e.g. "font-size: 16px; font-weight: bold; color: #000;").'}],fa=(t,e)=>{const r=d(e.variant,"body"),a=d(e.tone,"default"),i=qo(e.style);return o("span",{class:"rui-text","data-variant":r,"data-color":a,style:i||null},[d(e.value)])},Ho={name:"Text",description:'Renders plain text with a typographic variant. Optional `style` prop accepts a CSS declaration string (e.g. "font-size: 16px; color: #000;") applied directly to the rendered element.',props:ga,render:fa},Vo={name:"TextContent",description:"Deprecated alias for `Text`. Prefer `Text(...)` — both render identically.",props:ga,render:fa},Wo={name:"Image",description:"Inline image. `ratio` constrains the box to a fixed aspect ratio (e.g. `16:9`, `1:1`) so callers do not need an outer `AspectRatio`. `fit` controls how the image fills that box. When `src` is missing or unsafe the component renders a placeholder (or `fallback` text/icon).",props:[{name:"src",type:"string"},{name:"alt",type:"string",optional:!0},{name:"caption",type:"string",optional:!0},{name:"ratio",type:"string",optional:!0,description:"Aspect ratio shorthand (e.g. `16:9`, `1:1`, `4:3`)"},{name:"fit",type:"string",optional:!0,enum:["cover","contain","fill","none","scale-down"],description:"object-fit value (default `cover`)"},{name:"fallback",type:"string",optional:!0,description:"Text label or Font Awesome icon shown when src is missing/unsafe"}],render:(t,e)=>{const r=o("figure",{class:"rui-image","data-fit":d(e.fit,"cover"),style:e.ratio?`aspect-ratio:${Go(d(e.ratio))};`:null}),a=re(e.src);if(a)r.append(o("img",{src:a,alt:d(e.alt),loading:"lazy"}));else{const n=o("div",{class:"rui-image-placeholder",role:"presentation","aria-hidden":"true"}),s=d(e.fallback);if(s){const l=L(s,{className:"rui-image-fallback-icon"});l?n.append(l):n.append(o("span",{class:"rui-image-fallback-text"},[s]))}r.append(n)}const i=d(e.caption);return i&&r.append(o("figcaption",{class:"rui-image-caption"},[i])),r}};function Go(t){if(!t)return"auto";if(t.includes(":")){const[r,a]=t.split(":"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n>0)return`${i} / ${n}`}const e=Number(t);return Number.isFinite(e)&&e>0?`${e} / 1`:"auto"}const Ko={name:"Link",description:"Anchor link.",props:[{name:"label",type:"string"},{name:"href",type:"string"},{name:"external",type:"boolean",optional:!0}],render:(t,e)=>{const r=C(e.external),a=rt(e.href,"#");return o("a",{class:"rui-link",href:a,target:r?"_blank":null,rel:r?"noopener noreferrer":null},[d(e.label)])}},ha=["neutral","primary","success","warning","danger","info"],Yo={name:"Badge",description:"Small pill-style tag for status, counts, categories. Accepts an optional leading `icon` and a `size`.",props:[{name:"label",type:"string",positional:!0},{name:"tone",type:"string",optional:!0,enum:ha,aliases:["variant"],description:"Visual tone"},{name:"icon",type:"string",optional:!0,description:'Optional Font Awesome icon name (e.g. "star")'},{name:"size",type:"string",optional:!0,enum:it}],render:(t,e)=>{const r=d(e.tone,"neutral"),a=Lt(e.size,"md"),i=o("span",{class:"rui-badge","data-variant":r,"data-size":a}),n=L(e.icon,{className:"rui-badge-icon"});n&&i.append(n);const s=d(e.label);return s&&i.append(o("span",{class:"rui-badge-label"},[s])),i}},Jo={name:"BadgeList",description:"Cluster of Badge pills rendered from an array of strings.",props:[{name:"labels",type:"string[]",positional:!0,description:"Array of badge labels"},{name:"tone",type:"string",optional:!0,enum:ha,aliases:["variant"]},{name:"size",type:"string",optional:!0,enum:it}],render:(t,e)=>{const r=d(e.tone,"neutral"),a=Lt(e.size,"md"),i=o("div",{class:"rui-badge-list"});for(const n of k(e.labels)){const s=d(n);if(!s)continue;const l=o("span",{class:"rui-badge","data-variant":r,"data-size":a});l.append(o("span",{class:"rui-badge-label"},[s])),i.append(l)}return i}},Xo={name:"Callout",description:"Highlighted callout banner with variant, title, description, and leading icon. Pass `compact: true` for a one-line inline-note rendering.",props:[{name:"tone",type:"string",optional:!0,enum:["neutral","info","success","warning","danger","error"],aliases:["variant"]},{name:"title",type:"string",positional:!0,required:!0},{name:"description",type:"string",optional:!0,aliases:["text"],description:"Body text"},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name"},{name:"compact",type:"boolean",optional:!0,description:"Render with the dense, one-line note shape."}],render:(t,e)=>{const r=d(e.tone,"info"),a=C(e.compact),i=o("div",{class:"rui-callout","data-variant":r,"data-compact":a?"true":"false"}),n=d(e.icon)||es(r),s=L(n,{className:"rui-callout-icon"});s&&i.append(s);const l=o("div",{class:"rui-callout-body"});l.append(o("div",{class:"rui-callout-title"},[d(e.title)]));const c=d(e.description);return c&&l.append(o("div",{class:"rui-callout-description"},[c])),i.append(l),i}},Zo={name:"CodeBlock",description:'Read-only code block with a language label and a copy-to-clipboard button. Pass `showLineNumbers=true` to render a gutter; `highlightLines` accepts a string like `"3-5,8"` to emphasise specific lines.',props:[{name:"language",type:"string",optional:!0,description:"Display label (e.g. ts, bash)"},{name:"codeString",type:"string",positional:!0,required:!0,aliases:["code"],description:"Raw source text"},{name:"showLineNumbers",type:"boolean",optional:!0,description:"Render a left-side line-number gutter"},{name:"highlightLines",type:"string",optional:!0,aliases:["highlight"],description:'Highlight ranges, e.g. "3-5,8"'},{name:"copy",type:"boolean",optional:!0,description:"Show the copy-to-clipboard button (default true)"}],render:(t,e)=>{const r=d(e.language),a=d(e.codeString),i=C(e.showLineNumbers),n=Qo(d(e.highlightLines)),s=e.copy===void 0?!0:C(e.copy),l=o("div",{class:"rui-code-block"});if(r||s){const u=o("div",{class:"rui-code-block-head"});if(r&&u.append(o("span",{class:"rui-code-block-language"},[r])),s){const p=o("button",{type:"button",class:"rui-code-block-copy","aria-label":"Copy code",title:"Copy"}),m=L("copy",{className:"rui-code-block-copy-icon"});m&&p.append(m),p.append(o("span",{class:"rui-code-block-copy-label"},["Copy"])),p.onclick=g=>{const f=g.currentTarget??g.target,b=f.closest(".rui-code-block")?.querySelector("code")?.textContent??a,y=(typeof navigator<"u"?navigator:null)?.clipboard;y?.writeText&&y.writeText(b).catch(()=>{});const x=f.querySelector(".rui-code-block-copy-label");if(x){const w=x.textContent??"Copy";x.textContent="Copied",setTimeout(()=>{x.textContent=w},1500)}},u.append(p)}l.append(u)}const c=o("pre",{class:"rui-code-block-pre","data-line-numbers":i?"true":"false"});if(i||n.size>0){const u=a.split(/\r?\n/),p=o("code",{});u.forEach((m,g)=>{const f=g+1,h=o("span",{class:"rui-code-block-line","data-line":String(f),"data-highlight":n.has(f)?"true":null});i&&h.append(o("span",{class:"rui-code-block-gutter"},[String(f)])),h.append(o("span",{class:"rui-code-block-code"},[m])),p.append(h)}),c.append(p)}else c.append(o("code",{},[a]));return l.append(c),l}};function Qo(t){const e=new Set;if(!t)return e;for(const r of t.split(",")){const a=r.trim();if(a)if(a.includes("-")){const i=a.split("-").map(l=>Number(l.trim())),n=i[0]??NaN,s=i[1]??NaN;if(Number.isFinite(n)&&Number.isFinite(s)&&n<=s)for(let l=n;l<=s;l+=1)e.add(l)}else{const i=Number(a);Number.isFinite(i)&&e.add(i)}}return e}function es(t){switch(t){case"success":return"circle-check";case"warning":return"triangle-exclamation";case"danger":case"error":return"circle-xmark";case"info":return"circle-info";default:return"circle-info"}}const ts={name:"Skeleton",description:"Loading placeholder. Pass a `variant` for common shapes — `paragraph` (default), `card`, `table-row`, `avatar`, `image` — or use `shape` / `width` / `height` to build a custom one. All variants use a shimmer animation that respects `prefers-reduced-motion`.",props:[{name:"variant",type:"string",optional:!0,enum:["paragraph","card","table-row","avatar","image"]},{name:"lines",type:"number",optional:!0,aliases:["count"],description:"Lines for the `paragraph` variant (default 3)"},{name:"height",type:"number | string",optional:!0,description:"Line height in px (paragraph) or CSS height for custom shape"},{name:"shape",type:"string",optional:!0,enum:["rect","circle"],description:"Force a primitive shape (rect/circle)"},{name:"width",type:"string",optional:!0,description:"CSS width for shape-only skeletons"}],render:(t,e)=>{const r=d(e.variant),a=d(e.shape);if(a)return rs(a,e);if(r&&r!=="paragraph")return as(r,e);const i=Number(e.lines),n=Math.max(1,Math.min(50,Number.isFinite(i)?Math.floor(i):3)),s=Number(e.height),l=Number.isFinite(s)&&s>0?Math.min(200,Math.floor(s)):12,c=o("div",{class:"rui-skeleton","data-variant":"paragraph"});for(let u=0;u<n;u+=1)c.append(o("div",{class:"rui-skeleton-line",style:`height:${l}px`}));return c}};function rs(t,e){const r=ee(d(e.width),"100%"),a=d(e.height),i=a?ee(a,"16px"):t==="circle"?r:"16px";return o("div",{class:"rui-skeleton","data-variant":"shape","data-shape":t==="circle"?"circle":"rect",style:`width:${r};height:${i};`})}function as(t,e){const r=o("div",{class:"rui-skeleton","data-variant":t});switch(t){case"avatar":{const a=ee(d(e.width),"40px");return r.append(o("div",{class:"rui-skeleton-shape","data-shape":"circle",style:`width:${a};height:${a};`})),r}case"image":{const a=ee(d(e.width),"100%"),i=ee(d(e.height),"160px");return r.append(o("div",{class:"rui-skeleton-shape","data-shape":"rect",style:`width:${a};height:${i};`})),r}case"card":return r.append(o("div",{class:"rui-skeleton-shape","data-shape":"rect",style:"width:100%;height:120px;"})),r.append(o("div",{class:"rui-skeleton-line",style:"height:14px;width:70%;"})),r.append(o("div",{class:"rui-skeleton-line",style:"height:12px;width:90%;"})),r.append(o("div",{class:"rui-skeleton-line",style:"height:12px;width:60%;"})),r;case"table-row":{const a=Math.max(1,Math.min(8,Math.floor(Number(e.lines??4)))),i=o("div",{class:"rui-skeleton-row"});for(let n=0;n<a;n+=1)i.append(o("div",{class:"rui-skeleton-line",style:"height:12px;flex:1;"}));return r.append(i),r}default:return r}}const is={name:"Markdown",description:"Render markdown-flavoured text. Supports **bold**, *italic*, `code`, headings (`#`/`##`/`###`), blockquotes (`>`), bullet (`-`/`*`) and numbered (`1.`) lists, fenced code blocks (```), images (`![alt](src)`), inline links, and auto-linked bare URLs. Multi-line paragraphs collapse into `<p>` blocks.",props:[{name:"content",type:"string"}],render:(t,e)=>{const r=d(e.content),a=cs(r);return o("div",{class:"rui-markdown",html:a})}},ns={name:"Container",description:"Centered, max-width content wrapper. Use when a page is wider than comfortable reading width — landing pages, marketing sections, long documents. Picks a sensible default max-width per size; pass `maxWidth` to override with any CSS value.",props:[{name:"children",type:"Node[]"},{name:"size",type:"string",optional:!0,enum:["sm","md","lg","xl","full"],description:"sm=640 / md=820 / lg=1040 / xl=1280 / full=100% (default lg)"},{name:"maxWidth",type:"string",optional:!0,description:"Custom CSS max-width (overrides `size`)"},{name:"padding",type:"string",optional:!0,enum:["none","s","m","l"],description:"Horizontal padding (default m)"}],render:(t,e,r)=>{const a=o("div",{class:"rui-container","data-size":d(e.size,"lg"),"data-padding":d(e.padding,"m"),style:e.maxWidth?`max-width:${ee(e.maxWidth,"auto")};`:null});for(const i of k(e.children))a.append(r.renderNode(i));return a}},os={name:"Spacer",description:'Explicit space element for fine layout control. By default acts as a flex spacer that pushes following content to the far edge (use inside `Stack(direction="row")`). Pass `size` to render a fixed vertical/horizontal gap instead.',props:[{name:"size",type:"string",optional:!0,enum:["xs","s","m","l","xl"],description:"Fixed gap; omit to flex-grow"},{name:"flex",type:"boolean",optional:!0,description:"Flex-grow even when size is set (default true when size omitted)"}],render:(t,e)=>{const r=d(e.size),a=e.flex===void 0?!r:C(e.flex);return o("span",{class:"rui-spacer","data-size":r||null,"data-flex":a?"true":"false","aria-hidden":"true"})}},ss={name:"Spinner",description:"Indeterminate inline loader. Use for tiny loading states inside buttons, toolbars, table cells, or chat bubbles where `Skeleton` and `Progress(indeterminate=true)` are too heavy. Pass `label` to render an inline caption beside the spinner (also announced via `aria-label`).",props:[{name:"size",type:"string",optional:!0,enum:it,description:"Default `md`"},{name:"label",type:"string",optional:!0,description:"Caption rendered beside the spinner (also announced)"},{name:"tone",type:"string",optional:!0,enum:Fo,description:"Visual accent (default `primary`)"}],render:(t,e)=>{const r=Lt(e.size,"md"),a=d(e.tone,"primary"),i=d(e.label),n=o("span",{class:"rui-spinner","data-size":r,"data-tone":a,role:"status","aria-live":"polite","aria-label":i||"Loading"});return n.append(o("span",{class:"rui-spinner-ring","aria-hidden":"true"})),i&&n.append(o("span",{class:"rui-spinner-label"},[i])),n}},ls={name:"Quote",description:"Inline pull-quote with optional citation. Lighter than `Testimonial` — use inside articles, blog posts, marketing sections, or anywhere you need to highlight a sentence without the full quote/author/role + rating shape.",props:[{name:"text",type:"string"},{name:"cite",type:"string",optional:!0,aliases:["attribution","author"],description:"Attribution text shown below the quote"},{name:"tone",type:"string",optional:!0,enum:["default","primary","success","warning","danger","info"]}],render:(t,e)=>{const r=o("figure",{class:"rui-quote","data-tone":d(e.tone,"default")});r.append(o("blockquote",{class:"rui-quote-text"},[d(e.text)]));const a=d(e.cite);return a&&r.append(o("figcaption",{class:"rui-quote-cite"},[a])),r}};function cs(t){const e=f=>f.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),r=t.split(/\r?\n/),a=[];let i=null,n=!1,s=!1,l="",c=[];const u=()=>{i&&(a.push(i==="ul"?"</ul>":"</ol>"),i=null)},p=()=>{n&&(a.push("</blockquote>"),n=!1)},m=()=>{const f=l?` data-language="${e(l)}"`:"";a.push(`<pre class="rui-markdown-code"${f}><code>${e(c.join(`
20
- `))}</code></pre>`),c=[],l="",s=!1};for(const f of r){const h=/^```\s*(.*)$/.exec(f.trim());if(s){if(h){m();continue}c.push(f);continue}if(h){u(),p(),s=!0,l=h[1]??"";continue}const b=/^\s*(#{1,3})\s+(.+)$/.exec(f);if(b){u(),p();const w=b[1].length;a.push(`<h${w} class="rui-markdown-h${w}">${g(e(b[2]))}</h${w}>`);continue}const v=/^\s*>\s?(.*)$/.exec(f);if(v){u(),n||(a.push('<blockquote class="rui-markdown-quote">'),n=!0),a.push(`<p>${g(e(v[1]??""))}</p>`);continue}else n&&f.trim()!==""&&p();const y=/^\s*[-*]\s+(.*)$/.exec(f);if(y){p(),i!=="ul"&&(u(),a.push("<ul>"),i="ul"),a.push(`<li>${g(e(y[1]??""))}</li>`);continue}const x=/^\s*\d+\.\s+(.*)$/.exec(f);if(x){p(),i!=="ol"&&(u(),a.push("<ol>"),i="ol"),a.push(`<li>${g(e(x[1]??""))}</li>`);continue}if(f.trim()===""){u(),p();continue}u(),p(),a.push(`<p>${g(e(f))}</p>`)}return s&&m(),u(),p(),a.join("");function g(f){let h=f.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(b,v,y)=>{const x=re(y);return x?`<img class="rui-markdown-image" src="${nt(x)}" alt="${v}" loading="lazy">`:`<span class="rui-markdown-image-fallback">${v}</span>`}).replace(/`([^`]+)`/g,"<code>$1</code>").replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>").replace(/\*([^*]+)\*/g,"<em>$1</em>").replace(/\[([^\]]+)\]\(([^)]+)\)/g,(b,v,y)=>`<a class="rui-link" href="${ba(y)}" target="_blank" rel="noopener noreferrer">${v}</a>`);return h=h.replace(/(?<![="'>])\bhttps?:\/\/[a-zA-Z0-9._~:/?#@!$&'()*+,;=%\-]+/g,b=>`<a class="rui-link" href="${ba(b)}" target="_blank" rel="noopener noreferrer">${b}</a>`),h}}function ba(t){const e=t.trim();if(!e||e.startsWith("//"))return"#";if(e.startsWith("#")||e.startsWith("/")||e.startsWith("?"))return nt(e);const r=/^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(e);if(!r)return nt(e);const a=r[1].toLowerCase();return new Set(["http","https","mailto","tel"]).has(a)?nt(e):"#"}function nt(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Ve(t,e,r){const a=o("span",{class:"rui-avatar","data-size":r,role:"img"}),i=re(t);if(i){const n=o("img",{src:i,alt:e,loading:"lazy"});n.onerror=s=>{const l=s;(l.currentTarget??l.target).replaceWith(o("span",{class:"rui-avatar-fallback"},[We(e)]))},a.append(n)}else a.append(o("span",{class:"rui-avatar-fallback"},[We(e)]));return a}function We(t){const e=t.trim();return e?e.split(/\s+/).slice(0,2).map(a=>a.charAt(0).toUpperCase()).join("")||e.charAt(0).toUpperCase():"?"}const ot=new WeakMap;function Ee(t){const{liveRoot:e,onDismiss:r}=t,a=ot.get(e);a&&a.dispose();const i=e.getRootNode();let n=!1;const s=m=>{const g=m.target;g&&e.contains(g)||(p.dispose(),r())},l=m=>{m.key==="Escape"&&(p.dispose(),r())},c=e.ownerDocument;let u=null;if(c&&typeof MutationObserver<"u"){u=new MutationObserver(()=>{e.isConnected||p.dispose()});const m=e.getRootNode();(m instanceof Element||m instanceof Document||m instanceof ShadowRoot)&&u.observe(m,{childList:!0,subtree:!0})}const p={dispose:()=>{n||(n=!0,i.removeEventListener("click",s,!0),i.removeEventListener("keydown",l,!0),u?.disconnect(),ot.delete(e))}};return setTimeout(()=>{n||(i.addEventListener("click",s,!0),i.addEventListener("keydown",l,!0))},0),ot.set(e,p),p}function he(t){if(!t)return;const e=ot.get(t);e&&e.dispose()}const us=[{match:/\b(revenue|sales|sale|income|payment|charges?|invoices?|billing)\b/i,icon:"sack-dollar"},{match:/\b(profit|earnings?|margin|roi)\b/i,icon:"chart-line"},{match:/\b(customers?|clients?|users?|members?|people|accounts?)\b/i,icon:"users"},{match:/\b(visitors?|sessions?|traffic|page-?views?|impressions?)\b/i,icon:"chart-line"},{match:/\b(orders?|carts?|purchases?|transactions?)\b/i,icon:"cart-shopping"},{match:/\b(products?|inventory|sku|stock|items?)\b/i,icon:"box"},{match:/\b(subscriptions?|plans?|tiers?|pricing)\b/i,icon:"credit-card"},{match:/\b(emails?|messages?|inbox|threads?|mail)\b/i,icon:"envelope"},{match:/\b(notifications?|alerts?|reminders?)\b/i,icon:"bell"},{match:/\b(growth|trend|increase|up)\b/i,icon:"arrow-trend-up"},{match:/\b(decline|drop|down|decrease|loss)\b/i,icon:"arrow-trend-down"},{match:/\b(reports?|analytics|insights?|dashboards?|metrics?|stats?|kpis?)\b/i,icon:"chart-pie"},{match:/\b(charts?|graphs?)\b/i,icon:"chart-column"},{match:/\b(tasks?|todos?|backlog|kanban|sprint)\b/i,icon:"list-check"},{match:/\b(projects?|workspaces?)\b/i,icon:"folder-open"},{match:/\b(files?|folders?|documents?|docs?|attachments?)\b/i,icon:"folder-open"},{match:/\b(images?|photos?|gallery|albums?)\b/i,icon:"image"},{match:/\b(videos?|clips?|recordings?)\b/i,icon:"video"},{match:/\b(audio|music|podcasts?|sounds?)\b/i,icon:"music"},{match:/\b(calendars?|schedule|events?|meetings?|appointments?)\b/i,icon:"calendar-days"},{match:/\b(comments?|replies|feedback|reviews?|ratings?)\b/i,icon:"comments"},{match:/\b(settings?|preferences?|config|configuration|options?)\b/i,icon:"gear"},{match:/\b(security|privacy|password|locks?|secure)\b/i,icon:"shield-halved"},{match:/\b(api|integrations?|webhooks?|connections?)\b/i,icon:"plug"},{match:/\b(database|storage|backups?|servers?)\b/i,icon:"database"},{match:/\b(speed|performance|latency|response\s?time)\b/i,icon:"gauge-high"},{match:/\b(uptime|availability|status|health)\b/i,icon:"heart-pulse"},{match:/\b(errors?|bugs?|failures?|exceptions?|incidents?)\b/i,icon:"circle-exclamation"},{match:/\b(success|complete|done|approved)\b/i,icon:"circle-check"},{match:/\b(warnings?|caution)\b/i,icon:"triangle-exclamation"},{match:/\b(search|results?|queries)\b/i,icon:"magnifying-glass"},{match:/\b(downloads?|exports?)\b/i,icon:"download"},{match:/\b(uploads?|imports?)\b/i,icon:"upload"},{match:/\b(time|hours?|duration|elapsed)\b/i,icon:"clock"},{match:/\b(locations?|maps?|addresses?|countries?|regions?)\b/i,icon:"location-dot"},{match:/\b(stars?|favourites?|favorites?|highlights?)\b/i,icon:"star"},{match:/\b(trophy|awards?|achievements?|badges?|gold)\b/i,icon:"trophy"},{match:/\b(targets?|goals?|objectives?|quotas?)\b/i,icon:"bullseye"},{match:/\b(teams?|departments?|orgs?|organisations?|organizations?)\b/i,icon:"people-group"},{match:/\b(tickets?|issues?|bugs?|requests?)\b/i,icon:"ticket"},{match:/\b(deploys?|builds?|releases?|versions?)\b/i,icon:"rocket"}];function va(t){if(!t)return null;for(const e of us)if(e.match.test(t))return e.icon;return null}const ds={default:"circle-info",info:"circle-info",primary:"bolt",success:"circle-check",warning:"triangle-exclamation",danger:"circle-exclamation",error:"circle-exclamation",neutral:"circle-info"};function ps(t){return t?ds[t.toLowerCase()]??null:null}function ms(t,e="shapes"){const r=t.trim()||"anon";return`https://api.dicebear.com/9.x/${/^[a-z0-9-]+$/i.test(e)?e:"shapes"}/svg?seed=${encodeURIComponent(r)}`}function ya(t){return k(t).map(r=>{if(r&&typeof r=="object"){const i=r;if(i.__kind==="Component"&&Array.isArray(i.args)){const n=d(i.args[0]);return{value:n,label:d(i.args[1],n)}}if(i.value!==void 0||i.label!==void 0){const n=d(i.value);return{value:n,label:d(i.label,n)}}}const a=d(r);return{value:a,label:a}}).filter(r=>r.value!==""||r.label!=="")}const gs=["primary","secondary","ghost","danger"],fs=["xs","sm","md","lg","xl","small","normal","large"],hs=["text","email","password","number","tel","url","date"];function bs(t){const e=d(t).trim().toLowerCase();return e==="xs"||e==="extra-small"?"xs":e==="small"||e==="sm"?"sm":e==="large"||e==="lg"?"lg":e==="xl"||e==="extra-large"?"xl":e==="normal"||e==="md"||e===""?"md":e==="xs"||e==="sm"||e==="md"||e==="lg"||e==="xl"?e:"md"}const vs={name:"Button",description:"Clickable button. The action argument runs when clicked.",props:[{name:"label",type:"string"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Callable invoked when clicked"},{name:"variant",type:"string",optional:!0,aliases:["tone"],enum:gs},{name:"type",type:"string",optional:!0,enum:["button","submit"],description:"HTML button type"},{name:"size",type:"string",optional:!0,enum:fs,description:"Canonical `xs|sm|md|lg|xl` (legacy `small|normal|large` still accepted)"},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name"},{name:"iconPosition",type:"string",optional:!0,enum:["leading","trailing"],description:"Icon placement (default leading)"},{name:"iconOnly",type:"boolean",optional:!0,description:"Hide the label visually (keeps aria-label)"},{name:"loading",type:"boolean",optional:!0,description:"Show spinner and disable interaction"},{name:"fullWidth",type:"boolean",optional:!0},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=C(e.loading),i=C(e.iconOnly),n=d(e.iconPosition,"leading"),s=d(e.label),l=o("button",{class:"rui-button",type:d(e.type,"button"),"data-variant":d(e.variant,"primary"),"data-size":bs(e.size),"data-icon-position":n,"data-icon-only":i?"true":null,"data-full-width":C(e.fullWidth)?"true":null,"data-loading":a?"true":null,"aria-label":i?s:null,disabled:C(e.disabled)||a?"":null}),c=o("span",{class:"rui-button-label"},[s]),u=L(e.icon,{className:"rui-button-icon"}),m=(a?L("spinner",{className:"rui-button-spinner"}):null)??u;return i?m&&l.append(m):n==="trailing"?(l.append(c),m&&l.append(m)):(m&&l.append(m),l.append(c)),l.onclick=()=>{a||r.invoke(e.action)},l}},ys={name:"Buttons",description:"Group of buttons laid out horizontally or vertically.",props:[{name:"items",type:"Button[]"},{name:"direction",type:"string",optional:!0,enum:["row","column"]}],render:(t,e,r)=>{const a=o("div",{class:"rui-buttons","data-direction":d(e.direction,"row")});for(const i of k(e.items))a.append(r.renderNode(i));return a}},xs={name:"Input",description:"Text input field. Pass a $variable as `value` for two-way binding.",props:[{name:"id",type:"string",description:"Input identifier"},{name:"placeholder",type:"string",optional:!0},{name:"type",type:"string",optional:!0,enum:hs},{name:"validations",type:"any",optional:!0,description:"Array or object of validation hints"},{name:"value",type:"any",optional:!0,description:"Bound value (typically $variable)"}],render:(t,e,r)=>{const a=o("input",{class:"rui-input",id:d(e.id),name:d(e.id),type:d(e.type,"text"),placeholder:d(e.placeholder),value:d(e.value)});return Ce(a,t,4,r),Bs(a,e.validations),a}},ws={name:"TextArea",description:"Multi-line text input.",props:[{name:"id",type:"string"},{name:"placeholder",type:"string",optional:!0},{name:"rows",type:"number",optional:!0},{name:"value",type:"any",optional:!0}],render:(t,e,r)=>{const a=o("textarea",{class:"rui-textarea",id:d(e.id),name:d(e.id),placeholder:d(e.placeholder),rows:String(Number(e.rows??4)||4)});return a.value=d(e.value),Ce(a,t,3,r),a}},ks={name:"SelectItem",description:"Single option for a Select component.",props:[{name:"value",type:"string"},{name:"label",type:"string"}],render:(t,e)=>o("option",{value:d(e.value)},[d(e.label)])},Ss={name:"Select",description:"Dropdown select. Pass a `$variable` as `value` for two-way binding. Set `searchable: true` for a combobox-style filter UI on long option lists.",props:[{name:"id",type:"string"},{name:"items",type:"SelectItem[]"},{name:"label",type:"string",optional:!0},{name:"placeholder",type:"string",optional:!0},{name:"value",type:"any",optional:!0},{name:"searchable",type:"boolean",optional:!0,description:"Render as a filterable combobox"}],render:(t,e,r)=>{if(C(e.searchable))return js(t,e,r);const a=o("select",{class:"rui-select",id:d(e.id),name:d(e.id)}),i=d(e.placeholder);i&&a.append(o("option",{value:"",disabled:"",selected:""},[i]));for(const n of k(e.items))a.append(r.renderNode(n));return a.value=d(e.value),Ce(a,t,4,r),a}},Cs={name:"Checkbox",description:"Boolean checkbox.",props:[{name:"id",type:"string"},{name:"label",type:"string"},{name:"value",type:"boolean",optional:!0,aliases:["checked"]}],render:(t,e,r)=>{const a=o("label",{class:"rui-checkbox"}),i=C(e.value),n=o("input",{type:"checkbox",id:d(e.id),name:d(e.id),checked:i?"":null});return n.checked=i,Ce(n,t,2,r),a.append(n,o("span",{class:"rui-checkbox-label"},[d(e.label)])),a}},Ts={name:"CheckBoxItem",description:"Single option inside a CheckBoxGroup.",props:[{name:"label",type:"string"},{name:"name",type:"string",description:"Key inside the group's value object"},{name:"description",type:"string",optional:!0},{name:"defaultChecked",type:"boolean",optional:!0,aliases:["checked"]}],render:(t,e)=>{const r=d(e.name),a=d(e.label),i=d(e.description),n=C(e.defaultChecked),s=o("label",{class:"rui-checkbox-item","data-name":r}),l=o("input",{type:"checkbox",name:r,checked:n?"":null});l.checked=n;const c=o("div",{class:"rui-checkbox-item-text"});return c.append(o("div",{class:"rui-checkbox-item-label"},[a])),i&&c.append(o("div",{class:"rui-checkbox-item-description"},[i])),s.append(l,c),s}},Ns={name:"CheckBoxGroup",description:"Group of checkboxes. Value is an object keyed by item name. Pass a `$variable` for two-way binding.",props:[{name:"name",type:"string",description:"Group identifier"},{name:"items",type:"CheckBoxItem[]"},{name:"value",type:"any",optional:!0,description:"Bound value (typically $variable)"}],render:(t,e,r)=>{const a=d(e.name),i=o("div",{class:"rui-checkbox-group",role:"group","data-name":a}),n=k(e.items),s=e.value&&typeof e.value=="object"?e.value:{};n.forEach((c,u)=>{const p=d(c.args?.[0]),m=d(c.args?.[1],`${a}-${u}`),g=d(c.args?.[2]),f=C(c.args?.[3]),h=`${a}-${m}`,b=o("label",{class:"rui-checkbox-item",for:h}),v=m in s?!!s[m]:f,y=o("input",{type:"checkbox",id:h,name:m,checked:v?"":null}),x=o("div",{class:"rui-checkbox-item-text"});x.append(o("div",{class:"rui-checkbox-item-label"},[p])),g&&x.append(o("div",{class:"rui-checkbox-item-description"},[g])),b.append(y,x),i.append(b)});const l=t.argMeta?.[2]?.stateRef;return l&&r.bindState(i,l,{event:"change",getValue:c=>{const u={};return c.querySelectorAll('input[type="checkbox"]').forEach(p=>{u[p.name]=p.checked}),u}}),i}},$s={name:"Radio",description:"Radio button group.",props:[{name:"id",type:"string"},{name:"items",type:"SelectItem[]"},{name:"value",type:"any",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("div",{class:"rui-radio-group",role:"radiogroup"});for(const n of k(e.items)){const s=d(n.args?.[0]),l=d(n.args?.[1],s),c=`${a}-${s}`,u=o("label",{class:"rui-radio",for:c}),p=d(e.value)===s,m=o("input",{type:"radio",id:c,name:a,value:s,checked:p?"":null});m.checked=p,Ce(m,t,2,r),u.append(m,o("span",{class:"rui-radio-label"},[l])),i.append(u)}return i}},As={name:"FormControl",description:"Labeled wrapper around a single form field.",props:[{name:"label",type:"string"},{name:"field",type:"Node",aliases:["control"]},{name:"hint",type:"string",optional:!0}],render:(t,e,r)=>{const a=o("div",{class:"rui-form-control"});a.append(o("label",{class:"rui-form-label"},[d(e.label)]));const i=r.renderNode(e.field);a.append(i);const n=d(e.hint);return n&&a.append(o("p",{class:"rui-form-hint"},[n])),a}},xa={name:"SearchBar",description:"Pre-styled search input with a leading magnifying-glass icon, optional trailing submit button, and optional keyboard-shortcut hint. Pass a `$variable` as `value` for two-way binding. Use anywhere a user needs to filter content — toolbars, command bars, lists, headers.",props:[{name:"id",type:"string"},{name:"placeholder",type:"string",optional:!0},{name:"value",type:"string",optional:!0,description:"Bound value (typically $variable)"},{name:"shortcut",type:"string",optional:!0,description:'Keyboard hint chip on the right (e.g. "/")'},{name:"action",type:"callable",optional:!0,aliases:["onClick","onSubmit"],description:"Optional submit callable; clicking the trailing button or pressing Enter invokes it"},{name:"submitLabel",type:"string",optional:!0,description:'Label for the trailing submit button (default "Search"). Omitted when no action is provided.'}],render:(t,e,r)=>{const a=o("form",{class:"rui-search-bar",role:"search"});a.onsubmit=l=>{l.preventDefault(),r.invoke(e.action)};const i=L("magnifying-glass",{className:"rui-search-bar-icon"})??o("span",{class:"rui-search-bar-icon","aria-hidden":"true"});a.append(i);const n=o("input",{class:"rui-search-bar-input",id:d(e.id),name:d(e.id),type:"search",placeholder:d(e.placeholder,"Search…"),value:d(e.value),autocomplete:"off"});Ce(n,t,2,r),a.append(n);const s=d(e.shortcut);if(s&&a.append(o("span",{class:"rui-search-bar-shortcut"},[s])),e.action!=null){const l=o("button",{type:"submit",class:"rui-search-bar-submit"},[d(e.submitLabel,"Search")]);a.append(l)}return a}},Ms={name:"Form",description:"Form container. Children FormControls render in order; buttons render at the bottom.",props:[{name:"id",type:"string"},{name:"buttons",type:"Buttons | Button"},{name:"fields",type:"FormControl[]"}],render:(t,e,r)=>{const a=o("form",{class:"rui-form",id:d(e.id)});a.onsubmit=i=>i.preventDefault();for(const i of k(e.fields))a.append(r.renderNode(i));if(e.buttons){const i=o("div",{class:"rui-form-actions"});i.append(r.renderNode(e.buttons)),a.append(i)}return a}},Ps={name:"Slider",description:"Range slider for selecting a single numeric value between `min` and `max`. Pass a `$variable` as `value` for two-way binding. Useful for filters, settings (volume, brightness), and parameter tuning.",props:[{name:"id",type:"string"},{name:"min",type:"number",optional:!0,description:"Default 0"},{name:"max",type:"number",optional:!0,description:"Default 100"},{name:"step",type:"number",optional:!0,description:"Default 1"},{name:"value",type:"number",optional:!0,description:"Bound value (typically $variable)"},{name:"label",type:"string",optional:!0},{name:"showValue",type:"boolean",optional:!0,description:"Render the current numeric value beside the slider"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=P(e.min,0),n=P(e.max,100),s=P(e.step,1),l=P(e.value,i),c=o("div",{class:"rui-slider","data-disabled":C(e.disabled)?"true":"false"}),u=d(e.label),p=C(e.showValue);if(u||p){const f=o("div",{class:"rui-slider-head"});u&&f.append(o("label",{class:"rui-slider-label",for:a},[u])),p&&f.append(o("span",{class:"rui-slider-value"},[String(l)])),c.append(f)}const m=o("input",{type:"range",class:"rui-slider-input",id:a,name:a,min:String(i),max:String(n),step:String(s),value:String(l),disabled:C(e.disabled)?"":null});m.oninput=f=>{const h=f.currentTarget;if(!h)return;const v=h.closest(".rui-slider")?.querySelector(".rui-slider-value");v&&(v.textContent=h.value)};const g=t.argMeta?.[4]?.stateRef;return g&&r.bindState(m,g,{event:"input",getValue:f=>Number(f.value)}),c.append(m),c}},Is={name:"NumberInput",description:'Numeric input with paired increment/decrement buttons. Use for quantity steppers, integer settings, and any field where a `<input type="number">` plus +/- controls is friendlier than the native spinner. Pass a `$variable` as `value` for two-way binding.',props:[{name:"id",type:"string"},{name:"value",type:"number",optional:!0,description:"Bound value (typically $variable)"},{name:"min",type:"number",optional:!0},{name:"max",type:"number",optional:!0},{name:"step",type:"number",optional:!0,description:"Default 1"},{name:"placeholder",type:"string",optional:!0},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=P(e.step,1),n=e.min!==void 0&&e.min!==null,s=e.max!==void 0&&e.max!==null,l=n?P(e.min,0):Number.NEGATIVE_INFINITY,c=s?P(e.max,0):Number.POSITIVE_INFINITY,u=C(e.disabled),p=o("div",{class:"rui-number-input","data-disabled":u?"true":"false"}),m=o("button",{type:"button",class:"rui-number-input-button","data-direction":"down","aria-label":"Decrement",disabled:u?"":null},["−"]),g=o("input",{type:"number",class:"rui-number-input-field",id:a,name:a,value:d(e.value),placeholder:d(e.placeholder),min:n?String(l):null,max:s?String(c):null,step:String(i),disabled:u?"":null}),f=o("button",{type:"button",class:"rui-number-input-button","data-direction":"up","aria-label":"Increment",disabled:u?"":null},["+"]),h=t.argMeta?.[1]?.stateRef;h&&r.bindState(g,h,{event:"input",getValue:v=>{const y=v.value;if(y==="")return null;const x=Number(y);return Number.isFinite(x)?x:null}});const b=(v,y)=>{const w=v.closest(".rui-number-input")?.querySelector(".rui-number-input-field");if(!w)return;const T=Number(w.value),S=Number.isFinite(T)?T:0,$=_s(S+y,l,c);w.value=String($),w.dispatchEvent(new Event("input",{bubbles:!0}))};return m.onclick=v=>b(v.currentTarget??v.target,-i),f.onclick=v=>b(v.currentTarget??v.target,i),p.append(m,g,f),p}},zs={name:"DatePicker",description:'Date picker that wraps the native `<input type="date">` with consistent styling. Pass a `$variable` as `value` for two-way binding. Use `min`/`max` to bound the selectable range.',props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"ISO date (YYYY-MM-DD); typically $variable"},{name:"label",type:"string",optional:!0},{name:"min",type:"string",optional:!0,description:"Earliest ISO date"},{name:"max",type:"string",optional:!0,description:"Latest ISO date"},{name:"placeholder",type:"string",optional:!0},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("div",{class:"rui-date-picker"}),n=d(e.label);n&&i.append(o("label",{class:"rui-date-picker-label",for:a},[n]));const s=o("input",{type:"date",class:"rui-date-picker-input",id:a,name:a,value:d(e.value),min:d(e.min)||null,max:d(e.max)||null,placeholder:d(e.placeholder),disabled:C(e.disabled)?"":null});return Ce(s,t,1,r),i.append(s),i}},Rs={name:"FileUpload",description:'Styled file picker. Renders a click/drop area with a leading icon, label, and helper text. Files cannot round-trip through `$variables` (they are not serialisable), so pass a callable as `action` to handle the picked files via `ctx.query("#id").files`.',props:[{name:"id",type:"string"},{name:"label",type:"string",optional:!0,description:'Primary label (default "Choose a file")'},{name:"hint",type:"string",optional:!0,description:"Secondary helper text"},{name:"accept",type:"string",optional:!0,description:"Comma-separated MIME types or extensions"},{name:"multiple",type:"boolean",optional:!0},{name:"action",type:"callable",optional:!0,aliases:["onChange","onSelect"],description:"Callable fired when files are picked"},{name:"icon",type:"string",optional:!0,description:'Font Awesome icon (default "cloud-arrow-up")'},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=C(e.disabled),n=o("div",{class:"rui-file-upload","data-disabled":i?"true":"false"}),s=o("label",{class:"rui-file-upload-dropzone",for:a}),l=L(d(e.icon,"cloud-arrow-up"),{className:"rui-file-upload-icon"});l&&s.append(l);const c=o("div",{class:"rui-file-upload-text"});c.append(o("div",{class:"rui-file-upload-label"},[d(e.label,"Choose a file")]));const u=d(e.hint);u&&c.append(o("div",{class:"rui-file-upload-hint"},[u])),s.append(c);const p=o("input",{type:"file",id:a,name:a,class:"rui-file-upload-input",accept:d(e.accept)||null,multiple:C(e.multiple)?"":null,disabled:i?"":null});s.append(p),n.append(s);const m=(g,f)=>f.includes("image")||g.type.startsWith("image/")||/\.(png|jpe?g|gif|webp|svg|avif|bmp)$/i.test(g.name);return p.onchange=g=>{r.invoke(e.action);const f=g.currentTarget,h=f.closest(".rui-file-upload");if(!h)return;const b=f.files,v=h.querySelector(".rui-file-upload-preview");if(v&&v.remove(),!b||b.length===0)return;const y=d(e.accept),x=o("div",{class:"rui-file-upload-preview"});Array.from(b).forEach(w=>{const T=o("div",{class:"rui-file-upload-preview-item"});if(m(w,y)){const S=URL.createObjectURL(w),$=o("img",{src:S,alt:w.name,class:"rui-file-upload-thumbnail"});$.onload=()=>URL.revokeObjectURL(S),T.append($)}T.append(o("span",{class:"rui-file-upload-filename"},[w.name])),x.append(T)}),h.append(x)},n}},wa={name:"Combobox",description:"Searchable single-select dropdown — type to filter, click an option to choose. Use instead of `Select` when the list is long enough that scanning is faster than scrolling (countries, currencies, repos, users). Pass a `$variable` as `value` for two-way binding; the selected option's `value` is written to state on pick.",props:[{name:"id",type:"string"},{name:"items",type:"SelectItem[]",description:"Options; SelectItem(value, label) or {value, label}"},{name:"value",type:"string",optional:!0,description:"Bound selected value (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"emptyLabel",type:"string",optional:!0,description:'Text shown when no items match the filter (default "No matches")'},{name:"disabled",type:"boolean",optional:!0},{name:"open",type:"boolean",optional:!0,description:"Initial open state — use to demo or pre-open the dropdown"}],render:(t,e,r)=>{const a=d(e.id),i=ya(e.items),n=d(e.value),s=i.find($=>$.value===n)?.label??n,l=d(e.placeholder,"Select…"),c=d(e.emptyLabel,"No matches"),u=C(e.disabled),p=C(e.open),m=r.useInstanceState("open",p),g=r.useInstanceState("filter",""),f=m.get(),h=o("div",{class:"rui-combobox","data-open":f?"true":"false","data-disabled":u?"true":"false"}),b=o("button",{type:"button",class:"rui-combobox-trigger",id:a,"aria-haspopup":"listbox","aria-expanded":f?"true":"false",disabled:u?"":null});b.append(o("span",{class:"rui-combobox-value","data-placeholder":s?"false":"true"},[s||l]));const v=L("chevron-down",{className:"rui-combobox-chevron"});v&&b.append(v),h.append(b);const y=o("div",{class:"rui-combobox-panel",role:"listbox"}),x=o("input",{type:"text",class:"rui-combobox-filter",placeholder:"Filter…",autocomplete:"off",value:g.get()});y.append(x);const w=o("div",{class:"rui-combobox-list"});y.append(w);const T=($,N)=>{$.replaceChildren();const A=N.trim().toLowerCase(),z=A===""?i:i.filter(R=>R.label.toLowerCase().includes(A)||R.value.toLowerCase().includes(A));if(z.length===0){$.append(o("div",{class:"rui-combobox-empty"},[c]));return}for(const R of z){const _=o("button",{type:"button",class:"rui-combobox-option",role:"option","data-value":R.value,"aria-selected":R.value===n?"true":"false"},[R.label]);_.onclick=Q=>{Q.stopPropagation(),S(Q.currentTarget,R.value)},$.append(_)}},S=($,N)=>{const A=t.argMeta?.[2]?.stateRef;A&&r.setState(A,N),m.set(!1),g.set("");const z=$.closest(".rui-combobox");z?.setAttribute("data-open","false"),z?.querySelector(".rui-combobox-trigger")?.setAttribute("aria-expanded","false"),he(z)};return T(w,g.get()),x.oninput=$=>{const N=$.currentTarget;g.set(N.value);const A=N.closest(".rui-combobox-panel")?.querySelector(".rui-combobox-list");A&&T(A,N.value)},x.onkeydown=$=>{const N=$;if(N.key!=="Enter")return;N.preventDefault();const R=N.currentTarget.closest(".rui-combobox")?.querySelector(".rui-combobox-option[data-value]"),_=R?.getAttribute("data-value");_!=null&&R&&S(R,_)},b.onclick=$=>{if(u)return;$.stopPropagation();const N=!m.get();m.set(N);const A=$.currentTarget.closest(".rui-combobox");if(A?.setAttribute("data-open",N?"true":"false"),A?.querySelector(".rui-combobox-trigger")?.setAttribute("aria-expanded",N?"true":"false"),!!A){if(!N){he(A);return}setTimeout(()=>x.focus(),0),Ee({liveRoot:A,onDismiss:()=>{m.set(!1),g.set(""),A.setAttribute("data-open","false"),A.querySelector(".rui-combobox-trigger")?.setAttribute("aria-expanded","false")}})}},h.append(y),h}},Ls={name:"MultiSelect",description:"Multi-option searchable dropdown. Type to filter, click an option to add/remove it from the bound array. Renders the selected options as removable chips inside the trigger. Pass a `$variable` (array of values) as `value` for two-way binding.",props:[{name:"id",type:"string"},{name:"items",type:"SelectItem[]",description:"Options; SelectItem(value, label) or {value, label}"},{name:"value",type:"any[]",optional:!0,description:"Bound array of selected values (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"emptyLabel",type:"string",optional:!0,description:"Text shown when no items match the filter"},{name:"max",type:"number",optional:!0,description:"Maximum number of selections"},{name:"disabled",type:"boolean",optional:!0},{name:"open",type:"boolean",optional:!0,description:"Initial open state — use to demo or pre-open the dropdown"}],render:(t,e,r)=>{const a=d(e.id),i=ya(e.items),n=d(e.placeholder,"Select…"),s=d(e.emptyLabel,"No matches"),l=C(e.disabled),c=Math.max(0,Math.floor(Number(e.max??0))),u=Array.isArray(e.value)?e.value.map(z=>d(z)).filter(Boolean):[],p=new Set(u),m=t.argMeta?.[2]?.stateRef,g=C(e.open),f=r.useInstanceState("open",g),h=r.useInstanceState("filter",""),b=f.get(),v=o("div",{class:"rui-multiselect","data-open":b?"true":"false","data-disabled":l?"true":"false"}),y=o("button",{type:"button",class:"rui-multiselect-trigger",id:a,"aria-haspopup":"listbox","aria-expanded":b?"true":"false",disabled:l?"":null}),x=o("span",{class:"rui-multiselect-chips"}),w=z=>{m&&r.setState(m,z)};if(u.length===0)x.append(o("span",{class:"rui-multiselect-placeholder"},[n]));else for(const z of u){const R=i.find(B=>B.value===z)?.label??z,_=o("span",{class:"rui-multiselect-chip","data-value":z});_.append(o("span",{class:"rui-multiselect-chip-label"},[R]));const Q=o("button",{type:"button",class:"rui-multiselect-chip-remove","aria-label":`Remove ${R}`},["×"]);Q.onclick=B=>{B.stopPropagation();const O=u.filter(J=>J!==z);w(O)},_.append(Q),x.append(_)}y.append(x);const T=L("chevron-down",{className:"rui-multiselect-chevron"});T&&y.append(T),v.append(y);const S=o("div",{class:"rui-multiselect-panel",role:"listbox","aria-multiselectable":"true"}),$=o("input",{type:"text",class:"rui-multiselect-filter",placeholder:"Filter…",autocomplete:"off",value:h.get()});S.append($);const N=o("div",{class:"rui-multiselect-list"});S.append(N);const A=(z,R)=>{z.replaceChildren();const _=R.trim().toLowerCase(),Q=_===""?i:i.filter(B=>B.label.toLowerCase().includes(_)||B.value.toLowerCase().includes(_));if(Q.length===0){z.append(o("div",{class:"rui-multiselect-empty"},[s]));return}for(const B of Q){const O=p.has(B.value),J=!O&&c>0&&u.length>=c,X=o("button",{type:"button",class:"rui-multiselect-option",role:"option","data-value":B.value,"data-selected":O?"true":"false","aria-selected":O?"true":"false",disabled:J?"":null}),ue=o("span",{class:"rui-multiselect-option-check"}),me=L(O?"check":"",{className:"rui-multiselect-option-check-icon"});me&&ue.append(me),X.append(ue),X.append(o("span",{class:"rui-multiselect-option-label"},[B.label])),X.onclick=Je=>{if(Je.stopPropagation(),J)return;const Ae=O?u.filter(Qt=>Qt!==B.value):[...u,B.value];w(Ae)},z.append(X)}};return A(N,h.get()),$.oninput=z=>{const R=z.currentTarget;h.set(R.value);const _=R.closest(".rui-multiselect-panel")?.querySelector(".rui-multiselect-list");_&&A(_,R.value)},y.onclick=z=>{if(l)return;z.stopPropagation();const R=!f.get();f.set(R);const _=z.currentTarget.closest(".rui-multiselect");if(_?.setAttribute("data-open",R?"true":"false"),_?.querySelector(".rui-multiselect-trigger")?.setAttribute("aria-expanded",R?"true":"false"),!!_){if(!R){he(_);return}setTimeout(()=>$.focus(),0),Ee({liveRoot:_,onDismiss:()=>{f.set(!1),h.set(""),_.setAttribute("data-open","false"),_.querySelector(".rui-multiselect-trigger")?.setAttribute("aria-expanded","false")}})}},v.append(S),v}},Es={name:"DateRangePicker",description:"Paired date inputs with a single label, sharing the same min/max range. Pass `$variable` references for both `from` and `to` to two-way-bind a date range (ISO `YYYY-MM-DD` strings).",props:[{name:"id",type:"string"},{name:"from",type:"string",optional:!0,description:"ISO date start; typically $variable"},{name:"to",type:"string",optional:!0,description:"ISO date end; typically $variable"},{name:"label",type:"string",optional:!0},{name:"min",type:"string",optional:!0,description:"Earliest selectable ISO date"},{name:"max",type:"string",optional:!0,description:"Latest selectable ISO date"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=`${a}-from`,n=`${a}-to`,s=d(e.min),l=d(e.max),c=C(e.disabled),u=o("div",{class:"rui-date-range-picker","data-disabled":c?"true":"false"}),p=d(e.label);p&&u.append(o("label",{class:"rui-date-range-picker-label",for:i},[p]));const m=o("div",{class:"rui-date-range-picker-row"}),g=o("input",{type:"date",class:"rui-date-range-picker-input",id:i,name:i,value:d(e.from),min:s||null,max:l||null,disabled:c?"":null,"data-role":"from"});m.append(g),m.append(o("span",{class:"rui-date-range-picker-separator","aria-hidden":"true"},["–"]));const f=o("input",{type:"date",class:"rui-date-range-picker-input",id:n,name:n,value:d(e.to),min:s||null,max:l||null,disabled:c?"":null,"data-role":"to"});m.append(f),u.append(m);const h=t.argMeta?.[1]?.stateRef,b=t.argMeta?.[2]?.stateRef;return h&&r.bindState(g,h),b&&r.bindState(f,b),u}};function _s(t,e,r){return Number.isNaN(t)?e===Number.NEGATIVE_INFINITY?0:e:Math.min(Math.max(t,e),r)}function js(t,e,r){const a=t.argMeta?[...t.argMeta]:[];for(;a.length<5;)a.push({});a[4]?.stateRef&&(a[2]=a[4]);const i=wa.render({...t,argMeta:a},{id:e.id,items:e.items,value:e.value,placeholder:e.placeholder,emptyLabel:"No matches",disabled:!1},r);return i.classList.add("rui-select-searchable"),i}function Ce(t,e,r,a){const i=e.argMeta?.[r]?.stateRef;if(i){if(t instanceof HTMLInputElement&&t.type==="checkbox"){a.bindState(t,i,{event:"change",getValue:n=>n.checked});return}a.bindState(t,i)}}function Bs(t,e){if(!e)return;const r=Array.isArray(e)?e.map(a=>String(a)):typeof e=="object"?Object.entries(e).map(([a,i])=>i?`${a}:${i}`:a):[];for(const a of r)a==="required"?t.required=!0:a.startsWith("minLength:")?t.minLength=Number(a.slice(10))||0:a.startsWith("maxLength:")?t.maxLength=Number(a.slice(10))||0:a==="email"&&(t.type="email")}const ve=["default","primary","success","warning","danger","info"],Te=(t,e)=>{const r=k(t);if(r.length===0)return null;const a=o("div",{class:"rui-pattern-actions"});for(const i of r)a.append(e.renderNode(i));return a},Ds=[{match:/\bbeta\b/i,label:"Beta"},{match:/\b(early\s?access|preview)\b/i,label:"Preview"},{match:/\b(introduc(?:ing|e)|launch(?:ed|ing)?|announcing)\b/i,label:"Introducing"},{match:/\b(welcome\b|get(?:ting)?\s?started)/i,label:"Welcome"},{match:/\b(new\b|whats\s?new|now\b)/i,label:"What's new"},{match:/\bfree\b/i,label:"Free trial"},{match:/\bupgrade\b/i,label:"Upgrade"},{match:/\b(sale|discount|deal)\b/i,label:"Limited time"}];function Fs(t,e){const r=`${t} ${e}`.trim();if(!r)return"";for(const a of Ds)if(a.match.test(r))return a.label;return""}const Os={name:"Hero",description:'Eye-catching landing/marketing header with eyebrow tag, title, subtitle, optional bullet highlights, and primary/secondary CTA buttons. Use `layout="cover"` with `imageSrc` for an image-backed hero band (pass `height` and optional `caption`). Default layout shows an optional side illustration.',props:[{name:"title",type:"string"},{name:"subtitle",type:"string",optional:!0},{name:"primary",type:"Button",optional:!0,description:"Primary CTA — pass a Button(...)"},{name:"secondary",type:"Button",optional:!0,description:"Secondary CTA — pass a Button(...)"},{name:"eyebrow",type:"string",optional:!0,description:"Short uppercase tag above the title"},{name:"highlights",type:"string[]",optional:!0,description:"Bullet items rendered as tag pills"},{name:"imageSrc",type:"string",optional:!0,description:"Illustration or cover background when layout=cover"},{name:"caption",type:"string",optional:!0,description:"Small caption above CTAs (cover layout)"},{name:"height",type:"string",optional:!0,description:"Min-height for cover layout (default 280px)"},{name:"actions",type:"Node[]",optional:!0,description:"CTA row (cover layout; alternative to primary/secondary)"},{name:"layout",type:"string",optional:!0,enum:["default","cover"],description:"default = text-first; cover = image-backed band"},{name:"tone",type:"string",optional:!0,enum:ve,description:"Accent tone"}],render:(t,e,r)=>{const a=d(e.layout,"default"),i=d(e.title),n=d(e.subtitle),l=d(e.eyebrow)||Fs(i,n),c=d(e.tone,"primary");if(a==="cover"){const h=lo(d(e.imageSrc)),b=ee(d(e.height),"280px"),v=o("section",{class:"rui-cover","data-tone":c,style:`background-image:linear-gradient(180deg, rgba(15, 23, 42, 0.05) 0%, rgba(15, 23, 42, 0.62) 100%), url("${h}");min-height:${b};`}),y=o("div",{class:"rui-cover-body"});l&&y.append(o("span",{class:"rui-cover-eyebrow"},[l])),y.append(o("h1",{class:"rui-cover-title"},[i])),n&&y.append(o("p",{class:"rui-cover-subtitle"},[n]));const x=d(e.caption);x&&y.append(o("p",{class:"rui-cover-caption"},[x]));const w=Te(e.actions,r);if(w)w.classList.add("rui-cover-actions"),y.append(w);else{const T=[e.primary,e.secondary].filter(Boolean);if(T.length>0){const S=o("div",{class:"rui-cover-actions rui-pattern-actions"});for(const $ of T)S.append(r.renderNode($));y.append(S)}}return v.append(y),v}const u=re(e.imageSrc),p=o("section",{class:"rui-hero","data-tone":c,"data-has-image":u?"true":"false"}),m=o("div",{class:"rui-hero-body"});l&&m.append(o("span",{class:"rui-hero-eyebrow"},[l])),m.append(o("h1",{class:"rui-hero-title"},[i])),n&&m.append(o("p",{class:"rui-hero-subtitle"},[n]));const g=k(e.highlights);if(g.length>0){const h=o("div",{class:"rui-hero-highlights"});for(const b of g){const v=d(b);v&&h.append(o("span",{class:"rui-hero-highlight"},[v]))}m.append(h)}const f=[e.primary,e.secondary].filter(Boolean);if(f.length>0){const h=o("div",{class:"rui-hero-ctas"});for(const b of f)h.append(r.renderNode(b));m.append(h)}if(p.append(m),u){const h=o("div",{class:"rui-hero-media"});h.append(o("img",{src:u,alt:"",loading:"lazy"})),p.append(h)}return p}},Us={name:"PageHeader",description:'Page-level header with breadcrumbs, title, subtitle, status tag, and a right-aligned actions row. The canonical first child for any dashboard, settings, or detail page — replaces ad-hoc Stack+Header+Buttons stitching. If `breadcrumbs` is omitted the component auto-derives `["Home", title]` so the page never lacks a trail. Pass `breadcrumbs=false` to opt out.',props:[{name:"title",type:"string"},{name:"subtitle",type:"string",optional:!0},{name:"breadcrumbs",type:"string[] | Breadcrumb | false",optional:!0,description:"Array of strings, a Breadcrumb(...) node, or `false` to suppress the auto-derived trail"},{name:"actions",type:"Node[]",optional:!0,description:"Buttons / NavLinks shown on the right"},{name:"status",type:"Badge",optional:!0,aliases:["badge"],description:"Optional Badge(...) rendered next to the title"}],render:(t,e,r)=>{const a=o("header",{class:"rui-page-header"}),i=d(e.title);let n=e.breadcrumbs;if(n==null?i&&(n=["Home",i]):(n===!1||n==="false")&&(n=null),n){const m=o("div",{class:"rui-page-header-breadcrumbs"});Array.isArray(n)?n.forEach((g,f)=>{f>0&&m.append(o("span",{class:"rui-page-header-crumb-sep"},["/"])),m.append(o("span",{class:"rui-page-header-crumb"},[d(g)]))}):m.append(r.renderNode(n)),a.append(m)}const s=o("div",{class:"rui-page-header-title-row"}),l=o("div",{class:"rui-page-header-title-block"}),c=o("div",{class:"rui-page-header-title-line"});c.append(o("h1",{class:"rui-page-header-title"},[i])),e.status&&c.append(r.renderNode(e.status)),l.append(c);const u=d(e.subtitle);u&&l.append(o("p",{class:"rui-page-header-subtitle"},[u])),s.append(l);const p=Te(e.actions,r);return p&&(p.classList.add("rui-page-header-actions"),s.append(p)),a.append(s),a}},qs={name:"EmptyState",description:"Zero-state placeholder for empty lists, searches, dashboards. Renders a centered icon (or illustration), title, description, and either a single `action` Button or an `actions` row (primary + secondary). Always preferable to an empty Card with raw text.",props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0},{name:"icon",type:"string",optional:!0,description:'Font Awesome icon name (defaults to "inbox")'},{name:"illustration",type:"string",optional:!0,description:"Image URL — takes precedence over `icon` when provided"},{name:"action",type:"Button",optional:!0,description:"Single CTA (legacy slot)"},{name:"actions",type:"Node[]",optional:!0,description:"Row of CTA Buttons / Links — preferred over `action` for primary + secondary affordances"}],render:(t,e,r)=>{const a=o("div",{class:"rui-empty-state"}),i=re(e.illustration);if(i)a.append(o("img",{class:"rui-empty-state-illustration",src:i,alt:"",loading:"lazy"}));else{const l=d(e.title),c=d(e.description),u=d(e.icon)||va(`${l} ${c}`)||"inbox",p=L(u,{className:"rui-empty-state-icon"});p&&a.append(p)}a.append(o("h3",{class:"rui-empty-state-title"},[d(e.title)]));const n=d(e.description);n&&a.append(o("p",{class:"rui-empty-state-description"},[n]));const s=k(e.actions);if(s.length>0){const l=o("div",{class:"rui-empty-state-actions"});for(const c of s)l.append(r.renderNode(c));a.append(l)}else if(e.action){const l=o("div",{class:"rui-empty-state-action"});l.append(r.renderNode(e.action)),a.append(l)}return a}},Hs={name:"TimelineItem",description:"Single event on a Timeline.",props:[{name:"title",type:"string"},{name:"time",type:"string",optional:!0,description:"Display label (ISO, relative, etc.)"},{name:"description",type:"string",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name rendered inside the marker"},{name:"tone",type:"string",optional:!0,enum:ve}],render:(t,e)=>{const r=o("li",{class:"rui-timeline-item","data-tone":d(e.tone,"default")}),a=o("span",{class:"rui-timeline-marker"}),i=L(e.icon);i&&a.append(i),r.append(a);const n=o("div",{class:"rui-timeline-body"}),s=o("div",{class:"rui-timeline-head"});s.append(o("span",{class:"rui-timeline-title"},[d(e.title)]));const l=d(e.time);l&&s.append(o("span",{class:"rui-timeline-time"},[l])),n.append(s);const c=d(e.description);return c&&n.append(o("div",{class:"rui-timeline-description"},[c])),r.append(n),r}},Vs={name:"Timeline",description:"Vertical event timeline. Children must be TimelineItem entries. Ideal for activity feeds, changelogs, and process flows.",props:[{name:"items",type:"TimelineItem[]"}],render:(t,e,r)=>{const a=o("ol",{class:"rui-timeline"});for(const i of k(e.items))a.append(r.renderNode(i));return a}},Ws={name:"FeatureItem",description:"Single tile on a FeatureGrid.",props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown in a colored disc"},{name:"tone",type:"string",optional:!0,enum:ve}],render:(t,e)=>{const r=o("div",{class:"rui-feature-item","data-tone":d(e.tone,"primary")}),a=d(e.icon,"sparkles"),i=L(a,{className:"rui-feature-icon"});i&&r.append(i),r.append(o("h3",{class:"rui-feature-title"},[d(e.title)]));const n=d(e.description);return n&&r.append(o("p",{class:"rui-feature-description"},[n])),r}},Gs={name:"FeatureGrid",description:"Responsive grid of FeatureItem tiles (typically 2–3 columns). Use to highlight product capabilities or page categories.",props:[{name:"items",type:"FeatureItem[]"},{name:"columns",type:"number",optional:!0,description:"Preferred column count (default auto)"}],render:(t,e,r)=>{const a=Math.max(1,Math.min(4,Number(e.columns??"auto"))),i=o("div",{class:"rui-feature-grid","data-columns":a>0?String(a):null});for(const n of k(e.items))i.append(r.renderNode(n));return i}},Ks={name:"Testimonial",description:"Quote card with author, role, and optional avatar.",props:[{name:"quote",type:"string"},{name:"author",type:"string",aliases:["name"]},{name:"role",type:"string",optional:!0},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"]},{name:"rating",type:"number",optional:!0,description:"0–5 stars"}],render:(t,e)=>{const r=o("figure",{class:"rui-testimonial"}),a=Math.max(0,Math.min(5,Math.round(Number(e.rating??0))));if(a>0){const c=o("div",{class:"rui-testimonial-rating"});for(let u=0;u<5;u+=1){const p=u<a,m=L(p?"star":"regular:star",{className:"rui-testimonial-rating-star"});m&&c.append(m)}r.append(c)}r.append(o("blockquote",{class:"rui-testimonial-quote"},[d(e.quote)]));const i=o("figcaption",{class:"rui-testimonial-author"}),n=re(e.avatarSrc);n&&i.append(o("img",{class:"rui-testimonial-avatar",src:n,alt:""}));const s=o("div",{class:"rui-testimonial-meta"});s.append(o("div",{class:"rui-testimonial-name"},[d(e.author)]));const l=d(e.role);return l&&s.append(o("div",{class:"rui-testimonial-role"},[l])),i.append(s),r.append(i),r}},Ys={name:"ProfileCard",description:"Compact profile/user card with avatar, name, role, optional bio, social tags, and a row of action buttons. Use for team rosters, contributor lists, and contact panels.",props:[{name:"name",type:"string"},{name:"role",type:"string",optional:!0},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"],description:"Avatar image src; falls back to initials"},{name:"bio",type:"string",optional:!0},{name:"tags",type:"string[]",optional:!0},{name:"actions",type:"Node[]",optional:!0,description:"Buttons to render at the bottom"}],render:(t,e,r)=>{const a=o("div",{class:"rui-profile-card"}),i=o("div",{class:"rui-profile-card-header"});i.append(Ve(d(e.avatarSrc),d(e.name),"lg"));const n=o("div",{class:"rui-profile-card-meta"});n.append(o("h3",{class:"rui-profile-card-name"},[d(e.name)]));const s=d(e.role);s&&n.append(o("p",{class:"rui-profile-card-role"},[s])),i.append(n),a.append(i);const l=d(e.bio);l&&a.append(o("p",{class:"rui-profile-card-bio"},[l]));const c=k(e.tags);if(c.length>0){const p=o("div",{class:"rui-profile-card-tags"});for(const m of c){const g=d(m);g&&p.append(o("span",{class:"rui-tag","data-size":"sm"},[o("span",{class:"rui-tag-label"},[g])]))}a.append(p)}const u=Te(e.actions,r);return u&&(u.classList.add("rui-profile-card-actions"),a.append(u)),a}},Js={name:"Comment",description:"Single comment / message bubble. Renders avatar, author, timestamp, body, and an optional row of action buttons (reply, like, …).",props:[{name:"author",type:"string"},{name:"body",type:"string",aliases:["text","message"]},{name:"time",type:"string",optional:!0,description:"Relative or absolute timestamp"},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"]},{name:"actions",type:"Node[]",optional:!0}],render:(t,e,r)=>{const a=o("article",{class:"rui-comment"});a.append(Ve(d(e.avatarSrc),d(e.author),"md"));const i=o("div",{class:"rui-comment-body"}),n=o("header",{class:"rui-comment-header"});n.append(o("span",{class:"rui-comment-author"},[d(e.author)]));const s=d(e.time);s&&n.append(o("span",{class:"rui-comment-time"},[s])),i.append(n),i.append(o("div",{class:"rui-comment-content"},[d(e.body)]));const l=Te(e.actions,r);return l&&(l.classList.add("rui-comment-actions"),i.append(l)),a.append(i),a}},Xs={name:"Banner",description:"Full-width announcement banner. Use at the top of a page for promos, release notes, or downtime notices. For inline notices prefer Callout or Alert.",props:[{name:"title",type:"string"},{name:"message",type:"string",optional:!0,aliases:["description"]},{name:"action",type:"Button",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name"},{name:"tone",type:"string",optional:!0,enum:ve}],render:(t,e,r)=>{const a=d(e.tone,"primary"),i=o("aside",{class:"rui-banner","data-tone":a}),n=d(e.icon)||ps(a)||"",s=L(n,{className:"rui-banner-icon"});s&&i.append(s);const l=o("div",{class:"rui-banner-body"});l.append(o("strong",{class:"rui-banner-title"},[d(e.title)]));const c=d(e.message);if(c&&l.append(o("span",{class:"rui-banner-message"},[c])),i.append(l),e.action){const u=o("div",{class:"rui-banner-action"});u.append(r.renderNode(e.action)),i.append(u)}return i}},Zs={name:"KanbanCard",description:"Single card on a Kanban board.",props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0},{name:"tags",type:"string[]",optional:!0},{name:"assignee",type:"string",optional:!0,description:"Name shown next to avatar initials"},{name:"tone",type:"string",optional:!0,enum:ve},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name shown beside the title"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Optional callable fired when the card is clicked"}],render:(t,e,r)=>{const a=o("div",{class:"rui-kanban-card","data-tone":d(e.tone,"default")});typeof e.action=="function"&&(a.setAttribute("role","button"),a.setAttribute("tabindex","0"),a.onclick=()=>r.invoke(e.action),a.onkeydown=u=>{const p=u;(p.key==="Enter"||p.key===" ")&&(p.preventDefault(),r.invoke(e.action))});const i=o("div",{class:"rui-kanban-card-title"}),n=L(e.icon,{className:"rui-kanban-card-icon"});n&&i.append(n),i.append(document.createTextNode(d(e.title))),a.append(i);const s=d(e.description);s&&a.append(o("p",{class:"rui-kanban-card-description"},[s]));const l=k(e.tags);if(l.length>0){const u=o("div",{class:"rui-kanban-card-tags"});for(const p of l){const m=d(p);m&&u.append(o("span",{class:"rui-tag","data-size":"sm"},[o("span",{class:"rui-tag-label"},[m])]))}a.append(u)}const c=d(e.assignee);if(c){const u=o("footer",{class:"rui-kanban-card-footer"});u.append(Ve("",c,"sm")),u.append(o("span",{class:"rui-kanban-card-assignee"},[c])),a.append(u)}return a}},Qs={name:"KanbanColumn",description:"Single column inside a KanbanBoard. Children must be KanbanCard entries.",props:[{name:"title",type:"string"},{name:"items",type:"KanbanCard[]",aliases:["cards"]},{name:"tone",type:"string",optional:!0,enum:ve,description:"Header accent tone"}],render:(t,e,r)=>{const a=k(e.items),i=o("section",{class:"rui-kanban-column","data-tone":d(e.tone,"default")}),n=o("header",{class:"rui-kanban-column-header"});n.append(o("span",{class:"rui-kanban-column-title"},[d(e.title)])),n.append(o("span",{class:"rui-kanban-column-count"},[String(a.length)])),i.append(n);const s=o("div",{class:"rui-kanban-column-body"});for(const l of a)s.append(r.renderNode(l));return a.length===0&&s.append(o("div",{class:"rui-kanban-column-empty"},["No items"])),i.append(s),i}},el={name:"KanbanBoard",description:"Horizontal Kanban board. Children must be KanbanColumn entries. The board scrolls horizontally on narrow viewports so columns stay readable.",props:[{name:"columns",type:"KanbanColumn[]"}],render:(t,e,r)=>{const a=o("div",{class:"rui-kanban-board"});for(const i of k(e.columns))a.append(r.renderNode(i));return a}},tl={name:"SectionHeader",description:"Compact section header for the top of a Card or panel. Renders a small eyebrow, a title, an optional subtitle, an optional status Tag/Badge, and a right-aligned actions row. Use this inside a Card to introduce a section instead of a bare `CardHeader`.",props:[{name:"title",type:"string"},{name:"subtitle",type:"string",optional:!0,aliases:["description"]},{name:"eyebrow",type:"string",optional:!0,description:"Short uppercase label above the title"},{name:"status",type:"Badge | Tag",optional:!0,aliases:["badge"]},{name:"actions",type:"Node[]",optional:!0,description:"Buttons / Links shown on the right"}],render:(t,e,r)=>{const a=o("header",{class:"rui-section-header"}),i=o("div",{class:"rui-section-header-left"}),n=d(e.eyebrow);n&&i.append(o("span",{class:"rui-section-header-eyebrow"},[n]));const s=o("div",{class:"rui-section-header-title-line"});s.append(o("h3",{class:"rui-section-header-title"},[d(e.title)])),e.status&&s.append(r.renderNode(e.status)),i.append(s);const l=d(e.subtitle);l&&i.append(o("p",{class:"rui-section-header-subtitle"},[l])),a.append(i);const c=Te(e.actions,r);return c&&(c.classList.add("rui-section-header-actions"),a.append(c)),a}},rl={name:"Toolbar",description:"Horizontal toolbar for filters, search, view modes, and primary actions. Left/center/right slots wrap onto separate rows on narrow viewports so the bar never overflows. Pass `searchable: true` to auto-mount a SearchBar in the left slot (bind `searchValue` to a `$variable`). Use ABOVE a Table, List, Grid, or Kanban view — never replace `PageHeader` with it.",props:[{name:"left",type:"Node[]",optional:!0,description:"Filters / search inputs / chips"},{name:"right",type:"Node[]",optional:!0,description:"Primary action buttons"},{name:"center",type:"Node[]",optional:!0,description:"Centered controls (e.g. SegmentedControl, search bar)"},{name:"searchable",type:"boolean",optional:!0,description:"Auto-mount a SearchBar at the start of the left slot"},{name:"searchPlaceholder",type:"string",optional:!0,description:"Placeholder for the auto-mounted SearchBar"},{name:"searchValue",type:"string",optional:!0,description:"$variable bound to the auto-mounted SearchBar"}],render:(t,e,r)=>{const a=k(e.center),i=o("div",{class:"rui-toolbar","data-has-center":a.length>0?"true":"false"}),n=o("div",{class:"rui-toolbar-side rui-toolbar-left"});C(e.searchable)&&n.append(xa.render({__kind:"Component",name:"SearchBar",args:[],argMeta:[]},{id:"toolbar-search",placeholder:d(e.searchPlaceholder,"Search…"),value:e.searchValue},r));for(const l of k(e.left))n.append(r.renderNode(l));if(i.append(n),a.length>0){const l=o("div",{class:"rui-toolbar-side rui-toolbar-center"});for(const c of a)l.append(r.renderNode(c));i.append(l)}const s=o("div",{class:"rui-toolbar-side rui-toolbar-right"});for(const l of k(e.right))s.append(r.renderNode(l));return i.append(s),i}},al={name:"SidebarItem",description:"Single navigation item inside a Sidebar. Pass `active=true` to mark as the current page, an `action` Action for click handling, or an optional `badge` (string/number) for a trailing chip.",props:[{name:"label",type:"string"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name rendered before the label"},{name:"active",type:"boolean",optional:!0},{name:"badge",type:"string",optional:!0,description:"Trailing chip (count or status)"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"]}],render:(t,e,r)=>{const a=o("button",{type:"button",class:"rui-sidebar-item","data-active":C(e.active)?"true":"false"}),i=L(e.icon,{className:"rui-sidebar-item-icon"});i&&a.append(i),a.append(o("span",{class:"rui-sidebar-item-label"},[d(e.label)]));const n=d(e.badge);return n&&a.append(o("span",{class:"rui-sidebar-item-badge"},[n])),typeof e.action=="function"&&(a.onclick=()=>r.invoke(e.action)),a}},il={name:"SidebarSection",description:"Grouping inside a Sidebar — small uppercase label followed by SidebarItem entries. Use this to chunk a long sidebar into sections.",props:[{name:"label",type:"string"},{name:"items",type:"SidebarItem[]"}],render:(t,e,r)=>{const a=o("div",{class:"rui-sidebar-section"}),i=d(e.label);i&&a.append(o("div",{class:"rui-sidebar-section-label"},[i]));for(const n of k(e.items))a.append(r.renderNode(n));return a}},nl={name:"Sidebar",description:"Vertical app navigation panel. Supports a brand header, navigation items (`SidebarItem` or `SidebarSection`), an optional footer, and a `collapsed` mode that hides labels to leave just an icon rail. Use inside `AppShell` for SaaS-style left navigation.",props:[{name:"items",type:"(SidebarItem | SidebarSection)[]"},{name:"brand",type:"string",optional:!0,description:"Product name / workspace label at the top"},{name:"tagline",type:"string",optional:!0},{name:"footer",type:"Node[]",optional:!0,description:"Footer block (Avatar + name, upgrade CTA, …)"},{name:"collapsed",type:"boolean",optional:!0,description:"Render as an icon-only rail (hides labels/badges)"}],render:(t,e,r)=>{const a=C(e.collapsed),i=o("aside",{class:"rui-sidebar"});a&&(i.dataset.collapsed="true");const n=d(e.brand),s=d(e.tagline);if(n||s){const u=o("div",{class:"rui-sidebar-header"});n&&u.append(o("div",{class:"rui-sidebar-brand"},[n])),s&&u.append(o("div",{class:"rui-sidebar-tagline"},[s])),i.append(u)}const l=o("nav",{class:"rui-sidebar-body"});for(const u of k(e.items))l.append(r.renderNode(u));i.append(l);const c=k(e.footer);if(c.length>0){const u=o("div",{class:"rui-sidebar-footer"});for(const p of c)u.append(r.renderNode(p));i.append(u)}return i}},ol={name:"AppShell",description:"Canonical SaaS application shell: optional top bar, fixed left Sidebar, and scrollable main content. Reach for this whenever a response represents a full product surface (dashboard with nav, settings + sections, admin panels). Pass `collapsible=true` to render a hamburger that turns the sidebar into a slide-over drawer on narrow viewports.",props:[{name:"sidebar",type:"Sidebar",description:"Pass a Sidebar(...) node"},{name:"content",type:"Node[]",description:"Main content (typically starts with a PageHeader)"},{name:"topbar",type:"Node[]",optional:!0,description:"Optional thin top bar above the content"},{name:"collapsible",type:"boolean",optional:!0,description:"Show a hamburger that toggles the sidebar drawer on mobile"},{name:"sidebarOpen",type:"boolean",optional:!0,description:"$variable controlling whether the mobile drawer is open"}],render:(t,e,r)=>{const a=C(e.collapsible),i=C(e.sidebarOpen),n=o("div",{class:"rui-app-shell"});a&&(n.dataset.collapsible="true"),i&&(n.dataset.sidebarOpen="true");const s=o("div",{class:"rui-app-shell-sidebar"});if(s.append(r.renderNode(e.sidebar)),n.append(s),a){const p=o("div",{class:"rui-app-shell-scrim","aria-hidden":"true"});p.addEventListener("click",()=>{delete n.dataset.sidebarOpen}),n.append(p)}const l=o("div",{class:"rui-app-shell-main"}),c=k(e.topbar);if(c.length>0||a){const p=o("div",{class:"rui-app-shell-topbar"});if(a){const m=o("button",{class:"rui-app-shell-toggle",type:"button","aria-label":"Toggle navigation"});m.append(L("bars",{size:"md"})??document.createTextNode("≡")),m.addEventListener("click",()=>{n.dataset.sidebarOpen?delete n.dataset.sidebarOpen:n.dataset.sidebarOpen="true"}),p.append(m)}for(const m of c)p.append(r.renderNode(m));l.append(p)}const u=o("div",{class:"rui-app-shell-content"});for(const p of k(e.content))u.append(r.renderNode(p));return l.append(u),n.append(l),n}},sl={name:"SplitView",description:"Two-pane master/detail layout — a narrow primary pane on the left, wider detail pane on the right. Collapses to a single column on narrow viewports. Use for inboxes, file browsers, contact lists.",props:[{name:"primary",type:"Node[]",description:"Master pane content (list, filters)"},{name:"detail",type:"Node[]",aliases:["secondary"],description:"Detail pane content (selected item, empty state)"},{name:"primaryWidth",type:"string",optional:!0,aliases:["splitAt"],description:"CSS width for the primary pane (default 320px)"}],render:(t,e,r)=>{const a=ee(d(e.primaryWidth),"320px"),i=o("div",{class:"rui-split-view",style:`--rui-split-primary:${a}`}),n=o("div",{class:"rui-split-view-primary"});for(const l of k(e.primary))n.append(r.renderNode(l));const s=o("div",{class:"rui-split-view-detail"});for(const l of k(e.detail))s.append(r.renderNode(l));return i.append(n,s),i}},ll={name:"DescriptionItem",description:"Single row inside a DescriptionList. Renders a small uppercase label on the left and a value (string or arbitrary Node) on the right.",props:[{name:"label",type:"string"},{name:"value",type:"Node | string"},{name:"icon",type:"string",optional:!0}],render:(t,e,r)=>{const a=o("div",{class:"rui-description-item"}),i=o("dt",{class:"rui-description-label"}),n=L(e.icon,{className:"rui-description-icon"});n&&i.append(n),i.append(document.createTextNode(d(e.label)));const s=o("dd",{class:"rui-description-value"});return e.value&&typeof e.value=="object"&&e.value.__kind==="Component"?s.append(r.renderNode(e.value)):s.append(document.createTextNode(d(e.value))),a.append(i,s),a}},cl={name:"DescriptionList",description:"Compact key/value summary for detail pages — replaces a row of `Text`s with a properly aligned `<dl>`. Children must be DescriptionItem entries. Two columns by default on wide viewports.",props:[{name:"items",type:"DescriptionItem[]"},{name:"columns",type:"number",optional:!0,description:"1 or 2 (default 2)"}],render:(t,e,r)=>{const a=Math.max(1,Math.min(2,Math.floor(Number(e.columns??2)))),i=o("dl",{class:"rui-description-list","data-columns":String(a)});for(const n of k(e.items))i.append(r.renderNode(n));return i}},ul={name:"StatusDot",description:"Inline status pip + label. Use for compact health/state indicators in toolbars, sidebars, lists, and table cells.",props:[{name:"label",type:"string"},{name:"tone",type:"string",optional:!0,enum:["default","primary","success","warning","danger","info"]},{name:"pulse",type:"boolean",optional:!0,description:"Animate the dot for 'live' state"}],render:(t,e)=>{const r=o("span",{class:"rui-status-dot","data-tone":d(e.tone,"success"),"data-pulse":C(e.pulse)?"true":"false"});return r.append(o("span",{class:"rui-status-dot-marker"})),r.append(o("span",{class:"rui-status-dot-label"},[d(e.label)])),r}},dl={name:"PricingCard",description:"Single pricing tier card with plan name, price, billing period, description, bullet features, and a CTA button. Mark one tier as `featured=true` to highlight it (raises the card, adds a ribbon).",props:[{name:"plan",type:"string",description:"Tier name (e.g. 'Pro')"},{name:"price",type:"string",description:"Display price (e.g. '$29')"},{name:"period",type:"string",optional:!0,description:"Billing period (e.g. '/mo')"},{name:"description",type:"string",optional:!0},{name:"features",type:"string[]",optional:!0,description:"Bullet list of included features"},{name:"action",type:"Button",optional:!0,aliases:["cta"],description:"Primary CTA — pass a Button(...)"},{name:"badge",type:"string",optional:!0,description:"Eyebrow / badge above the plan name"},{name:"featured",type:"boolean",optional:!0,aliases:["highlighted"]}],render:(t,e,r)=>{const a=C(e.featured),i=o("article",{class:"rui-pricing-card","data-featured":a?"true":"false"}),n=d(e.badge);n&&i.append(o("div",{class:"rui-pricing-card-badge"},[n])),i.append(o("h3",{class:"rui-pricing-card-plan"},[d(e.plan)]));const s=d(e.description);s&&i.append(o("p",{class:"rui-pricing-card-description"},[s]));const l=o("div",{class:"rui-pricing-card-price-row"});l.append(o("span",{class:"rui-pricing-card-price"},[d(e.price)]));const c=d(e.period);c&&l.append(o("span",{class:"rui-pricing-card-period"},[c])),i.append(l);const u=k(e.features);if(u.length>0){const p=o("ul",{class:"rui-pricing-card-features"});for(const m of u){const g=d(m);if(!g)continue;const f=L("circle-check",{className:"rui-pricing-card-check"})??o("span",{class:"rui-pricing-card-check"});p.append(o("li",{class:"rui-pricing-card-feature"},[f,document.createTextNode(g)]))}i.append(p)}if(e.action){const p=o("div",{class:"rui-pricing-card-action"});p.append(r.renderNode(e.action)),i.append(p)}return i}},pl={name:"PricingTable",description:"Responsive grid of PricingCard tiers. Items size uniformly across a row and wrap onto multiple rows on narrow viewports. Use as the centerpiece of any pricing or upgrade page.",props:[{name:"tiers",type:"PricingCard[]"},{name:"columns",type:"number",optional:!0,description:"Preferred column count (default auto)"}],render:(t,e,r)=>{const a=Math.max(1,Math.min(4,Math.floor(Number(e.columns??"auto")))),i=o("div",{class:"rui-pricing-table","data-columns":a>0?String(a):null});for(const n of k(e.tiers))i.append(r.renderNode(n));return i}},ml={name:"MediaCard",description:'Card with a media (image) header followed by title, body, optional tags, footer meta, and an actions row. Use for article previews, product cards, project highlights, gallery items — anywhere a Card needs a leading image. Orient with `orientation="horizontal"` for side-by-side media + content on wide viewports.',props:[{name:"title",type:"string"},{name:"imageSrc",type:"string",optional:!0,aliases:["src","image"],description:"Image URL (omit to render a neutral placeholder)"},{name:"description",type:"string",optional:!0},{name:"tags",type:"string[]",optional:!0,description:"Tag pill labels"},{name:"meta",type:"string",optional:!0,description:"Footer meta line (author · date · category)"},{name:"actions",type:"Node[]",optional:!0,description:"Buttons / Links rendered at the bottom"},{name:"badge",type:"string | Badge",optional:!0,description:"Eyebrow string or Badge node shown over the image"},{name:"orientation",type:"string",optional:!0,enum:["vertical","horizontal"]},{name:"ratio",type:"string",optional:!0,description:"Media aspect ratio (default 16:9 vertical, 4:3 horizontal)"}],render:(t,e,r)=>{const a=d(e.orientation,"vertical"),i=o("article",{class:"rui-media-card","data-orientation":a}),n=gl(d(e.ratio,a==="horizontal"?"4:3":"16:9")),s=o("div",{class:"rui-media-card-media",style:`aspect-ratio:${n};`}),l=re(e.imageSrc);if(l)s.append(o("img",{src:l,alt:d(e.title),loading:"lazy"}));else{s.classList.add("rui-media-card-media-empty");const f=L("image",{className:"rui-media-card-placeholder"})??o("span",{class:"rui-media-card-placeholder"});s.append(f)}if(e.badge){const f=o("span",{class:"rui-media-card-badge"});typeof e.badge=="string"?f.append(document.createTextNode(d(e.badge))):f.append(r.renderNode(e.badge)),s.append(f)}i.append(s);const c=o("div",{class:"rui-media-card-body"});c.append(o("h3",{class:"rui-media-card-title"},[d(e.title)]));const u=d(e.description);u&&c.append(o("p",{class:"rui-media-card-description"},[u]));const p=k(e.tags);if(p.length>0){const f=o("div",{class:"rui-media-card-tags"});for(const h of p){const b=d(h);b&&f.append(o("span",{class:"rui-tag","data-size":"sm"},[o("span",{class:"rui-tag-label"},[b])]))}c.append(f)}const m=d(e.meta);m&&c.append(o("p",{class:"rui-media-card-meta"},[m]));const g=Te(e.actions,r);return g&&(g.classList.add("rui-media-card-actions"),c.append(g)),i.append(c),i}};function gl(t){if(t.includes(":")){const[r,a]=t.split(":"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n>0)return`${i} / ${n}`}const e=Number(t);return Number.isFinite(e)&&e>0?`${e} / 1`:"16 / 9"}function Et(t,e="primary"){const i="http://www.w3.org/2000/svg",n=document.createElementNS(i,"svg");if(n.setAttribute("class","rui-sparkline"),n.setAttribute("data-tone",e),n.setAttribute("viewBox","0 0 80 24"),n.setAttribute("width",String(80)),n.setAttribute("height",String(24)),n.setAttribute("aria-hidden","true"),t.length<2)return n;const s=Math.min(...t),l=Math.max(...t),c=l-s||1,u=80/(t.length-1),m=t.map((b,v)=>{const y=v*u,x=2+(l-b)/c*20;return[y,x]}).map(([b,v],y)=>`${y===0?"M":"L"}${b.toFixed(1)},${v.toFixed(1)}`).join(" "),g=`${m} L80,24 L0,24 Z`,f=document.createElementNS(i,"path");f.setAttribute("d",g),f.setAttribute("class","rui-sparkline-area"),n.appendChild(f);const h=document.createElementNS(i,"path");return h.setAttribute("d",m),h.setAttribute("class","rui-sparkline-line"),h.setAttribute("fill","none"),n.appendChild(h),n}const fl={name:"Stats",description:'KPI strip or grid. Pass `items` as `{label, value, hint?, tone?, spark?}` objects for strip layout, or as `StatCard(...)` nodes when `layout="grid"`.',props:[{name:"items",type:"object[] | StatCard[]",description:"Stat objects or StatCard nodes when layout=grid"},{name:"layout",type:"string",optional:!0,enum:["strip","grid"],description:"strip = horizontal row; grid = responsive Grid"},{name:"columns",type:"number",optional:!0,description:"Preferred column count for grid layout (1–6)"},{name:"align",type:"string",optional:!0,enum:["start","center","end"],description:"Strip alignment (layout=strip only)"}],render:(t,e,r)=>{const a=k(e.items),i=a.some(c=>c&&typeof c=="object"&&c.__kind==="Component");if(d(e.layout,i?"grid":"strip")==="grid"){const c=e.columns?Math.max(1,Math.min(6,Math.floor(P(e.columns)))):0,u=ma.render({__kind:"Component",name:"Grid",args:[],argMeta:[]},{children:a,columns:c>0?c:"auto",gap:"m"},r);return u.classList.add("rui-metric-grid"),u}const s=d(e.align,"start"),l=o("div",{class:"rui-stats","data-align":s});for(const c of a){const u=c??{},p=d(u.tone,"default"),m=o("div",{class:"rui-stats-item","data-tone":p});m.append(o("div",{class:"rui-stats-label"},[d(u.label)]));const g=o("div",{class:"rui-stats-value-row"});g.append(o("div",{class:"rui-stats-value"},[d(u.value)]));const f=k(u.spark).map(b=>Number(b)).filter(b=>Number.isFinite(b));f.length>1&&g.append(Et(f,p)),m.append(g);const h=d(u.hint);h&&m.append(o("div",{class:"rui-stats-hint"},[h])),l.append(m)}return l}},hl={name:"Tile",description:"Compact icon + label + optional value tile. Smaller and denser than `StatCard`, ideal for menu grids, quick-action panels, category directories, and category filters. Pair with `Grid` for uniform rows.",props:[{name:"label",type:"string"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown in a colored disc"},{name:"value",type:"string",optional:!0,description:"Secondary value rendered next to/under the label"},{name:"description",type:"string",optional:!0},{name:"tone",type:"string",optional:!0,enum:ve},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"]}],render:(t,e,r)=>{const a=typeof e.action=="function",n=o(a?"button":"div",{type:a?"button":null,class:"rui-tile","data-tone":d(e.tone,"default")}),s=L(e.icon,{className:"rui-tile-icon"});s&&n.append(s);const l=o("div",{class:"rui-tile-body"});l.append(o("div",{class:"rui-tile-label"},[d(e.label)]));const c=d(e.value);c&&l.append(o("div",{class:"rui-tile-value"},[c]));const u=d(e.description);return u&&l.append(o("div",{class:"rui-tile-description"},[u])),n.append(l),a&&(n.onclick=()=>r.invoke(e.action)),n}},ka={name:"Notification",description:"Inline notification card with title, message, time, optional avatar, and dismiss/action buttons. Use inside notification panels, inboxes, or activity drawers — for top-of-page announcements prefer `Banner`.",props:[{name:"title",type:"string"},{name:"message",type:"string",optional:!0,aliases:["description"]},{name:"time",type:"string",optional:!0,description:"Relative or absolute timestamp"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown in a colored disc"},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"],description:"Avatar URL (alternative to `icon`)"},{name:"tone",type:"string",optional:!0,enum:ve},{name:"unread",type:"boolean",optional:!0,description:"Highlights the card with an accent"},{name:"actions",type:"Node[]",optional:!0}],render:(t,e,r)=>{const a=o("article",{class:"rui-notification","data-tone":d(e.tone,"default"),"data-unread":C(e.unread)?"true":"false"}),i=d(e.avatarSrc);if(i)a.append(Ve(i,d(e.title),"md"));else{const p=L(d(e.icon,"bell"),{className:"rui-notification-icon"});p&&a.append(p)}const n=o("div",{class:"rui-notification-body"}),s=o("header",{class:"rui-notification-head"});s.append(o("span",{class:"rui-notification-title"},[d(e.title)]));const l=d(e.time);l&&s.append(o("span",{class:"rui-notification-time"},[l])),n.append(s);const c=d(e.message);c&&n.append(o("p",{class:"rui-notification-message"},[c]));const u=Te(e.actions,r);return u&&(u.classList.add("rui-notification-actions"),n.append(u)),a.append(n),a}},bl={name:"PersonChip",description:'Inline avatar + name + optional role/meta pill. Use anywhere a person needs to be referenced compactly: table cells, list rows, comments, kanban cards, sidebar footers. Pair multiple chips with `Stack(direction="row", wrap=true)` for assignee lists.',props:[{name:"name",type:"string"},{name:"role",type:"string",optional:!0,description:"Sub-line below the name (role, email, handle, …)"},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"]},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]},{name:"status",type:"string",optional:!0,enum:["online","offline","busy","away"]},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"]}],render:(t,e,r)=>{const a=typeof e.action=="function",i=a?"button":"div",n=d(e.size,"md"),s=n==="lg"?"lg":n==="sm"?"sm":"md",l=o(i,{type:a?"button":null,class:"rui-person-chip","data-size":n}),c=o("span",{class:"rui-person-chip-avatar"});c.append(Ve(d(e.avatarSrc),d(e.name),s));const u=d(e.status);u&&c.append(o("span",{class:"rui-person-chip-status","data-status":u})),l.append(c);const p=o("div",{class:"rui-person-chip-meta"});p.append(o("span",{class:"rui-person-chip-name"},[d(e.name)]));const m=d(e.role);return m&&p.append(o("span",{class:"rui-person-chip-role"},[m])),l.append(p),a&&(l.onclick=()=>r.invoke(e.action)),l}},Sa=["left","center","right"],vl={name:"Col",description:"Single column inside a Table or DataGrid. Use `align` for per-column text alignment, `format` for cell rendering (`text|number|currency|date`). `sortable` and `filterable` only take effect inside `DataGrid` (Table ignores them).",props:[{name:"header",type:"string"},{name:"values",type:"any[]",description:"Column values (use array pluck like data.rows.title)"},{name:"format",type:"string",optional:!0,enum:["text","number","currency","date"]},{name:"align",type:"string",optional:!0,enum:Sa,description:"Per-column horizontal alignment"},{name:"sortable",type:"boolean",optional:!0,description:"DataGrid: enable click-to-sort on this column"},{name:"filterable",type:"boolean",optional:!0,description:"DataGrid: enable a per-column filter chip"}],render:(t,e)=>{const r=o("div",{class:"rui-col"});return r.append(o("strong",{},[d(e.header)])),r}},yl={name:"Table",description:'Tabular data view. Children must be Col components. `density="compact"` tightens row padding for dense data, `striped=true` zebra-stripes the rows, and `sticky=true` pins the header row when the table scrolls. The empty-state row uses `emptyLabel` when set.',props:[{name:"columns",type:"Col[]"},{name:"caption",type:"string",optional:!0,aliases:["title"]},{name:"density",type:"string",optional:!0,enum:["comfortable","compact"],description:"Row padding (default `comfortable`)"},{name:"striped",type:"boolean",optional:!0,description:"Zebra-stripe alternating rows"},{name:"sticky",type:"boolean",optional:!0,description:"Pin the header row when the table scrolls"},{name:"emptyLabel",type:"string",optional:!0,description:"Text shown when the table has no rows (default `No data`)"}],render:(t,e,r)=>{const a=k(e.columns),i=d(e.density,"comfortable"),n=C(e.striped),s=C(e.sticky),l=o("div",{class:"rui-table-wrapper","data-density":i,"data-striped":n?"true":"false","data-sticky":s?"true":"false"}),c=o("table",{class:"rui-table"}),u=d(e.caption);u&&c.append(o("caption",{class:"rui-table-caption"},[u]));const p=a.map(y=>{const x=d(y.args?.[3],"");return Sa.includes(x)?x:""}),m=o("thead"),g=o("tr");for(let y=0;y<a.length;y+=1){const x=a[y],w=o("th",{"data-align":p[y]||null},[d(x.args?.[0])]);g.append(w)}m.append(g),c.append(m);const f=o("tbody"),h=a.map(y=>k(y.args?.[1])),b=a.map(y=>d(y.args?.[2],"text")),v=Math.max(0,...h.map(y=>y.length));for(let y=0;y<v;y+=1){const x=o("tr");h.forEach((w,T)=>{const S=w[y],$=b[T]??"text",N=p[T],A=o("td",{"data-format":$,"data-align":N||null});S!==null&&typeof S=="object"&&S.__kind==="Component"?A.append(r.renderNode(S)):A.textContent=$l(S,$),x.append(A)}),f.append(x)}if(v===0){const y=o("tr"),x=d(e.emptyLabel,"No data");y.append(o("td",{colspan:String(a.length||1),class:"rui-table-empty"},[x])),f.append(y)}return c.append(f),l.append(c),l}},xl={name:"ListItem",description:"Single list item with optional title and description.",props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0,aliases:["meta"]},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name"}],render:(t,e)=>{const r=o("li",{class:"rui-list-item"}),a=L(e.icon,{className:"rui-list-icon"});a&&r.append(a);const i=o("div",{class:"rui-list-text"});i.append(o("div",{class:"rui-list-title"},[d(e.title)]));const n=d(e.description);return n&&i.append(o("div",{class:"rui-list-description"},[n])),r.append(i),r}},wl={name:"List",description:"Vertical list of ListItems.",props:[{name:"items",type:"ListItem[]"},{name:"ordered",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=C(e.ordered)?"ol":"ul",i=o(a,{class:"rui-list"});for(const n of k(e.items))i.append(r.renderNode(n));return i}},kl={name:"StatCard",description:"Single KPI card with label, value, optional delta, optional icon, and optional inline sparkline (`spark=[…numbers]`). Use inside `Stats` for a uniform KPI strip.",props:[{name:"label",type:"string"},{name:"value",type:"string"},{name:"trend",type:"string",optional:!0,enum:["up","down","flat"]},{name:"delta",type:"string",optional:!0,description:"Change vs previous period"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown in a chip beside the label"},{name:"spark",type:"number[]",optional:!0,description:"Optional inline sparkline values"},{name:"tone",type:"string",optional:!0,enum:["default","primary","success","warning","danger","info"]}],render:(t,e)=>{const r=d(e.tone,"default"),a=o("div",{class:"rui-stat-card","data-tone":r}),i=o("div",{class:"rui-stat-label-row"}),n=d(e.label),s=d(e.icon)||va(n)||"",l=L(s,{className:"rui-stat-icon"});l&&i.append(l),i.append(o("div",{class:"rui-stat-label"},[n])),a.append(i),a.append(o("div",{class:"rui-stat-value"},[d(e.value)]));const c=d(e.delta),u=d(e.trend);(c||u)&&a.append(o("div",{class:"rui-stat-trend","data-trend":u||"flat"},[c||Nl(u)]));const p=k(e.spark).map(m=>P(m));if(p.length>1){const m=o("div",{class:"rui-stat-spark"});m.append(Et(p,r==="default"?"primary":r)),a.append(m)}return a}},Sl={name:"Sparkline",description:"Tiny inline trend chart for KPIs, table cells, and dashboards. Renders an SVG line with a soft fill — use anywhere you would otherwise reach for `LineChart` but a single value series should stay inline with surrounding text.",props:[{name:"values",type:"number[]"},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]}],render:(t,e)=>{const r=d(e.tone,"primary"),a=k(e.values).map(n=>P(n)),i=o("span",{class:"rui-sparkline-wrap"});return i.append(Et(a,r)),i}},Cl={name:"TreeNode",description:"Single node in a Tree view. When `children` is provided the node renders as an expandable branch with a chevron; otherwise it renders as a leaf. `action` fires on click. Use `active=true` to highlight the current selection.",props:[{name:"label",type:"string"},{name:"children",type:"TreeNode[]",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon shown before the label"},{name:"expanded",type:"boolean",optional:!0,description:"Whether the branch is open by default"},{name:"active",type:"boolean",optional:!0,aliases:["selected"],description:"Highlights the row as the current selection"},{name:"badge",type:"string",optional:!0,description:"Trailing chip (count or status)"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Callable fired when the row is clicked"}],render:(t,e,r)=>{const a=k(e.children),i=a.length>0,n=C(e.expanded),s=C(e.active),l=typeof e.action=="function",c=o(l?"button":"div",{type:l?"button":null,class:"rui-tree-node-row",role:"treeitem","data-active":s?"true":"false","aria-expanded":i?n?"true":"false":null});if(i){const h=L("chevron-right",{className:"rui-tree-node-chevron"});h&&c.append(h)}else c.append(o("span",{class:"rui-tree-node-chevron-spacer","aria-hidden":"true"}));const u=L(e.icon,{className:"rui-tree-node-icon"});u&&c.append(u),c.append(o("span",{class:"rui-tree-node-label"},[d(e.label)]));const p=d(e.badge);if(p&&c.append(o("span",{class:"rui-tree-node-badge"},[p])),l&&(c.onclick=()=>r.invoke(e.action)),!i)return c;const m=o("details",{class:"rui-tree-node"});n&&m.setAttribute("open","");const g=o("summary",{class:"rui-tree-node-summary"});g.append(c),l&&(g.onclick=h=>{h.target?.closest(".rui-tree-node-chevron")||h.preventDefault()}),m.append(g);const f=o("div",{class:"rui-tree-node-children",role:"group"});for(const h of a)f.append(r.renderNode(h));return m.append(f),m}},Tl={name:"Tree",description:"Hierarchical tree view. Children must be TreeNode entries. Use for file browsers, nested navigation, category pickers, and any parent/child structure with arbitrary depth.",props:[{name:"items",type:"TreeNode[]"}],render:(t,e,r)=>{const a=o("div",{class:"rui-tree",role:"tree"});for(const i of k(e.items))a.append(r.renderNode(i));return a}};function Nl(t){return t==="up"?"▲":t==="down"?"▼":"—"}function $l(t,e){if(t==null)return"";switch(e){case"number":return typeof t=="number"?t.toLocaleString():d(t);case"currency":return typeof t=="number"?t.toLocaleString(void 0,{style:"currency",currency:"USD"}):d(t);case"date":try{const r=new Date(d(t));return Number.isNaN(r.getTime())?d(t):r.toLocaleDateString()}catch{return d(t)}default:return d(t)}}const _t=["var(--rui-chart-1, #6366f1)","var(--rui-chart-2, #10b981)","var(--rui-chart-3, #f59e0b)","var(--rui-chart-4, #ef4444)","var(--rui-chart-5, #06b6d4)","var(--rui-chart-6, #8b5cf6)"],_e=t=>_t[t%_t.length]??_t[0],Al={name:"Series",description:"Named data series for charts. Used inside BarChart, LineChart, PieChart.",props:[{name:"name",type:"string"},{name:"values",type:"number[]"}],render:(t,e)=>o("span",{class:"rui-series","data-name":d(e.name)})},Ca=t=>t.map((e,r)=>{const a=e,i=d(a.args?.[0],`Series ${r+1}`),n=k(a.args?.[1]).map(s=>P(s));return{name:i,values:n}}),Ml={name:"BarChart",description:"Vertical bar chart. `labels` define the x-axis, `series` define grouped bars.",props:[{name:"labels",type:"string[]"},{name:"series",type:"Series[]"},{name:"title",type:"string",optional:!0}],render:(t,e)=>{const r=k(e.labels).map(y=>d(y)),a=Ca(k(e.series)),i=o("div",{class:"rui-chart rui-bar-chart"});d(e.title)&&i.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const n=Math.max(1,...a.flatMap(y=>y.values)),s=640,l=240,c=Na(r,s-40-12),u={left:40,right:12,top:12,bottom:c.bottomPadding},p=s-u.left-u.right,m=l-u.top-u.bottom,g=jt(s,l);Aa(g,u,p,m,n);const f=r.length,h=p/Math.max(f,1),b=a.length,v=h*.7/Math.max(b,1);return a.forEach((y,x)=>{y.values.forEach((w,T)=>{const S=w/n*m,$=u.left+T*h+h*.15+x*v,N=u.top+m-S,A=pe("rect",{x:String($),y:String(N),width:String(Math.max(v-2,1)),height:String(S),fill:_e(x),rx:"2"});A.append(pe("title",{},[`${y.name}: ${w}`])),g.append(A)})}),$a(g,r,u,p,m,c,y=>u.left+(y+.5)*h),i.append(g),a.length>0&&i.append(Bt(a)),i}},Pl={name:"LineChart",description:'Line chart. `labels` define the x-axis, each Series is a line. As a shortcut you can pass `data=[{x: "Jan", revenue: 12, signups: 4}, …]` and the labels + series will be derived automatically (one line per non-`x` key). Use `data` when the dataset is already row-shaped; use `series` when you have explicit Series objects.',props:[{name:"labels",type:"string[]",optional:!0},{name:"series",type:"Series[]",optional:!0},{name:"data",type:"{x: string, [key: string]: number}[]",optional:!0,description:"Row-shaped data — labels and series are auto-derived"},{name:"title",type:"string",optional:!0},{name:"filled",type:"boolean",optional:!0,description:"Fill the area beneath each line (area-chart style)"},{name:"stacked",type:"boolean",optional:!0,description:"Stack series when filled=true"}],render:(t,e)=>{let r=k(e.labels).map(N=>d(N)),a=Ca(k(e.series));const i=k(e.data);if(i.length>0&&(r.length===0||a.length===0)){const N=[],A=new Map;for(const z of i){const R=z;if(!(!R||typeof R!="object")){N.push(d(R.x??R.label??""));for(const[_,Q]of Object.entries(R)){if(_==="x"||_==="label")continue;const B=P(Q);Number.isNaN(B)||(A.has(_)||A.set(_,[]),A.get(_).push(B))}}}r.length===0&&(r=N),a.length===0&&(a=[...A.entries()].map(([z,R])=>({name:z,values:R})))}const n=e.filled===!0,s=e.stacked===!0,l=Math.max(r.length,...a.map(N=>N.values.length),1),c=a.map(()=>Array(l).fill(0));if(n&&s)for(let N=0;N<l;N+=1){let A=0;a.forEach((z,R)=>{A+=z.values[N]??0,c[R][N]=A})}const u=o("div",{class:"rui-chart rui-line-chart","data-filled":n?"true":"false"});d(e.title)&&u.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const p=n&&s?c.flat():a.flatMap(N=>N.values),m=Math.max(1,...p),g=n&&s?0:Math.min(0,...p),f=640,h=240,b=Na(r,f-40-12),v={left:40,right:12,top:12,bottom:b.bottomPadding},y=f-v.left-v.right,x=h-v.top-v.bottom,w=jt(f,h);Aa(w,v,y,x,m,g);const T=Math.max(r.length-1,1),S=y/T,$=N=>v.left+N*(y/Math.max(l-1,1));return a.forEach((N,A)=>{const z=n&&s?c[A]:N.values,R=n&&s&&A>0?c[A-1]:null,_=z.map((B,O)=>{const J=$(O),X=v.top+x-(B-g)/(m-g||1)*x;return[J,X]});if(n&&_.length>0){let B=_.map(([O,J],X)=>`${X===0?"M":"L"}${O.toFixed(1)},${J.toFixed(1)}`).join(" ");if(R){const O=R.map((J,X)=>{const ue=$(X),me=v.top+x-(J-g)/(m-g||1)*x;return[ue,me]});B+=" "+O.slice().reverse().map(([J,X])=>`L${J.toFixed(1)},${X.toFixed(1)}`).join(" ")+" Z"}else{const O=_[0],J=_[_.length-1];B+=` L${J[0].toFixed(1)},${(v.top+x).toFixed(1)} L${O[0].toFixed(1)},${(v.top+x).toFixed(1)} Z`}w.append(pe("path",{d:B,fill:_e(A),"fill-opacity":"0.2",stroke:"none"}))}const Q=_.map(([B,O],J)=>`${J===0?"M":"L"}${B.toFixed(1)},${O.toFixed(1)}`).join(" ");w.append(pe("path",{d:Q,fill:"none",stroke:_e(A),"stroke-width":"2","stroke-linejoin":"round","stroke-linecap":"round"})),N.values.length<=30&&_.forEach(([B,O])=>{w.append(pe("circle",{cx:String(B),cy:String(O),r:"3",fill:_e(A)}))})}),$a(w,r,v,y,x,b,N=>v.left+N*S),u.append(w),a.length>0&&u.append(Bt(a)),u}},Il={name:"PieChart",description:"Pie/Donut chart. Each segment maps to a label/value pair.",props:[{name:"labels",type:"string[]"},{name:"values",type:"number[]"},{name:"title",type:"string",optional:!0}],render:(t,e)=>{const r=k(e.labels).map(m=>d(m)),a=k(e.values).map(m=>P(m)),i=o("div",{class:"rui-chart rui-pie-chart"});d(e.title)&&i.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const n=a.reduce((m,g)=>m+g,0)||1,s=jt(240,240),l=120,c=120,u=90;let p=-Math.PI/2;return a.forEach((m,g)=>{const f=m/n*Math.PI*2,h=p+f,b=f>Math.PI?1:0,v=l+u*Math.cos(p),y=c+u*Math.sin(p),x=l+u*Math.cos(h),w=c+u*Math.sin(h),T=`M${l},${c} L${v},${y} A${u},${u} 0 ${b} 1 ${x},${w} Z`,S=pe("path",{d:T,fill:_e(g),stroke:"var(--rui-color-bg, #fff)","stroke-width":"2"});S.append(pe("title",{},[`${r[g]??""}: ${m}`])),s.append(S),p=h}),i.append(s),i.append(Bt(r.map((m,g)=>({name:m,values:[a[g]??0]})))),i}},zl=7,Ta=12;function Na(t,e){if(t.length===0)return{step:1,rotated:!1,maxChars:32,bottomPadding:32};const r=e/Math.max(t.length,1),a=t.reduce((s,l)=>Math.max(s,l.length),0);if(a*zl+4<=r)return{step:1,rotated:!1,maxChars:a,bottomPadding:32};const i=r<Ta?Math.max(1,Math.ceil(Ta/r)):1,n=Math.min(a,14);return{step:i,rotated:!0,maxChars:n,bottomPadding:60}}function Rl(t,e){return t.length<=e?t:t.slice(0,Math.max(e-1,1))+"…"}function $a(t,e,r,a,i,n,s){const l=r.top+i+(n.rotated?14:18);e.forEach((c,u)=>{if(u%n.step!==0)return;const p=s(u),m=Rl(c,n.maxChars),g={x:String(p),y:String(l),class:"rui-chart-label","text-anchor":n.rotated?"end":"middle"};n.rotated&&(g.transform=`rotate(-45, ${p}, ${l})`);const f=pe("text",g,[m]);m!==c&&f.append(pe("title",{},[c])),t.append(f)})}function jt(t,e){const r=document.createElementNS("http://www.w3.org/2000/svg","svg");return r.setAttribute("viewBox",`0 0 ${t} ${e}`),r.setAttribute("class","rui-chart-svg"),r.setAttribute("role","img"),r}function pe(t,e,r){const a=document.createElementNS("http://www.w3.org/2000/svg",t);for(const[i,n]of Object.entries(e))a.setAttribute(i,n);if(r)for(const i of r)a.append(typeof i=="string"?document.createTextNode(i):i);return a}function Aa(t,e,r,a,i,n=0){for(let l=0;l<=4;l+=1){const c=l/4,u=e.top+a-c*a;t.append(pe("line",{x1:String(e.left),x2:String(e.left+r),y1:String(u),y2:String(u),stroke:"var(--rui-color-border-subtle, rgba(0,0,0,0.08))"})),t.append(pe("text",{x:String(e.left-6),y:String(u+3),"text-anchor":"end",class:"rui-chart-tick"},[String(Math.round((n+(i-n)*c)*10)/10)]))}}function Bt(t){const e=o("div",{class:"rui-chart-legend"});return t.forEach((r,a)=>{const i=o("span",{class:"rui-chart-legend-item"});i.append(o("span",{class:"rui-chart-legend-swatch",style:`background:${_e(a)}`})),i.append(o("span",{},[r.name])),e.append(i)}),e}const Ll={name:"SectionBlock",description:"Titled chat block with a description and child content.",props:[{name:"title",type:"string"},{name:"children",type:"Node[]"},{name:"description",type:"string",optional:!0}],render:(t,e,r)=>{const a=o("section",{class:"rui-section-block"});a.append(o("h3",{class:"rui-section-block-title"},[d(e.title)]));const i=d(e.description);i&&a.append(o("p",{class:"rui-section-block-description"},[i]));for(const n of k(e.children))a.append(r.renderNode(n));return a}},El={name:"ListBlock",description:"Chat-styled list with bullets, useful for steps or summaries.",props:[{name:"items",type:"string[]"},{name:"ordered",type:"boolean",optional:!0}],render:(t,e)=>{const r=C(e.ordered)?"ol":"ul",a=o(r,{class:"rui-list-block"});for(const i of k(e.items))a.append(o("li",{},[d(i)]));return a}},_l={name:"FollowUpBlock",description:'Suggested follow-up prompts shown as buttons. Each item dispatches its label as an assistant message (equivalent to `emit "assistant-message" { message }`).',props:[{name:"items",type:"FollowUpItem[]",description:"Array of FollowUpItem(label, message?), {label, message} objects, or plain strings"},{name:"title",type:"string",optional:!0}],render:(t,e,r)=>{const a=o("div",{class:"rui-follow-up"}),i=d(e.title,"You can also ask");i&&a.append(o("div",{class:"rui-follow-up-title"},[i]));const n=o("div",{class:"rui-follow-up-list"});for(const s of k(e.items))n.append(jl(s,r));return a.append(n),a}},jl=(t,e)=>{const{label:r,message:a}=Bl(t),i=o("button",{class:"rui-follow-up-button",type:"button"},[r]);return i.onclick=()=>{e.sendToAssistant(a)},i},Bl=t=>{if(typeof t=="string")return{label:t,message:t};if(t&&typeof t=="object"){const r=t;if(r.__kind==="Component"&&Array.isArray(r.args)){const n=d(r.args[0]),s=d(r.args[1],n);return{label:n,message:s}}const a=d(r.label),i=d(r.message,a);return{label:a,message:i}}const e=d(t);return{label:e,message:e}},Dl={name:"FollowUpItem",description:"Single follow-up item.",props:[{name:"label",type:"string"},{name:"message",type:"string",optional:!0,description:"Defaults to label"}],render:(t,e,r)=>{const a=d(e.label),i=d(e.message,a),n=o("button",{class:"rui-follow-up-button",type:"button"},[a]);return n.onclick=()=>{r.sendToAssistant(i)},n}},Fl={name:"ActionLink",description:"Inline link that runs an Action when clicked instead of navigating.",props:[{name:"label",type:"string"},{name:"action",type:"callable",aliases:["onClick","onclick"]}],render:(t,e,r)=>{const a=o("a",{class:"rui-action-link",href:"#",role:"button"},[d(e.label)]);return a.onclick=i=>{i.preventDefault(),r.invoke(e.action)},a}},Ma=["sm","md","lg","xl"],Pa={name:"Avatar",description:'User avatar. Shows the image at `src`. When `src` is missing, falls back to a deterministic DiceBear illustration seeded by `name` (pass `fallback="initials"` to render two-letter initials instead). If the image errors at runtime the avatar gracefully degrades to initials.',props:[{name:"name",type:"string",description:"Used for alt text + initials fallback"},{name:"src",type:"string",optional:!0,description:"Image URL"},{name:"size",type:"string",optional:!0,enum:Ma},{name:"status",type:"string",optional:!0,enum:["online","offline","busy","away"]},{name:"fallback",type:"string",optional:!0,enum:["initials","dicebear"],description:"How to render when `src` is missing (default: dicebear illustration; pass `initials` for the two-letter pill)"}],render:(t,e)=>{const r=d(e.size,"md"),a=o("span",{class:"rui-avatar","data-size":r,role:"img"}),i=d(e.name),n=d(e.fallback,"dicebear"),s=re(e.src),l=!s&&n==="dicebear"&&i?re(ms(i)):"",c=s||l;if(c){const p=o("img",{src:c,alt:i,loading:"lazy"});p.onerror=m=>{const g=m;(g.currentTarget??g.target).replaceWith(o("span",{class:"rui-avatar-fallback"},[We(i)]))},a.append(p)}else a.append(o("span",{class:"rui-avatar-fallback"},[We(i)]));const u=d(e.status);return u&&a.append(o("span",{class:"rui-avatar-status","data-status":u})),a}},Ol={name:"AvatarGroup",description:"Stack of overlapping avatars with a `+N` chip when the list overflows. Pass either Avatar(...) nodes or plain {name, src} objects.",props:[{name:"items",type:"Avatar[]",description:"Avatar(...) nodes or {name, src} objects"},{name:"max",type:"number",optional:!0,description:"Maximum avatars to show (default 4)"},{name:"size",type:"string",optional:!0,enum:Ma}],render:(t,e,r)=>{const a=k(e.items),i=Math.max(1,Math.floor(Number(e.max??4))),n=d(e.size,"md"),s=a.slice(0,i),l=a.length-s.length,c=o("div",{class:"rui-avatar-group","data-size":n});for(const u of s){if(u&&typeof u=="object"&&u.__kind==="Component"){c.append(r.renderNode(u));continue}const p=u,m=typeof p=="string"?p:d((p??{}).name),g=typeof p=="string"?"":d((p??{}).src);c.append(Pa.render({__kind:"Component",name:"Avatar",args:[],argMeta:[]},{name:m,src:g,size:n},r))}return l>0&&c.append(o("span",{class:"rui-avatar rui-avatar-overflow","data-size":n},[o("span",{class:"rui-avatar-fallback"},[`+${l}`])])),c}},Ul={name:"Progress",description:"Linear progress bar. `value` is clamped between 0 and `max` (default 100). `indeterminate=true` renders a looping animation when the total is unknown. Provide `segments` to render a segmented progress strip (steps in an onboarding flow), or `buffered` for a secondary buffer indicator (downloads, video buffering).",props:[{name:"value",type:"number",optional:!0,description:"Current progress; ignored when indeterminate"},{name:"max",type:"number",optional:!0,description:"Upper bound (default 100)"},{name:"label",type:"string",optional:!0,description:"Shown above the bar"},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]},{name:"indeterminate",type:"boolean",optional:!0},{name:"showValue",type:"boolean",optional:!0,description:"Show the numeric value on the right"},{name:"segments",type:"number",optional:!0,description:"Render N equal segments (filled by current step)"},{name:"buffered",type:"number",optional:!0,description:"Secondary value (0..max) drawn behind the bar"}],render:(t,e)=>{const r=Math.max(1,P(e.max,100)),a=C(e.indeterminate),i=Math.max(0,Math.min(r,P(e.value,0))),n=Math.round(i/r*100),s=Math.max(0,Math.floor(P(e.segments,0))),l=e.buffered!=null?Math.max(0,Math.min(r,P(e.buffered,0))):null,c=o("div",{class:"rui-progress","data-tone":d(e.tone,"primary")}),u=d(e.label),p=C(e.showValue);if(u||p){const g=o("div",{class:"rui-progress-head"});if(g.append(o("span",{class:"rui-progress-label"},[u])),p&&!a){const f=s>0?`${Math.min(s,Math.round(i/r*s))} / ${s}`:`${n}%`;g.append(o("span",{class:"rui-progress-value"},[f]))}c.append(g)}if(s>0&&!a){const g=o("div",{class:"rui-progress-segments",role:"progressbar","aria-valuemin":"0","aria-valuemax":String(s),"aria-valuenow":String(Math.min(s,Math.round(i/r*s)))}),f=Math.min(s,Math.round(i/r*s));for(let h=0;h<s;h+=1)g.append(o("span",{class:"rui-progress-segment","data-filled":h<f?"true":"false"}));return c.append(g),c}const m=o("div",{class:"rui-progress-track",role:"progressbar","aria-valuemin":"0","aria-valuemax":String(r),"aria-valuenow":a?null:String(i),"data-indeterminate":a?"true":"false"});if(l!==null){const g=Math.round(l/r*100);m.append(o("div",{class:"rui-progress-buffer",style:`width:${g}%`,"aria-hidden":"true"}))}return m.append(o("div",{class:"rui-progress-bar",style:a?"":`width:${n}%`})),c.append(m),c}},ql={name:"Switch",description:"Compact on/off toggle. Pass a `$variable` as `value` for two-way binding — prefer Switch over Checkbox when the control represents a setting.",props:[{name:"id",type:"string"},{name:"label",type:"string",optional:!0},{name:"value",type:"boolean",optional:!0,aliases:["checked"],description:"Bound value (typically $variable)"},{name:"description",type:"string",optional:!0},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("label",{class:"rui-switch",for:a,"data-disabled":C(e.disabled)?"true":"false"}),n=C(e.value),s=o("input",{type:"checkbox",id:a,name:a,class:"rui-switch-input",role:"switch",checked:n?"":null,disabled:C(e.disabled)?"":null});s.checked=n;const l=o("span",{class:"rui-switch-track"},[o("span",{class:"rui-switch-thumb"})]),c=t.argMeta?.[2]?.stateRef;c&&r.bindState(s,c,{event:"change",getValue:m=>m.checked});const u=d(e.label),p=d(e.description);if(i.append(s,l),u||p){const m=o("span",{class:"rui-switch-meta"});u&&m.append(o("span",{class:"rui-switch-label"},[u])),p&&m.append(o("span",{class:"rui-switch-description"},[p])),i.append(m)}return i}},Hl={name:"ToggleGroup",description:"Group of mutually-exclusive Toggle-style buttons (single-select). Items are `[value, label]` arrays, `{value, label, icon?}` objects, or plain strings (used for both value and label). Pass a `$variable` as `value` for two-way binding.",props:[{name:"id",type:"string"},{name:"items",type:"any[]"},{name:"value",type:"any",optional:!0},{name:"variant",type:"string",optional:!0,enum:["default","outline"]},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]}],render:(t,e,r)=>{const a=d(e.value),i=d(e.variant,"outline"),n=d(e.size,"md"),s=o("div",{class:"rui-toggle-group",role:"radiogroup","data-variant":i,"data-size":n}),l=t.argMeta?.[2]?.stateRef;for(const c of k(e.items)){const{value:u,label:p,icon:m}=Vl(c),g=u===a,f=o("button",{type:"button",class:"rui-toggle",role:"radio","aria-checked":g?"true":"false","data-variant":i,"data-size":n,"data-state":g?"on":"off","data-value":u}),h=L(m,{className:"rui-toggle-icon"});h&&f.append(h),f.append(o("span",{class:"rui-toggle-label"},[p])),l&&(f.onclick=()=>{r.setState(l,u)}),s.append(f)}return s}};function Vl(t){if(typeof t=="string")return{value:t,label:t,icon:""};if(Array.isArray(t))return{value:d(t[0]),label:d(t[1],d(t[0])),icon:d(t[2])};if(t&&typeof t=="object"){const e=t,r=d(e.value);return{value:r,label:d(e.label,r),icon:d(e.icon)}}return{value:"",label:"",icon:""}}const Wl={name:"Tooltip",description:"Wraps a trigger node and shows `label` text when the user hovers or focuses it. Pure CSS — no JS needed. Use for short hints (≤6 words); reach for HoverCard when you need rich content.",props:[{name:"label",type:"string"},{name:"trigger",type:"Node",aliases:["children"]},{name:"side",type:"string",optional:!0,enum:["top","bottom","left","right"],aliases:["placement"]}],render:(t,e,r)=>{const a=o("span",{class:"rui-tooltip","data-side":d(e.side,"top"),tabindex:"0"});return a.append(o("span",{class:"rui-tooltip-trigger"},[r.renderNode(e.trigger)])),a.append(o("span",{class:"rui-tooltip-content",role:"tooltip"},[d(e.label)])),a}},Gl={name:"HoverCard",description:"Wraps a trigger node and reveals a card with rich content on hover/focus. Use for previewing a referenced item (profile, link target, definition).",props:[{name:"trigger",type:"Node"},{name:"content",type:"Node[]",aliases:["children"]},{name:"side",type:"string",optional:!0,enum:["top","bottom","left","right"],aliases:["placement"]},{name:"open",type:"boolean",optional:!0,description:"Force the card open (otherwise reveal on hover/focus)"}],render:(t,e,r)=>{const a=o("span",{class:"rui-hover-card","data-side":d(e.side,"bottom"),"data-open":C(e.open)?"true":null,tabindex:"0"});a.append(o("span",{class:"rui-hover-card-trigger"},[r.renderNode(e.trigger)]));const i=o("span",{class:"rui-hover-card-content",role:"dialog"});for(const n of k(e.content))i.append(r.renderNode(n));return a.append(i),a}},Dt={star:{full:"star",half:"star-half-stroke",empty:"regular:star"},heart:{full:"heart",half:"heart",empty:"regular:heart"},thumb:{full:"thumbs-up",half:"thumbs-up",empty:"regular:thumbs-up"},fire:{full:"fire",half:"fire",empty:"regular:fire"},bolt:{full:"bolt",half:"bolt",empty:"regular:bolt"}},Kl={name:"Rating",description:"Compact 0–5 star rating with optional numeric badge and review count. Use in product cards, testimonials, reviews, and KPI rows. Pass `interactive=true` and a `$variable` as `value` to let users rate something; with `halfStep=true` clicking the left half of a star sets a fractional value. `icon` swaps the glyph family — `star` (default), `heart`, `thumb`, `fire`, `bolt`, or any custom Font Awesome name.",props:[{name:"value",type:"number",description:"0–max; can be a $variable when interactive"},{name:"max",type:"number",optional:!0,description:"Maximum number of stars (default 5)"},{name:"label",type:"string",optional:!0,description:'Inline text shown after the stars (e.g. "4.2 of 5")'},{name:"count",type:"number",optional:!0,description:"Review/voter count rendered in parentheses"},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]},{name:"interactive",type:"boolean",optional:!0,description:"Allow clicking a star to set the value"},{name:"readonly",type:"boolean",optional:!0,description:"Force read-only (overrides `interactive`)"},{name:"halfStep",type:"boolean",optional:!0,description:"Allow half-star resolution when interactive"},{name:"icon",type:"string",optional:!0,description:"Icon family — `star` (default), `heart`, `thumb`, `fire`, `bolt`, or any FA name"}],render:(t,e,r)=>{const a=Math.max(1,Math.floor(P(e.max,5))),i=Math.max(0,Math.min(a,P(e.value,0))),n=d(e.size,"md"),s=C(e.interactive)&&!C(e.readonly),l=C(e.halfStep),c=t.argMeta?.[0]?.stateRef,u=Yl(d(e.icon)),p=o("div",{class:"rui-rating","data-size":n,"data-interactive":s&&c?"true":"false","data-half-step":s&&c&&l?"true":"false",role:"img","aria-label":`${i} of ${a}`}),m=o("span",{class:"rui-rating-stars"});for(let h=1;h<=a;h+=1){const b=Math.max(0,Math.min(1,i-(h-1))),v=b>=1?u.full:b>0?u.half:u.empty,y=zt(v).join(" "),x=o(s&&c?"button":"span",{class:`rui-rating-star ${y}`.trim(),type:s&&c?"button":null,"data-fill":b>=1?"full":b>0?"half":"empty","aria-label":s&&c?`Rate ${h}`:null,"aria-hidden":s&&c?null:"true"});if(s&&c){const w=h,T=h-.5;x.onclick=S=>{let $=w;if(l){const N=S,z=(N.currentTarget??N.target).getBoundingClientRect();z.width>0&&N.clientX-z.left<z.width/2&&($=T)}r.setState(c,$)}}m.append(x)}p.append(m);const g=d(e.label);g&&p.append(o("span",{class:"rui-rating-label"},[g]));const f=e.count!=null?P(e.count,0):null;return f!==null&&f>0&&p.append(o("span",{class:"rui-rating-count"},[`(${f.toLocaleString()})`])),p}};function Yl(t){const e=t.trim().toLowerCase();return e?Dt[e]?Dt[e]:{full:e,half:e,empty:`regular:${e}`}:Dt.star}const Jl={name:"ProgressRing",description:"Circular progress indicator. Use for KPIs, quotas, completion rings, and any metric better shown as a circle than a bar. Renders the value (or a custom label) inside the ring.",props:[{name:"value",type:"number",optional:!0,description:"Current value (ignored when indeterminate)"},{name:"max",type:"number",optional:!0,description:"Upper bound (default 100)"},{name:"label",type:"string",optional:!0,description:'Text shown inside the ring (default "{percent}%")'},{name:"caption",type:"string",optional:!0,aliases:["description"],description:"Small caption rendered under the ring"},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]},{name:"indeterminate",type:"boolean",optional:!0}],render:(t,e)=>{const r=Math.max(1,P(e.max,100)),a=C(e.indeterminate),i=Math.max(0,Math.min(r,P(e.value,0))),n=Math.round(i/r*100),s=d(e.size,"md"),l=s==="lg"?120:s==="sm"?72:96,c=s==="lg"?10:s==="sm"?6:8,u=(l-c)/2,p=2*Math.PI*u,m=a?p*.65:p*(1-n/100),g=o("div",{class:"rui-progress-ring","data-tone":d(e.tone,"primary"),"data-size":s,"data-indeterminate":a?"true":"false"}),f=o("div",{class:"rui-progress-ring-wrap"}),h="http://www.w3.org/2000/svg",b=document.createElementNS(h,"svg");b.setAttribute("width",String(l)),b.setAttribute("height",String(l)),b.setAttribute("viewBox",`0 0 ${l} ${l}`),b.setAttribute("class","rui-progress-ring-svg");const v=document.createElementNS(h,"circle");v.setAttribute("class","rui-progress-ring-track"),v.setAttribute("cx",String(l/2)),v.setAttribute("cy",String(l/2)),v.setAttribute("r",String(u)),v.setAttribute("stroke-width",String(c)),v.setAttribute("fill","none"),b.appendChild(v);const y=document.createElementNS(h,"circle");y.setAttribute("class","rui-progress-ring-bar"),y.setAttribute("cx",String(l/2)),y.setAttribute("cy",String(l/2)),y.setAttribute("r",String(u)),y.setAttribute("stroke-width",String(c)),y.setAttribute("fill","none"),y.setAttribute("stroke-linecap","round"),y.setAttribute("stroke-dasharray",String(p)),y.setAttribute("stroke-dashoffset",String(m)),b.appendChild(y),f.append(b);const x=d(e.label,a?"…":`${n}%`),w=o("span",{class:"rui-progress-ring-value"}),T=L(x,{className:"rui-progress-ring-icon"});T&&zt(x).length>0?w.append(T):w.append(document.createTextNode(x)),f.append(w),g.append(f);const S=d(e.caption);return S&&g.append(o("span",{class:"rui-progress-ring-caption"},[S])),g}},Xl={name:"ChatBubble",description:'Single chat-style message bubble with author, time, and body. Use for conversation threads, agent transcripts, support chats, and any message-style UI. Set `from="me"` (or any non-empty author) for the active speaker — the bubble aligns to the right with a primary tint. `from="agent"` (default) renders as the canonical incoming bubble on the left.',props:[{name:"author",type:"string"},{name:"body",type:"string",aliases:["text","message"]},{name:"time",type:"string",optional:!0},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"]},{name:"from",type:"string",optional:!0,enum:["agent","me","system"],aliases:["role"],description:"Lane (default agent)"},{name:"status",type:"string",optional:!0,enum:["sending","sent","delivered","read","error"]}],render:(t,e)=>{const r=d(e.from,"agent"),a=o("div",{class:"rui-chat-bubble","data-from":r});r!=="me"&&a.append(Ia(d(e.avatarSrc),d(e.author)));const i=o("div",{class:"rui-chat-bubble-bubble"}),n=o("header",{class:"rui-chat-bubble-head"});n.append(o("span",{class:"rui-chat-bubble-author"},[d(e.author)]));const s=d(e.time);s&&n.append(o("span",{class:"rui-chat-bubble-time"},[s])),i.append(n),i.append(o("p",{class:"rui-chat-bubble-body"},[d(e.body)]));const l=d(e.status);return l&&i.append(o("span",{class:"rui-chat-bubble-status","data-status":l},[l])),a.append(i),r==="me"&&a.append(Ia(d(e.avatarSrc),d(e.author))),a}};function Ia(t,e){const r=o("span",{class:"rui-chat-bubble-avatar"}),a=re(t);return a?r.append(o("img",{src:a,alt:e,loading:"lazy"})):r.append(o("span",{class:"rui-chat-bubble-fallback"},[We(e)])),r}const Zl={name:"Kbd",description:"Renders a keyboard shortcut chip (e.g. `Cmd+K`). Pass a single label, or multiple labels as an array to render a `key + key + …` combo.",props:[{name:"keys",type:"string | string[]"},{name:"size",type:"string",optional:!0,enum:["sm","md"]}],render:(t,e)=>{const r=d(e.size,"md"),a=o("span",{class:"rui-kbd-group","data-size":r});return(Array.isArray(e.keys)?e.keys:[e.keys]).forEach((n,s)=>{const l=d(n);l&&(s>0&&a.append(o("span",{class:"rui-kbd-sep"},["+"])),a.append(o("kbd",{class:"rui-kbd"},[l])))}),a}},Ql={name:"Popover",description:"Click-triggered popup with arbitrary rich content. Use when HoverCard's hover trigger is too eager and Modal/Sheet is too heavy — perfect for filter panels, color pickers, share menus, and small settings flyouts. The trigger stays visible while the popover is open — clicking it again, clicking outside, pressing Escape, or clicking the built-in × button all close it.",props:[{name:"trigger",type:"Node",description:"Clickable trigger element (Button, Avatar, IconButton, …). The trigger remains visible while the popover is open."},{name:"content",type:"Node[]",aliases:["children"],description:"Body rendered inside the popover"},{name:"title",type:"string",optional:!0,description:"Optional bold heading rendered above the content"},{name:"side",type:"string",optional:!0,enum:["bottom","top","left","right"],aliases:["placement"],description:'Where the popover opens relative to the trigger (default "bottom")'},{name:"align",type:"string",optional:!0,enum:["start","center","end"],description:'Alignment along the trigger edge (default "start")'},{name:"width",type:"string",optional:!0,description:'CSS width for the popover panel (default "280px")'},{name:"open",type:"boolean",optional:!0,description:"Initial open state — use to demo or pre-open the popover"}],render:(t,e,r)=>{const a=C(e.open),i=r.useInstanceState("open",a),n=i.get(),s=ee(e.width,""),l=o("div",{class:"rui-popover","data-open":n?"true":"false","data-side":d(e.side,"bottom"),"data-align":d(e.align,"start")}),c=o("span",{class:"rui-popover-trigger","data-state":n?"open":"closed","aria-haspopup":"dialog","aria-expanded":n?"true":"false"});c.append(r.renderNode(e.trigger)),l.append(c);const u=o("div",{class:"rui-popover-content",role:"dialog",style:s?`width: ${s};`:null}),p=o("div",{class:"rui-popover-header"}),m=d(e.title);p.append(m?o("div",{class:"rui-popover-title"},[m]):o("span",{class:"rui-popover-title-spacer"}));const g=o("button",{type:"button",class:"rui-popover-close","aria-label":"Close popover"},["×"]);g.onclick=f=>{f.stopPropagation(),st(g,!1,i)},p.append(g),u.append(p);for(const f of k(e.content))u.append(r.renderNode(f));return l.append(u),c.onclick=f=>{f.stopPropagation();const h=f.currentTarget??f.target,b=!i.get(),v=st(h,b,i);b&&v&&za(v,i)},c.onkeydown=f=>{const h=f,b=h.currentTarget??h.target;if(h.key==="Enter"||h.key===" "){h.preventDefault();const v=!i.get(),y=st(b,v,i);v&&y&&za(y,i)}else h.key==="Escape"&&i.get()&&(h.preventDefault(),st(b,!1,i))},l}},st=(t,e,r)=>{r.set(e);const a=t.closest(".rui-popover");if(!a)return null;a.setAttribute("data-open",e?"true":"false");const i=a.querySelector(".rui-popover-trigger");return i?.setAttribute("aria-expanded",e?"true":"false"),i?.setAttribute("data-state",e?"open":"closed"),e||he(a),a},za=(t,e)=>{Ee({liveRoot:t,onDismiss:()=>{e.set(!1),t.setAttribute("data-open","false");const r=t.querySelector(".rui-popover-trigger");r?.setAttribute("aria-expanded","false"),r?.setAttribute("data-state","closed")}})},ec={name:"Toast",description:"Single transient notification card. Always shows a close (×) button that removes the toast from the DOM (and fires `onClose` if set). Pass `duration` (ms) to auto-dismiss, or `position` for a standalone one-off toast (the renderer will pin it to the viewport corner so you do not have to wrap a single notification in `Stack(...)`). Use `Toasts` for grouped stacks; prefer `Banner` for top-of-page announcements and `Notification` for permanent inbox entries.",props:[{name:"title",type:"string"},{name:"message",type:"string",optional:!0,aliases:["description"]},{name:"tone",type:"string",optional:!0,enum:["default","primary","success","warning","danger","info"],description:'Visual accent (default "default")'},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name (default picked from tone)"},{name:"duration",type:"number",optional:!0,description:"Auto-dismiss after N milliseconds (e.g. 4000). Omit to keep the toast until the user closes it."},{name:"action",type:"Button",optional:!0,description:"Optional inline action Button(...) shown above the message"},{name:"onClose",type:"callable",optional:!0,description:"Callable invoked when the toast is dismissed (× button, auto-dismiss, or programmatic)"},{name:"position",type:"string",optional:!0,enum:["top-right","top-left","top-center","bottom-right","bottom-left","bottom-center"],description:"Pin a standalone Toast to a viewport corner without wrapping it in `Stack(...)`"}],render:(t,e,r)=>{const a=d(e.tone,"default"),i=d(e.position),n=o("div",{class:i?"rui-toast rui-toast-standalone":"rui-toast",role:"status","aria-live":a==="danger"?"assertive":"polite","data-tone":a,"data-position":i||null}),s=d(e.icon)||tc(a),l=L(s,{className:"rui-toast-icon"});l&&n.append(l);const c=o("div",{class:"rui-toast-body"});c.append(o("div",{class:"rui-toast-title"},[d(e.title)]));const u=d(e.message);if(u&&c.append(o("div",{class:"rui-toast-message"},[u])),e.action){const x=o("div",{class:"rui-toast-action"});x.append(r.renderNode(e.action)),c.append(x)}n.append(c);const p=r.useInstanceState("dismissed",!1),m=r.useInstanceState("timer",null),g=x=>{if(x){const w=x.closest(".rui-toast");if(w)return w}return n.isConnected?n:null},f=()=>{const x=m.get();x!==null&&(clearTimeout(x),m.set(null))},h=r.useInstanceState("removal-timer",null),b=x=>{if(p.get())return;p.set(!0),f();const w=g(x);if(!w)return;w.classList.add("is-dismissed");const T=setTimeout(()=>{h.set(null),w.remove()},180);h.set(T),r.registerDisposer(()=>{const S=h.get();S!==null&&(clearTimeout(S),h.set(null))},"exit-animation-timer"),r.invoke(e.onClose)},v=o("button",{type:"button",class:"rui-toast-close","aria-label":"Dismiss notification"},["×"]);v.onclick=x=>{x.stopPropagation(),b(x.currentTarget??x.target)},n.append(v);const y=P(e.duration,0);if(y>0&&m.get()===null&&!p.get()){const x=setTimeout(()=>{m.set(null),!p.get()&&n.isConnected&&b()},y);m.set(x),r.registerDisposer(()=>{const w=m.get();w!==null&&(clearTimeout(w),m.set(null))},"auto-dismiss-timer")}return p.get()?o("div",{class:"rui-toast-placeholder",hidden:""}):n}};function tc(t){switch(t){case"success":return"circle-check";case"warning":return"triangle-exclamation";case"danger":return"circle-xmark";case"primary":return"bell";case"info":return"circle-info";default:return"circle-info"}}const Ra={name:"BreadcrumbItem",description:"Single item inside a Breadcrumb trail. Provide `href` for a link, omit it for the current/leaf page (rendered with emphasis).",props:[{name:"label",type:"string"},{name:"href",type:"string",optional:!0},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name"}],render:(t,e)=>{const r=o("li",{class:"rui-breadcrumb-item"}),a=d(e.label),i=d(e.href),n=i?rt(i):"",s=[],l=L(e.icon,{className:"rui-breadcrumb-icon"});if(l&&s.push(l),s.push(o("span",{class:"rui-breadcrumb-label"},[a])),n)r.append(o("a",{class:"rui-breadcrumb-link",href:n},s));else{r.setAttribute("aria-current","page");const c=o("span",{class:"rui-breadcrumb-current"});for(const u of s)u&&c.append(typeof u=="string"?document.createTextNode(u):u);r.append(c)}return r}},rc={name:"Breadcrumb",description:"Trail of links showing the user's location. Children may be BreadcrumbItem(label, href?) nodes OR plain strings (the last string is treated as the current page).",props:[{name:"items",type:"BreadcrumbItem[] | string[]"},{name:"separator",type:"string",optional:!0,description:"Default `/`"}],render:(t,e,r)=>{const a=k(e.items),i=d(e.separator,"/"),n=o("nav",{class:"rui-breadcrumb","aria-label":"Breadcrumb"}),s=o("ol",{class:"rui-breadcrumb-list"});return a.forEach((l,c)=>{if(c>0&&s.append(o("li",{class:"rui-breadcrumb-separator","aria-hidden":"true"},[i])),l&&typeof l=="object"&&l.__kind==="Component"){s.append(r.renderNode(l));return}const u=d(l),p=c===a.length-1;s.append(Ra.render({__kind:"Component",name:"BreadcrumbItem",args:[],argMeta:[]},{label:u,href:p?"":"#"},r))}),n.append(s),n}},ac=[10,20,50,100],ic={name:"Pagination",description:'Page navigator with Prev/Next, page numbers, and ellipses. Pass a `$variable` as `page` for two-way binding — clicking a page button sets that state to the new (1-indexed) value. Add `total` to render a "Showing N–M of T" summary, pass `$variable` as `perPage` to expose a per-page selector, or set `compact: true` to drop the page-number row for tight toolbars.',props:[{name:"page",type:"number",description:"Current page (1-indexed); typically a $variable"},{name:"totalPages",type:"number",aliases:["pages"]},{name:"siblings",type:"number",optional:!0,description:"Number of page links shown around the current page (default 1)"},{name:"total",type:"number",optional:!0,description:'Total record count — enables the "Showing N–M of T" summary'},{name:"perPage",type:"number",optional:!0,description:"Bind a `$variable` to expose a per-page selector"},{name:"perPageOptions",type:"number[]",optional:!0,description:"Override the per-page choices (default 10/20/50/100)"},{name:"compact",type:"boolean",optional:!0,description:"Hide page numbers — keep Prev / Next only"}],render:(t,e,r)=>{const a=Math.max(1,Math.floor(P(e.totalPages,1))),i=Math.max(1,Math.min(a,Math.floor(P(e.page,1)))),n=Math.max(0,Math.floor(P(e.siblings,1))),s=C(e.compact),l=t.argMeta?.[0]?.stateRef,c=o("nav",{class:"rui-pagination","aria-label":"Pagination","data-compact":s?"true":"false"}),u=b=>{if(!l)return;const v=Math.max(1,Math.min(a,b));v!==i&&r.setState(l,v)},p=e.total!=null?Math.max(0,Math.floor(P(e.total,0))):null,m=e.perPage!=null?Math.max(1,Math.floor(P(e.perPage,0))):null;if(p!==null&&m&&m>0){const b=p===0?0:(i-1)*m+1,v=Math.min(p,i*m);c.append(o("span",{class:"rui-pagination-summary"},[p===0?"No results":`Showing ${b.toLocaleString()}–${v.toLocaleString()} of ${p.toLocaleString()}`]))}else p!==null&&c.append(o("span",{class:"rui-pagination-summary"},[`${p.toLocaleString()} result${p===1?"":"s"}`]));const g=o("div",{class:"rui-pagination-buttons"}),f=(b,v,y={})=>{if(y.ellipsis)return o("span",{class:"rui-pagination-ellipsis","aria-hidden":"true"},[b]);const x=o("button",{type:"button",class:"rui-pagination-button","data-active":y.active?"true":"false","aria-current":y.active?"page":null,"aria-label":y.ariaLabel??null,disabled:y.disabled?"":null},[b]);return!y.disabled&&!y.active&&(x.onclick=()=>u(v)),x};if(g.append(f("‹",i-1,{disabled:i<=1,ariaLabel:"Previous page"})),s)g.append(o("span",{class:"rui-pagination-current"},[`${i} / ${a}`]));else{const b=nc(i,a,n);for(const v of b)v==="…"?g.append(f("…",0,{ellipsis:!0})):g.append(f(String(v),v,{active:v===i}))}g.append(f("›",i+1,{disabled:i>=a,ariaLabel:"Next page"})),c.append(g);const h=t.argMeta?.[4]?.stateRef;if(m&&(h||k(e.perPageOptions).length>0)){const b=k(e.perPageOptions).length>0?k(e.perPageOptions).map(x=>Math.max(1,Math.floor(Number(x)||0))).filter(x=>x>0):Array.from(ac),v=o("label",{class:"rui-pagination-per-page"},[document.createTextNode("Show ")]),y=o("select",{class:"rui-pagination-per-page-select"});for(const x of b){const w=o("option",{value:String(x),selected:x===m?"":null},[String(x)]);y.append(w)}h&&r.bindState(y,h,{event:"change",getValue:x=>Number(x.value)}),v.append(y),v.append(document.createTextNode(" per page")),c.append(v)}return c}};function nc(t,e,r){const a=[],i=(c,u)=>{for(let p=c;p<=u;p+=1)a.push(p)},n=r*2+5;if(e<=n)return i(1,e),a;const s=Math.max(2,t-r),l=Math.min(e-1,t+r);return a.push(1),s>2&&a.push("…"),i(s,l),l<e-1&&a.push("…"),a.push(e),a}const oc={name:"NavbarItem",description:"Single link inside a Navbar's main item slot. Renders as an inline anchor / button — pass `to` for a router-aware link, `href` for an external link, or `action` for a click handler. `active=true` highlights the current page.",props:[{name:"label",type:"string"},{name:"to",type:"string",optional:!0,description:"Internal route (consumes the built-in router)"},{name:"href",type:"string",optional:!0,description:"External href; opens in a new tab when set with `external=true`"},{name:"icon",type:"string",optional:!0},{name:"active",type:"boolean",optional:!0},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Callable fired on click (alternative to `to`/`href`)"},{name:"external",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.label),i=e.icon,n=C(e.active),s=d(e.to),l=rt(e.href,""),c=C(e.external),u=s||l?"a":"button",p=o(u,{class:"rui-navbar-item",type:u==="button"?"button":null,href:l||(s?`#${s.startsWith("/")?s:`/${s}`}`:null),target:c&&l?"_blank":null,rel:c&&l?"noopener noreferrer":null,"data-active":n?"true":"false"}),m=L(i,{className:"rui-navbar-item-icon"});return m&&p.append(m),p.append(o("span",{class:"rui-navbar-item-label"},[a])),s&&!l?p.onclick=g=>{if(g.defaultPrevented)return;const f=g;f.button!==0||f.metaKey||f.ctrlKey||f.shiftKey||f.altKey||(g.preventDefault(),r.router.navigate(s))}:typeof e.action=="function"&&(p.onclick=g=>{g.preventDefault(),r.invoke(e.action)}),p}},sc={name:"Navbar",description:"Top navigation bar with a brand on the left, primary nav items in the middle, and a right-aligned actions slot (user avatar, DropdownMenu, CTA buttons, …). Use `sticky=true` to pin it to the top of the page. The canonical companion of `Sidebar` for product surfaces; prefer Navbar for marketing/docs pages without a sidebar.",props:[{name:"brand",type:"string | Node",optional:!0,description:"Workspace/product name (string) or a node (e.g. logo Image)"},{name:"items",type:"NavbarItem[]",optional:!0,description:"Center navigation items"},{name:"actions",type:"Node[]",optional:!0,description:"Right-side controls (Buttons, Avatar, DropdownMenu, …)"},{name:"sticky",type:"boolean",optional:!0,description:"Pin the bar to the top of the viewport"},{name:"variant",type:"string",optional:!0,enum:["default","transparent"],description:"Visual variant"}],render:(t,e,r)=>{const a=o("nav",{class:"rui-navbar","data-sticky":C(e.sticky)?"true":"false","data-variant":d(e.variant,"default"),"aria-label":"Primary"}),i=e.brand;if(i!=null&&i!==""){const l=o("div",{class:"rui-navbar-brand"});typeof i=="string"?l.append(document.createTextNode(i)):l.append(r.renderNode(i)),a.append(l)}const n=k(e.items);if(n.length>0){const l=o("div",{class:"rui-navbar-items"});for(const c of n)l.append(r.renderNode(c));a.append(l)}const s=k(e.actions);if(s.length>0){const l=o("div",{class:"rui-navbar-actions"});for(const c of s)l.append(r.renderNode(c));a.append(l)}return a}},lc=["bottom","top","left","right"],cc=["start","center","end"],uc=["default","danger"],lt=(t,e,r)=>{r.set(e);const a=t.closest(".rui-dropdown-menu");return a?(a.setAttribute("data-open",e?"true":"false"),a.querySelector(".rui-dropdown-menu-trigger")?.setAttribute("aria-expanded",e?"true":"false"),e||he(a),a):null},La=(t,e)=>{Ee({liveRoot:t,onDismiss:()=>{e.set(!1),t.setAttribute("data-open","false"),t.querySelector(".rui-dropdown-menu-trigger")?.setAttribute("aria-expanded","false")}})},Ft=(t,e)=>{if(!t||typeof t!="object")return!1;const r=t;return r.__kind==="Component"&&r.name===e},dc={name:"DropdownMenu",description:"Click-triggered dropdown menu. Click the trigger to toggle, click a MenuItem to run its action and close, click outside or press Escape to close without acting. Children must be MenuItem, MenuSeparator, or MenuLabel entries.",props:[{name:"trigger",type:"Node",description:"Clickable trigger element (typically a Button or Avatar)"},{name:"items",type:"(MenuItem | MenuSeparator | MenuLabel)[]"},{name:"side",type:"string",optional:!0,enum:lc,description:'Where the menu opens relative to the trigger (default "bottom")'},{name:"align",type:"string",optional:!0,enum:cc,description:'How the menu aligns along the trigger edge (default "start")'},{name:"label",type:"string",optional:!0,description:"Optional ARIA label for the menu"},{name:"open",type:"boolean",optional:!0,description:"Initial open state — use to demo or pre-open the menu"}],render:(t,e,r)=>{const a=C(e.open),i=r.useInstanceState("open",a),n=i.get(),s=o("div",{class:"rui-dropdown-menu","data-open":n?"true":"false","data-side":d(e.side,"bottom"),"data-align":d(e.align,"start")}),l=o("span",{class:"rui-dropdown-menu-trigger","data-state":n?"open":"closed","aria-haspopup":"menu","aria-expanded":n?"true":"false",tabindex:"0"});l.append(r.renderNode(e.trigger)),l.onclick=u=>{u.stopPropagation();const p=u.currentTarget??u.target,m=!i.get(),g=lt(p,m,i);m&&g&&La(g,i)},l.onkeydown=u=>{const p=u,m=p.currentTarget??p.target;if(p.key==="Enter"||p.key===" "){p.preventDefault();const g=!i.get(),f=lt(m,g,i);g&&f&&La(f,i);return}p.key==="Escape"&&i.get()&&(p.preventDefault(),lt(m,!1,i))},s.append(l);const c=o("div",{class:"rui-dropdown-menu-content",role:"menu","aria-label":d(e.label)||null});for(const u of k(e.items)){if(Ft(u,"MenuItem")){const p=u.args??[],m=d(p[0]),g=p[1],f=p[2],h=d(p[3]),b=d(p[4],"default"),v=C(p[5]),y=o("button",{type:"button",class:"rui-menu-item",role:"menuitem","data-variant":b,disabled:v?"":null}),x=L(f,{className:"rui-menu-item-icon"});x&&y.append(x),y.append(o("span",{class:"rui-menu-item-label"},[m])),h&&y.append(o("span",{class:"rui-menu-item-shortcut"},[h])),v||(y.onclick=w=>{const T=w.currentTarget??w.target;lt(T,!1,i),r.invoke(g)}),c.append(y);continue}if(Ft(u,"MenuSeparator")){c.append(o("div",{class:"rui-menu-separator",role:"separator"}));continue}if(Ft(u,"MenuLabel")){const p=d((u.args??[])[0]);c.append(o("div",{class:"rui-menu-label"},[p]));continue}c.append(r.renderNode(u))}return s.append(c),s}},pc={name:"MenuItem",description:"Single item inside a DropdownMenu. Renders a button-style row with an optional leading icon and trailing keyboard-shortcut hint. The action argument runs when clicked; the menu closes automatically afterwards.",props:[{name:"label",type:"string"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Callable to execute on click"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown before the label"},{name:"shortcut",type:"string",optional:!0,description:'Trailing keyboard-shortcut hint (e.g. "⌘ K")'},{name:"variant",type:"string",optional:!0,enum:uc,description:'Use "danger" for destructive actions'},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=C(e.disabled),i=o("button",{type:"button",class:"rui-menu-item",role:"menuitem","data-variant":d(e.variant,"default"),disabled:a?"":null}),n=L(e.icon,{className:"rui-menu-item-icon"});n&&i.append(n),i.append(o("span",{class:"rui-menu-item-label"},[d(e.label)]));const s=d(e.shortcut);return s&&i.append(o("span",{class:"rui-menu-item-shortcut"},[s])),a||(i.onclick=()=>{r.invoke(e.action)}),i}},mc={name:"MenuSeparator",description:"Thin horizontal rule used inside a DropdownMenu to group items.",props:[],render:()=>o("div",{class:"rui-menu-separator",role:"separator"})},gc={name:"MenuLabel",description:'Small uppercase section header inside a DropdownMenu. Use to group related MenuItems (e.g. "Account", "Workspace", "Danger zone").',props:[{name:"label",type:"string"}],render:(t,e)=>o("div",{class:"rui-menu-label"},[d(e.label)])},fc=["left","center","right"];function hc(t){return k(t).map((e,r)=>{const a=e.args??[],i=d(a[0]);return{header:i,values:k(a[1]),format:d(a[2],"text"),align:fc.includes(d(a[3]))?d(a[3]):"",sortable:C(a[4]),filterable:C(a[5]),key:i||`col-${r}`}})}function Ea(t,e,r){if(t==null)return e==null?0:1;if(e==null)return-1;if(r==="number"||r==="currency")return P(t,0)-P(e,0);if(r==="date"){const a=new Date(d(t)).getTime(),i=new Date(d(e)).getTime();if(Number.isFinite(a)&&Number.isFinite(i))return a-i}return d(t).localeCompare(d(e))}function ct(t,e){if(t==null)return"";switch(e){case"number":return typeof t=="number"?t.toLocaleString():d(t);case"currency":return typeof t=="number"?t.toLocaleString(void 0,{style:"currency",currency:"USD"}):d(t);case"date":try{const r=new Date(d(t));return Number.isNaN(r.getTime())?d(t):r.toLocaleDateString()}catch{return d(t)}default:return d(t)}}const bc={name:"DataGrid",description:"Advanced data table with sortable headers, per-column filter chips, row selection (checkboxes), sticky header / first column, optional pagination, an optional bulk-action toolbar slot, and click-to-act rows. Columns are Col(header, values, format?, align?, sortable?, filterable?) entries. Bind `$sort` (`{key, direction}` object), `$selectedIds` (string[]), and `$page` (number) for full reactivity. Use INSTEAD of `Table` when you need any of those interactions.",props:[{name:"columns",type:"Col[]",description:"Columns; pass sortable=true / filterable=true on each Col."},{name:"rowIds",type:"any[]",optional:!0,description:"Stable id per row (used by `selectedIds`); defaults to row index."},{name:"caption",type:"string",optional:!0},{name:"sort",type:"object",optional:!0,description:"`{key, direction}` — pass a $variable for two-way binding"},{name:"selectedIds",type:"any[]",optional:!0,description:"Array of selected row ids — bind a $variable"},{name:"selectable",type:"boolean",optional:!0,description:"Render leading selection checkboxes"},{name:"page",type:"number",optional:!0,description:"1-indexed current page — bind a $variable"},{name:"perPage",type:"number",optional:!0,description:"Page size (default 20)"},{name:"emptyLabel",type:"string",optional:!0,description:"Text shown when no rows match (default `No results`)"},{name:"rowAction",type:"callable",optional:!0,description:"Callable fired when a row is clicked"},{name:"toolbar",type:"Node[]",optional:!0,description:"Bulk-action toolbar shown above the table when any rows are selected"},{name:"density",type:"string",optional:!0,enum:["comfortable","compact"]},{name:"striped",type:"boolean",optional:!0},{name:"stickyHeader",type:"boolean",optional:!0,description:"Pin the header row (default true)"},{name:"stickyFirstColumn",type:"boolean",optional:!0,description:"Pin the first column horizontally"}],render:(t,e,r)=>{const a=hc(e.columns),i=Math.max(0,...a.map(E=>E.values.length)),n=k(e.rowIds),s=E=>d(n[E]??E),l=e.sort&&typeof e.sort=="object"?e.sort:null,c=d(l?.key),u=d(l?.direction,"asc")==="desc"?"desc":"asc",p=k(e.selectedIds).map(E=>d(E)),m=new Set(p),g=C(e.selectable)||t.argMeta?.[4]?.stateRef!==void 0,f=e.stickyHeader===void 0?!0:C(e.stickyHeader),h=C(e.stickyFirstColumn),b=d(e.density,"comfortable"),v=C(e.striped),y=r.useInstanceState("filters",{}),x=y.get(),w=[];for(let E=0;E<i;E+=1){let H=!0;for(const V of a){if(!V.filterable)continue;const q=(x[V.key]??"").trim().toLowerCase();if(!q)continue;const te=V.values[E];if(!ct(te,V.format).toLowerCase().includes(q)){H=!1;break}}H&&w.push(E)}if(c){const E=a.find(H=>H.key===c);E&&E.sortable&&w.sort((H,V)=>{const q=Ea(E.values[H],E.values[V],E.format);return u==="desc"?-q:q})}const T=w.length,S=Math.max(1,Math.floor(P(e.perPage,20))),$=Math.max(1,Math.ceil(T/S)),N=Math.max(1,Math.floor(P(e.page,1))),A=Math.min(N,$),z=w.slice((A-1)*S,A*S),R=o("div",{class:"rui-data-grid","data-density":b,"data-striped":v?"true":"false","data-sticky-header":f?"true":"false","data-sticky-first":h?"true":"false"}),_=t.argMeta?.[3]?.stateRef,Q=t.argMeta?.[4]?.stateRef,B=t.argMeta?.[6]?.stateRef,O=k(e.toolbar);if(p.length>0&&O.length>0){const E=o("div",{class:"rui-data-grid-bulk"});E.append(o("span",{class:"rui-data-grid-bulk-count"},[`${p.length} selected`]));const H=o("div",{class:"rui-data-grid-bulk-tools"});for(const V of O)H.append(r.renderNode(V));E.append(H),R.append(E)}const J=o("div",{class:"rui-data-grid-scroll"}),X=o("table",{class:"rui-data-grid-table"}),ue=d(e.caption);ue&&X.append(o("caption",{class:"rui-data-grid-caption"},[ue]));const me=o("thead"),Je=o("tr");if(g){const E=o("th",{class:"rui-data-grid-cell-select",scope:"col"}),H=z.length>0&&z.every(q=>m.has(s(q))),V=o("input",{type:"checkbox",class:"rui-data-grid-checkbox","aria-label":"Select all rows on this page",checked:H?"":null});Q&&(V.onclick=q=>{const te=q.currentTarget,Z=new Set(p);for(const K of z){const Y=s(K);te.checked?Z.add(Y):Z.delete(Y)}r.setState(Q,Array.from(Z))}),E.append(V),Je.append(E)}if(a.forEach((E,H)=>{const V=o("th",{scope:"col","data-align":E.align||null,"data-sortable":E.sortable?"true":null,"data-active":E.sortable&&E.key===c?"true":null,"data-first":H===0?"true":null});if(E.sortable&&_){const q=o("button",{type:"button",class:"rui-data-grid-sort"});q.append(o("span",{},[E.header]));const te=E.key===c?u==="asc"?"arrow-up-short-wide":"arrow-down-wide-short":"sort",Z=L(te,{className:"rui-data-grid-sort-icon"});Z&&q.append(Z),q.onclick=()=>{const K=E.key===c&&u==="asc"?"desc":"asc";r.setState(_,{key:E.key,direction:K})},V.append(q)}else V.append(document.createTextNode(E.header));Je.append(V)}),me.append(Je),a.some(E=>E.filterable)){const E=o("tr",{class:"rui-data-grid-filter-row"});g&&E.append(o("td",{class:"rui-data-grid-cell-select"})),a.forEach(H=>{const V=o("td");if(H.filterable){const q=o("input",{type:"search",class:"rui-data-grid-filter",placeholder:`Filter ${H.header}`,value:x[H.key]??""});q.oninput=te=>{const Z=te.currentTarget,K={...y.get(),[H.key]:Z.value};y.set(K);const Y=Z.closest("table")?.querySelector("tbody");op(Y)},V.append(q)}E.append(V)}),me.append(E)}X.append(me);const Ae=o("tbody");X.append(Ae);const Qt=E=>{if(Ae.replaceChildren(),E.length===0){const H=o("tr"),V=(g?1:0)+Math.max(a.length,1);H.append(o("td",{colspan:String(V),class:"rui-data-grid-empty"},[d(e.emptyLabel,"No results")])),Ae.append(H);return}for(const H of E){const V=s(H),q=m.has(V),te=o("tr",{"data-selected":q?"true":null});if(g){const Z=o("td",{class:"rui-data-grid-cell-select"}),K=o("input",{type:"checkbox",class:"rui-data-grid-checkbox","aria-label":"Select row",checked:q?"":null});Q&&(K.onclick=Y=>{Y.stopPropagation();const ne=Y.currentTarget,de=new Set(p);ne.checked?de.add(V):de.delete(V),r.setState(Q,Array.from(de))}),Z.append(K),te.append(Z)}a.forEach((Z,K)=>{const Y=Z.values[H],ne=o("td",{"data-format":Z.format,"data-align":Z.align||null,"data-first":K===0?"true":null});Y!==null&&typeof Y=="object"&&Y.__kind==="Component"?ne.append(r.renderNode(Y)):ne.textContent=ct(Y,Z.format),te.append(ne)}),typeof e.rowAction=="function"&&(te.setAttribute("data-clickable","true"),te.onclick=Z=>{Z.target?.closest("input,button,a,label,select,textarea")||r.invoke(e.rowAction)}),Ae.append(te)}},op=E=>{const H=E??Ae,V=y.get(),q=[];for(let K=0;K<i;K+=1){let Y=!0;for(const ne of a){if(!ne.filterable)continue;const de=(V[ne.key]??"").trim().toLowerCase();if(!de)continue;const Xe=ne.values[K];if(!ct(Xe,ne.format).toLowerCase().includes(de)){Y=!1;break}}Y&&q.push(K)}if(c){const K=a.find(Y=>Y.key===c);K&&K.sortable&&q.sort((Y,ne)=>{const de=Ea(K.values[Y],K.values[ne],K.format);return u==="desc"?-de:de})}const te=q.slice((A-1)*S,A*S);(K=>{K.replaceChildren();for(const Y of te){const ne=s(Y),de=m.has(ne),Xe=o("tr",{"data-selected":de?"true":null});if(g){const Me=o("td",{class:"rui-data-grid-cell-select"}),er=o("input",{type:"checkbox",class:"rui-data-grid-checkbox",checked:de?"":null});Me.append(er),Xe.append(Me)}a.forEach((Me,er)=>{const Ze=Me.values[Y],tr=o("td",{"data-format":Me.format,"data-align":Me.align||null,"data-first":er===0?"true":null});Ze!==null&&typeof Ze=="object"&&Ze.__kind==="Component"?tr.append(r.renderNode(Ze)):tr.textContent=ct(Ze,Me.format),Xe.append(tr)}),K.append(Xe)}if(te.length===0){const Y=o("tr"),ne=(g?1:0)+Math.max(a.length,1);Y.append(o("td",{colspan:String(ne),class:"rui-data-grid-empty"},[d(e.emptyLabel,"No results")])),K.append(Y)}})(H)};if(Qt(z),J.append(X),R.append(J),T>S){const E=o("div",{class:"rui-data-grid-footer"}),H=T===0?0:(A-1)*S+1,V=Math.min(T,A*S);E.append(o("span",{class:"rui-data-grid-footer-summary"},[T===0?"No results":`Showing ${H}–${V} of ${T}`]));const q=o("div",{class:"rui-data-grid-footer-buttons"}),te=o("button",{type:"button",class:"rui-data-grid-page-button",disabled:A<=1?"":null},["‹ Prev"]),Z=o("button",{type:"button",class:"rui-data-grid-page-button",disabled:A>=$?"":null},["Next ›"]);B&&(te.onclick=()=>{A<=1||r.setState(B,A-1)},Z.onclick=()=>{A>=$||r.setState(B,A+1)}),q.append(te),q.append(o("span",{class:"rui-data-grid-page-current"},[`${A} / ${$}`])),q.append(Z),E.append(q),R.append(E)}return R}};function vc(t){const e=[];for(const r of k(t)){if(!r||typeof r!="object")continue;const a=r,i=d(a.date);i&&e.push({date:i,title:d(a.title),tone:d(a.tone,"primary"),time:d(a.time)})}return e}function _a(t,e){const r=new Date(t.getFullYear(),t.getMonth(),t.getDate()),i=(r.getDay()-e+7)%7;return r.setDate(r.getDate()-i),r}function ja(t){const e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0");return`${e}-${r}-${a}`}const yc={name:"CalendarView",description:"Full-month or week calendar grid for scheduling apps — distinct from the form-input `DatePicker`. Pass events as an array of `{date: 'YYYY-MM-DD', title, tone?, time?}` objects. Bind `value` to a `$variable` for the selected date (ISO string). Use `view=\"week\"` for a single-week strip. `firstDay=1` (Monday) matches most business apps.",props:[{name:"value",type:"string",optional:!0,description:"Selected ISO date (YYYY-MM-DD); bind a $variable"},{name:"month",type:"string",optional:!0,description:"Reference month — ISO date or YYYY-MM (defaults to today)"},{name:"events",type:"object[]",optional:!0,description:"Array of {date, title, tone?, time?} objects"},{name:"view",type:"string",optional:!0,enum:["month","week"]},{name:"firstDay",type:"number",optional:!0,description:"0=Sunday, 1=Monday (default 1)"},{name:"onSelect",type:"callable",optional:!0,description:"Callable fired when a day is clicked; receives the ISO date string"}],render:(t,e,r)=>{const a=d(e.view,"month"),i=vc(e.events),n=d(e.value),s=d(e.month,n),l=new Date;let c=new Date(NaN);if(s){const S=/^(\d{4})-(\d{2})(?:-(\d{2}))?$/.exec(s);if(S)c=new Date(Number(S[1]),Number(S[2])-1,S[3]?Number(S[3]):1);else{const $=new Date(s);Number.isNaN($.getTime())||(c=$)}}Number.isNaN(c.getTime())&&(c=l);const u=(P(e.firstDay,1)%7+7)%7,p=n&&/^\d{4}-\d{2}-\d{2}$/.test(n)?n:"",m=new Map;for(const S of i){const $=S.date.slice(0,10),N=m.get($)??[];N.push(S),m.set($,N)}const g=t.argMeta?.[0]?.stateRef,f=o("div",{class:"rui-calendar","data-view":a}),h=o("div",{class:"rui-calendar-header"}),b=c.toLocaleDateString(void 0,{month:"long",year:"numeric"});h.append(o("div",{class:"rui-calendar-title"},[b])),f.append(h);const v=o("div",{class:"rui-calendar-weekrow"}),y=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];for(let S=0;S<7;S+=1){const $=y[(u+S)%7]??"";v.append(o("div",{class:"rui-calendar-weekday"},[$]))}f.append(v);const x=[];if(a==="week"){const S=p?new Date(p):c,$=_a(S,u);for(let N=0;N<7;N+=1){const A=new Date($);A.setDate($.getDate()+N),x.push({date:A,inMonth:A.getMonth()===c.getMonth()})}}else{const S=new Date(c.getFullYear(),c.getMonth(),1),$=new Date(c.getFullYear(),c.getMonth()+1,0),N=_a(S,u),A=Math.ceil(($.getDate()+(S.getDay()-u+7)%7)/7)*7;for(let z=0;z<A;z+=1){const R=new Date(N);R.setDate(N.getDate()+z),x.push({date:R,inMonth:R.getMonth()===c.getMonth()})}}const w=o("div",{class:"rui-calendar-grid","data-view":a}),T=ja(l);for(const S of x){const $=ja(S.date),N=$===T,A=$===p,z=m.get($)??[],R=o("button",{type:"button",class:"rui-calendar-day","data-in-month":S.inMonth?"true":"false","data-today":N?"true":"false","data-selected":A?"true":"false","aria-label":S.date.toDateString()});if(R.append(o("span",{class:"rui-calendar-daynumber"},[String(S.date.getDate())])),z.length>0){const _=o("div",{class:"rui-calendar-day-events"}),Q=z.slice(0,3);for(const B of Q){const O=o("span",{class:"rui-calendar-event","data-tone":B.tone??"primary",title:B.time?`${B.time} — ${B.title}`:B.title},[B.title]);_.append(O)}z.length>3&&_.append(o("span",{class:"rui-calendar-event-more"},[`+${z.length-3} more`])),R.append(_)}R.onclick=()=>{g&&r.setState(g,$),r.invoke(e.onSelect,$)},w.append(R)}return f.append(w),f}};function xc(t){const e=[];for(const r of k(t)){if(!r||typeof r!="object")continue;const a=r;e.push({title:d(a.title),description:d(a.description),actor:d(a.actor),avatarSrc:d(a.avatarSrc),time:d(a.time),icon:d(a.icon),tone:d(a.tone,"default"),meta:d(a.meta)})}return e}function wc(t,e,r){const a=o("ol",{class:t,"data-variant":r});for(const i of e){const n=o("li",{class:`${t}-item`,"data-tone":i.tone}),s=o("span",{class:`${t}-marker`}),l=L(i.icon,{className:`${t}-icon`});l&&s.append(l),n.append(s);const c=o("div",{class:`${t}-body`}),u=o("div",{class:`${t}-head`});i.actor&&u.append(o("span",{class:`${t}-actor`},[i.actor])),u.append(o("span",{class:`${t}-title`},[i.title])),i.time&&u.append(o("span",{class:`${t}-time`},[i.time])),c.append(u),i.description&&c.append(o("p",{class:`${t}-description`},[i.description])),i.meta&&c.append(o("span",{class:`${t}-meta`},[i.meta])),n.append(c),a.append(n)}return a}const kc={name:"ActivityLog",description:'Purpose-built feed of user/system activity. Each entry has `actor`, `title`, `description?`, `time?`, `icon?`, `tone?`, and optional `meta` (IP, browser, request id). Use `variant="audit"` for monospace security/admin trails. Pass items as `{actor, title, description, time, icon, tone, avatarSrc, meta}` objects.',props:[{name:"items",type:"object[]"},{name:"variant",type:"string",optional:!0,enum:["default","audit"],description:"audit = monospace voice with meta column"}],render:(t,e)=>{const r=d(e.variant,"default");return wc(r==="audit"?"rui-audit-trail":"rui-activity-log",xc(e.items),r)}},Sc={name:"ComparisonTable",description:"Feature/spec comparison table — generic counterpart of `PricingTable`. Pass `columns` (e.g. plan/product names) and `rows` of `{label, values}` where `values` aligns 1-to-1 with `columns`. Each value can be a boolean (✓/—), a string, or a node.",props:[{name:"columns",type:"string[]",description:"Column headers"},{name:"rows",type:"object[]",description:"Array of {label, values, hint?, group?} entries"},{name:"highlightColumn",type:"number",optional:!0,description:"0-indexed column to visually emphasise"}],render:(t,e,r)=>{const a=k(e.columns).map(g=>d(g)),i=k(e.rows).map(g=>{const f=g??{};return{label:d(f.label),values:k(f.values),hint:d(f.hint),group:d(f.group)}}),n=Math.floor(P(e.highlightColumn,-1)),s=o("div",{class:"rui-comparison-table"}),l=o("table"),c=o("thead"),u=o("tr");u.append(o("th",{scope:"col",class:"rui-comparison-table-feature"},["Feature"])),a.forEach((g,f)=>{u.append(o("th",{scope:"col","data-highlight":f===n?"true":null},[g]))}),c.append(u),l.append(c);const p=o("tbody");let m="";for(const g of i){if(g.group&&g.group!==m){m=g.group;const b=o("tr",{class:"rui-comparison-table-group"});b.append(o("td",{colspan:String(a.length+1)},[g.group])),p.append(b)}const f=o("tr"),h=o("td",{class:"rui-comparison-table-feature"});h.append(o("div",{class:"rui-comparison-table-feature-label"},[g.label])),g.hint&&h.append(o("div",{class:"rui-comparison-table-feature-hint"},[g.hint])),f.append(h);for(let b=0;b<a.length;b+=1){const v=g.values[b],y=o("td",{"data-highlight":b===n?"true":null});if(v===!0){const x=L("circle-check",{className:"rui-comparison-yes"});x?y.append(x):y.textContent="✓"}else v===!1||v===null||v===void 0?y.append(o("span",{class:"rui-comparison-no"},["—"])):v&&typeof v=="object"&&v.__kind==="Component"?y.append(r.renderNode(v)):y.textContent=d(v);f.append(y)}p.append(f)}return l.append(p),s.append(l),s}},Cc={name:"InfiniteList",description:"Vertical list that fires `onLoadMore` when the user scrolls near the bottom. Pass already-rendered child nodes as `items`; wire `onLoadMore` to an `action` that awaits a `$mutation` or `$query` (e.g. `await loadMore.invoke()`) and appends to the bound state. Use `loading=true` to show the spinner row, `hasMore=false` to suppress further loads.",props:[{name:"items",type:"Node[]",description:"Already-rendered child nodes"},{name:"onLoadMore",type:"callable",optional:!0,description:"Callable fired when the sentinel scrolls into view"},{name:"loading",type:"boolean",optional:!0},{name:"hasMore",type:"boolean",optional:!0,description:"Default true — set false to hide the sentinel"},{name:"loaderLabel",type:"string",optional:!0,description:"Label rendered while loading (default `Loading…`)"}],render:(t,e,r)=>{const a=o("div",{class:"rui-infinite-list"}),i=o("div",{class:"rui-infinite-list-body"});for(const l of k(e.items))i.append(r.renderNode(l));a.append(i);const n=e.hasMore===void 0?!0:C(e.hasMore),s=C(e.loading);if(n){const l=o("div",{class:"rui-infinite-list-sentinel"});if(s){const c=L("spinner",{className:"rui-infinite-list-spin"});c&&l.append(c),l.append(o("span",{},[d(e.loaderLabel,"Loading…")]))}else if(typeof e.onLoadMore=="function"){const c=o("button",{type:"button",class:"rui-infinite-list-load-more"},["Load more"]);c.onclick=()=>r.invoke(e.onLoadMore),l.append(c)}if(a.append(l),!s&&typeof e.onLoadMore=="function"&&typeof IntersectionObserver<"u"){const c=e.onLoadMore,u=new IntersectionObserver(p=>{for(const m of p)if(m.isIntersecting){r.invoke(c);break}});u.observe(l),r.registerDisposer(()=>u.disconnect(),"infinite-observer")}}return a}},Tc=/^(https?:|blob:|data:(audio|video)\/)/i;function ut(t){const e=d(t).trim();return e?e.startsWith("/")||e.startsWith(".")?e:e.startsWith("//")?"":Tc.test(e)?e:"":""}const Nc={name:"VideoPlayer",description:"Themed native `<video>` wrapper. Pass a `src` URL (or `sources` array for multi-codec fallback) and optional `poster`. Standard controls are visible by default; pass `autoplay`, `loop`, `muted`, or `controls=false` to override. Use for product demos, tutorials, and any inline video.",props:[{name:"src",type:"string",optional:!0,description:"Video URL (mp4 / webm / etc.)"},{name:"sources",type:"object[]",optional:!0,description:"Array of {src, type} entries for multi-codec fallback"},{name:"poster",type:"string",optional:!0,description:"Thumbnail image URL shown before playback"},{name:"caption",type:"string",optional:!0},{name:"controls",type:"boolean",optional:!0,description:"Show native controls (default true)"},{name:"autoplay",type:"boolean",optional:!0},{name:"loop",type:"boolean",optional:!0},{name:"muted",type:"boolean",optional:!0},{name:"ratio",type:"string",optional:!0,description:"Aspect ratio (default 16:9)"}],render:(t,e)=>{const r=o("figure",{class:"rui-video-player"}),a=Ot(d(e.ratio,"16:9")),i=o("div",{class:"rui-video-player-frame",style:`aspect-ratio:${a};`}),n=e.controls===void 0?!0:C(e.controls),s=o("video",{class:"rui-video-player-video",controls:n?"":null,autoplay:C(e.autoplay)?"":null,loop:C(e.loop)?"":null,muted:C(e.muted)?"":null,poster:re(e.poster)||null,playsinline:"",preload:"metadata"}),l=k(e.sources);if(l.length>0)for(const u of l){if(!u||typeof u!="object")continue;const p=u,m=ut(p.src);m&&s.append(o("source",{src:m,type:d(p.type)||null}))}else{const u=ut(e.src);u&&s.setAttribute("src",u)}i.append(s),r.append(i);const c=d(e.caption);return c&&r.append(o("figcaption",{class:"rui-video-player-caption"},[c])),r}},$c={name:"AudioPlayer",description:"Themed native `<audio>` wrapper with a title, optional artist, and standard transport controls. Pass `src` (or `sources`) plus a `title` so the bar still looks like a player when the controls bar is hidden. Use for podcasts, voice notes, and demo audio.",props:[{name:"src",type:"string",optional:!0,description:"Audio URL (mp3 / ogg / wav / etc.)"},{name:"sources",type:"object[]",optional:!0,description:"Array of {src, type} entries for multi-codec fallback"},{name:"title",type:"string",optional:!0},{name:"artist",type:"string",optional:!0},{name:"controls",type:"boolean",optional:!0,description:"Show native controls (default true)"},{name:"autoplay",type:"boolean",optional:!0},{name:"loop",type:"boolean",optional:!0},{name:"icon",type:"string",optional:!0,description:"Leading icon (default `music`)"}],render:(t,e)=>{const r=o("div",{class:"rui-audio-player"}),a=o("div",{class:"rui-audio-player-meta"}),i=L(d(e.icon,"music"),{className:"rui-audio-player-icon"});i&&a.append(i);const n=o("div",{class:"rui-audio-player-text"}),s=d(e.title);s&&n.append(o("div",{class:"rui-audio-player-title"},[s]));const l=d(e.artist);l&&n.append(o("div",{class:"rui-audio-player-artist"},[l])),a.append(n),r.append(a);const c=e.controls===void 0?!0:C(e.controls),u=o("audio",{class:"rui-audio-player-audio",controls:c?"":null,autoplay:C(e.autoplay)?"":null,loop:C(e.loop)?"":null,preload:"metadata"}),p=k(e.sources);if(p.length>0)for(const m of p){if(!m||typeof m!="object")continue;const g=m,f=ut(g.src);f&&u.append(o("source",{src:f,type:d(g.type)||null}))}else{const m=ut(e.src);m&&u.setAttribute("src",m)}return r.append(u),r}};function Ac(t,e){if(t==null)return null;if(typeof t=="object"&&t.__kind==="Component")return e.renderNode(t);if(typeof t=="string"){const r=re(t);return r?o("img",{src:r,alt:"",loading:"lazy",class:"rui-carousel-image"}):null}if(typeof t=="object"){const r=t,a=re(r.src);if(a){const i=o("figure",{class:"rui-carousel-figure"});i.append(o("img",{src:a,alt:d(r.alt??r.caption??r.title),loading:"lazy",class:"rui-carousel-image"}));const n=d(r.caption??r.title);return n&&i.append(o("figcaption",{class:"rui-carousel-caption"},[n])),i}}return e.renderNode(t)}const Mc={name:"Carousel",description:"Horizontal slider with prev/next buttons and dot navigation. Each child slide takes full width. Slides may be Component nodes (Image, Card, MediaCard, …), URL strings, or plain `{src, alt, caption?}` image objects — bare image objects are auto-wrapped into a captioned figure. Use for image galleries, onboarding carousels, hero banners, and product image strips. The active slide is preserved across re-renders via instance state.",props:[{name:"items",type:"Node[]",description:"Slide nodes, image URLs, or {src, alt, caption?} objects"},{name:"activeIndex",type:"number",optional:!0,description:"0-indexed initial slide (default 0)"},{name:"ratio",type:"string",optional:!0,description:"Aspect ratio of the frame (default `16:9`)"},{name:"showDots",type:"boolean",optional:!0,description:"Show indicator dots (default true)"},{name:"showArrows",type:"boolean",optional:!0,description:"Show prev/next arrows (default true)"}],render:(t,e,r)=>{const a=k(e.items),i=a.length,n=Math.max(0,Math.min(Math.max(i-1,0),Math.floor(P(e.activeIndex,0)))),s=r.useInstanceState("active",n);let l=s.get();l>=i&&(l=0,s.set(l));const c=e.showDots===void 0?!0:C(e.showDots),u=e.showArrows===void 0?!0:C(e.showArrows),p=Ot(d(e.ratio,"16:9")),m=o("div",{class:"rui-carousel"}),g=o("div",{class:"rui-carousel-frame",style:`aspect-ratio:${p};`}),f=o("div",{class:"rui-carousel-track",style:`transform:translateX(${l*-100}%);`});a.forEach(b=>{const v=o("div",{class:"rui-carousel-slide"}),y=Ac(b,r);y&&v.append(y),f.append(v)}),g.append(f);const h=(b,v)=>{const y=(v%i+i)%i;s.set(y);const x=b.closest(".rui-carousel"),w=x?.querySelector(".rui-carousel-track");w&&(w.style.transform=`translateX(${y*-100}%)`),x?.querySelectorAll(".rui-carousel-dot").forEach((T,S)=>{T.setAttribute("data-active",S===y?"true":"false")})};if(u&&i>1){const b=o("button",{type:"button",class:"rui-carousel-arrow","data-direction":"prev","aria-label":"Previous slide"}),v=L("chevron-left");v&&b.append(v);const y=o("button",{type:"button",class:"rui-carousel-arrow","data-direction":"next","aria-label":"Next slide"}),x=L("chevron-right");x&&y.append(x),b.onclick=w=>h(w.currentTarget,s.get()-1),y.onclick=w=>h(w.currentTarget,s.get()+1),g.append(b,y)}if(m.append(g),c&&i>1){const b=o("div",{class:"rui-carousel-dots"});a.forEach((v,y)=>{const x=o("button",{type:"button",class:"rui-carousel-dot","data-active":y===l?"true":"false","aria-label":`Go to slide ${y+1}`});x.onclick=w=>h(w.currentTarget,y),b.append(x)}),m.append(b)}return m}},Pc={name:"Gallery",description:"Responsive image grid. Pass items as plain URL strings, `{src, alt, caption?}` objects, or `Image(...)` nodes. When `onSelect` is provided each tile becomes a button; bind it through an Action that opens a `Lightbox`.",props:[{name:"items",type:"any[]"},{name:"columns",type:"number",optional:!0,description:"Preferred column count (default auto)"},{name:"ratio",type:"string",optional:!0,description:"Per-tile aspect ratio (default `1:1`)"},{name:"onSelect",type:"callable",optional:!0,description:"Callable fired when a tile is clicked"}],render:(t,e,r)=>{const a=k(e.items),i=Math.max(1,Math.min(6,Number(e.columns??"auto"))),n=Ot(d(e.ratio,"1:1")),s=o("div",{class:"rui-gallery","data-columns":i>0?String(i):null});return a.forEach((l,c)=>{const{src:u,alt:p,caption:m}=Ba(l),g=re(u),f=typeof e.onSelect=="function",h=o(f?"button":"figure",{type:f?"button":null,class:"rui-gallery-tile",style:`aspect-ratio:${n};`,"data-index":String(c)});if(g)h.append(o("img",{src:g,alt:p,loading:"lazy"}));else{const b=L("image",{className:"rui-gallery-placeholder"});b&&h.append(b)}m&&h.append(o("span",{class:"rui-gallery-caption"},[m])),f&&(h.onclick=()=>r.invoke(e.onSelect,c,l)),s.append(h)}),s}};function Ba(t){if(typeof t=="string")return{src:t,alt:"",caption:""};if(t&&typeof t=="object"){const e=t;return e.__kind==="Component"&&Array.isArray(e.args)?{src:d(e.args[0]),alt:d(e.args[1]),caption:d(e.args[2])}:{src:d(e.src),alt:d(e.alt),caption:d(e.caption)}}return{src:"",alt:"",caption:""}}const Ic={name:"Lightbox",description:"Image overlay. When you bind a `$variable` to `open` you control it explicitly; without one, Lightbox renders a clickable thumbnail of the current image that opens the overlay on click (and uses internal state for next/prev). Pass `items` (string URLs or `{src, alt, caption?}` objects). Clicking the backdrop or × closes; arrows step through the array.",props:[{name:"items",type:"any[]"},{name:"open",type:"boolean",optional:!0,description:"Open/closed; bind a $variable to control externally"},{name:"index",type:"number",optional:!0,description:"0-indexed current image; typically a $variable"}],render:(t,e,r)=>{const a=k(e.items).map(N=>Ba(N)).filter(N=>re(N.src)!==""),i=a.length,n=t.argMeta?.[2]?.stateRef,s=t.argMeta?.[1]?.stateRef,l=r.useInstanceState("open",!1),c=r.useInstanceState("index",0),u=s?C(e.open):l.get(),p=n?Math.floor(P(e.index,0)):c.get(),m=i===0?0:(p%i+i)%i,g=N=>{s?r.setState(s,N):l.set(N)},f=N=>{n?r.setState(n,N):c.set(N)},h=()=>g(!1),b=N=>{i!==0&&f(((m+N)%i+i)%i)},v=o("div",{class:"rui-lightbox-root"});if(!s&&i>0){const N=a[m],A=o("button",{type:"button",class:"rui-lightbox-thumb","aria-label":N?.alt||"Open image"});if(N){const z=re(N.src);z&&A.append(o("img",{src:z,alt:N.alt,loading:"lazy"}))}A.onclick=z=>{z.stopPropagation(),g(!0)},v.append(A)}const y=o("div",{class:"rui-lightbox-overlay","data-open":u?"true":"false"});if(v.append(y),!u||i===0)return v;const x=a[m];if(!x)return v;const w=re(x.src);y.onclick=N=>{N.target===y&&h()};const T=o("div",{class:"rui-lightbox",role:"dialog","aria-modal":"true"}),S=o("button",{type:"button",class:"rui-lightbox-close","aria-label":"Close lightbox"},["×"]);if(S.onclick=h,T.append(S),i>1){const N=o("button",{type:"button",class:"rui-lightbox-arrow","data-direction":"prev","aria-label":"Previous image"}),A=L("chevron-left");A&&N.append(A),N.onclick=()=>b(-1);const z=o("button",{type:"button",class:"rui-lightbox-arrow","data-direction":"next","aria-label":"Next image"}),R=L("chevron-right");R&&z.append(R),z.onclick=()=>b(1),T.append(N,z)}const $=o("div",{class:"rui-lightbox-image-wrap"});return w&&$.append(o("img",{src:w,alt:x.alt})),T.append($),x.caption&&T.append(o("div",{class:"rui-lightbox-caption"},[x.caption])),i>1&&T.append(o("div",{class:"rui-lightbox-counter"},[`${m+1} / ${i}`])),y.append(T),v}};function zc(t){if(!t)return null;if(typeof t=="object"&&!Array.isArray(t)){const e=t,r=P(e.lat??e.latitude,NaN),a=P(e.lng??e.longitude,NaN);if(Number.isFinite(r)&&Number.isFinite(a))return{lat:r,lng:a}}if(Array.isArray(t)&&t.length>=2){const e=P(t[0],NaN),r=P(t[1],NaN);if(Number.isFinite(e)&&Number.isFinite(r))return{lat:e,lng:r}}if(typeof t=="string"){const e=t.split(",").map(r=>Number(r.trim()));if(e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]))return{lat:e[0],lng:e[1]}}return null}const Rc={name:"Map",description:"Static map view centered on a lat/lng coordinate. Renders an OpenStreetMap embed inside an `<iframe>` (no external JS, no API key). Pass `lat` and `lng` as bare numbers; `zoom` controls the level (1–18, default 13). Optional `markers` array adds map pins (rendered as a labelled list alongside the map). Use for store locators, address cards, itinerary previews.",props:[{name:"lat",type:"number",description:"Latitude of the map center"},{name:"lng",type:"number",description:"Longitude of the map center"},{name:"zoom",type:"number",optional:!0,description:"1–18 (default 13)"},{name:"markers",type:"object[]",optional:!0,description:"Array of {lat, lng, label?} markers (informational; rendered alongside the map)"},{name:"height",type:"string",optional:!0,description:"CSS height (default 320px)"},{name:"caption",type:"string",optional:!0}],render:(t,e)=>{const r=o("figure",{class:"rui-map"}),a=ee(e.height,"320px"),i=o("div",{class:"rui-map-frame",style:`height:${a};`}),n=P(e.lat,NaN),s=P(e.lng,NaN),l=Number.isFinite(n)&&Number.isFinite(s)?{lat:n,lng:s}:null;if(!l){i.append(o("div",{class:"rui-map-empty"},["Pass lat & lng (numbers) to render the map."])),r.append(i);const b=d(e.caption);return b&&r.append(o("figcaption",{class:"rui-map-caption"},[b])),r}const c=Math.max(1,Math.min(18,Math.floor(P(e.zoom,13)))),u=1/Math.pow(2,c-8),m=`https://www.openstreetmap.org/export/embed.html?bbox=${[l.lng-u,l.lat-u/2,l.lng+u,l.lat+u/2].join(",")}&layer=mapnik&marker=${l.lat},${l.lng}`,g=o("iframe",{class:"rui-map-iframe",src:m,loading:"lazy",title:"Map view",referrerpolicy:"no-referrer"});i.append(g),r.append(i);const f=k(e.markers).map(b=>{const v=zc(b),y=b&&typeof b=="object"?d(b.label):"";return v?{...v,label:y}:null}).filter(b=>b!==null);if(f.length>0){const b=o("ul",{class:"rui-map-markers"});for(const v of f){const y=o("li",{class:"rui-map-marker"}),x=L("location-dot",{className:"rui-map-marker-icon"});x&&y.append(x),y.append(o("span",{class:"rui-map-marker-label"},[v.label||`${v.lat.toFixed(4)}, ${v.lng.toFixed(4)}`])),b.append(y)}r.append(b)}const h=d(e.caption);return h&&r.append(o("figcaption",{class:"rui-map-caption"},[h])),r}};function Ot(t){if(t.includes(":")){const[r,a]=t.split(":"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n>0)return`${i} / ${n}`}const e=Number(t);return Number.isFinite(e)&&e>0?`${e} / 1`:"16 / 9"}const Lc=[{command:"bold",icon:"bold",label:"Bold"},{command:"italic",icon:"italic",label:"Italic"},{command:"underline",icon:"underline",label:"Underline"},{command:"strikeThrough",icon:"strikethrough",label:"Strikethrough"},{command:"formatBlock",icon:"heading",label:"Heading",block:"h2"},{command:"formatBlock",icon:"quote-left",label:"Quote",block:"blockquote"},{command:"insertUnorderedList",icon:"list-ul",label:"Bullet list"},{command:"insertOrderedList",icon:"list-ol",label:"Numbered list"},{command:"createLink",icon:"link",label:"Link"}],Ec={name:"RichTextEditor",description:"Rich-text WYSIWYG editor for CMS, email, and comment surfaces. Renders a small toolbar (bold / italic / underline / strikethrough / headings / lists / quote / link) above a `contenteditable` region. Pass `$variable` as `value` for two-way binding — the HTML body is written back to state on every edit. Provide `placeholder` for the empty-state prompt.",props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"Bound HTML body (typically $variable)"},{name:"placeholder",type:"string",optional:!0,description:"Empty-state prompt"},{name:"minHeight",type:"string",optional:!0,description:"CSS min-height for the editor area (default 160px)"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=d(e.placeholder,"Start writing…"),n=C(e.disabled),s=o("div",{class:"rui-rich-text","data-disabled":n?"true":"false"}),l=o("div",{class:"rui-rich-text-toolbar",role:"toolbar"});for(const f of Lc){const h=o("button",{type:"button",class:"rui-rich-text-tool","data-command":f.command,"data-block":f.block??null,"aria-label":f.label,title:f.label,disabled:n?"":null}),b=L(f.icon);b&&h.append(b),h.onmousedown=v=>v.preventDefault(),h.onclick=v=>{const x=v.currentTarget.closest(".rui-rich-text")?.querySelector(".rui-rich-text-content");if(x){x.focus();try{if(f.command==="createLink"){const w=window.prompt("URL");w&&document.execCommand("createLink",!1,w)}else f.command==="formatBlock"&&f.block?document.execCommand("formatBlock",!1,f.block):document.execCommand(f.command,!1)}catch{}x.dispatchEvent(new Event("input",{bubbles:!0}))}},l.append(h)}s.append(l);const c=d(e.value)||"",u=f=>f.replace(/<br\s*\/?>(?=\s*$)/gi,"").replace(/<[^>]+>/g,"").replace(/&nbsp;/g," ").trim().length===0,p=o("div",{class:"rui-rich-text-content",id:a,contenteditable:n?"false":"true",role:"textbox","aria-multiline":"true","aria-placeholder":i,"data-placeholder":i,"data-empty":u(c)?"true":"false",style:`min-height:${d(e.minHeight,"160px")};`,html:c}),m=f=>{f.setAttribute("data-empty",u(f.innerHTML)?"true":"false")},g=t.argMeta?.[1]?.stateRef;return g&&!n?r.bindState(p,g,{event:"input",getValue:f=>{const h=f;return m(h),h.innerHTML}}):p.oninput=f=>{const h=f.currentTarget??f.target;m(h)},p.onblur=f=>{const h=f.currentTarget??f.target;m(h)},s.append(p),s}},_c={name:"CodeEditor",description:"Lightweight, dependency-free code editor. Pairs a styled textarea with a synchronised line-number gutter — no syntax highlighting, but the editor stays a single rendered node so it works inside Shadow DOM. Use for dev tooling, snippet editing, prompt playgrounds. Pass a `$variable` as `value` for two-way binding. For read-only rendering with highlights prefer `CodeBlock`.",props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"Bound source text (typically $variable)"},{name:"language",type:"string",optional:!0,enum:["text","javascript","typescript","json","html","css","bash","python","sql","markdown"],description:"Language label shown on the header (default `text`)"},{name:"placeholder",type:"string",optional:!0},{name:"minHeight",type:"string",optional:!0,description:"CSS min-height for the editor area (default 200px)"},{name:"tabSize",type:"number",optional:!0,description:"Spaces per Tab (default 2)"},{name:"showGutter",type:"boolean",optional:!0,description:"Show line-number gutter (default true)"},{name:"readonly",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=d(e.value),n=d(e.language,"text"),s=e.showGutter===void 0?!0:C(e.showGutter),l=Math.max(1,Math.min(8,Math.floor(P(e.tabSize,2)))),c=C(e.readonly),u=d(e.minHeight,"200px"),p=o("div",{class:"rui-code-editor","data-language":n,"data-gutter":s?"true":"false"}),m=o("div",{class:"rui-code-editor-head"});m.append(o("span",{class:"rui-code-editor-language"},[n])),p.append(m);const g=o("div",{class:"rui-code-editor-body",style:`min-height:${u};`}),f=o("div",{class:"rui-code-editor-gutter","aria-hidden":"true"});s&&((y=>{f.replaceChildren();const x=y.split(/\r?\n/),w=Math.max(1,x.length);for(let T=1;T<=w;T+=1)f.append(o("span",{class:"rui-code-editor-line"},[String(T)]))})(i),g.append(f));const b=o("textarea",{class:"rui-code-editor-textarea",id:a,name:a,spellcheck:"false",autocorrect:"off",autocapitalize:"off",placeholder:d(e.placeholder),readonly:c?"":null,style:`tab-size:${l};-moz-tab-size:${l};`});b.value=i,b.oninput=y=>{const x=y.currentTarget;if(!s)return;const T=x.closest(".rui-code-editor")?.querySelector(".rui-code-editor-gutter");if(!T)return;T.replaceChildren();const S=x.value.split(/\r?\n/),$=Math.max(1,S.length);for(let N=1;N<=$;N+=1)T.append(o("span",{class:"rui-code-editor-line"},[String(N)]))},b.onkeydown=y=>{const x=y;if(x.key!=="Tab")return;x.preventDefault();const w=x.currentTarget,T=w.selectionStart,S=w.selectionEnd,$=" ".repeat(l);w.value=w.value.slice(0,T)+$+w.value.slice(S),w.selectionStart=w.selectionEnd=T+$.length,w.dispatchEvent(new Event("input",{bubbles:!0}))};const v=t.argMeta?.[1]?.stateRef;return v&&!c&&r.bindState(b,v,{event:"input",getValue:y=>y.value}),g.append(b),p.append(g),p}};function jc(t){if(!t)return null;if(typeof t=="object"){const e=t;if(e.__kind==="Component"&&e.name==="MenuItem"&&Array.isArray(e.args)){const a=e.args;return{label:d(a[0]),action:a[1],icon:d(a[2]),shortcut:d(a[3]),variant:d(a[4],"default"),disabled:C(a[5]),separator:!1}}if(e.__kind==="Component"&&e.name==="MenuSeparator")return{label:"",action:null,icon:"",shortcut:"",variant:"default",disabled:!1,separator:!0};const r=t;return r.separator?{label:"",action:null,icon:"",shortcut:"",variant:"default",disabled:!1,separator:!0}:{label:d(r.label),action:r.action,icon:d(r.icon),shortcut:d(r.shortcut),variant:d(r.variant,"default"),disabled:C(r.disabled),separator:!1}}return null}const Bc={name:"ContextMenu",description:"Right-click (or long-press) menu that attaches to a child node. Wraps `target` and shows the menu at the pointer when the user right-clicks anywhere inside it. Items are `MenuItem(...)` nodes, `MenuSeparator()` entries, or `{label, action, icon?, shortcut?, variant?, disabled?, separator?}` objects. Use on table rows, tree nodes, kanban cards, file browser entries.",props:[{name:"target",type:"Node",description:"Child node the menu is bound to"},{name:"items",type:"any[]",description:"MenuItem nodes or {label, action} objects"},{name:"label",type:"string",optional:!0,description:"ARIA label for the menu"}],render:(t,e,r)=>{const a=o("div",{class:"rui-context-menu"}),i=o("div",{class:"rui-context-menu-target"});i.append(r.renderNode(e.target)),a.append(i);const n=o("div",{class:"rui-context-menu-pop",role:"menu","aria-label":d(e.label)||null,"data-open":"false"}),s=k(e.items).map(jc).filter(u=>u!==null);for(const u of s){if(u.separator){n.append(o("div",{class:"rui-menu-separator",role:"separator"}));continue}const p=o("button",{type:"button",class:"rui-menu-item",role:"menuitem","data-variant":u.variant,disabled:u.disabled?"":null}),m=L(u.icon,{className:"rui-menu-item-icon"});m&&p.append(m),p.append(o("span",{class:"rui-menu-item-label"},[u.label])),u.shortcut&&p.append(o("span",{class:"rui-menu-item-shortcut"},[u.shortcut])),u.disabled||(p.onclick=()=>{r.invoke(u.action),n.setAttribute("data-open","false")}),n.append(p)}a.append(n);const l=()=>n.setAttribute("data-open","false"),c=(u,p)=>{const m=i.isConnected?i.closest(".rui-context-menu"):null,g=m?.querySelector(".rui-context-menu-pop")??n,f=m?.getBoundingClientRect(),h=f?u-f.left:u,b=f?p-f.top:p;g.style.left=`${h}px`,g.style.top=`${b}px`,g.setAttribute("data-open","true");const v=y=>{y.target&&g.contains(y.target)||(g.setAttribute("data-open","false"),document.removeEventListener("click",v,!0),document.removeEventListener("contextmenu",v,!0))};setTimeout(()=>{document.addEventListener("click",v,!0),document.addEventListener("contextmenu",v,!0)},0)};return i.oncontextmenu=u=>{u.preventDefault(),c(u.clientX,u.clientY)},i.onkeydown=u=>{const p=u;if(p.key==="ContextMenu"||p.shiftKey&&p.key==="F10"){p.preventDefault();const g=p.currentTarget.getBoundingClientRect();c(g.left,g.top+g.height)}p.key==="Escape"&&l()},a}},Dc=["#0f172a","#334155","#64748b","#94a3b8","#ef4444","#f59e0b","#facc15","#10b981","#06b6d4","#3b82f6","#6366f1","#8b5cf6"];function Ge(t){const e=t.trim();if(!e)return"";let r=e.startsWith("#")?e.slice(1):e;return r.length===3&&(r=r.split("").map(a=>a+a).join("")),/^[0-9a-fA-F]{6,8}$/.test(r)?`#${r.toLowerCase().slice(0,6)}`:""}const Fc={name:"ColorPicker",description:'Hex / RGB color form control with preset swatches. Pairs a native `<input type="color">` chip with a hex text input and a row of preset swatches. Pass a `$variable` as `value` (hex string, e.g. `"#6366f1"`) for two-way binding. Use for theme builders, label color pickers, and any "pick a color" surface.',props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"Bound hex value (typically $variable)"},{name:"label",type:"string",optional:!0},{name:"swatches",type:"string[]",optional:!0,description:"Preset hex colors (default to a 12-color palette)"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=Ge(d(e.value))||d(e.value,"#000000"),n=C(e.disabled),s=o("div",{class:"rui-color-picker","data-disabled":n?"true":"false"}),l=d(e.label);l&&s.append(o("label",{class:"rui-color-picker-label",for:a},[l]));const c=o("div",{class:"rui-color-picker-row"}),u=o("input",{type:"color",class:"rui-color-picker-color",id:a,name:a,value:Ge(i)||"#000000",disabled:n?"":null}),p=o("input",{type:"text",class:"rui-color-picker-hex",value:i,placeholder:"#000000",disabled:n?"":null,autocomplete:"off"}),m=o("div",{class:"rui-color-picker-swatches"}),g=k(e.swatches).map(b=>d(b)).filter(Boolean),f=g.length>0?g:Dc;for(const b of f){const v=Ge(b)||b,y=o("button",{type:"button",class:"rui-color-picker-swatch",style:`background:${v}`,"aria-label":v,title:v,"data-active":v.toLowerCase()===i.toLowerCase()?"true":"false"});y.onclick=()=>{u.value=Ge(v)||u.value,p.value=v,u.dispatchEvent(new Event("input",{bubbles:!0}))},m.append(y)}const h=t.argMeta?.[1]?.stateRef;return h&&!n&&(r.bindState(u,h,{event:"input",getValue:b=>b.value}),u.addEventListener("input",()=>{p.value=u.value}),p.oninput=()=>{const b=Ge(p.value);b&&(u.value=b,u.dispatchEvent(new Event("input",{bubbles:!0})))}),c.append(u,p),s.append(c,m),s}},Ut=["var(--rui-chart-1, #6366f1)","var(--rui-chart-2, #10b981)","var(--rui-chart-3, #f59e0b)","var(--rui-chart-4, #ef4444)","var(--rui-chart-5, #06b6d4)","var(--rui-chart-6, #8b5cf6)"],Ne=t=>Ut[t%Ut.length]??Ut[0];function Oc(t){return t.map((e,r)=>{const a=e,i=d(a.args?.[0],`Series ${r+1}`),n=k(a.args?.[1]).map(s=>P(s));return{name:i,values:n}})}function dt(t,e){const r=document.createElementNS("http://www.w3.org/2000/svg","svg");return r.setAttribute("viewBox",`0 0 ${t} ${e}`),r.setAttribute("class","rui-chart-svg"),r.setAttribute("role","img"),r}function ie(t,e,r){const a=document.createElementNS("http://www.w3.org/2000/svg",t);for(const[i,n]of Object.entries(e))a.setAttribute(i,n);if(r)for(const i of r)a.append(typeof i=="string"?document.createTextNode(i):i);return a}function Da(t){const e=o("div",{class:"rui-chart-legend"});return t.forEach((r,a)=>{const i=o("span",{class:"rui-chart-legend-item"});i.append(o("span",{class:"rui-chart-legend-swatch",style:`background:${Ne(a)}`})),i.append(o("span",{},[r.name])),e.append(i)}),e}const Uc={name:"Gauge",description:"Half-doughnut gauge indicator for a single value between `min` and `max`. The inner value is auto-formatted from the value (override via `label`). Pass `caption`, `tone`, and `size` for visual treatment. Use for KPI thresholds (uptime %, score, capacity, NPS, page-speed).",props:[{name:"value",type:"number"},{name:"min",type:"number",optional:!0,description:"Lower bound (default 0)"},{name:"max",type:"number",optional:!0,description:"Upper bound (default 100)"},{name:"caption",type:"string",optional:!0,description:"Small caption below the gauge"},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]},{name:"label",type:"string",optional:!0,description:"Inner label override (defaults to auto-formatted value)"}],render:(t,e)=>{const r=P(e.min,0),a=Math.max(r+1,P(e.max,100)),i=Math.max(r,Math.min(a,P(e.value,r))),n=(i-r)/(a-r),s=d(e.tone,"primary"),l=d(e.size,"md"),c=l==="lg"?220:l==="sm"?140:180,u=c/2,p=l==="lg"?18:l==="sm"?10:14,m=u-p,g=o("div",{class:"rui-gauge","data-tone":s,"data-size":l}),f=dt(c,u+p+4),h=u,b=u,v=h-m,y=b,x=h+m,w=b;if(f.append(ie("path",{d:`M${v},${y} A${m},${m} 0 0 1 ${x},${w}`,fill:"none",stroke:"var(--rui-color-border, #e2e8f0)","stroke-width":String(p),"stroke-linecap":"round"})),n>0){const N=Math.PI*n,A=h-m*Math.cos(N),z=b-m*Math.sin(N);f.append(ie("path",{d:`M${v},${y} A${m},${m} 0 0 1 ${A.toFixed(2)},${z.toFixed(2)}`,fill:"none",stroke:`var(--rui-color-${s}, ${Ne(0)})`,"stroke-width":String(p),"stroke-linecap":"round",class:"rui-gauge-arc"}))}g.append(f);const T=qc(i,r,a),S=d(e.label)||T;g.append(o("div",{class:"rui-gauge-value"},[S]));const $=d(e.caption);return $&&g.append(o("div",{class:"rui-gauge-caption"},[$])),g}};function qc(t,e,r){return e===0&&r===100?t%1===0?`${t}%`:`${t.toFixed(1)}%`:Math.abs(t)>=1e3?Math.round(t).toLocaleString():t%1===0?String(t):t.toFixed(t<10?2:1)}const Hc={name:"Heatmap",description:"Color-intensity matrix grid (calendar-style or correlation-style). Pass `xLabels`, `yLabels`, and a `values` array of arrays (rows × columns). Each cell's color intensity scales with the value relative to the global max. Use for activity heatmaps, schedule density, correlation matrices.",props:[{name:"xLabels",type:"string[]"},{name:"yLabels",type:"string[]"},{name:"values",type:"number[][]",description:"Matrix indexed by row (y), then column (x)"},{name:"title",type:"string",optional:!0},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]}],render:(t,e)=>{const r=k(e.xLabels).map(p=>d(p)),a=k(e.yLabels).map(p=>d(p)),i=k(e.values).map(p=>k(p).map(m=>P(m,0))),n=d(e.tone,"primary"),s=Math.max(1,...i.flat()),l=o("div",{class:"rui-heatmap","data-tone":n});d(e.title)&&l.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const c=o("div",{class:"rui-heatmap-table"}),u=o("div",{class:"rui-heatmap-row rui-heatmap-row-header"});u.append(o("div",{class:"rui-heatmap-cell rui-heatmap-corner"}));for(const p of r)u.append(o("div",{class:"rui-heatmap-cell rui-heatmap-xlabel"},[p]));return c.append(u),i.forEach((p,m)=>{const g=o("div",{class:"rui-heatmap-row"});g.append(o("div",{class:"rui-heatmap-cell rui-heatmap-ylabel"},[a[m]??String(m+1)])),p.forEach((f,h)=>{const b=s>0?f/s:0,v=o("div",{class:"rui-heatmap-cell rui-heatmap-value",style:`background:color-mix(in srgb, var(--rui-color-${n}, ${Ne(0)}) ${Math.round(b*90+5)}%, transparent);`,title:`${r[h]??h+1} · ${a[m]??m+1}: ${f}`});v.append(o("span",{},[String(f)])),g.append(v)}),c.append(g)}),l.append(c),l}},Vc={name:"RadarChart",description:"Polygon chart with one axis per category. Use for skill maps, scorecards, capability comparisons, and any multi-dimensional snapshot. Each Series renders as a filled polygon — overlapping is expected for comparisons.",props:[{name:"axes",type:"string[]",description:"Category labels — one per radial axis"},{name:"series",type:"Series[]"},{name:"max",type:"number",optional:!0,description:"Outer ring value (default = max across series)"},{name:"title",type:"string",optional:!0}],render:(t,e)=>{const r=k(e.axes).map(f=>d(f)),a=Oc(k(e.series)),i=Math.max(r.length,3),n=o("div",{class:"rui-chart rui-radar-chart"});d(e.title)&&n.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const s=Math.max(1,P(e.max,a.flatMap(f=>f.values).reduce((f,h)=>Math.max(f,h),1))),l=280,c=l/2,u=l/2,p=l/2-24,m=dt(l,l),g=4;for(let f=1;f<=g;f+=1){const h=p/g*f,b=[];for(let v=0;v<i;v+=1){const y=Math.PI*2*v/i-Math.PI/2;b.push(`${(c+h*Math.cos(y)).toFixed(1)},${(u+h*Math.sin(y)).toFixed(1)}`)}m.append(ie("polygon",{points:b.join(" "),fill:"none",stroke:"var(--rui-color-border-subtle, rgba(0,0,0,0.08))","stroke-width":"1"}))}for(let f=0;f<i;f+=1){const h=Math.PI*2*f/i-Math.PI/2,b=c+p*Math.cos(h),v=u+p*Math.sin(h);m.append(ie("line",{x1:String(c),y1:String(u),x2:b.toFixed(1),y2:v.toFixed(1),stroke:"var(--rui-color-border-subtle, rgba(0,0,0,0.08))","stroke-width":"1"}));const y=c+(p+16)*Math.cos(h),x=u+(p+16)*Math.sin(h);m.append(ie("text",{x:y.toFixed(1),y:x.toFixed(1),"text-anchor":"middle","dominant-baseline":"middle",class:"rui-chart-label","font-size":"13","font-weight":"500"},[r[f]??""]))}return a.forEach((f,h)=>{const b=[];for(let v=0;v<i;v+=1){const y=f.values[v]??0,x=Math.max(0,Math.min(1,y/s)),w=Math.PI*2*v/i-Math.PI/2,T=c+p*x*Math.cos(w),S=u+p*x*Math.sin(w);b.push(`${T.toFixed(1)},${S.toFixed(1)}`)}m.append(ie("polygon",{points:b.join(" "),fill:Ne(h),"fill-opacity":"0.2",stroke:Ne(h),"stroke-width":"2","stroke-linejoin":"round"}))}),n.append(m),a.length>0&&n.append(Da(a)),n}};function Wc(t){return t.map((e,r)=>{const a=e,i=d(a.args?.[0],`Series ${r+1}`),n=k(a.args?.[1]).map(s=>{if(Array.isArray(s))return{x:P(s[0],0),y:P(s[1],0),label:d(s[2])};if(s&&typeof s=="object"){const l=s;return{x:P(l.x,0),y:P(l.y,0),label:d(l.label)}}return{x:0,y:0,label:""}});return{name:i,points:n}})}const Gc={name:"ScatterChart",description:'XY scatter plot — one dot per data point, optionally grouped by series. Pass each `Series(name, points)` with points as `{x, y, label?}` objects or `[x, y, label?]` tuples. Use for correlations, distributions, and "price vs. rating" style charts.',props:[{name:"series",type:"Series[]"},{name:"xLabel",type:"string",optional:!0},{name:"yLabel",type:"string",optional:!0},{name:"title",type:"string",optional:!0}],render:(t,e)=>{const r=Wc(k(e.series)),a=o("div",{class:"rui-chart rui-scatter-chart"});d(e.title)&&a.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const i=640,n=280,s={left:50,right:16,top:16,bottom:40},l=i-s.left-s.right,c=n-s.top-s.bottom,u=r.flatMap(T=>T.points);if(u.length===0)return a.append(o("div",{class:"rui-chart-empty"},["No points"])),a;const p=u.map(T=>T.x),m=u.map(T=>T.y),g=Math.min(...p),f=Math.max(...p),h=Math.min(...m),b=Math.max(...m),v=f-g||1,y=b-h||1,x=dt(i,n);if(Oa(x,s,l,c,b,h),x.append(ie("line",{x1:String(s.left),y1:String(s.top+c),x2:String(s.left+l),y2:String(s.top+c),stroke:"var(--rui-color-border, #e2e8f0)"})),r.forEach((T,S)=>{T.points.forEach($=>{const N=s.left+($.x-g)/v*l,A=s.top+c-($.y-h)/y*c,z=ie("circle",{cx:N.toFixed(1),cy:A.toFixed(1),r:"7",fill:Ne(S),"fill-opacity":"0.8",stroke:"#fff","stroke-width":"1.5"});z.append(ie("title",{},[$.label||`${$.x}, ${$.y}`])),x.append(z)})}),d(e.xLabel)&&x.append(ie("text",{x:String(s.left+l/2),y:String(n-6),"text-anchor":"middle",class:"rui-chart-label","font-size":"14","font-weight":"500"},[d(e.xLabel)])),d(e.yLabel)){const S=s.top+c/2;x.append(ie("text",{x:String(14),y:String(S),"text-anchor":"middle",transform:`rotate(-90, 14, ${S})`,class:"rui-chart-label","font-size":"14","font-weight":"500"},[d(e.yLabel)]))}a.append(x);const w=r.map(T=>({name:T.name,values:T.points.map(S=>S.y)}));return w.length>0&&a.append(Da(w)),a}},Kc={name:"Histogram",description:"Frequency distribution from raw numeric values. Pass `values` directly (the component bins them automatically) or pre-computed `bins` of `{label, count}` objects. Use for response-time histograms, score distributions, age buckets.",props:[{name:"values",type:"number[]",optional:!0,description:"Raw observations (binned automatically)"},{name:"bins",type:"object[]",optional:!0,description:"Pre-computed {label, count} entries (overrides `values`)"},{name:"binCount",type:"number",optional:!0,description:"Number of bins when computing from `values` (default 10)"},{name:"title",type:"string",optional:!0}],render:(t,e)=>{let r=[];if(Array.isArray(e.bins)&&e.bins.length>0)r=e.bins.map(g=>{const f=g??{};return{label:d(f.label),count:P(f.count,0)}});else{const g=k(e.values).map(f=>P(f,NaN)).filter(f=>Number.isFinite(f));if(g.length>0){const f=Math.max(2,Math.min(50,Math.floor(P(e.binCount,10)))),h=Math.min(...g),y=(Math.max(...g)-h||1)/f,x=new Array(f).fill(0);for(const w of g){let T=Math.floor((w-h)/y);T>=f&&(T=f-1),T<0&&(T=0),x[T]+=1}r=x.map((w,T)=>{const S=h+T*y,$=S+y;return{label:`${Fa(S)}–${Fa($)}`,count:w}})}}const a=o("div",{class:"rui-chart rui-histogram"});if(d(e.title)&&a.append(o("div",{class:"rui-chart-title"},[d(e.title)])),r.length===0)return a.append(o("div",{class:"rui-chart-empty"},["No data"])),a;const i=640,n=240,s={left:40,right:12,top:16,bottom:50},l=i-s.left-s.right,c=n-s.top-s.bottom,u=Math.max(1,...r.map(g=>g.count)),p=l/r.length,m=dt(i,n);return Oa(m,s,l,c,u),r.forEach((g,f)=>{const h=s.left+f*p+p*.1,b=p*.8,v=g.count/u*c,y=s.top+c-v,x=ie("rect",{x:h.toFixed(1),y:y.toFixed(1),width:b.toFixed(1),height:v.toFixed(1),fill:Ne(0),rx:"2"});x.append(ie("title",{},[`${g.label}: ${g.count}`])),m.append(x),m.append(ie("text",{x:(h+b/2).toFixed(1),y:String(s.top+c+22),"text-anchor":"middle",class:"rui-chart-label","font-size":"12"},[g.label]))}),a.append(m),a}};function Fa(t){return Number.isFinite(t)?Math.abs(t)>=1e3?Math.round(t).toLocaleString():Math.abs(t)>=10?t.toFixed(0):t.toFixed(1):"?"}function Oa(t,e,r,a,i,n=0){for(let l=0;l<=4;l+=1){const c=l/4,u=e.top+a-c*a;t.append(ie("line",{x1:String(e.left),x2:String(e.left+r),y1:String(u),y2:String(u),stroke:"var(--rui-color-border-subtle, rgba(0,0,0,0.08))"})),t.append(ie("text",{x:String(e.left-8),y:String(u+5),"text-anchor":"end",class:"rui-chart-tick","font-size":"14"},[String(Math.round((n+(i-n)*c)*10)/10)]))}}const Yc=["numeric","alphanumeric"];function Jc(t,e,r,a,i,n,s){const l=o("div",{class:"rui-pin-input","data-disabled":i?"true":"false"}),c=[];for(let m=0;m<e;m+=1){const g=o("input",{class:"rui-pin-input-slot",id:m===0?t:null,maxlength:"1",autocomplete:"one-time-code",inputmode:r==="numeric"?"numeric":"text",type:n?"password":"text","aria-label":`Digit ${m+1}`,value:a.charAt(m)||"",disabled:i?"":null});c.push(g),l.append(g)}const u=m=>{const g=m.closest(".rui-pin-input");return g?Array.from(g.querySelectorAll(".rui-pin-input-slot")):c},p=m=>u(m).map(g=>g.value).join("").slice(0,e);return c.forEach((m,g)=>{m.oninput=f=>{const h=f.currentTarget,b=u(h);let v=h.value;if(r==="numeric"?v=v.replace(/\D/g,""):v=v.replace(/[^A-Za-z0-9]/g,""),v.length>1){const y=v.split("");y.slice(0,e-g).forEach((w,T)=>{const S=b[g+T];S&&(S.value=w)});const x=Math.min(g+y.length,e-1);b[x]?.focus()}else h.value=v,v&&g<e-1&&b[g+1]?.focus();s?.(p(h))},m.onkeydown=f=>{const h=f,b=h.currentTarget,v=u(b);if(h.key==="Backspace"&&!b.value&&g>0){h.preventDefault(),v[g-1]?.focus();const y=v[g-1];y&&(y.value=""),s?.(p(b))}else h.key==="ArrowLeft"&&g>0?(h.preventDefault(),v[g-1]?.focus()):h.key==="ArrowRight"&&g<e-1&&(h.preventDefault(),v[g+1]?.focus())}}),l}const Xc={name:"PinInput",description:'Per-digit PIN entry. Auto-advances focus as the user types and supports paste. Pass a `$variable` as `value` for two-way binding (the bound value is the joined string). Use `type="numeric"` for PINs / 2FA codes, `"alphanumeric"` for invite codes.',props:[{name:"id",type:"string"},{name:"length",type:"number",optional:!0,description:"Number of slots (default 4)"},{name:"value",type:"string",optional:!0,description:"Bound value (typically $variable)"},{name:"type",type:"string",optional:!0,enum:Yc},{name:"mask",type:"boolean",optional:!0,description:"Render slots as `<input type=password>`"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=Math.max(1,Math.min(12,Math.floor(P(e.length,4)))),n=d(e.type,"numeric"),s=d(e.value),l=C(e.disabled),c=C(e.mask),u=t.argMeta?.[2]?.stateRef;return Jc(a,i,n,s,l,c,p=>{u&&r.setState(u,p)})}};function Zc(t){if(!t)return{score:0,label:""};let e=0;return t.length>=8&&(e+=1),t.length>=12&&(e+=1),/[A-Z]/.test(t)&&/[a-z]/.test(t)&&(e+=1),/[0-9]/.test(t)&&(e+=1),/[^A-Za-z0-9]/.test(t)&&(e+=1),e=Math.min(4,e),{score:e,label:["Too short","Weak","Fair","Good","Strong"][e]??""}}const Qc={name:"PasswordInput",description:"Password input with a show/hide toggle and an optional strength meter. Pass a `$variable` as `value` for two-way binding. Set `strengthMeter=true` to render a 4-step indicator and label.",props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"Bound value (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"label",type:"string",optional:!0,description:"Inline label above the field"},{name:"strengthMeter",type:"boolean",optional:!0,aliases:["showStrength"]},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=r.useInstanceState("visible",!1),n=i.get(),s=C(e.disabled),l=o("div",{class:"rui-password-input","data-disabled":s?"true":"false"}),c=d(e.label);c&&l.append(o("label",{class:"rui-password-input-label",for:a},[c]));const u=o("div",{class:"rui-password-input-row"}),p=o("input",{type:n?"text":"password",class:"rui-password-input-field",id:a,name:a,autocomplete:"current-password",placeholder:d(e.placeholder),value:d(e.value),disabled:s?"":null}),m=o("button",{type:"button",class:"rui-password-input-toggle","aria-label":n?"Hide password":"Show password"}),g=L(n?"eye-slash":"eye");g&&m.append(g),m.onclick=h=>{h.preventDefault();const b=!i.get();i.set(b);const x=h.currentTarget.closest(".rui-password-input")?.querySelector(".rui-password-input-field");x&&(x.type=b?"text":"password")};const f=t.argMeta?.[1]?.stateRef;if(f&&r.bindState(p,f,{event:"input",getValue:h=>h.value}),u.append(p),u.append(m),l.append(u),C(e.strengthMeter)){const h=Zc(d(e.value)),b=o("div",{class:"rui-password-input-strength","data-score":String(h.score)});for(let y=0;y<4;y+=1)b.append(o("span",{class:"rui-password-input-strength-bar","data-filled":y<h.score?"true":"false"}));const v=o("div",{class:"rui-password-input-strength-row"});v.append(b),h.label&&v.append(o("span",{class:"rui-password-input-strength-label"},[h.label])),l.append(v)}return l}},eu={name:"TagInput",description:"Tag/chip input — type a value, press Enter (or comma) to commit, click × on a chip to remove. Pass a `$variable` (array of strings) as `value` for two-way binding. Use for keywords, recipients, labels, skills, allowlists.",props:[{name:"id",type:"string"},{name:"value",type:"string[]",optional:!0,description:"Bound array of tag values"},{name:"placeholder",type:"string",optional:!0},{name:"label",type:"string",optional:!0,description:"Inline label above the field"},{name:"max",type:"number",optional:!0,description:"Maximum number of tags"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=k(e.value).map(g=>d(g)).filter(Boolean),n=Math.max(0,Math.floor(P(e.max,0))),s=C(e.disabled),l=t.argMeta?.[1]?.stateRef,c=g=>{l&&r.setState(l,g)},u=d(e.label),p=o("div",{class:"rui-tag-input","data-disabled":s?"true":"false"});for(const g of i){const f=o("span",{class:"rui-tag-input-chip"});f.append(o("span",{},[g]));const h=o("button",{type:"button",class:"rui-tag-input-remove","aria-label":`Remove ${g}`},["×"]);h.onclick=()=>c(i.filter(b=>b!==g)),f.append(h),p.append(f)}const m=o("input",{type:"text",class:"rui-tag-input-field",id:a,name:a,placeholder:d(e.placeholder,i.length===0?"Add tags…":""),disabled:s?"":null,autocomplete:"off"});if(m.onkeydown=g=>{const f=g,h=f.currentTarget;if(f.key==="Enter"||f.key===","){f.preventDefault();const b=h.value.trim();if(!b||n>0&&i.length>=n)return;if(i.includes(b)){h.value="";return}c([...i,b]),h.value=""}else f.key==="Backspace"&&h.value===""&&i.length>0&&(f.preventDefault(),c(i.slice(0,-1)))},p.append(m),u){const g=o("div",{class:"rui-tag-input-wrapper"});return g.append(o("label",{class:"rui-tag-input-label",for:a},[u])),g.append(p),g}return p}};function tu(t){return k(t).map(e=>{if(typeof e=="string")return{value:e,label:e};if(e&&typeof e=="object"){const r=e,a=d(r.value??r.id??r.name),i=d(r.label,a);return{value:a,label:i}}return{value:"",label:""}}).filter(e=>e.value)}const ru={name:"MentionInput",description:"Multi-line input with inline @-mention suggestions. Typing `@` opens a popover listing the provided `people` (filtered by what follows). Selecting an option inserts `@label` into the text. Pass a `$variable` as `value` for two-way binding. Use for comments, task notes, chat composers.",props:[{name:"id",type:"string"},{name:"people",type:"any[]",description:"Available mentions: strings or {value, label} objects"},{name:"value",type:"string",optional:!0,description:"Bound text (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"rows",type:"number",optional:!0,description:"TextArea rows (default 3)"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=tu(e.people),n=C(e.disabled),s=o("div",{class:"rui-mention-input","data-disabled":n?"true":"false"}),l=o("textarea",{class:"rui-mention-input-field",id:a,name:a,rows:String(Math.max(2,Math.floor(P(e.rows,3)))),placeholder:d(e.placeholder,"Type @ to mention someone"),disabled:n?"":null});l.value=d(e.value);const c=t.argMeta?.[2]?.stateRef;c&&r.bindState(l,c,{event:"input",getValue:g=>g.value});const u=o("div",{class:"rui-mention-input-suggestions","data-open":"false"}),p=g=>{u.replaceChildren();const h=i.filter(b=>b.label.toLowerCase().includes(g.toLowerCase())).slice(0,6);if(h.length===0){u.setAttribute("data-open","false");return}u.setAttribute("data-open","true");for(const b of h){const v=o("button",{type:"button",class:"rui-mention-input-option","data-value":b.value},[b.label]);v.onmousedown=y=>y.preventDefault(),v.onclick=()=>{m(b),u.setAttribute("data-open","false")},u.append(v)}},m=g=>{const f=l.value,h=l.selectionStart,b=f.slice(0,h),v=b.lastIndexOf("@");if(v===-1)return;const y=f.slice(h),x=`@${g.label} `,w=b.slice(0,v)+x+y;l.value=w;const T=v+x.length;l.selectionStart=l.selectionEnd=T,l.dispatchEvent(new Event("input",{bubbles:!0})),l.focus()};return l.oninput=()=>{const g=l.selectionStart,f=l.value.slice(0,g),h=/@([\w-]*)$/.exec(f);h?p(h[1]??""):u.setAttribute("data-open","false")},l.onblur=()=>setTimeout(()=>u.setAttribute("data-open","false"),80),s.append(l),s.append(u),s}},au={name:"TimePicker",description:'Time-of-day picker that wraps `<input type="time">`. Pass a `$variable` as `value` for two-way binding (HH:MM 24-hour). Set `step` to constrain to specific increments (e.g. 900 for 15-minute buckets).',props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"HH:MM value; typically $variable"},{name:"label",type:"string",optional:!0},{name:"min",type:"string",optional:!0},{name:"max",type:"string",optional:!0},{name:"step",type:"number",optional:!0,description:"Seconds between selectable times"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("div",{class:"rui-time-picker"}),n=d(e.label);n&&i.append(o("label",{class:"rui-time-picker-label",for:a},[n]));const s=o("input",{type:"time",class:"rui-time-picker-input",id:a,name:a,value:d(e.value),min:d(e.min)||null,max:d(e.max)||null,step:e.step!=null?String(P(e.step,60)):null,disabled:C(e.disabled)?"":null}),l=t.argMeta?.[1]?.stateRef;return l&&r.bindState(s,l),i.append(s),i}},iu={name:"DateTimePicker",description:'Combined date + time picker — wraps `<input type="datetime-local">`. Pass a `$variable` as `value` for two-way binding (ISO `YYYY-MM-DDTHH:MM`).',props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"ISO date-time value; typically $variable"},{name:"label",type:"string",optional:!0},{name:"min",type:"string",optional:!0},{name:"max",type:"string",optional:!0},{name:"step",type:"number",optional:!0,description:"Seconds between selectable times"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("div",{class:"rui-datetime-picker"}),n=d(e.label);n&&i.append(o("label",{class:"rui-datetime-picker-label",for:a},[n]));const s=o("input",{type:"datetime-local",class:"rui-datetime-picker-input",id:a,name:a,value:d(e.value),min:d(e.min)||null,max:d(e.max)||null,step:e.step!=null?String(P(e.step,60)):null,disabled:C(e.disabled)?"":null}),l=t.argMeta?.[1]?.stateRef;return l&&r.bindState(s,l),i.append(s),i}};function Ua(t,e){let r="",a=t;for(const i of e){if(!a)break;if(i==="9"){const n=/\d/.exec(a);if(!n)break;r+=n[0],a=a.slice(a.indexOf(n[0])+1)}else if(i==="A"){const n=/[a-zA-Z]/.exec(a);if(!n)break;r+=n[0],a=a.slice(a.indexOf(n[0])+1)}else i==="*"?(r+=a.charAt(0),a=a.slice(1)):(r+=i,a.startsWith(i)&&(a=a.slice(1)))}return r}const nu={name:"MaskedInput",description:'Text input with an inline mask — `9` matches a digit, `A` matches a letter, `*` matches any character, every other character is a fixed delimiter. Useful for phone numbers, postal codes, credit cards. Pass `mask` (e.g. `"(999) 999-9999"`) and a `$variable` as `value`.',props:[{name:"id",type:"string"},{name:"mask",type:"string",description:"Mask pattern"},{name:"value",type:"string",optional:!0,description:"Bound value (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"label",type:"string",optional:!0,description:"Inline label above the field"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=d(e.mask),n=C(e.disabled),s=Ua(d(e.value),i),l=d(e.label),c=o("input",{type:"text",class:"rui-masked-input",id:a,name:a,value:s,placeholder:d(e.placeholder,i),disabled:n?"":null,autocomplete:"off"}),u=t.argMeta?.[2]?.stateRef;if(c.oninput=()=>{c.value=Ua(c.value,i)},u&&r.bindState(c,u,{event:"input",getValue:p=>p.value}),l){const p=o("div",{class:"rui-masked-input-wrapper"});return p.append(o("label",{class:"rui-masked-input-label",for:a},[l])),p.append(c),p}return c}},ou={name:"FormSection",description:"Semantic grouping for related form fields — renders a small heading (`label`), optional helper paragraph, and stacks the children with consistent spacing. Use INSTEAD of wrapping fields in `Card` + `SectionHeader` by hand. Pair with `FieldSet` when the group is a true `<fieldset>` (radio sets, checkbox groups).",props:[{name:"label",type:"string",aliases:["title"]},{name:"children",type:"Node[]",aliases:["fields"]},{name:"helper",type:"string",optional:!0,aliases:["description"],description:"Description rendered below the label"}],render:(t,e,r)=>{const a=o("section",{class:"rui-form-section"}),i=o("header",{class:"rui-form-section-header"});i.append(o("h3",{class:"rui-form-section-label"},[d(e.label)]));const n=d(e.helper);n&&i.append(o("p",{class:"rui-form-section-helper"},[n])),a.append(i);const s=o("div",{class:"rui-form-section-body"});for(const l of k(e.children))s.append(r.renderNode(l));return a.append(s),a}},su={name:"FieldSet",description:"Native `<fieldset>`/`<legend>` wrapper for accessible grouping of related controls. Use when assistive tech should announce the wrapper (radio sets, checkbox groups). For purely visual grouping prefer `FormSection`.",props:[{name:"legend",type:"string",aliases:["title","label"]},{name:"children",type:"Node[]",aliases:["fields"]},{name:"helper",type:"string",optional:!0,aliases:["hint","description"]},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=o("fieldset",{class:"rui-fieldset",disabled:C(e.disabled)?"":null});a.append(o("legend",{class:"rui-fieldset-legend"},[d(e.legend)]));const i=d(e.helper);i&&a.append(o("p",{class:"rui-fieldset-helper"},[i]));for(const n of k(e.children))a.append(r.renderNode(n));return a}},lu={name:"ValidationSummary",description:"Aggregate error list rendered at the top of a form. Pass `errors` as `{label?, message, field?}` objects or plain strings. Pair with individual field hints via `FormControl(hint=...)`.",props:[{name:"errors",type:"any[]"},{name:"title",type:"string",optional:!0,description:'Heading (default "Please fix the following:")'},{name:"tone",type:"string",optional:!0,enum:["danger","warning"]}],render:(t,e)=>{const r=k(e.errors).map(c=>{if(!c)return null;if(typeof c=="string")return{label:"",message:c,field:""};if(typeof c=="object"){const u=c;return{label:d(u.label),message:d(u.message??u.error),field:d(u.field)}}return null}).filter(c=>c!==null&&c.message!=="");if(r.length===0)return o("div",{class:"rui-validation-summary","data-empty":"true",hidden:""});const a=d(e.tone,"danger"),i=o("aside",{class:"rui-validation-summary","data-tone":a,role:"alert"}),n=o("div",{class:"rui-validation-summary-title"}),s=L(a==="warning"?"triangle-exclamation":"circle-xmark",{className:"rui-validation-summary-icon"});s&&n.append(s),n.append(document.createTextNode(d(e.title,"Please fix the following:"))),i.append(n);const l=o("ul",{class:"rui-validation-summary-list"});for(const c of r){const u=o("li",{class:"rui-validation-summary-item"});c.label&&u.append(o("strong",{},[`${c.label}: `])),u.append(document.createTextNode(c.message)),l.append(u)}return i.append(l),i}};function cu(t){return k(t).map(e=>{if(!e||typeof e!="object")return{title:d(e),details:"",content:null};const r=e;return{title:d(r.title),details:d(r.details),content:r.content??null}})}const uu={name:"MultiStepForm",description:"Multi-step / wizard form composite. Renders a `Steps` indicator, the active step's `content`, and Prev/Next buttons that drive a `$variable` for the current 0-indexed step. Use INSTEAD of hand-rolling `Steps` + content + manual prev/next wiring. The submit button is rendered on the final step (override via `submitLabel`).",props:[{name:"steps",type:"object[]",description:"Array of {title, details?, content} step objects"},{name:"current",type:"number",description:"0-indexed active step — bind a $variable"},{name:"onSubmit",type:"callable",optional:!0,description:"Callable fired when the user clicks Submit on the final step"},{name:"prevLabel",type:"string",optional:!0,description:'Default "Back"'},{name:"nextLabel",type:"string",optional:!0,description:'Default "Continue"'},{name:"submitLabel",type:"string",optional:!0,description:'Default "Submit" (final step)'}],render:(t,e,r)=>{const a=cu(e.steps),i=a.length,n=Math.max(0,Math.min(i-1,Math.floor(P(e.current,0)))),s=t.argMeta?.[1]?.stateRef,l=o("div",{class:"rui-multi-step-form"}),c=o("ol",{class:"rui-steps rui-multi-step-form-steps"});a.forEach((v,y)=>{const x=o("li",{class:"rui-steps-item","data-active":y===n?"true":"false","data-complete":y<n?"true":"false"});x.append(o("div",{class:"rui-steps-title"},[v.title||`Step ${y+1}`])),v.details&&x.append(o("div",{class:"rui-steps-details"},[v.details])),c.append(x)}),l.append(c);const u=o("div",{class:"rui-multi-step-form-body"}),p=a[n];p&&p.content&&u.append(r.renderNode(p.content)),l.append(u);const m=o("div",{class:"rui-multi-step-form-footer"}),g=o("button",{type:"button",class:"rui-button","data-variant":"ghost",disabled:n<=0?"":null},[d(e.prevLabel,"Back")]);s&&n>0&&(g.onclick=()=>r.setState(s,n-1));const f=n>=i-1,h=f?d(e.submitLabel,"Submit"):d(e.nextLabel,"Continue"),b=o("button",{type:"button",class:"rui-button","data-variant":"primary"},[h]);return b.onclick=()=>{f?r.invoke(e.onSubmit):s&&r.setState(s,n+1)},m.append(g),m.append(o("span",{class:"rui-multi-step-form-progress"},[`${n+1} / ${i}`])),m.append(b),l.append(m),l}};function du(t){return k(t).map(e=>{if(!e||typeof e!="object")return null;const r=e;return{title:d(r.title),message:d(r.message),time:d(r.time),icon:d(r.icon),tone:d(r.tone,"default"),unread:C(r.unread),avatarSrc:d(r.avatarSrc),action:r.action}}).filter(e=>e!==null)}const pu={name:"InboxPanel",description:"Grouped notification list — entries are grouped into Unread/Earlier sections, with a count chip on each group header. Pass `items` as `{title, message, time, icon?, tone?, unread?, avatarSrc?, action?}` objects. Pair with a `SectionHeader` for the panel title (the component does not render its own title to avoid duplication). Use for top-bar notification trays, activity drawers, and alert center pages.",props:[{name:"items",type:"object[]"},{name:"emptyLabel",type:"string",optional:!0,description:"Text shown when there are no notifications"},{name:"onMarkAllRead",type:"callable",optional:!0,description:'Callable fired by the "Mark all as read" button'}],render:(t,e,r)=>{const a=du(e.items),i=a.filter(c=>c.unread),n=a.filter(c=>!c.unread),s=o("div",{class:"rui-inbox-panel"});if(typeof e.onMarkAllRead=="function"&&i.length>0){const c=o("div",{class:"rui-inbox-panel-toolbar"}),u=o("button",{type:"button",class:"rui-inbox-panel-mark-all"},["Mark all as read"]);u.onclick=()=>r.invoke(e.onMarkAllRead),c.append(u),s.append(c)}if(a.length===0)return s.append(o("div",{class:"rui-inbox-panel-empty"},[d(e.emptyLabel,"You're all caught up.")])),s;const l=(c,u)=>{if(u.length===0)return;const p=o("section",{class:"rui-inbox-panel-group"}),m=o("header",{class:"rui-inbox-panel-group-head"});m.append(o("span",{class:"rui-inbox-panel-group-label"},[c])),m.append(o("span",{class:"rui-inbox-panel-group-count"},[String(u.length)])),p.append(m);for(const g of u){const f=ka.render({__kind:"Component",name:"Notification",args:[],argMeta:[]},{title:g.title,message:g.message,time:g.time,icon:g.icon,tone:g.tone,avatarSrc:g.avatarSrc,unread:g.unread},r);typeof g.action=="function"&&(f.setAttribute("data-clickable","true"),f.onclick=()=>r.invoke(g.action)),p.append(f)}s.append(p)};return l(`Unread (${i.length})`,i),l("Earlier",n),s}};function mu(t){return k(t).map(e=>{if(!e||typeof e!="object")return null;const r=e;return{title:d(r.title),description:d(r.description),done:C(r.done),action:r.action,cta:d(r.cta,"Start")}}).filter(e=>e!==null)}const gu={name:"OnboardingChecklist",description:'Step-by-step product checklist with completion progress at the top. Pass `items` as `{title, description?, done?, action?, cta?}` objects. The progress percentage is computed automatically from `done`. Use on first-run dashboards, empty workspaces, and "complete your profile" surfaces.',props:[{name:"items",type:"object[]"},{name:"title",type:"string",optional:!0,description:'Heading (default "Getting started")'},{name:"subtitle",type:"string",optional:!0}],render:(t,e,r)=>{const a=mu(e.items),i=a.filter(m=>m.done).length,n=Math.max(1,a.length),s=Math.round(i/n*100),l=o("div",{class:"rui-onboarding-checklist"}),c=o("header",{class:"rui-onboarding-checklist-header"});c.append(o("h3",{class:"rui-onboarding-checklist-title"},[d(e.title,"Getting started")]));const u=d(e.subtitle);u&&c.append(o("p",{class:"rui-onboarding-checklist-subtitle"},[u])),c.append(o("div",{class:"rui-onboarding-checklist-progress"},[o("div",{class:"rui-onboarding-checklist-bar"},[o("div",{class:"rui-onboarding-checklist-fill",style:`width:${s}%`})]),o("span",{class:"rui-onboarding-checklist-meta"},[`${i}/${a.length} complete`])])),l.append(c);const p=o("ol",{class:"rui-onboarding-checklist-list"});for(const m of a){const g=o("li",{class:"rui-onboarding-checklist-item","data-done":m.done?"true":"false"}),f=o("span",{class:"rui-onboarding-checklist-marker"}),h=L(m.done?"circle-check":"circle",{className:"rui-onboarding-checklist-marker-icon"});h&&f.append(h),g.append(f);const b=o("div",{class:"rui-onboarding-checklist-body"});if(b.append(o("div",{class:"rui-onboarding-checklist-item-title"},[m.title])),m.description&&b.append(o("p",{class:"rui-onboarding-checklist-item-description"},[m.description])),g.append(b),!m.done&&typeof m.action=="function"){const v=o("button",{type:"button",class:"rui-button","data-variant":"secondary","data-size":"sm"},[m.cta]);v.onclick=()=>r.invoke(m.action),g.append(v)}p.append(g)}return l.append(p),l}};function qa(t){const e=o("div",{class:`rui-${t.klass}`});if(t.iconName){const a=L(t.iconName,{className:t.iconClass});a&&e.append(a)}t.title&&e.append(o("h3",{class:`rui-${t.klass}-title`},[t.title])),t.description&&e.append(o("p",{class:`rui-${t.klass}-description`},[t.description]));const r=k(t.actions);if(r.length>0){const a=o("div",{class:`rui-${t.klass}-actions`});for(const i of r)a.append(t.helpers.renderNode(i));e.append(a)}return e}const fu={name:"LoadingState",description:"Full-card loading state — large spinner + title + description. Use while a query is in flight or while a long-running tool runs. For tiny inline loaders prefer `Spinner`; for skeleton placeholders prefer `Skeleton`.",props:[{name:"title",type:"string",optional:!0,description:'Default "Loading…"'},{name:"description",type:"string",optional:!0}],render:(t,e)=>{const r=o("div",{class:"rui-loading-state"}),a=o("span",{class:"rui-spinner","data-size":"lg","data-tone":"primary"});a.append(o("span",{class:"rui-spinner-ring","aria-hidden":"true"})),r.append(a),r.append(o("h3",{class:"rui-loading-state-title"},[d(e.title,"Loading…")]));const i=d(e.description);return i&&r.append(o("p",{class:"rui-loading-state-description"},[i])),r}},hu={name:"ErrorState",description:"Full-card error placeholder. Pairs a danger icon with title, description, and a row of recovery actions (Retry / Contact support / Go home). Pass `actions` as Button(...) entries.",props:[{name:"title",type:"string",optional:!0,description:'Default "Something went wrong"'},{name:"description",type:"string",optional:!0},{name:"actions",type:"Node[]",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon (default `circle-exclamation`)"}],render:(t,e,r)=>qa({klass:"error-state",iconName:d(e.icon,"circle-exclamation"),iconClass:"rui-error-state-icon",title:d(e.title,"Something went wrong"),description:d(e.description),actions:e.actions,helpers:r})},bu={name:"SuccessState",description:'Full-card success placeholder. Use for confirmation screens ("Order placed", "Payment succeeded", "Account verified") at the end of a flow. Pass `actions` for follow-up CTAs.',props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0},{name:"actions",type:"Node[]",optional:!0},{name:"icon",type:"string",optional:!0,description:"Default `circle-check`"}],render:(t,e,r)=>qa({klass:"success-state",iconName:d(e.icon,"circle-check"),iconClass:"rui-success-state-icon",title:d(e.title),description:d(e.description),actions:e.actions,helpers:r})},vu={name:"Tour",description:"Product-tour controller — renders the current step's title, description, and a Prev/Next/Skip row. Bind `current` to a `$variable` (0-indexed). Pass `steps` as `{title, description, target?}` objects; the optional `target` is a CSS selector that renders alongside the step for designers to reference.",props:[{name:"steps",type:"object[]"},{name:"current",type:"number",description:"0-indexed active step — bind a $variable"},{name:"open",type:"boolean",optional:!0,description:"Whether the tour is visible"},{name:"onComplete",type:"callable",optional:!0}],render:(t,e,r)=>{const a=k(e.steps).map(v=>{if(!v||typeof v!="object")return{title:d(v),description:"",target:""};const y=v;return{title:d(y.title),description:d(y.description),target:d(y.target)}}),i=e.open===void 0?!0:C(e.open),n=a.length,s=Math.max(0,Math.min(n-1,Math.floor(P(e.current,0)))),l=t.argMeta?.[1]?.stateRef,c=o("div",{class:"rui-tour","data-open":i?"true":"false"});if(!i||n===0)return c;const u=a[s];if(!u)return c;const p=o("div",{class:"rui-tour-card",role:"dialog","aria-modal":"false"});p.append(o("div",{class:"rui-tour-step"},[`Step ${s+1} of ${n}`])),p.append(o("h3",{class:"rui-tour-title"},[u.title])),u.description&&p.append(o("p",{class:"rui-tour-description"},[u.description])),u.target&&p.append(o("div",{class:"rui-tour-target"},[`Target: ${u.target}`]));const m=o("div",{class:"rui-tour-footer"}),g=o("button",{type:"button",class:"rui-button","data-variant":"ghost"},["Skip"]);g.onclick=()=>r.invoke(e.onComplete);const f=o("button",{type:"button",class:"rui-button","data-variant":"secondary",disabled:s<=0?"":null},["Back"]);l&&s>0&&(f.onclick=()=>r.setState(l,s-1));const h=s>=n-1,b=o("button",{type:"button",class:"rui-button","data-variant":"primary"},[h?"Finish":"Next"]);return b.onclick=()=>{h?r.invoke(e.onComplete):l&&r.setState(l,s+1)},m.append(g,f,b),p.append(m),c.append(p),c}},yu={name:"Spotlight",description:'Single-step product highlight — a dimmed full-page overlay with a ring around the focused area and a small explainer card. Use for one-off feature reveals ("Try the new commands menu"). Bind `open` to a `$variable` to dismiss.',props:[{name:"title",type:"string"},{name:"open",type:"boolean",optional:!0,description:"Whether the spotlight is visible — typically a $variable (default true)"},{name:"description",type:"string",optional:!0},{name:"actions",type:"Node[]",optional:!0,aliases:["action"]}],render:(t,e,r)=>{const a=e.open===void 0?!0:C(e.open),i=o("div",{class:"rui-spotlight","data-open":a?"true":"false"});if(!a)return i;const n=o("div",{class:"rui-spotlight-card"});n.append(o("h3",{class:"rui-spotlight-title"},[d(e.title)]));const s=d(e.description);s&&n.append(o("p",{class:"rui-spotlight-description"},[s]));const l=k(e.actions);if(l.length>0){const u=o("div",{class:"rui-spotlight-actions"});for(const p of l)u.append(r.renderNode(p));n.append(u)}const c=t.argMeta?.[1]?.stateRef;return c&&(i.onclick=u=>{u.target===i&&r.setState(c,!1)}),i.append(n),i}},xu={name:"Sticky",description:"Wraps content in a `position: sticky` container so it pins to the top (or bottom) of the nearest scrollable ancestor. Use for toolbar action rows above tables, in-page navs, status banners.",props:[{name:"children",type:"Node[]"},{name:"side",type:"string",optional:!0,enum:["top","bottom"]},{name:"offset",type:"string",optional:!0,description:"CSS offset (default 0)"},{name:"zIndex",type:"number",optional:!0,description:"Z-index (default 10)"}],render:(t,e,r)=>{const a=d(e.side,"top"),i=ee(e.offset,"0"),n=Math.max(0,Math.floor(P(e.zIndex,10))),s=`position:sticky;${a}:${i};z-index:${n};`,l=o("div",{class:"rui-sticky",style:s});for(const c of k(e.children))l.append(r.renderNode(c));return l}},wu={name:"ResizablePanels",description:"Two-pane horizontal split with a draggable divider. The user can drag the divider to resize the primary pane; defaults respect the starting width. Use for code editors, file browsers, master/detail layouts that need user-controllable proportions.",props:[{name:"primary",type:"Node[]"},{name:"secondary",type:"Node[]"},{name:"initialPrimaryWidth",type:"string",optional:!0,description:"CSS width for the primary pane (default 40%)"},{name:"minPrimaryWidth",type:"string",optional:!0,description:"Min width (default 240px)"}],render:(t,e,r)=>{const a=ee(e.initialPrimaryWidth,"40%"),i=ee(e.minPrimaryWidth,"240px"),n=o("div",{class:"rui-resizable-panels",style:`--rui-resizable-primary:${a};--rui-resizable-min:${i};`}),s=o("div",{class:"rui-resizable-panel rui-resizable-panel-primary"});for(const u of k(e.primary))s.append(r.renderNode(u));const l=o("div",{class:"rui-resizable-divider",role:"separator","aria-orientation":"vertical",tabindex:"0"}),c=o("div",{class:"rui-resizable-panel rui-resizable-panel-secondary"});for(const u of k(e.secondary))c.append(r.renderNode(u));return n.append(s,l,c),l.onpointerdown=u=>{const p=u,m=p.currentTarget;m.setPointerCapture(p.pointerId);const g=m.closest(".rui-resizable-panels");if(!g)return;const f=g.getBoundingClientRect(),h=v=>{const y=(v.clientX-f.left)/f.width*100,x=Math.max(15,Math.min(85,y));g.style.setProperty("--rui-resizable-primary",`${x}%`)},b=v=>{m.releasePointerCapture(v.pointerId),m.removeEventListener("pointermove",h),m.removeEventListener("pointerup",b)};m.addEventListener("pointermove",h),m.addEventListener("pointerup",b)},n}},ku={name:"MasonryGrid",description:"Pinterest-style column grid. Children flow into columns that reflow on viewport changes. Use for galleries, social-style feeds, and mixed-height card walls. Prefer `Grid` when children should share the same height per row.",props:[{name:"items",type:"Node[]"},{name:"columns",type:"number",optional:!0,description:"Preferred column count (default 3)"},{name:"gap",type:"string",optional:!0,enum:["xs","s","m","l","xl"]}],render:(t,e,r)=>{const a=Math.max(1,Math.min(6,Math.floor(P(e.columns,3)))),i=d(e.gap,"m"),n=o("div",{class:"rui-masonry-grid","data-columns":String(a),"data-gap":i});for(const s of k(e.items))n.append(r.renderNode(s));return n}},Su={name:"Drawer",description:"Side drawer overlay shown when `open` is true. Pass a `$variable` as `open` to control it. Choose `side` for slide direction (default right).",props:[{name:"title",type:"string"},{name:"open",type:"boolean",description:"Open/closed state — usually a $variable"},{name:"children",type:"Node[]"},{name:"side",type:"string",optional:!0,enum:["right","left","top","bottom"]},{name:"footer",type:"Node[]",optional:!0,description:"Optional footer actions row"}],render:(t,e,r)=>{const a=C(e.open),i=d(e.side,"right"),n=o("div",{class:"rui-sheet-overlay","data-open":a?"true":"false","data-side":i}),s=o("aside",{class:"rui-sheet",role:"dialog","aria-modal":"true","data-side":i}),l=o("header",{class:"rui-sheet-header"});l.append(o("h3",{class:"rui-sheet-title"},[d(e.title)]));const c=o("button",{type:"button",class:"rui-sheet-close","aria-label":"Close"},["×"]),u=t.argMeta?.[1]?.stateRef;u&&(c.onclick=()=>r.setState(u,!1),n.onclick=g=>{g.target===n&&r.setState(u,!1)}),l.append(c),s.append(l);const p=o("div",{class:"rui-sheet-body"});for(const g of k(e.children))p.append(r.renderNode(g));s.append(p);const m=k(e.footer);if(m.length>0){const g=o("footer",{class:"rui-sheet-footer"});for(const f of m)g.append(r.renderNode(f));s.append(g)}return n.append(s),n}},Cu={name:"TopBar",description:'Compact header strip that pairs a title (or breadcrumb) with search and action slots. Use INSTEAD of hand-rolling a `Stack(direction="row")` above a page. For full SaaS shells use `Navbar` (links) or `AppShell` (sidebar + topbar + content).',props:[{name:"title",type:"string",optional:!0},{name:"subtitle",type:"string",optional:!0},{name:"left",type:"Node[]",optional:!0,aliases:["badges"],description:"Leading slot (breadcrumbs, brand, status, badges)"},{name:"center",type:"Node[]",optional:!0,aliases:["search"],description:"Centered slot (search bar, segmented control)"},{name:"right",type:"Node[]",optional:!0,aliases:["actions"],description:"Trailing slot (actions, avatar)"},{name:"sticky",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=o("header",{class:"rui-topbar","data-sticky":C(e.sticky)?"true":"false"}),i=o("div",{class:"rui-topbar-side rui-topbar-left"}),n=d(e.title);if(n){const c=o("div",{class:"rui-topbar-title-block"});c.append(o("h2",{class:"rui-topbar-title"},[n]));const u=d(e.subtitle);u&&c.append(o("p",{class:"rui-topbar-subtitle"},[u])),i.append(c)}for(const c of k(e.left))i.append(r.renderNode(c));a.append(i);const s=k(e.center);if(s.length>0){const c=o("div",{class:"rui-topbar-side rui-topbar-center"});for(const u of s)c.append(r.renderNode(u));a.append(c)}const l=o("div",{class:"rui-topbar-side rui-topbar-right"});for(const c of k(e.right))l.append(r.renderNode(c));return a.append(l),a}},Tu={name:"Theme",description:"Apply a partial theme on top of the base theme. Pass an object of token → value pairs (colors, fonts, radii, spacing, button styling). Assigning the result to a top-level binding (conventionally `theme`) lets the runtime detect it and write the tokens to the host as CSS custom properties — the rest of the rendered UI picks them up instantly.",props:[{name:"tokens",type:"any",description:"Object literal of theme tokens. Keys must match `ThemeTokens` (e.g. colorPrimary, colorBg, fontFamily, fontFamilyHeading, fontSizeBase, radiusMd, radiusButton, borderWidth, shadowMd, buttonFontWeight, …). Unknown keys are ignored."}],render:()=>document.createDocumentFragment()},Nu={name:"NavLink",description:'Anchor that navigates to a route on click and stays in sync with the URL hash. Reflects `data-active="true"` when the current path matches `to` (set `exact=true` to require exact equality instead of prefix matching).',props:[{name:"label",type:"string",description:"Visible link text."},{name:"to",type:"string",description:'Target route path, e.g. "/about".'},{name:"variant",type:"string",optional:!0,enum:["default","primary","ghost","pill"],description:"Visual variant."},{name:"exact",type:"boolean",optional:!0,description:"Match the current path exactly (default: prefix match)."},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name shown before the label."}],render:(t,e,r)=>{const a=d(e.label,""),i=d(e.to,"/"),n=d(e.variant,"default"),s=C(e.exact,!1),l=r.router,c=l.getPath(),u=c?s?c===i:i==="/"?c==="/":c===i?!0:c.startsWith(i+"/"):!1,p=o("a",{class:"rui-nav-link","data-variant":n,"data-active":u?"true":"false",href:"#"+(i.startsWith("/")?i:"/"+i)}),m=L(e.icon,{className:"rui-nav-link-icon"});return m&&p.append(m),p.append(o("span",{class:"rui-nav-link-label"},[a])),p.onclick=g=>{g.defaultPrevented||g.button===0&&(g.metaKey||g.ctrlKey||g.shiftKey||g.altKey||(g.preventDefault(),l.navigate(i)))},p}},$u=["primary","secondary","ghost","danger"],Au=["xs","sm","md","lg","xl","small","normal","large"];function Mu(t){const e=d(t).trim().toLowerCase();return e==="xs"||e==="extra-small"?"xs":e==="small"||e==="sm"?"sm":e==="large"||e==="lg"?"lg":e==="xl"||e==="extra-large"?"xl":e==="normal"||e==="md"||e===""?"md":e==="xs"||e==="sm"||e==="md"||e==="lg"||e==="xl"?e:"md"}function Pu(t){return k(t).map(e=>{if(e&&typeof e=="object"){const a=e,i=d(a.value??a.label);return{value:i,label:d(a.label,i)}}const r=d(e);return{value:r,label:r}}).filter(e=>e.label!=="")}function pt(t){return k(t).filter(e=>!!e&&typeof e=="object"&&!Array.isArray(e))}function Iu(t){return k(t).map(e=>{if(e&&typeof e=="object"){const a=e,i=d(a.value??a.label);return{value:i,label:d(a.label,i),group:d(a.group)||void 0,shortcut:d(a.shortcut)||void 0,action:a.action}}const r=d(e);return{value:r,label:r}}).filter(e=>e.label!=="")}function Ha(t){return k(t).map(e=>{if(e&&typeof e=="object"){const a=e,i=d(a.name??a.label);return{name:i,label:d(a.label,i),type:d(a.type,"text")||"text"}}const r=d(e);return{name:r,label:r,type:"text"}}).filter(e=>e.name!=="")}function zu(t){return pt(t).map((e,r)=>({id:d(e.id,`task-${r}`),label:d(e.label??e.name,`Task ${r+1}`),start:d(e.start),end:d(e.end),progress:e.progress!=null?P(e.progress,0):void 0}))}function $e(t){const e=Date.parse(t);return Number.isNaN(e)?Date.now():e}function Ru(t,e){const r=t.split(`
18
+ `)}function oe(t){switch(t.kind){case"Literal":return typeof t.value=="string"?`"${t.value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:String(t.value);case"Identifier":return t.name;case"StateRef":return`$${t.name}`;case"Call":return`${t.callee}(${t.arguments.map(oe).join(", ")})`;case"MethodCall":return`${oe(t.object)}${t.optional?"?.":"."}${t.method}(${t.arguments.map(oe).join(", ")})`;case"NamedArg":return`${t.name}: ${oe(t.value)}`;case"Array":return`[${t.elements.map(oe).join(", ")}]`;case"Object":return`{ ${t.properties.map(e=>e.spread?`...${oe(e.value)}`:`${e.key}: ${oe(e.value)}`).join(", ")} }`;case"Member":{const e=oe(t.object);return t.property?`${e}${t.optional?"?.":"."}${t.property}`:t.computed?`${e}${t.optional?"?.":""}[${oe(t.computed)}]`:e}case"Binary":return`${oe(t.left)} ${t.operator} ${oe(t.right)}`;case"Template":{const e=[];for(let r=0;r<t.quasis.length;r+=1)e.push(t.quasis[r]??""),r<t.expressions.length&&(e.push("${"),e.push(oe(t.expressions[r])),e.push("}"));return`\`${e.join("")}\``}default:return"/* unprintable */"}}function yr(t){return t.length>40?`${t.slice(0,37)}...`:t}const xr=new WeakMap;function Ji(t){let e=xr.get(t.components);if(!e){e=new Map;for(const r of t.components)r?.name&&e.set(r.name,r);xr.set(t.components,e)}return e}function wr(t,e){const r=new Map;for(const a of t.components)r.set(a.name,a);for(const a of e.components)r.set(a.name,a);return{root:e.root??t.root,components:[...r.values()],componentGroups:t.componentGroups}}function Ie(t,e){return Ji(t).get(e)}function Tt(t){const e=t.props.findIndex(r=>r.positional===!0);return e>=0?e:t.props.length>0?0:-1}function $t(t){const e=Tt(t);return e>=0?t.props[e]:void 0}function kr(t){for(const e of t){const r=e.props.filter(a=>a.positional===!0);if(r.length>1){const a=r.map(i=>i.name).join(", ");throw new SyntaxError(`Component "${e.name}" declares ${r.length} positional props (${a}). Aktion 0.5 §19.1 allows at most one.`)}}}function Sr(t,e){const r={};return t.props.forEach((a,i)=>{i<e.length&&(r[a.name]=e[i])}),r}function Xi(t,e){const r=fe(t),a=Nt(r,e);return a.length>0&&(r.errors=[...r.errors,...a]),r}function Nt(t,e){const r=[];for(const a of t.statements)Oe(a,e,r);return r}function Oe(t,e,r){switch(t.kind){case"Assignment":G(t.expression,e,r);return;case"ExpressionStatement":G(t.expression,e,r);return;case"ComponentDeclaration":case"ActionDeclaration":case"EffectDeclaration":for(const a of t.body.body)Oe(a,e,r);return;case"Return":t.argument&&G(t.argument,e,r);return;default:return}}function G(t,e,r){if(t)switch(t.kind){case"Call":{Qi(t,e,r);for(const a of t.arguments)G(a,e,r);return}case"MethodCall":{G(t.object,e,r);for(const a of t.arguments)G(a,e,r);return}case"BuiltinCall":{nn(t,r);for(const a of t.arguments)G(a,e,r);return}case"Array":for(const a of t.elements)G(a,e,r);return;case"Object":for(const a of t.properties)G(a.value,e,r);return;case"Template":for(const a of t.expressions)G(a,e,r);return;case"Binary":G(t.left,e,r),G(t.right,e,r);return;case"Unary":G(t.argument,e,r);return;case"Ternary":G(t.test,e,r),G(t.consequent,e,r),G(t.alternate,e,r);return;case"Member":G(t.object,e,r),t.computed&&G(t.computed,e,r);return;case"Spread":G(t.argument,e,r);return;case"NamedArg":G(t.value,e,r);return;case"If":G(t.test,e,r);for(const a of t.consequent.body)Oe(a,e,r);if(t.alternate)if(t.alternate.kind==="If")G(t.alternate,e,r);else for(const a of t.alternate.body)Oe(a,e,r);return;case"Match":G(t.discriminant,e,r);for(const a of t.arms)G(a.body,e,r);return;case"For":G(t.iterable,e,r);for(const a of t.body.body)Oe(a,e,r);return;case"Lambda":t.body.kind!=="JsBlock"&&G(t.body,e,r);return;case"Bind":G(t.target,e,r);return;default:return}}const Zi={Script:'Script("id", body, deps?) is not supported. Use an `effect [$deps] { js{ … } }` block (see §9 — effect declarations).',Action:'Action([@Set, @Run, …]) payloads are removed in 0.5. Use `action <Name>() { … }` declarations and reference them by name (e.g. `Button("Save", action: save)`) — see §10.',Routes:'Routes(items, default?) is removed in 0.5. Use `pages = _router_({ "/": Home(), default: NotFound() })` (see §12 — outlet-first router).',Route:'Route(path, content) is only valid inside a v1 `Routes(...)` outlet, which has been removed. Use `"/path": content` arms inside a `_router_({ … })` call (see §12).',Query:'Query("name", args, placeholder, refreshSec?) is removed in 0.5. Declare a top-level `query <Name>(args) { url, method, … }` block and bind it with `$query foo = <Name>(args)` (see §11.2).',Mutation:'Mutation("name", args) is removed in 0.5. Declare a top-level `mutation <Name>(args) { url, method, body, … }` block and bind it with `$mutation save = <Name>` (see §11.3).',NavLinkRoute:'NavLinkRoute is removed in 0.5. Use `NavLink(label, to: "/path")` (see §12 — Outlet-first router).',useInstanceState:"useInstanceState(...) is removed in 0.5. Declare per-instance state inside the component body with `$state name = init` — identity is content-addressed (§13)."};function Qi(t,e,r){const a=Zi[t.callee];if(a){r.push({message:`${t.callee}(...) — ${a}`,line:t.loc?.line??0,column:t.loc?.column??0});return}if(t.callee==="Theme"){rn(t,r);return}const i=Ie(e,t.callee);if(!i)return;const n=new Set;for(const l of i.props)if(n.add(l.name),l.aliases)for(const c of l.aliases)n.add(c);n.add("key");const s=[];for(const l of t.arguments)l.kind!=="NamedArg"&&s.push(l);if(s.length>1){const c=$t(i)?.name??"(none)",u=new Set(t.arguments.filter(g=>g.kind==="NamedArg").map(g=>g.name)),p=i.props.filter(g=>g.name!==c&&!u.has(g.name)).slice(0,s.length-1).map(g=>g.name),m=p.length>0?p.map(g=>`${g}: …`).join(", "):"use named arguments";r.push({message:`${t.callee}(...) — Aktion 0.5 §19.1 allows at most one positional argument (the "${c}" prop). The extra ${s.length-1} positional argument(s) must be passed as named arguments: ${m}. Multi-positional calls are removed.`,line:t.loc?.line??0,column:t.loc?.column??0})}for(const l of t.arguments){if(l.kind!=="NamedArg")continue;if(!n.has(l.name)){r.push({message:`Unknown prop "${l.name}" on <${t.callee}>. Known props: ${i.props.map(u=>u.name).join(", ")}.`,line:l.loc?.line??t.loc?.line??0,column:l.loc?.column??t.loc?.column??0});continue}const c=i.props.find(u=>u.name===l.name||(u.aliases?.includes(l.name)??!1));if(c?.enum&&l.value.kind==="Literal"&&typeof l.value.value=="string"){const u=l.value.value;c.enum.includes(u)||r.push({message:`<${t.callee}> ${l.name}="${u}" — must be one of ${c.enum.map(p=>`"${p}"`).join(", ")}.`,line:l.loc?.line??t.loc?.line??0,column:l.loc?.column??t.loc?.column??0})}}}const en=new Set(["colors","radius","font","motion","elevation"]),tn=new Set(["name","direction"]);function rn(t,e){const r=t.arguments[0];if(!(!r||r.kind!=="Object"))for(const a of r.properties){if(a.spread||en.has(a.key)||tn.has(a.key))continue;const i=on(a.key),n=a.key.startsWith("--")?`Theme({"${a.key}": ...}) — free-form CSS variable keys are removed in Aktion 0.5. Use the structured form: Theme({ colors: {...}, radius: {...}, font: {...} }).`:`Theme({${a.key}: ...}) — legacy flat-shape token is removed in Aktion 0.5. Use ${i}.`;e.push({message:n,line:t.loc?.line??0,column:t.loc?.column??0})}}const an={Set:"@Set($x, value) is removed in 0.5. Inside an `action Name() { … }` body, assign directly: `$x = value`.",Reset:"@Reset($x) is removed in 0.5. Inside an `action Name() { … }` body, assign the default explicitly: `$x = defaultValue`.",Run:"@Run(name) is removed in 0.5. Inside an `action Name() { … }` body, call the mutation: `await $mutation.foo.call(args)` (see §11.3).",ToAssistant:'@ToAssistant("text") is removed in 0.5. Use `emit "assistant-message" { message: "..." }` inside an `action Name() { … }` body (see §22.2).',OpenUrl:'@OpenUrl("https://…") is removed in 0.5. Inside an `action Name() { js{ … } }` body, call `window.open(url, "_blank", "noopener,noreferrer")`.',Navigate:'@Navigate("/path") is removed in 0.5. Use `pages = _router_({ … })` (see §12) and navigate via the host (`el.navigate("/path")`), `_route_.navigate("/path")` from inside an action, or by linking to the path with `NavLink(label, "/path")`.',Js:"@Js(body, args?) is removed in 0.5. Use `effect <id> on $deps { js{ … } }` or `action Name() { js{ … } }` (see §9, §10).",Const:"@Const(expr) is removed in 0.5. Use `$computed name = expr` (see §4 — state tiers).",Memo:"@Memo(expr) is removed in 0.5. Use `$computed name = expr` (see §4 — state tiers).",Push:"@Push(arr, value) is removed in 0.5. Use spread: `[...arr, value]`.",Concat:"@Concat(a, b) is removed in 0.5. Use spread: `[...a, ...b]`.",Map:'@Map(arr, "field") is removed in 0.5. Use array pluck shorthand: `arr.field` (yields `[arr[0].field, arr[1].field, …]`).',Take:"@Take(arr, n) is removed in 0.5. Use @Slice(arr, 0, n) or array shortcuts like `arr.first` / `arr.last`.",FormatCurrency:'@FormatCurrency(value, opts?) is removed in 0.5. Use `@Format(value, "currency", opts?)`.',FormatNumber:'@FormatNumber(value, opts?) is removed in 0.5. Use `@Format(value, "number", opts?)`.',Each:'@Each(items, "x", template) is removed in 0.5. Use the expression-form loop: `for x in items { template }` (see §8.3).',If:"@If(cond, then, else?) is removed in 0.5. Use the expression-form conditional: `if cond { then } else { else }` (see §8.1).",Switch:'@Switch(value, cases, default?) is removed in 0.5. Use the expression-form match: `match value { "a" -> A() _ -> Default() }` (see §8.2).'};function nn(t,e){const r=an[t.name];r&&e.push({message:`@${t.name}(...) — ${r}`,line:t.loc?.line??0,column:t.loc?.column??0})}function on(t){const e=[{prefix:"color",group:"colors"},{prefix:"radius",group:"radius"},{prefix:"font",group:"font"},{prefix:"motion",group:"motion"},{prefix:"elevation",group:"elevation"}];for(const{prefix:r,group:a}of e)if(t!==r&&t.startsWith(r)&&t.length>r.length){const i=t.slice(r.length),n=i.charAt(0).toLowerCase()+i.slice(1);return`Theme({ ${a}: { ${n}: ... } })`}return"Theme({ colors: {...}, radius: {...}, font: {...}, motion: {...}, elevation: {...} })"}const F=t=>typeof t=="number"?t:typeof t=="string"&&t.trim()!==""&&!Number.isNaN(Number(t))?Number(t):0,ae=t=>Array.isArray(t)?t:[],Cr=(t,e,r)=>{switch(t){case"==":return e===r;case"!=":return e!==r;case">":return F(e)>F(r);case"<":return F(e)<F(r);case">=":return F(e)>=F(r);case"<=":return F(e)<=F(r);case"contains":{const a=String(e??"").toLowerCase(),i=String(r??"").toLowerCase();return a.includes(i)}default:return!1}},ze=(t,e)=>{if(e==="")return t;if(t&&typeof t=="object"){if(e.includes(".")){const r=e.split(".");let a=t;for(const i of r)if(a&&typeof a=="object")a=a[i];else return;return a}return t[e]}},Tr=t=>{const e=ae(t[0]),r=String(t[1]??""),a=String(t[2]??"=="),i=t[3];return e.filter(n=>Cr(a,ze(n,r),i))},sn=t=>!!t&&typeof t=="object"&&!Array.isArray(t),xe=t=>{if(t instanceof Date)return t;if(typeof t=="number")return new Date(t);if(typeof t=="string"&&t.trim()!==""){if(!Number.isNaN(Number(t))&&/^-?\d+$/.test(t.trim()))return new Date(Number(t));const e=new Date(t);if(!Number.isNaN(e.getTime()))return e}return new Date},ln=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],cn=["January","February","March","April","May","June","July","August","September","October","November","December"],un=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dn=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],pn=(t,e)=>{const r=(l,c=2)=>String(l).padStart(c,"0"),a=t.getHours(),i=(a+11)%12+1,n=[[/YYYY/g,String(t.getFullYear())],[/YY/g,String(t.getFullYear()).slice(-2)],[/MMMM/g,cn[t.getMonth()]],[/MMM/g,ln[t.getMonth()]],[/MM/g,r(t.getMonth()+1)],[/dddd/g,dn[t.getDay()]],[/ddd/g,un[t.getDay()]],[/DD/g,r(t.getDate())],[/HH/g,r(a)],[/hh/g,r(i)],[/mm/g,r(t.getMinutes())],[/ss/g,r(t.getSeconds())],[/\bM\b/g,String(t.getMonth()+1)],[/\bD\b/g,String(t.getDate())],[/\bH\b/g,String(a)],[/\bh\b/g,String(i)],[/\bm\b/g,String(t.getMinutes())],[/\bs\b/g,String(t.getSeconds())],[/A/g,a>=12?"PM":"AM"],[/a/g,a>=12?"pm":"am"]];let s=e;for(const[l,c]of n)s=s.replace(l,c);return s},mn=(t,e=Date.now())=>{const r=e-t.getTime(),a=Math.abs(r),i=r<0,n=6e4,s=60*n,l=24*s,c=7*l,u=30*l,p=365*l;let m,g;return a<n?i?"in a moment":"just now":(a<s?(m=Math.round(a/n),g="m"):a<l?(m=Math.round(a/s),g="h"):a<c?(m=Math.round(a/l),g="d"):a<u?(m=Math.round(a/c),g="w"):a<p?(m=Math.round(a/u),g="mo"):(m=Math.round(a/p),g="y"),i?`in ${m}${g}`:`${m}${g} ago`)},$r=(t,e)=>{const a=String(t??"").replace(/([a-z0-9])([A-Z])/g,"$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map(n=>n.toLowerCase());if(a.length===0)return"";if(e==="snake")return a.join("_");if(e==="kebab")return a.join("-");const i=n=>n.charAt(0).toUpperCase()+n.slice(1);return e==="pascal"?a.map(i).join(""):a[0]+a.slice(1).map(i).join("")},At={Count:t=>ae(t[0]).length,Sum:t=>ae(t[0]).reduce((e,r)=>e+F(r),0),Avg:t=>{const e=ae(t[0]);return e.length===0?0:e.reduce((r,a)=>r+F(a),0)/e.length},Min:t=>{const e=ae(t[0]).map(F);return e.length===0?0:Math.min(...e)},Max:t=>{const e=ae(t[0]).map(F);return e.length===0?0:Math.max(...e)},First:t=>ae(t[0])[0]??null,Last:t=>{const e=ae(t[0]);return e.length===0?null:e[e.length-1]},Filter:Tr,FilterBy:Tr,Sort:t=>{const e=[...ae(t[0])],r=String(t[1]??""),a=String(t[2]??"asc").toLowerCase()==="desc"?-1:1;return e.sort((i,n)=>{const s=ze(i,r),l=ze(n,r);return typeof s=="number"&&typeof l=="number"?(s-l)*a:String(s??"").localeCompare(String(l??""))*a}),e},Round:t=>{const e=F(t[0]),r=t[1]===void 0?0:F(t[1]),a=Math.pow(10,r);return Math.round(e*a)/a},Abs:t=>Math.abs(F(t[0])),Floor:t=>Math.floor(F(t[0])),Ceil:t=>Math.ceil(F(t[0])),Find:t=>{const e=ae(t[0]),r=String(t[1]??""),a=String(t[2]??"=="),i=t[3];return e.find(n=>Cr(a,ze(n,r),i))??null},GroupBy:t=>{const e=ae(t[0]),r=String(t[1]??""),a={};for(const i of e){const n=String(ze(i,r)??"");(a[n]??(a[n]=[])).push(i)}return a},Slice:t=>{const e=ae(t[0]),r=t[1]===void 0?0:F(t[1]),a=t[2]===void 0?e.length:F(t[2]);return e.slice(r,a)},Unique:t=>{const e=ae(t[0]),r=t[1]===void 0?"":String(t[1]??"");if(!r)return Array.from(new Set(e));const a=new Set,i=[];for(const n of e){const s=ze(n,r);a.has(s)||(a.add(s),i.push(n))}return i},Reverse:t=>[...ae(t[0])].reverse(),Range:t=>{const e=F(t[0]),r=F(t[1]),a=t[2]===void 0?r>=e?1:-1:F(t[2]);if(a===0)return[e];const i=[];if(a>0)for(let n=e;n<=r;n+=a)i.push(n);else for(let n=e;n>=r;n+=a)i.push(n);return i},Repeat:t=>{const e=Math.max(0,F(t[1]));return Array.from({length:e},()=>t[0])},Pick:t=>{const e=t[0];if(!sn(e))return{};const r=ae(t[1]).map(i=>String(i??"")),a={};for(const i of r)i in e&&(a[i]=e[i]);return a},Format:t=>{const e=F(t[0]),r=String(t[1]??"number"),a=t[2];if(r==="currency"){const n=String(a??"USD")||"USD",s=t[3]===void 0?void 0:String(t[3]??"");try{return new Intl.NumberFormat(s||void 0,{style:"currency",currency:n}).format(e)}catch{return e.toFixed(2)}}if(r==="percent"){const n=t[2]===void 0?void 0:String(t[2]??"");return new Intl.NumberFormat(n||void 0,{style:"percent",maximumFractionDigits:2}).format(e)}const i=t[2]===void 0?void 0:String(t[2]??"");return new Intl.NumberFormat(i||void 0).format(e)},FormatDate:t=>{const e=xe(t[0]),r=String(t[1]??"MMM D");switch(r){case"relative":return mn(e);case"date":return e.toLocaleDateString();case"time":return e.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});case"datetime":return e.toLocaleString();case"iso":return e.toISOString();default:return pn(e,r)}},Now:()=>Date.now(),Today:()=>{const t=new Date;return t.setHours(0,0,0,0),t.toISOString()},AddDays:t=>{const e=xe(t[0]),r=F(t[1]),a=new Date(e.getTime());return a.setDate(a.getDate()+r),a.toISOString()},AddHours:t=>{const e=xe(t[0]),r=F(t[1]),a=new Date(e.getTime());return a.setTime(a.getTime()+r*36e5),a.toISOString()},DiffDays:t=>{const e=xe(t[0]),r=xe(t[1]);return Math.round((r.getTime()-e.getTime())/864e5)},StartOfWeek:t=>{const e=xe(t[0]),r=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()));return r.setUTCDate(r.getUTCDate()-r.getUTCDay()),r.toISOString()},EndOfMonth:t=>{const e=xe(t[0]);return new Date(e.getFullYear(),e.getMonth()+1,0,23,59,59,999).toISOString()},Plural:t=>{const e=F(t[0]),r=String(t[1]??""),a=t[2]===void 0?r+"s":String(t[2]??"");return`${e} ${e===1?r:a}`},Capitalize:t=>{const e=String(t[0]??"");return e.length===0?"":e.charAt(0).toUpperCase()+e.slice(1)},Lowercase:t=>String(t[0]??"").toLowerCase(),Uppercase:t=>String(t[0]??"").toUpperCase(),Titlecase:t=>String(t[0]??"").split(/\s+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" "),Case:t=>{const e=String(t[1]??"camel").toLowerCase();return e==="snake"||e==="kebab"||e==="pascal"||e==="camel"?$r(t[0],e):$r(t[0],"camel")},Join:t=>{const e=ae(t[0]),r=t[1]===void 0?",":String(t[1]??"");return e.map(a=>a==null?"":String(a)).join(r)},Split:t=>{const e=String(t[0]??""),r=t[1]===void 0?",":String(t[1]??"");return e.split(r)},Trim:t=>String(t[0]??"").trim(),Replace:t=>{const e=String(t[0]??""),r=String(t[1]??""),a=t[2]===void 0?"":String(t[2]??"");return e.split(r).join(a)},Substring:t=>{const e=String(t[0]??""),r=F(t[1]),a=t[2]===void 0?e.length:F(t[2]);return e.substring(r,a)},StartsWith:t=>String(t[0]??"").startsWith(String(t[1]??"")),EndsWith:t=>String(t[0]??"").endsWith(String(t[1]??"")),Contains:t=>String(t[0]??"").includes(String(t[1]??"")),Match:t=>{const e=String(t[0]??""),r=String(t[1]??"");try{return new RegExp(r).test(e)}catch{return!1}},Clamp:t=>{const e=F(t[0]),r=F(t[1]),a=F(t[2]);return Math.min(Math.max(e,r),a)},Pow:t=>Math.pow(F(t[0]),F(t[1])),Sqrt:t=>Math.sqrt(F(t[0])),Random:()=>Math.random(),Log:t=>Math.log(F(t[0]))},Nr=t=>!!(t&&typeof t=="object"&&t.kind==="Theme");class Ar{constructor(){j(this,"values",new Map);j(this,"defaults",new Map);j(this,"persistent",new Set);j(this,"persistenceAdapter",null);j(this,"subscribers",new Set);j(this,"pendingChanges",new Set);j(this,"flushScheduled",!1)}setPersistenceAdapter(e){this.persistenceAdapter=e}declare(e,r){this.defaults.set(e,r),this.values.has(e)||this.values.set(e,r)}declarePersistent(e,r){this.persistent.add(e),this.defaults.set(e,r);const a=this.persistenceAdapter;let i=r;if(a){const n=a.load(e);n!==void 0&&(i=n)}this.values.set(e,i)}isPersistent(e){return this.persistent.has(e)}has(e){return this.values.has(e)}get(e){return this.values.get(e)}set(e,r){this.values.get(e)!==r&&(this.values.set(e,r),this.pendingChanges.add(e),this.persistent.has(e)&&this.persistenceAdapter?.save(e,r),this.scheduleFlush())}entries(){return this.values.entries()}snapshot(){const e={};return this.values.forEach((r,a)=>{e[a]=r}),e}hydrate(e){for(const[r,a]of Object.entries(e))this.values.set(r,a)}reset(...e){let r=!1;for(const a of e){if(!this.defaults.has(a))continue;const i=this.defaults.get(a);this.values.get(a)!==i&&(this.values.set(a,i),this.pendingChanges.add(a),this.persistent.has(a)&&this.persistenceAdapter?.save(a,i),r=!0)}r&&this.scheduleFlush()}resetAll(){let e=!1;for(const[r,a]of this.defaults.entries())this.values.get(r)!==a&&(this.values.set(r,a),this.pendingChanges.add(r),e=!0);e&&this.scheduleFlush()}rebind(e){this.values.clear(),this.defaults.clear(),this.persistent.clear(),this.pendingChanges.clear();for(const[r,a]of e)this.defaults.set(r,a),this.values.set(r,a)}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}scheduleFlush(){this.flushScheduled||(this.flushScheduled=!0,queueMicrotask(()=>this.flush()))}flush(){if(this.flushScheduled=!1,this.pendingChanges.size===0)return;const e=new Set(this.pendingChanges);this.pendingChanges.clear();for(const r of[...this.subscribers])r(e)}}function Mr(t,e){if(!e)return null;const r=a=>`${t}::${a}`;return{load(a){try{const i=e.getItem(r(a));return i===null?void 0:JSON.parse(i)}catch{return}},save(a,i){try{e.setItem(r(a),JSON.stringify(i))}catch{}},remove(a){try{e.removeItem(r(a))}catch{}}}}class Pr{constructor(){j(this,"interceptors",{});j(this,"defaults",{})}setDefaults(e){this.defaults={...e}}registerInterceptors(e){this.interceptors={...this.interceptors,...e}}resolveUrl(e){const r=this.defaults.baseUrl;return!r||/^https?:\/\//i.test(e)||/^wss?:\/\//i.test(e)?e:e.startsWith("/")?r.replace(/\/$/,"")+e:r.replace(/\/$/,"")+"/"+e}async request(e){let r={...e,headers:{...this.defaults.headers,...e.headers}};if(this.interceptors.onRequest)try{r=await this.interceptors.onRequest(r)}catch(c){throw this.interceptors.onError?.(c,r),c}const a=async()=>{const c=new AbortController,u=this.defaults.timeoutMs??0;let p=null;u>0&&(p=setTimeout(()=>c.abort(),u));try{const m=typeof fetch=="function"?fetch:null;if(!m)throw new Error("`fetch` is not available in this environment");const g={method:r.method,headers:r.headers,signal:r.signal??c.signal};r.body!==void 0&&r.method!=="GET"&&r.method!=="HEAD"&&(g.body=gn(r.body,r.headers)),this.defaults.credentials&&(g.credentials=this.defaults.credentials);const f=await m(r.url,g),h={};f.headers.forEach((y,x)=>{h[x]=y});const b=h["content-type"]??"";let v;return f.status===204||r.method==="HEAD"?v=null:b.includes("application/json")?v=await f.json().catch(()=>null):v=await f.text().catch(()=>""),{status:f.status,headers:h,body:v}}finally{p&&clearTimeout(p)}},i=this.defaults.retry,n=Math.max(0,i?.count??0),s=i?.backoff??"exponential",l=async()=>{let c=null;for(let u=0;u<=n;u+=1)try{const p=await a();if(p.status>=500&&p.status<=599&&u<n){await zr(Ir(s,u));continue}return p}catch(p){if(c=p,u<n){await zr(Ir(s,u));continue}throw p}throw c??new Error("retry loop exhausted")};try{let c=await l();if(this.interceptors.onResponse){let u=!1;const p=async()=>u?c:(u=!0,l());c=await this.interceptors.onResponse(c,p)}return c}catch(c){throw this.interceptors.onError?.(c,r),c}}}function Ir(t,e){return t==="linear"?1e3*(e+1):Math.min(3e4,500*2**e)}function zr(t){return new Promise(e=>setTimeout(e,t))}function gn(t,e){if(t==null)return"";if(typeof t=="string"||t instanceof Blob||t instanceof ArrayBuffer||typeof FormData<"u"&&t instanceof FormData||typeof URLSearchParams<"u"&&t instanceof URLSearchParams)return t;!e["content-type"]&&!e["Content-Type"]&&(e["Content-Type"]="application/json");try{return JSON.stringify(t)}catch{return String(t)}}function fn(t){const e=t&&typeof t=="object"&&!Array.isArray(t)?t:{},r=typeof e.url=="string"?e.url:"",a=typeof e.method=="string"?e.method.toUpperCase():"GET",i={};if(e.headers&&typeof e.headers=="object"&&!Array.isArray(e.headers))for(const[l,c]of Object.entries(e.headers))c!=null&&(i[l]=String(c));let n=r;if(e.query&&typeof e.query=="object"&&!Array.isArray(e.query)){const l=new URLSearchParams;for(const[u,p]of Object.entries(e.query))p!=null&&l.append(u,String(p));const c=l.toString();c&&(n+=(n.includes("?")?"&":"?")+c)}const s={url:n,method:a,headers:i,body:e.body};return e.signal instanceof AbortSignal&&(s.signal=e.signal),s}function Rr(t,e){const r={state:"loading",data:void 0,error:void 0,loading:!0,refetch:async()=>{await s()},cancel:()=>{a&&a.abort()}};let a=null,i=!1;const n=()=>e.notify?.(),s=async()=>{if(i&&a&&a.abort(),i=!0,a=new AbortController,r.state=r.data===void 0?"loading":"stale",r.loading=!0,n(),!e.http){r.error={message:"http runtime not available"},r.state="error",r.loading=!1,i=!1,n();return}try{const l=fn(t);l.url=e.http.resolveUrl(l.url),l.signal=a.signal;const c=await e.http.request(l);c.status>=200&&c.status<300?(r.data=c.body,r.state="data",r.error=void 0):(r.error={status:c.status,body:c.body},r.state="error"),r.status=c.status,r.headers=c.headers,r.lastUpdated=Date.now()}catch(l){if(l?.name==="AbortError")return;r.error=l,r.state="error"}finally{i=!1,r.loading=!1,n()}};return s(),r}function we(t){if(!t)return"/";let e=String(t);e.startsWith("#")&&(e=e.slice(1));const r=e.indexOf("?");return r>=0&&(e=e.slice(0,r)),e=e.replace(/\/{2,}/g,"/"),!e||e==="/"?"/":(e.startsWith("/")||(e="/"+e),e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e)}function Lr(t,e){if(!t)return{matched:!1,params:{}};if(t==="*")return{matched:!0,params:{},wildcard:!0};const r=we(t),a=we(e),i=r==="/"?[]:r.slice(1).split("/"),n=a==="/"?[]:a.slice(1).split("/"),s={};let l=!1;for(let c=0;c<i.length;c+=1){const u=i[c];if(u==="*"){l=!0;const m=n.slice(c).join("/");return s._=m,{matched:!0,params:s,wildcard:l}}const p=n[c];if(p===void 0)return{matched:!1,params:{}};if(u.startsWith(":")){const m=u.slice(1);if(!m)return{matched:!1,params:{}};s[m]=decodeURIComponent(p);continue}if(u!==p)return{matched:!1,params:{}}}return!l&&n.length>i.length?{matched:!1,params:{}}:l?{matched:!0,params:s,wildcard:!0}:{matched:!0,params:s}}class Er{constructor(e={}){j(this,"currentPath");j(this,"currentParams",{});j(this,"currentPattern",null);j(this,"enabled",!1);j(this,"hashListener",null);j(this,"listeners",new Set);j(this,"defaultPath");j(this,"settingHash",!1);this.defaultPath=we(e.defaultPath??"/"),this.currentPath=this.defaultPath}start(){if(this.enabled||(this.enabled=!0,typeof window>"u"))return;const e=a=>{if(this.settingHash)return;const i=we(window.location.hash);this.setPath(i,a)},r=()=>e("hashchange");window.addEventListener("hashchange",r),this.hashListener=r,e("init")}stop(){this.enabled&&(this.enabled=!1,typeof window<"u"&&this.hashListener&&window.removeEventListener("hashchange",this.hashListener),this.hashListener=null)}getPath(){return this.currentPath}getParams(){return this.currentParams}getActivePattern(){return this.currentPattern}setActiveMatch(e,r){this.currentPattern=e,hn(this.currentParams,r)||(this.currentParams=r)}navigate(e){const r=we(e);if(r!==this.currentPath){if(this.enabled&&typeof window<"u"){this.settingHash=!0;try{window.location.hash="#"+r}finally{queueMicrotask(()=>{this.settingHash=!1})}this.setPath(r,"navigate");return}this.setPath(r,"navigate")}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}setPath(e,r){const a=we(e);if(a===this.currentPath)return;const i=this.currentPath;this.currentPath=a,this.currentParams={},this.currentPattern=null;for(const n of[...this.listeners])try{n({path:a,previousPath:i,source:r})}catch(s){console.error("[aktion] router listener failed",s)}}}function hn(t,e){const r=Object.keys(t),a=Object.keys(e);if(r.length!==a.length)return!1;for(const i of r)if(t[i]!==e[i])return!1;return!0}const be=(t,e)=>{try{return t()}catch{return e}},_r=t=>{if(typeof t=="string")return t;if(t===null)return"null";if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}},jr=t=>{if(t===null||t==="")return t;try{return JSON.parse(t)}catch{return t}},Br=t=>({set:(e,r)=>be(()=>{const a=t();return a?(a.setItem(String(e),_r(r)),!0):!1},!1),get:e=>be(()=>{const r=t();return r?jr(r.getItem(String(e))):null},null),remove:e=>be(()=>{const r=t();return r?(r.removeItem(String(e)),!0):!1},!1),clear:()=>be(()=>{const e=t();return e?(e.clear(),!0):!1},!1)}),bn=()=>typeof globalThis>"u"?null:globalThis.localStorage??null,vn=()=>typeof globalThis>"u"?null:globalThis.sessionStorage??null,Qe=()=>typeof globalThis>"u"?null:globalThis.document??null,yn=t=>{if(t==null)return null;if(t instanceof Date)return t.toUTCString();if(typeof t=="string"){const e=new Date(t);return Number.isNaN(e.getTime())?null:e.toUTCString()}if(typeof t=="number"&&Number.isFinite(t)){const e=new Date;return e.setTime(e.getTime()+t*864e5),e.toUTCString()}return null},Mt=(t={})=>{const e=[],r=yn(t.expires);if(r&&e.push(`expires=${r}`),typeof t.maxAge=="number"&&Number.isFinite(t.maxAge)&&e.push(`max-age=${Math.floor(t.maxAge)}`),e.push(`path=${t.path??"/"}`),t.domain&&e.push(`domain=${t.domain}`),t.secure&&e.push("secure"),t.sameSite){const a=t.sameSite.charAt(0).toUpperCase()+t.sameSite.slice(1).toLowerCase();e.push(`samesite=${a}`)}return e.length===0?"":`; ${e.join("; ")}`},Dr=()=>{const t=Qe();if(!t)return{};const e={},r=t.cookie??"";if(!r)return e;for(const a of r.split(";")){const i=a.trim();if(!i)continue;const n=i.indexOf("=");if(n<0){e[decodeURIComponent(i)]="";continue}const s=decodeURIComponent(i.slice(0,n)),l=decodeURIComponent(i.slice(n+1));e[s]=l}return e},xn={set:(t,e,r)=>be(()=>{const a=Qe();if(!a)return!1;const i=encodeURIComponent(String(t)),n=encodeURIComponent(_r(e));return a.cookie=`${i}=${n}${Mt(r)}`,!0},!1),get:t=>be(()=>{const r=Dr()[String(t)];return r===void 0?null:jr(r)},null),remove:(t,e)=>be(()=>{const r=Qe();if(!r)return!1;const a=encodeURIComponent(String(t)),i={...e,expires:new Date(0),maxAge:0};return r.cookie=`${a}=${Mt(i)}`,!0},!1),clear:()=>be(()=>{const t=Qe();if(!t)return!1;const e=Dr();for(const r of Object.keys(e)){const a=encodeURIComponent(r);t.cookie=`${a}=${Mt({expires:new Date(0),maxAge:0})}`}return!0},!1)},Ue=Br(bn),wn=Br(vn),Fr={set:Ue.set,get:Ue.get,remove:Ue.remove,clear:Ue.clear,local:Ue,session:wn,cookies:xn},kn=["log","error","warn","info","debug"],Sn=()=>typeof globalThis>"u"?null:globalThis.console??null,Cn=t=>(...e)=>{const r=Sn();if(!r)return;const a=r[t]??r.log;if(typeof a=="function")try{a(...e)}catch{}},Or=kn.reduce((t,e)=>(t[e]=Cn(e),t),{}),Ur={storage:Fr,console:Or},qr=t=>!!(t&&typeof t=="object"&&t.__kind==="Component"),Hr=t=>!!(t&&typeof t=="object"&&t.__kind==="UserComponent");function Pt(t,e={}){return{state:t,bindings:new Map,expressions:new Map,trackedState:new Set,loopVars:new Map,stateAliases:[],router:e.router,library:e.library,componentDecls:new Map,effectDecls:new Map,componentEffectStack:[],actionDecls:new Map,http:e.http,i18n:e.i18n,actionRunner:e.actionRunner,notify:e.notify,jsBlockExecutor:e.jsBlockExecutor}}function Vr(t,e){const r={};for(let a=0;a<t.length;a+=1)r[t[a].name]=e[a];return r}function ke(t,e){for(let r=t.stateAliases.length-1;r>=0;r-=1){const i=t.stateAliases[r].get(e);if(i!==void 0)return i}return e}function Wr(t,e){for(const r of t.statements)if(r.kind==="Assignment"&&r.isState){const a=et(r.expression);e.state.declare(r.identifier,a)}for(const r of t.statements){if(r.kind!=="Assignment"||!r.isState||r.expression.kind!=="Call"||r.expression.callee!=="http")continue;const a=M(r.expression,e);e.state.set(r.identifier,a)}for(const r of t.statements){if(r.kind!=="Assignment")continue;const a=r.expression;if(a.kind==="Call"){if((r.identifier==="http"||r.identifier==="$http")&&a.callee==="Http"){M(a,e);continue}if((r.identifier==="i18n"||r.identifier==="$i18n")&&a.callee==="i18n"){M(a,e);continue}}}for(const r of t.statements)It(r,e)}function It(t,e){switch(t.kind){case"ComponentDeclaration":e.componentDecls.set(t.name,t);return;case"EffectDeclaration":e.effectDecls.set(t.name,t);return;case"ActionDeclaration":e.actionDecls.set(t.name,t);return;case"Emit":case"Cleanup":case"Await":case"Return":case"ExpressionStatement":return;case"Assignment":{if(t.isState)return;e.expressions.set(t.identifier,t.expression);const r=t.expression;e.bindings.set(t.identifier,()=>M(r,e));return}}}function Tn(t,e,r){const a=t[0];if(!a||a.kind!=="Object")return console.error('[aktion] _router_ expects an object literal of route arms (e.g. `_router_({ "/": Home(), default: NotFound() })`).',r),e.router?.setActiveMatch(null,{}),null;const i=Dn(e);let n=null;for(const s of a.properties){if(s.spread)continue;const l=s.key;if(l==="default"||l==="*"){n=s;continue}const c=Lr(l,i);if(c.matched)return Gr(l,s.value,c.params,e)}return n?Gr(null,n.value,{},e):(e.router?.setActiveMatch(null,{}),null)}function Gr(t,e,r,a){const i=a.loopVars.get("params"),n=a.loopVars.has("params");a.loopVars.set("params",r);try{const s=M(e,a);return a.router?.setActiveMatch(t,r),s}finally{n?a.loopVars.set("params",i):a.loopVars.delete("params")}}function et(t){switch(t.kind){case"Literal":return t.value;case"Array":{const e=[];for(const r of t.elements)r.kind!=="Spread"&&e.push(et(r));return e}case"Object":{const e={};for(const r of t.properties)r.spread||(e[r.key]=et(r.value));return e}case"Template":return t.expressions.length===0?t.quasis[0]??"":null;default:return null}}function M(t,e){switch(t.kind){case"Literal":return t.value;case"Identifier":{if(e.loopVars.has(t.name))return e.loopVars.get(t.name);if(t.name==="_route_")return e.trackedState.add("route"),e.router?Fn(e.router):{path:"/",params:{},pattern:null,query:{},navigate(){},toString(){return"/"}};const r=e.bindings.get(t.name);if(r)return r();const a=e.actionDecls.get(t.name);return a?Yr(a,e):Object.prototype.hasOwnProperty.call(Ur,t.name)?Ur[t.name]:null}case"StateRef":{const r=ke(e,t.name);return e.trackedState.add(r),e.state.get(r)}case"Array":{const r=[];for(const a of t.elements){if(a.kind==="Spread"){const i=M(a.argument,e);if(Array.isArray(i))for(const n of i)r.push(n);else if(i!=null&&typeof i=="string")for(const n of i)r.push(n);continue}r.push(M(a,e))}return r}case"Object":{const r={};for(const a of t.properties){if(a.spread){const i=M(a.value,e);if(i&&typeof i=="object"&&!Array.isArray(i))for(const[n,s]of Object.entries(i))r[n]=s;continue}r[a.key]=M(a.value,e)}return r}case"Member":{const r=M(t.object,e);if(t.optional&&r==null)return;if(t.computed){const a=M(t.computed,e);return On(r,a)}return Un(r,t.property??"")}case"Unary":{const r=M(t.argument,e);return t.operator==="!"?!r:-U(r)}case"Binary":return Pn(t.operator,t.left,t.right,e);case"Ternary":{const r=M(t.test,e);return M(r?t.consequent:t.alternate,e)}case"Call":return zn(t.callee,t.arguments,e,t.loc);case"MethodCall":return In(t,e);case"BuiltinCall":return En(t.name,t.arguments,e);case"Template":return Mn(t.quasis,t.expressions,e);case"Spread":return M(t.argument,e);case"If":return $n(t,e);case"Match":return Nn(t,e);case"For":return An(t,e);case"Block":return Re(t,e);case"Lambda":{const r=t.params,a=t.body,i=e.stateAliases.map(s=>new Map(s)),n=new Map(e.loopVars);return(...s)=>{const l=new Map(e.loopVars),c=e.stateAliases.slice();e.loopVars.clear();for(const[p,m]of n)e.loopVars.set(p,m);e.stateAliases.length=0;for(const p of i)e.stateAliases.push(p);const u=[];for(let p=0;p<r.length;p+=1){const m=r[p];let g=s[p];g===void 0&&m.defaultValue&&(g=M(m.defaultValue,e)),u.push({name:m.name,had:e.loopVars.has(m.name),prev:e.loopVars.get(m.name)}),e.loopVars.set(m.name,g)}try{if(a.kind==="JsBlock"){const m=a.body;return e.jsBlockExecutor?e.jsBlockExecutor(m,Vr(r,s)):{__kind:"JsBlock",body:m}}const p=M(a,e);if(e.jsBlockExecutor&&p&&typeof p=="object"&&p.__kind==="JsBlock"){const m=p.body;return e.jsBlockExecutor(m,Vr(r,s))}return p}finally{for(const p of u)p.had?e.loopVars.set(p.name,p.prev):e.loopVars.delete(p.name);e.loopVars.clear();for(const[p,m]of l)e.loopVars.set(p,m);e.stateAliases.length=0;for(const p of c)e.stateAliases.push(p)}}}case"JsBlock":return{__kind:"JsBlock",body:t.body};case"Bind":return{__kind:"Bind",prop:t.prop,target:M(t.target,e),targetExpr:t.target};case"NamedArg":return M(t.value,e);default:return null}}function $n(t,e){return M(t.test,e)?Re(t.consequent,e):t.alternate?t.alternate.kind==="Block"?Re(t.alternate,e):M(t.alternate,e):null}function Nn(t,e){const r=M(t.discriminant,e);for(const a of t.arms)if(a.pattern==="_"||M(a.pattern,e)===r)return M(a.body,e);return null}function An(t,e){const r=M(t.iterable,e);if(!Array.isArray(r))return[];const a=[],i=e.loopVars.has(t.item),n=e.loopVars.get(t.item),s=t.index,l=s?e.loopVars.has(s):!1,c=s?e.loopVars.get(s):void 0,u=t.destructure??[],p=u.map(m=>({name:m,had:e.loopVars.has(m),value:e.loopVars.get(m)}));try{for(let m=0;m<r.length;m+=1){const g=r[m];e.loopVars.set(t.item,g),s&&e.loopVars.set(s,m);for(const f of u){const h=g&&typeof g=="object"?g[f]:void 0;e.loopVars.set(f,h)}a.push(Re(t.body,e))}}finally{i?e.loopVars.set(t.item,n):e.loopVars.delete(t.item),s&&(l?e.loopVars.set(s,c):e.loopVars.delete(s));for(const m of p)m.had?e.loopVars.set(m.name,m.value):e.loopVars.delete(m.name)}return a}function Re(t,e){let r=null;const a=[];for(const i of t.body)switch(i.kind){case"ExpressionStatement":r=M(i.expression,e);continue;case"Assignment":{const n=M(i.expression,e);if(i.isState&&i.identifier){const s=ke(e,i.identifier);e.state.set(s,n)}else e.loopVars.has(i.identifier)||a.push(i.identifier),e.loopVars.set(i.identifier,n);r=n;continue}case"Return":return r=i.argument?M(i.argument,e):void 0,r;case"EffectDeclaration":{const n=e.componentEffectStack[e.componentEffectStack.length-1];n?n.push(i):It(i,e);continue}case"ComponentDeclaration":case"ActionDeclaration":It(i,e);continue;case"Emit":case"Cleanup":case"Await":continue}for(const i of a)e.loopVars.delete(i);return r}function Mn(t,e,r){let a=t[0]??"";for(let i=0;i<e.length;i+=1)a+=tt(M(e[i],r)),a+=t[i+1]??"";return a}function Pn(t,e,r,a){if(t==="&&"){const s=M(e,a);return s&&M(r,a)}if(t==="||"){const s=M(e,a);return s||M(r,a)}if(t==="??"){const s=M(e,a);return s??M(r,a)}const i=M(e,a),n=M(r,a);switch(t){case"+":return typeof i=="string"||typeof n=="string"?tt(i)+tt(n):U(i)+U(n);case"-":return U(i)-U(n);case"*":return U(i)*U(n);case"/":{const s=U(n);return s===0?0:U(i)/s}case"%":{const s=U(n);return s===0?0:U(i)%s}case"==":return i===n;case"!=":return i!==n;case">":return U(i)>U(n);case"<":return U(i)<U(n);case">=":return U(i)>=U(n);case"<=":return U(i)<=U(n);default:return null}}function In(t,e){const r=M(t.object,e);if(r==null)return t.optional?void 0:null;const a=r[t.method];if(typeof a!="function")return null;const i=[],n={};let s=!1;for(const c of t.arguments){if(c.kind==="NamedArg"){n[c.name]=M(c.value,e),s=!0;continue}if(c.kind==="Spread"){const u=M(c.argument,e);if(Array.isArray(u))for(const p of u)i.push(p);continue}i.push(M(c,e))}const l=s?[...i,n]:i;try{return a.apply(r,l)}catch(c){return console.error(`[aktion] method "${t.method}" threw`,c),null}}function zn(t,e,r,a){if(t==="_router_")return Tn(e,r,a);const i=r.componentDecls.get(t);if(i)return Ln(i,e,r,a);const n=r.actionDecls.get(t);if(n){if(e.length===0)return Yr(n,r);const f=e.map(h=>h.kind==="NamedArg"?M(h.value,r):M(h,r));return Jr(n,f,r)}if(t==="http"){const f=e[0],h=f?f.kind==="NamedArg"?M(f.value,r):M(f,r):{};return Rr(h,r)}const s=r.loopVars.get(t);if(typeof s=="function"){const f=e.map(h=>M(h,r));return s(...f)}const l=r.bindings.get(t);if(l){const f=l();if(typeof f=="function"){const h=e.map(b=>b.kind==="NamedArg"?M(b.value,r):M(b,r));return f(...h)}}if(t==="Theme"){const f=e[0];return{kind:"Theme",tokens:Vn(f?M(f,r):null)}}if(t==="Http"){const f=e[0],h=f?M(f,r):null;if(h&&typeof h=="object"&&!Array.isArray(h)&&r.http){const b=h;r.http.setDefaults({baseUrl:typeof b.baseUrl=="string"?b.baseUrl:void 0,headers:b.headers&&typeof b.headers=="object"&&!Array.isArray(b.headers)?Object.fromEntries(Object.entries(b.headers).map(([v,y])=>[v,String(y??"")])):void 0,timeoutMs:typeof b.timeout=="number"?b.timeout:void 0,retry:b.retry&&typeof b.retry=="object"&&!Array.isArray(b.retry)?{count:Number(b.retry.count??0)||0,backoff:b.retry.backoff==="linear"?"linear":"exponential"}:void 0,credentials:b.credentials==="omit"||b.credentials==="same-origin"||b.credentials==="include"?b.credentials:void 0})}return{__kind:"Http",config:h}}if(t==="i18n"){const f=e[0],h=f?M(f,r):null;if(h&&typeof h=="object"&&!Array.isArray(h)&&r.i18n){const b=h;r.i18n.configure({locale:typeof b.locale=="string"?b.locale:"en",messages:b.messages&&typeof b.messages=="object"&&!Array.isArray(b.messages)?b.messages:{},fallback:typeof b.fallback=="string"?b.fallback:"en",fallbackMessages:b.fallbackMessages&&typeof b.fallbackMessages=="object"&&!Array.isArray(b.fallbackMessages)?b.fallbackMessages:void 0})}return{__kind:"I18n",config:h}}if(r.library&&!Ie(r.library,t))return Ie(r.library,"Skeleton")?{__kind:"Component",name:"Skeleton",args:[],argMeta:[],source:a}:null;let c;const u=[];for(const f of e){if(f.kind==="NamedArg"&&f.name==="key"){c=M(f.value,r);continue}u.push(f)}const{args:p,argMeta:m}=Rn(r,t,u);return{__kind:"Component",name:t,args:p,argMeta:m,explicitKey:c,source:a}}function Rn(t,e,r){const a=t.library?Ie(t.library,e):void 0;if(!a){const m=r.map(f=>f.kind==="NamedArg"?M(f.value,t):f.kind==="Bind"?M(f.target,t):M(f,t)),g=r.map(f=>f.kind==="StateRef"?{stateRef:f.name}:f.kind==="Bind"&&f.target.kind==="StateRef"?{stateRef:f.target.name}:f.kind==="NamedArg"&&f.value.kind==="StateRef"?{stateRef:f.value.name}:{});return{args:m,argMeta:g}}const i=new Map;a.props.forEach((m,g)=>{if(i.set(m.name,g),m.aliases)for(const f of m.aliases)i.has(f)||i.set(f,g)});const n=Tt(a),s=a.props.map(()=>({value:void 0,meta:{},filled:!1})),l=[];for(const m of r){if(m.kind==="NamedArg"){const g=i.get(m.name);if(g===void 0)continue;const f=M(m.value,t);s[g].value=f,s[g].filled=!0,m.value.kind==="StateRef"&&(s[g].meta={stateRef:m.value.name});continue}if(m.kind==="Bind"){const g=i.get(m.prop);if(g===void 0)continue;const f=M(m.target,t);s[g].value=f,s[g].filled=!0,m.target.kind==="StateRef"&&(s[g].meta={stateRef:m.target.name});continue}l.push({expr:m,value:M(m,t)})}if(l.length>0&&n>=0&&!s[n].filled){const{expr:m,value:g}=l.shift();s[n].value=g,s[n].filled=!0,m.kind==="StateRef"&&(s[n].meta={stateRef:m.name})}let c=0;for(const{expr:m,value:g}of l){for(;c<a.props.length&&s[c].filled;)c+=1;if(c>=a.props.length)break;s[c].value=g,s[c].filled=!0,m.kind==="StateRef"&&(s[c].meta={stateRef:m.name}),c+=1}const u=s.map(m=>m.value),p=s.map(m=>m.meta);for(;u.length>0&&u[u.length-1]===void 0;)u.pop(),p.pop();return{args:u,argMeta:p}}function Ln(t,e,r,a){const i=[],n={};let s;for(const m of e)m.kind==="NamedArg"?m.name==="key"?s=m.value:n[m.name]=m.value:i.push(m);const l=i.map(m=>m.kind==="Spread"?M(m.argument,r):M(m,r)),c=[];for(let m=0;m<i.length;m+=1){const g=i[m],f=l[m];if(g.kind==="Spread"&&Array.isArray(f))for(const h of f)c.push(h);else c.push(f)}const u={};for(const[m,g]of Object.entries(n))u[m]=M(g,r);const p=s?M(s,r):void 0;return{__kind:"UserComponent",decl:t,positional:c,named:u,explicitKey:p,source:a}}function Kr(t,e,r){const{decl:a,positional:i,named:n}=t,s=[];for(let u=0;u<a.params.length;u+=1){const p=a.params[u];let m;n[p.name]!==void 0?m=n[p.name]:i[u]!==void 0?m=i[u]:p.defaultValue?m=M(p.defaultValue,e):m=void 0,s.push({name:p.name,had:e.loopVars.has(p.name),prev:e.loopVars.get(p.name)}),e.loopVars.set(p.name,m)}if(i.length>a.params.length){const u=i.slice(a.params.length),p=u.length===1?u[0]:u;s.push({name:"children",had:e.loopVars.has("children"),prev:e.loopVars.get("children")}),e.loopVars.set("children",p)}if(a.slots.length>0){const u={};for(const p of a.slots)n[p]!==void 0&&(u[p]=n[p]);s.push({name:"slots",had:e.loopVars.has("slots"),prev:e.loopVars.get("slots")}),e.loopVars.set("slots",u)}const l=new Map;for(const u of a.body.body)if(u.kind==="Assignment"&&u.isState){const p=`${r}:${u.identifier}`;l.set(u.identifier,p),e.state.declare(p,et(u.expression))}e.stateAliases.push(l);const c=[];e.componentEffectStack.push(c);try{return{value:Re(a.body,e),effects:c}}finally{e.componentEffectStack.pop(),e.stateAliases.pop();for(const u of s)u.had?e.loopVars.set(u.name,u.prev):e.loopVars.delete(u.name)}}function Yr(t,e){const r=e.stateAliases.map(a=>new Map(a));return async(...a)=>{const i=e.stateAliases.slice();e.stateAliases.length=0;for(const n of r)e.stateAliases.push(n);try{return await Jr(t,a,e)}finally{e.stateAliases.length=0;for(const n of i)e.stateAliases.push(n)}}}function Jr(t,e,r){if(!r.actionRunner){const a=[];for(let i=0;i<t.params.length;i+=1){const n=t.params[i];a.push({name:n.name,had:r.loopVars.has(n.name),prev:r.loopVars.get(n.name)}),r.loopVars.set(n.name,e[i])}try{return Re(t.body,r)}finally{for(const i of a)i.had?r.loopVars.set(i.name,i.prev):r.loopVars.delete(i.name)}}return r.actionRunner.run(t,e,r)}function En(t,e,r){if(t==="__rui_assign__")return _n(e,r);if(t==="__rui_postfix__")return jn(e,r);if(t==="Each"){const n=e[0],s=e[1],l=e[2];if(!n||!s||!l)return[];const c=M(n,r),u=Array.isArray(c)?c:[],p=s.kind==="Literal"?String(s.value??""):"",m=Bn(p),g=[],f=m.bindings.map(h=>({name:h,had:r.loopVars.has(h),prev:r.loopVars.get(h)}));try{for(const h of u){m.scalarName&&r.loopVars.set(m.scalarName,h);for(const b of m.fields)h&&typeof h=="object"?r.loopVars.set(b,h[b]):r.loopVars.set(b,void 0);g.push(M(l,r))}}finally{for(const h of f)h.had?r.loopVars.set(h.name,h.prev):r.loopVars.delete(h.name)}return g}if(t==="If"){const n=e[0],s=e[1],l=e[2];return n?M(n,r)?s?M(s,r):null:l?M(l,r):null:null}if(t==="Switch"){const n=e[0],s=e[1],l=e[2];if(!n||!s)return null;const c=M(n,r),u=tt(c);if(s.kind==="Object"){for(const p of s.properties)if(!p.spread&&p.key===u)return M(p.value,r)}return l?M(l,r):null}if(t==="T"||t==="t"){const n=e[0],s=e[1],l=n?String(M(n,r)??""):"";if(!r.i18n)return l;let c;if(s){const u=M(s,r);u&&typeof u=="object"&&!Array.isArray(u)&&(c=u)}return r.i18n.t(l,c)}if(t==="Locale")return r.i18n?.getLocale()??"";const a=At[t];if(!a)return null;const i=e.map(n=>M(n,r));return a(i)}function Xr(t,e,r){switch(t){case"=":return r;case"+=":return typeof e=="string"||typeof r=="string"?`${e??""}${r??""}`:U(e)+U(r);case"-=":return U(e)-U(r);case"*=":return U(e)*U(r);case"/=":{const a=U(r);return a===0?0:U(e)/a}case"??=":return e??r;default:return r}}function _n(t,e){const[r,a,i]=t;if(!r||!a)return null;const n=i&&i.kind==="Literal"?String(i.value??"="):"=",s=M(a,e);if(r.kind==="StateRef"){const l=ke(e,r.name),c=e.state.get(l),u=Xr(n,c,s);return e.state.set(l,u),u}if(r.kind==="Identifier"){const l=e.loopVars.get(r.name),c=Xr(n,l,s);return e.loopVars.set(r.name,c),c}return s}function jn(t,e){const[r,a]=t;if(!r)return null;const n=(a&&a.kind==="Literal"?String(a.value??"++"):"++")==="--"?-1:1;if(r.kind==="StateRef"){const s=ke(e,r.name),l=U(e.state.get(s))+n;return e.state.set(s,l),l}if(r.kind==="Identifier"){const s=U(e.loopVars.get(r.name))+n;return e.loopVars.set(r.name,s),s}return null}function Bn(t){const e=t.trim();if(!e)return{scalarName:"",fields:[],bindings:[]};if(e.startsWith("{")&&e.endsWith("}")){const a=e.slice(1,-1).split(",").map(i=>i.trim()).filter(Boolean);return{scalarName:"",fields:a,bindings:a}}const r=e.indexOf("{");if(r>0){const i=e.slice(0,r).trim().replace(/,\s*$/,"").trim(),n=e.indexOf("}",r),s=n>r?e.slice(r+1,n).split(",").map(l=>l.trim()).filter(Boolean):[];return{scalarName:i,fields:s,bindings:i?[i,...s]:s}}return{scalarName:e,fields:[],bindings:[e]}}function Dn(t){if(t.router)return t.router.getPath();if(t.state.has("route")){t.trackedState.add("route");const e=t.state.get("route");if(typeof e=="string"&&e)return e;if(e&&typeof e=="object"&&"path"in e){const r=e.path;if(typeof r=="string"&&r)return r}}return"/"}function Fn(t){const e=t.getPath(),r={...t.getParams()},a=t.getActivePattern(),i={};if(typeof globalThis<"u"&&globalThis.location){const n=globalThis.location?.search??"";if(n){const s=new URLSearchParams(n.startsWith("?")?n.slice(1):n);for(const[l,c]of s)i[l]=c}}return{path:e,params:r,pattern:a,query:i,navigate(n){typeof n!="string"||!n||t.navigate(n)},toString(){return e}}}function On(t,e){if(t!=null){if(Array.isArray(t)){const r=Zr(e,t.length);return r===null?void 0:t[r]}if(typeof t=="string"){const r=Zr(e,t.length);return r===null?void 0:t[r]}if(typeof t=="object")return t[String(e??"")]}}function Zr(t,e){let r;if(typeof t=="number")r=t;else if(typeof t=="string"&&t.trim()!==""&&!Number.isNaN(Number(t)))r=Number(t);else return null;return r<0&&(r=e+r),r<0||r>=e?null:r}function Un(t,e){if(t!=null){if(Array.isArray(t)){switch(e){case"length":return t.length;case"first":return t[0]??null;case"last":return t.length===0?null:t[t.length-1]}return t.map(r=>{if(r&&typeof r=="object")return r[e]})}if(typeof t=="string"&&e==="length")return t.length;if(typeof t=="object")return t[e]}}function U(t){if(typeof t=="number")return t;if(typeof t=="string"){if(t.trim()==="")return 0;const e=Number(t);return Number.isNaN(e)?0:e}return typeof t=="boolean"&&t?1:0}const qn=new Set(["colors","radius","font","motion","elevation"]),Hn=new Set(["name","direction"]);function Vn(t){const e={};if(!t||typeof t!="object"||Array.isArray(t))return e;const r=t;for(const[a,i]of Object.entries(r))if(i!=null&&!Hn.has(a)&&qn.has(a)&&i&&typeof i=="object"&&!Array.isArray(i)){const n=a==="colors"?"color":a;for(const[s,l]of Object.entries(i)){if(l==null)continue;const c=n+Wn(s);e[c]=Gn(l)}}return e}function Wn(t){return t?t.charAt(0).toUpperCase()+t.slice(1):""}function Gn(t){return typeof t=="string"?t:typeof t=="number"?String(t):""}function tt(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);if(typeof t=="object"&&t!==null){const e=t.toString;if(typeof e=="function"&&e!==Object.prototype.toString){const r=e.call(t);if(typeof r=="string")return r}}try{return JSON.stringify(t)}catch{return String(t)}}class Qr{constructor(){j(this,"locale","en");j(this,"fallback","en");j(this,"messages",{});j(this,"fallbackMessages",{})}configure(e){this.locale=e.locale||"en",this.fallback=e.fallback??"en",this.messages=ea(e.messages),this.fallbackMessages=ea(e.fallbackMessages??{})}getLocale(){return this.locale}getFallback(){return this.fallback}t(e,r){const a=ta(this.messages,e)??ta(this.fallbackMessages,e)??e;return typeof a!="string"?e:Kn(a,r)}}function ea(t){return!t||typeof t!="object"||Array.isArray(t)?{}:t}function ta(t,e){if(!e)return;if(e.indexOf(".")===-1)return t[e];let r=t;for(const a of e.split(".")){if(!r||typeof r!="object")return;r=r[a]}return r}function Kn(t,e){return e?t.replace(/\$\{([^}]+)\}/g,(r,a)=>{const i=e[a.trim()];return i==null?"":String(i)}):t}const zt="::";class ra{constructor(e){j(this,"mounted",new Map);j(this,"errors",[]);this.options=e}getErrors(){return this.errors}syncEffects(e,r){this.errors=[];const a=new Set(e.map(i=>i.name));for(const i of[...this.mounted.keys()])i.includes(zt)||a.has(i)||this.unmount(i);for(const i of e)this.mounted.has(i.name)||this.mount(i.name,i,r)}syncInstanceEffects(e,r,a){const i=`${e}${zt}`,n=new Set(r.map(s=>`${i}${s.name}`));for(const s of[...this.mounted.keys()])s.startsWith(i)&&(n.has(s)||this.unmount(s));for(const s of r){const l=`${i}${s.name}`;this.mounted.has(l)||this.mount(l,s,a)}}unmountInstance(e){const r=`${e}${zt}`;for(const a of[...this.mounted.keys()])a.startsWith(r)&&this.unmount(a)}reset(){for(const e of[...this.mounted.keys()])this.unmount(e);this.errors=[]}mount(e,r,a){const i={decl:r,cleanups:[],intervals:[],unsubscribers:[],ctxRef:a};this.mounted.set(e,i);const s=Yn(()=>{for(const p of i.cleanups.splice(0))try{p()}catch(m){ia(e,m)}try{aa(r,a(),i,this.options)}catch(p){console.error(`[aktion] effect "${e}" failed`,p)}finally{this.options.notify()}},r.rateLimit,i);let l=!1,c=!1,u=!1;for(const p of r.triggers)switch(p.kind){case"lifecycle":p.name==="mount"&&(l=!0),p.name==="unmount"&&(c=!0);break;case"every":{u=!0;const m=setInterval(s,p.intervalMs);i.intervals.push(m);break}case"state":{const m=p.name,g=this.options.state.subscribe(f=>{f.has(m)&&s()});i.unsubscribers.push(g);break}}(r.triggers.length===0||l||!u&&!c&&r.triggers.every(p=>p.kind==="state"))&&s()}unmount(e){const r=this.mounted.get(e);if(!r)return;this.mounted.delete(e);for(const i of r.intervals)clearInterval(i);for(const i of r.unsubscribers)try{i()}catch{}for(const i of r.cleanups)try{i()}catch(n){ia(e,n)}if(r.decl.triggers.some(i=>i.kind==="lifecycle"&&i.name==="unmount"))try{aa(r.decl,r.ctxRef(),r,this.options)}catch(i){console.error(`[aktion] effect "${e}" unmount body threw`,i)}}}function Yn(t,e,r){if(!e||e.ms<=0)return t;if(e.kind==="debounce"){let n=null;const s=()=>{n&&(clearTimeout(n),n=null)};return r.cleanups.push(s),()=>{n&&clearTimeout(n),n=setTimeout(()=>{n=null,t()},e.ms)}}let a=0,i=null;return r.cleanups.push(()=>{i&&(clearTimeout(i),i=null)}),()=>{const n=Date.now(),s=n-a;s>=e.ms?(a=n,t()):i||(i=setTimeout(()=>{i=null,a=Date.now(),t()},e.ms-s))}}function aa(t,e,r,a){for(const i of t.body.body)Jn(i,e,r,a)}function Jn(t,e,r,a){switch(t.kind){case"ExpressionStatement":{const i=t.expression;if(i.kind==="Call"&&i.callee==="cleanup"){const n=i.arguments[0]?M(i.arguments[0],e):null;typeof n=="function"&&r.cleanups.push(n);return}return i.kind==="JsBlock"?Rt(i.body,r.decl.name,e,a,r):M(i,e)}case"Assignment":{const i=M(t.expression,e);if(t.identifier&&t.identifier!==""){const n=ke(e,t.identifier);e.state.set(n,i)}return i}case"Cleanup":{const i=t.callback?M(t.callback,e):null;typeof i=="function"&&r.cleanups.push(i);return}case"Emit":{const i=M(t.detail,e);a.onEmit?.(t.eventName,i);return}default:return}}function ia(t,e){console.error(`[aktion] cleanup for effect "${t}" threw`,e)}function na(t){return(e,r={})=>Rt(e,"<inline>",void 0,t,void 0,r)}function Rt(t,e,r,a,i,n={}){const s={state:{get:l=>a.state.get(l),set:(l,c)=>a.state.set(l,c)},cleanup:l=>{typeof l=="function"&&i&&i.cleanups.push(l)},host:a.host,tools:a.tools??{},args:n};try{const c=new Function("ctx",`return (async () => { ${t}
19
+ })()`)(s);return c&&typeof c.then=="function"&&c.catch(u=>{console.error(`[aktion] js{} body in "${e}" rejected`,u)}),c}catch(l){console.error(`[aktion] js{} body in "${e}" threw`,l);return}}class oa{constructor(e){this.options=e}async run(e,r,a){const i=[],n={};for(let l=0;l<e.params.length;l+=1){const c=e.params[l],u=r[l];i.push({name:c.name,had:a.loopVars.has(c.name),prev:a.loopVars.get(c.name)}),a.loopVars.set(c.name,u),n[c.name]=u}const s=e.optimistic?Xn(this.options.state):null;try{let l;for(const c of e.body.body)l=await this.runStatement(c,a,e,n);return this.options.notify(),l}catch(l){throw s&&(Zn(this.options.state,s),this.options.notify()),console.error(`[aktion] action "${e.name}" failed`,l),l}finally{for(const l of i)l.had?a.loopVars.set(l.name,l.prev):a.loopVars.delete(l.name)}}async runStatement(e,r,a,i){switch(e.kind){case"ExpressionStatement":{const n=e.expression;if(n.kind==="JsBlock"){const l=Rt(n.body,a.name,r,this.options,void 0,i);return await qe(l)}const s=M(n,r);return await qe(s)}case"Await":{const n=M(e.argument,r);return await qe(n)}case"Assignment":{const n=await qe(M(e.expression,r));if(e.identifier){const s=ke(r,e.identifier);this.options.state.set(s,n)}return n}case"Return":return e.argument?await qe(M(e.argument,r)):void 0;case"Emit":{const n=M(e.detail,r);this.options.onEmit?.(e.eventName,n);return}default:return}}}async function qe(t){return t&&typeof t.then=="function"?await t:t}function Xn(t){const e=new Map;for(const[r,a]of t.entries())e.set(r,a);return e}function Zn(t,e){for(const[r,a]of e)t.set(r,a)}const Qn="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css",sa="6.7.2",la="data-rui-font-awesome",eo=new Set(["solid","regular","brands"]),ca="solid";function to(t){typeof document<"u"&&ua(document.head,document),ua(t,t.ownerDocument??document)}function ua(t,e){if(ro()||t.querySelector(`link[${la}="${sa}"]`))return;const a=e.createElement("link");a.rel="stylesheet",a.href=Qn,a.setAttribute(la,sa);try{t.appendChild(a)}catch{}}function ro(){return typeof globalThis.happyDOM<"u"}function Lt(t){if(typeof t!="string")return[];const e=io(t).trim();if(!e)return[];if(!oo(e))return[];const[r,a]=no(e);return a?[`fa-${r}`,`fa-${a}`]:[]}const ao=/[\uFE0E\uFE0F\u200D\u200C\uFEFF]/g;function io(t){return t.replace(ao,"")}function no(t){const e=t.indexOf(":");if(e===-1)return[ca,t];const r=t.slice(0,e).trim().toLowerCase(),a=t.slice(e+1).trim();return eo.has(r)?[r,a]:[ca,a||t]}function oo(t){return/^[a-zA-Z0-9:_-]+$/.test(t)}const so=["xs","sm","md","lg","xl"];function o(t,e,r){const a=document.createElement(t);if(e)for(const[i,n]of Object.entries(e))n==null||n===!1||(i==="class"?a.setAttribute("class",String(n)):i==="html"?a.innerHTML=String(n):n===!0?a.setAttribute(i,""):a.setAttribute(i,String(n)));if(r)for(const i of r)i!=null&&a.append(typeof i=="string"?document.createTextNode(i):i);return a}function k(t){return Array.isArray(t)?t:t==null?[]:[t]}function d(t,e=""){return t==null?e:typeof t=="string"?t:String(t)}function C(t,e=!1){return typeof t=="boolean"?t:t==="true"?!0:t==="false"?!1:t==null?e:!!t}function P(t,e=0){if(typeof t=="number")return t;if(typeof t=="string"&&t.trim()!==""){const r=Number(t);if(!Number.isNaN(r))return r}return e}const Le=["base","sm","md","lg","xl"];function se(t){if(t==null||typeof t!="object"||Array.isArray(t))return{kind:"single",value:t??null};const e=Object.entries(t),r={};let a=!1;for(const[i,n]of e)Le.includes(i)&&(r[i]=n,a=!0);return a?{kind:"responsive",values:r}:{kind:"single",value:t}}const lo=/["'\\\n\r<>;{}]/g;function co(t){return t?t.replace(lo,"").trim():""}const uo=/^[a-zA-Z0-9.%+\-*/\s(),]+$/;function ee(t,e){const r=(d(t)??"").trim();return!r||r.length>64||!uo.test(r)?e:r}const po=new Set(["http","https","mailto","tel"]);function rt(t,e="#"){const r=d(t).trim();if(!r)return e;const a=r.replace(/[\u0000-\u001F\u007F]/g,"");if(!a||a.startsWith("//"))return e;if(a.startsWith("#")||a.startsWith("/")||a.startsWith("?")||a.startsWith("."))return a;const i=/^([a-zA-Z][a-zA-Z0-9+.\-]*):/.exec(a);if(!i)return a;const n=i[1].toLowerCase();return po.has(n)?a:e}const mo=new Set(["http","https","data","blob"]);function re(t){const e=d(t).trim();if(!e)return"";const r=e.replace(/[\u0000-\u001F\u007F]/g,"");if(!r||r.startsWith("//"))return"";if(r.startsWith("/")||r.startsWith(".")||r.startsWith("?")||r.startsWith("#"))return r;const a=/^([a-zA-Z][a-zA-Z0-9+.\-]*):/.exec(r);if(!a)return r;const i=a[1].toLowerCase();return!mo.has(i)||i==="data"&&!/^data:image\//i.test(r)?"":r}function L(t,e={}){const r=d(t);if(!r)return null;const a=Lt(r),i=["rui-icon",e.className].filter(Boolean).join(" ");return a.length===0?o("span",{class:i,"data-icon-size":e.size??null},[r]):o("i",{class:`${i} ${a.join(" ")}`,"data-icon-size":e.size??null,"aria-hidden":"true"})}const He=12,go={start:"flex-start",center:"center",end:"flex-end",stretch:"stretch"},fo={start:"flex-start",center:"center",end:"flex-end",between:"space-between",around:"space-around",evenly:"space-evenly"};function ho(t){return go[t]??"stretch"}function bo(t){return fo[t]??"flex-start"}function da(t,e){return e?t==="row"?"row-reverse":t==="column"?"column-reverse":t.endsWith("-reverse")?t:`${t}-reverse`:t}function Se(t,e,r){for(const a of Le){const i=e.values[a];i&&t.push(`${r}-${a}:var(--rui-spacing-${i}, ${i})`)}}function vo(t,e,r,a){for(const i of Le){const n=e.values[i];n&&t.push(`${r}-${i}:${a(String(n))}`)}}function pa(t,e,r,a){const i=se(t);if(i.kind==="single"){const n=i.value?String(i.value):a.defaultToken;r[a.attrName]=n;return}r[a.attrName]="responsive",r[a.responsiveFlag]="true",vo(e,i,a.cssVarPrefix,a.mapper)}function yo(t,e){return!!(t&&typeof t=="object"&&t.__kind==="Component"&&t.name===e)}function xo(t){const e=se(t.direction);return e.kind==="single"?e.value?String(e.value):"column":e.values.base?String(e.values.base):"column"}const wo={name:"StackItem",description:"Wraps a single child in a flex item with explicit grow/shrink/basis, alignment, and order. Use inside `Stack` when the default row flex growth would stretch toolbars, chips, or asymmetric layouts.",props:[{name:"child",type:"Node",description:"Child node to wrap"},{name:"grow",type:"number",optional:!0,description:"flex-grow (0 or 1 typical)"},{name:"shrink",type:"number",optional:!0,description:"flex-shrink (0 or 1 typical)"},{name:"basis",type:"string",optional:!0,description:"flex-basis (`auto`, `0`, or CSS length)"},{name:"alignSelf",type:"string",optional:!0,enum:["start","center","end","stretch"],description:"Per-item cross-axis alignment"},{name:"order",type:"number",optional:!0,description:"Visual order override"},{name:"minWidth",type:"string",optional:!0,description:"CSS min-width"},{name:"maxWidth",type:"string",optional:!0,description:"CSS max-width"}],render:(t,e,r)=>{const a={class:"rui-stack-item"},i=[];e.grow!==void 0&&e.grow!==null&&(a["data-grow"]=String(P(e.grow,0))),e.shrink!==void 0&&e.shrink!==null&&(a["data-shrink"]=String(P(e.shrink,1)));const n=d(e.basis);n==="auto"||n==="0"?a["data-basis"]=n:n&&i.push(`flex-basis:${ee(n,n)}`);const s=d(e.alignSelf);if(s&&(a["data-align-self"]=s),e.order!==void 0&&e.order!==null){const p=P(e.order,0);a["data-order"]=String(p),i.push(`order:${p}`)}const l=d(e.minWidth);l&&i.push(`min-width:${ee(l,l)}`);const c=d(e.maxWidth);c&&i.push(`max-width:${ee(c,c)}`),i.length>0&&(a.style=i.join(";"));const u=o("div",a);return u.append(r.renderNode(e.child)),u}},ko={name:"Stack",description:'Flex container that arranges children in a row or column. `direction`, `gap`, `align`, `justify`, and `padding` accept either a single value OR a responsive map like `{sm: "column", md: "row"}`. Row stacks grow children uniformly by default (`uniform=true`); set `uniform=false` or wrap children in `StackItem` for toolbars and asymmetric rows. Use `reverse` for chat-style column-reverse timelines.',props:[{name:"children",type:"Node[]",description:"Child components to stack"},{name:"direction",type:"string | object",optional:!0,enum:["column","row"],description:"Layout direction (default column). May be a responsive map."},{name:"gap",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Spacing between children. May be a responsive map."},{name:"align",type:"string | object",optional:!0,enum:["start","center","end","stretch"],description:"Cross-axis alignment. May be a responsive map."},{name:"justify",type:"string | object",optional:!0,enum:["start","center","end","between","around","evenly"],description:"Main-axis alignment. May be a responsive map."},{name:"alignContent",type:"string",optional:!0,enum:["start","center","end","between","around","stretch"],description:"Multi-line wrap alignment"},{name:"wrap",type:"boolean",optional:!0,description:"Allow wrapping"},{name:"reverse",type:"boolean",optional:!0,description:"Reverse main-axis order (column-reverse / row-reverse)"},{name:"uniform",type:"boolean",optional:!0,description:"Row children share space equally (default true for row stacks)"},{name:"inline",type:"boolean",optional:!0,description:"Use inline-flex instead of flex"},{name:"padding",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Inner padding token. May be a responsive map."}],render:(t,e,r)=>{const a=se(e.direction),i=se(e.gap),n=se(e.padding),s=C(e.reverse),c=xo(e)==="row",u=e.uniform===void 0?c:C(e.uniform,c),p={class:"rui-stack","data-wrap":C(e.wrap)?"true":null,"data-reverse":s?"true":null,"data-uniform":u?"true":"false","data-inline":C(e.inline)?"true":null},m=[];if(a.kind==="single"){const h=a.value?String(a.value):"column";p["data-direction"]=da(h,s)}else{p["data-direction"]="responsive",p["data-responsive-dir"]="true";for(const h of Le){const b=a.values[h];b&&m.push(`--rui-stack-dir-${h}:${da(String(b),s)}`)}}i.kind==="single"?p["data-gap"]=i.value?String(i.value):"m":(p["data-gap"]="responsive",p["data-responsive-gap"]="true",Se(m,i,"--rui-stack-gap")),pa(e.align,m,p,{attrName:"data-align",responsiveFlag:"data-responsive-align",cssVarPrefix:"--rui-stack-align",defaultToken:"stretch",mapper:ho}),pa(e.justify,m,p,{attrName:"data-justify",responsiveFlag:"data-responsive-justify",cssVarPrefix:"--rui-stack-justify",defaultToken:"start",mapper:bo});const g=d(e.alignContent);if(g&&(p["data-align-content"]=g),n.kind==="single"){const h=n.value?String(n.value):null;h&&(p["data-padding"]=h)}else p["data-padding"]="responsive",p["data-responsive-padding"]="true",Se(m,n,"--rui-stack-padding");m.length>0&&(p.style=m.join(";"));const f=o("div",p);for(const h of k(e.children))f.append(r.renderNode(h));return f}},So={name:"Card",description:"Vertical card container.",props:[{name:"children",type:"Node[]",description:"Card contents"},{name:"variant",type:"string",optional:!0,enum:["default","outlined","elevated"]}],render:(t,e,r)=>{const a=o("div",{class:"rui-card","data-variant":d(e.variant,"default")});for(const i of k(e.children))a.append(r.renderNode(i));return a}},Co={name:"CardHeader",description:"Card header with title and optional subtitle.",props:[{name:"title",type:"string"},{name:"subtitle",type:"string",optional:!0}],render:(t,e)=>{const r=o("header",{class:"rui-card-header"});r.append(o("h3",{class:"rui-card-title"},[d(e.title)]));const a=d(e.subtitle);return a&&r.append(o("p",{class:"rui-card-subtitle"},[a])),r}},To={name:"CardFooter",description:"Card footer for actions.",props:[{name:"children",type:"Node[]"}],render:(t,e,r)=>{const a=o("footer",{class:"rui-card-footer"});for(const i of k(e.children))a.append(r.renderNode(i));return a}},$o={name:"Separator",description:"Visual divider between content sections. Supports horizontal or vertical orientation, and an optional center `label` (lifted from the legacy `Divider`). Use `decorative=false` to expose the separator to assistive tech.",props:[{name:"orientation",type:"string",optional:!0,enum:["horizontal","vertical"]},{name:"label",type:"string",optional:!0,description:"Optional label rendered in the middle (horizontal only)"},{name:"decorative",type:"boolean",optional:!0,description:"Hides the separator from assistive tech when true (default)"}],render:(t,e)=>{const r=d(e.orientation,"horizontal"),a=C(e.decorative,!0),i=d(e.label);return i&&r==="horizontal"?o("div",{class:"rui-separator rui-separator-with-label","data-orientation":r,role:a?"presentation":"separator","aria-orientation":a?null:r},[o("span",{class:"rui-separator-line"}),o("span",{class:"rui-separator-label"},[i]),o("span",{class:"rui-separator-line"})]):o("div",{class:"rui-separator","data-orientation":r,role:a?"presentation":"separator","aria-orientation":a?null:r})}},ma=(t,e,r=!1)=>{const a=o("li",{class:"rui-steps-item","data-active":r?"true":"false"});return a.append(o("div",{class:"rui-steps-title"},[t])),e&&a.append(o("div",{class:"rui-steps-details"},[e])),a},No={name:"Steps",description:"Numbered step-by-step guide. Pass items as `{title, details?, active?}` objects. Use `active` to mark the current step in a multi-step flow.",props:[{name:"items",type:"object[]"}],render:(t,e,r)=>{const a=o("ol",{class:"rui-steps"});for(const i of k(e.items)){if(i&&typeof i=="object"&&i.__kind==="Component"){a.append(r.renderNode(i));continue}if(i&&typeof i=="object"){const n=i;a.append(ma(d(n.title),d(n.details),C(n.active)));continue}a.append(ma(d(i),""))}return a}},Ao={name:"TabItem",description:"Single tab definition (used inside Tabs). Add `badge` for a count chip in the tab trigger, and `icon` for a leading Font Awesome icon.",props:[{name:"value",type:"string",description:"Stable identifier for the tab"},{name:"label",type:"string",description:"Display label"},{name:"children",type:"Node[]",description:"Tab content"},{name:"badge",type:"string",optional:!0,description:"Trailing chip rendered in the tab trigger (count / status)"},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name shown before the label"}],render:(t,e,r)=>{const a=o("div",{class:"rui-tab-content",role:"tabpanel","data-value":d(e.value),"data-active":"false"});for(const i of k(e.children))a.append(r.renderNode(i));return a}},Mo={name:"Tabs",description:'Tabbed container. Children must be TabItem components. Supports `orientation="vertical"` for sidebar-style tabs and built-in keyboard navigation (←/→ or ↑/↓, Home, End).',props:[{name:"items",type:"TabItem[]",description:"Tab definitions"},{name:"defaultValue",type:"string",optional:!0,description:"Initially active tab value"},{name:"orientation",type:"string",optional:!0,enum:["horizontal","vertical"],description:"Layout direction (default `horizontal`)"}],render:(t,e,r)=>{const a=k(e.items),i=d(e.orientation,"horizontal"),n=o("div",{class:"rui-tabs","data-orientation":i}),s=o("div",{class:"rui-tab-list",role:"tablist","aria-orientation":i}),l=o("div",{class:"rui-tab-panels"});let c=d(e.defaultValue);if(!c&&a.length>0){const g=a[0];c=d(g?.args?.[0],"tab-0")}const u=r.useInstanceState("activeTab",c);d(e.defaultValue)&&d(e.defaultValue)!==c&&u.set(d(e.defaultValue)),new Set(a.map((g,f)=>d(g.args?.[0],`tab-${f}`))).has(u.get())||u.set(c);const m=(g,f)=>{u.set(g);const h=f.closest(".rui-tabs");h&&(h.querySelectorAll(".rui-tab-trigger").forEach(b=>{const v=b.getAttribute("data-value")===g;b.setAttribute("aria-selected",v?"true":"false"),b.tabIndex=v?0:-1}),h.querySelectorAll(".rui-tab-content").forEach(b=>{b.setAttribute("data-active",b.getAttribute("data-value")===g?"true":"false")}))};return a.forEach((g,f)=>{const h=g,b=d(h.args?.[0],`tab-${f}`),v=d(h.args?.[1],`Tab ${f+1}`),y=d(h.args?.[3]),x=d(h.args?.[4]),w=b===u.get(),T=o("button",{class:"rui-tab-trigger",role:"tab",type:"button","data-value":b,"aria-selected":w?"true":"false",tabindex:w?"0":"-1"}),S=x?Po(x):null;S&&T.append(S),T.append(o("span",{class:"rui-tab-trigger-label"},[v])),y&&T.append(o("span",{class:"rui-tab-trigger-badge"},[y])),T.onclick=$=>{const A=$.currentTarget??$.target;m(b,A)},T.onkeydown=$=>{const A=$,z=i!=="vertical",R=z?A.key==="ArrowRight":A.key==="ArrowDown",_=z?A.key==="ArrowLeft":A.key==="ArrowUp";if(!R&&!_&&A.key!=="Home"&&A.key!=="End")return;A.preventDefault();const Q=A.currentTarget??A.target,B=Q.closest(".rui-tab-list");if(!B)return;const O=Array.from(B.querySelectorAll(".rui-tab-trigger"));if(O.length===0)return;const J=O.indexOf(Q);let X=J;A.key==="Home"?X=0:A.key==="End"?X=O.length-1:R?X=(J+1)%O.length:_&&(X=(J-1+O.length)%O.length);const ue=O[X];if(!ue)return;ue.focus();const me=ue.getAttribute("data-value")??"";me&&m(me,ue)},s.append(T);const N=r.renderNode(g);N.setAttribute("data-value",b),N.setAttribute("data-active",w?"true":"false"),l.append(N)}),n.append(s,l),n}};function Po(t){return L(t,{className:"rui-tab-trigger-icon"})}const Io={name:"AccordionItem",description:"Single accordion section.",props:[{name:"title",type:"string"},{name:"children",type:"Node[]"},{name:"open",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=o("details",{class:"rui-accordion-item"});C(e.open)&&a.setAttribute("open","");const i=o("summary",{class:"rui-accordion-trigger"},[d(e.title)]);a.append(i);const n=o("div",{class:"rui-accordion-body"});for(const s of k(e.children))n.append(r.renderNode(s));return a.append(n),a}},zo={name:"Accordion",description:"Accordion container. Children must be AccordionItem components.",props:[{name:"items",type:"AccordionItem[]"}],render:(t,e,r)=>{const a=o("div",{class:"rui-accordion"});for(const i of k(e.items))a.append(r.renderNode(i));return a}},at=t=>Math.max(1,Math.min(He,Math.round(t)));function Et(t){if(t==null||t==="")return 12;const e=String(t).trim();if(e.includes("/")){const[r,a]=e.split("/"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n>0)return at(Math.round(He*i/n))}return e==="auto"||e==="fit"||e==="auto-fit"||e==="full"||e==="100%"?12:at(P(t,12))}function Ro(t){const e=d(t.minChildWidth)||d(t.minItemWidth);return ee(e||"220px","220px")}const Lo={name:"GridItem",description:'Wraps a child in a 12-column grid cell with `span`, `offset`, and responsive `spanAt` maps. Parent `Grid` auto-enables 12-column mode when any child is a `GridItem`. Fraction spans like `"1/3"` resolve against the 12-column track.',props:[{name:"child",type:"Node",description:"Child node to place in the grid"},{name:"span",type:"number | string",optional:!0,description:'Columns to span (1–12) or fraction like "1/2", "1/3"'},{name:"offset",type:"number",optional:!0,description:"Empty columns before this item (0–11)"},{name:"spanAt",type:"object",optional:!0,description:"Responsive span map `{sm: 12, md: 6, lg: 4}`"}],render:(t,e,r)=>{const a=Et(e.span??12),i=se(e.spanAt),n=e.offset===void 0||e.offset===null?0:Math.max(0,Math.min(He-1,Math.round(P(e.offset,0)))),s={class:"rui-grid-item","data-span":String(a)},l=[`--rui-grid-item-span:${a}`];if(n>0&&(s["data-offset"]=String(n),l.push(`--rui-grid-item-offset:${n}`)),i.kind==="responsive"){s["data-responsive-span"]="true";for(const u of Le){const p=i.values[u];if(p!==void 0){const m=Et(p);l.push(`--rui-grid-item-span-${u}:${m}`)}}}else if(i.kind==="single"&&i.value!=null){const u=Et(i.value);l.push(`--rui-grid-item-span:${u}`),s["data-span"]=String(u)}s.style=l.join(";");const c=o("div",s);return c.append(r.renderNode(e.child)),c}},Eo={name:"Box",description:"Spacing and surface wrapper for padding, margin, borders, semantic backgrounds, and max-width constraints. Use when a `Card` is too heavy but the content needs a subtle surface or inset.",props:[{name:"children",type:"Node[]"},{name:"padding",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Inner padding. May be a responsive map."},{name:"margin",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Outer margin. May be a responsive map."},{name:"border",type:"string",optional:!0,enum:["none","subtle","default"],description:"Border preset (default none)"},{name:"background",type:"string",optional:!0,enum:["none","surface","muted","primary","success","warning","danger","info"],description:"Semantic background token"},{name:"maxWidth",type:"string",optional:!0,description:"CSS max-width"}],render:(t,e,r)=>{const a=se(e.padding),i=se(e.margin),n={class:"rui-box","data-border":d(e.border,"none"),"data-background":d(e.background,"none")},s=[],l=d(e.maxWidth);if(l&&s.push(`max-width:${ee(l,l)}`),a.kind==="single"){const u=a.value?String(a.value):null;u&&(n["data-padding"]=u)}else n["data-padding"]="responsive",n["data-responsive-padding"]="true",Se(s,a,"--rui-box-padding");if(i.kind==="single"){const u=i.value?String(i.value):null;u&&(n["data-margin"]=u)}else n["data-margin"]="responsive",n["data-responsive-margin"]="true",Se(s,i,"--rui-box-margin");s.length>0&&(n.style=s.join(";"));const c=o("div",n);for(const u of k(e.children))c.append(r.renderNode(u));return c}},ga={name:"Grid",description:'Responsive CSS grid. Use for KPI strips, feature blocks, card grids, and asymmetric layouts with `GridItem` spans. Set `columns: 12` (or include `GridItem` children) for a 12-column track system with fractional spans like `"1/3"`. `columns` and `gap` accept responsive maps like `{sm: 1, md: 2, lg: 4}`.',props:[{name:"children",type:"Node[]"},{name:"columns",type:"number | object",optional:!0,description:"Target column count 1–12 (default auto-fit). `12` enables 12-column mode. May be a responsive map."},{name:"gap",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Gap size (both axes). May be a responsive map."},{name:"rowGap",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Row gap override. May be a responsive map."},{name:"columnGap",type:"string | object",optional:!0,enum:["xs","s","m","l","xl"],description:"Column gap override. May be a responsive map."},{name:"minItemWidth",type:"string",optional:!0,description:"CSS min width for auto-fit fallback (alias: minChildWidth)"},{name:"minChildWidth",type:"string",optional:!0,description:"CSS min child width; also applies when `columns` is set"},{name:"alignItems",type:"string",optional:!0,enum:["start","center","end","stretch"],description:"Align items inside grid cells"},{name:"justifyItems",type:"string",optional:!0,enum:["start","center","end","stretch"],description:"Justify items inside grid cells"},{name:"dense",type:"boolean",optional:!0,description:"Use dense auto-flow packing"}],render:(t,e,r)=>{const a=k(e.children),i=a.some(v=>yo(v,"GridItem")),n=se(e.columns),s=se(e.gap),l=se(e.rowGap),c=se(e.columnGap),u={class:"rui-grid"},p=[];let m=!1,g=!1;if(n.kind==="single"){const v=n.value===null?0:P(n.value,0),y=v>0?at(v):0;if(y===He?m=!0:y>0&&(g=!0),y>0){u["data-columns"]=String(y);const x=d(e.minChildWidth)||d(e.minItemWidth);x&&(u["data-min-child-width"]="true",p.push(`--rui-grid-min-child:${ee(x,"220px")}`))}else p.push(`--rui-grid-min-item:${Ro(e)}`)}else{u["data-responsive-cols"]="true";for(const v of Le){const y=n.values[v];if(y===void 0)continue;const x=at(P(y,0));x===He?m=!0:x>0&&(g=!0),p.push(`--rui-grid-cols-${v}:${x}`)}}i&&!g&&(m=!0),m&&(u["data-grid-mode"]="12"),s.kind==="single"?u["data-gap"]=s.value?String(s.value):"m":(u["data-gap"]="responsive",u["data-responsive-gap"]="true",Se(p,s,"--rui-grid-gap")),l.kind==="single"&&l.value?u["data-row-gap"]=String(l.value):l.kind==="responsive"&&(u["data-row-gap"]="responsive",u["data-responsive-row-gap"]="true",Se(p,l,"--rui-grid-row-gap")),c.kind==="single"&&c.value?u["data-column-gap"]=String(c.value):c.kind==="responsive"&&(u["data-column-gap"]="responsive",u["data-responsive-column-gap"]="true",Se(p,c,"--rui-grid-column-gap"));const f=d(e.alignItems);f&&(u["data-align-items"]=f);const h=d(e.justifyItems);h&&(u["data-justify-items"]=h),C(e.dense)&&(u["data-dense"]="true"),p.length>0&&(u.style=p.join(";"));const b=o("div",u);for(const v of a)b.append(r.renderNode(v));return b}},_o={name:"AspectRatio",description:"Container that constrains its child to a fixed aspect ratio (e.g. 16:9 for video embeds, 1:1 for thumbnails). The child fills the box.",props:[{name:"ratio",type:"string",description:"`width:height` (e.g. `16:9`, `4:3`) or a decimal like `1.78`"},{name:"children",type:"Node[]"}],render:(t,e,r)=>{const a=jo(d(e.ratio,"16:9")),i=o("div",{class:"rui-aspect-ratio",style:`aspect-ratio:${a};`});for(const n of k(e.children))i.append(r.renderNode(n));return i}};function jo(t){if(t.includes(":")){const[r,a]=t.split(":"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n!==0)return`${i} / ${n}`}const e=Number(t);return Number.isFinite(e)&&e>0?`${e} / 1`:"16 / 9"}const Bo={name:"ScrollArea",description:"Bounded scroll container. Use to clip long lists / logs / chat panels to a fixed max height with a clean scrollbar.",props:[{name:"children",type:"Node[]"},{name:"maxHeight",type:"string",optional:!0,aliases:["height"],description:"CSS height (default 320px)"},{name:"direction",type:"string",optional:!0,enum:["vertical","horizontal","both"]}],render:(t,e,r)=>{const a=o("div",{class:"rui-scroll-area","data-direction":d(e.direction,"vertical"),style:`max-height:${ee(e.maxHeight,"320px")};`});for(const i of k(e.children))a.append(r.renderNode(i));return a}},Do={name:"Modal",description:"Dialog overlay shown when `open` is true. Pass a `$variable` as `open` to control it. The header always renders a × close button (disable via `closable: false`); the optional `footer` slot is the canonical place for action buttons. `closeOnBackdrop=true` opts in to backdrop-click dismissal.",props:[{name:"title",type:"string"},{name:"open",type:"boolean",description:"Open/closed state — usually a $variable"},{name:"children",type:"Node[]"},{name:"size",type:"string",optional:!0,enum:["sm","md","lg","xl","full"],description:"Width preset (default `md`)"},{name:"footer",type:"Node[]",optional:!0,description:"Footer slot — typically a row of action Buttons"},{name:"closable",type:"boolean",optional:!0,description:"Render the header × button (default true)"},{name:"closeOnBackdrop",type:"boolean",optional:!0,description:"Close when the overlay is clicked (default false)"}],render:(t,e,r)=>{const a=d(e.size,"md"),i=e.closable===void 0?!0:C(e.closable),n=o("div",{class:"rui-modal-overlay","data-open":C(e.open)?"true":"false"}),s=o("div",{class:"rui-modal",role:"dialog","aria-modal":"true","data-size":a}),l=o("header",{class:"rui-modal-header"});l.append(o("h3",{class:"rui-modal-title"},[d(e.title)]));const c=t.argMeta?.[1]?.stateRef,u=()=>{c&&r.setState(c,!1)};if(i){const g=o("button",{type:"button",class:"rui-modal-close","aria-label":"Close dialog"},["×"]);g.onclick=f=>{f.stopPropagation(),u()},l.append(g)}s.append(l);const p=o("div",{class:"rui-modal-body"});for(const g of k(e.children))p.append(r.renderNode(g));s.append(p);const m=k(e.footer);if(m.length>0){const g=o("footer",{class:"rui-modal-footer"});for(const f of m)g.append(r.renderNode(f));s.append(g)}return n.append(s),C(e.closeOnBackdrop)&&c&&(n.onclick=g=>{g.target===n&&u()}),n}},Fo=["solid","regular","brands"],it=["xs","sm","md","lg","xl"],Oo=["default","neutral","primary","success","warning","danger","info"];function _t(t,e="md"){const r=d(t).trim().toLowerCase();return r?r==="small"?"sm":r==="normal"?"md":r==="large"?"lg":it.includes(r)?r:e:e}const Uo={name:"Icon",description:'Single Font Awesome icon. `name` is the FA name without the `fa-` prefix (e.g. `"house"`, `"chart-line"`). Use `variant` for non-solid styles (`regular`/`brands`) or prefix the name (`"regular:star"`).',props:[{name:"name",type:"string",description:"FA name without the fa- prefix"},{name:"variant",type:"string",optional:!0,enum:Fo},{name:"size",type:"string",optional:!0,enum:so}],render:(t,e)=>{const r=d(e.name),a=d(e.variant,""),i=d(e.size,"md"),n=a?`${a}:${r}`:r,s=L(n,{size:i});return s||o("span",{class:"rui-icon","data-icon-size":i},[r])}},qo=["small","small-heavy","body","body-heavy","large","large-heavy","heading","title"];function Ho(t){const e=d(t).trim();return!e||/[<>]/.test(e)||/\bexpression\s*\(|\bjavascript\s*:|\bbehavior\s*:|@import\b/i.test(e)?"":e}const fa=[{name:"value",type:"string"},{name:"variant",type:"string",optional:!0,enum:qo},{name:"tone",type:"string",optional:!0,enum:["default","muted","primary","success","warning","danger"],description:"Visual accent"},{name:"style",type:"string",optional:!0,description:'Inline CSS declarations applied to the rendered element (e.g. "font-size: 16px; font-weight: bold; color: #000;").'}],ha=(t,e)=>{const r=d(e.variant,"body"),a=d(e.tone,"default"),i=Ho(e.style);return o("span",{class:"rui-text","data-variant":r,"data-color":a,style:i||null},[d(e.value)])},Vo={name:"Text",description:'Renders plain text with a typographic variant. Optional `style` prop accepts a CSS declaration string (e.g. "font-size: 16px; color: #000;") applied directly to the rendered element.',props:fa,render:ha},Wo={name:"TextContent",description:"Deprecated alias for `Text`. Prefer `Text(...)` — both render identically.",props:fa,render:ha},Go={name:"Image",description:"Inline image. `ratio` constrains the box to a fixed aspect ratio (e.g. `16:9`, `1:1`) so callers do not need an outer `AspectRatio`. `fit` controls how the image fills that box. When `src` is missing or unsafe the component renders a placeholder (or `fallback` text/icon).",props:[{name:"src",type:"string"},{name:"alt",type:"string",optional:!0},{name:"caption",type:"string",optional:!0},{name:"ratio",type:"string",optional:!0,description:"Aspect ratio shorthand (e.g. `16:9`, `1:1`, `4:3`)"},{name:"fit",type:"string",optional:!0,enum:["cover","contain","fill","none","scale-down"],description:"object-fit value (default `cover`)"},{name:"fallback",type:"string",optional:!0,description:"Text label or Font Awesome icon shown when src is missing/unsafe"}],render:(t,e)=>{const r=o("figure",{class:"rui-image","data-fit":d(e.fit,"cover"),style:e.ratio?`aspect-ratio:${Ko(d(e.ratio))};`:null}),a=re(e.src);if(a)r.append(o("img",{src:a,alt:d(e.alt),loading:"lazy"}));else{const n=o("div",{class:"rui-image-placeholder",role:"presentation","aria-hidden":"true"}),s=d(e.fallback);if(s){const l=L(s,{className:"rui-image-fallback-icon"});l?n.append(l):n.append(o("span",{class:"rui-image-fallback-text"},[s]))}r.append(n)}const i=d(e.caption);return i&&r.append(o("figcaption",{class:"rui-image-caption"},[i])),r}};function Ko(t){if(!t)return"auto";if(t.includes(":")){const[r,a]=t.split(":"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n>0)return`${i} / ${n}`}const e=Number(t);return Number.isFinite(e)&&e>0?`${e} / 1`:"auto"}const Yo={name:"Link",description:"Anchor link.",props:[{name:"label",type:"string"},{name:"href",type:"string"},{name:"external",type:"boolean",optional:!0}],render:(t,e)=>{const r=C(e.external),a=rt(e.href,"#");return o("a",{class:"rui-link",href:a,target:r?"_blank":null,rel:r?"noopener noreferrer":null},[d(e.label)])}},ba=["neutral","primary","success","warning","danger","info"],Jo={name:"Badge",description:"Small pill-style tag for status, counts, categories. Accepts an optional leading `icon` and a `size`.",props:[{name:"label",type:"string",positional:!0},{name:"tone",type:"string",optional:!0,enum:ba,aliases:["variant"],description:"Visual tone"},{name:"icon",type:"string",optional:!0,description:'Optional Font Awesome icon name (e.g. "star")'},{name:"size",type:"string",optional:!0,enum:it}],render:(t,e)=>{const r=d(e.tone,"neutral"),a=_t(e.size,"md"),i=o("span",{class:"rui-badge","data-variant":r,"data-size":a}),n=L(e.icon,{className:"rui-badge-icon"});n&&i.append(n);const s=d(e.label);return s&&i.append(o("span",{class:"rui-badge-label"},[s])),i}},Xo={name:"BadgeList",description:"Cluster of Badge pills rendered from an array of strings.",props:[{name:"labels",type:"string[]",positional:!0,description:"Array of badge labels"},{name:"tone",type:"string",optional:!0,enum:ba,aliases:["variant"]},{name:"size",type:"string",optional:!0,enum:it}],render:(t,e)=>{const r=d(e.tone,"neutral"),a=_t(e.size,"md"),i=o("div",{class:"rui-badge-list"});for(const n of k(e.labels)){const s=d(n);if(!s)continue;const l=o("span",{class:"rui-badge","data-variant":r,"data-size":a});l.append(o("span",{class:"rui-badge-label"},[s])),i.append(l)}return i}},Zo={name:"Callout",description:"Highlighted callout banner with variant, title, description, and leading icon. Pass `compact: true` for a one-line inline-note rendering.",props:[{name:"tone",type:"string",optional:!0,enum:["neutral","info","success","warning","danger","error"],aliases:["variant"]},{name:"title",type:"string",positional:!0,required:!0},{name:"description",type:"string",optional:!0,aliases:["text"],description:"Body text"},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name"},{name:"compact",type:"boolean",optional:!0,description:"Render with the dense, one-line note shape."}],render:(t,e)=>{const r=d(e.tone,"info"),a=C(e.compact),i=o("div",{class:"rui-callout","data-variant":r,"data-compact":a?"true":"false"}),n=d(e.icon)||ts(r),s=L(n,{className:"rui-callout-icon"});s&&i.append(s);const l=o("div",{class:"rui-callout-body"});l.append(o("div",{class:"rui-callout-title"},[d(e.title)]));const c=d(e.description);return c&&l.append(o("div",{class:"rui-callout-description"},[c])),i.append(l),i}},Qo={name:"CodeBlock",description:'Read-only code block with a language label and a copy-to-clipboard button. Pass `showLineNumbers=true` to render a gutter; `highlightLines` accepts a string like `"3-5,8"` to emphasise specific lines.',props:[{name:"language",type:"string",optional:!0,description:"Display label (e.g. ts, bash)"},{name:"codeString",type:"string",positional:!0,required:!0,aliases:["code"],description:"Raw source text"},{name:"showLineNumbers",type:"boolean",optional:!0,description:"Render a left-side line-number gutter"},{name:"highlightLines",type:"string",optional:!0,aliases:["highlight"],description:'Highlight ranges, e.g. "3-5,8"'},{name:"copy",type:"boolean",optional:!0,description:"Show the copy-to-clipboard button (default true)"}],render:(t,e)=>{const r=d(e.language),a=d(e.codeString),i=C(e.showLineNumbers),n=es(d(e.highlightLines)),s=e.copy===void 0?!0:C(e.copy),l=o("div",{class:"rui-code-block"});if(r||s){const u=o("div",{class:"rui-code-block-head"});if(r&&u.append(o("span",{class:"rui-code-block-language"},[r])),s){const p=o("button",{type:"button",class:"rui-code-block-copy","aria-label":"Copy code",title:"Copy"}),m=L("copy",{className:"rui-code-block-copy-icon"});m&&p.append(m),p.append(o("span",{class:"rui-code-block-copy-label"},["Copy"])),p.onclick=g=>{const f=g.currentTarget??g.target,b=f.closest(".rui-code-block")?.querySelector("code")?.textContent??a,y=(typeof navigator<"u"?navigator:null)?.clipboard;y?.writeText&&y.writeText(b).catch(()=>{});const x=f.querySelector(".rui-code-block-copy-label");if(x){const w=x.textContent??"Copy";x.textContent="Copied",setTimeout(()=>{x.textContent=w},1500)}},u.append(p)}l.append(u)}const c=o("pre",{class:"rui-code-block-pre","data-line-numbers":i?"true":"false"});if(i||n.size>0){const u=a.split(/\r?\n/),p=o("code",{});u.forEach((m,g)=>{const f=g+1,h=o("span",{class:"rui-code-block-line","data-line":String(f),"data-highlight":n.has(f)?"true":null});i&&h.append(o("span",{class:"rui-code-block-gutter"},[String(f)])),h.append(o("span",{class:"rui-code-block-code"},[m])),p.append(h)}),c.append(p)}else c.append(o("code",{},[a]));return l.append(c),l}};function es(t){const e=new Set;if(!t)return e;for(const r of t.split(",")){const a=r.trim();if(a)if(a.includes("-")){const i=a.split("-").map(l=>Number(l.trim())),n=i[0]??NaN,s=i[1]??NaN;if(Number.isFinite(n)&&Number.isFinite(s)&&n<=s)for(let l=n;l<=s;l+=1)e.add(l)}else{const i=Number(a);Number.isFinite(i)&&e.add(i)}}return e}function ts(t){switch(t){case"success":return"circle-check";case"warning":return"triangle-exclamation";case"danger":case"error":return"circle-xmark";case"info":return"circle-info";default:return"circle-info"}}const rs={name:"Skeleton",description:"Loading placeholder. Pass a `variant` for common shapes — `paragraph` (default), `card`, `table-row`, `avatar`, `image` — or use `shape` / `width` / `height` to build a custom one. All variants use a shimmer animation that respects `prefers-reduced-motion`.",props:[{name:"variant",type:"string",optional:!0,enum:["paragraph","card","table-row","avatar","image"]},{name:"lines",type:"number",optional:!0,aliases:["count"],description:"Lines for the `paragraph` variant (default 3)"},{name:"height",type:"number | string",optional:!0,description:"Line height in px (paragraph) or CSS height for custom shape"},{name:"shape",type:"string",optional:!0,enum:["rect","circle"],description:"Force a primitive shape (rect/circle)"},{name:"width",type:"string",optional:!0,description:"CSS width for shape-only skeletons"}],render:(t,e)=>{const r=d(e.variant),a=d(e.shape);if(a)return as(a,e);if(r&&r!=="paragraph")return is(r,e);const i=Number(e.lines),n=Math.max(1,Math.min(50,Number.isFinite(i)?Math.floor(i):3)),s=Number(e.height),l=Number.isFinite(s)&&s>0?Math.min(200,Math.floor(s)):12,c=o("div",{class:"rui-skeleton","data-variant":"paragraph"});for(let u=0;u<n;u+=1)c.append(o("div",{class:"rui-skeleton-line",style:`height:${l}px`}));return c}};function as(t,e){const r=ee(d(e.width),"100%"),a=d(e.height),i=a?ee(a,"16px"):t==="circle"?r:"16px";return o("div",{class:"rui-skeleton","data-variant":"shape","data-shape":t==="circle"?"circle":"rect",style:`width:${r};height:${i};`})}function is(t,e){const r=o("div",{class:"rui-skeleton","data-variant":t});switch(t){case"avatar":{const a=ee(d(e.width),"40px");return r.append(o("div",{class:"rui-skeleton-shape","data-shape":"circle",style:`width:${a};height:${a};`})),r}case"image":{const a=ee(d(e.width),"100%"),i=ee(d(e.height),"160px");return r.append(o("div",{class:"rui-skeleton-shape","data-shape":"rect",style:`width:${a};height:${i};`})),r}case"card":return r.append(o("div",{class:"rui-skeleton-shape","data-shape":"rect",style:"width:100%;height:120px;"})),r.append(o("div",{class:"rui-skeleton-line",style:"height:14px;width:70%;"})),r.append(o("div",{class:"rui-skeleton-line",style:"height:12px;width:90%;"})),r.append(o("div",{class:"rui-skeleton-line",style:"height:12px;width:60%;"})),r;case"table-row":{const a=Math.max(1,Math.min(8,Math.floor(Number(e.lines??4)))),i=o("div",{class:"rui-skeleton-row"});for(let n=0;n<a;n+=1)i.append(o("div",{class:"rui-skeleton-line",style:"height:12px;flex:1;"}));return r.append(i),r}default:return r}}const ns={name:"Markdown",description:"Render markdown-flavoured text. Supports **bold**, *italic*, `code`, headings (`#`/`##`/`###`), blockquotes (`>`), bullet (`-`/`*`) and numbered (`1.`) lists, fenced code blocks (```), images (`![alt](src)`), inline links, and auto-linked bare URLs. Multi-line paragraphs collapse into `<p>` blocks.",props:[{name:"content",type:"string"}],render:(t,e)=>{const r=d(e.content),a=us(r);return o("div",{class:"rui-markdown",html:a})}},os={name:"Container",description:"Centered, max-width content wrapper. Use when a page is wider than comfortable reading width — landing pages, marketing sections, long documents. Picks a sensible default max-width per size; pass `maxWidth` to override with any CSS value.",props:[{name:"children",type:"Node[]"},{name:"size",type:"string",optional:!0,enum:["sm","md","lg","xl","full"],description:"sm=640 / md=820 / lg=1040 / xl=1280 / full=100% (default lg)"},{name:"maxWidth",type:"string",optional:!0,description:"Custom CSS max-width (overrides `size`)"},{name:"padding",type:"string",optional:!0,enum:["none","s","m","l"],description:"Horizontal padding (default m)"}],render:(t,e,r)=>{const a=o("div",{class:"rui-container","data-size":d(e.size,"lg"),"data-padding":d(e.padding,"m"),style:e.maxWidth?`max-width:${ee(e.maxWidth,"auto")};`:null});for(const i of k(e.children))a.append(r.renderNode(i));return a}},ss={name:"Spacer",description:'Explicit space element for fine layout control. By default acts as a flex spacer that pushes following content to the far edge (use inside `Stack(direction="row")`). Pass `size` to render a fixed vertical/horizontal gap instead.',props:[{name:"size",type:"string",optional:!0,enum:["xs","s","m","l","xl"],description:"Fixed gap; omit to flex-grow"},{name:"flex",type:"boolean",optional:!0,description:"Flex-grow even when size is set (default true when size omitted)"}],render:(t,e)=>{const r=d(e.size),a=e.flex===void 0?!r:C(e.flex);return o("span",{class:"rui-spacer","data-size":r||null,"data-flex":a?"true":"false","aria-hidden":"true"})}},ls={name:"Spinner",description:"Indeterminate inline loader. Use for tiny loading states inside buttons, toolbars, table cells, or chat bubbles where `Skeleton` and `Progress(indeterminate=true)` are too heavy. Pass `label` to render an inline caption beside the spinner (also announced via `aria-label`).",props:[{name:"size",type:"string",optional:!0,enum:it,description:"Default `md`"},{name:"label",type:"string",optional:!0,description:"Caption rendered beside the spinner (also announced)"},{name:"tone",type:"string",optional:!0,enum:Oo,description:"Visual accent (default `primary`)"}],render:(t,e)=>{const r=_t(e.size,"md"),a=d(e.tone,"primary"),i=d(e.label),n=o("span",{class:"rui-spinner","data-size":r,"data-tone":a,role:"status","aria-live":"polite","aria-label":i||"Loading"});return n.append(o("span",{class:"rui-spinner-ring","aria-hidden":"true"})),i&&n.append(o("span",{class:"rui-spinner-label"},[i])),n}},cs={name:"Quote",description:"Inline pull-quote with optional citation. Lighter than `Testimonial` — use inside articles, blog posts, marketing sections, or anywhere you need to highlight a sentence without the full quote/author/role + rating shape.",props:[{name:"text",type:"string"},{name:"cite",type:"string",optional:!0,aliases:["attribution","author"],description:"Attribution text shown below the quote"},{name:"tone",type:"string",optional:!0,enum:["default","primary","success","warning","danger","info"]}],render:(t,e)=>{const r=o("figure",{class:"rui-quote","data-tone":d(e.tone,"default")});r.append(o("blockquote",{class:"rui-quote-text"},[d(e.text)]));const a=d(e.cite);return a&&r.append(o("figcaption",{class:"rui-quote-cite"},[a])),r}};function us(t){const e=f=>f.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),r=t.split(/\r?\n/),a=[];let i=null,n=!1,s=!1,l="",c=[];const u=()=>{i&&(a.push(i==="ul"?"</ul>":"</ol>"),i=null)},p=()=>{n&&(a.push("</blockquote>"),n=!1)},m=()=>{const f=l?` data-language="${e(l)}"`:"";a.push(`<pre class="rui-markdown-code"${f}><code>${e(c.join(`
20
+ `))}</code></pre>`),c=[],l="",s=!1};for(const f of r){const h=/^```\s*(.*)$/.exec(f.trim());if(s){if(h){m();continue}c.push(f);continue}if(h){u(),p(),s=!0,l=h[1]??"";continue}const b=/^\s*(#{1,3})\s+(.+)$/.exec(f);if(b){u(),p();const w=b[1].length;a.push(`<h${w} class="rui-markdown-h${w}">${g(e(b[2]))}</h${w}>`);continue}const v=/^\s*>\s?(.*)$/.exec(f);if(v){u(),n||(a.push('<blockquote class="rui-markdown-quote">'),n=!0),a.push(`<p>${g(e(v[1]??""))}</p>`);continue}else n&&f.trim()!==""&&p();const y=/^\s*[-*]\s+(.*)$/.exec(f);if(y){p(),i!=="ul"&&(u(),a.push("<ul>"),i="ul"),a.push(`<li>${g(e(y[1]??""))}</li>`);continue}const x=/^\s*\d+\.\s+(.*)$/.exec(f);if(x){p(),i!=="ol"&&(u(),a.push("<ol>"),i="ol"),a.push(`<li>${g(e(x[1]??""))}</li>`);continue}if(f.trim()===""){u(),p();continue}u(),p(),a.push(`<p>${g(e(f))}</p>`)}return s&&m(),u(),p(),a.join("");function g(f){let h=f.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(b,v,y)=>{const x=re(y);return x?`<img class="rui-markdown-image" src="${nt(x)}" alt="${v}" loading="lazy">`:`<span class="rui-markdown-image-fallback">${v}</span>`}).replace(/`([^`]+)`/g,"<code>$1</code>").replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>").replace(/\*([^*]+)\*/g,"<em>$1</em>").replace(/\[([^\]]+)\]\(([^)]+)\)/g,(b,v,y)=>`<a class="rui-link" href="${va(y)}" target="_blank" rel="noopener noreferrer">${v}</a>`);return h=h.replace(/(?<![="'>])\bhttps?:\/\/[a-zA-Z0-9._~:/?#@!$&'()*+,;=%\-]+/g,b=>`<a class="rui-link" href="${va(b)}" target="_blank" rel="noopener noreferrer">${b}</a>`),h}}function va(t){const e=t.trim();if(!e||e.startsWith("//"))return"#";if(e.startsWith("#")||e.startsWith("/")||e.startsWith("?"))return nt(e);const r=/^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(e);if(!r)return nt(e);const a=r[1].toLowerCase();return new Set(["http","https","mailto","tel"]).has(a)?nt(e):"#"}function nt(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Ve(t,e,r){const a=o("span",{class:"rui-avatar","data-size":r,role:"img"}),i=re(t);if(i){const n=o("img",{src:i,alt:e,loading:"lazy"});n.onerror=s=>{const l=s;(l.currentTarget??l.target).replaceWith(o("span",{class:"rui-avatar-fallback"},[We(e)]))},a.append(n)}else a.append(o("span",{class:"rui-avatar-fallback"},[We(e)]));return a}function We(t){const e=t.trim();return e?e.split(/\s+/).slice(0,2).map(a=>a.charAt(0).toUpperCase()).join("")||e.charAt(0).toUpperCase():"?"}const ot=new WeakMap;function Ee(t){const{liveRoot:e,onDismiss:r}=t,a=ot.get(e);a&&a.dispose();const i=e.getRootNode();let n=!1;const s=m=>{const g=m.target;g&&e.contains(g)||(p.dispose(),r())},l=m=>{m.key==="Escape"&&(p.dispose(),r())},c=e.ownerDocument;let u=null;if(c&&typeof MutationObserver<"u"){u=new MutationObserver(()=>{e.isConnected||p.dispose()});const m=e.getRootNode();(m instanceof Element||m instanceof Document||m instanceof ShadowRoot)&&u.observe(m,{childList:!0,subtree:!0})}const p={dispose:()=>{n||(n=!0,i.removeEventListener("click",s,!0),i.removeEventListener("keydown",l,!0),u?.disconnect(),ot.delete(e))}};return setTimeout(()=>{n||(i.addEventListener("click",s,!0),i.addEventListener("keydown",l,!0))},0),ot.set(e,p),p}function he(t){if(!t)return;const e=ot.get(t);e&&e.dispose()}const ds=[{match:/\b(revenue|sales|sale|income|payment|charges?|invoices?|billing)\b/i,icon:"sack-dollar"},{match:/\b(profit|earnings?|margin|roi)\b/i,icon:"chart-line"},{match:/\b(customers?|clients?|users?|members?|people|accounts?)\b/i,icon:"users"},{match:/\b(visitors?|sessions?|traffic|page-?views?|impressions?)\b/i,icon:"chart-line"},{match:/\b(orders?|carts?|purchases?|transactions?)\b/i,icon:"cart-shopping"},{match:/\b(products?|inventory|sku|stock|items?)\b/i,icon:"box"},{match:/\b(subscriptions?|plans?|tiers?|pricing)\b/i,icon:"credit-card"},{match:/\b(emails?|messages?|inbox|threads?|mail)\b/i,icon:"envelope"},{match:/\b(notifications?|alerts?|reminders?)\b/i,icon:"bell"},{match:/\b(growth|trend|increase|up)\b/i,icon:"arrow-trend-up"},{match:/\b(decline|drop|down|decrease|loss)\b/i,icon:"arrow-trend-down"},{match:/\b(reports?|analytics|insights?|dashboards?|metrics?|stats?|kpis?)\b/i,icon:"chart-pie"},{match:/\b(charts?|graphs?)\b/i,icon:"chart-column"},{match:/\b(tasks?|todos?|backlog|kanban|sprint)\b/i,icon:"list-check"},{match:/\b(projects?|workspaces?)\b/i,icon:"folder-open"},{match:/\b(files?|folders?|documents?|docs?|attachments?)\b/i,icon:"folder-open"},{match:/\b(images?|photos?|gallery|albums?)\b/i,icon:"image"},{match:/\b(videos?|clips?|recordings?)\b/i,icon:"video"},{match:/\b(audio|music|podcasts?|sounds?)\b/i,icon:"music"},{match:/\b(calendars?|schedule|events?|meetings?|appointments?)\b/i,icon:"calendar-days"},{match:/\b(comments?|replies|feedback|reviews?|ratings?)\b/i,icon:"comments"},{match:/\b(settings?|preferences?|config|configuration|options?)\b/i,icon:"gear"},{match:/\b(security|privacy|password|locks?|secure)\b/i,icon:"shield-halved"},{match:/\b(api|integrations?|webhooks?|connections?)\b/i,icon:"plug"},{match:/\b(database|storage|backups?|servers?)\b/i,icon:"database"},{match:/\b(speed|performance|latency|response\s?time)\b/i,icon:"gauge-high"},{match:/\b(uptime|availability|status|health)\b/i,icon:"heart-pulse"},{match:/\b(errors?|bugs?|failures?|exceptions?|incidents?)\b/i,icon:"circle-exclamation"},{match:/\b(success|complete|done|approved)\b/i,icon:"circle-check"},{match:/\b(warnings?|caution)\b/i,icon:"triangle-exclamation"},{match:/\b(search|results?|queries)\b/i,icon:"magnifying-glass"},{match:/\b(downloads?|exports?)\b/i,icon:"download"},{match:/\b(uploads?|imports?)\b/i,icon:"upload"},{match:/\b(time|hours?|duration|elapsed)\b/i,icon:"clock"},{match:/\b(locations?|maps?|addresses?|countries?|regions?)\b/i,icon:"location-dot"},{match:/\b(stars?|favourites?|favorites?|highlights?)\b/i,icon:"star"},{match:/\b(trophy|awards?|achievements?|badges?|gold)\b/i,icon:"trophy"},{match:/\b(targets?|goals?|objectives?|quotas?)\b/i,icon:"bullseye"},{match:/\b(teams?|departments?|orgs?|organisations?|organizations?)\b/i,icon:"people-group"},{match:/\b(tickets?|issues?|bugs?|requests?)\b/i,icon:"ticket"},{match:/\b(deploys?|builds?|releases?|versions?)\b/i,icon:"rocket"}];function ya(t){if(!t)return null;for(const e of ds)if(e.match.test(t))return e.icon;return null}const ps={default:"circle-info",info:"circle-info",primary:"bolt",success:"circle-check",warning:"triangle-exclamation",danger:"circle-exclamation",error:"circle-exclamation",neutral:"circle-info"};function ms(t){return t?ps[t.toLowerCase()]??null:null}function gs(t,e="shapes"){const r=t.trim()||"anon";return`https://api.dicebear.com/9.x/${/^[a-z0-9-]+$/i.test(e)?e:"shapes"}/svg?seed=${encodeURIComponent(r)}`}function xa(t){return k(t).map(r=>{if(r&&typeof r=="object"){const i=r;if(i.__kind==="Component"&&Array.isArray(i.args)){const n=d(i.args[0]);return{value:n,label:d(i.args[1],n)}}if(i.value!==void 0||i.label!==void 0){const n=d(i.value);return{value:n,label:d(i.label,n)}}}const a=d(r);return{value:a,label:a}}).filter(r=>r.value!==""||r.label!=="")}const fs=["primary","secondary","ghost","danger"],hs=["xs","sm","md","lg","xl","small","normal","large"],bs=["text","email","password","number","tel","url","date"];function vs(t){const e=d(t).trim().toLowerCase();return e==="xs"||e==="extra-small"?"xs":e==="small"||e==="sm"?"sm":e==="large"||e==="lg"?"lg":e==="xl"||e==="extra-large"?"xl":e==="normal"||e==="md"||e===""?"md":e==="xs"||e==="sm"||e==="md"||e==="lg"||e==="xl"?e:"md"}const ys={name:"Button",description:"Clickable button. The action argument runs when clicked.",props:[{name:"label",type:"string"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Callable invoked when clicked"},{name:"variant",type:"string",optional:!0,aliases:["tone"],enum:fs},{name:"type",type:"string",optional:!0,enum:["button","submit"],description:"HTML button type"},{name:"size",type:"string",optional:!0,enum:hs,description:"Canonical `xs|sm|md|lg|xl` (legacy `small|normal|large` still accepted)"},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name"},{name:"iconPosition",type:"string",optional:!0,enum:["leading","trailing"],description:"Icon placement (default leading)"},{name:"iconOnly",type:"boolean",optional:!0,description:"Hide the label visually (keeps aria-label)"},{name:"loading",type:"boolean",optional:!0,description:"Show spinner and disable interaction"},{name:"fullWidth",type:"boolean",optional:!0},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=C(e.loading),i=C(e.iconOnly),n=d(e.iconPosition,"leading"),s=d(e.label),l=o("button",{class:"rui-button",type:d(e.type,"button"),"data-variant":d(e.variant,"primary"),"data-size":vs(e.size),"data-icon-position":n,"data-icon-only":i?"true":null,"data-full-width":C(e.fullWidth)?"true":null,"data-loading":a?"true":null,"aria-label":i?s:null,disabled:C(e.disabled)||a?"":null}),c=o("span",{class:"rui-button-label"},[s]),u=L(e.icon,{className:"rui-button-icon"}),m=(a?L("spinner",{className:"rui-button-spinner"}):null)??u;return i?m&&l.append(m):n==="trailing"?(l.append(c),m&&l.append(m)):(m&&l.append(m),l.append(c)),l.onclick=()=>{a||r.invoke(e.action)},l}},xs={name:"Buttons",description:"Group of buttons laid out horizontally or vertically.",props:[{name:"items",type:"Button[]"},{name:"direction",type:"string",optional:!0,enum:["row","column"]}],render:(t,e,r)=>{const a=o("div",{class:"rui-buttons","data-direction":d(e.direction,"row")});for(const i of k(e.items))a.append(r.renderNode(i));return a}},ws={name:"Input",description:"Text input field. Pass a $variable as `value` for two-way binding.",props:[{name:"id",type:"string",description:"Input identifier"},{name:"placeholder",type:"string",optional:!0},{name:"type",type:"string",optional:!0,enum:bs},{name:"validations",type:"any",optional:!0,description:"Array or object of validation hints"},{name:"value",type:"any",optional:!0,description:"Bound value (typically $variable)"}],render:(t,e,r)=>{const a=o("input",{class:"rui-input",id:d(e.id),name:d(e.id),type:d(e.type,"text"),placeholder:d(e.placeholder),value:d(e.value)});return Ce(a,t,4,r),Ds(a,e.validations),a}},ks={name:"TextArea",description:"Multi-line text input.",props:[{name:"id",type:"string"},{name:"placeholder",type:"string",optional:!0},{name:"rows",type:"number",optional:!0},{name:"value",type:"any",optional:!0}],render:(t,e,r)=>{const a=o("textarea",{class:"rui-textarea",id:d(e.id),name:d(e.id),placeholder:d(e.placeholder),rows:String(Number(e.rows??4)||4)});return a.value=d(e.value),Ce(a,t,3,r),a}},Ss={name:"SelectItem",description:"Single option for a Select component.",props:[{name:"value",type:"string"},{name:"label",type:"string"}],render:(t,e)=>o("option",{value:d(e.value)},[d(e.label)])},Cs={name:"Select",description:"Dropdown select. Pass a `$variable` as `value` for two-way binding. Set `searchable: true` for a combobox-style filter UI on long option lists.",props:[{name:"id",type:"string"},{name:"items",type:"SelectItem[]"},{name:"label",type:"string",optional:!0},{name:"placeholder",type:"string",optional:!0},{name:"value",type:"any",optional:!0},{name:"searchable",type:"boolean",optional:!0,description:"Render as a filterable combobox"}],render:(t,e,r)=>{if(C(e.searchable))return Bs(t,e,r);const a=o("select",{class:"rui-select",id:d(e.id),name:d(e.id)}),i=d(e.placeholder);i&&a.append(o("option",{value:"",disabled:"",selected:""},[i]));for(const n of k(e.items))a.append(r.renderNode(n));return a.value=d(e.value),Ce(a,t,4,r),a}},Ts={name:"Checkbox",description:"Boolean checkbox.",props:[{name:"id",type:"string"},{name:"label",type:"string"},{name:"value",type:"boolean",optional:!0,aliases:["checked"]}],render:(t,e,r)=>{const a=o("label",{class:"rui-checkbox"}),i=C(e.value),n=o("input",{type:"checkbox",id:d(e.id),name:d(e.id),checked:i?"":null});return n.checked=i,Ce(n,t,2,r),a.append(n,o("span",{class:"rui-checkbox-label"},[d(e.label)])),a}},$s={name:"CheckBoxItem",description:"Single option inside a CheckBoxGroup.",props:[{name:"label",type:"string"},{name:"name",type:"string",description:"Key inside the group's value object"},{name:"description",type:"string",optional:!0},{name:"defaultChecked",type:"boolean",optional:!0,aliases:["checked"]}],render:(t,e)=>{const r=d(e.name),a=d(e.label),i=d(e.description),n=C(e.defaultChecked),s=o("label",{class:"rui-checkbox-item","data-name":r}),l=o("input",{type:"checkbox",name:r,checked:n?"":null});l.checked=n;const c=o("div",{class:"rui-checkbox-item-text"});return c.append(o("div",{class:"rui-checkbox-item-label"},[a])),i&&c.append(o("div",{class:"rui-checkbox-item-description"},[i])),s.append(l,c),s}},Ns={name:"CheckBoxGroup",description:"Group of checkboxes. Value is an object keyed by item name. Pass a `$variable` for two-way binding.",props:[{name:"name",type:"string",description:"Group identifier"},{name:"items",type:"CheckBoxItem[]"},{name:"value",type:"any",optional:!0,description:"Bound value (typically $variable)"}],render:(t,e,r)=>{const a=d(e.name),i=o("div",{class:"rui-checkbox-group",role:"group","data-name":a}),n=k(e.items),s=e.value&&typeof e.value=="object"?e.value:{};n.forEach((c,u)=>{const p=d(c.args?.[0]),m=d(c.args?.[1],`${a}-${u}`),g=d(c.args?.[2]),f=C(c.args?.[3]),h=`${a}-${m}`,b=o("label",{class:"rui-checkbox-item",for:h}),v=m in s?!!s[m]:f,y=o("input",{type:"checkbox",id:h,name:m,checked:v?"":null}),x=o("div",{class:"rui-checkbox-item-text"});x.append(o("div",{class:"rui-checkbox-item-label"},[p])),g&&x.append(o("div",{class:"rui-checkbox-item-description"},[g])),b.append(y,x),i.append(b)});const l=t.argMeta?.[2]?.stateRef;return l&&r.bindState(i,l,{event:"change",getValue:c=>{const u={};return c.querySelectorAll('input[type="checkbox"]').forEach(p=>{u[p.name]=p.checked}),u}}),i}},As={name:"Radio",description:"Radio button group.",props:[{name:"id",type:"string"},{name:"items",type:"SelectItem[]"},{name:"value",type:"any",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("div",{class:"rui-radio-group",role:"radiogroup"});for(const n of k(e.items)){const s=d(n.args?.[0]),l=d(n.args?.[1],s),c=`${a}-${s}`,u=o("label",{class:"rui-radio",for:c}),p=d(e.value)===s,m=o("input",{type:"radio",id:c,name:a,value:s,checked:p?"":null});m.checked=p,Ce(m,t,2,r),u.append(m,o("span",{class:"rui-radio-label"},[l])),i.append(u)}return i}},Ms={name:"FormControl",description:"Labeled wrapper around a single form field.",props:[{name:"label",type:"string"},{name:"field",type:"Node",aliases:["control"]},{name:"hint",type:"string",optional:!0}],render:(t,e,r)=>{const a=o("div",{class:"rui-form-control"});a.append(o("label",{class:"rui-form-label"},[d(e.label)]));const i=r.renderNode(e.field);a.append(i);const n=d(e.hint);return n&&a.append(o("p",{class:"rui-form-hint"},[n])),a}},wa={name:"SearchBar",description:"Pre-styled search input with a leading magnifying-glass icon, optional trailing submit button, and optional keyboard-shortcut hint. Pass a `$variable` as `value` for two-way binding. Use anywhere a user needs to filter content — toolbars, command bars, lists, headers.",props:[{name:"id",type:"string"},{name:"placeholder",type:"string",optional:!0},{name:"value",type:"string",optional:!0,description:"Bound value (typically $variable)"},{name:"shortcut",type:"string",optional:!0,description:'Keyboard hint chip on the right (e.g. "/")'},{name:"action",type:"callable",optional:!0,aliases:["onClick","onSubmit"],description:"Optional submit callable; clicking the trailing button or pressing Enter invokes it"},{name:"submitLabel",type:"string",optional:!0,description:'Label for the trailing submit button (default "Search"). Omitted when no action is provided.'}],render:(t,e,r)=>{const a=o("form",{class:"rui-search-bar",role:"search"});a.onsubmit=l=>{l.preventDefault(),r.invoke(e.action)};const i=L("magnifying-glass",{className:"rui-search-bar-icon"})??o("span",{class:"rui-search-bar-icon","aria-hidden":"true"});a.append(i);const n=o("input",{class:"rui-search-bar-input",id:d(e.id),name:d(e.id),type:"search",placeholder:d(e.placeholder,"Search…"),value:d(e.value),autocomplete:"off"});Ce(n,t,2,r),a.append(n);const s=d(e.shortcut);if(s&&a.append(o("span",{class:"rui-search-bar-shortcut"},[s])),e.action!=null){const l=o("button",{type:"submit",class:"rui-search-bar-submit"},[d(e.submitLabel,"Search")]);a.append(l)}return a}},Ps={name:"Form",description:"Form container. Children FormControls render in order; buttons render at the bottom.",props:[{name:"id",type:"string"},{name:"buttons",type:"Buttons | Button"},{name:"fields",type:"FormControl[]"}],render:(t,e,r)=>{const a=o("form",{class:"rui-form",id:d(e.id)});a.onsubmit=i=>i.preventDefault();for(const i of k(e.fields))a.append(r.renderNode(i));if(e.buttons){const i=o("div",{class:"rui-form-actions"});i.append(r.renderNode(e.buttons)),a.append(i)}return a}},Is={name:"Slider",description:"Range slider for selecting a single numeric value between `min` and `max`. Pass a `$variable` as `value` for two-way binding. Useful for filters, settings (volume, brightness), and parameter tuning.",props:[{name:"id",type:"string"},{name:"min",type:"number",optional:!0,description:"Default 0"},{name:"max",type:"number",optional:!0,description:"Default 100"},{name:"step",type:"number",optional:!0,description:"Default 1"},{name:"value",type:"number",optional:!0,description:"Bound value (typically $variable)"},{name:"label",type:"string",optional:!0},{name:"showValue",type:"boolean",optional:!0,description:"Render the current numeric value beside the slider"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=P(e.min,0),n=P(e.max,100),s=P(e.step,1),l=P(e.value,i),c=o("div",{class:"rui-slider","data-disabled":C(e.disabled)?"true":"false"}),u=d(e.label),p=C(e.showValue);if(u||p){const f=o("div",{class:"rui-slider-head"});u&&f.append(o("label",{class:"rui-slider-label",for:a},[u])),p&&f.append(o("span",{class:"rui-slider-value"},[String(l)])),c.append(f)}const m=o("input",{type:"range",class:"rui-slider-input",id:a,name:a,min:String(i),max:String(n),step:String(s),value:String(l),disabled:C(e.disabled)?"":null});m.oninput=f=>{const h=f.currentTarget;if(!h)return;const v=h.closest(".rui-slider")?.querySelector(".rui-slider-value");v&&(v.textContent=h.value)};const g=t.argMeta?.[4]?.stateRef;return g&&r.bindState(m,g,{event:"input",getValue:f=>Number(f.value)}),c.append(m),c}},zs={name:"NumberInput",description:'Numeric input with paired increment/decrement buttons. Use for quantity steppers, integer settings, and any field where a `<input type="number">` plus +/- controls is friendlier than the native spinner. Pass a `$variable` as `value` for two-way binding.',props:[{name:"id",type:"string"},{name:"value",type:"number",optional:!0,description:"Bound value (typically $variable)"},{name:"min",type:"number",optional:!0},{name:"max",type:"number",optional:!0},{name:"step",type:"number",optional:!0,description:"Default 1"},{name:"placeholder",type:"string",optional:!0},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=P(e.step,1),n=e.min!==void 0&&e.min!==null,s=e.max!==void 0&&e.max!==null,l=n?P(e.min,0):Number.NEGATIVE_INFINITY,c=s?P(e.max,0):Number.POSITIVE_INFINITY,u=C(e.disabled),p=o("div",{class:"rui-number-input","data-disabled":u?"true":"false"}),m=o("button",{type:"button",class:"rui-number-input-button","data-direction":"down","aria-label":"Decrement",disabled:u?"":null},["−"]),g=o("input",{type:"number",class:"rui-number-input-field",id:a,name:a,value:d(e.value),placeholder:d(e.placeholder),min:n?String(l):null,max:s?String(c):null,step:String(i),disabled:u?"":null}),f=o("button",{type:"button",class:"rui-number-input-button","data-direction":"up","aria-label":"Increment",disabled:u?"":null},["+"]),h=t.argMeta?.[1]?.stateRef;h&&r.bindState(g,h,{event:"input",getValue:v=>{const y=v.value;if(y==="")return null;const x=Number(y);return Number.isFinite(x)?x:null}});const b=(v,y)=>{const w=v.closest(".rui-number-input")?.querySelector(".rui-number-input-field");if(!w)return;const T=Number(w.value),S=Number.isFinite(T)?T:0,N=js(S+y,l,c);w.value=String(N),w.dispatchEvent(new Event("input",{bubbles:!0}))};return m.onclick=v=>b(v.currentTarget??v.target,-i),f.onclick=v=>b(v.currentTarget??v.target,i),p.append(m,g,f),p}},Rs={name:"DatePicker",description:'Date picker that wraps the native `<input type="date">` with consistent styling. Pass a `$variable` as `value` for two-way binding. Use `min`/`max` to bound the selectable range.',props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"ISO date (YYYY-MM-DD); typically $variable"},{name:"label",type:"string",optional:!0},{name:"min",type:"string",optional:!0,description:"Earliest ISO date"},{name:"max",type:"string",optional:!0,description:"Latest ISO date"},{name:"placeholder",type:"string",optional:!0},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("div",{class:"rui-date-picker"}),n=d(e.label);n&&i.append(o("label",{class:"rui-date-picker-label",for:a},[n]));const s=o("input",{type:"date",class:"rui-date-picker-input",id:a,name:a,value:d(e.value),min:d(e.min)||null,max:d(e.max)||null,placeholder:d(e.placeholder),disabled:C(e.disabled)?"":null});return Ce(s,t,1,r),i.append(s),i}},Ls={name:"FileUpload",description:'Styled file picker. Renders a click/drop area with a leading icon, label, and helper text. Files cannot round-trip through `$variables` (they are not serialisable), so pass a callable as `action` to handle the picked files via `ctx.query("#id").files`.',props:[{name:"id",type:"string"},{name:"label",type:"string",optional:!0,description:'Primary label (default "Choose a file")'},{name:"hint",type:"string",optional:!0,description:"Secondary helper text"},{name:"accept",type:"string",optional:!0,description:"Comma-separated MIME types or extensions"},{name:"multiple",type:"boolean",optional:!0},{name:"action",type:"callable",optional:!0,aliases:["onChange","onSelect"],description:"Callable fired when files are picked"},{name:"icon",type:"string",optional:!0,description:'Font Awesome icon (default "cloud-arrow-up")'},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=C(e.disabled),n=o("div",{class:"rui-file-upload","data-disabled":i?"true":"false"}),s=o("label",{class:"rui-file-upload-dropzone",for:a}),l=L(d(e.icon,"cloud-arrow-up"),{className:"rui-file-upload-icon"});l&&s.append(l);const c=o("div",{class:"rui-file-upload-text"});c.append(o("div",{class:"rui-file-upload-label"},[d(e.label,"Choose a file")]));const u=d(e.hint);u&&c.append(o("div",{class:"rui-file-upload-hint"},[u])),s.append(c);const p=o("input",{type:"file",id:a,name:a,class:"rui-file-upload-input",accept:d(e.accept)||null,multiple:C(e.multiple)?"":null,disabled:i?"":null});s.append(p),n.append(s);const m=(g,f)=>f.includes("image")||g.type.startsWith("image/")||/\.(png|jpe?g|gif|webp|svg|avif|bmp)$/i.test(g.name);return p.onchange=g=>{r.invoke(e.action);const f=g.currentTarget,h=f.closest(".rui-file-upload");if(!h)return;const b=f.files,v=h.querySelector(".rui-file-upload-preview");if(v&&v.remove(),!b||b.length===0)return;const y=d(e.accept),x=o("div",{class:"rui-file-upload-preview"});Array.from(b).forEach(w=>{const T=o("div",{class:"rui-file-upload-preview-item"});if(m(w,y)){const S=URL.createObjectURL(w),N=o("img",{src:S,alt:w.name,class:"rui-file-upload-thumbnail"});N.onload=()=>URL.revokeObjectURL(S),T.append(N)}T.append(o("span",{class:"rui-file-upload-filename"},[w.name])),x.append(T)}),h.append(x)},n}},ka={name:"Combobox",description:"Searchable single-select dropdown — type to filter, click an option to choose. Use instead of `Select` when the list is long enough that scanning is faster than scrolling (countries, currencies, repos, users). Pass a `$variable` as `value` for two-way binding; the selected option's `value` is written to state on pick.",props:[{name:"id",type:"string"},{name:"items",type:"SelectItem[]",description:"Options; SelectItem(value, label) or {value, label}"},{name:"value",type:"string",optional:!0,description:"Bound selected value (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"emptyLabel",type:"string",optional:!0,description:'Text shown when no items match the filter (default "No matches")'},{name:"disabled",type:"boolean",optional:!0},{name:"open",type:"boolean",optional:!0,description:"Initial open state — use to demo or pre-open the dropdown"}],render:(t,e,r)=>{const a=d(e.id),i=xa(e.items),n=d(e.value),s=i.find(N=>N.value===n)?.label??n,l=d(e.placeholder,"Select…"),c=d(e.emptyLabel,"No matches"),u=C(e.disabled),p=C(e.open),m=r.useInstanceState("open",p),g=r.useInstanceState("filter",""),f=m.get(),h=o("div",{class:"rui-combobox","data-open":f?"true":"false","data-disabled":u?"true":"false"}),b=o("button",{type:"button",class:"rui-combobox-trigger",id:a,"aria-haspopup":"listbox","aria-expanded":f?"true":"false",disabled:u?"":null});b.append(o("span",{class:"rui-combobox-value","data-placeholder":s?"false":"true"},[s||l]));const v=L("chevron-down",{className:"rui-combobox-chevron"});v&&b.append(v),h.append(b);const y=o("div",{class:"rui-combobox-panel",role:"listbox"}),x=o("input",{type:"text",class:"rui-combobox-filter",placeholder:"Filter…",autocomplete:"off",value:g.get()});y.append(x);const w=o("div",{class:"rui-combobox-list"});y.append(w);const T=(N,$)=>{N.replaceChildren();const A=$.trim().toLowerCase(),z=A===""?i:i.filter(R=>R.label.toLowerCase().includes(A)||R.value.toLowerCase().includes(A));if(z.length===0){N.append(o("div",{class:"rui-combobox-empty"},[c]));return}for(const R of z){const _=o("button",{type:"button",class:"rui-combobox-option",role:"option","data-value":R.value,"aria-selected":R.value===n?"true":"false"},[R.label]);_.onclick=Q=>{Q.stopPropagation(),S(Q.currentTarget,R.value)},N.append(_)}},S=(N,$)=>{const A=t.argMeta?.[2]?.stateRef;A&&r.setState(A,$),m.set(!1),g.set("");const z=N.closest(".rui-combobox");z?.setAttribute("data-open","false"),z?.querySelector(".rui-combobox-trigger")?.setAttribute("aria-expanded","false"),he(z)};return T(w,g.get()),x.oninput=N=>{const $=N.currentTarget;g.set($.value);const A=$.closest(".rui-combobox-panel")?.querySelector(".rui-combobox-list");A&&T(A,$.value)},x.onkeydown=N=>{const $=N;if($.key!=="Enter")return;$.preventDefault();const R=$.currentTarget.closest(".rui-combobox")?.querySelector(".rui-combobox-option[data-value]"),_=R?.getAttribute("data-value");_!=null&&R&&S(R,_)},b.onclick=N=>{if(u)return;N.stopPropagation();const $=!m.get();m.set($);const A=N.currentTarget.closest(".rui-combobox");if(A?.setAttribute("data-open",$?"true":"false"),A?.querySelector(".rui-combobox-trigger")?.setAttribute("aria-expanded",$?"true":"false"),!!A){if(!$){he(A);return}setTimeout(()=>x.focus(),0),Ee({liveRoot:A,onDismiss:()=>{m.set(!1),g.set(""),A.setAttribute("data-open","false"),A.querySelector(".rui-combobox-trigger")?.setAttribute("aria-expanded","false")}})}},h.append(y),h}},Es={name:"MultiSelect",description:"Multi-option searchable dropdown. Type to filter, click an option to add/remove it from the bound array. Renders the selected options as removable chips inside the trigger. Pass a `$variable` (array of values) as `value` for two-way binding.",props:[{name:"id",type:"string"},{name:"items",type:"SelectItem[]",description:"Options; SelectItem(value, label) or {value, label}"},{name:"value",type:"any[]",optional:!0,description:"Bound array of selected values (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"emptyLabel",type:"string",optional:!0,description:"Text shown when no items match the filter"},{name:"max",type:"number",optional:!0,description:"Maximum number of selections"},{name:"disabled",type:"boolean",optional:!0},{name:"open",type:"boolean",optional:!0,description:"Initial open state — use to demo or pre-open the dropdown"}],render:(t,e,r)=>{const a=d(e.id),i=xa(e.items),n=d(e.placeholder,"Select…"),s=d(e.emptyLabel,"No matches"),l=C(e.disabled),c=Math.max(0,Math.floor(Number(e.max??0))),u=Array.isArray(e.value)?e.value.map(z=>d(z)).filter(Boolean):[],p=new Set(u),m=t.argMeta?.[2]?.stateRef,g=C(e.open),f=r.useInstanceState("open",g),h=r.useInstanceState("filter",""),b=f.get(),v=o("div",{class:"rui-multiselect","data-open":b?"true":"false","data-disabled":l?"true":"false"}),y=o("button",{type:"button",class:"rui-multiselect-trigger",id:a,"aria-haspopup":"listbox","aria-expanded":b?"true":"false",disabled:l?"":null}),x=o("span",{class:"rui-multiselect-chips"}),w=z=>{m&&r.setState(m,z)};if(u.length===0)x.append(o("span",{class:"rui-multiselect-placeholder"},[n]));else for(const z of u){const R=i.find(B=>B.value===z)?.label??z,_=o("span",{class:"rui-multiselect-chip","data-value":z});_.append(o("span",{class:"rui-multiselect-chip-label"},[R]));const Q=o("button",{type:"button",class:"rui-multiselect-chip-remove","aria-label":`Remove ${R}`},["×"]);Q.onclick=B=>{B.stopPropagation();const O=u.filter(J=>J!==z);w(O)},_.append(Q),x.append(_)}y.append(x);const T=L("chevron-down",{className:"rui-multiselect-chevron"});T&&y.append(T),v.append(y);const S=o("div",{class:"rui-multiselect-panel",role:"listbox","aria-multiselectable":"true"}),N=o("input",{type:"text",class:"rui-multiselect-filter",placeholder:"Filter…",autocomplete:"off",value:h.get()});S.append(N);const $=o("div",{class:"rui-multiselect-list"});S.append($);const A=(z,R)=>{z.replaceChildren();const _=R.trim().toLowerCase(),Q=_===""?i:i.filter(B=>B.label.toLowerCase().includes(_)||B.value.toLowerCase().includes(_));if(Q.length===0){z.append(o("div",{class:"rui-multiselect-empty"},[s]));return}for(const B of Q){const O=p.has(B.value),J=!O&&c>0&&u.length>=c,X=o("button",{type:"button",class:"rui-multiselect-option",role:"option","data-value":B.value,"data-selected":O?"true":"false","aria-selected":O?"true":"false",disabled:J?"":null}),ue=o("span",{class:"rui-multiselect-option-check"}),me=L(O?"check":"",{className:"rui-multiselect-option-check-icon"});me&&ue.append(me),X.append(ue),X.append(o("span",{class:"rui-multiselect-option-label"},[B.label])),X.onclick=Je=>{if(Je.stopPropagation(),J)return;const Ae=O?u.filter(tr=>tr!==B.value):[...u,B.value];w(Ae)},z.append(X)}};return A($,h.get()),N.oninput=z=>{const R=z.currentTarget;h.set(R.value);const _=R.closest(".rui-multiselect-panel")?.querySelector(".rui-multiselect-list");_&&A(_,R.value)},y.onclick=z=>{if(l)return;z.stopPropagation();const R=!f.get();f.set(R);const _=z.currentTarget.closest(".rui-multiselect");if(_?.setAttribute("data-open",R?"true":"false"),_?.querySelector(".rui-multiselect-trigger")?.setAttribute("aria-expanded",R?"true":"false"),!!_){if(!R){he(_);return}setTimeout(()=>N.focus(),0),Ee({liveRoot:_,onDismiss:()=>{f.set(!1),h.set(""),_.setAttribute("data-open","false"),_.querySelector(".rui-multiselect-trigger")?.setAttribute("aria-expanded","false")}})}},v.append(S),v}},_s={name:"DateRangePicker",description:"Paired date inputs with a single label, sharing the same min/max range. Pass `$variable` references for both `from` and `to` to two-way-bind a date range (ISO `YYYY-MM-DD` strings).",props:[{name:"id",type:"string"},{name:"from",type:"string",optional:!0,description:"ISO date start; typically $variable"},{name:"to",type:"string",optional:!0,description:"ISO date end; typically $variable"},{name:"label",type:"string",optional:!0},{name:"min",type:"string",optional:!0,description:"Earliest selectable ISO date"},{name:"max",type:"string",optional:!0,description:"Latest selectable ISO date"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=`${a}-from`,n=`${a}-to`,s=d(e.min),l=d(e.max),c=C(e.disabled),u=o("div",{class:"rui-date-range-picker","data-disabled":c?"true":"false"}),p=d(e.label);p&&u.append(o("label",{class:"rui-date-range-picker-label",for:i},[p]));const m=o("div",{class:"rui-date-range-picker-row"}),g=o("input",{type:"date",class:"rui-date-range-picker-input",id:i,name:i,value:d(e.from),min:s||null,max:l||null,disabled:c?"":null,"data-role":"from"});m.append(g),m.append(o("span",{class:"rui-date-range-picker-separator","aria-hidden":"true"},["–"]));const f=o("input",{type:"date",class:"rui-date-range-picker-input",id:n,name:n,value:d(e.to),min:s||null,max:l||null,disabled:c?"":null,"data-role":"to"});m.append(f),u.append(m);const h=t.argMeta?.[1]?.stateRef,b=t.argMeta?.[2]?.stateRef;return h&&r.bindState(g,h),b&&r.bindState(f,b),u}};function js(t,e,r){return Number.isNaN(t)?e===Number.NEGATIVE_INFINITY?0:e:Math.min(Math.max(t,e),r)}function Bs(t,e,r){const a=t.argMeta?[...t.argMeta]:[];for(;a.length<5;)a.push({});a[4]?.stateRef&&(a[2]=a[4]);const i=ka.render({...t,argMeta:a},{id:e.id,items:e.items,value:e.value,placeholder:e.placeholder,emptyLabel:"No matches",disabled:!1},r);return i.classList.add("rui-select-searchable"),i}function Ce(t,e,r,a){const i=e.argMeta?.[r]?.stateRef;if(i){if(t instanceof HTMLInputElement&&t.type==="checkbox"){a.bindState(t,i,{event:"change",getValue:n=>n.checked});return}a.bindState(t,i)}}function Ds(t,e){if(!e)return;const r=Array.isArray(e)?e.map(a=>String(a)):typeof e=="object"?Object.entries(e).map(([a,i])=>i?`${a}:${i}`:a):[];for(const a of r)a==="required"?t.required=!0:a.startsWith("minLength:")?t.minLength=Number(a.slice(10))||0:a.startsWith("maxLength:")?t.maxLength=Number(a.slice(10))||0:a==="email"&&(t.type="email")}const ve=["default","primary","success","warning","danger","info"],Te=(t,e)=>{const r=k(t);if(r.length===0)return null;const a=o("div",{class:"rui-pattern-actions"});for(const i of r)a.append(e.renderNode(i));return a},Fs=[{match:/\bbeta\b/i,label:"Beta"},{match:/\b(early\s?access|preview)\b/i,label:"Preview"},{match:/\b(introduc(?:ing|e)|launch(?:ed|ing)?|announcing)\b/i,label:"Introducing"},{match:/\b(welcome\b|get(?:ting)?\s?started)/i,label:"Welcome"},{match:/\b(new\b|whats\s?new|now\b)/i,label:"What's new"},{match:/\bfree\b/i,label:"Free trial"},{match:/\bupgrade\b/i,label:"Upgrade"},{match:/\b(sale|discount|deal)\b/i,label:"Limited time"}];function Os(t,e){const r=`${t} ${e}`.trim();if(!r)return"";for(const a of Fs)if(a.match.test(r))return a.label;return""}const Us={name:"Hero",description:'Eye-catching landing/marketing header with eyebrow tag, title, subtitle, optional bullet highlights, and primary/secondary CTA buttons. Use `layout="cover"` with `imageSrc` for an image-backed hero band (pass `height` and optional `caption`). Default layout shows an optional side illustration.',props:[{name:"title",type:"string"},{name:"subtitle",type:"string",optional:!0},{name:"primary",type:"Button",optional:!0,description:"Primary CTA — pass a Button(...)"},{name:"secondary",type:"Button",optional:!0,description:"Secondary CTA — pass a Button(...)"},{name:"eyebrow",type:"string",optional:!0,description:"Short uppercase tag above the title"},{name:"highlights",type:"string[]",optional:!0,description:"Bullet items rendered as tag pills"},{name:"imageSrc",type:"string",optional:!0,description:"Illustration or cover background when layout=cover"},{name:"caption",type:"string",optional:!0,description:"Small caption above CTAs (cover layout)"},{name:"height",type:"string",optional:!0,description:"Min-height for cover layout (default 280px)"},{name:"actions",type:"Node[]",optional:!0,description:"CTA row (cover layout; alternative to primary/secondary)"},{name:"layout",type:"string",optional:!0,enum:["default","cover"],description:"default = text-first; cover = image-backed band"},{name:"tone",type:"string",optional:!0,enum:ve,description:"Accent tone"}],render:(t,e,r)=>{const a=d(e.layout,"default"),i=d(e.title),n=d(e.subtitle),l=d(e.eyebrow)||Os(i,n),c=d(e.tone,"primary");if(a==="cover"){const h=co(d(e.imageSrc)),b=ee(d(e.height),"280px"),v=o("section",{class:"rui-cover","data-tone":c,style:`background-image:linear-gradient(180deg, rgba(15, 23, 42, 0.05) 0%, rgba(15, 23, 42, 0.62) 100%), url("${h}");min-height:${b};`}),y=o("div",{class:"rui-cover-body"});l&&y.append(o("span",{class:"rui-cover-eyebrow"},[l])),y.append(o("h1",{class:"rui-cover-title"},[i])),n&&y.append(o("p",{class:"rui-cover-subtitle"},[n]));const x=d(e.caption);x&&y.append(o("p",{class:"rui-cover-caption"},[x]));const w=Te(e.actions,r);if(w)w.classList.add("rui-cover-actions"),y.append(w);else{const T=[e.primary,e.secondary].filter(Boolean);if(T.length>0){const S=o("div",{class:"rui-cover-actions rui-pattern-actions"});for(const N of T)S.append(r.renderNode(N));y.append(S)}}return v.append(y),v}const u=re(e.imageSrc),p=o("section",{class:"rui-hero","data-tone":c,"data-has-image":u?"true":"false"}),m=o("div",{class:"rui-hero-body"});l&&m.append(o("span",{class:"rui-hero-eyebrow"},[l])),m.append(o("h1",{class:"rui-hero-title"},[i])),n&&m.append(o("p",{class:"rui-hero-subtitle"},[n]));const g=k(e.highlights);if(g.length>0){const h=o("div",{class:"rui-hero-highlights"});for(const b of g){const v=d(b);v&&h.append(o("span",{class:"rui-hero-highlight"},[v]))}m.append(h)}const f=[e.primary,e.secondary].filter(Boolean);if(f.length>0){const h=o("div",{class:"rui-hero-ctas"});for(const b of f)h.append(r.renderNode(b));m.append(h)}if(p.append(m),u){const h=o("div",{class:"rui-hero-media"});h.append(o("img",{src:u,alt:"",loading:"lazy"})),p.append(h)}return p}},qs={name:"PageHeader",description:'Page-level header with breadcrumbs, title, subtitle, status tag, and a right-aligned actions row. The canonical first child for any dashboard, settings, or detail page — replaces ad-hoc Stack+Header+Buttons stitching. If `breadcrumbs` is omitted the component auto-derives `["Home", title]` so the page never lacks a trail. Pass `breadcrumbs=false` to opt out.',props:[{name:"title",type:"string"},{name:"subtitle",type:"string",optional:!0},{name:"breadcrumbs",type:"string[] | Breadcrumb | false",optional:!0,description:"Array of strings, a Breadcrumb(...) node, or `false` to suppress the auto-derived trail"},{name:"actions",type:"Node[]",optional:!0,description:"Buttons / NavLinks shown on the right"},{name:"status",type:"Badge",optional:!0,aliases:["badge"],description:"Optional Badge(...) rendered next to the title"}],render:(t,e,r)=>{const a=o("header",{class:"rui-page-header"}),i=d(e.title);let n=e.breadcrumbs;if(n==null?i&&(n=["Home",i]):(n===!1||n==="false")&&(n=null),n){const m=o("div",{class:"rui-page-header-breadcrumbs"});Array.isArray(n)?n.forEach((g,f)=>{f>0&&m.append(o("span",{class:"rui-page-header-crumb-sep"},["/"])),m.append(o("span",{class:"rui-page-header-crumb"},[d(g)]))}):m.append(r.renderNode(n)),a.append(m)}const s=o("div",{class:"rui-page-header-title-row"}),l=o("div",{class:"rui-page-header-title-block"}),c=o("div",{class:"rui-page-header-title-line"});c.append(o("h1",{class:"rui-page-header-title"},[i])),e.status&&c.append(r.renderNode(e.status)),l.append(c);const u=d(e.subtitle);u&&l.append(o("p",{class:"rui-page-header-subtitle"},[u])),s.append(l);const p=Te(e.actions,r);return p&&(p.classList.add("rui-page-header-actions"),s.append(p)),a.append(s),a}},Hs={name:"EmptyState",description:"Zero-state placeholder for empty lists, searches, dashboards. Renders a centered icon (or illustration), title, description, and either a single `action` Button or an `actions` row (primary + secondary). Always preferable to an empty Card with raw text.",props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0},{name:"icon",type:"string",optional:!0,description:'Font Awesome icon name (defaults to "inbox")'},{name:"illustration",type:"string",optional:!0,description:"Image URL — takes precedence over `icon` when provided"},{name:"action",type:"Button",optional:!0,description:"Single CTA (legacy slot)"},{name:"actions",type:"Node[]",optional:!0,description:"Row of CTA Buttons / Links — preferred over `action` for primary + secondary affordances"}],render:(t,e,r)=>{const a=o("div",{class:"rui-empty-state"}),i=re(e.illustration);if(i)a.append(o("img",{class:"rui-empty-state-illustration",src:i,alt:"",loading:"lazy"}));else{const l=d(e.title),c=d(e.description),u=d(e.icon)||ya(`${l} ${c}`)||"inbox",p=L(u,{className:"rui-empty-state-icon"});p&&a.append(p)}a.append(o("h3",{class:"rui-empty-state-title"},[d(e.title)]));const n=d(e.description);n&&a.append(o("p",{class:"rui-empty-state-description"},[n]));const s=k(e.actions);if(s.length>0){const l=o("div",{class:"rui-empty-state-actions"});for(const c of s)l.append(r.renderNode(c));a.append(l)}else if(e.action){const l=o("div",{class:"rui-empty-state-action"});l.append(r.renderNode(e.action)),a.append(l)}return a}},Vs={name:"TimelineItem",description:"Single event on a Timeline.",props:[{name:"title",type:"string"},{name:"time",type:"string",optional:!0,description:"Display label (ISO, relative, etc.)"},{name:"description",type:"string",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name rendered inside the marker"},{name:"tone",type:"string",optional:!0,enum:ve}],render:(t,e)=>{const r=o("li",{class:"rui-timeline-item","data-tone":d(e.tone,"default")}),a=o("span",{class:"rui-timeline-marker"}),i=L(e.icon);i&&a.append(i),r.append(a);const n=o("div",{class:"rui-timeline-body"}),s=o("div",{class:"rui-timeline-head"});s.append(o("span",{class:"rui-timeline-title"},[d(e.title)]));const l=d(e.time);l&&s.append(o("span",{class:"rui-timeline-time"},[l])),n.append(s);const c=d(e.description);return c&&n.append(o("div",{class:"rui-timeline-description"},[c])),r.append(n),r}},Ws={name:"Timeline",description:"Vertical event timeline. Children must be TimelineItem entries. Ideal for activity feeds, changelogs, and process flows.",props:[{name:"items",type:"TimelineItem[]"}],render:(t,e,r)=>{const a=o("ol",{class:"rui-timeline"});for(const i of k(e.items))a.append(r.renderNode(i));return a}},Gs={name:"FeatureItem",description:"Single tile on a FeatureGrid.",props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown in a colored disc"},{name:"tone",type:"string",optional:!0,enum:ve}],render:(t,e)=>{const r=o("div",{class:"rui-feature-item","data-tone":d(e.tone,"primary")}),a=d(e.icon,"sparkles"),i=L(a,{className:"rui-feature-icon"});i&&r.append(i),r.append(o("h3",{class:"rui-feature-title"},[d(e.title)]));const n=d(e.description);return n&&r.append(o("p",{class:"rui-feature-description"},[n])),r}},Ks={name:"FeatureGrid",description:"Responsive grid of FeatureItem tiles (typically 2–3 columns). Use to highlight product capabilities or page categories.",props:[{name:"items",type:"FeatureItem[]"},{name:"columns",type:"number",optional:!0,description:"Preferred column count (default auto)"}],render:(t,e,r)=>{const a=Math.max(1,Math.min(4,Number(e.columns??"auto"))),i=o("div",{class:"rui-feature-grid","data-columns":a>0?String(a):null});for(const n of k(e.items))i.append(r.renderNode(n));return i}},Ys={name:"Testimonial",description:"Quote card with author, role, and optional avatar.",props:[{name:"quote",type:"string"},{name:"author",type:"string",aliases:["name"]},{name:"role",type:"string",optional:!0},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"]},{name:"rating",type:"number",optional:!0,description:"0–5 stars"}],render:(t,e)=>{const r=o("figure",{class:"rui-testimonial"}),a=Math.max(0,Math.min(5,Math.round(Number(e.rating??0))));if(a>0){const c=o("div",{class:"rui-testimonial-rating"});for(let u=0;u<5;u+=1){const p=u<a,m=L(p?"star":"regular:star",{className:"rui-testimonial-rating-star"});m&&c.append(m)}r.append(c)}r.append(o("blockquote",{class:"rui-testimonial-quote"},[d(e.quote)]));const i=o("figcaption",{class:"rui-testimonial-author"}),n=re(e.avatarSrc);n&&i.append(o("img",{class:"rui-testimonial-avatar",src:n,alt:""}));const s=o("div",{class:"rui-testimonial-meta"});s.append(o("div",{class:"rui-testimonial-name"},[d(e.author)]));const l=d(e.role);return l&&s.append(o("div",{class:"rui-testimonial-role"},[l])),i.append(s),r.append(i),r}},Js={name:"ProfileCard",description:"Compact profile/user card with avatar, name, role, optional bio, social tags, and a row of action buttons. Use for team rosters, contributor lists, and contact panels.",props:[{name:"name",type:"string"},{name:"role",type:"string",optional:!0},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"],description:"Avatar image src; falls back to initials"},{name:"bio",type:"string",optional:!0},{name:"tags",type:"string[]",optional:!0},{name:"actions",type:"Node[]",optional:!0,description:"Buttons to render at the bottom"}],render:(t,e,r)=>{const a=o("div",{class:"rui-profile-card"}),i=o("div",{class:"rui-profile-card-header"});i.append(Ve(d(e.avatarSrc),d(e.name),"lg"));const n=o("div",{class:"rui-profile-card-meta"});n.append(o("h3",{class:"rui-profile-card-name"},[d(e.name)]));const s=d(e.role);s&&n.append(o("p",{class:"rui-profile-card-role"},[s])),i.append(n),a.append(i);const l=d(e.bio);l&&a.append(o("p",{class:"rui-profile-card-bio"},[l]));const c=k(e.tags);if(c.length>0){const p=o("div",{class:"rui-profile-card-tags"});for(const m of c){const g=d(m);g&&p.append(o("span",{class:"rui-tag","data-size":"sm"},[o("span",{class:"rui-tag-label"},[g])]))}a.append(p)}const u=Te(e.actions,r);return u&&(u.classList.add("rui-profile-card-actions"),a.append(u)),a}},Xs={name:"Comment",description:"Single comment / message bubble. Renders avatar, author, timestamp, body, and an optional row of action buttons (reply, like, …).",props:[{name:"author",type:"string"},{name:"body",type:"string",aliases:["text","message"]},{name:"time",type:"string",optional:!0,description:"Relative or absolute timestamp"},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"]},{name:"actions",type:"Node[]",optional:!0}],render:(t,e,r)=>{const a=o("article",{class:"rui-comment"});a.append(Ve(d(e.avatarSrc),d(e.author),"md"));const i=o("div",{class:"rui-comment-body"}),n=o("header",{class:"rui-comment-header"});n.append(o("span",{class:"rui-comment-author"},[d(e.author)]));const s=d(e.time);s&&n.append(o("span",{class:"rui-comment-time"},[s])),i.append(n),i.append(o("div",{class:"rui-comment-content"},[d(e.body)]));const l=Te(e.actions,r);return l&&(l.classList.add("rui-comment-actions"),i.append(l)),a.append(i),a}},Zs={name:"Banner",description:"Full-width announcement banner. Use at the top of a page for promos, release notes, or downtime notices. For inline notices prefer Callout or Alert.",props:[{name:"title",type:"string"},{name:"message",type:"string",optional:!0,aliases:["description"]},{name:"action",type:"Button",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name"},{name:"tone",type:"string",optional:!0,enum:ve}],render:(t,e,r)=>{const a=d(e.tone,"primary"),i=o("aside",{class:"rui-banner","data-tone":a}),n=d(e.icon)||ms(a)||"",s=L(n,{className:"rui-banner-icon"});s&&i.append(s);const l=o("div",{class:"rui-banner-body"});l.append(o("strong",{class:"rui-banner-title"},[d(e.title)]));const c=d(e.message);if(c&&l.append(o("span",{class:"rui-banner-message"},[c])),i.append(l),e.action){const u=o("div",{class:"rui-banner-action"});u.append(r.renderNode(e.action)),i.append(u)}return i}},Qs={name:"KanbanCard",description:"Single card on a Kanban board.",props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0},{name:"tags",type:"string[]",optional:!0},{name:"assignee",type:"string",optional:!0,description:"Name shown next to avatar initials"},{name:"tone",type:"string",optional:!0,enum:ve},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name shown beside the title"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Optional callable fired when the card is clicked"}],render:(t,e,r)=>{const a=o("div",{class:"rui-kanban-card","data-tone":d(e.tone,"default")});typeof e.action=="function"&&(a.setAttribute("role","button"),a.setAttribute("tabindex","0"),a.onclick=()=>r.invoke(e.action),a.onkeydown=u=>{const p=u;(p.key==="Enter"||p.key===" ")&&(p.preventDefault(),r.invoke(e.action))});const i=o("div",{class:"rui-kanban-card-title"}),n=L(e.icon,{className:"rui-kanban-card-icon"});n&&i.append(n),i.append(document.createTextNode(d(e.title))),a.append(i);const s=d(e.description);s&&a.append(o("p",{class:"rui-kanban-card-description"},[s]));const l=k(e.tags);if(l.length>0){const u=o("div",{class:"rui-kanban-card-tags"});for(const p of l){const m=d(p);m&&u.append(o("span",{class:"rui-tag","data-size":"sm"},[o("span",{class:"rui-tag-label"},[m])]))}a.append(u)}const c=d(e.assignee);if(c){const u=o("footer",{class:"rui-kanban-card-footer"});u.append(Ve("",c,"sm")),u.append(o("span",{class:"rui-kanban-card-assignee"},[c])),a.append(u)}return a}},el={name:"KanbanColumn",description:"Single column inside a KanbanBoard. Children must be KanbanCard entries.",props:[{name:"title",type:"string"},{name:"items",type:"KanbanCard[]",aliases:["cards"]},{name:"tone",type:"string",optional:!0,enum:ve,description:"Header accent tone"}],render:(t,e,r)=>{const a=k(e.items),i=o("section",{class:"rui-kanban-column","data-tone":d(e.tone,"default")}),n=o("header",{class:"rui-kanban-column-header"});n.append(o("span",{class:"rui-kanban-column-title"},[d(e.title)])),n.append(o("span",{class:"rui-kanban-column-count"},[String(a.length)])),i.append(n);const s=o("div",{class:"rui-kanban-column-body"});for(const l of a)s.append(r.renderNode(l));return a.length===0&&s.append(o("div",{class:"rui-kanban-column-empty"},["No items"])),i.append(s),i}},tl={name:"KanbanBoard",description:"Horizontal Kanban board. Children must be KanbanColumn entries. The board scrolls horizontally on narrow viewports so columns stay readable.",props:[{name:"columns",type:"KanbanColumn[]"}],render:(t,e,r)=>{const a=o("div",{class:"rui-kanban-board"});for(const i of k(e.columns))a.append(r.renderNode(i));return a}},rl={name:"SectionHeader",description:"Compact section header for the top of a Card or panel. Renders a small eyebrow, a title, an optional subtitle, an optional status Tag/Badge, and a right-aligned actions row. Use this inside a Card to introduce a section instead of a bare `CardHeader`.",props:[{name:"title",type:"string"},{name:"subtitle",type:"string",optional:!0,aliases:["description"]},{name:"eyebrow",type:"string",optional:!0,description:"Short uppercase label above the title"},{name:"status",type:"Badge | Tag",optional:!0,aliases:["badge"]},{name:"actions",type:"Node[]",optional:!0,description:"Buttons / Links shown on the right"}],render:(t,e,r)=>{const a=o("header",{class:"rui-section-header"}),i=o("div",{class:"rui-section-header-left"}),n=d(e.eyebrow);n&&i.append(o("span",{class:"rui-section-header-eyebrow"},[n]));const s=o("div",{class:"rui-section-header-title-line"});s.append(o("h3",{class:"rui-section-header-title"},[d(e.title)])),e.status&&s.append(r.renderNode(e.status)),i.append(s);const l=d(e.subtitle);l&&i.append(o("p",{class:"rui-section-header-subtitle"},[l])),a.append(i);const c=Te(e.actions,r);return c&&(c.classList.add("rui-section-header-actions"),a.append(c)),a}},al={name:"Toolbar",description:"Horizontal toolbar for filters, search, view modes, and primary actions. Left/center/right slots wrap onto separate rows on narrow viewports so the bar never overflows. Pass `searchable: true` to auto-mount a SearchBar in the left slot (bind `searchValue` to a `$variable`). Use ABOVE a Table, List, Grid, or Kanban view — never replace `PageHeader` with it.",props:[{name:"left",type:"Node[]",optional:!0,description:"Filters / search inputs / chips"},{name:"right",type:"Node[]",optional:!0,description:"Primary action buttons"},{name:"center",type:"Node[]",optional:!0,description:"Centered controls (e.g. SegmentedControl, search bar)"},{name:"searchable",type:"boolean",optional:!0,description:"Auto-mount a SearchBar at the start of the left slot"},{name:"searchPlaceholder",type:"string",optional:!0,description:"Placeholder for the auto-mounted SearchBar"},{name:"searchValue",type:"string",optional:!0,description:"$variable bound to the auto-mounted SearchBar"}],render:(t,e,r)=>{const a=k(e.center),i=o("div",{class:"rui-toolbar","data-has-center":a.length>0?"true":"false"}),n=o("div",{class:"rui-toolbar-side rui-toolbar-left"});C(e.searchable)&&n.append(wa.render({__kind:"Component",name:"SearchBar",args:[],argMeta:[]},{id:"toolbar-search",placeholder:d(e.searchPlaceholder,"Search…"),value:e.searchValue},r));for(const l of k(e.left))n.append(r.renderNode(l));if(i.append(n),a.length>0){const l=o("div",{class:"rui-toolbar-side rui-toolbar-center"});for(const c of a)l.append(r.renderNode(c));i.append(l)}const s=o("div",{class:"rui-toolbar-side rui-toolbar-right"});for(const l of k(e.right))s.append(r.renderNode(l));return i.append(s),i}},il={name:"SidebarItem",description:"Single navigation item inside a Sidebar. Pass `active=true` to mark as the current page, an `action` Action for click handling, or an optional `badge` (string/number) for a trailing chip.",props:[{name:"label",type:"string"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name rendered before the label"},{name:"active",type:"boolean",optional:!0},{name:"badge",type:"string",optional:!0,description:"Trailing chip (count or status)"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"]}],render:(t,e,r)=>{const a=o("button",{type:"button",class:"rui-sidebar-item","data-active":C(e.active)?"true":"false"}),i=L(e.icon,{className:"rui-sidebar-item-icon"});i&&a.append(i),a.append(o("span",{class:"rui-sidebar-item-label"},[d(e.label)]));const n=d(e.badge);return n&&a.append(o("span",{class:"rui-sidebar-item-badge"},[n])),typeof e.action=="function"&&(a.onclick=()=>r.invoke(e.action)),a}},nl={name:"SidebarSection",description:"Grouping inside a Sidebar — small uppercase label followed by SidebarItem entries. Use this to chunk a long sidebar into sections.",props:[{name:"label",type:"string"},{name:"items",type:"SidebarItem[]"}],render:(t,e,r)=>{const a=o("div",{class:"rui-sidebar-section"}),i=d(e.label);i&&a.append(o("div",{class:"rui-sidebar-section-label"},[i]));for(const n of k(e.items))a.append(r.renderNode(n));return a}},ol={name:"Sidebar",description:"Vertical app navigation panel. Supports a brand header, navigation items (`SidebarItem` or `SidebarSection`), an optional footer, and a `collapsed` mode that hides labels to leave just an icon rail. Use inside `AppShell` for SaaS-style left navigation.",props:[{name:"items",type:"(SidebarItem | SidebarSection)[]"},{name:"brand",type:"string",optional:!0,description:"Product name / workspace label at the top"},{name:"tagline",type:"string",optional:!0},{name:"footer",type:"Node[]",optional:!0,description:"Footer block (Avatar + name, upgrade CTA, …)"},{name:"collapsed",type:"boolean",optional:!0,description:"Render as an icon-only rail (hides labels/badges)"}],render:(t,e,r)=>{const a=C(e.collapsed),i=o("aside",{class:"rui-sidebar"});a&&(i.dataset.collapsed="true");const n=d(e.brand),s=d(e.tagline);if(n||s){const u=o("div",{class:"rui-sidebar-header"});n&&u.append(o("div",{class:"rui-sidebar-brand"},[n])),s&&u.append(o("div",{class:"rui-sidebar-tagline"},[s])),i.append(u)}const l=o("nav",{class:"rui-sidebar-body"});for(const u of k(e.items))l.append(r.renderNode(u));i.append(l);const c=k(e.footer);if(c.length>0){const u=o("div",{class:"rui-sidebar-footer"});for(const p of c)u.append(r.renderNode(p));i.append(u)}return i}},sl={name:"AppShell",description:"Canonical SaaS application shell: optional top bar, fixed left Sidebar, and scrollable main content. Reach for this whenever a response represents a full product surface (dashboard with nav, settings + sections, admin panels). Pass `collapsible=true` to render a hamburger that turns the sidebar into a slide-over drawer on narrow viewports.",props:[{name:"sidebar",type:"Sidebar",description:"Pass a Sidebar(...) node"},{name:"content",type:"Node[]",description:"Main content (typically starts with a PageHeader)"},{name:"topbar",type:"Node[]",optional:!0,description:"Optional thin top bar above the content"},{name:"collapsible",type:"boolean",optional:!0,description:"Show a hamburger that toggles the sidebar drawer on mobile"},{name:"sidebarOpen",type:"boolean",optional:!0,description:"$variable controlling whether the mobile drawer is open"}],render:(t,e,r)=>{const a=C(e.collapsible),i=C(e.sidebarOpen),n=o("div",{class:"rui-app-shell"});a&&(n.dataset.collapsible="true"),i&&(n.dataset.sidebarOpen="true");const s=o("div",{class:"rui-app-shell-sidebar"});if(s.append(r.renderNode(e.sidebar)),n.append(s),a){const p=o("div",{class:"rui-app-shell-scrim","aria-hidden":"true"});p.addEventListener("click",()=>{delete n.dataset.sidebarOpen}),n.append(p)}const l=o("div",{class:"rui-app-shell-main"}),c=k(e.topbar);if(c.length>0||a){const p=o("div",{class:"rui-app-shell-topbar"});if(a){const m=o("button",{class:"rui-app-shell-toggle",type:"button","aria-label":"Toggle navigation"});m.append(L("bars",{size:"md"})??document.createTextNode("≡")),m.addEventListener("click",()=>{n.dataset.sidebarOpen?delete n.dataset.sidebarOpen:n.dataset.sidebarOpen="true"}),p.append(m)}for(const m of c)p.append(r.renderNode(m));l.append(p)}const u=o("div",{class:"rui-app-shell-content"});for(const p of k(e.content))u.append(r.renderNode(p));return l.append(u),n.append(l),n}},ll={name:"SplitView",description:"Two-pane master/detail layout — a narrow primary pane on the left, wider detail pane on the right. Collapses to a single column on narrow viewports. Use for inboxes, file browsers, contact lists.",props:[{name:"primary",type:"Node[]",description:"Master pane content (list, filters)"},{name:"detail",type:"Node[]",aliases:["secondary"],description:"Detail pane content (selected item, empty state)"},{name:"primaryWidth",type:"string",optional:!0,aliases:["splitAt"],description:"CSS width for the primary pane (default 320px)"}],render:(t,e,r)=>{const a=ee(d(e.primaryWidth),"320px"),i=o("div",{class:"rui-split-view",style:`--rui-split-primary:${a}`}),n=o("div",{class:"rui-split-view-primary"});for(const l of k(e.primary))n.append(r.renderNode(l));const s=o("div",{class:"rui-split-view-detail"});for(const l of k(e.detail))s.append(r.renderNode(l));return i.append(n,s),i}},cl={name:"DescriptionItem",description:"Single row inside a DescriptionList. Renders a small uppercase label on the left and a value (string or arbitrary Node) on the right.",props:[{name:"label",type:"string"},{name:"value",type:"Node | string"},{name:"icon",type:"string",optional:!0}],render:(t,e,r)=>{const a=o("div",{class:"rui-description-item"}),i=o("dt",{class:"rui-description-label"}),n=L(e.icon,{className:"rui-description-icon"});n&&i.append(n),i.append(document.createTextNode(d(e.label)));const s=o("dd",{class:"rui-description-value"});return e.value&&typeof e.value=="object"&&e.value.__kind==="Component"?s.append(r.renderNode(e.value)):s.append(document.createTextNode(d(e.value))),a.append(i,s),a}},ul={name:"DescriptionList",description:"Compact key/value summary for detail pages — replaces a row of `Text`s with a properly aligned `<dl>`. Children must be DescriptionItem entries. Two columns by default on wide viewports.",props:[{name:"items",type:"DescriptionItem[]"},{name:"columns",type:"number",optional:!0,description:"1 or 2 (default 2)"}],render:(t,e,r)=>{const a=Math.max(1,Math.min(2,Math.floor(Number(e.columns??2)))),i=o("dl",{class:"rui-description-list","data-columns":String(a)});for(const n of k(e.items))i.append(r.renderNode(n));return i}},dl={name:"StatusDot",description:"Inline status pip + label. Use for compact health/state indicators in toolbars, sidebars, lists, and table cells.",props:[{name:"label",type:"string"},{name:"tone",type:"string",optional:!0,enum:["default","primary","success","warning","danger","info"]},{name:"pulse",type:"boolean",optional:!0,description:"Animate the dot for 'live' state"}],render:(t,e)=>{const r=o("span",{class:"rui-status-dot","data-tone":d(e.tone,"success"),"data-pulse":C(e.pulse)?"true":"false"});return r.append(o("span",{class:"rui-status-dot-marker"})),r.append(o("span",{class:"rui-status-dot-label"},[d(e.label)])),r}},pl={name:"PricingCard",description:"Single pricing tier card with plan name, price, billing period, description, bullet features, and a CTA button. Mark one tier as `featured=true` to highlight it (raises the card, adds a ribbon).",props:[{name:"plan",type:"string",description:"Tier name (e.g. 'Pro')"},{name:"price",type:"string",description:"Display price (e.g. '$29')"},{name:"period",type:"string",optional:!0,description:"Billing period (e.g. '/mo')"},{name:"description",type:"string",optional:!0},{name:"features",type:"string[]",optional:!0,description:"Bullet list of included features"},{name:"action",type:"Button",optional:!0,aliases:["cta"],description:"Primary CTA — pass a Button(...)"},{name:"badge",type:"string",optional:!0,description:"Eyebrow / badge above the plan name"},{name:"featured",type:"boolean",optional:!0,aliases:["highlighted"]}],render:(t,e,r)=>{const a=C(e.featured),i=o("article",{class:"rui-pricing-card","data-featured":a?"true":"false"}),n=d(e.badge);n&&i.append(o("div",{class:"rui-pricing-card-badge"},[n])),i.append(o("h3",{class:"rui-pricing-card-plan"},[d(e.plan)]));const s=d(e.description);s&&i.append(o("p",{class:"rui-pricing-card-description"},[s]));const l=o("div",{class:"rui-pricing-card-price-row"});l.append(o("span",{class:"rui-pricing-card-price"},[d(e.price)]));const c=d(e.period);c&&l.append(o("span",{class:"rui-pricing-card-period"},[c])),i.append(l);const u=k(e.features);if(u.length>0){const p=o("ul",{class:"rui-pricing-card-features"});for(const m of u){const g=d(m);if(!g)continue;const f=L("circle-check",{className:"rui-pricing-card-check"})??o("span",{class:"rui-pricing-card-check"});p.append(o("li",{class:"rui-pricing-card-feature"},[f,document.createTextNode(g)]))}i.append(p)}if(e.action){const p=o("div",{class:"rui-pricing-card-action"});p.append(r.renderNode(e.action)),i.append(p)}return i}},ml={name:"PricingTable",description:"Responsive grid of PricingCard tiers. Items size uniformly across a row and wrap onto multiple rows on narrow viewports. Use as the centerpiece of any pricing or upgrade page.",props:[{name:"tiers",type:"PricingCard[]"},{name:"columns",type:"number",optional:!0,description:"Preferred column count (default auto)"}],render:(t,e,r)=>{const a=Math.max(1,Math.min(4,Math.floor(Number(e.columns??"auto")))),i=o("div",{class:"rui-pricing-table","data-columns":a>0?String(a):null});for(const n of k(e.tiers))i.append(r.renderNode(n));return i}},gl={name:"MediaCard",description:'Card with a media (image) header followed by title, body, optional tags, footer meta, and an actions row. Use for article previews, product cards, project highlights, gallery items — anywhere a Card needs a leading image. Orient with `orientation="horizontal"` for side-by-side media + content on wide viewports.',props:[{name:"title",type:"string"},{name:"imageSrc",type:"string",optional:!0,aliases:["src","image"],description:"Image URL (omit to render a neutral placeholder)"},{name:"description",type:"string",optional:!0},{name:"tags",type:"string[]",optional:!0,description:"Tag pill labels"},{name:"meta",type:"string",optional:!0,description:"Footer meta line (author · date · category)"},{name:"actions",type:"Node[]",optional:!0,description:"Buttons / Links rendered at the bottom"},{name:"badge",type:"string | Badge",optional:!0,description:"Eyebrow string or Badge node shown over the image"},{name:"orientation",type:"string",optional:!0,enum:["vertical","horizontal"]},{name:"ratio",type:"string",optional:!0,description:"Media aspect ratio (default 16:9 vertical, 4:3 horizontal)"}],render:(t,e,r)=>{const a=d(e.orientation,"vertical"),i=o("article",{class:"rui-media-card","data-orientation":a}),n=fl(d(e.ratio,a==="horizontal"?"4:3":"16:9")),s=o("div",{class:"rui-media-card-media",style:`aspect-ratio:${n};`}),l=re(e.imageSrc);if(l)s.append(o("img",{src:l,alt:d(e.title),loading:"lazy"}));else{s.classList.add("rui-media-card-media-empty");const f=L("image",{className:"rui-media-card-placeholder"})??o("span",{class:"rui-media-card-placeholder"});s.append(f)}if(e.badge){const f=o("span",{class:"rui-media-card-badge"});typeof e.badge=="string"?f.append(document.createTextNode(d(e.badge))):f.append(r.renderNode(e.badge)),s.append(f)}i.append(s);const c=o("div",{class:"rui-media-card-body"});c.append(o("h3",{class:"rui-media-card-title"},[d(e.title)]));const u=d(e.description);u&&c.append(o("p",{class:"rui-media-card-description"},[u]));const p=k(e.tags);if(p.length>0){const f=o("div",{class:"rui-media-card-tags"});for(const h of p){const b=d(h);b&&f.append(o("span",{class:"rui-tag","data-size":"sm"},[o("span",{class:"rui-tag-label"},[b])]))}c.append(f)}const m=d(e.meta);m&&c.append(o("p",{class:"rui-media-card-meta"},[m]));const g=Te(e.actions,r);return g&&(g.classList.add("rui-media-card-actions"),c.append(g)),i.append(c),i}};function fl(t){if(t.includes(":")){const[r,a]=t.split(":"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n>0)return`${i} / ${n}`}const e=Number(t);return Number.isFinite(e)&&e>0?`${e} / 1`:"16 / 9"}function jt(t,e="primary"){const i="http://www.w3.org/2000/svg",n=document.createElementNS(i,"svg");if(n.setAttribute("class","rui-sparkline"),n.setAttribute("data-tone",e),n.setAttribute("viewBox","0 0 80 24"),n.setAttribute("width",String(80)),n.setAttribute("height",String(24)),n.setAttribute("aria-hidden","true"),t.length<2)return n;const s=Math.min(...t),l=Math.max(...t),c=l-s||1,u=80/(t.length-1),m=t.map((b,v)=>{const y=v*u,x=2+(l-b)/c*20;return[y,x]}).map(([b,v],y)=>`${y===0?"M":"L"}${b.toFixed(1)},${v.toFixed(1)}`).join(" "),g=`${m} L80,24 L0,24 Z`,f=document.createElementNS(i,"path");f.setAttribute("d",g),f.setAttribute("class","rui-sparkline-area"),n.appendChild(f);const h=document.createElementNS(i,"path");return h.setAttribute("d",m),h.setAttribute("class","rui-sparkline-line"),h.setAttribute("fill","none"),n.appendChild(h),n}const hl={name:"Stats",description:'KPI strip or grid. Pass `items` as `{label, value, hint?, tone?, spark?}` objects for strip layout, or as `StatCard(...)` nodes when `layout="grid"`.',props:[{name:"items",type:"object[] | StatCard[]",description:"Stat objects or StatCard nodes when layout=grid"},{name:"layout",type:"string",optional:!0,enum:["strip","grid"],description:"strip = horizontal row; grid = responsive Grid"},{name:"columns",type:"number",optional:!0,description:"Preferred column count for grid layout (1–6)"},{name:"align",type:"string",optional:!0,enum:["start","center","end"],description:"Strip alignment (layout=strip only)"}],render:(t,e,r)=>{const a=k(e.items),i=a.some(c=>c&&typeof c=="object"&&c.__kind==="Component");if(d(e.layout,i?"grid":"strip")==="grid"){const c=e.columns?Math.max(1,Math.min(6,Math.floor(P(e.columns)))):0,u=ga.render({__kind:"Component",name:"Grid",args:[],argMeta:[]},{children:a,columns:c>0?c:"auto",gap:"m"},r);return u.classList.add("rui-metric-grid"),u}const s=d(e.align,"start"),l=o("div",{class:"rui-stats","data-align":s});for(const c of a){const u=c??{},p=d(u.tone,"default"),m=o("div",{class:"rui-stats-item","data-tone":p});m.append(o("div",{class:"rui-stats-label"},[d(u.label)]));const g=o("div",{class:"rui-stats-value-row"});g.append(o("div",{class:"rui-stats-value"},[d(u.value)]));const f=k(u.spark).map(b=>Number(b)).filter(b=>Number.isFinite(b));f.length>1&&g.append(jt(f,p)),m.append(g);const h=d(u.hint);h&&m.append(o("div",{class:"rui-stats-hint"},[h])),l.append(m)}return l}},bl={name:"Tile",description:"Compact icon + label + optional value tile. Smaller and denser than `StatCard`, ideal for menu grids, quick-action panels, category directories, and category filters. Pair with `Grid` for uniform rows.",props:[{name:"label",type:"string"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown in a colored disc"},{name:"value",type:"string",optional:!0,description:"Secondary value rendered next to/under the label"},{name:"description",type:"string",optional:!0},{name:"tone",type:"string",optional:!0,enum:ve},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"]}],render:(t,e,r)=>{const a=typeof e.action=="function",n=o(a?"button":"div",{type:a?"button":null,class:"rui-tile","data-tone":d(e.tone,"default")}),s=L(e.icon,{className:"rui-tile-icon"});s&&n.append(s);const l=o("div",{class:"rui-tile-body"});l.append(o("div",{class:"rui-tile-label"},[d(e.label)]));const c=d(e.value);c&&l.append(o("div",{class:"rui-tile-value"},[c]));const u=d(e.description);return u&&l.append(o("div",{class:"rui-tile-description"},[u])),n.append(l),a&&(n.onclick=()=>r.invoke(e.action)),n}},Sa={name:"Notification",description:"Inline notification card with title, message, time, optional avatar, and dismiss/action buttons. Use inside notification panels, inboxes, or activity drawers — for top-of-page announcements prefer `Banner`.",props:[{name:"title",type:"string"},{name:"message",type:"string",optional:!0,aliases:["description"]},{name:"time",type:"string",optional:!0,description:"Relative or absolute timestamp"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown in a colored disc"},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"],description:"Avatar URL (alternative to `icon`)"},{name:"tone",type:"string",optional:!0,enum:ve},{name:"unread",type:"boolean",optional:!0,description:"Highlights the card with an accent"},{name:"actions",type:"Node[]",optional:!0}],render:(t,e,r)=>{const a=o("article",{class:"rui-notification","data-tone":d(e.tone,"default"),"data-unread":C(e.unread)?"true":"false"}),i=d(e.avatarSrc);if(i)a.append(Ve(i,d(e.title),"md"));else{const p=L(d(e.icon,"bell"),{className:"rui-notification-icon"});p&&a.append(p)}const n=o("div",{class:"rui-notification-body"}),s=o("header",{class:"rui-notification-head"});s.append(o("span",{class:"rui-notification-title"},[d(e.title)]));const l=d(e.time);l&&s.append(o("span",{class:"rui-notification-time"},[l])),n.append(s);const c=d(e.message);c&&n.append(o("p",{class:"rui-notification-message"},[c]));const u=Te(e.actions,r);return u&&(u.classList.add("rui-notification-actions"),n.append(u)),a.append(n),a}},vl={name:"PersonChip",description:'Inline avatar + name + optional role/meta pill. Use anywhere a person needs to be referenced compactly: table cells, list rows, comments, kanban cards, sidebar footers. Pair multiple chips with `Stack(direction="row", wrap=true)` for assignee lists.',props:[{name:"name",type:"string"},{name:"role",type:"string",optional:!0,description:"Sub-line below the name (role, email, handle, …)"},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"]},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]},{name:"status",type:"string",optional:!0,enum:["online","offline","busy","away"]},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"]}],render:(t,e,r)=>{const a=typeof e.action=="function",i=a?"button":"div",n=d(e.size,"md"),s=n==="lg"?"lg":n==="sm"?"sm":"md",l=o(i,{type:a?"button":null,class:"rui-person-chip","data-size":n}),c=o("span",{class:"rui-person-chip-avatar"});c.append(Ve(d(e.avatarSrc),d(e.name),s));const u=d(e.status);u&&c.append(o("span",{class:"rui-person-chip-status","data-status":u})),l.append(c);const p=o("div",{class:"rui-person-chip-meta"});p.append(o("span",{class:"rui-person-chip-name"},[d(e.name)]));const m=d(e.role);return m&&p.append(o("span",{class:"rui-person-chip-role"},[m])),l.append(p),a&&(l.onclick=()=>r.invoke(e.action)),l}},Ca=["left","center","right"],yl={name:"Col",description:"Single column inside a Table or DataGrid. Use `align` for per-column text alignment, `format` for cell rendering (`text|number|currency|date`). `sortable` and `filterable` only take effect inside `DataGrid` (Table ignores them).",props:[{name:"header",type:"string"},{name:"values",type:"any[]",description:"Column values (use array pluck like data.rows.title)"},{name:"format",type:"string",optional:!0,enum:["text","number","currency","date"]},{name:"align",type:"string",optional:!0,enum:Ca,description:"Per-column horizontal alignment"},{name:"sortable",type:"boolean",optional:!0,description:"DataGrid: enable click-to-sort on this column"},{name:"filterable",type:"boolean",optional:!0,description:"DataGrid: enable a per-column filter chip"}],render:(t,e)=>{const r=o("div",{class:"rui-col"});return r.append(o("strong",{},[d(e.header)])),r}},xl={name:"Table",description:'Tabular data view. Children must be Col components. `density="compact"` tightens row padding for dense data, `striped=true` zebra-stripes the rows, and `sticky=true` pins the header row when the table scrolls. The empty-state row uses `emptyLabel` when set.',props:[{name:"columns",type:"Col[]"},{name:"caption",type:"string",optional:!0,aliases:["title"]},{name:"density",type:"string",optional:!0,enum:["comfortable","compact"],description:"Row padding (default `comfortable`)"},{name:"striped",type:"boolean",optional:!0,description:"Zebra-stripe alternating rows"},{name:"sticky",type:"boolean",optional:!0,description:"Pin the header row when the table scrolls"},{name:"emptyLabel",type:"string",optional:!0,description:"Text shown when the table has no rows (default `No data`)"}],render:(t,e,r)=>{const a=k(e.columns),i=d(e.density,"comfortable"),n=C(e.striped),s=C(e.sticky),l=o("div",{class:"rui-table-wrapper","data-density":i,"data-striped":n?"true":"false","data-sticky":s?"true":"false"}),c=o("table",{class:"rui-table"}),u=d(e.caption);u&&c.append(o("caption",{class:"rui-table-caption"},[u]));const p=a.map(y=>{const x=d(y.args?.[3],"");return Ca.includes(x)?x:""}),m=o("thead"),g=o("tr");for(let y=0;y<a.length;y+=1){const x=a[y],w=o("th",{"data-align":p[y]||null},[d(x.args?.[0])]);g.append(w)}m.append(g),c.append(m);const f=o("tbody"),h=a.map(y=>k(y.args?.[1])),b=a.map(y=>d(y.args?.[2],"text")),v=Math.max(0,...h.map(y=>y.length));for(let y=0;y<v;y+=1){const x=o("tr");h.forEach((w,T)=>{const S=w[y],N=b[T]??"text",$=p[T],A=o("td",{"data-format":N,"data-align":$||null});S!==null&&typeof S=="object"&&S.__kind==="Component"?A.append(r.renderNode(S)):A.textContent=Al(S,N),x.append(A)}),f.append(x)}if(v===0){const y=o("tr"),x=d(e.emptyLabel,"No data");y.append(o("td",{colspan:String(a.length||1),class:"rui-table-empty"},[x])),f.append(y)}return c.append(f),l.append(c),l}},wl={name:"ListItem",description:"Single list item with optional title and description.",props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0,aliases:["meta"]},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name"}],render:(t,e)=>{const r=o("li",{class:"rui-list-item"}),a=L(e.icon,{className:"rui-list-icon"});a&&r.append(a);const i=o("div",{class:"rui-list-text"});i.append(o("div",{class:"rui-list-title"},[d(e.title)]));const n=d(e.description);return n&&i.append(o("div",{class:"rui-list-description"},[n])),r.append(i),r}},kl={name:"List",description:"Vertical list of ListItems.",props:[{name:"items",type:"ListItem[]"},{name:"ordered",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=C(e.ordered)?"ol":"ul",i=o(a,{class:"rui-list"});for(const n of k(e.items))i.append(r.renderNode(n));return i}},Sl={name:"StatCard",description:"Single KPI card with label, value, optional delta, optional icon, and optional inline sparkline (`spark=[…numbers]`). Use inside `Stats` for a uniform KPI strip.",props:[{name:"label",type:"string"},{name:"value",type:"string"},{name:"trend",type:"string",optional:!0,enum:["up","down","flat"]},{name:"delta",type:"string",optional:!0,description:"Change vs previous period"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown in a chip beside the label"},{name:"spark",type:"number[]",optional:!0,description:"Optional inline sparkline values"},{name:"tone",type:"string",optional:!0,enum:["default","primary","success","warning","danger","info"]}],render:(t,e)=>{const r=d(e.tone,"default"),a=o("div",{class:"rui-stat-card","data-tone":r}),i=o("div",{class:"rui-stat-label-row"}),n=d(e.label),s=d(e.icon)||ya(n)||"",l=L(s,{className:"rui-stat-icon"});l&&i.append(l),i.append(o("div",{class:"rui-stat-label"},[n])),a.append(i),a.append(o("div",{class:"rui-stat-value"},[d(e.value)]));const c=d(e.delta),u=d(e.trend);(c||u)&&a.append(o("div",{class:"rui-stat-trend","data-trend":u||"flat"},[c||Nl(u)]));const p=k(e.spark).map(m=>P(m));if(p.length>1){const m=o("div",{class:"rui-stat-spark"});m.append(jt(p,r==="default"?"primary":r)),a.append(m)}return a}},Cl={name:"Sparkline",description:"Tiny inline trend chart for KPIs, table cells, and dashboards. Renders an SVG line with a soft fill — use anywhere you would otherwise reach for `LineChart` but a single value series should stay inline with surrounding text.",props:[{name:"values",type:"number[]"},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]}],render:(t,e)=>{const r=d(e.tone,"primary"),a=k(e.values).map(n=>P(n)),i=o("span",{class:"rui-sparkline-wrap"});return i.append(jt(a,r)),i}},Tl={name:"TreeNode",description:"Single node in a Tree view. When `children` is provided the node renders as an expandable branch with a chevron; otherwise it renders as a leaf. `action` fires on click. Use `active=true` to highlight the current selection.",props:[{name:"label",type:"string"},{name:"children",type:"TreeNode[]",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon shown before the label"},{name:"expanded",type:"boolean",optional:!0,description:"Whether the branch is open by default"},{name:"active",type:"boolean",optional:!0,aliases:["selected"],description:"Highlights the row as the current selection"},{name:"badge",type:"string",optional:!0,description:"Trailing chip (count or status)"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Callable fired when the row is clicked"}],render:(t,e,r)=>{const a=k(e.children),i=a.length>0,n=C(e.expanded),s=C(e.active),l=typeof e.action=="function",c=o(l?"button":"div",{type:l?"button":null,class:"rui-tree-node-row",role:"treeitem","data-active":s?"true":"false","aria-expanded":i?n?"true":"false":null});if(i){const h=L("chevron-right",{className:"rui-tree-node-chevron"});h&&c.append(h)}else c.append(o("span",{class:"rui-tree-node-chevron-spacer","aria-hidden":"true"}));const u=L(e.icon,{className:"rui-tree-node-icon"});u&&c.append(u),c.append(o("span",{class:"rui-tree-node-label"},[d(e.label)]));const p=d(e.badge);if(p&&c.append(o("span",{class:"rui-tree-node-badge"},[p])),l&&(c.onclick=()=>r.invoke(e.action)),!i)return c;const m=o("details",{class:"rui-tree-node"});n&&m.setAttribute("open","");const g=o("summary",{class:"rui-tree-node-summary"});g.append(c),l&&(g.onclick=h=>{h.target?.closest(".rui-tree-node-chevron")||h.preventDefault()}),m.append(g);const f=o("div",{class:"rui-tree-node-children",role:"group"});for(const h of a)f.append(r.renderNode(h));return m.append(f),m}},$l={name:"Tree",description:"Hierarchical tree view. Children must be TreeNode entries. Use for file browsers, nested navigation, category pickers, and any parent/child structure with arbitrary depth.",props:[{name:"items",type:"TreeNode[]"}],render:(t,e,r)=>{const a=o("div",{class:"rui-tree",role:"tree"});for(const i of k(e.items))a.append(r.renderNode(i));return a}};function Nl(t){return t==="up"?"▲":t==="down"?"▼":"—"}function Al(t,e){if(t==null)return"";switch(e){case"number":return typeof t=="number"?t.toLocaleString():d(t);case"currency":return typeof t=="number"?t.toLocaleString(void 0,{style:"currency",currency:"USD"}):d(t);case"date":try{const r=new Date(d(t));return Number.isNaN(r.getTime())?d(t):r.toLocaleDateString()}catch{return d(t)}default:return d(t)}}const Bt=["var(--rui-chart-1, #6366f1)","var(--rui-chart-2, #10b981)","var(--rui-chart-3, #f59e0b)","var(--rui-chart-4, #ef4444)","var(--rui-chart-5, #06b6d4)","var(--rui-chart-6, #8b5cf6)"],_e=t=>Bt[t%Bt.length]??Bt[0],Ml={name:"Series",description:"Named data series for charts. Used inside BarChart, LineChart, PieChart.",props:[{name:"name",type:"string"},{name:"values",type:"number[]"}],render:(t,e)=>o("span",{class:"rui-series","data-name":d(e.name)})},Ta=t=>t.map((e,r)=>{const a=e,i=d(a.args?.[0],`Series ${r+1}`),n=k(a.args?.[1]).map(s=>P(s));return{name:i,values:n}}),Pl={name:"BarChart",description:"Vertical bar chart. `labels` define the x-axis, `series` define grouped bars.",props:[{name:"labels",type:"string[]"},{name:"series",type:"Series[]"},{name:"title",type:"string",optional:!0}],render:(t,e)=>{const r=k(e.labels).map(y=>d(y)),a=Ta(k(e.series)),i=o("div",{class:"rui-chart rui-bar-chart"});d(e.title)&&i.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const n=Math.max(1,...a.flatMap(y=>y.values)),s=640,l=240,c=Na(r,s-40-12),u={left:40,right:12,top:12,bottom:c.bottomPadding},p=s-u.left-u.right,m=l-u.top-u.bottom,g=Dt(s,l);Ma(g,u,p,m,n);const f=r.length,h=p/Math.max(f,1),b=a.length,v=h*.7/Math.max(b,1);return a.forEach((y,x)=>{y.values.forEach((w,T)=>{const S=w/n*m,N=u.left+T*h+h*.15+x*v,$=u.top+m-S,A=pe("rect",{x:String(N),y:String($),width:String(Math.max(v-2,1)),height:String(S),fill:_e(x),rx:"2"});A.append(pe("title",{},[`${y.name}: ${w}`])),g.append(A)})}),Aa(g,r,u,p,m,c,y=>u.left+(y+.5)*h),i.append(g),a.length>0&&i.append(Ft(a)),i}},Il={name:"LineChart",description:'Line chart. `labels` define the x-axis, each Series is a line. As a shortcut you can pass `data=[{x: "Jan", revenue: 12, signups: 4}, …]` and the labels + series will be derived automatically (one line per non-`x` key). Use `data` when the dataset is already row-shaped; use `series` when you have explicit Series objects.',props:[{name:"labels",type:"string[]",optional:!0},{name:"series",type:"Series[]",optional:!0},{name:"data",type:"{x: string, [key: string]: number}[]",optional:!0,description:"Row-shaped data — labels and series are auto-derived"},{name:"title",type:"string",optional:!0},{name:"filled",type:"boolean",optional:!0,description:"Fill the area beneath each line (area-chart style)"},{name:"stacked",type:"boolean",optional:!0,description:"Stack series when filled=true"}],render:(t,e)=>{let r=k(e.labels).map($=>d($)),a=Ta(k(e.series));const i=k(e.data);if(i.length>0&&(r.length===0||a.length===0)){const $=[],A=new Map;for(const z of i){const R=z;if(!(!R||typeof R!="object")){$.push(d(R.x??R.label??""));for(const[_,Q]of Object.entries(R)){if(_==="x"||_==="label")continue;const B=P(Q);Number.isNaN(B)||(A.has(_)||A.set(_,[]),A.get(_).push(B))}}}r.length===0&&(r=$),a.length===0&&(a=[...A.entries()].map(([z,R])=>({name:z,values:R})))}const n=e.filled===!0,s=e.stacked===!0,l=Math.max(r.length,...a.map($=>$.values.length),1),c=a.map(()=>Array(l).fill(0));if(n&&s)for(let $=0;$<l;$+=1){let A=0;a.forEach((z,R)=>{A+=z.values[$]??0,c[R][$]=A})}const u=o("div",{class:"rui-chart rui-line-chart","data-filled":n?"true":"false"});d(e.title)&&u.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const p=n&&s?c.flat():a.flatMap($=>$.values),m=Math.max(1,...p),g=n&&s?0:Math.min(0,...p),f=640,h=240,b=Na(r,f-40-12),v={left:40,right:12,top:12,bottom:b.bottomPadding},y=f-v.left-v.right,x=h-v.top-v.bottom,w=Dt(f,h);Ma(w,v,y,x,m,g);const T=Math.max(r.length-1,1),S=y/T,N=$=>v.left+$*(y/Math.max(l-1,1));return a.forEach(($,A)=>{const z=n&&s?c[A]:$.values,R=n&&s&&A>0?c[A-1]:null,_=z.map((B,O)=>{const J=N(O),X=v.top+x-(B-g)/(m-g||1)*x;return[J,X]});if(n&&_.length>0){let B=_.map(([O,J],X)=>`${X===0?"M":"L"}${O.toFixed(1)},${J.toFixed(1)}`).join(" ");if(R){const O=R.map((J,X)=>{const ue=N(X),me=v.top+x-(J-g)/(m-g||1)*x;return[ue,me]});B+=" "+O.slice().reverse().map(([J,X])=>`L${J.toFixed(1)},${X.toFixed(1)}`).join(" ")+" Z"}else{const O=_[0],J=_[_.length-1];B+=` L${J[0].toFixed(1)},${(v.top+x).toFixed(1)} L${O[0].toFixed(1)},${(v.top+x).toFixed(1)} Z`}w.append(pe("path",{d:B,fill:_e(A),"fill-opacity":"0.2",stroke:"none"}))}const Q=_.map(([B,O],J)=>`${J===0?"M":"L"}${B.toFixed(1)},${O.toFixed(1)}`).join(" ");w.append(pe("path",{d:Q,fill:"none",stroke:_e(A),"stroke-width":"2","stroke-linejoin":"round","stroke-linecap":"round"})),$.values.length<=30&&_.forEach(([B,O])=>{w.append(pe("circle",{cx:String(B),cy:String(O),r:"3",fill:_e(A)}))})}),Aa(w,r,v,y,x,b,$=>v.left+$*S),u.append(w),a.length>0&&u.append(Ft(a)),u}},zl={name:"PieChart",description:"Pie/Donut chart. Each segment maps to a label/value pair.",props:[{name:"labels",type:"string[]"},{name:"values",type:"number[]"},{name:"title",type:"string",optional:!0}],render:(t,e)=>{const r=k(e.labels).map(m=>d(m)),a=k(e.values).map(m=>P(m)),i=o("div",{class:"rui-chart rui-pie-chart"});d(e.title)&&i.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const n=a.reduce((m,g)=>m+g,0)||1,s=Dt(240,240),l=120,c=120,u=90;let p=-Math.PI/2;return a.forEach((m,g)=>{const f=m/n*Math.PI*2,h=p+f,b=f>Math.PI?1:0,v=l+u*Math.cos(p),y=c+u*Math.sin(p),x=l+u*Math.cos(h),w=c+u*Math.sin(h),T=`M${l},${c} L${v},${y} A${u},${u} 0 ${b} 1 ${x},${w} Z`,S=pe("path",{d:T,fill:_e(g),stroke:"var(--rui-color-bg, #fff)","stroke-width":"2"});S.append(pe("title",{},[`${r[g]??""}: ${m}`])),s.append(S),p=h}),i.append(s),i.append(Ft(r.map((m,g)=>({name:m,values:[a[g]??0]})))),i}},Rl=7,$a=12;function Na(t,e){if(t.length===0)return{step:1,rotated:!1,maxChars:32,bottomPadding:32};const r=e/Math.max(t.length,1),a=t.reduce((s,l)=>Math.max(s,l.length),0);if(a*Rl+4<=r)return{step:1,rotated:!1,maxChars:a,bottomPadding:32};const i=r<$a?Math.max(1,Math.ceil($a/r)):1,n=Math.min(a,14);return{step:i,rotated:!0,maxChars:n,bottomPadding:60}}function Ll(t,e){return t.length<=e?t:t.slice(0,Math.max(e-1,1))+"…"}function Aa(t,e,r,a,i,n,s){const l=r.top+i+(n.rotated?14:18);e.forEach((c,u)=>{if(u%n.step!==0)return;const p=s(u),m=Ll(c,n.maxChars),g={x:String(p),y:String(l),class:"rui-chart-label","text-anchor":n.rotated?"end":"middle"};n.rotated&&(g.transform=`rotate(-45, ${p}, ${l})`);const f=pe("text",g,[m]);m!==c&&f.append(pe("title",{},[c])),t.append(f)})}function Dt(t,e){const r=document.createElementNS("http://www.w3.org/2000/svg","svg");return r.setAttribute("viewBox",`0 0 ${t} ${e}`),r.setAttribute("class","rui-chart-svg"),r.setAttribute("role","img"),r}function pe(t,e,r){const a=document.createElementNS("http://www.w3.org/2000/svg",t);for(const[i,n]of Object.entries(e))a.setAttribute(i,n);if(r)for(const i of r)a.append(typeof i=="string"?document.createTextNode(i):i);return a}function Ma(t,e,r,a,i,n=0){for(let l=0;l<=4;l+=1){const c=l/4,u=e.top+a-c*a;t.append(pe("line",{x1:String(e.left),x2:String(e.left+r),y1:String(u),y2:String(u),stroke:"var(--rui-color-border-subtle, rgba(0,0,0,0.08))"})),t.append(pe("text",{x:String(e.left-6),y:String(u+3),"text-anchor":"end",class:"rui-chart-tick"},[String(Math.round((n+(i-n)*c)*10)/10)]))}}function Ft(t){const e=o("div",{class:"rui-chart-legend"});return t.forEach((r,a)=>{const i=o("span",{class:"rui-chart-legend-item"});i.append(o("span",{class:"rui-chart-legend-swatch",style:`background:${_e(a)}`})),i.append(o("span",{},[r.name])),e.append(i)}),e}const El={name:"SectionBlock",description:"Titled chat block with a description and child content.",props:[{name:"title",type:"string"},{name:"children",type:"Node[]"},{name:"description",type:"string",optional:!0}],render:(t,e,r)=>{const a=o("section",{class:"rui-section-block"});a.append(o("h3",{class:"rui-section-block-title"},[d(e.title)]));const i=d(e.description);i&&a.append(o("p",{class:"rui-section-block-description"},[i]));for(const n of k(e.children))a.append(r.renderNode(n));return a}},_l={name:"ListBlock",description:"Chat-styled list with bullets, useful for steps or summaries.",props:[{name:"items",type:"string[]"},{name:"ordered",type:"boolean",optional:!0}],render:(t,e)=>{const r=C(e.ordered)?"ol":"ul",a=o(r,{class:"rui-list-block"});for(const i of k(e.items))a.append(o("li",{},[d(i)]));return a}},jl={name:"FollowUpBlock",description:'Suggested follow-up prompts shown as buttons. Each item dispatches its label as an assistant message (equivalent to `emit "assistant-message" { message }`).',props:[{name:"items",type:"FollowUpItem[]",description:"Array of FollowUpItem(label, message?), {label, message} objects, or plain strings"},{name:"title",type:"string",optional:!0}],render:(t,e,r)=>{const a=o("div",{class:"rui-follow-up"}),i=d(e.title,"You can also ask");i&&a.append(o("div",{class:"rui-follow-up-title"},[i]));const n=o("div",{class:"rui-follow-up-list"});for(const s of k(e.items))n.append(Bl(s,r));return a.append(n),a}},Bl=(t,e)=>{const{label:r,message:a}=Dl(t),i=o("button",{class:"rui-follow-up-button",type:"button"},[r]);return i.onclick=()=>{e.sendToAssistant(a)},i},Dl=t=>{if(typeof t=="string")return{label:t,message:t};if(t&&typeof t=="object"){const r=t;if(r.__kind==="Component"&&Array.isArray(r.args)){const n=d(r.args[0]),s=d(r.args[1],n);return{label:n,message:s}}const a=d(r.label),i=d(r.message,a);return{label:a,message:i}}const e=d(t);return{label:e,message:e}},Fl={name:"FollowUpItem",description:"Single follow-up item.",props:[{name:"label",type:"string"},{name:"message",type:"string",optional:!0,description:"Defaults to label"}],render:(t,e,r)=>{const a=d(e.label),i=d(e.message,a),n=o("button",{class:"rui-follow-up-button",type:"button"},[a]);return n.onclick=()=>{r.sendToAssistant(i)},n}},Ol={name:"ActionLink",description:"Inline link that runs an Action when clicked instead of navigating.",props:[{name:"label",type:"string"},{name:"action",type:"callable",aliases:["onClick","onclick"]}],render:(t,e,r)=>{const a=o("a",{class:"rui-action-link",href:"#",role:"button"},[d(e.label)]);return a.onclick=i=>{i.preventDefault(),r.invoke(e.action)},a}},Pa=["sm","md","lg","xl"],Ia={name:"Avatar",description:'User avatar. Shows the image at `src`. When `src` is missing, falls back to a deterministic DiceBear illustration seeded by `name` (pass `fallback="initials"` to render two-letter initials instead). If the image errors at runtime the avatar gracefully degrades to initials.',props:[{name:"name",type:"string",description:"Used for alt text + initials fallback"},{name:"src",type:"string",optional:!0,description:"Image URL"},{name:"size",type:"string",optional:!0,enum:Pa},{name:"status",type:"string",optional:!0,enum:["online","offline","busy","away"]},{name:"fallback",type:"string",optional:!0,enum:["initials","dicebear"],description:"How to render when `src` is missing (default: dicebear illustration; pass `initials` for the two-letter pill)"}],render:(t,e)=>{const r=d(e.size,"md"),a=o("span",{class:"rui-avatar","data-size":r,role:"img"}),i=d(e.name),n=d(e.fallback,"dicebear"),s=re(e.src),l=!s&&n==="dicebear"&&i?re(gs(i)):"",c=s||l;if(c){const p=o("img",{src:c,alt:i,loading:"lazy"});p.onerror=m=>{const g=m;(g.currentTarget??g.target).replaceWith(o("span",{class:"rui-avatar-fallback"},[We(i)]))},a.append(p)}else a.append(o("span",{class:"rui-avatar-fallback"},[We(i)]));const u=d(e.status);return u&&a.append(o("span",{class:"rui-avatar-status","data-status":u})),a}},Ul={name:"AvatarGroup",description:"Stack of overlapping avatars with a `+N` chip when the list overflows. Pass either Avatar(...) nodes or plain {name, src} objects.",props:[{name:"items",type:"Avatar[]",description:"Avatar(...) nodes or {name, src} objects"},{name:"max",type:"number",optional:!0,description:"Maximum avatars to show (default 4)"},{name:"size",type:"string",optional:!0,enum:Pa}],render:(t,e,r)=>{const a=k(e.items),i=Math.max(1,Math.floor(Number(e.max??4))),n=d(e.size,"md"),s=a.slice(0,i),l=a.length-s.length,c=o("div",{class:"rui-avatar-group","data-size":n});for(const u of s){if(u&&typeof u=="object"&&u.__kind==="Component"){c.append(r.renderNode(u));continue}const p=u,m=typeof p=="string"?p:d((p??{}).name),g=typeof p=="string"?"":d((p??{}).src);c.append(Ia.render({__kind:"Component",name:"Avatar",args:[],argMeta:[]},{name:m,src:g,size:n},r))}return l>0&&c.append(o("span",{class:"rui-avatar rui-avatar-overflow","data-size":n},[o("span",{class:"rui-avatar-fallback"},[`+${l}`])])),c}},ql={name:"Progress",description:"Linear progress bar. `value` is clamped between 0 and `max` (default 100). `indeterminate=true` renders a looping animation when the total is unknown. Provide `segments` to render a segmented progress strip (steps in an onboarding flow), or `buffered` for a secondary buffer indicator (downloads, video buffering).",props:[{name:"value",type:"number",optional:!0,description:"Current progress; ignored when indeterminate"},{name:"max",type:"number",optional:!0,description:"Upper bound (default 100)"},{name:"label",type:"string",optional:!0,description:"Shown above the bar"},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]},{name:"indeterminate",type:"boolean",optional:!0},{name:"showValue",type:"boolean",optional:!0,description:"Show the numeric value on the right"},{name:"segments",type:"number",optional:!0,description:"Render N equal segments (filled by current step)"},{name:"buffered",type:"number",optional:!0,description:"Secondary value (0..max) drawn behind the bar"}],render:(t,e)=>{const r=Math.max(1,P(e.max,100)),a=C(e.indeterminate),i=Math.max(0,Math.min(r,P(e.value,0))),n=Math.round(i/r*100),s=Math.max(0,Math.floor(P(e.segments,0))),l=e.buffered!=null?Math.max(0,Math.min(r,P(e.buffered,0))):null,c=o("div",{class:"rui-progress","data-tone":d(e.tone,"primary")}),u=d(e.label),p=C(e.showValue);if(u||p){const g=o("div",{class:"rui-progress-head"});if(g.append(o("span",{class:"rui-progress-label"},[u])),p&&!a){const f=s>0?`${Math.min(s,Math.round(i/r*s))} / ${s}`:`${n}%`;g.append(o("span",{class:"rui-progress-value"},[f]))}c.append(g)}if(s>0&&!a){const g=o("div",{class:"rui-progress-segments",role:"progressbar","aria-valuemin":"0","aria-valuemax":String(s),"aria-valuenow":String(Math.min(s,Math.round(i/r*s)))}),f=Math.min(s,Math.round(i/r*s));for(let h=0;h<s;h+=1)g.append(o("span",{class:"rui-progress-segment","data-filled":h<f?"true":"false"}));return c.append(g),c}const m=o("div",{class:"rui-progress-track",role:"progressbar","aria-valuemin":"0","aria-valuemax":String(r),"aria-valuenow":a?null:String(i),"data-indeterminate":a?"true":"false"});if(l!==null){const g=Math.round(l/r*100);m.append(o("div",{class:"rui-progress-buffer",style:`width:${g}%`,"aria-hidden":"true"}))}return m.append(o("div",{class:"rui-progress-bar",style:a?"":`width:${n}%`})),c.append(m),c}},Hl={name:"Switch",description:"Compact on/off toggle. Pass a `$variable` as `value` for two-way binding — prefer Switch over Checkbox when the control represents a setting.",props:[{name:"id",type:"string"},{name:"label",type:"string",optional:!0},{name:"value",type:"boolean",optional:!0,aliases:["checked"],description:"Bound value (typically $variable)"},{name:"description",type:"string",optional:!0},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("label",{class:"rui-switch",for:a,"data-disabled":C(e.disabled)?"true":"false"}),n=C(e.value),s=o("input",{type:"checkbox",id:a,name:a,class:"rui-switch-input",role:"switch",checked:n?"":null,disabled:C(e.disabled)?"":null});s.checked=n;const l=o("span",{class:"rui-switch-track"},[o("span",{class:"rui-switch-thumb"})]),c=t.argMeta?.[2]?.stateRef;c&&r.bindState(s,c,{event:"change",getValue:m=>m.checked});const u=d(e.label),p=d(e.description);if(i.append(s,l),u||p){const m=o("span",{class:"rui-switch-meta"});u&&m.append(o("span",{class:"rui-switch-label"},[u])),p&&m.append(o("span",{class:"rui-switch-description"},[p])),i.append(m)}return i}},Vl={name:"ToggleGroup",description:"Group of mutually-exclusive Toggle-style buttons (single-select). Items are `[value, label]` arrays, `{value, label, icon?}` objects, or plain strings (used for both value and label). Pass a `$variable` as `value` for two-way binding.",props:[{name:"id",type:"string"},{name:"items",type:"any[]"},{name:"value",type:"any",optional:!0},{name:"variant",type:"string",optional:!0,enum:["default","outline"]},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]}],render:(t,e,r)=>{const a=d(e.value),i=d(e.variant,"outline"),n=d(e.size,"md"),s=o("div",{class:"rui-toggle-group",role:"radiogroup","data-variant":i,"data-size":n}),l=t.argMeta?.[2]?.stateRef;for(const c of k(e.items)){const{value:u,label:p,icon:m}=Wl(c),g=u===a,f=o("button",{type:"button",class:"rui-toggle",role:"radio","aria-checked":g?"true":"false","data-variant":i,"data-size":n,"data-state":g?"on":"off","data-value":u}),h=L(m,{className:"rui-toggle-icon"});h&&f.append(h),f.append(o("span",{class:"rui-toggle-label"},[p])),l&&(f.onclick=()=>{r.setState(l,u)}),s.append(f)}return s}};function Wl(t){if(typeof t=="string")return{value:t,label:t,icon:""};if(Array.isArray(t))return{value:d(t[0]),label:d(t[1],d(t[0])),icon:d(t[2])};if(t&&typeof t=="object"){const e=t,r=d(e.value);return{value:r,label:d(e.label,r),icon:d(e.icon)}}return{value:"",label:"",icon:""}}const Gl={name:"Tooltip",description:"Wraps a trigger node and shows `label` text when the user hovers or focuses it. Pure CSS — no JS needed. Use for short hints (≤6 words); reach for HoverCard when you need rich content.",props:[{name:"label",type:"string"},{name:"trigger",type:"Node",aliases:["children"]},{name:"side",type:"string",optional:!0,enum:["top","bottom","left","right"],aliases:["placement"]}],render:(t,e,r)=>{const a=o("span",{class:"rui-tooltip","data-side":d(e.side,"top"),tabindex:"0"});return a.append(o("span",{class:"rui-tooltip-trigger"},[r.renderNode(e.trigger)])),a.append(o("span",{class:"rui-tooltip-content",role:"tooltip"},[d(e.label)])),a}},Kl={name:"HoverCard",description:"Wraps a trigger node and reveals a card with rich content on hover/focus. Use for previewing a referenced item (profile, link target, definition).",props:[{name:"trigger",type:"Node"},{name:"content",type:"Node[]",aliases:["children"]},{name:"side",type:"string",optional:!0,enum:["top","bottom","left","right"],aliases:["placement"]},{name:"open",type:"boolean",optional:!0,description:"Force the card open (otherwise reveal on hover/focus)"}],render:(t,e,r)=>{const a=o("span",{class:"rui-hover-card","data-side":d(e.side,"bottom"),"data-open":C(e.open)?"true":null,tabindex:"0"});a.append(o("span",{class:"rui-hover-card-trigger"},[r.renderNode(e.trigger)]));const i=o("span",{class:"rui-hover-card-content",role:"dialog"});for(const n of k(e.content))i.append(r.renderNode(n));return a.append(i),a}},Ot={star:{full:"star",half:"star-half-stroke",empty:"regular:star"},heart:{full:"heart",half:"heart",empty:"regular:heart"},thumb:{full:"thumbs-up",half:"thumbs-up",empty:"regular:thumbs-up"},fire:{full:"fire",half:"fire",empty:"regular:fire"},bolt:{full:"bolt",half:"bolt",empty:"regular:bolt"}},Yl={name:"Rating",description:"Compact 0–5 star rating with optional numeric badge and review count. Use in product cards, testimonials, reviews, and KPI rows. Pass `interactive=true` and a `$variable` as `value` to let users rate something; with `halfStep=true` clicking the left half of a star sets a fractional value. `icon` swaps the glyph family — `star` (default), `heart`, `thumb`, `fire`, `bolt`, or any custom Font Awesome name.",props:[{name:"value",type:"number",description:"0–max; can be a $variable when interactive"},{name:"max",type:"number",optional:!0,description:"Maximum number of stars (default 5)"},{name:"label",type:"string",optional:!0,description:'Inline text shown after the stars (e.g. "4.2 of 5")'},{name:"count",type:"number",optional:!0,description:"Review/voter count rendered in parentheses"},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]},{name:"interactive",type:"boolean",optional:!0,description:"Allow clicking a star to set the value"},{name:"readonly",type:"boolean",optional:!0,description:"Force read-only (overrides `interactive`)"},{name:"halfStep",type:"boolean",optional:!0,description:"Allow half-star resolution when interactive"},{name:"icon",type:"string",optional:!0,description:"Icon family — `star` (default), `heart`, `thumb`, `fire`, `bolt`, or any FA name"}],render:(t,e,r)=>{const a=Math.max(1,Math.floor(P(e.max,5))),i=Math.max(0,Math.min(a,P(e.value,0))),n=d(e.size,"md"),s=C(e.interactive)&&!C(e.readonly),l=C(e.halfStep),c=t.argMeta?.[0]?.stateRef,u=Jl(d(e.icon)),p=o("div",{class:"rui-rating","data-size":n,"data-interactive":s&&c?"true":"false","data-half-step":s&&c&&l?"true":"false",role:"img","aria-label":`${i} of ${a}`}),m=o("span",{class:"rui-rating-stars"});for(let h=1;h<=a;h+=1){const b=Math.max(0,Math.min(1,i-(h-1))),v=b>=1?u.full:b>0?u.half:u.empty,y=Lt(v).join(" "),x=o(s&&c?"button":"span",{class:`rui-rating-star ${y}`.trim(),type:s&&c?"button":null,"data-fill":b>=1?"full":b>0?"half":"empty","aria-label":s&&c?`Rate ${h}`:null,"aria-hidden":s&&c?null:"true"});if(s&&c){const w=h,T=h-.5;x.onclick=S=>{let N=w;if(l){const $=S,z=($.currentTarget??$.target).getBoundingClientRect();z.width>0&&$.clientX-z.left<z.width/2&&(N=T)}r.setState(c,N)}}m.append(x)}p.append(m);const g=d(e.label);g&&p.append(o("span",{class:"rui-rating-label"},[g]));const f=e.count!=null?P(e.count,0):null;return f!==null&&f>0&&p.append(o("span",{class:"rui-rating-count"},[`(${f.toLocaleString()})`])),p}};function Jl(t){const e=t.trim().toLowerCase();return e?Ot[e]?Ot[e]:{full:e,half:e,empty:`regular:${e}`}:Ot.star}const Xl={name:"ProgressRing",description:"Circular progress indicator. Use for KPIs, quotas, completion rings, and any metric better shown as a circle than a bar. Renders the value (or a custom label) inside the ring.",props:[{name:"value",type:"number",optional:!0,description:"Current value (ignored when indeterminate)"},{name:"max",type:"number",optional:!0,description:"Upper bound (default 100)"},{name:"label",type:"string",optional:!0,description:'Text shown inside the ring (default "{percent}%")'},{name:"caption",type:"string",optional:!0,aliases:["description"],description:"Small caption rendered under the ring"},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]},{name:"indeterminate",type:"boolean",optional:!0}],render:(t,e)=>{const r=Math.max(1,P(e.max,100)),a=C(e.indeterminate),i=Math.max(0,Math.min(r,P(e.value,0))),n=Math.round(i/r*100),s=d(e.size,"md"),l=s==="lg"?120:s==="sm"?72:96,c=s==="lg"?10:s==="sm"?6:8,u=(l-c)/2,p=2*Math.PI*u,m=a?p*.65:p*(1-n/100),g=o("div",{class:"rui-progress-ring","data-tone":d(e.tone,"primary"),"data-size":s,"data-indeterminate":a?"true":"false"}),f=o("div",{class:"rui-progress-ring-wrap"}),h="http://www.w3.org/2000/svg",b=document.createElementNS(h,"svg");b.setAttribute("width",String(l)),b.setAttribute("height",String(l)),b.setAttribute("viewBox",`0 0 ${l} ${l}`),b.setAttribute("class","rui-progress-ring-svg");const v=document.createElementNS(h,"circle");v.setAttribute("class","rui-progress-ring-track"),v.setAttribute("cx",String(l/2)),v.setAttribute("cy",String(l/2)),v.setAttribute("r",String(u)),v.setAttribute("stroke-width",String(c)),v.setAttribute("fill","none"),b.appendChild(v);const y=document.createElementNS(h,"circle");y.setAttribute("class","rui-progress-ring-bar"),y.setAttribute("cx",String(l/2)),y.setAttribute("cy",String(l/2)),y.setAttribute("r",String(u)),y.setAttribute("stroke-width",String(c)),y.setAttribute("fill","none"),y.setAttribute("stroke-linecap","round"),y.setAttribute("stroke-dasharray",String(p)),y.setAttribute("stroke-dashoffset",String(m)),b.appendChild(y),f.append(b);const x=d(e.label,a?"…":`${n}%`),w=o("span",{class:"rui-progress-ring-value"}),T=L(x,{className:"rui-progress-ring-icon"});T&&Lt(x).length>0?w.append(T):w.append(document.createTextNode(x)),f.append(w),g.append(f);const S=d(e.caption);return S&&g.append(o("span",{class:"rui-progress-ring-caption"},[S])),g}},Zl={name:"ChatBubble",description:'Single chat-style message bubble with author, time, and body. Use for conversation threads, agent transcripts, support chats, and any message-style UI. Set `from="me"` (or any non-empty author) for the active speaker — the bubble aligns to the right with a primary tint. `from="agent"` (default) renders as the canonical incoming bubble on the left.',props:[{name:"author",type:"string"},{name:"body",type:"string",aliases:["text","message"]},{name:"time",type:"string",optional:!0},{name:"avatarSrc",type:"string",optional:!0,aliases:["src"]},{name:"from",type:"string",optional:!0,enum:["agent","me","system"],aliases:["role"],description:"Lane (default agent)"},{name:"status",type:"string",optional:!0,enum:["sending","sent","delivered","read","error"]}],render:(t,e)=>{const r=d(e.from,"agent"),a=o("div",{class:"rui-chat-bubble","data-from":r});r!=="me"&&a.append(za(d(e.avatarSrc),d(e.author)));const i=o("div",{class:"rui-chat-bubble-bubble"}),n=o("header",{class:"rui-chat-bubble-head"});n.append(o("span",{class:"rui-chat-bubble-author"},[d(e.author)]));const s=d(e.time);s&&n.append(o("span",{class:"rui-chat-bubble-time"},[s])),i.append(n),i.append(o("p",{class:"rui-chat-bubble-body"},[d(e.body)]));const l=d(e.status);return l&&i.append(o("span",{class:"rui-chat-bubble-status","data-status":l},[l])),a.append(i),r==="me"&&a.append(za(d(e.avatarSrc),d(e.author))),a}};function za(t,e){const r=o("span",{class:"rui-chat-bubble-avatar"}),a=re(t);return a?r.append(o("img",{src:a,alt:e,loading:"lazy"})):r.append(o("span",{class:"rui-chat-bubble-fallback"},[We(e)])),r}const Ql={name:"Kbd",description:"Renders a keyboard shortcut chip (e.g. `Cmd+K`). Pass a single label, or multiple labels as an array to render a `key + key + …` combo.",props:[{name:"keys",type:"string | string[]"},{name:"size",type:"string",optional:!0,enum:["sm","md"]}],render:(t,e)=>{const r=d(e.size,"md"),a=o("span",{class:"rui-kbd-group","data-size":r});return(Array.isArray(e.keys)?e.keys:[e.keys]).forEach((n,s)=>{const l=d(n);l&&(s>0&&a.append(o("span",{class:"rui-kbd-sep"},["+"])),a.append(o("kbd",{class:"rui-kbd"},[l])))}),a}},ec={name:"Popover",description:"Click-triggered popup with arbitrary rich content. Use when HoverCard's hover trigger is too eager and Modal/Sheet is too heavy — perfect for filter panels, color pickers, share menus, and small settings flyouts. The trigger stays visible while the popover is open — clicking it again, clicking outside, pressing Escape, or clicking the built-in × button all close it.",props:[{name:"trigger",type:"Node",description:"Clickable trigger element (Button, Avatar, IconButton, …). The trigger remains visible while the popover is open."},{name:"content",type:"Node[]",aliases:["children"],description:"Body rendered inside the popover"},{name:"title",type:"string",optional:!0,description:"Optional bold heading rendered above the content"},{name:"side",type:"string",optional:!0,enum:["bottom","top","left","right"],aliases:["placement"],description:'Where the popover opens relative to the trigger (default "bottom")'},{name:"align",type:"string",optional:!0,enum:["start","center","end"],description:'Alignment along the trigger edge (default "start")'},{name:"width",type:"string",optional:!0,description:'CSS width for the popover panel (default "280px")'},{name:"open",type:"boolean",optional:!0,description:"Initial open state — use to demo or pre-open the popover"}],render:(t,e,r)=>{const a=C(e.open),i=r.useInstanceState("open",a),n=i.get(),s=ee(e.width,""),l=o("div",{class:"rui-popover","data-open":n?"true":"false","data-side":d(e.side,"bottom"),"data-align":d(e.align,"start")}),c=o("span",{class:"rui-popover-trigger","data-state":n?"open":"closed","aria-haspopup":"dialog","aria-expanded":n?"true":"false"});c.append(r.renderNode(e.trigger)),l.append(c);const u=o("div",{class:"rui-popover-content",role:"dialog",style:s?`width: ${s};`:null}),p=o("div",{class:"rui-popover-header"}),m=d(e.title);p.append(m?o("div",{class:"rui-popover-title"},[m]):o("span",{class:"rui-popover-title-spacer"}));const g=o("button",{type:"button",class:"rui-popover-close","aria-label":"Close popover"},["×"]);g.onclick=f=>{f.stopPropagation(),st(g,!1,i)},p.append(g),u.append(p);for(const f of k(e.content))u.append(r.renderNode(f));return l.append(u),c.onclick=f=>{f.stopPropagation();const h=f.currentTarget??f.target,b=!i.get(),v=st(h,b,i);b&&v&&Ra(v,i)},c.onkeydown=f=>{const h=f,b=h.currentTarget??h.target;if(h.key==="Enter"||h.key===" "){h.preventDefault();const v=!i.get(),y=st(b,v,i);v&&y&&Ra(y,i)}else h.key==="Escape"&&i.get()&&(h.preventDefault(),st(b,!1,i))},l}},st=(t,e,r)=>{r.set(e);const a=t.closest(".rui-popover");if(!a)return null;a.setAttribute("data-open",e?"true":"false");const i=a.querySelector(".rui-popover-trigger");return i?.setAttribute("aria-expanded",e?"true":"false"),i?.setAttribute("data-state",e?"open":"closed"),e||he(a),a},Ra=(t,e)=>{Ee({liveRoot:t,onDismiss:()=>{e.set(!1),t.setAttribute("data-open","false");const r=t.querySelector(".rui-popover-trigger");r?.setAttribute("aria-expanded","false"),r?.setAttribute("data-state","closed")}})},tc={name:"Toast",description:"Single transient notification card. Always shows a close (×) button that removes the toast from the DOM (and fires `onClose` if set). Pass `duration` (ms) to auto-dismiss, or `position` for a standalone one-off toast (the renderer will pin it to the viewport corner so you do not have to wrap a single notification in `Stack(...)`). Use `Toasts` for grouped stacks; prefer `Banner` for top-of-page announcements and `Notification` for permanent inbox entries.",props:[{name:"title",type:"string"},{name:"message",type:"string",optional:!0,aliases:["description"]},{name:"tone",type:"string",optional:!0,enum:["default","primary","success","warning","danger","info"],description:'Visual accent (default "default")'},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name (default picked from tone)"},{name:"duration",type:"number",optional:!0,description:"Auto-dismiss after N milliseconds (e.g. 4000). Omit to keep the toast until the user closes it."},{name:"action",type:"Button",optional:!0,description:"Optional inline action Button(...) shown above the message"},{name:"onClose",type:"callable",optional:!0,description:"Callable invoked when the toast is dismissed (× button, auto-dismiss, or programmatic)"},{name:"position",type:"string",optional:!0,enum:["top-right","top-left","top-center","bottom-right","bottom-left","bottom-center"],description:"Pin a standalone Toast to a viewport corner without wrapping it in `Stack(...)`"}],render:(t,e,r)=>{const a=d(e.tone,"default"),i=d(e.position),n=o("div",{class:i?"rui-toast rui-toast-standalone":"rui-toast",role:"status","aria-live":a==="danger"?"assertive":"polite","data-tone":a,"data-position":i||null}),s=d(e.icon)||rc(a),l=L(s,{className:"rui-toast-icon"});l&&n.append(l);const c=o("div",{class:"rui-toast-body"});c.append(o("div",{class:"rui-toast-title"},[d(e.title)]));const u=d(e.message);if(u&&c.append(o("div",{class:"rui-toast-message"},[u])),e.action){const x=o("div",{class:"rui-toast-action"});x.append(r.renderNode(e.action)),c.append(x)}n.append(c);const p=r.useInstanceState("dismissed",!1),m=r.useInstanceState("timer",null),g=x=>{if(x){const w=x.closest(".rui-toast");if(w)return w}return n.isConnected?n:null},f=()=>{const x=m.get();x!==null&&(clearTimeout(x),m.set(null))},h=r.useInstanceState("removal-timer",null),b=x=>{if(p.get())return;p.set(!0),f();const w=g(x);if(!w)return;w.classList.add("is-dismissed");const T=setTimeout(()=>{h.set(null),w.remove()},180);h.set(T),r.registerDisposer(()=>{const S=h.get();S!==null&&(clearTimeout(S),h.set(null))},"exit-animation-timer"),r.invoke(e.onClose)},v=o("button",{type:"button",class:"rui-toast-close","aria-label":"Dismiss notification"},["×"]);v.onclick=x=>{x.stopPropagation(),b(x.currentTarget??x.target)},n.append(v);const y=P(e.duration,0);if(y>0&&m.get()===null&&!p.get()){const x=setTimeout(()=>{m.set(null),!p.get()&&n.isConnected&&b()},y);m.set(x),r.registerDisposer(()=>{const w=m.get();w!==null&&(clearTimeout(w),m.set(null))},"auto-dismiss-timer")}return p.get()?o("div",{class:"rui-toast-placeholder",hidden:""}):n}};function rc(t){switch(t){case"success":return"circle-check";case"warning":return"triangle-exclamation";case"danger":return"circle-xmark";case"primary":return"bell";case"info":return"circle-info";default:return"circle-info"}}const La={name:"BreadcrumbItem",description:"Single item inside a Breadcrumb trail. Provide `href` for a link, omit it for the current/leaf page (rendered with emphasis).",props:[{name:"label",type:"string"},{name:"href",type:"string",optional:!0},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name"}],render:(t,e)=>{const r=o("li",{class:"rui-breadcrumb-item"}),a=d(e.label),i=d(e.href),n=i?rt(i):"",s=[],l=L(e.icon,{className:"rui-breadcrumb-icon"});if(l&&s.push(l),s.push(o("span",{class:"rui-breadcrumb-label"},[a])),n)r.append(o("a",{class:"rui-breadcrumb-link",href:n},s));else{r.setAttribute("aria-current","page");const c=o("span",{class:"rui-breadcrumb-current"});for(const u of s)u&&c.append(typeof u=="string"?document.createTextNode(u):u);r.append(c)}return r}},ac={name:"Breadcrumb",description:"Trail of links showing the user's location. Children may be BreadcrumbItem(label, href?) nodes OR plain strings (the last string is treated as the current page).",props:[{name:"items",type:"BreadcrumbItem[] | string[]"},{name:"separator",type:"string",optional:!0,description:"Default `/`"}],render:(t,e,r)=>{const a=k(e.items),i=d(e.separator,"/"),n=o("nav",{class:"rui-breadcrumb","aria-label":"Breadcrumb"}),s=o("ol",{class:"rui-breadcrumb-list"});return a.forEach((l,c)=>{if(c>0&&s.append(o("li",{class:"rui-breadcrumb-separator","aria-hidden":"true"},[i])),l&&typeof l=="object"&&l.__kind==="Component"){s.append(r.renderNode(l));return}const u=d(l),p=c===a.length-1;s.append(La.render({__kind:"Component",name:"BreadcrumbItem",args:[],argMeta:[]},{label:u,href:p?"":"#"},r))}),n.append(s),n}},ic=[10,20,50,100],nc={name:"Pagination",description:'Page navigator with Prev/Next, page numbers, and ellipses. Pass a `$variable` as `page` for two-way binding — clicking a page button sets that state to the new (1-indexed) value. Add `total` to render a "Showing N–M of T" summary, pass `$variable` as `perPage` to expose a per-page selector, or set `compact: true` to drop the page-number row for tight toolbars.',props:[{name:"page",type:"number",description:"Current page (1-indexed); typically a $variable"},{name:"totalPages",type:"number",aliases:["pages"]},{name:"siblings",type:"number",optional:!0,description:"Number of page links shown around the current page (default 1)"},{name:"total",type:"number",optional:!0,description:'Total record count — enables the "Showing N–M of T" summary'},{name:"perPage",type:"number",optional:!0,description:"Bind a `$variable` to expose a per-page selector"},{name:"perPageOptions",type:"number[]",optional:!0,description:"Override the per-page choices (default 10/20/50/100)"},{name:"compact",type:"boolean",optional:!0,description:"Hide page numbers — keep Prev / Next only"}],render:(t,e,r)=>{const a=Math.max(1,Math.floor(P(e.totalPages,1))),i=Math.max(1,Math.min(a,Math.floor(P(e.page,1)))),n=Math.max(0,Math.floor(P(e.siblings,1))),s=C(e.compact),l=t.argMeta?.[0]?.stateRef,c=o("nav",{class:"rui-pagination","aria-label":"Pagination","data-compact":s?"true":"false"}),u=b=>{if(!l)return;const v=Math.max(1,Math.min(a,b));v!==i&&r.setState(l,v)},p=e.total!=null?Math.max(0,Math.floor(P(e.total,0))):null,m=e.perPage!=null?Math.max(1,Math.floor(P(e.perPage,0))):null;if(p!==null&&m&&m>0){const b=p===0?0:(i-1)*m+1,v=Math.min(p,i*m);c.append(o("span",{class:"rui-pagination-summary"},[p===0?"No results":`Showing ${b.toLocaleString()}–${v.toLocaleString()} of ${p.toLocaleString()}`]))}else p!==null&&c.append(o("span",{class:"rui-pagination-summary"},[`${p.toLocaleString()} result${p===1?"":"s"}`]));const g=o("div",{class:"rui-pagination-buttons"}),f=(b,v,y={})=>{if(y.ellipsis)return o("span",{class:"rui-pagination-ellipsis","aria-hidden":"true"},[b]);const x=o("button",{type:"button",class:"rui-pagination-button","data-active":y.active?"true":"false","aria-current":y.active?"page":null,"aria-label":y.ariaLabel??null,disabled:y.disabled?"":null},[b]);return!y.disabled&&!y.active&&(x.onclick=()=>u(v)),x};if(g.append(f("‹",i-1,{disabled:i<=1,ariaLabel:"Previous page"})),s)g.append(o("span",{class:"rui-pagination-current"},[`${i} / ${a}`]));else{const b=oc(i,a,n);for(const v of b)v==="…"?g.append(f("…",0,{ellipsis:!0})):g.append(f(String(v),v,{active:v===i}))}g.append(f("›",i+1,{disabled:i>=a,ariaLabel:"Next page"})),c.append(g);const h=t.argMeta?.[4]?.stateRef;if(m&&(h||k(e.perPageOptions).length>0)){const b=k(e.perPageOptions).length>0?k(e.perPageOptions).map(x=>Math.max(1,Math.floor(Number(x)||0))).filter(x=>x>0):Array.from(ic),v=o("label",{class:"rui-pagination-per-page"},[document.createTextNode("Show ")]),y=o("select",{class:"rui-pagination-per-page-select"});for(const x of b){const w=o("option",{value:String(x),selected:x===m?"":null},[String(x)]);y.append(w)}h&&r.bindState(y,h,{event:"change",getValue:x=>Number(x.value)}),v.append(y),v.append(document.createTextNode(" per page")),c.append(v)}return c}};function oc(t,e,r){const a=[],i=(c,u)=>{for(let p=c;p<=u;p+=1)a.push(p)},n=r*2+5;if(e<=n)return i(1,e),a;const s=Math.max(2,t-r),l=Math.min(e-1,t+r);return a.push(1),s>2&&a.push("…"),i(s,l),l<e-1&&a.push("…"),a.push(e),a}const sc={name:"NavbarItem",description:"Single link inside a Navbar's main item slot. Renders as an inline anchor / button — pass `to` for a router-aware link, `href` for an external link, or `action` for a click handler. `active=true` highlights the current page.",props:[{name:"label",type:"string"},{name:"to",type:"string",optional:!0,description:"Internal route (consumes the built-in router)"},{name:"href",type:"string",optional:!0,description:"External href; opens in a new tab when set with `external=true`"},{name:"icon",type:"string",optional:!0},{name:"active",type:"boolean",optional:!0},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Callable fired on click (alternative to `to`/`href`)"},{name:"external",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.label),i=e.icon,n=C(e.active),s=d(e.to),l=rt(e.href,""),c=C(e.external),u=s||l?"a":"button",p=o(u,{class:"rui-navbar-item",type:u==="button"?"button":null,href:l||(s?`#${s.startsWith("/")?s:`/${s}`}`:null),target:c&&l?"_blank":null,rel:c&&l?"noopener noreferrer":null,"data-active":n?"true":"false"}),m=L(i,{className:"rui-navbar-item-icon"});return m&&p.append(m),p.append(o("span",{class:"rui-navbar-item-label"},[a])),s&&!l?p.onclick=g=>{if(g.defaultPrevented)return;const f=g;f.button!==0||f.metaKey||f.ctrlKey||f.shiftKey||f.altKey||(g.preventDefault(),r.router.navigate(s))}:typeof e.action=="function"&&(p.onclick=g=>{g.preventDefault(),r.invoke(e.action)}),p}},lc={name:"Navbar",description:"Top navigation bar with a brand on the left, primary nav items in the middle, and a right-aligned actions slot (user avatar, DropdownMenu, CTA buttons, …). Use `sticky=true` to pin it to the top of the page. The canonical companion of `Sidebar` for product surfaces; prefer Navbar for marketing/docs pages without a sidebar.",props:[{name:"brand",type:"string | Node",optional:!0,description:"Workspace/product name (string) or a node (e.g. logo Image)"},{name:"items",type:"NavbarItem[]",optional:!0,description:"Center navigation items"},{name:"actions",type:"Node[]",optional:!0,description:"Right-side controls (Buttons, Avatar, DropdownMenu, …)"},{name:"sticky",type:"boolean",optional:!0,description:"Pin the bar to the top of the viewport"},{name:"variant",type:"string",optional:!0,enum:["default","transparent"],description:"Visual variant"}],render:(t,e,r)=>{const a=o("nav",{class:"rui-navbar","data-sticky":C(e.sticky)?"true":"false","data-variant":d(e.variant,"default"),"aria-label":"Primary"}),i=e.brand;if(i!=null&&i!==""){const l=o("div",{class:"rui-navbar-brand"});typeof i=="string"?l.append(document.createTextNode(i)):l.append(r.renderNode(i)),a.append(l)}const n=k(e.items);if(n.length>0){const l=o("div",{class:"rui-navbar-items"});for(const c of n)l.append(r.renderNode(c));a.append(l)}const s=k(e.actions);if(s.length>0){const l=o("div",{class:"rui-navbar-actions"});for(const c of s)l.append(r.renderNode(c));a.append(l)}return a}},cc=["bottom","top","left","right"],uc=["start","center","end"],dc=["default","danger"],lt=(t,e,r)=>{r.set(e);const a=t.closest(".rui-dropdown-menu");return a?(a.setAttribute("data-open",e?"true":"false"),a.querySelector(".rui-dropdown-menu-trigger")?.setAttribute("aria-expanded",e?"true":"false"),e||he(a),a):null},Ea=(t,e)=>{Ee({liveRoot:t,onDismiss:()=>{e.set(!1),t.setAttribute("data-open","false"),t.querySelector(".rui-dropdown-menu-trigger")?.setAttribute("aria-expanded","false")}})},Ut=(t,e)=>{if(!t||typeof t!="object")return!1;const r=t;return r.__kind==="Component"&&r.name===e},pc={name:"DropdownMenu",description:"Click-triggered dropdown menu. Click the trigger to toggle, click a MenuItem to run its action and close, click outside or press Escape to close without acting. Children must be MenuItem, MenuSeparator, or MenuLabel entries.",props:[{name:"trigger",type:"Node",description:"Clickable trigger element (typically a Button or Avatar)"},{name:"items",type:"(MenuItem | MenuSeparator | MenuLabel)[]"},{name:"side",type:"string",optional:!0,enum:cc,description:'Where the menu opens relative to the trigger (default "bottom")'},{name:"align",type:"string",optional:!0,enum:uc,description:'How the menu aligns along the trigger edge (default "start")'},{name:"label",type:"string",optional:!0,description:"Optional ARIA label for the menu"},{name:"open",type:"boolean",optional:!0,description:"Initial open state — use to demo or pre-open the menu"}],render:(t,e,r)=>{const a=C(e.open),i=r.useInstanceState("open",a),n=i.get(),s=o("div",{class:"rui-dropdown-menu","data-open":n?"true":"false","data-side":d(e.side,"bottom"),"data-align":d(e.align,"start")}),l=o("span",{class:"rui-dropdown-menu-trigger","data-state":n?"open":"closed","aria-haspopup":"menu","aria-expanded":n?"true":"false",tabindex:"0"});l.append(r.renderNode(e.trigger)),l.onclick=u=>{u.stopPropagation();const p=u.currentTarget??u.target,m=!i.get(),g=lt(p,m,i);m&&g&&Ea(g,i)},l.onkeydown=u=>{const p=u,m=p.currentTarget??p.target;if(p.key==="Enter"||p.key===" "){p.preventDefault();const g=!i.get(),f=lt(m,g,i);g&&f&&Ea(f,i);return}p.key==="Escape"&&i.get()&&(p.preventDefault(),lt(m,!1,i))},s.append(l);const c=o("div",{class:"rui-dropdown-menu-content",role:"menu","aria-label":d(e.label)||null});for(const u of k(e.items)){if(Ut(u,"MenuItem")){const p=u.args??[],m=d(p[0]),g=p[1],f=p[2],h=d(p[3]),b=d(p[4],"default"),v=C(p[5]),y=o("button",{type:"button",class:"rui-menu-item",role:"menuitem","data-variant":b,disabled:v?"":null}),x=L(f,{className:"rui-menu-item-icon"});x&&y.append(x),y.append(o("span",{class:"rui-menu-item-label"},[m])),h&&y.append(o("span",{class:"rui-menu-item-shortcut"},[h])),v||(y.onclick=w=>{const T=w.currentTarget??w.target;lt(T,!1,i),r.invoke(g)}),c.append(y);continue}if(Ut(u,"MenuSeparator")){c.append(o("div",{class:"rui-menu-separator",role:"separator"}));continue}if(Ut(u,"MenuLabel")){const p=d((u.args??[])[0]);c.append(o("div",{class:"rui-menu-label"},[p]));continue}c.append(r.renderNode(u))}return s.append(c),s}},mc={name:"MenuItem",description:"Single item inside a DropdownMenu. Renders a button-style row with an optional leading icon and trailing keyboard-shortcut hint. The action argument runs when clicked; the menu closes automatically afterwards.",props:[{name:"label",type:"string"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"],description:"Callable to execute on click"},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon name shown before the label"},{name:"shortcut",type:"string",optional:!0,description:'Trailing keyboard-shortcut hint (e.g. "⌘ K")'},{name:"variant",type:"string",optional:!0,enum:dc,description:'Use "danger" for destructive actions'},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=C(e.disabled),i=o("button",{type:"button",class:"rui-menu-item",role:"menuitem","data-variant":d(e.variant,"default"),disabled:a?"":null}),n=L(e.icon,{className:"rui-menu-item-icon"});n&&i.append(n),i.append(o("span",{class:"rui-menu-item-label"},[d(e.label)]));const s=d(e.shortcut);return s&&i.append(o("span",{class:"rui-menu-item-shortcut"},[s])),a||(i.onclick=()=>{r.invoke(e.action)}),i}},gc={name:"MenuSeparator",description:"Thin horizontal rule used inside a DropdownMenu to group items.",props:[],render:()=>o("div",{class:"rui-menu-separator",role:"separator"})},fc={name:"MenuLabel",description:'Small uppercase section header inside a DropdownMenu. Use to group related MenuItems (e.g. "Account", "Workspace", "Danger zone").',props:[{name:"label",type:"string"}],render:(t,e)=>o("div",{class:"rui-menu-label"},[d(e.label)])},hc=["left","center","right"];function bc(t){return k(t).map((e,r)=>{const a=e.args??[],i=d(a[0]);return{header:i,values:k(a[1]),format:d(a[2],"text"),align:hc.includes(d(a[3]))?d(a[3]):"",sortable:C(a[4]),filterable:C(a[5]),key:i||`col-${r}`}})}function _a(t,e,r){if(t==null)return e==null?0:1;if(e==null)return-1;if(r==="number"||r==="currency")return P(t,0)-P(e,0);if(r==="date"){const a=new Date(d(t)).getTime(),i=new Date(d(e)).getTime();if(Number.isFinite(a)&&Number.isFinite(i))return a-i}return d(t).localeCompare(d(e))}function ct(t,e){if(t==null)return"";switch(e){case"number":return typeof t=="number"?t.toLocaleString():d(t);case"currency":return typeof t=="number"?t.toLocaleString(void 0,{style:"currency",currency:"USD"}):d(t);case"date":try{const r=new Date(d(t));return Number.isNaN(r.getTime())?d(t):r.toLocaleDateString()}catch{return d(t)}default:return d(t)}}const vc={name:"DataGrid",description:"Advanced data table with sortable headers, per-column filter chips, row selection (checkboxes), sticky header / first column, optional pagination, an optional bulk-action toolbar slot, and click-to-act rows. Columns are Col(header, values, format?, align?, sortable?, filterable?) entries. Bind `$sort` (`{key, direction}` object), `$selectedIds` (string[]), and `$page` (number) for full reactivity. Use INSTEAD of `Table` when you need any of those interactions.",props:[{name:"columns",type:"Col[]",description:"Columns; pass sortable=true / filterable=true on each Col."},{name:"rowIds",type:"any[]",optional:!0,description:"Stable id per row (used by `selectedIds`); defaults to row index."},{name:"caption",type:"string",optional:!0},{name:"sort",type:"object",optional:!0,description:"`{key, direction}` — pass a $variable for two-way binding"},{name:"selectedIds",type:"any[]",optional:!0,description:"Array of selected row ids — bind a $variable"},{name:"selectable",type:"boolean",optional:!0,description:"Render leading selection checkboxes"},{name:"page",type:"number",optional:!0,description:"1-indexed current page — bind a $variable"},{name:"perPage",type:"number",optional:!0,description:"Page size (default 20)"},{name:"emptyLabel",type:"string",optional:!0,description:"Text shown when no rows match (default `No results`)"},{name:"rowAction",type:"callable",optional:!0,description:"Callable fired when a row is clicked"},{name:"toolbar",type:"Node[]",optional:!0,description:"Bulk-action toolbar shown above the table when any rows are selected"},{name:"density",type:"string",optional:!0,enum:["comfortable","compact"]},{name:"striped",type:"boolean",optional:!0},{name:"stickyHeader",type:"boolean",optional:!0,description:"Pin the header row (default true)"},{name:"stickyFirstColumn",type:"boolean",optional:!0,description:"Pin the first column horizontally"}],render:(t,e,r)=>{const a=bc(e.columns),i=Math.max(0,...a.map(E=>E.values.length)),n=k(e.rowIds),s=E=>d(n[E]??E),l=e.sort&&typeof e.sort=="object"?e.sort:null,c=d(l?.key),u=d(l?.direction,"asc")==="desc"?"desc":"asc",p=k(e.selectedIds).map(E=>d(E)),m=new Set(p),g=C(e.selectable)||t.argMeta?.[4]?.stateRef!==void 0,f=e.stickyHeader===void 0?!0:C(e.stickyHeader),h=C(e.stickyFirstColumn),b=d(e.density,"comfortable"),v=C(e.striped),y=r.useInstanceState("filters",{}),x=y.get(),w=[];for(let E=0;E<i;E+=1){let H=!0;for(const V of a){if(!V.filterable)continue;const q=(x[V.key]??"").trim().toLowerCase();if(!q)continue;const te=V.values[E];if(!ct(te,V.format).toLowerCase().includes(q)){H=!1;break}}H&&w.push(E)}if(c){const E=a.find(H=>H.key===c);E&&E.sortable&&w.sort((H,V)=>{const q=_a(E.values[H],E.values[V],E.format);return u==="desc"?-q:q})}const T=w.length,S=Math.max(1,Math.floor(P(e.perPage,20))),N=Math.max(1,Math.ceil(T/S)),$=Math.max(1,Math.floor(P(e.page,1))),A=Math.min($,N),z=w.slice((A-1)*S,A*S),R=o("div",{class:"rui-data-grid","data-density":b,"data-striped":v?"true":"false","data-sticky-header":f?"true":"false","data-sticky-first":h?"true":"false"}),_=t.argMeta?.[3]?.stateRef,Q=t.argMeta?.[4]?.stateRef,B=t.argMeta?.[6]?.stateRef,O=k(e.toolbar);if(p.length>0&&O.length>0){const E=o("div",{class:"rui-data-grid-bulk"});E.append(o("span",{class:"rui-data-grid-bulk-count"},[`${p.length} selected`]));const H=o("div",{class:"rui-data-grid-bulk-tools"});for(const V of O)H.append(r.renderNode(V));E.append(H),R.append(E)}const J=o("div",{class:"rui-data-grid-scroll"}),X=o("table",{class:"rui-data-grid-table"}),ue=d(e.caption);ue&&X.append(o("caption",{class:"rui-data-grid-caption"},[ue]));const me=o("thead"),Je=o("tr");if(g){const E=o("th",{class:"rui-data-grid-cell-select",scope:"col"}),H=z.length>0&&z.every(q=>m.has(s(q))),V=o("input",{type:"checkbox",class:"rui-data-grid-checkbox","aria-label":"Select all rows on this page",checked:H?"":null});Q&&(V.onclick=q=>{const te=q.currentTarget,Z=new Set(p);for(const K of z){const Y=s(K);te.checked?Z.add(Y):Z.delete(Y)}r.setState(Q,Array.from(Z))}),E.append(V),Je.append(E)}if(a.forEach((E,H)=>{const V=o("th",{scope:"col","data-align":E.align||null,"data-sortable":E.sortable?"true":null,"data-active":E.sortable&&E.key===c?"true":null,"data-first":H===0?"true":null});if(E.sortable&&_){const q=o("button",{type:"button",class:"rui-data-grid-sort"});q.append(o("span",{},[E.header]));const te=E.key===c?u==="asc"?"arrow-up-short-wide":"arrow-down-wide-short":"sort",Z=L(te,{className:"rui-data-grid-sort-icon"});Z&&q.append(Z),q.onclick=()=>{const K=E.key===c&&u==="asc"?"desc":"asc";r.setState(_,{key:E.key,direction:K})},V.append(q)}else V.append(document.createTextNode(E.header));Je.append(V)}),me.append(Je),a.some(E=>E.filterable)){const E=o("tr",{class:"rui-data-grid-filter-row"});g&&E.append(o("td",{class:"rui-data-grid-cell-select"})),a.forEach(H=>{const V=o("td");if(H.filterable){const q=o("input",{type:"search",class:"rui-data-grid-filter",placeholder:`Filter ${H.header}`,value:x[H.key]??""});q.oninput=te=>{const Z=te.currentTarget,K={...y.get(),[H.key]:Z.value};y.set(K);const Y=Z.closest("table")?.querySelector("tbody");sp(Y)},V.append(q)}E.append(V)}),me.append(E)}X.append(me);const Ae=o("tbody");X.append(Ae);const tr=E=>{if(Ae.replaceChildren(),E.length===0){const H=o("tr"),V=(g?1:0)+Math.max(a.length,1);H.append(o("td",{colspan:String(V),class:"rui-data-grid-empty"},[d(e.emptyLabel,"No results")])),Ae.append(H);return}for(const H of E){const V=s(H),q=m.has(V),te=o("tr",{"data-selected":q?"true":null});if(g){const Z=o("td",{class:"rui-data-grid-cell-select"}),K=o("input",{type:"checkbox",class:"rui-data-grid-checkbox","aria-label":"Select row",checked:q?"":null});Q&&(K.onclick=Y=>{Y.stopPropagation();const ne=Y.currentTarget,de=new Set(p);ne.checked?de.add(V):de.delete(V),r.setState(Q,Array.from(de))}),Z.append(K),te.append(Z)}a.forEach((Z,K)=>{const Y=Z.values[H],ne=o("td",{"data-format":Z.format,"data-align":Z.align||null,"data-first":K===0?"true":null});Y!==null&&typeof Y=="object"&&Y.__kind==="Component"?ne.append(r.renderNode(Y)):ne.textContent=ct(Y,Z.format),te.append(ne)}),typeof e.rowAction=="function"&&(te.setAttribute("data-clickable","true"),te.onclick=Z=>{Z.target?.closest("input,button,a,label,select,textarea")||r.invoke(e.rowAction)}),Ae.append(te)}},sp=E=>{const H=E??Ae,V=y.get(),q=[];for(let K=0;K<i;K+=1){let Y=!0;for(const ne of a){if(!ne.filterable)continue;const de=(V[ne.key]??"").trim().toLowerCase();if(!de)continue;const Xe=ne.values[K];if(!ct(Xe,ne.format).toLowerCase().includes(de)){Y=!1;break}}Y&&q.push(K)}if(c){const K=a.find(Y=>Y.key===c);K&&K.sortable&&q.sort((Y,ne)=>{const de=_a(K.values[Y],K.values[ne],K.format);return u==="desc"?-de:de})}const te=q.slice((A-1)*S,A*S);(K=>{K.replaceChildren();for(const Y of te){const ne=s(Y),de=m.has(ne),Xe=o("tr",{"data-selected":de?"true":null});if(g){const Me=o("td",{class:"rui-data-grid-cell-select"}),rr=o("input",{type:"checkbox",class:"rui-data-grid-checkbox",checked:de?"":null});Me.append(rr),Xe.append(Me)}a.forEach((Me,rr)=>{const Ze=Me.values[Y],ar=o("td",{"data-format":Me.format,"data-align":Me.align||null,"data-first":rr===0?"true":null});Ze!==null&&typeof Ze=="object"&&Ze.__kind==="Component"?ar.append(r.renderNode(Ze)):ar.textContent=ct(Ze,Me.format),Xe.append(ar)}),K.append(Xe)}if(te.length===0){const Y=o("tr"),ne=(g?1:0)+Math.max(a.length,1);Y.append(o("td",{colspan:String(ne),class:"rui-data-grid-empty"},[d(e.emptyLabel,"No results")])),K.append(Y)}})(H)};if(tr(z),J.append(X),R.append(J),T>S){const E=o("div",{class:"rui-data-grid-footer"}),H=T===0?0:(A-1)*S+1,V=Math.min(T,A*S);E.append(o("span",{class:"rui-data-grid-footer-summary"},[T===0?"No results":`Showing ${H}–${V} of ${T}`]));const q=o("div",{class:"rui-data-grid-footer-buttons"}),te=o("button",{type:"button",class:"rui-data-grid-page-button",disabled:A<=1?"":null},["‹ Prev"]),Z=o("button",{type:"button",class:"rui-data-grid-page-button",disabled:A>=N?"":null},["Next ›"]);B&&(te.onclick=()=>{A<=1||r.setState(B,A-1)},Z.onclick=()=>{A>=N||r.setState(B,A+1)}),q.append(te),q.append(o("span",{class:"rui-data-grid-page-current"},[`${A} / ${N}`])),q.append(Z),E.append(q),R.append(E)}return R}};function yc(t){const e=[];for(const r of k(t)){if(!r||typeof r!="object")continue;const a=r,i=d(a.date);i&&e.push({date:i,title:d(a.title),tone:d(a.tone,"primary"),time:d(a.time)})}return e}function ja(t,e){const r=new Date(t.getFullYear(),t.getMonth(),t.getDate()),i=(r.getDay()-e+7)%7;return r.setDate(r.getDate()-i),r}function Ba(t){const e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0");return`${e}-${r}-${a}`}const xc={name:"CalendarView",description:"Full-month or week calendar grid for scheduling apps — distinct from the form-input `DatePicker`. Pass events as an array of `{date: 'YYYY-MM-DD', title, tone?, time?}` objects. Bind `value` to a `$variable` for the selected date (ISO string). Use `view=\"week\"` for a single-week strip. `firstDay=1` (Monday) matches most business apps.",props:[{name:"value",type:"string",optional:!0,description:"Selected ISO date (YYYY-MM-DD); bind a $variable"},{name:"month",type:"string",optional:!0,description:"Reference month — ISO date or YYYY-MM (defaults to today)"},{name:"events",type:"object[]",optional:!0,description:"Array of {date, title, tone?, time?} objects"},{name:"view",type:"string",optional:!0,enum:["month","week"]},{name:"firstDay",type:"number",optional:!0,description:"0=Sunday, 1=Monday (default 1)"},{name:"onSelect",type:"callable",optional:!0,description:"Callable fired when a day is clicked; receives the ISO date string"}],render:(t,e,r)=>{const a=d(e.view,"month"),i=yc(e.events),n=d(e.value),s=d(e.month,n),l=new Date;let c=new Date(NaN);if(s){const S=/^(\d{4})-(\d{2})(?:-(\d{2}))?$/.exec(s);if(S)c=new Date(Number(S[1]),Number(S[2])-1,S[3]?Number(S[3]):1);else{const N=new Date(s);Number.isNaN(N.getTime())||(c=N)}}Number.isNaN(c.getTime())&&(c=l);const u=(P(e.firstDay,1)%7+7)%7,p=n&&/^\d{4}-\d{2}-\d{2}$/.test(n)?n:"",m=new Map;for(const S of i){const N=S.date.slice(0,10),$=m.get(N)??[];$.push(S),m.set(N,$)}const g=t.argMeta?.[0]?.stateRef,f=o("div",{class:"rui-calendar","data-view":a}),h=o("div",{class:"rui-calendar-header"}),b=c.toLocaleDateString(void 0,{month:"long",year:"numeric"});h.append(o("div",{class:"rui-calendar-title"},[b])),f.append(h);const v=o("div",{class:"rui-calendar-weekrow"}),y=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];for(let S=0;S<7;S+=1){const N=y[(u+S)%7]??"";v.append(o("div",{class:"rui-calendar-weekday"},[N]))}f.append(v);const x=[];if(a==="week"){const S=p?new Date(p):c,N=ja(S,u);for(let $=0;$<7;$+=1){const A=new Date(N);A.setDate(N.getDate()+$),x.push({date:A,inMonth:A.getMonth()===c.getMonth()})}}else{const S=new Date(c.getFullYear(),c.getMonth(),1),N=new Date(c.getFullYear(),c.getMonth()+1,0),$=ja(S,u),A=Math.ceil((N.getDate()+(S.getDay()-u+7)%7)/7)*7;for(let z=0;z<A;z+=1){const R=new Date($);R.setDate($.getDate()+z),x.push({date:R,inMonth:R.getMonth()===c.getMonth()})}}const w=o("div",{class:"rui-calendar-grid","data-view":a}),T=Ba(l);for(const S of x){const N=Ba(S.date),$=N===T,A=N===p,z=m.get(N)??[],R=o("button",{type:"button",class:"rui-calendar-day","data-in-month":S.inMonth?"true":"false","data-today":$?"true":"false","data-selected":A?"true":"false","aria-label":S.date.toDateString()});if(R.append(o("span",{class:"rui-calendar-daynumber"},[String(S.date.getDate())])),z.length>0){const _=o("div",{class:"rui-calendar-day-events"}),Q=z.slice(0,3);for(const B of Q){const O=o("span",{class:"rui-calendar-event","data-tone":B.tone??"primary",title:B.time?`${B.time} — ${B.title}`:B.title},[B.title]);_.append(O)}z.length>3&&_.append(o("span",{class:"rui-calendar-event-more"},[`+${z.length-3} more`])),R.append(_)}R.onclick=()=>{g&&r.setState(g,N),r.invoke(e.onSelect,N)},w.append(R)}return f.append(w),f}};function wc(t){const e=[];for(const r of k(t)){if(!r||typeof r!="object")continue;const a=r;e.push({title:d(a.title),description:d(a.description),actor:d(a.actor),avatarSrc:d(a.avatarSrc),time:d(a.time),icon:d(a.icon),tone:d(a.tone,"default"),meta:d(a.meta)})}return e}function kc(t,e,r){const a=o("ol",{class:t,"data-variant":r});for(const i of e){const n=o("li",{class:`${t}-item`,"data-tone":i.tone}),s=o("span",{class:`${t}-marker`}),l=L(i.icon,{className:`${t}-icon`});l&&s.append(l),n.append(s);const c=o("div",{class:`${t}-body`}),u=o("div",{class:`${t}-head`});i.actor&&u.append(o("span",{class:`${t}-actor`},[i.actor])),u.append(o("span",{class:`${t}-title`},[i.title])),i.time&&u.append(o("span",{class:`${t}-time`},[i.time])),c.append(u),i.description&&c.append(o("p",{class:`${t}-description`},[i.description])),i.meta&&c.append(o("span",{class:`${t}-meta`},[i.meta])),n.append(c),a.append(n)}return a}const Sc={name:"ActivityLog",description:'Purpose-built feed of user/system activity. Each entry has `actor`, `title`, `description?`, `time?`, `icon?`, `tone?`, and optional `meta` (IP, browser, request id). Use `variant="audit"` for monospace security/admin trails. Pass items as `{actor, title, description, time, icon, tone, avatarSrc, meta}` objects.',props:[{name:"items",type:"object[]"},{name:"variant",type:"string",optional:!0,enum:["default","audit"],description:"audit = monospace voice with meta column"}],render:(t,e)=>{const r=d(e.variant,"default");return kc(r==="audit"?"rui-audit-trail":"rui-activity-log",wc(e.items),r)}},Cc={name:"ComparisonTable",description:"Feature/spec comparison table — generic counterpart of `PricingTable`. Pass `columns` (e.g. plan/product names) and `rows` of `{label, values}` where `values` aligns 1-to-1 with `columns`. Each value can be a boolean (✓/—), a string, or a node.",props:[{name:"columns",type:"string[]",description:"Column headers"},{name:"rows",type:"object[]",description:"Array of {label, values, hint?, group?} entries"},{name:"highlightColumn",type:"number",optional:!0,description:"0-indexed column to visually emphasise"}],render:(t,e,r)=>{const a=k(e.columns).map(g=>d(g)),i=k(e.rows).map(g=>{const f=g??{};return{label:d(f.label),values:k(f.values),hint:d(f.hint),group:d(f.group)}}),n=Math.floor(P(e.highlightColumn,-1)),s=o("div",{class:"rui-comparison-table"}),l=o("table"),c=o("thead"),u=o("tr");u.append(o("th",{scope:"col",class:"rui-comparison-table-feature"},["Feature"])),a.forEach((g,f)=>{u.append(o("th",{scope:"col","data-highlight":f===n?"true":null},[g]))}),c.append(u),l.append(c);const p=o("tbody");let m="";for(const g of i){if(g.group&&g.group!==m){m=g.group;const b=o("tr",{class:"rui-comparison-table-group"});b.append(o("td",{colspan:String(a.length+1)},[g.group])),p.append(b)}const f=o("tr"),h=o("td",{class:"rui-comparison-table-feature"});h.append(o("div",{class:"rui-comparison-table-feature-label"},[g.label])),g.hint&&h.append(o("div",{class:"rui-comparison-table-feature-hint"},[g.hint])),f.append(h);for(let b=0;b<a.length;b+=1){const v=g.values[b],y=o("td",{"data-highlight":b===n?"true":null});if(v===!0){const x=L("circle-check",{className:"rui-comparison-yes"});x?y.append(x):y.textContent="✓"}else v===!1||v===null||v===void 0?y.append(o("span",{class:"rui-comparison-no"},["—"])):v&&typeof v=="object"&&v.__kind==="Component"?y.append(r.renderNode(v)):y.textContent=d(v);f.append(y)}p.append(f)}return l.append(p),s.append(l),s}},Tc={name:"InfiniteList",description:"Vertical list that fires `onLoadMore` when the user scrolls near the bottom. Pass already-rendered child nodes as `items`; wire `onLoadMore` to an `action` that awaits a `$mutation` or `$query` (e.g. `await loadMore.invoke()`) and appends to the bound state. Use `loading=true` to show the spinner row, `hasMore=false` to suppress further loads.",props:[{name:"items",type:"Node[]",description:"Already-rendered child nodes"},{name:"onLoadMore",type:"callable",optional:!0,description:"Callable fired when the sentinel scrolls into view"},{name:"loading",type:"boolean",optional:!0},{name:"hasMore",type:"boolean",optional:!0,description:"Default true — set false to hide the sentinel"},{name:"loaderLabel",type:"string",optional:!0,description:"Label rendered while loading (default `Loading…`)"}],render:(t,e,r)=>{const a=o("div",{class:"rui-infinite-list"}),i=o("div",{class:"rui-infinite-list-body"});for(const l of k(e.items))i.append(r.renderNode(l));a.append(i);const n=e.hasMore===void 0?!0:C(e.hasMore),s=C(e.loading);if(n){const l=o("div",{class:"rui-infinite-list-sentinel"});if(s){const c=L("spinner",{className:"rui-infinite-list-spin"});c&&l.append(c),l.append(o("span",{},[d(e.loaderLabel,"Loading…")]))}else if(typeof e.onLoadMore=="function"){const c=o("button",{type:"button",class:"rui-infinite-list-load-more"},["Load more"]);c.onclick=()=>r.invoke(e.onLoadMore),l.append(c)}if(a.append(l),!s&&typeof e.onLoadMore=="function"&&typeof IntersectionObserver<"u"){const c=e.onLoadMore,u=new IntersectionObserver(p=>{for(const m of p)if(m.isIntersecting){r.invoke(c);break}});u.observe(l),r.registerDisposer(()=>u.disconnect(),"infinite-observer")}}return a}},$c=/^(https?:|blob:|data:(audio|video)\/)/i;function ut(t){const e=d(t).trim();return e?e.startsWith("/")||e.startsWith(".")?e:e.startsWith("//")?"":$c.test(e)?e:"":""}const Nc={name:"VideoPlayer",description:"Themed native `<video>` wrapper. Pass a `src` URL (or `sources` array for multi-codec fallback) and optional `poster`. Standard controls are visible by default; pass `autoplay`, `loop`, `muted`, or `controls=false` to override. Use for product demos, tutorials, and any inline video.",props:[{name:"src",type:"string",optional:!0,description:"Video URL (mp4 / webm / etc.)"},{name:"sources",type:"object[]",optional:!0,description:"Array of {src, type} entries for multi-codec fallback"},{name:"poster",type:"string",optional:!0,description:"Thumbnail image URL shown before playback"},{name:"caption",type:"string",optional:!0},{name:"controls",type:"boolean",optional:!0,description:"Show native controls (default true)"},{name:"autoplay",type:"boolean",optional:!0},{name:"loop",type:"boolean",optional:!0},{name:"muted",type:"boolean",optional:!0},{name:"ratio",type:"string",optional:!0,description:"Aspect ratio (default 16:9)"}],render:(t,e)=>{const r=o("figure",{class:"rui-video-player"}),a=qt(d(e.ratio,"16:9")),i=o("div",{class:"rui-video-player-frame",style:`aspect-ratio:${a};`}),n=e.controls===void 0?!0:C(e.controls),s=o("video",{class:"rui-video-player-video",controls:n?"":null,autoplay:C(e.autoplay)?"":null,loop:C(e.loop)?"":null,muted:C(e.muted)?"":null,poster:re(e.poster)||null,playsinline:"",preload:"metadata"}),l=k(e.sources);if(l.length>0)for(const u of l){if(!u||typeof u!="object")continue;const p=u,m=ut(p.src);m&&s.append(o("source",{src:m,type:d(p.type)||null}))}else{const u=ut(e.src);u&&s.setAttribute("src",u)}i.append(s),r.append(i);const c=d(e.caption);return c&&r.append(o("figcaption",{class:"rui-video-player-caption"},[c])),r}},Ac={name:"AudioPlayer",description:"Themed native `<audio>` wrapper with a title, optional artist, and standard transport controls. Pass `src` (or `sources`) plus a `title` so the bar still looks like a player when the controls bar is hidden. Use for podcasts, voice notes, and demo audio.",props:[{name:"src",type:"string",optional:!0,description:"Audio URL (mp3 / ogg / wav / etc.)"},{name:"sources",type:"object[]",optional:!0,description:"Array of {src, type} entries for multi-codec fallback"},{name:"title",type:"string",optional:!0},{name:"artist",type:"string",optional:!0},{name:"controls",type:"boolean",optional:!0,description:"Show native controls (default true)"},{name:"autoplay",type:"boolean",optional:!0},{name:"loop",type:"boolean",optional:!0},{name:"icon",type:"string",optional:!0,description:"Leading icon (default `music`)"}],render:(t,e)=>{const r=o("div",{class:"rui-audio-player"}),a=o("div",{class:"rui-audio-player-meta"}),i=L(d(e.icon,"music"),{className:"rui-audio-player-icon"});i&&a.append(i);const n=o("div",{class:"rui-audio-player-text"}),s=d(e.title);s&&n.append(o("div",{class:"rui-audio-player-title"},[s]));const l=d(e.artist);l&&n.append(o("div",{class:"rui-audio-player-artist"},[l])),a.append(n),r.append(a);const c=e.controls===void 0?!0:C(e.controls),u=o("audio",{class:"rui-audio-player-audio",controls:c?"":null,autoplay:C(e.autoplay)?"":null,loop:C(e.loop)?"":null,preload:"metadata"}),p=k(e.sources);if(p.length>0)for(const m of p){if(!m||typeof m!="object")continue;const g=m,f=ut(g.src);f&&u.append(o("source",{src:f,type:d(g.type)||null}))}else{const m=ut(e.src);m&&u.setAttribute("src",m)}return r.append(u),r}};function Mc(t,e){if(t==null)return null;if(typeof t=="object"&&t.__kind==="Component")return e.renderNode(t);if(typeof t=="string"){const r=re(t);return r?o("img",{src:r,alt:"",loading:"lazy",class:"rui-carousel-image"}):null}if(typeof t=="object"){const r=t,a=re(r.src);if(a){const i=o("figure",{class:"rui-carousel-figure"});i.append(o("img",{src:a,alt:d(r.alt??r.caption??r.title),loading:"lazy",class:"rui-carousel-image"}));const n=d(r.caption??r.title);return n&&i.append(o("figcaption",{class:"rui-carousel-caption"},[n])),i}}return e.renderNode(t)}const Pc={name:"Carousel",description:"Horizontal slider with prev/next buttons and dot navigation. Each child slide takes full width. Slides may be Component nodes (Image, Card, MediaCard, …), URL strings, or plain `{src, alt, caption?}` image objects — bare image objects are auto-wrapped into a captioned figure. Use for image galleries, onboarding carousels, hero banners, and product image strips. The active slide is preserved across re-renders via instance state.",props:[{name:"items",type:"Node[]",description:"Slide nodes, image URLs, or {src, alt, caption?} objects"},{name:"activeIndex",type:"number",optional:!0,description:"0-indexed initial slide (default 0)"},{name:"ratio",type:"string",optional:!0,description:"Aspect ratio of the frame (default `16:9`)"},{name:"showDots",type:"boolean",optional:!0,description:"Show indicator dots (default true)"},{name:"showArrows",type:"boolean",optional:!0,description:"Show prev/next arrows (default true)"}],render:(t,e,r)=>{const a=k(e.items),i=a.length,n=Math.max(0,Math.min(Math.max(i-1,0),Math.floor(P(e.activeIndex,0)))),s=r.useInstanceState("active",n);let l=s.get();l>=i&&(l=0,s.set(l));const c=e.showDots===void 0?!0:C(e.showDots),u=e.showArrows===void 0?!0:C(e.showArrows),p=qt(d(e.ratio,"16:9")),m=o("div",{class:"rui-carousel"}),g=o("div",{class:"rui-carousel-frame",style:`aspect-ratio:${p};`}),f=o("div",{class:"rui-carousel-track",style:`transform:translateX(${l*-100}%);`});a.forEach(b=>{const v=o("div",{class:"rui-carousel-slide"}),y=Mc(b,r);y&&v.append(y),f.append(v)}),g.append(f);const h=(b,v)=>{const y=(v%i+i)%i;s.set(y);const x=b.closest(".rui-carousel"),w=x?.querySelector(".rui-carousel-track");w&&(w.style.transform=`translateX(${y*-100}%)`),x?.querySelectorAll(".rui-carousel-dot").forEach((T,S)=>{T.setAttribute("data-active",S===y?"true":"false")})};if(u&&i>1){const b=o("button",{type:"button",class:"rui-carousel-arrow","data-direction":"prev","aria-label":"Previous slide"}),v=L("chevron-left");v&&b.append(v);const y=o("button",{type:"button",class:"rui-carousel-arrow","data-direction":"next","aria-label":"Next slide"}),x=L("chevron-right");x&&y.append(x),b.onclick=w=>h(w.currentTarget,s.get()-1),y.onclick=w=>h(w.currentTarget,s.get()+1),g.append(b,y)}if(m.append(g),c&&i>1){const b=o("div",{class:"rui-carousel-dots"});a.forEach((v,y)=>{const x=o("button",{type:"button",class:"rui-carousel-dot","data-active":y===l?"true":"false","aria-label":`Go to slide ${y+1}`});x.onclick=w=>h(w.currentTarget,y),b.append(x)}),m.append(b)}return m}},Ic={name:"Gallery",description:"Responsive image grid. Pass items as plain URL strings, `{src, alt, caption?}` objects, or `Image(...)` nodes. When `onSelect` is provided each tile becomes a button; bind it through an Action that opens a `Lightbox`.",props:[{name:"items",type:"any[]"},{name:"columns",type:"number",optional:!0,description:"Preferred column count (default auto)"},{name:"ratio",type:"string",optional:!0,description:"Per-tile aspect ratio (default `1:1`)"},{name:"onSelect",type:"callable",optional:!0,description:"Callable fired when a tile is clicked"}],render:(t,e,r)=>{const a=k(e.items),i=Math.max(1,Math.min(6,Number(e.columns??"auto"))),n=qt(d(e.ratio,"1:1")),s=o("div",{class:"rui-gallery","data-columns":i>0?String(i):null});return a.forEach((l,c)=>{const{src:u,alt:p,caption:m}=Da(l),g=re(u),f=typeof e.onSelect=="function",h=o(f?"button":"figure",{type:f?"button":null,class:"rui-gallery-tile",style:`aspect-ratio:${n};`,"data-index":String(c)});if(g)h.append(o("img",{src:g,alt:p,loading:"lazy"}));else{const b=L("image",{className:"rui-gallery-placeholder"});b&&h.append(b)}m&&h.append(o("span",{class:"rui-gallery-caption"},[m])),f&&(h.onclick=()=>r.invoke(e.onSelect,c,l)),s.append(h)}),s}};function Da(t){if(typeof t=="string")return{src:t,alt:"",caption:""};if(t&&typeof t=="object"){const e=t;return e.__kind==="Component"&&Array.isArray(e.args)?{src:d(e.args[0]),alt:d(e.args[1]),caption:d(e.args[2])}:{src:d(e.src),alt:d(e.alt),caption:d(e.caption)}}return{src:"",alt:"",caption:""}}const zc={name:"Lightbox",description:"Image overlay. When you bind a `$variable` to `open` you control it explicitly; without one, Lightbox renders a clickable thumbnail of the current image that opens the overlay on click (and uses internal state for next/prev). Pass `items` (string URLs or `{src, alt, caption?}` objects). Clicking the backdrop or × closes; arrows step through the array.",props:[{name:"items",type:"any[]"},{name:"open",type:"boolean",optional:!0,description:"Open/closed; bind a $variable to control externally"},{name:"index",type:"number",optional:!0,description:"0-indexed current image; typically a $variable"}],render:(t,e,r)=>{const a=k(e.items).map($=>Da($)).filter($=>re($.src)!==""),i=a.length,n=t.argMeta?.[2]?.stateRef,s=t.argMeta?.[1]?.stateRef,l=r.useInstanceState("open",!1),c=r.useInstanceState("index",0),u=s?C(e.open):l.get(),p=n?Math.floor(P(e.index,0)):c.get(),m=i===0?0:(p%i+i)%i,g=$=>{s?r.setState(s,$):l.set($)},f=$=>{n?r.setState(n,$):c.set($)},h=()=>g(!1),b=$=>{i!==0&&f(((m+$)%i+i)%i)},v=o("div",{class:"rui-lightbox-root"});if(!s&&i>0){const $=a[m],A=o("button",{type:"button",class:"rui-lightbox-thumb","aria-label":$?.alt||"Open image"});if($){const z=re($.src);z&&A.append(o("img",{src:z,alt:$.alt,loading:"lazy"}))}A.onclick=z=>{z.stopPropagation(),g(!0)},v.append(A)}const y=o("div",{class:"rui-lightbox-overlay","data-open":u?"true":"false"});if(v.append(y),!u||i===0)return v;const x=a[m];if(!x)return v;const w=re(x.src);y.onclick=$=>{$.target===y&&h()};const T=o("div",{class:"rui-lightbox",role:"dialog","aria-modal":"true"}),S=o("button",{type:"button",class:"rui-lightbox-close","aria-label":"Close lightbox"},["×"]);if(S.onclick=h,T.append(S),i>1){const $=o("button",{type:"button",class:"rui-lightbox-arrow","data-direction":"prev","aria-label":"Previous image"}),A=L("chevron-left");A&&$.append(A),$.onclick=()=>b(-1);const z=o("button",{type:"button",class:"rui-lightbox-arrow","data-direction":"next","aria-label":"Next image"}),R=L("chevron-right");R&&z.append(R),z.onclick=()=>b(1),T.append($,z)}const N=o("div",{class:"rui-lightbox-image-wrap"});return w&&N.append(o("img",{src:w,alt:x.alt})),T.append(N),x.caption&&T.append(o("div",{class:"rui-lightbox-caption"},[x.caption])),i>1&&T.append(o("div",{class:"rui-lightbox-counter"},[`${m+1} / ${i}`])),y.append(T),v}};function Rc(t){if(!t)return null;if(typeof t=="object"&&!Array.isArray(t)){const e=t,r=P(e.lat??e.latitude,NaN),a=P(e.lng??e.longitude,NaN);if(Number.isFinite(r)&&Number.isFinite(a))return{lat:r,lng:a}}if(Array.isArray(t)&&t.length>=2){const e=P(t[0],NaN),r=P(t[1],NaN);if(Number.isFinite(e)&&Number.isFinite(r))return{lat:e,lng:r}}if(typeof t=="string"){const e=t.split(",").map(r=>Number(r.trim()));if(e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]))return{lat:e[0],lng:e[1]}}return null}const Lc={name:"Map",description:"Static map view centered on a lat/lng coordinate. Renders an OpenStreetMap embed inside an `<iframe>` (no external JS, no API key). Pass `lat` and `lng` as bare numbers; `zoom` controls the level (1–18, default 13). Optional `markers` array adds map pins (rendered as a labelled list alongside the map). Use for store locators, address cards, itinerary previews.",props:[{name:"lat",type:"number",description:"Latitude of the map center"},{name:"lng",type:"number",description:"Longitude of the map center"},{name:"zoom",type:"number",optional:!0,description:"1–18 (default 13)"},{name:"markers",type:"object[]",optional:!0,description:"Array of {lat, lng, label?} markers (informational; rendered alongside the map)"},{name:"height",type:"string",optional:!0,description:"CSS height (default 320px)"},{name:"caption",type:"string",optional:!0}],render:(t,e)=>{const r=o("figure",{class:"rui-map"}),a=ee(e.height,"320px"),i=o("div",{class:"rui-map-frame",style:`height:${a};`}),n=P(e.lat,NaN),s=P(e.lng,NaN),l=Number.isFinite(n)&&Number.isFinite(s)?{lat:n,lng:s}:null;if(!l){i.append(o("div",{class:"rui-map-empty"},["Pass lat & lng (numbers) to render the map."])),r.append(i);const b=d(e.caption);return b&&r.append(o("figcaption",{class:"rui-map-caption"},[b])),r}const c=Math.max(1,Math.min(18,Math.floor(P(e.zoom,13)))),u=1/Math.pow(2,c-8),m=`https://www.openstreetmap.org/export/embed.html?bbox=${[l.lng-u,l.lat-u/2,l.lng+u,l.lat+u/2].join(",")}&layer=mapnik&marker=${l.lat},${l.lng}`,g=o("iframe",{class:"rui-map-iframe",src:m,loading:"lazy",title:"Map view",referrerpolicy:"no-referrer"});i.append(g),r.append(i);const f=k(e.markers).map(b=>{const v=Rc(b),y=b&&typeof b=="object"?d(b.label):"";return v?{...v,label:y}:null}).filter(b=>b!==null);if(f.length>0){const b=o("ul",{class:"rui-map-markers"});for(const v of f){const y=o("li",{class:"rui-map-marker"}),x=L("location-dot",{className:"rui-map-marker-icon"});x&&y.append(x),y.append(o("span",{class:"rui-map-marker-label"},[v.label||`${v.lat.toFixed(4)}, ${v.lng.toFixed(4)}`])),b.append(y)}r.append(b)}const h=d(e.caption);return h&&r.append(o("figcaption",{class:"rui-map-caption"},[h])),r}};function qt(t){if(t.includes(":")){const[r,a]=t.split(":"),i=Number(r),n=Number(a);if(Number.isFinite(i)&&Number.isFinite(n)&&n>0)return`${i} / ${n}`}const e=Number(t);return Number.isFinite(e)&&e>0?`${e} / 1`:"16 / 9"}const Ec=[{command:"bold",icon:"bold",label:"Bold"},{command:"italic",icon:"italic",label:"Italic"},{command:"underline",icon:"underline",label:"Underline"},{command:"strikeThrough",icon:"strikethrough",label:"Strikethrough"},{command:"formatBlock",icon:"heading",label:"Heading",block:"h2"},{command:"formatBlock",icon:"quote-left",label:"Quote",block:"blockquote"},{command:"insertUnorderedList",icon:"list-ul",label:"Bullet list"},{command:"insertOrderedList",icon:"list-ol",label:"Numbered list"},{command:"createLink",icon:"link",label:"Link"}],_c={name:"RichTextEditor",description:"Rich-text WYSIWYG editor for CMS, email, and comment surfaces. Renders a small toolbar (bold / italic / underline / strikethrough / headings / lists / quote / link) above a `contenteditable` region. Pass `$variable` as `value` for two-way binding — the HTML body is written back to state on every edit. Provide `placeholder` for the empty-state prompt.",props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"Bound HTML body (typically $variable)"},{name:"placeholder",type:"string",optional:!0,description:"Empty-state prompt"},{name:"minHeight",type:"string",optional:!0,description:"CSS min-height for the editor area (default 160px)"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=d(e.placeholder,"Start writing…"),n=C(e.disabled),s=o("div",{class:"rui-rich-text","data-disabled":n?"true":"false"}),l=o("div",{class:"rui-rich-text-toolbar",role:"toolbar"});for(const f of Ec){const h=o("button",{type:"button",class:"rui-rich-text-tool","data-command":f.command,"data-block":f.block??null,"aria-label":f.label,title:f.label,disabled:n?"":null}),b=L(f.icon);b&&h.append(b),h.onmousedown=v=>v.preventDefault(),h.onclick=v=>{const x=v.currentTarget.closest(".rui-rich-text")?.querySelector(".rui-rich-text-content");if(x){x.focus();try{if(f.command==="createLink"){const w=window.prompt("URL");w&&document.execCommand("createLink",!1,w)}else f.command==="formatBlock"&&f.block?document.execCommand("formatBlock",!1,f.block):document.execCommand(f.command,!1)}catch{}x.dispatchEvent(new Event("input",{bubbles:!0}))}},l.append(h)}s.append(l);const c=d(e.value)||"",u=f=>f.replace(/<br\s*\/?>(?=\s*$)/gi,"").replace(/<[^>]+>/g,"").replace(/&nbsp;/g," ").trim().length===0,p=o("div",{class:"rui-rich-text-content",id:a,contenteditable:n?"false":"true",role:"textbox","aria-multiline":"true","aria-placeholder":i,"data-placeholder":i,"data-empty":u(c)?"true":"false",style:`min-height:${d(e.minHeight,"160px")};`,html:c}),m=f=>{f.setAttribute("data-empty",u(f.innerHTML)?"true":"false")},g=t.argMeta?.[1]?.stateRef;return g&&!n?r.bindState(p,g,{event:"input",getValue:f=>{const h=f;return m(h),h.innerHTML}}):p.oninput=f=>{const h=f.currentTarget??f.target;m(h)},p.onblur=f=>{const h=f.currentTarget??f.target;m(h)},s.append(p),s}},jc={name:"CodeEditor",description:"Lightweight, dependency-free code editor. Pairs a styled textarea with a synchronised line-number gutter — no syntax highlighting, but the editor stays a single rendered node so it works inside Shadow DOM. Use for dev tooling, snippet editing, prompt playgrounds. Pass a `$variable` as `value` for two-way binding. For read-only rendering with highlights prefer `CodeBlock`.",props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"Bound source text (typically $variable)"},{name:"language",type:"string",optional:!0,enum:["text","javascript","typescript","json","html","css","bash","python","sql","markdown"],description:"Language label shown on the header (default `text`)"},{name:"placeholder",type:"string",optional:!0},{name:"minHeight",type:"string",optional:!0,description:"CSS min-height for the editor area (default 200px)"},{name:"tabSize",type:"number",optional:!0,description:"Spaces per Tab (default 2)"},{name:"showGutter",type:"boolean",optional:!0,description:"Show line-number gutter (default true)"},{name:"readonly",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=d(e.value),n=d(e.language,"text"),s=e.showGutter===void 0?!0:C(e.showGutter),l=Math.max(1,Math.min(8,Math.floor(P(e.tabSize,2)))),c=C(e.readonly),u=d(e.minHeight,"200px"),p=o("div",{class:"rui-code-editor","data-language":n,"data-gutter":s?"true":"false"}),m=o("div",{class:"rui-code-editor-head"});m.append(o("span",{class:"rui-code-editor-language"},[n])),p.append(m);const g=o("div",{class:"rui-code-editor-body",style:`min-height:${u};`}),f=o("div",{class:"rui-code-editor-gutter","aria-hidden":"true"});s&&((y=>{f.replaceChildren();const x=y.split(/\r?\n/),w=Math.max(1,x.length);for(let T=1;T<=w;T+=1)f.append(o("span",{class:"rui-code-editor-line"},[String(T)]))})(i),g.append(f));const b=o("textarea",{class:"rui-code-editor-textarea",id:a,name:a,spellcheck:"false",autocorrect:"off",autocapitalize:"off",placeholder:d(e.placeholder),readonly:c?"":null,style:`tab-size:${l};-moz-tab-size:${l};`});b.value=i,b.oninput=y=>{const x=y.currentTarget;if(!s)return;const T=x.closest(".rui-code-editor")?.querySelector(".rui-code-editor-gutter");if(!T)return;T.replaceChildren();const S=x.value.split(/\r?\n/),N=Math.max(1,S.length);for(let $=1;$<=N;$+=1)T.append(o("span",{class:"rui-code-editor-line"},[String($)]))},b.onkeydown=y=>{const x=y;if(x.key!=="Tab")return;x.preventDefault();const w=x.currentTarget,T=w.selectionStart,S=w.selectionEnd,N=" ".repeat(l);w.value=w.value.slice(0,T)+N+w.value.slice(S),w.selectionStart=w.selectionEnd=T+N.length,w.dispatchEvent(new Event("input",{bubbles:!0}))};const v=t.argMeta?.[1]?.stateRef;return v&&!c&&r.bindState(b,v,{event:"input",getValue:y=>y.value}),g.append(b),p.append(g),p}};function Bc(t){if(!t)return null;if(typeof t=="object"){const e=t;if(e.__kind==="Component"&&e.name==="MenuItem"&&Array.isArray(e.args)){const a=e.args;return{label:d(a[0]),action:a[1],icon:d(a[2]),shortcut:d(a[3]),variant:d(a[4],"default"),disabled:C(a[5]),separator:!1}}if(e.__kind==="Component"&&e.name==="MenuSeparator")return{label:"",action:null,icon:"",shortcut:"",variant:"default",disabled:!1,separator:!0};const r=t;return r.separator?{label:"",action:null,icon:"",shortcut:"",variant:"default",disabled:!1,separator:!0}:{label:d(r.label),action:r.action,icon:d(r.icon),shortcut:d(r.shortcut),variant:d(r.variant,"default"),disabled:C(r.disabled),separator:!1}}return null}const Dc={name:"ContextMenu",description:"Right-click (or long-press) menu that attaches to a child node. Wraps `target` and shows the menu at the pointer when the user right-clicks anywhere inside it. Items are `MenuItem(...)` nodes, `MenuSeparator()` entries, or `{label, action, icon?, shortcut?, variant?, disabled?, separator?}` objects. Use on table rows, tree nodes, kanban cards, file browser entries.",props:[{name:"target",type:"Node",description:"Child node the menu is bound to"},{name:"items",type:"any[]",description:"MenuItem nodes or {label, action} objects"},{name:"label",type:"string",optional:!0,description:"ARIA label for the menu"}],render:(t,e,r)=>{const a=o("div",{class:"rui-context-menu"}),i=o("div",{class:"rui-context-menu-target"});i.append(r.renderNode(e.target)),a.append(i);const n=o("div",{class:"rui-context-menu-pop",role:"menu","aria-label":d(e.label)||null,"data-open":"false"}),s=k(e.items).map(Bc).filter(u=>u!==null);for(const u of s){if(u.separator){n.append(o("div",{class:"rui-menu-separator",role:"separator"}));continue}const p=o("button",{type:"button",class:"rui-menu-item",role:"menuitem","data-variant":u.variant,disabled:u.disabled?"":null}),m=L(u.icon,{className:"rui-menu-item-icon"});m&&p.append(m),p.append(o("span",{class:"rui-menu-item-label"},[u.label])),u.shortcut&&p.append(o("span",{class:"rui-menu-item-shortcut"},[u.shortcut])),u.disabled||(p.onclick=()=>{r.invoke(u.action),n.setAttribute("data-open","false")}),n.append(p)}a.append(n);const l=()=>n.setAttribute("data-open","false"),c=(u,p)=>{const m=i.isConnected?i.closest(".rui-context-menu"):null,g=m?.querySelector(".rui-context-menu-pop")??n,f=m?.getBoundingClientRect(),h=f?u-f.left:u,b=f?p-f.top:p;g.style.left=`${h}px`,g.style.top=`${b}px`,g.setAttribute("data-open","true");const v=y=>{y.target&&g.contains(y.target)||(g.setAttribute("data-open","false"),document.removeEventListener("click",v,!0),document.removeEventListener("contextmenu",v,!0))};setTimeout(()=>{document.addEventListener("click",v,!0),document.addEventListener("contextmenu",v,!0)},0)};return i.oncontextmenu=u=>{u.preventDefault(),c(u.clientX,u.clientY)},i.onkeydown=u=>{const p=u;if(p.key==="ContextMenu"||p.shiftKey&&p.key==="F10"){p.preventDefault();const g=p.currentTarget.getBoundingClientRect();c(g.left,g.top+g.height)}p.key==="Escape"&&l()},a}},Fc=["#0f172a","#334155","#64748b","#94a3b8","#ef4444","#f59e0b","#facc15","#10b981","#06b6d4","#3b82f6","#6366f1","#8b5cf6"];function Ge(t){const e=t.trim();if(!e)return"";let r=e.startsWith("#")?e.slice(1):e;return r.length===3&&(r=r.split("").map(a=>a+a).join("")),/^[0-9a-fA-F]{6,8}$/.test(r)?`#${r.toLowerCase().slice(0,6)}`:""}const Oc={name:"ColorPicker",description:'Hex / RGB color form control with preset swatches. Pairs a native `<input type="color">` chip with a hex text input and a row of preset swatches. Pass a `$variable` as `value` (hex string, e.g. `"#6366f1"`) for two-way binding. Use for theme builders, label color pickers, and any "pick a color" surface.',props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"Bound hex value (typically $variable)"},{name:"label",type:"string",optional:!0},{name:"swatches",type:"string[]",optional:!0,description:"Preset hex colors (default to a 12-color palette)"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=Ge(d(e.value))||d(e.value,"#000000"),n=C(e.disabled),s=o("div",{class:"rui-color-picker","data-disabled":n?"true":"false"}),l=d(e.label);l&&s.append(o("label",{class:"rui-color-picker-label",for:a},[l]));const c=o("div",{class:"rui-color-picker-row"}),u=o("input",{type:"color",class:"rui-color-picker-color",id:a,name:a,value:Ge(i)||"#000000",disabled:n?"":null}),p=o("input",{type:"text",class:"rui-color-picker-hex",value:i,placeholder:"#000000",disabled:n?"":null,autocomplete:"off"}),m=o("div",{class:"rui-color-picker-swatches"}),g=k(e.swatches).map(b=>d(b)).filter(Boolean),f=g.length>0?g:Fc;for(const b of f){const v=Ge(b)||b,y=o("button",{type:"button",class:"rui-color-picker-swatch",style:`background:${v}`,"aria-label":v,title:v,"data-active":v.toLowerCase()===i.toLowerCase()?"true":"false"});y.onclick=()=>{u.value=Ge(v)||u.value,p.value=v,u.dispatchEvent(new Event("input",{bubbles:!0}))},m.append(y)}const h=t.argMeta?.[1]?.stateRef;return h&&!n&&(r.bindState(u,h,{event:"input",getValue:b=>b.value}),u.addEventListener("input",()=>{p.value=u.value}),p.oninput=()=>{const b=Ge(p.value);b&&(u.value=b,u.dispatchEvent(new Event("input",{bubbles:!0})))}),c.append(u,p),s.append(c,m),s}},Ht=["var(--rui-chart-1, #6366f1)","var(--rui-chart-2, #10b981)","var(--rui-chart-3, #f59e0b)","var(--rui-chart-4, #ef4444)","var(--rui-chart-5, #06b6d4)","var(--rui-chart-6, #8b5cf6)"],$e=t=>Ht[t%Ht.length]??Ht[0];function Uc(t){return t.map((e,r)=>{const a=e,i=d(a.args?.[0],`Series ${r+1}`),n=k(a.args?.[1]).map(s=>P(s));return{name:i,values:n}})}function dt(t,e){const r=document.createElementNS("http://www.w3.org/2000/svg","svg");return r.setAttribute("viewBox",`0 0 ${t} ${e}`),r.setAttribute("class","rui-chart-svg"),r.setAttribute("role","img"),r}function ie(t,e,r){const a=document.createElementNS("http://www.w3.org/2000/svg",t);for(const[i,n]of Object.entries(e))a.setAttribute(i,n);if(r)for(const i of r)a.append(typeof i=="string"?document.createTextNode(i):i);return a}function Fa(t){const e=o("div",{class:"rui-chart-legend"});return t.forEach((r,a)=>{const i=o("span",{class:"rui-chart-legend-item"});i.append(o("span",{class:"rui-chart-legend-swatch",style:`background:${$e(a)}`})),i.append(o("span",{},[r.name])),e.append(i)}),e}const qc={name:"Gauge",description:"Half-doughnut gauge indicator for a single value between `min` and `max`. The inner value is auto-formatted from the value (override via `label`). Pass `caption`, `tone`, and `size` for visual treatment. Use for KPI thresholds (uptime %, score, capacity, NPS, page-speed).",props:[{name:"value",type:"number"},{name:"min",type:"number",optional:!0,description:"Lower bound (default 0)"},{name:"max",type:"number",optional:!0,description:"Upper bound (default 100)"},{name:"caption",type:"string",optional:!0,description:"Small caption below the gauge"},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]},{name:"size",type:"string",optional:!0,enum:["sm","md","lg"]},{name:"label",type:"string",optional:!0,description:"Inner label override (defaults to auto-formatted value)"}],render:(t,e)=>{const r=P(e.min,0),a=Math.max(r+1,P(e.max,100)),i=Math.max(r,Math.min(a,P(e.value,r))),n=(i-r)/(a-r),s=d(e.tone,"primary"),l=d(e.size,"md"),c=l==="lg"?220:l==="sm"?140:180,u=c/2,p=l==="lg"?18:l==="sm"?10:14,m=u-p,g=o("div",{class:"rui-gauge","data-tone":s,"data-size":l}),f=dt(c,u+p+4),h=u,b=u,v=h-m,y=b,x=h+m,w=b;if(f.append(ie("path",{d:`M${v},${y} A${m},${m} 0 0 1 ${x},${w}`,fill:"none",stroke:"var(--rui-color-border, #e2e8f0)","stroke-width":String(p),"stroke-linecap":"round"})),n>0){const $=Math.PI*n,A=h-m*Math.cos($),z=b-m*Math.sin($);f.append(ie("path",{d:`M${v},${y} A${m},${m} 0 0 1 ${A.toFixed(2)},${z.toFixed(2)}`,fill:"none",stroke:`var(--rui-color-${s}, ${$e(0)})`,"stroke-width":String(p),"stroke-linecap":"round",class:"rui-gauge-arc"}))}g.append(f);const T=Hc(i,r,a),S=d(e.label)||T;g.append(o("div",{class:"rui-gauge-value"},[S]));const N=d(e.caption);return N&&g.append(o("div",{class:"rui-gauge-caption"},[N])),g}};function Hc(t,e,r){return e===0&&r===100?t%1===0?`${t}%`:`${t.toFixed(1)}%`:Math.abs(t)>=1e3?Math.round(t).toLocaleString():t%1===0?String(t):t.toFixed(t<10?2:1)}const Vc={name:"Heatmap",description:"Color-intensity matrix grid (calendar-style or correlation-style). Pass `xLabels`, `yLabels`, and a `values` array of arrays (rows × columns). Each cell's color intensity scales with the value relative to the global max. Use for activity heatmaps, schedule density, correlation matrices.",props:[{name:"xLabels",type:"string[]"},{name:"yLabels",type:"string[]"},{name:"values",type:"number[][]",description:"Matrix indexed by row (y), then column (x)"},{name:"title",type:"string",optional:!0},{name:"tone",type:"string",optional:!0,enum:["primary","success","warning","danger","info"]}],render:(t,e)=>{const r=k(e.xLabels).map(p=>d(p)),a=k(e.yLabels).map(p=>d(p)),i=k(e.values).map(p=>k(p).map(m=>P(m,0))),n=d(e.tone,"primary"),s=Math.max(1,...i.flat()),l=o("div",{class:"rui-heatmap","data-tone":n});d(e.title)&&l.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const c=o("div",{class:"rui-heatmap-table"}),u=o("div",{class:"rui-heatmap-row rui-heatmap-row-header"});u.append(o("div",{class:"rui-heatmap-cell rui-heatmap-corner"}));for(const p of r)u.append(o("div",{class:"rui-heatmap-cell rui-heatmap-xlabel"},[p]));return c.append(u),i.forEach((p,m)=>{const g=o("div",{class:"rui-heatmap-row"});g.append(o("div",{class:"rui-heatmap-cell rui-heatmap-ylabel"},[a[m]??String(m+1)])),p.forEach((f,h)=>{const b=s>0?f/s:0,v=o("div",{class:"rui-heatmap-cell rui-heatmap-value",style:`background:color-mix(in srgb, var(--rui-color-${n}, ${$e(0)}) ${Math.round(b*90+5)}%, transparent);`,title:`${r[h]??h+1} · ${a[m]??m+1}: ${f}`});v.append(o("span",{},[String(f)])),g.append(v)}),c.append(g)}),l.append(c),l}},Wc={name:"RadarChart",description:"Polygon chart with one axis per category. Use for skill maps, scorecards, capability comparisons, and any multi-dimensional snapshot. Each Series renders as a filled polygon — overlapping is expected for comparisons.",props:[{name:"axes",type:"string[]",description:"Category labels — one per radial axis"},{name:"series",type:"Series[]"},{name:"max",type:"number",optional:!0,description:"Outer ring value (default = max across series)"},{name:"title",type:"string",optional:!0}],render:(t,e)=>{const r=k(e.axes).map(f=>d(f)),a=Uc(k(e.series)),i=Math.max(r.length,3),n=o("div",{class:"rui-chart rui-radar-chart"});d(e.title)&&n.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const s=Math.max(1,P(e.max,a.flatMap(f=>f.values).reduce((f,h)=>Math.max(f,h),1))),l=280,c=l/2,u=l/2,p=l/2-24,m=dt(l,l),g=4;for(let f=1;f<=g;f+=1){const h=p/g*f,b=[];for(let v=0;v<i;v+=1){const y=Math.PI*2*v/i-Math.PI/2;b.push(`${(c+h*Math.cos(y)).toFixed(1)},${(u+h*Math.sin(y)).toFixed(1)}`)}m.append(ie("polygon",{points:b.join(" "),fill:"none",stroke:"var(--rui-color-border-subtle, rgba(0,0,0,0.08))","stroke-width":"1"}))}for(let f=0;f<i;f+=1){const h=Math.PI*2*f/i-Math.PI/2,b=c+p*Math.cos(h),v=u+p*Math.sin(h);m.append(ie("line",{x1:String(c),y1:String(u),x2:b.toFixed(1),y2:v.toFixed(1),stroke:"var(--rui-color-border-subtle, rgba(0,0,0,0.08))","stroke-width":"1"}));const y=c+(p+16)*Math.cos(h),x=u+(p+16)*Math.sin(h);m.append(ie("text",{x:y.toFixed(1),y:x.toFixed(1),"text-anchor":"middle","dominant-baseline":"middle",class:"rui-chart-label","font-size":"13","font-weight":"500"},[r[f]??""]))}return a.forEach((f,h)=>{const b=[];for(let v=0;v<i;v+=1){const y=f.values[v]??0,x=Math.max(0,Math.min(1,y/s)),w=Math.PI*2*v/i-Math.PI/2,T=c+p*x*Math.cos(w),S=u+p*x*Math.sin(w);b.push(`${T.toFixed(1)},${S.toFixed(1)}`)}m.append(ie("polygon",{points:b.join(" "),fill:$e(h),"fill-opacity":"0.2",stroke:$e(h),"stroke-width":"2","stroke-linejoin":"round"}))}),n.append(m),a.length>0&&n.append(Fa(a)),n}};function Gc(t){return t.map((e,r)=>{const a=e,i=d(a.args?.[0],`Series ${r+1}`),n=k(a.args?.[1]).map(s=>{if(Array.isArray(s))return{x:P(s[0],0),y:P(s[1],0),label:d(s[2])};if(s&&typeof s=="object"){const l=s;return{x:P(l.x,0),y:P(l.y,0),label:d(l.label)}}return{x:0,y:0,label:""}});return{name:i,points:n}})}const Kc={name:"ScatterChart",description:'XY scatter plot — one dot per data point, optionally grouped by series. Pass each `Series(name, points)` with points as `{x, y, label?}` objects or `[x, y, label?]` tuples. Use for correlations, distributions, and "price vs. rating" style charts.',props:[{name:"series",type:"Series[]"},{name:"xLabel",type:"string",optional:!0},{name:"yLabel",type:"string",optional:!0},{name:"title",type:"string",optional:!0}],render:(t,e)=>{const r=Gc(k(e.series)),a=o("div",{class:"rui-chart rui-scatter-chart"});d(e.title)&&a.append(o("div",{class:"rui-chart-title"},[d(e.title)]));const i=640,n=280,s={left:50,right:16,top:16,bottom:40},l=i-s.left-s.right,c=n-s.top-s.bottom,u=r.flatMap(T=>T.points);if(u.length===0)return a.append(o("div",{class:"rui-chart-empty"},["No points"])),a;const p=u.map(T=>T.x),m=u.map(T=>T.y),g=Math.min(...p),f=Math.max(...p),h=Math.min(...m),b=Math.max(...m),v=f-g||1,y=b-h||1,x=dt(i,n);if(Ua(x,s,l,c,b,h),x.append(ie("line",{x1:String(s.left),y1:String(s.top+c),x2:String(s.left+l),y2:String(s.top+c),stroke:"var(--rui-color-border, #e2e8f0)"})),r.forEach((T,S)=>{T.points.forEach(N=>{const $=s.left+(N.x-g)/v*l,A=s.top+c-(N.y-h)/y*c,z=ie("circle",{cx:$.toFixed(1),cy:A.toFixed(1),r:"7",fill:$e(S),"fill-opacity":"0.8",stroke:"#fff","stroke-width":"1.5"});z.append(ie("title",{},[N.label||`${N.x}, ${N.y}`])),x.append(z)})}),d(e.xLabel)&&x.append(ie("text",{x:String(s.left+l/2),y:String(n-6),"text-anchor":"middle",class:"rui-chart-label","font-size":"14","font-weight":"500"},[d(e.xLabel)])),d(e.yLabel)){const S=s.top+c/2;x.append(ie("text",{x:String(14),y:String(S),"text-anchor":"middle",transform:`rotate(-90, 14, ${S})`,class:"rui-chart-label","font-size":"14","font-weight":"500"},[d(e.yLabel)]))}a.append(x);const w=r.map(T=>({name:T.name,values:T.points.map(S=>S.y)}));return w.length>0&&a.append(Fa(w)),a}},Yc={name:"Histogram",description:"Frequency distribution from raw numeric values. Pass `values` directly (the component bins them automatically) or pre-computed `bins` of `{label, count}` objects. Use for response-time histograms, score distributions, age buckets.",props:[{name:"values",type:"number[]",optional:!0,description:"Raw observations (binned automatically)"},{name:"bins",type:"object[]",optional:!0,description:"Pre-computed {label, count} entries (overrides `values`)"},{name:"binCount",type:"number",optional:!0,description:"Number of bins when computing from `values` (default 10)"},{name:"title",type:"string",optional:!0}],render:(t,e)=>{let r=[];if(Array.isArray(e.bins)&&e.bins.length>0)r=e.bins.map(g=>{const f=g??{};return{label:d(f.label),count:P(f.count,0)}});else{const g=k(e.values).map(f=>P(f,NaN)).filter(f=>Number.isFinite(f));if(g.length>0){const f=Math.max(2,Math.min(50,Math.floor(P(e.binCount,10)))),h=Math.min(...g),y=(Math.max(...g)-h||1)/f,x=new Array(f).fill(0);for(const w of g){let T=Math.floor((w-h)/y);T>=f&&(T=f-1),T<0&&(T=0),x[T]+=1}r=x.map((w,T)=>{const S=h+T*y,N=S+y;return{label:`${Oa(S)}–${Oa(N)}`,count:w}})}}const a=o("div",{class:"rui-chart rui-histogram"});if(d(e.title)&&a.append(o("div",{class:"rui-chart-title"},[d(e.title)])),r.length===0)return a.append(o("div",{class:"rui-chart-empty"},["No data"])),a;const i=640,n=240,s={left:40,right:12,top:16,bottom:50},l=i-s.left-s.right,c=n-s.top-s.bottom,u=Math.max(1,...r.map(g=>g.count)),p=l/r.length,m=dt(i,n);return Ua(m,s,l,c,u),r.forEach((g,f)=>{const h=s.left+f*p+p*.1,b=p*.8,v=g.count/u*c,y=s.top+c-v,x=ie("rect",{x:h.toFixed(1),y:y.toFixed(1),width:b.toFixed(1),height:v.toFixed(1),fill:$e(0),rx:"2"});x.append(ie("title",{},[`${g.label}: ${g.count}`])),m.append(x),m.append(ie("text",{x:(h+b/2).toFixed(1),y:String(s.top+c+22),"text-anchor":"middle",class:"rui-chart-label","font-size":"12"},[g.label]))}),a.append(m),a}};function Oa(t){return Number.isFinite(t)?Math.abs(t)>=1e3?Math.round(t).toLocaleString():Math.abs(t)>=10?t.toFixed(0):t.toFixed(1):"?"}function Ua(t,e,r,a,i,n=0){for(let l=0;l<=4;l+=1){const c=l/4,u=e.top+a-c*a;t.append(ie("line",{x1:String(e.left),x2:String(e.left+r),y1:String(u),y2:String(u),stroke:"var(--rui-color-border-subtle, rgba(0,0,0,0.08))"})),t.append(ie("text",{x:String(e.left-8),y:String(u+5),"text-anchor":"end",class:"rui-chart-tick","font-size":"14"},[String(Math.round((n+(i-n)*c)*10)/10)]))}}const Jc=["numeric","alphanumeric"];function Xc(t,e,r,a,i,n,s){const l=o("div",{class:"rui-pin-input","data-disabled":i?"true":"false"}),c=[];for(let m=0;m<e;m+=1){const g=o("input",{class:"rui-pin-input-slot",id:m===0?t:null,maxlength:"1",autocomplete:"one-time-code",inputmode:r==="numeric"?"numeric":"text",type:n?"password":"text","aria-label":`Digit ${m+1}`,value:a.charAt(m)||"",disabled:i?"":null});c.push(g),l.append(g)}const u=m=>{const g=m.closest(".rui-pin-input");return g?Array.from(g.querySelectorAll(".rui-pin-input-slot")):c},p=m=>u(m).map(g=>g.value).join("").slice(0,e);return c.forEach((m,g)=>{m.oninput=f=>{const h=f.currentTarget,b=u(h);let v=h.value;if(r==="numeric"?v=v.replace(/\D/g,""):v=v.replace(/[^A-Za-z0-9]/g,""),v.length>1){const y=v.split("");y.slice(0,e-g).forEach((w,T)=>{const S=b[g+T];S&&(S.value=w)});const x=Math.min(g+y.length,e-1);b[x]?.focus()}else h.value=v,v&&g<e-1&&b[g+1]?.focus();s?.(p(h))},m.onkeydown=f=>{const h=f,b=h.currentTarget,v=u(b);if(h.key==="Backspace"&&!b.value&&g>0){h.preventDefault(),v[g-1]?.focus();const y=v[g-1];y&&(y.value=""),s?.(p(b))}else h.key==="ArrowLeft"&&g>0?(h.preventDefault(),v[g-1]?.focus()):h.key==="ArrowRight"&&g<e-1&&(h.preventDefault(),v[g+1]?.focus())}}),l}const Zc={name:"PinInput",description:'Per-digit PIN entry. Auto-advances focus as the user types and supports paste. Pass a `$variable` as `value` for two-way binding (the bound value is the joined string). Use `type="numeric"` for PINs / 2FA codes, `"alphanumeric"` for invite codes.',props:[{name:"id",type:"string"},{name:"length",type:"number",optional:!0,description:"Number of slots (default 4)"},{name:"value",type:"string",optional:!0,description:"Bound value (typically $variable)"},{name:"type",type:"string",optional:!0,enum:Jc},{name:"mask",type:"boolean",optional:!0,description:"Render slots as `<input type=password>`"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=Math.max(1,Math.min(12,Math.floor(P(e.length,4)))),n=d(e.type,"numeric"),s=d(e.value),l=C(e.disabled),c=C(e.mask),u=t.argMeta?.[2]?.stateRef;return Xc(a,i,n,s,l,c,p=>{u&&r.setState(u,p)})}};function Qc(t){if(!t)return{score:0,label:""};let e=0;return t.length>=8&&(e+=1),t.length>=12&&(e+=1),/[A-Z]/.test(t)&&/[a-z]/.test(t)&&(e+=1),/[0-9]/.test(t)&&(e+=1),/[^A-Za-z0-9]/.test(t)&&(e+=1),e=Math.min(4,e),{score:e,label:["Too short","Weak","Fair","Good","Strong"][e]??""}}const eu={name:"PasswordInput",description:"Password input with a show/hide toggle and an optional strength meter. Pass a `$variable` as `value` for two-way binding. Set `strengthMeter=true` to render a 4-step indicator and label.",props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"Bound value (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"label",type:"string",optional:!0,description:"Inline label above the field"},{name:"strengthMeter",type:"boolean",optional:!0,aliases:["showStrength"]},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=r.useInstanceState("visible",!1),n=i.get(),s=C(e.disabled),l=o("div",{class:"rui-password-input","data-disabled":s?"true":"false"}),c=d(e.label);c&&l.append(o("label",{class:"rui-password-input-label",for:a},[c]));const u=o("div",{class:"rui-password-input-row"}),p=o("input",{type:n?"text":"password",class:"rui-password-input-field",id:a,name:a,autocomplete:"current-password",placeholder:d(e.placeholder),value:d(e.value),disabled:s?"":null}),m=o("button",{type:"button",class:"rui-password-input-toggle","aria-label":n?"Hide password":"Show password"}),g=L(n?"eye-slash":"eye");g&&m.append(g),m.onclick=h=>{h.preventDefault();const b=!i.get();i.set(b);const x=h.currentTarget.closest(".rui-password-input")?.querySelector(".rui-password-input-field");x&&(x.type=b?"text":"password")};const f=t.argMeta?.[1]?.stateRef;if(f&&r.bindState(p,f,{event:"input",getValue:h=>h.value}),u.append(p),u.append(m),l.append(u),C(e.strengthMeter)){const h=Qc(d(e.value)),b=o("div",{class:"rui-password-input-strength","data-score":String(h.score)});for(let y=0;y<4;y+=1)b.append(o("span",{class:"rui-password-input-strength-bar","data-filled":y<h.score?"true":"false"}));const v=o("div",{class:"rui-password-input-strength-row"});v.append(b),h.label&&v.append(o("span",{class:"rui-password-input-strength-label"},[h.label])),l.append(v)}return l}},tu={name:"TagInput",description:"Tag/chip input — type a value, press Enter (or comma) to commit, click × on a chip to remove. Pass a `$variable` (array of strings) as `value` for two-way binding. Use for keywords, recipients, labels, skills, allowlists.",props:[{name:"id",type:"string"},{name:"value",type:"string[]",optional:!0,description:"Bound array of tag values"},{name:"placeholder",type:"string",optional:!0},{name:"label",type:"string",optional:!0,description:"Inline label above the field"},{name:"max",type:"number",optional:!0,description:"Maximum number of tags"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=k(e.value).map(g=>d(g)).filter(Boolean),n=Math.max(0,Math.floor(P(e.max,0))),s=C(e.disabled),l=t.argMeta?.[1]?.stateRef,c=g=>{l&&r.setState(l,g)},u=d(e.label),p=o("div",{class:"rui-tag-input","data-disabled":s?"true":"false"});for(const g of i){const f=o("span",{class:"rui-tag-input-chip"});f.append(o("span",{},[g]));const h=o("button",{type:"button",class:"rui-tag-input-remove","aria-label":`Remove ${g}`},["×"]);h.onclick=()=>c(i.filter(b=>b!==g)),f.append(h),p.append(f)}const m=o("input",{type:"text",class:"rui-tag-input-field",id:a,name:a,placeholder:d(e.placeholder,i.length===0?"Add tags…":""),disabled:s?"":null,autocomplete:"off"});if(m.onkeydown=g=>{const f=g,h=f.currentTarget;if(f.key==="Enter"||f.key===","){f.preventDefault();const b=h.value.trim();if(!b||n>0&&i.length>=n)return;if(i.includes(b)){h.value="";return}c([...i,b]),h.value=""}else f.key==="Backspace"&&h.value===""&&i.length>0&&(f.preventDefault(),c(i.slice(0,-1)))},p.append(m),u){const g=o("div",{class:"rui-tag-input-wrapper"});return g.append(o("label",{class:"rui-tag-input-label",for:a},[u])),g.append(p),g}return p}};function ru(t){return k(t).map(e=>{if(typeof e=="string")return{value:e,label:e};if(e&&typeof e=="object"){const r=e,a=d(r.value??r.id??r.name),i=d(r.label,a);return{value:a,label:i}}return{value:"",label:""}}).filter(e=>e.value)}const au={name:"MentionInput",description:"Multi-line input with inline @-mention suggestions. Typing `@` opens a popover listing the provided `people` (filtered by what follows). Selecting an option inserts `@label` into the text. Pass a `$variable` as `value` for two-way binding. Use for comments, task notes, chat composers.",props:[{name:"id",type:"string"},{name:"people",type:"any[]",description:"Available mentions: strings or {value, label} objects"},{name:"value",type:"string",optional:!0,description:"Bound text (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"rows",type:"number",optional:!0,description:"TextArea rows (default 3)"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=ru(e.people),n=C(e.disabled),s=o("div",{class:"rui-mention-input","data-disabled":n?"true":"false"}),l=o("textarea",{class:"rui-mention-input-field",id:a,name:a,rows:String(Math.max(2,Math.floor(P(e.rows,3)))),placeholder:d(e.placeholder,"Type @ to mention someone"),disabled:n?"":null});l.value=d(e.value);const c=t.argMeta?.[2]?.stateRef;c&&r.bindState(l,c,{event:"input",getValue:g=>g.value});const u=o("div",{class:"rui-mention-input-suggestions","data-open":"false"}),p=g=>{u.replaceChildren();const h=i.filter(b=>b.label.toLowerCase().includes(g.toLowerCase())).slice(0,6);if(h.length===0){u.setAttribute("data-open","false");return}u.setAttribute("data-open","true");for(const b of h){const v=o("button",{type:"button",class:"rui-mention-input-option","data-value":b.value},[b.label]);v.onmousedown=y=>y.preventDefault(),v.onclick=()=>{m(b),u.setAttribute("data-open","false")},u.append(v)}},m=g=>{const f=l.value,h=l.selectionStart,b=f.slice(0,h),v=b.lastIndexOf("@");if(v===-1)return;const y=f.slice(h),x=`@${g.label} `,w=b.slice(0,v)+x+y;l.value=w;const T=v+x.length;l.selectionStart=l.selectionEnd=T,l.dispatchEvent(new Event("input",{bubbles:!0})),l.focus()};return l.oninput=()=>{const g=l.selectionStart,f=l.value.slice(0,g),h=/@([\w-]*)$/.exec(f);h?p(h[1]??""):u.setAttribute("data-open","false")},l.onblur=()=>setTimeout(()=>u.setAttribute("data-open","false"),80),s.append(l),s.append(u),s}},iu={name:"TimePicker",description:'Time-of-day picker that wraps `<input type="time">`. Pass a `$variable` as `value` for two-way binding (HH:MM 24-hour). Set `step` to constrain to specific increments (e.g. 900 for 15-minute buckets).',props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"HH:MM value; typically $variable"},{name:"label",type:"string",optional:!0},{name:"min",type:"string",optional:!0},{name:"max",type:"string",optional:!0},{name:"step",type:"number",optional:!0,description:"Seconds between selectable times"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("div",{class:"rui-time-picker"}),n=d(e.label);n&&i.append(o("label",{class:"rui-time-picker-label",for:a},[n]));const s=o("input",{type:"time",class:"rui-time-picker-input",id:a,name:a,value:d(e.value),min:d(e.min)||null,max:d(e.max)||null,step:e.step!=null?String(P(e.step,60)):null,disabled:C(e.disabled)?"":null}),l=t.argMeta?.[1]?.stateRef;return l&&r.bindState(s,l),i.append(s),i}},nu={name:"DateTimePicker",description:'Combined date + time picker — wraps `<input type="datetime-local">`. Pass a `$variable` as `value` for two-way binding (ISO `YYYY-MM-DDTHH:MM`).',props:[{name:"id",type:"string"},{name:"value",type:"string",optional:!0,description:"ISO date-time value; typically $variable"},{name:"label",type:"string",optional:!0},{name:"min",type:"string",optional:!0},{name:"max",type:"string",optional:!0},{name:"step",type:"number",optional:!0,description:"Seconds between selectable times"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=o("div",{class:"rui-datetime-picker"}),n=d(e.label);n&&i.append(o("label",{class:"rui-datetime-picker-label",for:a},[n]));const s=o("input",{type:"datetime-local",class:"rui-datetime-picker-input",id:a,name:a,value:d(e.value),min:d(e.min)||null,max:d(e.max)||null,step:e.step!=null?String(P(e.step,60)):null,disabled:C(e.disabled)?"":null}),l=t.argMeta?.[1]?.stateRef;return l&&r.bindState(s,l),i.append(s),i}};function qa(t,e){let r="",a=t;for(const i of e){if(!a)break;if(i==="9"){const n=/\d/.exec(a);if(!n)break;r+=n[0],a=a.slice(a.indexOf(n[0])+1)}else if(i==="A"){const n=/[a-zA-Z]/.exec(a);if(!n)break;r+=n[0],a=a.slice(a.indexOf(n[0])+1)}else i==="*"?(r+=a.charAt(0),a=a.slice(1)):(r+=i,a.startsWith(i)&&(a=a.slice(1)))}return r}const ou={name:"MaskedInput",description:'Text input with an inline mask — `9` matches a digit, `A` matches a letter, `*` matches any character, every other character is a fixed delimiter. Useful for phone numbers, postal codes, credit cards. Pass `mask` (e.g. `"(999) 999-9999"`) and a `$variable` as `value`.',props:[{name:"id",type:"string"},{name:"mask",type:"string",description:"Mask pattern"},{name:"value",type:"string",optional:!0,description:"Bound value (typically $variable)"},{name:"placeholder",type:"string",optional:!0},{name:"label",type:"string",optional:!0,description:"Inline label above the field"},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=d(e.id),i=d(e.mask),n=C(e.disabled),s=qa(d(e.value),i),l=d(e.label),c=o("input",{type:"text",class:"rui-masked-input",id:a,name:a,value:s,placeholder:d(e.placeholder,i),disabled:n?"":null,autocomplete:"off"}),u=t.argMeta?.[2]?.stateRef;if(c.oninput=()=>{c.value=qa(c.value,i)},u&&r.bindState(c,u,{event:"input",getValue:p=>p.value}),l){const p=o("div",{class:"rui-masked-input-wrapper"});return p.append(o("label",{class:"rui-masked-input-label",for:a},[l])),p.append(c),p}return c}},su={name:"FormSection",description:"Semantic grouping for related form fields — renders a small heading (`label`), optional helper paragraph, and stacks the children with consistent spacing. Use INSTEAD of wrapping fields in `Card` + `SectionHeader` by hand. Pair with `FieldSet` when the group is a true `<fieldset>` (radio sets, checkbox groups).",props:[{name:"label",type:"string",aliases:["title"]},{name:"children",type:"Node[]",aliases:["fields"]},{name:"helper",type:"string",optional:!0,aliases:["description"],description:"Description rendered below the label"}],render:(t,e,r)=>{const a=o("section",{class:"rui-form-section"}),i=o("header",{class:"rui-form-section-header"});i.append(o("h3",{class:"rui-form-section-label"},[d(e.label)]));const n=d(e.helper);n&&i.append(o("p",{class:"rui-form-section-helper"},[n])),a.append(i);const s=o("div",{class:"rui-form-section-body"});for(const l of k(e.children))s.append(r.renderNode(l));return a.append(s),a}},lu={name:"FieldSet",description:"Native `<fieldset>`/`<legend>` wrapper for accessible grouping of related controls. Use when assistive tech should announce the wrapper (radio sets, checkbox groups). For purely visual grouping prefer `FormSection`.",props:[{name:"legend",type:"string",aliases:["title","label"]},{name:"children",type:"Node[]",aliases:["fields"]},{name:"helper",type:"string",optional:!0,aliases:["hint","description"]},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=o("fieldset",{class:"rui-fieldset",disabled:C(e.disabled)?"":null});a.append(o("legend",{class:"rui-fieldset-legend"},[d(e.legend)]));const i=d(e.helper);i&&a.append(o("p",{class:"rui-fieldset-helper"},[i]));for(const n of k(e.children))a.append(r.renderNode(n));return a}},cu={name:"ValidationSummary",description:"Aggregate error list rendered at the top of a form. Pass `errors` as `{label?, message, field?}` objects or plain strings. Pair with individual field hints via `FormControl(hint=...)`.",props:[{name:"errors",type:"any[]"},{name:"title",type:"string",optional:!0,description:'Heading (default "Please fix the following:")'},{name:"tone",type:"string",optional:!0,enum:["danger","warning"]}],render:(t,e)=>{const r=k(e.errors).map(c=>{if(!c)return null;if(typeof c=="string")return{label:"",message:c,field:""};if(typeof c=="object"){const u=c;return{label:d(u.label),message:d(u.message??u.error),field:d(u.field)}}return null}).filter(c=>c!==null&&c.message!=="");if(r.length===0)return o("div",{class:"rui-validation-summary","data-empty":"true",hidden:""});const a=d(e.tone,"danger"),i=o("aside",{class:"rui-validation-summary","data-tone":a,role:"alert"}),n=o("div",{class:"rui-validation-summary-title"}),s=L(a==="warning"?"triangle-exclamation":"circle-xmark",{className:"rui-validation-summary-icon"});s&&n.append(s),n.append(document.createTextNode(d(e.title,"Please fix the following:"))),i.append(n);const l=o("ul",{class:"rui-validation-summary-list"});for(const c of r){const u=o("li",{class:"rui-validation-summary-item"});c.label&&u.append(o("strong",{},[`${c.label}: `])),u.append(document.createTextNode(c.message)),l.append(u)}return i.append(l),i}};function uu(t){return k(t).map(e=>{if(!e||typeof e!="object")return{title:d(e),details:"",content:null};const r=e;return{title:d(r.title),details:d(r.details),content:r.content??null}})}const du={name:"MultiStepForm",description:"Multi-step / wizard form composite. Renders a `Steps` indicator, the active step's `content`, and Prev/Next buttons that drive a `$variable` for the current 0-indexed step. Use INSTEAD of hand-rolling `Steps` + content + manual prev/next wiring. The submit button is rendered on the final step (override via `submitLabel`).",props:[{name:"steps",type:"object[]",description:"Array of {title, details?, content} step objects"},{name:"current",type:"number",description:"0-indexed active step — bind a $variable"},{name:"onSubmit",type:"callable",optional:!0,description:"Callable fired when the user clicks Submit on the final step"},{name:"prevLabel",type:"string",optional:!0,description:'Default "Back"'},{name:"nextLabel",type:"string",optional:!0,description:'Default "Continue"'},{name:"submitLabel",type:"string",optional:!0,description:'Default "Submit" (final step)'}],render:(t,e,r)=>{const a=uu(e.steps),i=a.length,n=Math.max(0,Math.min(i-1,Math.floor(P(e.current,0)))),s=t.argMeta?.[1]?.stateRef,l=o("div",{class:"rui-multi-step-form"}),c=o("ol",{class:"rui-steps rui-multi-step-form-steps"});a.forEach((v,y)=>{const x=o("li",{class:"rui-steps-item","data-active":y===n?"true":"false","data-complete":y<n?"true":"false"});x.append(o("div",{class:"rui-steps-title"},[v.title||`Step ${y+1}`])),v.details&&x.append(o("div",{class:"rui-steps-details"},[v.details])),c.append(x)}),l.append(c);const u=o("div",{class:"rui-multi-step-form-body"}),p=a[n];p&&p.content&&u.append(r.renderNode(p.content)),l.append(u);const m=o("div",{class:"rui-multi-step-form-footer"}),g=o("button",{type:"button",class:"rui-button","data-variant":"ghost",disabled:n<=0?"":null},[d(e.prevLabel,"Back")]);s&&n>0&&(g.onclick=()=>r.setState(s,n-1));const f=n>=i-1,h=f?d(e.submitLabel,"Submit"):d(e.nextLabel,"Continue"),b=o("button",{type:"button",class:"rui-button","data-variant":"primary"},[h]);return b.onclick=()=>{f?r.invoke(e.onSubmit):s&&r.setState(s,n+1)},m.append(g),m.append(o("span",{class:"rui-multi-step-form-progress"},[`${n+1} / ${i}`])),m.append(b),l.append(m),l}};function pu(t){return k(t).map(e=>{if(!e||typeof e!="object")return null;const r=e;return{title:d(r.title),message:d(r.message),time:d(r.time),icon:d(r.icon),tone:d(r.tone,"default"),unread:C(r.unread),avatarSrc:d(r.avatarSrc),action:r.action}}).filter(e=>e!==null)}const mu={name:"InboxPanel",description:"Grouped notification list — entries are grouped into Unread/Earlier sections, with a count chip on each group header. Pass `items` as `{title, message, time, icon?, tone?, unread?, avatarSrc?, action?}` objects. Pair with a `SectionHeader` for the panel title (the component does not render its own title to avoid duplication). Use for top-bar notification trays, activity drawers, and alert center pages.",props:[{name:"items",type:"object[]"},{name:"emptyLabel",type:"string",optional:!0,description:"Text shown when there are no notifications"},{name:"onMarkAllRead",type:"callable",optional:!0,description:'Callable fired by the "Mark all as read" button'}],render:(t,e,r)=>{const a=pu(e.items),i=a.filter(c=>c.unread),n=a.filter(c=>!c.unread),s=o("div",{class:"rui-inbox-panel"});if(typeof e.onMarkAllRead=="function"&&i.length>0){const c=o("div",{class:"rui-inbox-panel-toolbar"}),u=o("button",{type:"button",class:"rui-inbox-panel-mark-all"},["Mark all as read"]);u.onclick=()=>r.invoke(e.onMarkAllRead),c.append(u),s.append(c)}if(a.length===0)return s.append(o("div",{class:"rui-inbox-panel-empty"},[d(e.emptyLabel,"You're all caught up.")])),s;const l=(c,u)=>{if(u.length===0)return;const p=o("section",{class:"rui-inbox-panel-group"}),m=o("header",{class:"rui-inbox-panel-group-head"});m.append(o("span",{class:"rui-inbox-panel-group-label"},[c])),m.append(o("span",{class:"rui-inbox-panel-group-count"},[String(u.length)])),p.append(m);for(const g of u){const f=Sa.render({__kind:"Component",name:"Notification",args:[],argMeta:[]},{title:g.title,message:g.message,time:g.time,icon:g.icon,tone:g.tone,avatarSrc:g.avatarSrc,unread:g.unread},r);typeof g.action=="function"&&(f.setAttribute("data-clickable","true"),f.onclick=()=>r.invoke(g.action)),p.append(f)}s.append(p)};return l(`Unread (${i.length})`,i),l("Earlier",n),s}};function gu(t){return k(t).map(e=>{if(!e||typeof e!="object")return null;const r=e;return{title:d(r.title),description:d(r.description),done:C(r.done),action:r.action,cta:d(r.cta,"Start")}}).filter(e=>e!==null)}const fu={name:"OnboardingChecklist",description:'Step-by-step product checklist with completion progress at the top. Pass `items` as `{title, description?, done?, action?, cta?}` objects. The progress percentage is computed automatically from `done`. Use on first-run dashboards, empty workspaces, and "complete your profile" surfaces.',props:[{name:"items",type:"object[]"},{name:"title",type:"string",optional:!0,description:'Heading (default "Getting started")'},{name:"subtitle",type:"string",optional:!0}],render:(t,e,r)=>{const a=gu(e.items),i=a.filter(m=>m.done).length,n=Math.max(1,a.length),s=Math.round(i/n*100),l=o("div",{class:"rui-onboarding-checklist"}),c=o("header",{class:"rui-onboarding-checklist-header"});c.append(o("h3",{class:"rui-onboarding-checklist-title"},[d(e.title,"Getting started")]));const u=d(e.subtitle);u&&c.append(o("p",{class:"rui-onboarding-checklist-subtitle"},[u])),c.append(o("div",{class:"rui-onboarding-checklist-progress"},[o("div",{class:"rui-onboarding-checklist-bar"},[o("div",{class:"rui-onboarding-checklist-fill",style:`width:${s}%`})]),o("span",{class:"rui-onboarding-checklist-meta"},[`${i}/${a.length} complete`])])),l.append(c);const p=o("ol",{class:"rui-onboarding-checklist-list"});for(const m of a){const g=o("li",{class:"rui-onboarding-checklist-item","data-done":m.done?"true":"false"}),f=o("span",{class:"rui-onboarding-checklist-marker"}),h=L(m.done?"circle-check":"circle",{className:"rui-onboarding-checklist-marker-icon"});h&&f.append(h),g.append(f);const b=o("div",{class:"rui-onboarding-checklist-body"});if(b.append(o("div",{class:"rui-onboarding-checklist-item-title"},[m.title])),m.description&&b.append(o("p",{class:"rui-onboarding-checklist-item-description"},[m.description])),g.append(b),!m.done&&typeof m.action=="function"){const v=o("button",{type:"button",class:"rui-button","data-variant":"secondary","data-size":"sm"},[m.cta]);v.onclick=()=>r.invoke(m.action),g.append(v)}p.append(g)}return l.append(p),l}};function Ha(t){const e=o("div",{class:`rui-${t.klass}`});if(t.iconName){const a=L(t.iconName,{className:t.iconClass});a&&e.append(a)}t.title&&e.append(o("h3",{class:`rui-${t.klass}-title`},[t.title])),t.description&&e.append(o("p",{class:`rui-${t.klass}-description`},[t.description]));const r=k(t.actions);if(r.length>0){const a=o("div",{class:`rui-${t.klass}-actions`});for(const i of r)a.append(t.helpers.renderNode(i));e.append(a)}return e}const hu={name:"LoadingState",description:"Full-card loading state — large spinner + title + description. Use while a query is in flight or while a long-running tool runs. For tiny inline loaders prefer `Spinner`; for skeleton placeholders prefer `Skeleton`.",props:[{name:"title",type:"string",optional:!0,description:'Default "Loading…"'},{name:"description",type:"string",optional:!0}],render:(t,e)=>{const r=o("div",{class:"rui-loading-state"}),a=o("span",{class:"rui-spinner","data-size":"lg","data-tone":"primary"});a.append(o("span",{class:"rui-spinner-ring","aria-hidden":"true"})),r.append(a),r.append(o("h3",{class:"rui-loading-state-title"},[d(e.title,"Loading…")]));const i=d(e.description);return i&&r.append(o("p",{class:"rui-loading-state-description"},[i])),r}},bu={name:"ErrorState",description:"Full-card error placeholder. Pairs a danger icon with title, description, and a row of recovery actions (Retry / Contact support / Go home). Pass `actions` as Button(...) entries.",props:[{name:"title",type:"string",optional:!0,description:'Default "Something went wrong"'},{name:"description",type:"string",optional:!0},{name:"actions",type:"Node[]",optional:!0},{name:"icon",type:"string",optional:!0,description:"Font Awesome icon (default `circle-exclamation`)"}],render:(t,e,r)=>Ha({klass:"error-state",iconName:d(e.icon,"circle-exclamation"),iconClass:"rui-error-state-icon",title:d(e.title,"Something went wrong"),description:d(e.description),actions:e.actions,helpers:r})},vu={name:"SuccessState",description:'Full-card success placeholder. Use for confirmation screens ("Order placed", "Payment succeeded", "Account verified") at the end of a flow. Pass `actions` for follow-up CTAs.',props:[{name:"title",type:"string"},{name:"description",type:"string",optional:!0},{name:"actions",type:"Node[]",optional:!0},{name:"icon",type:"string",optional:!0,description:"Default `circle-check`"}],render:(t,e,r)=>Ha({klass:"success-state",iconName:d(e.icon,"circle-check"),iconClass:"rui-success-state-icon",title:d(e.title),description:d(e.description),actions:e.actions,helpers:r})},yu={name:"Tour",description:"Product-tour controller — renders the current step's title, description, and a Prev/Next/Skip row. Bind `current` to a `$variable` (0-indexed). Pass `steps` as `{title, description, target?}` objects; the optional `target` is a CSS selector that renders alongside the step for designers to reference.",props:[{name:"steps",type:"object[]"},{name:"current",type:"number",description:"0-indexed active step — bind a $variable"},{name:"open",type:"boolean",optional:!0,description:"Whether the tour is visible"},{name:"onComplete",type:"callable",optional:!0}],render:(t,e,r)=>{const a=k(e.steps).map(v=>{if(!v||typeof v!="object")return{title:d(v),description:"",target:""};const y=v;return{title:d(y.title),description:d(y.description),target:d(y.target)}}),i=e.open===void 0?!0:C(e.open),n=a.length,s=Math.max(0,Math.min(n-1,Math.floor(P(e.current,0)))),l=t.argMeta?.[1]?.stateRef,c=o("div",{class:"rui-tour","data-open":i?"true":"false"});if(!i||n===0)return c;const u=a[s];if(!u)return c;const p=o("div",{class:"rui-tour-card",role:"dialog","aria-modal":"false"});p.append(o("div",{class:"rui-tour-step"},[`Step ${s+1} of ${n}`])),p.append(o("h3",{class:"rui-tour-title"},[u.title])),u.description&&p.append(o("p",{class:"rui-tour-description"},[u.description])),u.target&&p.append(o("div",{class:"rui-tour-target"},[`Target: ${u.target}`]));const m=o("div",{class:"rui-tour-footer"}),g=o("button",{type:"button",class:"rui-button","data-variant":"ghost"},["Skip"]);g.onclick=()=>r.invoke(e.onComplete);const f=o("button",{type:"button",class:"rui-button","data-variant":"secondary",disabled:s<=0?"":null},["Back"]);l&&s>0&&(f.onclick=()=>r.setState(l,s-1));const h=s>=n-1,b=o("button",{type:"button",class:"rui-button","data-variant":"primary"},[h?"Finish":"Next"]);return b.onclick=()=>{h?r.invoke(e.onComplete):l&&r.setState(l,s+1)},m.append(g,f,b),p.append(m),c.append(p),c}},xu={name:"Spotlight",description:'Single-step product highlight — a dimmed full-page overlay with a ring around the focused area and a small explainer card. Use for one-off feature reveals ("Try the new commands menu"). Bind `open` to a `$variable` to dismiss.',props:[{name:"title",type:"string"},{name:"open",type:"boolean",optional:!0,description:"Whether the spotlight is visible — typically a $variable (default true)"},{name:"description",type:"string",optional:!0},{name:"actions",type:"Node[]",optional:!0,aliases:["action"]}],render:(t,e,r)=>{const a=e.open===void 0?!0:C(e.open),i=o("div",{class:"rui-spotlight","data-open":a?"true":"false"});if(!a)return i;const n=o("div",{class:"rui-spotlight-card"});n.append(o("h3",{class:"rui-spotlight-title"},[d(e.title)]));const s=d(e.description);s&&n.append(o("p",{class:"rui-spotlight-description"},[s]));const l=k(e.actions);if(l.length>0){const u=o("div",{class:"rui-spotlight-actions"});for(const p of l)u.append(r.renderNode(p));n.append(u)}const c=t.argMeta?.[1]?.stateRef;return c&&(i.onclick=u=>{u.target===i&&r.setState(c,!1)}),i.append(n),i}},wu={name:"Sticky",description:"Wraps content in a `position: sticky` container so it pins to the top (or bottom) of the nearest scrollable ancestor. Use for toolbar action rows above tables, in-page navs, status banners.",props:[{name:"children",type:"Node[]"},{name:"side",type:"string",optional:!0,enum:["top","bottom"]},{name:"offset",type:"string",optional:!0,description:"CSS offset (default 0)"},{name:"zIndex",type:"number",optional:!0,description:"Z-index (default 10)"}],render:(t,e,r)=>{const a=d(e.side,"top"),i=ee(e.offset,"0"),n=Math.max(0,Math.floor(P(e.zIndex,10))),s=`position:sticky;${a}:${i};z-index:${n};`,l=o("div",{class:"rui-sticky",style:s});for(const c of k(e.children))l.append(r.renderNode(c));return l}},ku={name:"ResizablePanels",description:"Two-pane horizontal split with a draggable divider. The user can drag the divider to resize the primary pane; defaults respect the starting width. Use for code editors, file browsers, master/detail layouts that need user-controllable proportions.",props:[{name:"primary",type:"Node[]"},{name:"secondary",type:"Node[]"},{name:"initialPrimaryWidth",type:"string",optional:!0,description:"CSS width for the primary pane (default 40%)"},{name:"minPrimaryWidth",type:"string",optional:!0,description:"Min width (default 240px)"}],render:(t,e,r)=>{const a=ee(e.initialPrimaryWidth,"40%"),i=ee(e.minPrimaryWidth,"240px"),n=o("div",{class:"rui-resizable-panels",style:`--rui-resizable-primary:${a};--rui-resizable-min:${i};`}),s=o("div",{class:"rui-resizable-panel rui-resizable-panel-primary"});for(const u of k(e.primary))s.append(r.renderNode(u));const l=o("div",{class:"rui-resizable-divider",role:"separator","aria-orientation":"vertical",tabindex:"0"}),c=o("div",{class:"rui-resizable-panel rui-resizable-panel-secondary"});for(const u of k(e.secondary))c.append(r.renderNode(u));return n.append(s,l,c),l.onpointerdown=u=>{const p=u,m=p.currentTarget;m.setPointerCapture(p.pointerId);const g=m.closest(".rui-resizable-panels");if(!g)return;const f=g.getBoundingClientRect(),h=v=>{const y=(v.clientX-f.left)/f.width*100,x=Math.max(15,Math.min(85,y));g.style.setProperty("--rui-resizable-primary",`${x}%`)},b=v=>{m.releasePointerCapture(v.pointerId),m.removeEventListener("pointermove",h),m.removeEventListener("pointerup",b)};m.addEventListener("pointermove",h),m.addEventListener("pointerup",b)},n}},Su={name:"MasonryGrid",description:"Pinterest-style column grid. Children flow into columns that reflow on viewport changes. Use for galleries, social-style feeds, and mixed-height card walls. Prefer `Grid` when children should share the same height per row.",props:[{name:"items",type:"Node[]"},{name:"columns",type:"number",optional:!0,description:"Preferred column count (default 3)"},{name:"gap",type:"string",optional:!0,enum:["xs","s","m","l","xl"]}],render:(t,e,r)=>{const a=Math.max(1,Math.min(6,Math.floor(P(e.columns,3)))),i=d(e.gap,"m"),n=o("div",{class:"rui-masonry-grid","data-columns":String(a),"data-gap":i});for(const s of k(e.items))n.append(r.renderNode(s));return n}},Cu={name:"Drawer",description:"Side drawer overlay shown when `open` is true. Pass a `$variable` as `open` to control it. Choose `side` for slide direction (default right).",props:[{name:"title",type:"string"},{name:"open",type:"boolean",description:"Open/closed state — usually a $variable"},{name:"children",type:"Node[]"},{name:"side",type:"string",optional:!0,enum:["right","left","top","bottom"]},{name:"footer",type:"Node[]",optional:!0,description:"Optional footer actions row"}],render:(t,e,r)=>{const a=C(e.open),i=d(e.side,"right"),n=o("div",{class:"rui-sheet-overlay","data-open":a?"true":"false","data-side":i}),s=o("aside",{class:"rui-sheet",role:"dialog","aria-modal":"true","data-side":i}),l=o("header",{class:"rui-sheet-header"});l.append(o("h3",{class:"rui-sheet-title"},[d(e.title)]));const c=o("button",{type:"button",class:"rui-sheet-close","aria-label":"Close"},["×"]),u=t.argMeta?.[1]?.stateRef;u&&(c.onclick=()=>r.setState(u,!1),n.onclick=g=>{g.target===n&&r.setState(u,!1)}),l.append(c),s.append(l);const p=o("div",{class:"rui-sheet-body"});for(const g of k(e.children))p.append(r.renderNode(g));s.append(p);const m=k(e.footer);if(m.length>0){const g=o("footer",{class:"rui-sheet-footer"});for(const f of m)g.append(r.renderNode(f));s.append(g)}return n.append(s),n}},Tu={name:"TopBar",description:'Compact header strip that pairs a title (or breadcrumb) with search and action slots. Use INSTEAD of hand-rolling a `Stack(direction="row")` above a page. For full SaaS shells use `Navbar` (links) or `AppShell` (sidebar + topbar + content).',props:[{name:"title",type:"string",optional:!0},{name:"subtitle",type:"string",optional:!0},{name:"left",type:"Node[]",optional:!0,aliases:["badges"],description:"Leading slot (breadcrumbs, brand, status, badges)"},{name:"center",type:"Node[]",optional:!0,aliases:["search"],description:"Centered slot (search bar, segmented control)"},{name:"right",type:"Node[]",optional:!0,aliases:["actions"],description:"Trailing slot (actions, avatar)"},{name:"sticky",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=o("header",{class:"rui-topbar","data-sticky":C(e.sticky)?"true":"false"}),i=o("div",{class:"rui-topbar-side rui-topbar-left"}),n=d(e.title);if(n){const c=o("div",{class:"rui-topbar-title-block"});c.append(o("h2",{class:"rui-topbar-title"},[n]));const u=d(e.subtitle);u&&c.append(o("p",{class:"rui-topbar-subtitle"},[u])),i.append(c)}for(const c of k(e.left))i.append(r.renderNode(c));a.append(i);const s=k(e.center);if(s.length>0){const c=o("div",{class:"rui-topbar-side rui-topbar-center"});for(const u of s)c.append(r.renderNode(u));a.append(c)}const l=o("div",{class:"rui-topbar-side rui-topbar-right"});for(const c of k(e.right))l.append(r.renderNode(c));return a.append(l),a}},$u={name:"Theme",description:"Apply a partial theme on top of the base theme. Pass an object of token → value pairs (colors, fonts, radii, spacing, button styling). Assigning the result to a top-level binding (conventionally `theme`) lets the runtime detect it and write the tokens to the host as CSS custom properties — the rest of the rendered UI picks them up instantly.",props:[{name:"tokens",type:"any",description:"Object literal of theme tokens. Keys must match `ThemeTokens` (e.g. colorPrimary, colorBg, fontFamily, fontFamilyHeading, fontSizeBase, radiusMd, radiusButton, borderWidth, shadowMd, buttonFontWeight, …). Unknown keys are ignored."}],render:()=>document.createDocumentFragment()},Nu={name:"NavLink",description:'Anchor that navigates to a route on click and stays in sync with the URL hash. Reflects `data-active="true"` when the current path matches `to` (set `exact=true` to require exact equality instead of prefix matching).',props:[{name:"label",type:"string",description:"Visible link text."},{name:"to",type:"string",description:'Target route path, e.g. "/about".'},{name:"variant",type:"string",optional:!0,enum:["default","primary","ghost","pill"],description:"Visual variant."},{name:"exact",type:"boolean",optional:!0,description:"Match the current path exactly (default: prefix match)."},{name:"icon",type:"string",optional:!0,description:"Optional Font Awesome icon name shown before the label."}],render:(t,e,r)=>{const a=d(e.label,""),i=d(e.to,"/"),n=d(e.variant,"default"),s=C(e.exact,!1),l=r.router,c=l.getPath(),u=c?s?c===i:i==="/"?c==="/":c===i?!0:c.startsWith(i+"/"):!1,p=o("a",{class:"rui-nav-link","data-variant":n,"data-active":u?"true":"false",href:"#"+(i.startsWith("/")?i:"/"+i)}),m=L(e.icon,{className:"rui-nav-link-icon"});return m&&p.append(m),p.append(o("span",{class:"rui-nav-link-label"},[a])),p.onclick=g=>{g.defaultPrevented||g.button===0&&(g.metaKey||g.ctrlKey||g.shiftKey||g.altKey||(g.preventDefault(),l.navigate(i)))},p}},Au=["primary","secondary","ghost","danger"],Mu=["xs","sm","md","lg","xl","small","normal","large"];function Pu(t){const e=d(t).trim().toLowerCase();return e==="xs"||e==="extra-small"?"xs":e==="small"||e==="sm"?"sm":e==="large"||e==="lg"?"lg":e==="xl"||e==="extra-large"?"xl":e==="normal"||e==="md"||e===""?"md":e==="xs"||e==="sm"||e==="md"||e==="lg"||e==="xl"?e:"md"}function Iu(t){return k(t).map(e=>{if(e&&typeof e=="object"){const a=e,i=d(a.value??a.label);return{value:i,label:d(a.label,i)}}const r=d(e);return{value:r,label:r}}).filter(e=>e.label!=="")}function pt(t){return k(t).filter(e=>!!e&&typeof e=="object"&&!Array.isArray(e))}function zu(t){return k(t).map(e=>{if(e&&typeof e=="object"){const a=e,i=d(a.value??a.label);return{value:i,label:d(a.label,i),group:d(a.group)||void 0,shortcut:d(a.shortcut)||void 0,action:a.action}}const r=d(e);return{value:r,label:r}}).filter(e=>e.label!=="")}function Va(t){return k(t).map(e=>{if(e&&typeof e=="object"){const a=e,i=d(a.name??a.label);return{name:i,label:d(a.label,i),type:d(a.type,"text")||"text"}}const r=d(e);return{name:r,label:r,type:"text"}}).filter(e=>e.name!=="")}function Ru(t){return pt(t).map((e,r)=>({id:d(e.id,`task-${r}`),label:d(e.label??e.name,`Task ${r+1}`),start:d(e.start),end:d(e.end),progress:e.progress!=null?P(e.progress,0):void 0}))}function Ne(t){const e=Date.parse(t);return Number.isNaN(e)?Date.now():e}function Lu(t,e){const r=t.split(`
21
21
  `),a=e.split(`
22
- `),i=Math.max(r.length,a.length),n=[];for(let s=0;s<i;s++){const l=r[s],c=a[s];l===c?l!==void 0&&n.push({type:"same",text:l}):(l!==void 0&&n.push({type:"remove",text:l}),c!==void 0&&n.push({type:"add",text:c}))}return n}function Va(t){try{return JSON.stringify(t,null,2)}catch{return String(t)}}function Wa(t,e,r,a){for(const[i,n]of e){const s=o("div",{class:"rui-json-tree-row"});s.append(o("span",{class:"rui-json-tree-key"},[`${i}: `])),n!==null&&typeof n=="object"?s.append(Ga(n,r,a+1)):s.append(o("span",{class:"rui-json-tree-leaf"},[Va(n)])),t.append(s)}}function Ga(t,e,r=0){const a=o("div",{class:"rui-json-tree-node","data-depth":String(r)});if(t===null||typeof t!="object")return a.append(o("span",{class:"rui-json-tree-leaf"},[Va(t)])),a;const i=Array.isArray(t),n=i?t.map((u,p)=>[String(p),u]):Object.entries(t),s=e||r<1,l=o("button",{type:"button",class:"rui-json-tree-toggle","aria-expanded":s?"true":"false"},[s?"▼":"▶",i?` Array(${n.length})`:" Object"]),c=o("div",{class:"rui-json-tree-children","data-open":s?"true":"false"});return s&&Wa(c,n,e,r),l.onclick=u=>{const p=u.currentTarget,m=p.nextElementSibling;if(!m)return;const g=m.getAttribute("data-open")!=="true";m.setAttribute("data-open",g?"true":"false"),p.setAttribute("aria-expanded",g?"true":"false"),p.firstChild&&(p.firstChild.textContent=g?"▼":"▶"),g&&m.childElementCount===0?Wa(m,n,e,r):g||m.replaceChildren()},a.append(l,c),a}const Lu={name:"IconButton",description:"Icon-only button with an accessible label. Use for toolbars, table row actions, and compact controls.",props:[{name:"icon",type:"string",description:"Font Awesome icon name"},{name:"label",type:"string",description:"Accessible label (visually hidden)"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"]},{name:"variant",type:"string",optional:!0,aliases:["tone"],enum:$u},{name:"size",type:"string",optional:!0,enum:Au},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=o("button",{class:"rui-icon-button",type:"button","data-variant":d(e.variant,"ghost"),"data-size":Mu(e.size),"aria-label":d(e.label),title:d(e.label),disabled:C(e.disabled)?"":null}),i=L(e.icon,{className:"rui-icon-button-icon"});return i&&a.append(i),a.onclick=()=>r.invoke(e.action),a}},Eu={name:"CommandPalette",description:"Cmd-K style searchable command list. Pass `items` as `{label, value, group?, shortcut?, action?}` objects.",props:[{name:"items",type:"any[]"},{name:"open",type:"boolean",optional:!0,description:"Whether the palette is visible (default true)"},{name:"placeholder",type:"string",optional:!0},{name:"shortcut",type:"string",optional:!0,description:"Hint label, e.g. Cmd+K"}],render:(t,e,r)=>{const a=Iu(e.items),i=e.open!==void 0,n=i?C(e.open):!0,s=r.useInstanceState("open",n);i&&s.get()!==n&&s.set(n);const l=r.useInstanceState("filter",""),c=i?n:s.get(),u=o("div",{class:"rui-command-palette","data-open":c?"true":"false"});if(!c)return u;const p=o("div",{class:"rui-command-palette-backdrop"}),m=o("div",{class:"rui-command-palette-panel",role:"dialog","aria-modal":"true"}),g=o("div",{class:"rui-command-palette-header"}),f=o("input",{type:"text",class:"rui-command-palette-input",placeholder:d(e.placeholder,"Search commands…"),value:l.get(),autocomplete:"off"});g.append(f);const h=d(e.shortcut);h&&g.append(o("span",{class:"rui-command-palette-shortcut"},[h])),m.append(g);const b=o("div",{class:"rui-command-palette-list",role:"listbox"}),v=(y,x)=>{y.replaceChildren();const w=x.trim().toLowerCase(),T=w===""?a:a.filter($=>$.label.toLowerCase().includes(w)||$.value.toLowerCase().includes(w)||($.group??"").toLowerCase().includes(w));let S="";for(const $ of T.slice(0,50)){$.group&&$.group!==S&&(S=$.group,y.append(o("div",{class:"rui-command-palette-group"},[S])));const N=o("button",{type:"button",class:"rui-command-palette-item",role:"option","data-value":$.value},[$.label]);$.shortcut&&N.append(o("span",{class:"rui-command-palette-item-kbd"},[$.shortcut])),N.onclick=A=>{A.stopPropagation(),r.invoke($.action),s.set(!1),l.set("");const z=A.currentTarget.closest(".rui-command-palette"),R=z?.querySelector(".rui-command-palette-panel");z?.setAttribute("data-open","false"),he(R??null)},y.append(N)}T.length===0&&y.append(o("div",{class:"rui-command-palette-empty"},["No commands found"]))};return v(b,l.get()),m.append(b),p.onclick=y=>{const x=y.currentTarget.closest(".rui-command-palette"),w=x?.querySelector(".rui-command-palette-panel");s.set(!1),x?.setAttribute("data-open","false"),he(w??null)},u.append(p,m),f.oninput=y=>{const x=y.currentTarget,w=x.closest(".rui-command-palette-panel")?.querySelector(".rui-command-palette-list");l.set(x.value),w&&v(w,x.value)},f.onkeydown=y=>{if(y.key==="Escape"){const x=y.currentTarget.closest(".rui-command-palette"),w=x?.querySelector(".rui-command-palette-panel");s.set(!1),x?.setAttribute("data-open","false"),he(w??null)}},setTimeout(()=>f.focus(),0),Ee({liveRoot:m,onDismiss:()=>{s.set(!1),u.setAttribute("data-open","false")}}),u}},_u={name:"FilterChips",description:"Removable filter chips with an optional clear-all control.",props:[{name:"chips",type:"any[]",description:"Array of strings or {label, value} objects"},{name:"onRemove",type:"callable",optional:!0,description:"Receives the removed chip value as an argument"},{name:"onClear",type:"callable",optional:!0}],render:(t,e,r)=>{const a=Pu(e.chips),i=o("div",{class:"rui-filter-chips"}),n=o("div",{class:"rui-filter-chips-row"});for(const s of a){const l=o("span",{class:"rui-filter-chip","data-value":s.value});l.append(o("span",{class:"rui-filter-chip-label"},[s.label]));const c=o("button",{type:"button",class:"rui-filter-chip-remove","aria-label":`Remove ${s.label}`}),u=L("xmark",{className:"rui-filter-chip-remove-icon"});u&&c.append(u),c.onclick=()=>r.invoke(e.onRemove,s.value),l.append(c),n.append(l)}if(i.append(n),a.length>0&&typeof e.onClear=="function"){const s=o("button",{type:"button",class:"rui-filter-chips-clear"},["Clear all"]);s.onclick=()=>r.invoke(e.onClear),i.append(s)}return i}},ju={name:"FieldRepeater",description:"Dynamic list of field groups. Pass `items` as row objects and `fields` as `{name, label, type?}` definitions.",props:[{name:"items",type:"any[]"},{name:"fields",type:"any[]"},{name:"onAdd",type:"callable",optional:!0},{name:"onRemove",type:"callable",optional:!0,description:"Receives the removed row's 0-indexed position"},{name:"addLabel",type:"string",optional:!0}],render:(t,e,r)=>{const a=pt(e.items),i=Ha(e.fields),n=o("div",{class:"rui-field-repeater"});if(a.forEach((s,l)=>{const c=o("div",{class:"rui-field-repeater-row","data-index":String(l)}),u=o("div",{class:"rui-field-repeater-grid"});for(const p of i){const m=o("label",{class:"rui-field-repeater-field"});m.append(o("span",{class:"rui-field-repeater-label"},[p.label]));const g=o("input",{class:"rui-input",type:p.type==="number"?"number":"text",name:`${p.name}-${l}`,value:d(s[p.name]),readonly:""});m.append(g),u.append(m)}if(c.append(u),typeof e.onRemove=="function"){const p=o("button",{type:"button",class:"rui-field-repeater-remove","aria-label":"Remove row"},["Remove"]);p.onclick=()=>r.invoke(e.onRemove,l),c.append(p)}n.append(c)}),typeof e.onAdd=="function"){const s=o("button",{type:"button",class:"rui-field-repeater-add rui-button","data-variant":"secondary"},[d(e.addLabel,"Add row")]);s.onclick=()=>r.invoke(e.onAdd),n.append(s)}return n}},Bu={name:"VirtualList",description:"Windowed vertical list for large datasets. Pass pre-rendered nodes as `items` or plain row objects plus a `renderItem` component node per row.",props:[{name:"items",type:"any[]"},{name:"itemHeight",type:"number",optional:!0,description:"Fixed row height in px (default 40)"},{name:"renderItem",type:"Node",optional:!0,description:"Template node rendered per data row"}],render:(t,e,r)=>{const a=Math.max(24,P(e.itemHeight,40)),i=k(e.items),n=o("div",{class:"rui-virtual-list"}),s=o("div",{class:"rui-virtual-list-scroller"}),l=o("div",{class:"rui-virtual-list-spacer"}),c=o("div",{class:"rui-virtual-list-window"}),u=i.length;l.style.height=`${u*a}px`,l.style.position="relative",c.style.position="absolute",c.style.top="0",c.style.left="0",c.style.right="0",s.style.maxHeight=`${Math.min(Math.max(u,1),12)*a}px`,s.style.overflow="auto";const p=m=>{c.replaceChildren();const g=s.clientHeight||a*12,f=Math.ceil(g/a)+2,h=Math.max(0,m),b=Math.min(u,h+f);c.style.transform=`translateY(${h*a}px)`;for(let v=h;v<b;v++){const y=i[v];if(e.renderItem)c.append(r.renderNode(y??e.renderItem));else if(y&&typeof y=="object"&&y.__kind)c.append(r.renderNode(y));else{const x=o("div",{class:"rui-virtual-list-item",style:`height:${a}px`});x.append(o("span",{},[d(y)])),c.append(x)}}};return s.onscroll=()=>{const m=Math.floor(s.scrollTop/a);p(m)},p(0),s.append(l,c),n.append(s),n}},Du={name:"QueryBuilder",description:"Visual filter builder. Pass `fields` as `{name, label, type?}` and bind `value` to a rule array.",props:[{name:"fields",type:"any[]"},{name:"value",type:"any[]",optional:!0},{name:"onChange",type:"callable",optional:!0,description:"Receives the next rule array"}],render:(t,e,r)=>{const a=Ha(e.fields),i=pt(e.value),n=t.argMeta?.[1]?.stateRef,s=o("div",{class:"rui-query-builder"}),l=c=>{s.replaceChildren(),c.forEach((p,m)=>{const g=o("div",{class:"rui-query-builder-row","data-index":String(m)}),f=o("select",{class:"rui-select rui-query-builder-field"});for(const y of a)f.append(o("option",{value:y.name},[y.label]));f.value=d(p.field??a[0]?.name);const h=o("select",{class:"rui-select rui-query-builder-op"},[]);for(const y of["equals","contains","gt","lt"])h.append(o("option",{value:y},[y]));h.value=d(p.op,"equals");const b=o("input",{class:"rui-input rui-query-builder-value",value:d(p.value)});g.append(f,h,b);const v=o("button",{type:"button",class:"rui-query-builder-remove"},["×"]);v.onclick=()=>{const y=c.filter((x,w)=>w!==m);n?r.setState(n,y):r.invoke(e.onChange,y),l(y)},g.append(v),s.append(g)});const u=o("button",{type:"button",class:"rui-query-builder-add"},["Add rule"]);u.onclick=()=>{const p=[...c,{field:a[0]?.name??"",op:"equals",value:""}];n?r.setState(n,p):r.invoke(e.onChange,p),l(p)},s.append(u)};return l(i.length>0?i:[{field:a[0]?.name??"",op:"equals",value:""}]),s}},Fu={name:"DiffViewer",description:"Side-by-side or unified diff of two text blobs.",props:[{name:"left",type:"string"},{name:"right",type:"string"},{name:"mode",type:"string",optional:!0,enum:["split","unified"],description:"Default split"}],render:(t,e)=>{const r=d(e.left),a=d(e.right),i=d(e.mode,"split"),n=o("div",{class:"rui-diff-viewer","data-mode":i});if(i==="unified"){const u=o("pre",{class:"rui-diff-viewer-unified"});for(const p of Ru(r,a))u.append(o("div",{class:`rui-diff-line rui-diff-line-${p.type}`},[(p.type==="add"?"+ ":p.type==="remove"?"- ":" ")+p.text]));return n.append(u),n}const s=o("div",{class:"rui-diff-viewer-panes"}),l=o("pre",{class:"rui-diff-viewer-pane rui-diff-viewer-left"},[r]),c=o("pre",{class:"rui-diff-viewer-pane rui-diff-viewer-right"},[a]);return s.append(l,c),n.append(s),n}},Ou={name:"JsonTree",description:"Expandable JSON tree viewer for objects and arrays.",props:[{name:"data",type:"any"},{name:"expanded",type:"boolean",optional:!0,description:"Expand all nodes (default: first level only)"}],render:(t,e)=>{const r=o("div",{class:"rui-json-tree"});return r.append(Ga(e.data,C(e.expanded))),r}},Uu={name:"Gantt",description:"Simple Gantt chart. Pass `tasks` as `{id, label, start, end, progress?}` ISO date strings.",props:[{name:"tasks",type:"any[]"},{name:"startDate",type:"string",optional:!0},{name:"endDate",type:"string",optional:!0}],render:(t,e)=>{const r=zu(e.tasks),a=r.map(p=>$e(p.start)),i=r.map(p=>$e(p.end)),n=e.startDate?$e(d(e.startDate)):a.length?Math.min(...a):Date.now(),s=e.endDate?$e(d(e.endDate)):i.length?Math.max(...i):n+864e5,l=Math.max(s-n,1),c=o("div",{class:"rui-gantt"}),u=o("div",{class:"rui-gantt-track"});for(const p of r){const m=o("div",{class:"rui-gantt-row"});m.append(o("div",{class:"rui-gantt-label"},[p.label]));const g=o("div",{class:"rui-gantt-bars"}),f=($e(p.start)-n)/l*100,h=Math.max(($e(p.end)-$e(p.start))/l*100,2),b=o("div",{class:"rui-gantt-bar",style:`left:${f}%;width:${h}%`,title:`${p.start} → ${p.end}`});p.progress!=null&&b.append(o("div",{class:"rui-gantt-bar-progress",style:`width:${Math.min(100,Math.max(0,p.progress))}%`})),g.append(b),m.append(g),u.append(m)}return c.append(u),c}},qu={name:"Truncate",description:"Clamp long text with an expand control.",props:[{name:"text",type:"string"},{name:"maxLines",type:"number",optional:!0,description:"Lines before clamping (default 3)"},{name:"expandLabel",type:"string",optional:!0}],render:(t,e,r)=>{const a=Math.max(1,Math.floor(P(e.maxLines,3))),i=r.useInstanceState("expanded",!1),n=`display:-webkit-box;-webkit-line-clamp:${a};-webkit-box-orient:vertical;overflow:hidden`,s=o("div",{class:"rui-truncate","data-expanded":i.get()?"true":"false"}),l=o("p",{class:"rui-truncate-text",style:i.get()?"":n},[d(e.text)]),c=o("button",{type:"button",class:"rui-truncate-toggle"},[i.get()?"Show less":d(e.expandLabel,"Show more")]);return c.onclick=u=>{const p=u.currentTarget,m=p.closest(".rui-truncate"),g=m?.querySelector(".rui-truncate-text");if(!m||!g)return;const f=!i.get();i.set(f),g.style.cssText=f?"":n,p.textContent=f?"Show less":d(e.expandLabel,"Show more"),m.setAttribute("data-expanded",f?"true":"false")},s.append(l,c),s}},Hu={name:"InlineEdit",description:"Click-to-edit inline field with save on Enter or blur.",props:[{name:"value",type:"string"},{name:"label",type:"string",optional:!0},{name:"onSave",type:"callable",optional:!0,description:"Receives the committed draft string"}],render:(t,e,r)=>{const a=r.useInstanceState("editing",!1),i=r.useInstanceState("draft",d(e.value)),n=t.argMeta?.[0]?.stateRef,s=o("div",{class:"rui-inline-edit","data-editing":a.get()?"true":"false"}),l=d(e.label);l&&s.append(o("span",{class:"rui-inline-edit-label"},[l]));const c=o("button",{type:"button",class:"rui-inline-edit-display"},[d(e.value)]),u=o("input",{class:"rui-inline-edit-input rui-input",value:i.get()}),p=g=>{const f=g.closest(".rui-inline-edit"),h=f?.querySelector(".rui-inline-edit-input");return!f||!h?null:{root:f,input:h}},m=g=>{const f=p(g);a.set(!1),f?.root.setAttribute("data-editing","false");const h=i.get();n&&r.setState(n,h),r.invoke(e.onSave,h)};return c.onclick=g=>{const f=p(g.currentTarget);i.set(d(e.value)),a.set(!0),f&&(f.root.setAttribute("data-editing","true"),f.input.value=i.get(),setTimeout(()=>f.input.focus(),0))},u.oninput=g=>i.set(g.currentTarget.value),u.onkeydown=g=>{const f=g;if(f.key==="Enter"&&m(g.currentTarget),f.key==="Escape"){const h=p(g.currentTarget);a.set(!1),h?.root.setAttribute("data-editing","false")}},u.onblur=g=>m(g.currentTarget),s.append(c,u),s}},Vu={name:"NotificationBell",description:"Bell icon with unread count badge and dropdown notification list.",props:[{name:"count",type:"number",optional:!0},{name:"items",type:"any[]",optional:!0,description:"{title, message?, time?} objects"},{name:"onOpen",type:"callable",optional:!0}],render:(t,e,r)=>{const a=Math.max(0,Math.floor(P(e.count,0))),i=pt(e.items),n=r.useInstanceState("open",!1),s=n.get(),l=o("div",{class:"rui-notification-bell","data-open":s?"true":"false"}),c=o("button",{type:"button",class:"rui-notification-bell-trigger","aria-expanded":s?"true":"false","aria-haspopup":"true"}),u=L("bell",{className:"rui-notification-bell-icon"});u&&c.append(u),a>0&&c.append(o("span",{class:"rui-notification-bell-badge"},[a>99?"99+":String(a)])),l.append(c);const p=o("div",{class:"rui-notification-bell-panel",role:"menu"});if(i.length===0)p.append(o("div",{class:"rui-notification-bell-empty"},["No notifications"]));else for(const m of i){const g=o("div",{class:"rui-notification-bell-item"});g.append(o("div",{class:"rui-notification-bell-item-title"},[d(m.title)]));const f=d(m.message);f&&g.append(o("div",{class:"rui-notification-bell-item-message"},[f]));const h=d(m.time);h&&g.append(o("div",{class:"rui-notification-bell-item-time"},[h])),p.append(g)}return l.append(p),c.onclick=m=>{m.stopPropagation();const g=m.currentTarget,f=g.closest(".rui-notification-bell");if(!f)return;const h=!n.get();n.set(h),f.setAttribute("data-open",h?"true":"false"),g.setAttribute("aria-expanded",h?"true":"false"),h?(r.invoke(e.onOpen),Ee({liveRoot:f,onDismiss:()=>{n.set(!1),f.setAttribute("data-open","false"),g.setAttribute("aria-expanded","false")}})):he(f)},l}},le=(t,e)=>e==null?document.createDocumentFragment():t.renderNode(e),Wu=t=>!!(t&&typeof t=="object"),Ka=[wo,xo,ma,Ro,Lo,ko,So,Co,To,Ao,$o,Io,Po,Bo,No,Eo,jo,ns,os,Ho,Vo,Wo,Ko,Yo,Jo,Xo,Zo,ts,is,ls,Oo,ss,Ms,As,xs,ws,Ss,ks,Cs,Ns,Ts,$s,vs,ys,xa,Ps,Is,zs,Rs,wa,Ls,Es,yl,vl,wl,xl,kl,Sl,Tl,Cl,Ml,Pl,Il,Al,Ll,El,_l,Dl,Fl,Xl,Pa,Ol,Ul,Jl,ql,Hl,Wl,Gl,Ql,ec,Zl,Kl,rc,Ra,ic,sc,oc,dc,pc,mc,gc,Os,Us,fl,hl,qs,Vs,Hs,Gs,Ws,Ks,Ys,bl,Js,Xs,ka,ml,el,Qs,Zs,tl,rl,nl,il,al,ol,sl,cl,ll,ul,pl,dl,bc,yc,kc,Sc,Cc,Nc,$c,Mc,Pc,Ic,Rc,Ec,_c,Bc,Fc,Uc,Hc,Vc,Gc,Kc,Xc,Qc,eu,ru,au,iu,nu,ou,su,lu,uu,pu,gu,fu,hu,bu,vu,yu,xu,wu,ku,Su,Cu,Tu,Nu,Lu,Eu,_u,ju,Bu,Du,Fu,Ou,Uu,qu,Hu,Vu,{name:"Async",description:"Render `loading`, `error`, `empty`, or `data` slot based on an `http({...})` resource's state.",props:[{name:"resource",type:"any",positional:!0,required:!0},{name:"loading",type:"Node",optional:!0},{name:"error",type:"Node",optional:!0},{name:"empty",type:"Node",optional:!0},{name:"data",type:"Node",optional:!0}],render:(t,e,r)=>{const a=e.resource,i={loading:e.loading,error:e.error,empty:e.empty,data:e.data};if(!Wu(a))return le(r,i.empty??i.data??null);const n=a.state;if(n==="loading"||a.loading)return le(r,i.loading??null);if(n==="error"||a.error)return le(r,i.error??null);const s=a.data;return s==null||Array.isArray(s)&&s.length===0?le(r,i.empty??i.data??null):le(r,i.data??null)}},{name:"Show",description:"Conditional renderer. Sugar over `if expr { children } else { fallback }`.",props:[{name:"when",type:"any",positional:!0,required:!0},{name:"fallback",type:"Node",optional:!0},{name:"children",type:"Node[]",optional:!0}],render:(t,e,r)=>e.when?le(r,e.children??null):le(r,e.fallback??null)},{name:"Portal",description:"Render children outside the parent subtree (e.g. into document.body).",props:[{name:"target",type:"string",optional:!0},{name:"children",type:"Node[]",positional:!0}],render:(t,e,r)=>{const a=d(e.target);let i=null;if(a)try{i=document.querySelector(a)}catch{i=null}i||(i=document.body);const n=o("div",{class:"rui-portal"});for(const s of k(e.children))n.append(r.renderNode(s));return i&&(i.append(n),r.registerDisposer(()=>{n.parentNode&&n.parentNode.removeChild(n)})),o("span",{class:"rui-portal-anchor","data-portal":a??"body"})}},{name:"Redirect",description:"Navigate to `path` and unmount the rest of the subtree.",props:[{name:"path",type:"string",positional:!0,required:!0}],render:(t,e,r)=>{const a=d(e.path);if(a)try{r.router.navigate(a)}catch{}return o("span",{class:"rui-redirect","data-path":a,hidden:"true"})}},{name:"Lazy",description:"Defer rendering `children` until `loader` resolves.",props:[{name:"loader",type:"any",positional:!0,required:!0},{name:"fallback",type:"Node",optional:!0},{name:"children",type:"Node[]",optional:!0}],render:(t,e,r)=>{const a=e.loader;if(typeof a=="function")try{const i=a();return i&&typeof i.then=="function"?le(r,e.fallback??null):le(r,i??e.children??null)}catch{return le(r,e.fallback??null)}return le(r,e.children??null)}},{name:"ErrorBoundary",description:"Render a fallback subtree when rendering children throws.",props:[{name:"fallback",type:"Node",optional:!0},{name:"onError",type:"callable",optional:!0},{name:"children",type:"Node[]",positional:!0}],render:(t,e,r)=>{const a=o("div",{class:"rui-error-boundary"});try{for(const i of k(e.children))a.append(r.renderNode(i));return a}catch(i){try{r.invoke(e.onError,i)}catch{}const n=le(r,e.fallback??null),s=o("div",{class:"rui-error-boundary rui-error-boundary--fallback"});return s.append(n),s.setAttribute("data-error",i instanceof Error?i.message:String(i)),s}}}],Gu=[{name:"Layout",components:["Stack","StackItem","Grid","GridItem","Box","Container","Spacer","Card","CardHeader","CardFooter","Separator","Tabs","TabItem","Accordion","AccordionItem","Modal","Drawer","Steps","AspectRatio","ScrollArea","Sticky","ResizablePanels","MasonryGrid"],notes:["- `root` MUST be `Stack(...)` and contain at least one child.","- Wrap each major chunk of content in a `Card(...)` for visual grouping.",'- Prefer `Grid(...)` over `Stack` with `direction="row" wrap=true` when children should size uniformly (KPIs, feature tiles, card grids).',"- Use `Container(children, size?)` to centre a wide page within a comfortable max-width (landing pages, articles, marketing sections).",'- Use `Spacer()` inside `Stack(direction="row")` to push the next item to the far edge; pass a `size` for an explicit fixed gap.','- Use `Separator(orientation?, label?)` between sections to add visual breaks. Pass a `label` for a centered "OR"-style separator.',"- Use `Drawer` for side-panel detail views, `Modal` for centered dialogs.","- Use `Sticky(children, side?, offset?)` to pin a toolbar/banner while the surrounding content scrolls.","- Use `ResizablePanels(primary, secondary, initialPrimaryWidth?)` for user-resizable two-pane layouts (code editors, file browsers).","- Use `MasonryGrid([...])` for Pinterest-style mixed-height card walls — prefer `Grid` when rows should share a height.",'- Use `StackItem(child, grow?, shrink?, basis?, alignSelf?)` inside `Stack(direction="row", uniform=false)` for toolbars.','- Use `Grid(columns: 12, [GridItem(child, span: "1/4"), GridItem(main, span: "3/4")])` for sidebar layouts; fractional spans `"1/2"`…`"1/12"` resolve on a 12-column track.',"- Use `Box(children, padding?, margin?, border?, background?)` for spacing and surfaces without raw CSS."]},{name:"Content",components:["Text","Image","Link","Badge","BadgeList","Callout","Quote","CodeBlock","Skeleton","Spinner","Markdown","Kbd","Icon"],notes:["- Prefer `Markdown(...)` for rich paragraph text with inline formatting — the parser supports headings, blockquotes, fenced code, numbered/bullet lists, links, images, and bare-URL auto-linking.","- Use `Callout(variant, title, description, icon?, compact?)` for highlighted notices; pass `compact: true` for a one-line inline note.","- Use `Quote(text, cite?)` for inline pull-quotes inside articles and marketing sections (use `Testimonial` when you also have author/role/rating).","- Use `CodeBlock(language, codeString, showLineNumbers?, highlightLines?)` for read-only code snippets. The header always renders a copy-to-clipboard button.",'- Use `Badge(label, variant?, icon?, size?)` for a single pill and `BadgeList(["a","b","c"], variant?, size?)` to render an array of strings as Badge pills.',"- Use `Skeleton(variant?, lines?, height?, shape?, width?)` for loading placeholders; `variant` accepts `paragraph` (default), `card`, `table-row`, `avatar`, `image`.","- Use `Spinner(size?, label?, tone?)` for tiny inline loading indicators inside buttons, toolbars, or table cells.",'- Use `Image(src, alt?, caption?, ratio?, fit?, fallback?)` — `ratio` (e.g. `"16:9"`) makes the image self-constrain so you do not need an outer `AspectRatio`.','- Use `Kbd(["Cmd", "K"])` when referring to keyboard shortcuts.','- Use `Icon(name, variant?, size?)` to render a standalone Font Awesome icon (`name` is the FA name without the `fa-` prefix, e.g. `"house"`, `"chart-line"`, `"regular:star"`, `"brands:github"`).','- For page-level titles reach for `PageHeader(...)` (top of dashboards/detail pages) or `SectionHeader(...)` (inside a Card). For tiny inline titles use `Text(value, variant="large-heavy")`.']},{name:"Forms",components:["Form","FormControl","FormSection","FieldSet","ValidationSummary","Input","TextArea","PasswordInput","MaskedInput","MentionInput","TagInput","Select","SelectItem","Combobox","MultiSelect","Checkbox","CheckBoxGroup","CheckBoxItem","Radio","Switch","ToggleGroup","Button","Buttons","SearchBar","Slider","NumberInput","ColorPicker","DatePicker","DateRangePicker","TimePicker","DateTimePicker","FileUpload","PinInput","MultiStepForm"],notes:["- Each FormControl should be a separate reference for progressive streaming.","- Pass a `$variable` as the last argument to `Input`, `Select`, `Checkbox`, `Switch`, `MultiSelect`, or `CheckBoxGroup` for two-way binding.","- Prefer `Switch` over `Checkbox` for settings; use `ToggleGroup` for view-mode pickers and mutually-exclusive filters.","- Reach for `SearchBar(id, placeholder?, value?, shortcut?)` instead of a raw `Input` whenever the field's purpose is to filter content. It ships with the magnifier icon and keyboard hint baked in.","- `Slider(id, min?, max?, step?, value?, label?, showValue?)` is the canonical control for numeric ranges (volume, brightness, filters); pass a `$variable` as `value` for two-way binding.",'- `NumberInput(id, value?, min?, max?, step?, placeholder?)` is friendlier than `Input(type="number")` for quantity steppers and integer settings — it ships with +/- buttons that respect `min`/`max`.',"- `DatePicker(id, value?, label?, min?, max?, placeholder?)` wraps the native date picker; pass `value` as a `$variable` for two-way binding (ISO `YYYY-MM-DD`).","- `DateRangePicker(id, from?, to?, label?, min?, max?)` is the paired-date variant — bind both `from` and `to` to `$variable`s for a single shared range.","- `Combobox(id, items, value?, placeholder?, emptyLabel?)` is the searchable single-select alternative to `Select` — type to filter long option lists (countries, currencies, users).","- `MultiSelect(id, items, value?, placeholder?, emptyLabel?, max?)` is the multi-select equivalent — bind a `$variable` array as `value` for two-way binding, the trigger renders the picks as removable chips.","- `FileUpload(id, label?, hint?, accept?, multiple?, action?)` is the styled file picker; the picked files cannot pass through a `$variable`, so wire the `action` prop to an `action` block (use a `js{ … }` body if you need to read file contents directly).",'- A submit button should call an `action` that awaits the relevant `$mutation` resource, optionally refetches a `$query`, and resets the form `$variable`s (e.g. `$title = ""`).',"- Button `size` accepts both `sm|md|lg` (canonical) and the legacy `small|normal|large`. Pass `icon` for an inline leading icon.","- `FormSection(label, children, helper?)` is the canonical wrapper for related fields. Reach for it INSTEAD of nesting fields in Card + SectionHeader by hand.","- `FieldSet(legend, children, helper?)` is the accessible `<fieldset>` for radio/checkbox groups; prefer `FormSection` for purely visual grouping.","- `ValidationSummary(errors, title?)` renders an aggregate error panel at the top of the form. Pass `errors` as `{label, message}` objects.",'- `PasswordInput(id, value?, placeholder?, strengthMeter?)` adds a show/hide toggle and an optional 4-step strength meter — prefer over `Input(type="password")` for sign-up flows.',"- `PinInput(id, length?, value?, type?)` renders per-digit code entry for 2FA / SMS verification (use `length=6` for OTP codes).","- `TagInput(id, value?, placeholder?)` lets the user add comma- or Enter-separated chips bound to a `$variable` array.","- `MentionInput(id, people, value?)` is a textarea with inline @-mention suggestions — use for comments, task notes, chat composers.","- `MaskedInput(id, mask, value?)` formats input against a mask string (`9` digit, `A` letter, `*` any). Use for phone numbers, postal codes.","- `TimePicker(id, value?)` and `DateTimePicker(id, value?)` wrap the corresponding native inputs with consistent styling.","- `ColorPicker(id, value?, label?, swatches?)` pairs a color chip with a hex input and preset swatches — bind a $variable holding a hex string.","- `MultiStepForm(steps, current, onSubmit?)` replaces ad-hoc `Steps` + content + manual prev/next wiring. Each step is `{title, details?, content}`."]},{name:"Data",components:["Table","Col","DataGrid","List","ListItem","StatCard","Stats","Sparkline","Tile","Progress","ProgressRing","Pagination","Tree","TreeNode","CalendarView","ComparisonTable","InfiniteList"],notes:['- Build columns using array pluck: `Col("Title", data.rows.title, format?, align?)`.','- For per-row controls inside a Col, use `@Each(data.rows, "row", ...)` and reference `row.field` inline.','- `Table(cols, caption?, density?, striped?, sticky?, emptyLabel?)` — pass `density="compact"` for dense data, `sticky=true` to pin the header in a scrolling parent, and `emptyLabel` for the zero-state cell.',"- `DataGrid(cols, rowIds?, caption?, sort, selectedIds, selectable?, page, perPage?, …)` is the advanced Table — adds sortable headers (`sortable=true` on Col), per-column filter chips (`filterable=true`), checkbox row selection bound to `$selectedIds`, sticky header / first column, pagination, and an optional bulk-action toolbar. Reach for this whenever a user needs to sort, filter, or page through a list.","- `CalendarView(value?, month?, events?, view?, firstDay?, onSelect?)` renders a full-month (or week) calendar grid for scheduling apps — distinct from the `DatePicker` input. Bind `value` to a `$variable` for the selected ISO date.","- `ComparisonTable(columns, rows, highlightColumn?)` is the generic counterpart of `PricingTable` — pass rows of `{label, values, hint?, group?}`. Use for feature comparisons, spec sheets, plan grids.","- `InfiniteList(items, onLoadMore?, loading?, hasMore?)` is a scroll-to-load list; the action fires when the sentinel scrolls into view.","- Use `Progress(value, max?, label?, tone?, indeterminate?, segments?, buffered?)` for linear bars — `segments` renders an N-step strip (onboarding flows), `buffered` adds a secondary buffer indicator.","- `ProgressRing(value, max?, label?, tone?, size?)` is the circular variant for quotas/completion.",'- `Stats([{label, value, hint?, tone?, spark?}, …], layout?)` — `layout="strip"` (default) for inline KPIs; `layout="grid"` for a responsive StatCard grid. Pass `spark` for an inline trend line.',"- `StatCard(label, value, trend?, delta?, icon?, spark?, tone?)` gains an optional inline `Sparkline` via the `spark` prop. Use `Sparkline(values, tone?)` standalone for tiny trend chips in table cells.","- `Tile(label, icon?, value?, description?, tone?, action?)` is the dense icon tile for quick-action menus and category grids; pair with `Grid` for uniform rows.","- `Tree([TreeNode(label, children?, icon?, expanded?, active?, badge?, action?)])` renders a hierarchical tree (file browsers, nested navigation, category pickers); use `expanded=true` to open a branch by default.",'- `Pagination(page, totalPages, siblings?, total?, perPage?, perPageOptions?, compact?)` — bind `page` (and optionally `perPage`) to a `$variable`; pass `total` to render the "Showing N–M of T" summary. Reuse the same variable when slicing data with `@Filter` / `@Each`.']},{name:"Charts",components:["BarChart","LineChart","PieChart","RadarChart","ScatterChart","Histogram","Heatmap","Gauge","Series"],notes:["- Use `LineChart` for trends (pass `filled=true` for area-style charts), `BarChart` for comparisons, `PieChart` for proportions, `RadarChart` for multi-axis scorecards.","- `Heatmap(xLabels, yLabels, values)` renders a color-intensity matrix — perfect for calendar heatmaps, correlation grids, schedule density.","- `ScatterChart(series, xLabel?, yLabel?)` plots XY points; pass each Series as `Series(name, points)` where points are `{x, y, label?}`.","- `Histogram(values, binCount?)` bins raw numbers; pass pre-computed `bins=[{label, count}]` instead when you control the bucketing.","- `Gauge(value, min?, max?, label?, tone?, size?)` is the half-doughnut KPI indicator for thresholds (uptime %, score, NPS).",'- Pass series via `Series("Name", [...numbers])`.']},{name:"Feedback & Media",components:["Avatar","AvatarGroup","PersonChip","Tooltip","HoverCard","Popover","Rating","Toast","VideoPlayer","AudioPlayer","Carousel","Gallery","Lightbox","Map"],notes:["- `Avatar(name, src?, size?, status?)` falls back to initials when the image is missing.","- Use `AvatarGroup` to render contributor strips with a `+N` overflow chip.","- `PersonChip(name, role?, avatarSrc?, size?, status?, action?)` is the inline avatar + name + role pill — use everywhere a person is referenced (table cells, list rows, sidebar footers, kanban cards) instead of a raw `Avatar` next to `Text`.","- Wrap any node in `Tooltip(label, trigger)` for inline hints.","- Use `HoverCard(trigger, content)` when the popover needs rich content (profile preview, link target) and the trigger should open on hover.","- `Popover(trigger, content, title?, side?, align?, width?)` is the click-triggered counterpart of `HoverCard` — use for filter panels, color pickers, share menus, and small settings flyouts. Always renders an × close button in the header; clicking the trigger again, clicking outside, or pressing Escape also closes it.",'- `Rating(value, max?, label?, count?, size?, interactive?, halfStep?, icon?)` renders stars for product reviews, testimonials, and ranked lists. Pass a `$variable` as `value` with `interactive=true` to let users rate; add `halfStep=true` so clicking the left half of a star sets a half-value. Set `icon="heart"|"thumb"|"fire"|"bolt"` (or any FA name) to swap glyphs.','- `Toast(title, message?, tone?, icon?, duration?, action?, onClose?, position?)` pins a transient notice; pass `duration` (ms) for auto-dismiss. Drive lists from an `action` body: `$toasts = [...$toasts, item]` to append and `$toasts = @Filter($toasts, "id", "!=", id)` to dismiss. Use `Banner` for top-of-page announcements and `Notification` for permanent inbox entries.',"- `NotificationBell(count?, items?, onOpen?)` — compact inbox trigger; `CommandPalette` for Cmd-K action search."]},{name:"Navigation",components:["Breadcrumb","BreadcrumbItem","Navbar","NavbarItem","DropdownMenu","MenuItem","MenuSeparator","MenuLabel"],notes:['- Use `Breadcrumb(["Workspace", "Reports", "Q3"])` at the top of every detail page so users see the path.',"- For per-item links, pass `BreadcrumbItem(label, href)` nodes instead of strings.","- `Navbar(brand?, items?, actions?, sticky?, variant?)` + `NavbarItem(label, to?, href?, icon?, active?, action?, external?)` produces a top navigation bar with brand on the left, links in the middle, and actions on the right — the canonical companion of `Sidebar` for marketing pages, docs, or any product surface without left-side nav.",'- `DropdownMenu(trigger, items, side?, align?, label?)` is the click-triggered dropdown menu — use it for user-profile menus, row "…" action menus, and any compact list of actions hanging off a single trigger. Children must be `MenuItem`, `MenuSeparator`, or `MenuLabel` entries.','- `MenuItem(label, action?, icon?, shortcut?, variant?, disabled?)` renders a single row inside a `DropdownMenu`; use `variant="danger"` for destructive actions and `MenuSeparator()`/`MenuLabel(label)` to group related items.']},{name:"Chat",components:["SectionBlock","ListBlock","FollowUpBlock","FollowUpItem","ActionLink","ChatBubble"],notes:["- End most responses with a `FollowUpBlock` of 2–4 short prompts to keep the conversation moving.",'- `ChatBubble(author, body, time?, avatarSrc?, from?)` renders a single message bubble; use `from="me"` for the active speaker and `from="agent"` for the assistant. Compose transcripts as `Stack([ChatBubble(...), ChatBubble(...), …])` inside a `Card`.']},{name:"Patterns",components:["Hero","PageHeader","EmptyState","Timeline","TimelineItem","ActivityLog","FeatureGrid","FeatureItem","Testimonial","ProfileCard","Comment","Banner","Notification","InboxPanel","OnboardingChecklist","MediaCard","TopBar","KanbanBoard","KanbanColumn","KanbanCard","SectionHeader","Toolbar","DescriptionList","DescriptionItem","StatusDot","PricingTable","PricingCard","LoadingState","ErrorState","SuccessState","Tour","Spotlight"],notes:["- Patterns are **opinionated composites** that pack an entire UI idiom into one component. Reach for them BEFORE composing equivalent layouts by hand with Card+Stack — the result will look more polished and require fewer tokens.",'- `Hero(title, subtitle, primary, secondary, eyebrow?, highlights?, tone?)` — landing-style text-first header. Use `layout="cover"` with `imageSrc`, `height`, and optional `caption` for image-backed hero bands.','- `PageHeader(title, subtitle?, breadcrumbs?, actions?, status?)` — the canonical first child for any dashboard or detail page. If you omit `breadcrumbs`, the component auto-derives `["Home", title]`.',"- `TopBar(title?, search?, actions?, sticky?)` — compact top strip for a content surface (panels, dialogs, embedded views). Use `AppShell` when you need a full sidebar; use `TopBar` for narrower headers above scrolling content.","- `SectionHeader(title, subtitle?, eyebrow?, status?, actions?)` — sub-header inside a Card or panel. Use instead of bare `CardHeader` when the section also needs eyebrow / actions / status.",'- `Stats(items, layout?)` — KPI strip (`layout="strip"`, default) or responsive grid (`layout="grid"` with StatCard children). Prefer over hand-rolled StatCard rows.',"- `Toolbar(left?, right?, center?, searchable?, searchPlaceholder?, searchValue?)` — filter/search/actions row above a list, table, or board. Pass `searchable: true` to auto-mount a `SearchBar` (use `searchValue` to bind it to a `$variable`).","- `EmptyState(title, description?, icon?, illustration?, actions?, action?)` — render this when a list is empty rather than an empty Card. The icon is auto-picked from the title keywords if you omit it (inbox/messages → `inbox`, charts/analytics → `chart-pie`, files/folders → `folder-open`, etc.).","- `Timeline([TimelineItem(...)])` — vertical event feed (audit log, changelog, activity).",'- `ActivityLog(entries, variant?)` — purpose-built feed of user actions. Pass `entries` of `{actor, title, description?, time?, icon?, tone?, meta?}`; use `variant="audit"` for security/admin trails with monospace meta.',"- `FeatureGrid([FeatureItem(...)])` — feature highlights with iconography.","- `MediaCard(title, imageSrc?, description?, tags?, meta?, actions?, badge?, orientation?, ratio?)` — image + content card. Use for article previews, product cards, project highlights. Pair with `Grid` for uniform card rows.",'- `KanbanBoard([KanbanColumn("To do", [KanbanCard(...), ...])])` — task boards.','- `DescriptionList([DescriptionItem("Status", Badge(...)), …])` — detail-page key/value summary. Always preferable to a Stack of Text rows on profile, billing, or metadata panels.',"- `StatusDot(label, tone?, pulse?)` — inline status pip. Use in toolbars, list rows, table cells, sidebars.","- `Notification(title, message?, time?, icon?, avatarSrc?, tone?, unread?, actions?)` — inline notification card for notification panels / inboxes (prefer `Banner` for top-of-page announcements).","- `InboxPanel(items, title?, onMarkAllRead?)` — `Notification` cards grouped into Unread / Earlier sections, with a shared mark-all-read action.","- `OnboardingChecklist(items, title?, description?)` — checklist of `{title, description?, done?, action?}` items with progress. Use for product onboarding, setup wizards, getting-started panels.","- `PricingTable([PricingCard(plan, price, period?, description?, features?, action?, badge?, featured?)])` — full pricing page block.","- `LoadingState(title?, description?, tone?, action?)`, `ErrorState(title, description?, action?, secondaryAction?, retryLabel?)`, `SuccessState(title, description?, action?, secondaryAction?)` — full-card empty-state alternatives for asynchronous content states.","- `Tour(steps, current, onFinish?)` and `Spotlight(title?, description?, action?)` are the product-tour primitives. `Spotlight` is a single highlighted call-out; `Tour` walks the user through multiple `{title, description, image?}` steps with Prev/Next/Skip controls and a progress dots indicator."]},{name:"Editors & overlays",components:["RichTextEditor","CodeEditor","ContextMenu"],notes:["- `RichTextEditor(id, value?, placeholder?, minHeight?)` is the contenteditable WYSIWYG editor — toolbar ships with bold/italic/underline/strike/heading/lists/link. Bind `value` to a `$variable` holding HTML.","- `CodeEditor(id, value?, language?, placeholder?, minHeight?)` is a lightweight `<textarea>` with a synced line-number gutter and tab indentation. Use for snippet editors, prompt sandboxes, settings JSON.","- `ContextMenu(target, items)` attaches a right-click menu to any node. `items` are `MenuItem` or `{label, action?, icon?, shortcut?, variant?, disabled?}` objects; pass a `MenuSeparator()` to split groups."]},{name:"App shell",components:["AppShell","Sidebar","SidebarSection","SidebarItem","SplitView"],notes:["- App shell components produce a **full SaaS-style layout in a single statement**. Use them whenever the response represents a complete product surface (dashboards with nav, settings sections, admin consoles, inboxes).","- `AppShell(sidebar, content, topbar?, collapsible?, sidebarOpen?)` — fixed-left navigation + scrollable main area. Pass `collapsible=true` to enable a hamburger that turns the sidebar into a slide-over drawer on mobile; bind `sidebarOpen` to a `$variable` if you want to drive that drawer programmatically.","- `Sidebar(items, brand?, tagline?, footer?, collapsed?)` + `SidebarItem(label, icon?, active?, badge?, action?)` + `SidebarSection(label, items)` — group nav links into sections, mark the current page with `active=true`, attach badges for counts. Pass `collapsed=true` (or bind to a `$variable`) to collapse it to an icon rail.","- `SplitView(primary, detail, primaryWidth?)` — master/detail layout (inboxes, file browsers, contact lists). Both panes are scrollable."]},{name:"Theming",components:["Theme"],notes:["- `Theme({...})` applies a partial token override **on top of** the base theme set by the host (attribute / `setTheme()`). Use it to brand a single response without changing host configuration.","- Assign the result to a top-level binding called `theme` so the runtime picks it up:",' `theme = Theme({ colors: { primary: "#0969da" }, radius: { button: "6px" } })`',"- Tokens MUST use the structured form. Top-level groups: `colors`, `radius`, `font`, `motion`, `elevation` (plus metadata: `name`, `direction`).","- Common tokens (each lives inside its group): `colors.primary`, `colors.primaryHover`, `colors.primaryText`, `colors.accent`, `colors.bg`, `colors.surface`, `colors.text`, `colors.textMuted`, `colors.border`, `colors.focusRing`; `radius.md`, `radius.button`, `radius.input`; `font.family`, `font.familyHeading`, `font.sizeBase`, `font.weightHeading`; `motion.transitionDuration`; `elevation.md`.","- The legacy flat-shape form (`Theme({colorPrimary: ...})`) and free-form `--css-vars` are removed in Aktion 0.5 — the runtime drops them and the schema validator surfaces a migration warning.",'- Tokens are CSS values (`"#0969da"`, `"\'Inter\', sans-serif"`, `"6px"`, `"600"`). The runtime ignores unknown keys inside a group, so typos fail silent.',"- Removing the `Theme(...)` line snaps the UI back to the base theme without a reload."]},{name:"Advanced UI",components:["IconButton","CommandPalette","FilterChips","FieldRepeater","VirtualList","QueryBuilder","DiffViewer","JsonTree","Gantt","Truncate","InlineEdit","NotificationBell"],notes:["- `IconButton(icon, label, action?, variant?, size?, disabled?)` — accessible icon-only control.","- `CommandPalette(items, open?, placeholder?, shortcut?)` — Cmd-K searchable actions.","- `FilterChips(chips, onRemove?, onClear?)` — applied filter pills with remove.","- `FieldRepeater(items, fields, onAdd?, onRemove?)` — dynamic form rows.","- `VirtualList(items, itemHeight?, renderItem)` — windowed long lists.","- `QueryBuilder(fields, value?)` — visual AND/OR filter builder.","- `DiffViewer(left, right, mode?)` — side-by-side or unified diff.","- `JsonTree(data)` — collapsible JSON inspector.","- `Gantt(tasks, startDate?, endDate?)` — horizontal schedule timeline.","- `Truncate(text, maxLines?)` / `InlineEdit(value, onSave?)` / `NotificationBell(count?, items?)`."]},{name:"Routing",components:["NavLink"],notes:['- Declare routes with the `_router_({...})` call form: `pages = _router_({ "/": Dashboard(), "/orders/:id": OrderDetail(id: params.id), default: NotFound() })`. The matched arm\'s `params` object is in scope on the right-hand side; nest `_router_` inside components for layout-preserving sub-routes.',"- `Redirect(path)` is a router-aware component: returning it from a route's body navigates and unmounts the rest of the subtree.","- `NavLink(label, to)` is a thin link wrapper that reads `_route_.path` and dispatches `_route_.navigate(to)` — use it for sidebars, navbars and breadcrumbs.","- Read URL params via `_route_.params.<name>` (e.g. `_route_.params.id` for `/users/:id`) and the current path via `_route_.path`."]},{name:"Helpers",components:["Async","Show","Portal","Redirect","Lazy","ErrorBoundary"],notes:["- `Async(resource, loading:, error:, empty:, data:)` switches a `$query` / `$mutation` / `$subscription` resource on its `state` field.","- `Show(when, fallback?, children)` is sugar over `if expr { children } else { fallback }`.","- `Portal(target?, children)` renders into a different DOM subtree (defaults to `document.body`).","- `Redirect(path)` is a router-aware component — see Routing.","- `Lazy(loader, fallback?)` defers children until `loader` resolves.","- `ErrorBoundary(fallback?, onError?, children)` catches rendering errors thrown by descendants."]}];xr(Ka);const Ke={root:"Stack",components:Ka,componentGroups:Gu},Ku="$";class Ya{constructor(e){j(this,"instanceStates",new Map);j(this,"instanceDisposers",new Map);j(this,"aliveInstances",new Set);this.options=e}setLibrary(e){this.options={...this.options,library:e}}reset(){for(const e of this.instanceDisposers.values())for(const r of e.values())this.safeDispose(r);this.instanceDisposers.clear(),this.instanceStates.clear(),this.aliveInstances=new Set}beginRender(){this.aliveInstances=new Set}endRender(){const e=this.aliveInstances;for(const r of[...this.instanceStates.keys()]){const a=r.lastIndexOf("::"),i=a===-1?r:r.slice(0,a);e.has(i)||this.instanceStates.delete(r)}for(const[r,a]of[...this.instanceDisposers.entries()])if(!e.has(r)){for(const i of a.values())this.safeDispose(i);this.instanceDisposers.delete(r)}}safeDispose(e){try{e()}catch(r){console.error("[aktion] disposer threw",r)}}render(e){return this.renderAt(e,Ku)}renderAt(e,r){if(e==null)return document.createTextNode("");if(Array.isArray(e)){const a=document.createDocumentFragment();return e.forEach((i,n)=>{a.append(this.renderAt(i,`${r}/${n}`))}),a}return Ur(e)?this.renderUserComponent(e,r):Or(e)?this.renderComponent(e,r):typeof e=="string"||typeof e=="number"||typeof e=="boolean"?document.createTextNode(String(e)):document.createTextNode("")}renderUserComponent(e,r){const a=this.options.evaluationContext;if(!a){const c=document.createElement("div");return c.className="rui-unknown-component",c.textContent=`[unknown component: ${e.decl.name}]`,c}const i=a(),n=e.explicitKey!=null?`=${String(e.explicitKey)}`:`@${e.source?.line??0}:${e.source?.column??0}`,s=`${r}#${e.decl.name}${n}`;this.aliveInstances.add(s);const l=Gr(e,i,s);return this.renderAt(l,s)}renderComponent(e,r){const a=Ie(this.options.library,e.name);if(!a){const u=document.createElement("div");return u.className="rui-unknown-component",u.textContent=`[unknown component: ${e.name}]`,u}const i=wr(a,e.args),n=e.explicitKey!=null?`=${String(e.explicitKey)}`:`@${e.source?.line??0}:${e.source?.column??0}`,s=`${r}#${e.name}${n}`;this.aliveInstances.add(s);let l=0;const c={renderNode:u=>this.renderAt(u,`${s}>${l++}`),invoke:(u,...p)=>{if(typeof u=="function")try{const m=u(...p);m&&typeof m.then=="function"&&m.catch(g=>{console.error("[aktion] handler rejected",g)})}catch(m){console.error("[aktion] handler threw",m)}},setState:(u,p)=>{this.options.state.set(u,p)},resetState:(...u)=>{this.options.state.reset(...u)},sendToAssistant:u=>{this.options.onAssistantMessage?.(u)},openUrl:u=>{const p=rt(u,"#"),m=this.options.onOpenUrl;m?m(p):p!=="#"&&typeof window<"u"&&window.open(p,"_blank","noopener,noreferrer")},bindState:(u,p,m)=>{const f=`on${m?.event??this.eventFor(u)}`,h=m?.getValue??this.defaultValueGetter(u);u[f]=b=>{const v=b.currentTarget??b.target??u;this.options.state.set(p,h(v))}},useInstanceState:(u,p)=>{const m=`${s}::${u}`;return this.instanceStates.has(m)||this.instanceStates.set(m,p),{get:()=>this.instanceStates.get(m),set:g=>{this.instanceStates.set(m,g)}}},registerDisposer:(u,p)=>{let m=this.instanceDisposers.get(s);m||(m=new Map,this.instanceDisposers.set(s,m));const g=p??`__anon::${m.size}`,f=m.get(g);f&&f!==u&&this.safeDispose(f),m.set(g,u)},router:this.options.router};try{return a.render(e,i,c)}catch(u){console.error(`[aktion] failed to render ${a.name}`,u);const p=document.createElement("div");return p.className="rui-render-error",p.textContent=`[render error in ${a.name}]`,p}}eventFor(e){return e instanceof HTMLSelectElement||e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")?"change":"input"}defaultValueGetter(e){return e instanceof HTMLInputElement&&e.type==="checkbox"?r=>r.checked:e instanceof HTMLInputElement&&e.type==="radio"?r=>r.value:e instanceof HTMLInputElement&&e.type==="number"?r=>{const a=r.value;if(a==="")return null;const i=Number(a);return Number.isFinite(i)?i:null}:e instanceof HTMLInputElement&&e.type==="range"?r=>Number(r.value):r=>r.value}}const Yu=["onclick","oninput","onchange","onsubmit","onfocus","onblur","onkeydown","onkeyup","onkeypress","onerror","onmouseenter","onmouseleave","onmousedown","onmouseup","onpointerdown","onpointerup"];function Ju(t,e){const r=e.nodeType===Node.DOCUMENT_FRAGMENT_NODE?Array.from(e.childNodes):[e];Za(t,r)}function Ja(t,e){if(t===e)return t;if(t.nodeType!==e.nodeType)return Xa(t,e);if(t.nodeType===Node.TEXT_NODE)return t.textContent!==e.textContent&&(t.textContent=e.textContent),t;if(t.nodeType!==Node.ELEMENT_NODE)return t;const r=t,a=e;return r.tagName!==a.tagName?Xa(r,a):(Xu(r,a),r)}function Xa(t,e){return t.parentNode?.replaceChild(e,t),e}function Xu(t,e){Zu(t,e),Qu(t,e),Za(t,Array.from(e.childNodes)),ed(t,e)}function Zu(t,e){const r=t.attributes;for(let i=r.length-1;i>=0;i-=1){const n=r[i];e.hasAttribute(n.name)||n.name==="open"&&t.tagName==="DETAILS"||t.removeAttribute(n.name)}const a=e.attributes;for(let i=0;i<a.length;i+=1){const n=a[i];t.getAttribute(n.name)!==n.value&&t.setAttribute(n.name,n.value)}}function Qu(t,e){for(const r of Yu){const a=e[r],i=t[r];a!==i&&(t[r]=a??null)}}function ed(t,e){if(t instanceof HTMLInputElement&&e instanceof HTMLInputElement){td(t,e);return}if(t instanceof HTMLTextAreaElement&&e instanceof HTMLTextAreaElement){rd(t,e);return}if(t instanceof HTMLSelectElement&&e instanceof HTMLSelectElement){!mt(t)&&t.value!==e.value&&(t.value=e.value);return}}function td(t,e){if(t.type==="checkbox"||t.type==="radio"){const a=e.hasAttribute("checked")||e.checked;t.checked!==a&&!mt(t)&&(t.checked=a);return}const r=e.getAttribute("value")??e.value??"";!mt(t)&&t.value!==r&&(t.value=r)}function rd(t,e){const r=e.value??e.textContent??"";!mt(t)&&t.value!==r&&(t.value=r)}function mt(t){const e=t.getRootNode();return e instanceof ShadowRoot||e instanceof Document?e.activeElement===t:t.ownerDocument?.activeElement===t}function Za(t,e){const r=new Map;for(const i of Array.from(t.childNodes)){const n=qt(i);n&&r.set(n,i)}let a=0;for(const i of e){const n=t.childNodes[a]??null,s=qt(i);if(s&&r.has(s)){const c=r.get(s);r.delete(s),c!==n&&t.insertBefore(c,n),Ja(c,i),a+=1;continue}if(!n){t.appendChild(i),a+=1;continue}const l=qt(n);if(l&&(!s||l!==s)){t.insertBefore(i,n),a+=1;continue}Ja(n,i),a+=1}for(;t.childNodes.length>e.length;){const i=t.childNodes[t.childNodes.length-1];t.removeChild(i)}}function qt(t){if(t.nodeType!==Node.ELEMENT_NODE)return null;const e=t;if(e.id)return`#${e.id}`;const r=e.getAttribute("data-rui-key");return r?`@${r}`:null}const ad={Count:{description:"Number of items in an array.",params:[{name:"array",type:"any[]",required:!0}]},Sum:{description:"Sum of numeric values in an array.",params:[{name:"array",type:"number[]",required:!0}]},Avg:{description:"Average of numeric values in an array.",params:[{name:"array",type:"number[]",required:!0}]},Min:{description:"Minimum of numeric values in an array.",params:[{name:"array",type:"number[]",required:!0}]},Max:{description:"Maximum of numeric values in an array.",params:[{name:"array",type:"number[]",required:!0}]},First:{description:"First element of an array, or null.",params:[{name:"array",type:"any[]",required:!0}]},Last:{description:"Last element of an array, or null.",params:[{name:"array",type:"any[]",required:!0}]},Filter:{description:"Filter an array by a field/operator/value comparison.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0},{name:"op",type:"'=='|'!='|'>'|'<'|'>='|'<='|'contains'",required:!0},{name:"value",type:"any",required:!0}]},FilterBy:{description:"Alias for `@Filter` — filter an array by a field/operator/value comparison.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0},{name:"op",type:"'=='|'!='|'>'|'<'|'>='|'<='|'contains'",required:!0},{name:"value",type:"any",required:!0}]},Sort:{description:"Sort an array by a field, ascending or descending.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0},{name:"direction",type:"'asc'|'desc'",required:!1}]},Round:{description:"Round a number to N decimals (default 0).",params:[{name:"value",type:"number",required:!0},{name:"decimals",type:"number",required:!1}]},Abs:{description:"Absolute value of a number.",params:[{name:"value",type:"number",required:!0}]},Floor:{description:"Round a number down to the nearest integer.",params:[{name:"value",type:"number",required:!0}]},Ceil:{description:"Round a number up to the nearest integer.",params:[{name:"value",type:"number",required:!0}]},Find:{description:"Find the first item matching a field/op/value comparator.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0},{name:"op",type:"'=='|'!='|'>'|'<'|'>='|'<='|'contains'",required:!0},{name:"value",type:"any",required:!0}]},GroupBy:{description:"Group items into `{groupKey: [items…]}` by a field value.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0}]},Slice:{description:"Slice an array by `[start, end)` — both indices optional.",params:[{name:"array",type:"any[]",required:!0},{name:"start",type:"number",required:!1},{name:"end",type:"number",required:!1}]},Unique:{description:"Deduplicate. With a `field`, dedupes by that field (first wins).",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!1}]},Reverse:{description:"Return a reversed copy of the array (non-mutating).",params:[{name:"array",type:"any[]",required:!0}]},Range:{description:"Inclusive integer range. Third arg is the step (default 1 / -1).",params:[{name:"start",type:"number",required:!0},{name:"end",type:"number",required:!0},{name:"step",type:"number",required:!1}]},Repeat:{description:"Repeat a value N times. Useful for skeleton/placeholder grids.",params:[{name:"value",type:"any",required:!0},{name:"count",type:"number",required:!0}]},Pick:{description:'Keep only the listed keys from an object — `@Pick(obj, ["a","b"])`.',params:[{name:"object",type:"object",required:!0},{name:"keys",type:"string[]",required:!0}]},Format:{description:"Locale-aware number formatter. Modes: 'currency', 'percent', 'number'.",params:[{name:"value",type:"number",required:!0},{name:"mode",type:"'currency'|'percent'|'number'",required:!1},{name:"currencyOrLocale",type:"string",required:!1},{name:"locale",type:"string",required:!1}]},FormatDate:{description:"Format a date. Pattern tokens (MMM D, YYYY-MM-DD) or named: 'relative', 'date', 'time', 'datetime', 'iso'.",params:[{name:"value",type:"Date|number|string",required:!0},{name:"format",type:"string",required:!1}]},Now:{description:"Current moment as epoch ms — pair with `@FormatDate`.",params:[]},Today:{description:"Today's date at midnight, as an ISO string.",params:[]},AddDays:{description:"Shift a date by N days (negative N moves backward).",params:[{name:"date",type:"Date|number|string",required:!0},{name:"days",type:"number",required:!0}]},AddHours:{description:"Shift a date by N hours (negative N moves backward).",params:[{name:"date",type:"Date|number|string",required:!0},{name:"hours",type:"number",required:!0}]},DiffDays:{description:"Whole-day difference from start to end (end − start).",params:[{name:"start",type:"Date|number|string",required:!0},{name:"end",type:"Date|number|string",required:!0}]},StartOfWeek:{description:"Local Sunday 00:00:00 for the week containing the date.",params:[{name:"date",type:"Date|number|string",required:!0}]},EndOfMonth:{description:"Last moment of the calendar month containing the date.",params:[{name:"date",type:"Date|number|string",required:!0}]},Plural:{description:'Pluralisation: `@Plural(n, "order", "orders")` → "1 order" / "2 orders".',params:[{name:"count",type:"number",required:!0},{name:"singular",type:"string",required:!0},{name:"plural",type:"string",required:!1}]},Capitalize:{description:"Uppercase the first character.",params:[{name:"value",type:"string",required:!0}]},Lowercase:{description:"Lowercase every character.",params:[{name:"value",type:"string",required:!0}]},Uppercase:{description:"Uppercase every character.",params:[{name:"value",type:"string",required:!0}]},Titlecase:{description:"Capitalise the first letter of each word.",params:[{name:"value",type:"string",required:!0}]},Case:{description:'Convert casing — mode: "camel", "snake", "kebab", or "pascal".',params:[{name:"value",type:"string",required:!0},{name:"mode",type:"'camel'|'snake'|'kebab'|'pascal'",required:!0}]},Join:{description:'Join array values into a string (default separator ",").',params:[{name:"array",type:"any[]",required:!0},{name:"separator",type:"string",required:!1}]},Split:{description:'Split a string by a separator (default ",").',params:[{name:"value",type:"string",required:!0},{name:"separator",type:"string",required:!1}]},Trim:{description:"Trim leading and trailing whitespace.",params:[{name:"value",type:"string",required:!0}]},Replace:{description:"Replace all occurrences of search with replacement.",params:[{name:"value",type:"string",required:!0},{name:"search",type:"string",required:!0},{name:"replacement",type:"string",required:!1}]},Substring:{description:"Extract a substring — `start`, optional `end`.",params:[{name:"value",type:"string",required:!0},{name:"start",type:"number",required:!0},{name:"end",type:"number",required:!1}]},StartsWith:{description:"True when the string starts with the given prefix.",params:[{name:"value",type:"string",required:!0},{name:"prefix",type:"string",required:!0}]},EndsWith:{description:"True when the string ends with the given suffix.",params:[{name:"value",type:"string",required:!0},{name:"suffix",type:"string",required:!0}]},Contains:{description:"True when the string contains the given substring.",params:[{name:"value",type:"string",required:!0},{name:"needle",type:"string",required:!0}]},Match:{description:"Test a string against a RegExp pattern (invalid patterns return false).",params:[{name:"value",type:"string",required:!0},{name:"pattern",type:"string",required:!0}]},Clamp:{description:"Clamp a number into `[min, max]`.",params:[{name:"value",type:"number",required:!0},{name:"min",type:"number",required:!0},{name:"max",type:"number",required:!0}]},Pow:{description:"Raise a number to a power — `Math.pow(base, exp)`.",params:[{name:"base",type:"number",required:!0},{name:"exp",type:"number",required:!0}]},Sqrt:{description:"Square root of a number.",params:[{name:"value",type:"number",required:!0}]},Random:{description:"Pseudo-random number in [0, 1) — `Math.random()`.",params:[]},Log:{description:"Natural logarithm — `Math.log(value)`.",params:[{name:"value",type:"number",required:!0}]}},id=[{name:"Each",category:"iteration",description:'Iterate over an array. The loop variable is scoped to the template. Supports destructuring: "{id, name}" binds those fields per row.',params:[{name:"array",type:"any[]",required:!0},{name:"varName",type:"string",required:!0},{name:"template",type:"Node",required:!0}]},{name:"If",category:"iteration",description:"Lazy conditional renderer — only the selected branch is evaluated. Useful when an unused branch would otherwise read missing loop variables.",params:[{name:"condition",type:"any",required:!0},{name:"trueBranch",type:"Node",required:!0},{name:"falseBranch",type:"Node",required:!1}]},{name:"Switch",category:"iteration",description:"Key-based branch selector. Stringifies `value` and renders the matching property of `cases` (or `default` when no key matches).",params:[{name:"value",type:"any",required:!0},{name:"cases",type:"{key: Node | string, ...}, i.e. {overview: Node, billing: 'Invoice', security: Node}",required:!0},{name:"default",type:"Node",required:!1}]}],nd=t=>{const e=t.params.map(r=>r.required?r.name:`${r.name}?`);return`@${t.name}(${e.join(", ")})`},Ht=t=>({...t,signature:nd(t)});function gt(){return[...Object.keys(At).map(e=>{const r=ad[e];return Ht(r?{name:e,category:"data",...r}:{name:e,category:"data",description:`Data helper: @${e}`,params:[{name:"value",type:"any",required:!0}]})}),...id.map(Ht)]}function Qa(t){const e={};for(const r of t)e[r.name]=r;return e}const D="_app_";function Vt(t,e={}){return e.mode==="chat"?ld(t,e):sd(t,e)}function od(t){return ft(t)}function sd(t,e){const r=(e.tools?.length??0)>0,a={toolCalls:e.toolCalls??r,bindings:e.bindings??e.toolCalls??r,inlineMode:e.inlineMode??!1,editMode:e.editMode??!1},i=[];i.push(cd(e.preamble)),i.push(ud()),i.push(dd()),a.bindings&&i.push(pd()),i.push(md()),i.push(gd()),i.push(fd()),a.toolCalls&&i.push(hd()),i.push(bd()),i.push(vd()),i.push(yd()),i.push(xd()),(a.toolCalls||a.bindings)&&i.push(wd()),i.push(kd()),i.push(Sd()),i.push(Cd()),i.push(Td()),i.push(Nd()),i.push($d(t)),a.inlineMode&&i.push(Ad()),a.editMode&&i.push(Md()),e.tools&&e.tools.length>0&&i.push(Wd(e.tools)),e.toolExamples&&e.toolExamples.length>0&&i.push(Wt("Endpoint examples",e.toolExamples));const n=e.examples??Rd();return n.length>0&&i.push(Wt("Examples",n)),e.additionalRules&&e.additionalRules.length>0&&i.push(ei(e.additionalRules)),i.push(Pd()),i.push(Id()),i.push(zd()),i.join(`
22
+ `),i=Math.max(r.length,a.length),n=[];for(let s=0;s<i;s++){const l=r[s],c=a[s];l===c?l!==void 0&&n.push({type:"same",text:l}):(l!==void 0&&n.push({type:"remove",text:l}),c!==void 0&&n.push({type:"add",text:c}))}return n}function Wa(t){try{return JSON.stringify(t,null,2)}catch{return String(t)}}function Ga(t,e,r,a){for(const[i,n]of e){const s=o("div",{class:"rui-json-tree-row"});s.append(o("span",{class:"rui-json-tree-key"},[`${i}: `])),n!==null&&typeof n=="object"?s.append(Ka(n,r,a+1)):s.append(o("span",{class:"rui-json-tree-leaf"},[Wa(n)])),t.append(s)}}function Ka(t,e,r=0){const a=o("div",{class:"rui-json-tree-node","data-depth":String(r)});if(t===null||typeof t!="object")return a.append(o("span",{class:"rui-json-tree-leaf"},[Wa(t)])),a;const i=Array.isArray(t),n=i?t.map((u,p)=>[String(p),u]):Object.entries(t),s=e||r<1,l=o("button",{type:"button",class:"rui-json-tree-toggle","aria-expanded":s?"true":"false"},[s?"▼":"▶",i?` Array(${n.length})`:" Object"]),c=o("div",{class:"rui-json-tree-children","data-open":s?"true":"false"});return s&&Ga(c,n,e,r),l.onclick=u=>{const p=u.currentTarget,m=p.nextElementSibling;if(!m)return;const g=m.getAttribute("data-open")!=="true";m.setAttribute("data-open",g?"true":"false"),p.setAttribute("aria-expanded",g?"true":"false"),p.firstChild&&(p.firstChild.textContent=g?"▼":"▶"),g&&m.childElementCount===0?Ga(m,n,e,r):g||m.replaceChildren()},a.append(l,c),a}const Eu={name:"IconButton",description:"Icon-only button with an accessible label. Use for toolbars, table row actions, and compact controls.",props:[{name:"icon",type:"string",description:"Font Awesome icon name"},{name:"label",type:"string",description:"Accessible label (visually hidden)"},{name:"action",type:"callable",optional:!0,aliases:["onClick","onclick"]},{name:"variant",type:"string",optional:!0,aliases:["tone"],enum:Au},{name:"size",type:"string",optional:!0,enum:Mu},{name:"disabled",type:"boolean",optional:!0}],render:(t,e,r)=>{const a=o("button",{class:"rui-icon-button",type:"button","data-variant":d(e.variant,"ghost"),"data-size":Pu(e.size),"aria-label":d(e.label),title:d(e.label),disabled:C(e.disabled)?"":null}),i=L(e.icon,{className:"rui-icon-button-icon"});return i&&a.append(i),a.onclick=()=>r.invoke(e.action),a}},_u={name:"CommandPalette",description:"Cmd-K style searchable command list. Pass `items` as `{label, value, group?, shortcut?, action?}` objects.",props:[{name:"items",type:"any[]"},{name:"open",type:"boolean",optional:!0,description:"Whether the palette is visible (default true)"},{name:"placeholder",type:"string",optional:!0},{name:"shortcut",type:"string",optional:!0,description:"Hint label, e.g. Cmd+K"}],render:(t,e,r)=>{const a=zu(e.items),i=e.open!==void 0,n=i?C(e.open):!0,s=r.useInstanceState("open",n);i&&s.get()!==n&&s.set(n);const l=r.useInstanceState("filter",""),c=i?n:s.get(),u=o("div",{class:"rui-command-palette","data-open":c?"true":"false"});if(!c)return u;const p=o("div",{class:"rui-command-palette-backdrop"}),m=o("div",{class:"rui-command-palette-panel",role:"dialog","aria-modal":"true"}),g=o("div",{class:"rui-command-palette-header"}),f=o("input",{type:"text",class:"rui-command-palette-input",placeholder:d(e.placeholder,"Search commands…"),value:l.get(),autocomplete:"off"});g.append(f);const h=d(e.shortcut);h&&g.append(o("span",{class:"rui-command-palette-shortcut"},[h])),m.append(g);const b=o("div",{class:"rui-command-palette-list",role:"listbox"}),v=(y,x)=>{y.replaceChildren();const w=x.trim().toLowerCase(),T=w===""?a:a.filter(N=>N.label.toLowerCase().includes(w)||N.value.toLowerCase().includes(w)||(N.group??"").toLowerCase().includes(w));let S="";for(const N of T.slice(0,50)){N.group&&N.group!==S&&(S=N.group,y.append(o("div",{class:"rui-command-palette-group"},[S])));const $=o("button",{type:"button",class:"rui-command-palette-item",role:"option","data-value":N.value},[N.label]);N.shortcut&&$.append(o("span",{class:"rui-command-palette-item-kbd"},[N.shortcut])),$.onclick=A=>{A.stopPropagation(),r.invoke(N.action),s.set(!1),l.set("");const z=A.currentTarget.closest(".rui-command-palette"),R=z?.querySelector(".rui-command-palette-panel");z?.setAttribute("data-open","false"),he(R??null)},y.append($)}T.length===0&&y.append(o("div",{class:"rui-command-palette-empty"},["No commands found"]))};return v(b,l.get()),m.append(b),p.onclick=y=>{const x=y.currentTarget.closest(".rui-command-palette"),w=x?.querySelector(".rui-command-palette-panel");s.set(!1),x?.setAttribute("data-open","false"),he(w??null)},u.append(p,m),f.oninput=y=>{const x=y.currentTarget,w=x.closest(".rui-command-palette-panel")?.querySelector(".rui-command-palette-list");l.set(x.value),w&&v(w,x.value)},f.onkeydown=y=>{if(y.key==="Escape"){const x=y.currentTarget.closest(".rui-command-palette"),w=x?.querySelector(".rui-command-palette-panel");s.set(!1),x?.setAttribute("data-open","false"),he(w??null)}},setTimeout(()=>f.focus(),0),Ee({liveRoot:m,onDismiss:()=>{s.set(!1),u.setAttribute("data-open","false")}}),u}},ju={name:"FilterChips",description:"Removable filter chips with an optional clear-all control.",props:[{name:"chips",type:"any[]",description:"Array of strings or {label, value} objects"},{name:"onRemove",type:"callable",optional:!0,description:"Receives the removed chip value as an argument"},{name:"onClear",type:"callable",optional:!0}],render:(t,e,r)=>{const a=Iu(e.chips),i=o("div",{class:"rui-filter-chips"}),n=o("div",{class:"rui-filter-chips-row"});for(const s of a){const l=o("span",{class:"rui-filter-chip","data-value":s.value});l.append(o("span",{class:"rui-filter-chip-label"},[s.label]));const c=o("button",{type:"button",class:"rui-filter-chip-remove","aria-label":`Remove ${s.label}`}),u=L("xmark",{className:"rui-filter-chip-remove-icon"});u&&c.append(u),c.onclick=()=>r.invoke(e.onRemove,s.value),l.append(c),n.append(l)}if(i.append(n),a.length>0&&typeof e.onClear=="function"){const s=o("button",{type:"button",class:"rui-filter-chips-clear"},["Clear all"]);s.onclick=()=>r.invoke(e.onClear),i.append(s)}return i}},Bu={name:"FieldRepeater",description:"Dynamic list of field groups. Pass `items` as row objects and `fields` as `{name, label, type?}` definitions.",props:[{name:"items",type:"any[]"},{name:"fields",type:"any[]"},{name:"onAdd",type:"callable",optional:!0},{name:"onRemove",type:"callable",optional:!0,description:"Receives the removed row's 0-indexed position"},{name:"addLabel",type:"string",optional:!0}],render:(t,e,r)=>{const a=pt(e.items),i=Va(e.fields),n=o("div",{class:"rui-field-repeater"});if(a.forEach((s,l)=>{const c=o("div",{class:"rui-field-repeater-row","data-index":String(l)}),u=o("div",{class:"rui-field-repeater-grid"});for(const p of i){const m=o("label",{class:"rui-field-repeater-field"});m.append(o("span",{class:"rui-field-repeater-label"},[p.label]));const g=o("input",{class:"rui-input",type:p.type==="number"?"number":"text",name:`${p.name}-${l}`,value:d(s[p.name]),readonly:""});m.append(g),u.append(m)}if(c.append(u),typeof e.onRemove=="function"){const p=o("button",{type:"button",class:"rui-field-repeater-remove","aria-label":"Remove row"},["Remove"]);p.onclick=()=>r.invoke(e.onRemove,l),c.append(p)}n.append(c)}),typeof e.onAdd=="function"){const s=o("button",{type:"button",class:"rui-field-repeater-add rui-button","data-variant":"secondary"},[d(e.addLabel,"Add row")]);s.onclick=()=>r.invoke(e.onAdd),n.append(s)}return n}},Du={name:"VirtualList",description:"Windowed vertical list for large datasets. Pass pre-rendered nodes as `items` or plain row objects plus a `renderItem` component node per row.",props:[{name:"items",type:"any[]"},{name:"itemHeight",type:"number",optional:!0,description:"Fixed row height in px (default 40)"},{name:"renderItem",type:"Node",optional:!0,description:"Template node rendered per data row"}],render:(t,e,r)=>{const a=Math.max(24,P(e.itemHeight,40)),i=k(e.items),n=o("div",{class:"rui-virtual-list"}),s=o("div",{class:"rui-virtual-list-scroller"}),l=o("div",{class:"rui-virtual-list-spacer"}),c=o("div",{class:"rui-virtual-list-window"}),u=i.length;l.style.height=`${u*a}px`,l.style.position="relative",c.style.position="absolute",c.style.top="0",c.style.left="0",c.style.right="0",s.style.maxHeight=`${Math.min(Math.max(u,1),12)*a}px`,s.style.overflow="auto";const p=m=>{c.replaceChildren();const g=s.clientHeight||a*12,f=Math.ceil(g/a)+2,h=Math.max(0,m),b=Math.min(u,h+f);c.style.transform=`translateY(${h*a}px)`;for(let v=h;v<b;v++){const y=i[v];if(e.renderItem)c.append(r.renderNode(y??e.renderItem));else if(y&&typeof y=="object"&&y.__kind)c.append(r.renderNode(y));else{const x=o("div",{class:"rui-virtual-list-item",style:`height:${a}px`});x.append(o("span",{},[d(y)])),c.append(x)}}};return s.onscroll=()=>{const m=Math.floor(s.scrollTop/a);p(m)},p(0),s.append(l,c),n.append(s),n}},Fu={name:"QueryBuilder",description:"Visual filter builder. Pass `fields` as `{name, label, type?}` and bind `value` to a rule array.",props:[{name:"fields",type:"any[]"},{name:"value",type:"any[]",optional:!0},{name:"onChange",type:"callable",optional:!0,description:"Receives the next rule array"}],render:(t,e,r)=>{const a=Va(e.fields),i=pt(e.value),n=t.argMeta?.[1]?.stateRef,s=o("div",{class:"rui-query-builder"}),l=c=>{s.replaceChildren(),c.forEach((p,m)=>{const g=o("div",{class:"rui-query-builder-row","data-index":String(m)}),f=o("select",{class:"rui-select rui-query-builder-field"});for(const y of a)f.append(o("option",{value:y.name},[y.label]));f.value=d(p.field??a[0]?.name);const h=o("select",{class:"rui-select rui-query-builder-op"},[]);for(const y of["equals","contains","gt","lt"])h.append(o("option",{value:y},[y]));h.value=d(p.op,"equals");const b=o("input",{class:"rui-input rui-query-builder-value",value:d(p.value)});g.append(f,h,b);const v=o("button",{type:"button",class:"rui-query-builder-remove"},["×"]);v.onclick=()=>{const y=c.filter((x,w)=>w!==m);n?r.setState(n,y):r.invoke(e.onChange,y),l(y)},g.append(v),s.append(g)});const u=o("button",{type:"button",class:"rui-query-builder-add"},["Add rule"]);u.onclick=()=>{const p=[...c,{field:a[0]?.name??"",op:"equals",value:""}];n?r.setState(n,p):r.invoke(e.onChange,p),l(p)},s.append(u)};return l(i.length>0?i:[{field:a[0]?.name??"",op:"equals",value:""}]),s}},Ou={name:"DiffViewer",description:"Side-by-side or unified diff of two text blobs.",props:[{name:"left",type:"string"},{name:"right",type:"string"},{name:"mode",type:"string",optional:!0,enum:["split","unified"],description:"Default split"}],render:(t,e)=>{const r=d(e.left),a=d(e.right),i=d(e.mode,"split"),n=o("div",{class:"rui-diff-viewer","data-mode":i});if(i==="unified"){const u=o("pre",{class:"rui-diff-viewer-unified"});for(const p of Lu(r,a))u.append(o("div",{class:`rui-diff-line rui-diff-line-${p.type}`},[(p.type==="add"?"+ ":p.type==="remove"?"- ":" ")+p.text]));return n.append(u),n}const s=o("div",{class:"rui-diff-viewer-panes"}),l=o("pre",{class:"rui-diff-viewer-pane rui-diff-viewer-left"},[r]),c=o("pre",{class:"rui-diff-viewer-pane rui-diff-viewer-right"},[a]);return s.append(l,c),n.append(s),n}},Uu={name:"JsonTree",description:"Expandable JSON tree viewer for objects and arrays.",props:[{name:"data",type:"any"},{name:"expanded",type:"boolean",optional:!0,description:"Expand all nodes (default: first level only)"}],render:(t,e)=>{const r=o("div",{class:"rui-json-tree"});return r.append(Ka(e.data,C(e.expanded))),r}},qu={name:"Gantt",description:"Simple Gantt chart. Pass `tasks` as `{id, label, start, end, progress?}` ISO date strings.",props:[{name:"tasks",type:"any[]"},{name:"startDate",type:"string",optional:!0},{name:"endDate",type:"string",optional:!0}],render:(t,e)=>{const r=Ru(e.tasks),a=r.map(p=>Ne(p.start)),i=r.map(p=>Ne(p.end)),n=e.startDate?Ne(d(e.startDate)):a.length?Math.min(...a):Date.now(),s=e.endDate?Ne(d(e.endDate)):i.length?Math.max(...i):n+864e5,l=Math.max(s-n,1),c=o("div",{class:"rui-gantt"}),u=o("div",{class:"rui-gantt-track"});for(const p of r){const m=o("div",{class:"rui-gantt-row"});m.append(o("div",{class:"rui-gantt-label"},[p.label]));const g=o("div",{class:"rui-gantt-bars"}),f=(Ne(p.start)-n)/l*100,h=Math.max((Ne(p.end)-Ne(p.start))/l*100,2),b=o("div",{class:"rui-gantt-bar",style:`left:${f}%;width:${h}%`,title:`${p.start} → ${p.end}`});p.progress!=null&&b.append(o("div",{class:"rui-gantt-bar-progress",style:`width:${Math.min(100,Math.max(0,p.progress))}%`})),g.append(b),m.append(g),u.append(m)}return c.append(u),c}},Hu={name:"Truncate",description:"Clamp long text with an expand control.",props:[{name:"text",type:"string"},{name:"maxLines",type:"number",optional:!0,description:"Lines before clamping (default 3)"},{name:"expandLabel",type:"string",optional:!0}],render:(t,e,r)=>{const a=Math.max(1,Math.floor(P(e.maxLines,3))),i=r.useInstanceState("expanded",!1),n=`display:-webkit-box;-webkit-line-clamp:${a};-webkit-box-orient:vertical;overflow:hidden`,s=o("div",{class:"rui-truncate","data-expanded":i.get()?"true":"false"}),l=o("p",{class:"rui-truncate-text",style:i.get()?"":n},[d(e.text)]),c=o("button",{type:"button",class:"rui-truncate-toggle"},[i.get()?"Show less":d(e.expandLabel,"Show more")]);return c.onclick=u=>{const p=u.currentTarget,m=p.closest(".rui-truncate"),g=m?.querySelector(".rui-truncate-text");if(!m||!g)return;const f=!i.get();i.set(f),g.style.cssText=f?"":n,p.textContent=f?"Show less":d(e.expandLabel,"Show more"),m.setAttribute("data-expanded",f?"true":"false")},s.append(l,c),s}},Vu={name:"InlineEdit",description:"Click-to-edit inline field with save on Enter or blur.",props:[{name:"value",type:"string"},{name:"label",type:"string",optional:!0},{name:"onSave",type:"callable",optional:!0,description:"Receives the committed draft string"}],render:(t,e,r)=>{const a=r.useInstanceState("editing",!1),i=r.useInstanceState("draft",d(e.value)),n=t.argMeta?.[0]?.stateRef,s=o("div",{class:"rui-inline-edit","data-editing":a.get()?"true":"false"}),l=d(e.label);l&&s.append(o("span",{class:"rui-inline-edit-label"},[l]));const c=o("button",{type:"button",class:"rui-inline-edit-display"},[d(e.value)]),u=o("input",{class:"rui-inline-edit-input rui-input",value:i.get()}),p=g=>{const f=g.closest(".rui-inline-edit"),h=f?.querySelector(".rui-inline-edit-input");return!f||!h?null:{root:f,input:h}},m=g=>{const f=p(g);a.set(!1),f?.root.setAttribute("data-editing","false");const h=i.get();n&&r.setState(n,h),r.invoke(e.onSave,h)};return c.onclick=g=>{const f=p(g.currentTarget);i.set(d(e.value)),a.set(!0),f&&(f.root.setAttribute("data-editing","true"),f.input.value=i.get(),setTimeout(()=>f.input.focus(),0))},u.oninput=g=>i.set(g.currentTarget.value),u.onkeydown=g=>{const f=g;if(f.key==="Enter"&&m(g.currentTarget),f.key==="Escape"){const h=p(g.currentTarget);a.set(!1),h?.root.setAttribute("data-editing","false")}},u.onblur=g=>m(g.currentTarget),s.append(c,u),s}},Wu={name:"NotificationBell",description:"Bell icon with unread count badge and dropdown notification list.",props:[{name:"count",type:"number",optional:!0},{name:"items",type:"any[]",optional:!0,description:"{title, message?, time?} objects"},{name:"onOpen",type:"callable",optional:!0}],render:(t,e,r)=>{const a=Math.max(0,Math.floor(P(e.count,0))),i=pt(e.items),n=r.useInstanceState("open",!1),s=n.get(),l=o("div",{class:"rui-notification-bell","data-open":s?"true":"false"}),c=o("button",{type:"button",class:"rui-notification-bell-trigger","aria-expanded":s?"true":"false","aria-haspopup":"true"}),u=L("bell",{className:"rui-notification-bell-icon"});u&&c.append(u),a>0&&c.append(o("span",{class:"rui-notification-bell-badge"},[a>99?"99+":String(a)])),l.append(c);const p=o("div",{class:"rui-notification-bell-panel",role:"menu"});if(i.length===0)p.append(o("div",{class:"rui-notification-bell-empty"},["No notifications"]));else for(const m of i){const g=o("div",{class:"rui-notification-bell-item"});g.append(o("div",{class:"rui-notification-bell-item-title"},[d(m.title)]));const f=d(m.message);f&&g.append(o("div",{class:"rui-notification-bell-item-message"},[f]));const h=d(m.time);h&&g.append(o("div",{class:"rui-notification-bell-item-time"},[h])),p.append(g)}return l.append(p),c.onclick=m=>{m.stopPropagation();const g=m.currentTarget,f=g.closest(".rui-notification-bell");if(!f)return;const h=!n.get();n.set(h),f.setAttribute("data-open",h?"true":"false"),g.setAttribute("aria-expanded",h?"true":"false"),h?(r.invoke(e.onOpen),Ee({liveRoot:f,onDismiss:()=>{n.set(!1),f.setAttribute("data-open","false"),g.setAttribute("aria-expanded","false")}})):he(f)},l}},le=(t,e)=>e==null?document.createDocumentFragment():t.renderNode(e),Gu=t=>!!(t&&typeof t=="object"),Ya=[ko,wo,ga,Lo,Eo,So,Co,To,$o,Mo,Ao,zo,Io,Do,No,_o,Bo,os,ss,Vo,Wo,Go,Yo,Jo,Xo,Zo,Qo,rs,ns,cs,Uo,ls,Ps,Ms,ws,ks,Cs,Ss,Ts,Ns,$s,As,ys,xs,wa,Is,zs,Rs,Ls,ka,Es,_s,xl,yl,kl,wl,Sl,Cl,$l,Tl,Pl,Il,zl,Ml,El,_l,jl,Fl,Ol,Zl,Ia,Ul,ql,Xl,Hl,Vl,Gl,Kl,ec,tc,Ql,Yl,ac,La,nc,lc,sc,pc,mc,gc,fc,Us,qs,hl,bl,Hs,Ws,Vs,Ks,Gs,Ys,Js,vl,Xs,Zs,Sa,gl,tl,el,Qs,rl,al,ol,nl,il,sl,ll,ul,cl,dl,ml,pl,vc,xc,Sc,Cc,Tc,Nc,Ac,Pc,Ic,zc,Lc,_c,jc,Dc,Oc,qc,Vc,Wc,Kc,Yc,Zc,eu,tu,au,iu,nu,ou,su,lu,cu,du,mu,fu,hu,bu,vu,yu,xu,wu,ku,Su,Cu,Tu,$u,Nu,Eu,_u,ju,Bu,Du,Fu,Ou,Uu,qu,Hu,Vu,Wu,{name:"Async",description:"Render `loading`, `error`, `empty`, or `data` slot based on an `http({...})` resource's state.",props:[{name:"resource",type:"any",positional:!0,required:!0},{name:"loading",type:"Node",optional:!0},{name:"error",type:"Node",optional:!0},{name:"empty",type:"Node",optional:!0},{name:"data",type:"Node",optional:!0}],render:(t,e,r)=>{const a=e.resource,i={loading:e.loading,error:e.error,empty:e.empty,data:e.data};if(!Gu(a))return le(r,i.empty??i.data??null);const n=a.state;if(n==="loading"||a.loading)return le(r,i.loading??null);if(n==="error"||a.error)return le(r,i.error??null);const s=a.data;return s==null||Array.isArray(s)&&s.length===0?le(r,i.empty??i.data??null):le(r,i.data??null)}},{name:"Show",description:"Conditional renderer. Sugar over `if expr { children } else { fallback }`.",props:[{name:"when",type:"any",positional:!0,required:!0},{name:"fallback",type:"Node",optional:!0},{name:"children",type:"Node[]",optional:!0}],render:(t,e,r)=>e.when?le(r,e.children??null):le(r,e.fallback??null)},{name:"Portal",description:"Render children outside the parent subtree (e.g. into document.body).",props:[{name:"target",type:"string",optional:!0},{name:"children",type:"Node[]",positional:!0}],render:(t,e,r)=>{const a=d(e.target);let i=null;if(a)try{i=document.querySelector(a)}catch{i=null}i||(i=document.body);const n=o("div",{class:"rui-portal"});for(const s of k(e.children))n.append(r.renderNode(s));return i&&(i.append(n),r.registerDisposer(()=>{n.parentNode&&n.parentNode.removeChild(n)})),o("span",{class:"rui-portal-anchor","data-portal":a??"body"})}},{name:"Redirect",description:"Navigate to `path` and unmount the rest of the subtree.",props:[{name:"path",type:"string",positional:!0,required:!0}],render:(t,e,r)=>{const a=d(e.path);if(a)try{r.router.navigate(a)}catch{}return o("span",{class:"rui-redirect","data-path":a,hidden:"true"})}},{name:"Lazy",description:"Defer rendering `children` until `loader` resolves.",props:[{name:"loader",type:"any",positional:!0,required:!0},{name:"fallback",type:"Node",optional:!0},{name:"children",type:"Node[]",optional:!0}],render:(t,e,r)=>{const a=e.loader;if(typeof a=="function")try{const i=a();return i&&typeof i.then=="function"?le(r,e.fallback??null):le(r,i??e.children??null)}catch{return le(r,e.fallback??null)}return le(r,e.children??null)}},{name:"ErrorBoundary",description:"Render a fallback subtree when rendering children throws.",props:[{name:"fallback",type:"Node",optional:!0},{name:"onError",type:"callable",optional:!0},{name:"children",type:"Node[]",positional:!0}],render:(t,e,r)=>{const a=o("div",{class:"rui-error-boundary"});try{for(const i of k(e.children))a.append(r.renderNode(i));return a}catch(i){try{r.invoke(e.onError,i)}catch{}const n=le(r,e.fallback??null),s=o("div",{class:"rui-error-boundary rui-error-boundary--fallback"});return s.append(n),s.setAttribute("data-error",i instanceof Error?i.message:String(i)),s}}}],Ku=[{name:"Layout",components:["Stack","StackItem","Grid","GridItem","Box","Container","Spacer","Card","CardHeader","CardFooter","Separator","Tabs","TabItem","Accordion","AccordionItem","Modal","Drawer","Steps","AspectRatio","ScrollArea","Sticky","ResizablePanels","MasonryGrid"],notes:["- `root` MUST be `Stack(...)` and contain at least one child.","- Wrap each major chunk of content in a `Card(...)` for visual grouping.",'- Prefer `Grid(...)` over `Stack` with `direction="row" wrap=true` when children should size uniformly (KPIs, feature tiles, card grids).',"- Use `Container(children, size?)` to centre a wide page within a comfortable max-width (landing pages, articles, marketing sections).",'- Use `Spacer()` inside `Stack(direction="row")` to push the next item to the far edge; pass a `size` for an explicit fixed gap.','- Use `Separator(orientation?, label?)` between sections to add visual breaks. Pass a `label` for a centered "OR"-style separator.',"- Use `Drawer` for side-panel detail views, `Modal` for centered dialogs.","- Use `Sticky(children, side?, offset?)` to pin a toolbar/banner while the surrounding content scrolls.","- Use `ResizablePanels(primary, secondary, initialPrimaryWidth?)` for user-resizable two-pane layouts (code editors, file browsers).","- Use `MasonryGrid([...])` for Pinterest-style mixed-height card walls — prefer `Grid` when rows should share a height.",'- Use `StackItem(child, grow?, shrink?, basis?, alignSelf?)` inside `Stack(direction="row", uniform=false)` for toolbars.','- Use `Grid(columns: 12, [GridItem(child, span: "1/4"), GridItem(main, span: "3/4")])` for sidebar layouts; fractional spans `"1/2"`…`"1/12"` resolve on a 12-column track.',"- Use `Box(children, padding?, margin?, border?, background?)` for spacing and surfaces without raw CSS."]},{name:"Content",components:["Text","Image","Link","Badge","BadgeList","Callout","Quote","CodeBlock","Skeleton","Spinner","Markdown","Kbd","Icon"],notes:["- Prefer `Markdown(...)` for rich paragraph text with inline formatting — the parser supports headings, blockquotes, fenced code, numbered/bullet lists, links, images, and bare-URL auto-linking.","- Use `Callout(variant, title, description, icon?, compact?)` for highlighted notices; pass `compact: true` for a one-line inline note.","- Use `Quote(text, cite?)` for inline pull-quotes inside articles and marketing sections (use `Testimonial` when you also have author/role/rating).","- Use `CodeBlock(language, codeString, showLineNumbers?, highlightLines?)` for read-only code snippets. The header always renders a copy-to-clipboard button.",'- Use `Badge(label, variant?, icon?, size?)` for a single pill and `BadgeList(["a","b","c"], variant?, size?)` to render an array of strings as Badge pills.',"- Use `Skeleton(variant?, lines?, height?, shape?, width?)` for loading placeholders; `variant` accepts `paragraph` (default), `card`, `table-row`, `avatar`, `image`.","- Use `Spinner(size?, label?, tone?)` for tiny inline loading indicators inside buttons, toolbars, or table cells.",'- Use `Image(src, alt?, caption?, ratio?, fit?, fallback?)` — `ratio` (e.g. `"16:9"`) makes the image self-constrain so you do not need an outer `AspectRatio`.','- Use `Kbd(["Cmd", "K"])` when referring to keyboard shortcuts.','- Use `Icon(name, variant?, size?)` to render a standalone Font Awesome icon (`name` is the FA name without the `fa-` prefix, e.g. `"house"`, `"chart-line"`, `"regular:star"`, `"brands:github"`).','- For page-level titles reach for `PageHeader(...)` (top of dashboards/detail pages) or `SectionHeader(...)` (inside a Card). For tiny inline titles use `Text(value, variant="large-heavy")`.']},{name:"Forms",components:["Form","FormControl","FormSection","FieldSet","ValidationSummary","Input","TextArea","PasswordInput","MaskedInput","MentionInput","TagInput","Select","SelectItem","Combobox","MultiSelect","Checkbox","CheckBoxGroup","CheckBoxItem","Radio","Switch","ToggleGroup","Button","Buttons","SearchBar","Slider","NumberInput","ColorPicker","DatePicker","DateRangePicker","TimePicker","DateTimePicker","FileUpload","PinInput","MultiStepForm"],notes:["- Each FormControl should be a separate reference for progressive streaming.","- Pass a `$variable` as the last argument to `Input`, `Select`, `Checkbox`, `Switch`, `MultiSelect`, or `CheckBoxGroup` for two-way binding.","- Prefer `Switch` over `Checkbox` for settings; use `ToggleGroup` for view-mode pickers and mutually-exclusive filters.","- Reach for `SearchBar(id, placeholder?, value?, shortcut?)` instead of a raw `Input` whenever the field's purpose is to filter content. It ships with the magnifier icon and keyboard hint baked in.","- `Slider(id, min?, max?, step?, value?, label?, showValue?)` is the canonical control for numeric ranges (volume, brightness, filters); pass a `$variable` as `value` for two-way binding.",'- `NumberInput(id, value?, min?, max?, step?, placeholder?)` is friendlier than `Input(type="number")` for quantity steppers and integer settings — it ships with +/- buttons that respect `min`/`max`.',"- `DatePicker(id, value?, label?, min?, max?, placeholder?)` wraps the native date picker; pass `value` as a `$variable` for two-way binding (ISO `YYYY-MM-DD`).","- `DateRangePicker(id, from?, to?, label?, min?, max?)` is the paired-date variant — bind both `from` and `to` to `$variable`s for a single shared range.","- `Combobox(id, items, value?, placeholder?, emptyLabel?)` is the searchable single-select alternative to `Select` — type to filter long option lists (countries, currencies, users).","- `MultiSelect(id, items, value?, placeholder?, emptyLabel?, max?)` is the multi-select equivalent — bind a `$variable` array as `value` for two-way binding, the trigger renders the picks as removable chips.","- `FileUpload(id, label?, hint?, accept?, multiple?, action?)` is the styled file picker; the picked files cannot pass through a `$variable`, so wire the `action` prop to an `action` block (use a `js{ … }` body if you need to read file contents directly).",'- A submit button should call an `action` that awaits the relevant `$mutation` resource, optionally refetches a `$query`, and resets the form `$variable`s (e.g. `$title = ""`).',"- Button `size` accepts both `sm|md|lg` (canonical) and the legacy `small|normal|large`. Pass `icon` for an inline leading icon.","- `FormSection(label, children, helper?)` is the canonical wrapper for related fields. Reach for it INSTEAD of nesting fields in Card + SectionHeader by hand.","- `FieldSet(legend, children, helper?)` is the accessible `<fieldset>` for radio/checkbox groups; prefer `FormSection` for purely visual grouping.","- `ValidationSummary(errors, title?)` renders an aggregate error panel at the top of the form. Pass `errors` as `{label, message}` objects.",'- `PasswordInput(id, value?, placeholder?, strengthMeter?)` adds a show/hide toggle and an optional 4-step strength meter — prefer over `Input(type="password")` for sign-up flows.',"- `PinInput(id, length?, value?, type?)` renders per-digit code entry for 2FA / SMS verification (use `length=6` for OTP codes).","- `TagInput(id, value?, placeholder?)` lets the user add comma- or Enter-separated chips bound to a `$variable` array.","- `MentionInput(id, people, value?)` is a textarea with inline @-mention suggestions — use for comments, task notes, chat composers.","- `MaskedInput(id, mask, value?)` formats input against a mask string (`9` digit, `A` letter, `*` any). Use for phone numbers, postal codes.","- `TimePicker(id, value?)` and `DateTimePicker(id, value?)` wrap the corresponding native inputs with consistent styling.","- `ColorPicker(id, value?, label?, swatches?)` pairs a color chip with a hex input and preset swatches — bind a $variable holding a hex string.","- `MultiStepForm(steps, current, onSubmit?)` replaces ad-hoc `Steps` + content + manual prev/next wiring. Each step is `{title, details?, content}`."]},{name:"Data",components:["Table","Col","DataGrid","List","ListItem","StatCard","Stats","Sparkline","Tile","Progress","ProgressRing","Pagination","Tree","TreeNode","CalendarView","ComparisonTable","InfiniteList"],notes:['- Build columns using array pluck: `Col("Title", data.rows.title, format?, align?)`.','- For per-row controls inside a Col, use `@Each(data.rows, "row", ...)` and reference `row.field` inline.','- `Table(cols, caption?, density?, striped?, sticky?, emptyLabel?)` — pass `density="compact"` for dense data, `sticky=true` to pin the header in a scrolling parent, and `emptyLabel` for the zero-state cell.',"- `DataGrid(cols, rowIds?, caption?, sort, selectedIds, selectable?, page, perPage?, …)` is the advanced Table — adds sortable headers (`sortable=true` on Col), per-column filter chips (`filterable=true`), checkbox row selection bound to `$selectedIds`, sticky header / first column, pagination, and an optional bulk-action toolbar. Reach for this whenever a user needs to sort, filter, or page through a list.","- `CalendarView(value?, month?, events?, view?, firstDay?, onSelect?)` renders a full-month (or week) calendar grid for scheduling apps — distinct from the `DatePicker` input. Bind `value` to a `$variable` for the selected ISO date.","- `ComparisonTable(columns, rows, highlightColumn?)` is the generic counterpart of `PricingTable` — pass rows of `{label, values, hint?, group?}`. Use for feature comparisons, spec sheets, plan grids.","- `InfiniteList(items, onLoadMore?, loading?, hasMore?)` is a scroll-to-load list; the action fires when the sentinel scrolls into view.","- Use `Progress(value, max?, label?, tone?, indeterminate?, segments?, buffered?)` for linear bars — `segments` renders an N-step strip (onboarding flows), `buffered` adds a secondary buffer indicator.","- `ProgressRing(value, max?, label?, tone?, size?)` is the circular variant for quotas/completion.",'- `Stats([{label, value, hint?, tone?, spark?}, …], layout?)` — `layout="strip"` (default) for inline KPIs; `layout="grid"` for a responsive StatCard grid. Pass `spark` for an inline trend line.',"- `StatCard(label, value, trend?, delta?, icon?, spark?, tone?)` gains an optional inline `Sparkline` via the `spark` prop. Use `Sparkline(values, tone?)` standalone for tiny trend chips in table cells.","- `Tile(label, icon?, value?, description?, tone?, action?)` is the dense icon tile for quick-action menus and category grids; pair with `Grid` for uniform rows.","- `Tree([TreeNode(label, children?, icon?, expanded?, active?, badge?, action?)])` renders a hierarchical tree (file browsers, nested navigation, category pickers); use `expanded=true` to open a branch by default.",'- `Pagination(page, totalPages, siblings?, total?, perPage?, perPageOptions?, compact?)` — bind `page` (and optionally `perPage`) to a `$variable`; pass `total` to render the "Showing N–M of T" summary. Reuse the same variable when slicing data with `@Filter` / `@Each`.']},{name:"Charts",components:["BarChart","LineChart","PieChart","RadarChart","ScatterChart","Histogram","Heatmap","Gauge","Series"],notes:["- Use `LineChart` for trends (pass `filled=true` for area-style charts), `BarChart` for comparisons, `PieChart` for proportions, `RadarChart` for multi-axis scorecards.","- `Heatmap(xLabels, yLabels, values)` renders a color-intensity matrix — perfect for calendar heatmaps, correlation grids, schedule density.","- `ScatterChart(series, xLabel?, yLabel?)` plots XY points; pass each Series as `Series(name, points)` where points are `{x, y, label?}`.","- `Histogram(values, binCount?)` bins raw numbers; pass pre-computed `bins=[{label, count}]` instead when you control the bucketing.","- `Gauge(value, min?, max?, label?, tone?, size?)` is the half-doughnut KPI indicator for thresholds (uptime %, score, NPS).",'- Pass series via `Series("Name", [...numbers])`.']},{name:"Feedback & Media",components:["Avatar","AvatarGroup","PersonChip","Tooltip","HoverCard","Popover","Rating","Toast","VideoPlayer","AudioPlayer","Carousel","Gallery","Lightbox","Map"],notes:["- `Avatar(name, src?, size?, status?)` falls back to initials when the image is missing.","- Use `AvatarGroup` to render contributor strips with a `+N` overflow chip.","- `PersonChip(name, role?, avatarSrc?, size?, status?, action?)` is the inline avatar + name + role pill — use everywhere a person is referenced (table cells, list rows, sidebar footers, kanban cards) instead of a raw `Avatar` next to `Text`.","- Wrap any node in `Tooltip(label, trigger)` for inline hints.","- Use `HoverCard(trigger, content)` when the popover needs rich content (profile preview, link target) and the trigger should open on hover.","- `Popover(trigger, content, title?, side?, align?, width?)` is the click-triggered counterpart of `HoverCard` — use for filter panels, color pickers, share menus, and small settings flyouts. Always renders an × close button in the header; clicking the trigger again, clicking outside, or pressing Escape also closes it.",'- `Rating(value, max?, label?, count?, size?, interactive?, halfStep?, icon?)` renders stars for product reviews, testimonials, and ranked lists. Pass a `$variable` as `value` with `interactive=true` to let users rate; add `halfStep=true` so clicking the left half of a star sets a half-value. Set `icon="heart"|"thumb"|"fire"|"bolt"` (or any FA name) to swap glyphs.','- `Toast(title, message?, tone?, icon?, duration?, action?, onClose?, position?)` pins a transient notice; pass `duration` (ms) for auto-dismiss. Drive lists from an `action` body: `$toasts = [...$toasts, item]` to append and `$toasts = @Filter($toasts, "id", "!=", id)` to dismiss. Use `Banner` for top-of-page announcements and `Notification` for permanent inbox entries.',"- `NotificationBell(count?, items?, onOpen?)` — compact inbox trigger; `CommandPalette` for Cmd-K action search."]},{name:"Navigation",components:["Breadcrumb","BreadcrumbItem","Navbar","NavbarItem","DropdownMenu","MenuItem","MenuSeparator","MenuLabel"],notes:['- Use `Breadcrumb(["Workspace", "Reports", "Q3"])` at the top of every detail page so users see the path.',"- For per-item links, pass `BreadcrumbItem(label, href)` nodes instead of strings.","- `Navbar(brand?, items?, actions?, sticky?, variant?)` + `NavbarItem(label, to?, href?, icon?, active?, action?, external?)` produces a top navigation bar with brand on the left, links in the middle, and actions on the right — the canonical companion of `Sidebar` for marketing pages, docs, or any product surface without left-side nav.",'- `DropdownMenu(trigger, items, side?, align?, label?)` is the click-triggered dropdown menu — use it for user-profile menus, row "…" action menus, and any compact list of actions hanging off a single trigger. Children must be `MenuItem`, `MenuSeparator`, or `MenuLabel` entries.','- `MenuItem(label, action?, icon?, shortcut?, variant?, disabled?)` renders a single row inside a `DropdownMenu`; use `variant="danger"` for destructive actions and `MenuSeparator()`/`MenuLabel(label)` to group related items.']},{name:"Chat",components:["SectionBlock","ListBlock","FollowUpBlock","FollowUpItem","ActionLink","ChatBubble"],notes:["- End most responses with a `FollowUpBlock` of 2–4 short prompts to keep the conversation moving.",'- `ChatBubble(author, body, time?, avatarSrc?, from?)` renders a single message bubble; use `from="me"` for the active speaker and `from="agent"` for the assistant. Compose transcripts as `Stack([ChatBubble(...), ChatBubble(...), …])` inside a `Card`.']},{name:"Patterns",components:["Hero","PageHeader","EmptyState","Timeline","TimelineItem","ActivityLog","FeatureGrid","FeatureItem","Testimonial","ProfileCard","Comment","Banner","Notification","InboxPanel","OnboardingChecklist","MediaCard","TopBar","KanbanBoard","KanbanColumn","KanbanCard","SectionHeader","Toolbar","DescriptionList","DescriptionItem","StatusDot","PricingTable","PricingCard","LoadingState","ErrorState","SuccessState","Tour","Spotlight"],notes:["- Patterns are **opinionated composites** that pack an entire UI idiom into one component. Reach for them BEFORE composing equivalent layouts by hand with Card+Stack — the result will look more polished and require fewer tokens.",'- `Hero(title, subtitle, primary, secondary, eyebrow?, highlights?, tone?)` — landing-style text-first header. Use `layout="cover"` with `imageSrc`, `height`, and optional `caption` for image-backed hero bands.','- `PageHeader(title, subtitle?, breadcrumbs?, actions?, status?)` — the canonical first child for any dashboard or detail page. If you omit `breadcrumbs`, the component auto-derives `["Home", title]`.',"- `TopBar(title?, search?, actions?, sticky?)` — compact top strip for a content surface (panels, dialogs, embedded views). Use `AppShell` when you need a full sidebar; use `TopBar` for narrower headers above scrolling content.","- `SectionHeader(title, subtitle?, eyebrow?, status?, actions?)` — sub-header inside a Card or panel. Use instead of bare `CardHeader` when the section also needs eyebrow / actions / status.",'- `Stats(items, layout?)` — KPI strip (`layout="strip"`, default) or responsive grid (`layout="grid"` with StatCard children). Prefer over hand-rolled StatCard rows.',"- `Toolbar(left?, right?, center?, searchable?, searchPlaceholder?, searchValue?)` — filter/search/actions row above a list, table, or board. Pass `searchable: true` to auto-mount a `SearchBar` (use `searchValue` to bind it to a `$variable`).","- `EmptyState(title, description?, icon?, illustration?, actions?, action?)` — render this when a list is empty rather than an empty Card. The icon is auto-picked from the title keywords if you omit it (inbox/messages → `inbox`, charts/analytics → `chart-pie`, files/folders → `folder-open`, etc.).","- `Timeline([TimelineItem(...)])` — vertical event feed (audit log, changelog, activity).",'- `ActivityLog(entries, variant?)` — purpose-built feed of user actions. Pass `entries` of `{actor, title, description?, time?, icon?, tone?, meta?}`; use `variant="audit"` for security/admin trails with monospace meta.',"- `FeatureGrid([FeatureItem(...)])` — feature highlights with iconography.","- `MediaCard(title, imageSrc?, description?, tags?, meta?, actions?, badge?, orientation?, ratio?)` — image + content card. Use for article previews, product cards, project highlights. Pair with `Grid` for uniform card rows.",'- `KanbanBoard([KanbanColumn("To do", [KanbanCard(...), ...])])` — task boards.','- `DescriptionList([DescriptionItem("Status", Badge(...)), …])` — detail-page key/value summary. Always preferable to a Stack of Text rows on profile, billing, or metadata panels.',"- `StatusDot(label, tone?, pulse?)` — inline status pip. Use in toolbars, list rows, table cells, sidebars.","- `Notification(title, message?, time?, icon?, avatarSrc?, tone?, unread?, actions?)` — inline notification card for notification panels / inboxes (prefer `Banner` for top-of-page announcements).","- `InboxPanel(items, title?, onMarkAllRead?)` — `Notification` cards grouped into Unread / Earlier sections, with a shared mark-all-read action.","- `OnboardingChecklist(items, title?, description?)` — checklist of `{title, description?, done?, action?}` items with progress. Use for product onboarding, setup wizards, getting-started panels.","- `PricingTable([PricingCard(plan, price, period?, description?, features?, action?, badge?, featured?)])` — full pricing page block.","- `LoadingState(title?, description?, tone?, action?)`, `ErrorState(title, description?, action?, secondaryAction?, retryLabel?)`, `SuccessState(title, description?, action?, secondaryAction?)` — full-card empty-state alternatives for asynchronous content states.","- `Tour(steps, current, onFinish?)` and `Spotlight(title?, description?, action?)` are the product-tour primitives. `Spotlight` is a single highlighted call-out; `Tour` walks the user through multiple `{title, description, image?}` steps with Prev/Next/Skip controls and a progress dots indicator."]},{name:"Editors & overlays",components:["RichTextEditor","CodeEditor","ContextMenu"],notes:["- `RichTextEditor(id, value?, placeholder?, minHeight?)` is the contenteditable WYSIWYG editor — toolbar ships with bold/italic/underline/strike/heading/lists/link. Bind `value` to a `$variable` holding HTML.","- `CodeEditor(id, value?, language?, placeholder?, minHeight?)` is a lightweight `<textarea>` with a synced line-number gutter and tab indentation. Use for snippet editors, prompt sandboxes, settings JSON.","- `ContextMenu(target, items)` attaches a right-click menu to any node. `items` are `MenuItem` or `{label, action?, icon?, shortcut?, variant?, disabled?}` objects; pass a `MenuSeparator()` to split groups."]},{name:"App shell",components:["AppShell","Sidebar","SidebarSection","SidebarItem","SplitView"],notes:["- App shell components produce a **full SaaS-style layout in a single statement**. Use them whenever the response represents a complete product surface (dashboards with nav, settings sections, admin consoles, inboxes).","- `AppShell(sidebar, content, topbar?, collapsible?, sidebarOpen?)` — fixed-left navigation + scrollable main area. Pass `collapsible=true` to enable a hamburger that turns the sidebar into a slide-over drawer on mobile; bind `sidebarOpen` to a `$variable` if you want to drive that drawer programmatically.","- `Sidebar(items, brand?, tagline?, footer?, collapsed?)` + `SidebarItem(label, icon?, active?, badge?, action?)` + `SidebarSection(label, items)` — group nav links into sections, mark the current page with `active=true`, attach badges for counts. Pass `collapsed=true` (or bind to a `$variable`) to collapse it to an icon rail.","- `SplitView(primary, detail, primaryWidth?)` — master/detail layout (inboxes, file browsers, contact lists). Both panes are scrollable."]},{name:"Theming",components:["Theme"],notes:["- `Theme({...})` applies a partial token override **on top of** the base theme set by the host (attribute / `setTheme()`). Use it to brand a single response without changing host configuration.","- Assign the result to a top-level binding called `theme` so the runtime picks it up:",' `theme = Theme({ colors: { primary: "#0969da" }, radius: { button: "6px" } })`',"- Tokens MUST use the structured form. Top-level groups: `colors`, `radius`, `font`, `motion`, `elevation` (plus metadata: `name`, `direction`).","- Common tokens (each lives inside its group): `colors.primary`, `colors.primaryHover`, `colors.primaryText`, `colors.accent`, `colors.bg`, `colors.surface`, `colors.text`, `colors.textMuted`, `colors.border`, `colors.focusRing`; `radius.md`, `radius.button`, `radius.input`; `font.family`, `font.familyHeading`, `font.sizeBase`, `font.weightHeading`; `motion.transitionDuration`; `elevation.md`.","- The legacy flat-shape form (`Theme({colorPrimary: ...})`) and free-form `--css-vars` are removed in Aktion 0.5 — the runtime drops them and the schema validator surfaces a migration warning.",'- Tokens are CSS values (`"#0969da"`, `"\'Inter\', sans-serif"`, `"6px"`, `"600"`). The runtime ignores unknown keys inside a group, so typos fail silent.',"- Removing the `Theme(...)` line snaps the UI back to the base theme without a reload."]},{name:"Advanced UI",components:["IconButton","CommandPalette","FilterChips","FieldRepeater","VirtualList","QueryBuilder","DiffViewer","JsonTree","Gantt","Truncate","InlineEdit","NotificationBell"],notes:["- `IconButton(icon, label, action?, variant?, size?, disabled?)` — accessible icon-only control.","- `CommandPalette(items, open?, placeholder?, shortcut?)` — Cmd-K searchable actions.","- `FilterChips(chips, onRemove?, onClear?)` — applied filter pills with remove.","- `FieldRepeater(items, fields, onAdd?, onRemove?)` — dynamic form rows.","- `VirtualList(items, itemHeight?, renderItem)` — windowed long lists.","- `QueryBuilder(fields, value?)` — visual AND/OR filter builder.","- `DiffViewer(left, right, mode?)` — side-by-side or unified diff.","- `JsonTree(data)` — collapsible JSON inspector.","- `Gantt(tasks, startDate?, endDate?)` — horizontal schedule timeline.","- `Truncate(text, maxLines?)` / `InlineEdit(value, onSave?)` / `NotificationBell(count?, items?)`."]},{name:"Routing",components:["NavLink"],notes:['- Declare routes with the `_router_({...})` call form: `pages = _router_({ "/": Dashboard(), "/orders/:id": OrderDetail(id: params.id), default: NotFound() })`. The matched arm\'s `params` object is in scope on the right-hand side; nest `_router_` inside components for layout-preserving sub-routes.',"- `Redirect(path)` is a router-aware component: returning it from a route's body navigates and unmounts the rest of the subtree.","- `NavLink(label, to)` is a thin link wrapper that reads `_route_.path` and dispatches `_route_.navigate(to)` — use it for sidebars, navbars and breadcrumbs.","- Read URL params via `_route_.params.<name>` (e.g. `_route_.params.id` for `/users/:id`) and the current path via `_route_.path`."]},{name:"Helpers",components:["Async","Show","Portal","Redirect","Lazy","ErrorBoundary"],notes:["- `Async(resource, loading:, error:, empty:, data:)` switches a `$query` / `$mutation` / `$subscription` resource on its `state` field.","- `Show(when, fallback?, children)` is sugar over `if expr { children } else { fallback }`.","- `Portal(target?, children)` renders into a different DOM subtree (defaults to `document.body`).","- `Redirect(path)` is a router-aware component — see Routing.","- `Lazy(loader, fallback?)` defers children until `loader` resolves.","- `ErrorBoundary(fallback?, onError?, children)` catches rendering errors thrown by descendants."]}];kr(Ya);const Ke={root:"Stack",components:Ya,componentGroups:Ku},Yu="$";class Ja{constructor(e){j(this,"instanceStates",new Map);j(this,"instanceDisposers",new Map);j(this,"aliveInstances",new Set);j(this,"instancesWithEffects",new Set);this.options=e}setLibrary(e){this.options={...this.options,library:e}}reset(){for(const e of this.instanceDisposers.values())for(const r of e.values())this.safeDispose(r);if(this.instanceDisposers.clear(),this.instanceStates.clear(),this.options.unmountInstanceEffects)for(const e of this.instancesWithEffects)try{this.options.unmountInstanceEffects(e)}catch(r){console.error(`[aktion] unmountInstanceEffects threw for ${e}`,r)}this.instancesWithEffects.clear(),this.aliveInstances=new Set}beginRender(){this.aliveInstances=new Set}endRender(){const e=this.aliveInstances;for(const r of[...this.instanceStates.keys()]){const a=r.lastIndexOf("::"),i=a===-1?r:r.slice(0,a);e.has(i)||this.instanceStates.delete(r)}for(const[r,a]of[...this.instanceDisposers.entries()])if(!e.has(r)){for(const i of a.values())this.safeDispose(i);this.instanceDisposers.delete(r)}if(this.options.unmountInstanceEffects){for(const r of[...this.instancesWithEffects])if(!e.has(r)){try{this.options.unmountInstanceEffects(r)}catch(a){console.error(`[aktion] unmountInstanceEffects threw for ${r}`,a)}this.instancesWithEffects.delete(r)}}}safeDispose(e){try{e()}catch(r){console.error("[aktion] disposer threw",r)}}render(e){return this.renderAt(e,Yu)}renderAt(e,r){if(e==null)return document.createTextNode("");if(Array.isArray(e)){const a=document.createDocumentFragment();return e.forEach((i,n)=>{a.append(this.renderAt(i,`${r}/${n}`))}),a}return Hr(e)?this.renderUserComponent(e,r):qr(e)?this.renderComponent(e,r):typeof e=="string"||typeof e=="number"||typeof e=="boolean"?document.createTextNode(String(e)):document.createTextNode("")}renderUserComponent(e,r){const a=this.options.evaluationContext;if(!a){const u=document.createElement("div");return u.className="rui-unknown-component",u.textContent=`[unknown component: ${e.decl.name}]`,u}const i=a(),n=e.explicitKey!=null?`=${String(e.explicitKey)}`:`@${e.source?.line??0}:${e.source?.column??0}`,s=`${r}#${e.decl.name}${n}`;this.aliveInstances.add(s);const{value:l,effects:c}=Kr(e,i,s);return this.options.mountInstanceEffects&&(this.options.mountInstanceEffects(s,c,a),c.length>0&&this.instancesWithEffects.add(s)),this.renderAt(l,s)}renderComponent(e,r){const a=Ie(this.options.library,e.name);if(!a){const u=document.createElement("div");return u.className="rui-unknown-component",u.textContent=`[unknown component: ${e.name}]`,u}const i=Sr(a,e.args),n=e.explicitKey!=null?`=${String(e.explicitKey)}`:`@${e.source?.line??0}:${e.source?.column??0}`,s=`${r}#${e.name}${n}`;this.aliveInstances.add(s);let l=0;const c={renderNode:u=>this.renderAt(u,`${s}>${l++}`),invoke:(u,...p)=>{if(typeof u=="function")try{const m=u(...p);m&&typeof m.then=="function"&&m.catch(g=>{console.error("[aktion] handler rejected",g)})}catch(m){console.error("[aktion] handler threw",m)}},setState:(u,p)=>{this.options.state.set(u,p)},resetState:(...u)=>{this.options.state.reset(...u)},sendToAssistant:u=>{this.options.onAssistantMessage?.(u)},openUrl:u=>{const p=rt(u,"#"),m=this.options.onOpenUrl;m?m(p):p!=="#"&&typeof window<"u"&&window.open(p,"_blank","noopener,noreferrer")},bindState:(u,p,m)=>{const f=`on${m?.event??this.eventFor(u)}`,h=m?.getValue??this.defaultValueGetter(u);u[f]=b=>{const v=b.currentTarget??b.target??u;this.options.state.set(p,h(v))}},useInstanceState:(u,p)=>{const m=`${s}::${u}`;return this.instanceStates.has(m)||this.instanceStates.set(m,p),{get:()=>this.instanceStates.get(m),set:g=>{this.instanceStates.set(m,g)}}},registerDisposer:(u,p)=>{let m=this.instanceDisposers.get(s);m||(m=new Map,this.instanceDisposers.set(s,m));const g=p??`__anon::${m.size}`,f=m.get(g);f&&f!==u&&this.safeDispose(f),m.set(g,u)},router:this.options.router};try{return a.render(e,i,c)}catch(u){console.error(`[aktion] failed to render ${a.name}`,u);const p=document.createElement("div");return p.className="rui-render-error",p.textContent=`[render error in ${a.name}]`,p}}eventFor(e){return e instanceof HTMLSelectElement||e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")?"change":"input"}defaultValueGetter(e){return e instanceof HTMLInputElement&&e.type==="checkbox"?r=>r.checked:e instanceof HTMLInputElement&&e.type==="radio"?r=>r.value:e instanceof HTMLInputElement&&e.type==="number"?r=>{const a=r.value;if(a==="")return null;const i=Number(a);return Number.isFinite(i)?i:null}:e instanceof HTMLInputElement&&e.type==="range"?r=>Number(r.value):r=>r.value}}const Ju=["onclick","oninput","onchange","onsubmit","onfocus","onblur","onkeydown","onkeyup","onkeypress","onerror","onmouseenter","onmouseleave","onmousedown","onmouseup","onpointerdown","onpointerup"];function Xu(t,e){const r=e.nodeType===Node.DOCUMENT_FRAGMENT_NODE?Array.from(e.childNodes):[e];Qa(t,r)}function Xa(t,e){if(t===e)return t;if(t.nodeType!==e.nodeType)return Za(t,e);if(t.nodeType===Node.TEXT_NODE)return t.textContent!==e.textContent&&(t.textContent=e.textContent),t;if(t.nodeType!==Node.ELEMENT_NODE)return t;const r=t,a=e;return r.tagName!==a.tagName?Za(r,a):(Zu(r,a),r)}function Za(t,e){return t.parentNode?.replaceChild(e,t),e}function Zu(t,e){Qu(t,e),ed(t,e),Qa(t,Array.from(e.childNodes)),td(t,e)}function Qu(t,e){const r=t.attributes;for(let i=r.length-1;i>=0;i-=1){const n=r[i];e.hasAttribute(n.name)||n.name==="open"&&t.tagName==="DETAILS"||t.removeAttribute(n.name)}const a=e.attributes;for(let i=0;i<a.length;i+=1){const n=a[i];t.getAttribute(n.name)!==n.value&&t.setAttribute(n.name,n.value)}}function ed(t,e){for(const r of Ju){const a=e[r],i=t[r];a!==i&&(t[r]=a??null)}}function td(t,e){if(t instanceof HTMLInputElement&&e instanceof HTMLInputElement){rd(t,e);return}if(t instanceof HTMLTextAreaElement&&e instanceof HTMLTextAreaElement){ad(t,e);return}if(t instanceof HTMLSelectElement&&e instanceof HTMLSelectElement){!mt(t)&&t.value!==e.value&&(t.value=e.value);return}}function rd(t,e){if(t.type==="checkbox"||t.type==="radio"){const a=e.hasAttribute("checked")||e.checked;t.checked!==a&&!mt(t)&&(t.checked=a);return}const r=e.getAttribute("value")??e.value??"";!mt(t)&&t.value!==r&&(t.value=r)}function ad(t,e){const r=e.value??e.textContent??"";!mt(t)&&t.value!==r&&(t.value=r)}function mt(t){const e=t.getRootNode();return e instanceof ShadowRoot||e instanceof Document?e.activeElement===t:t.ownerDocument?.activeElement===t}function Qa(t,e){const r=new Map;for(const i of Array.from(t.childNodes)){const n=Vt(i);n&&r.set(n,i)}let a=0;for(const i of e){const n=t.childNodes[a]??null,s=Vt(i);if(s&&r.has(s)){const c=r.get(s);r.delete(s),c!==n&&t.insertBefore(c,n),Xa(c,i),a+=1;continue}if(!n){t.appendChild(i),a+=1;continue}const l=Vt(n);if(l&&(!s||l!==s)){t.insertBefore(i,n),a+=1;continue}Xa(n,i),a+=1}for(;t.childNodes.length>e.length;){const i=t.childNodes[t.childNodes.length-1];t.removeChild(i)}}function Vt(t){if(t.nodeType!==Node.ELEMENT_NODE)return null;const e=t;if(e.id)return`#${e.id}`;const r=e.getAttribute("data-rui-key");return r?`@${r}`:null}const id={Count:{description:"Number of items in an array.",params:[{name:"array",type:"any[]",required:!0}]},Sum:{description:"Sum of numeric values in an array.",params:[{name:"array",type:"number[]",required:!0}]},Avg:{description:"Average of numeric values in an array.",params:[{name:"array",type:"number[]",required:!0}]},Min:{description:"Minimum of numeric values in an array.",params:[{name:"array",type:"number[]",required:!0}]},Max:{description:"Maximum of numeric values in an array.",params:[{name:"array",type:"number[]",required:!0}]},First:{description:"First element of an array, or null.",params:[{name:"array",type:"any[]",required:!0}]},Last:{description:"Last element of an array, or null.",params:[{name:"array",type:"any[]",required:!0}]},Filter:{description:"Filter an array by a field/operator/value comparison.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0},{name:"op",type:"'=='|'!='|'>'|'<'|'>='|'<='|'contains'",required:!0},{name:"value",type:"any",required:!0}]},FilterBy:{description:"Alias for `@Filter` — filter an array by a field/operator/value comparison.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0},{name:"op",type:"'=='|'!='|'>'|'<'|'>='|'<='|'contains'",required:!0},{name:"value",type:"any",required:!0}]},Sort:{description:"Sort an array by a field, ascending or descending.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0},{name:"direction",type:"'asc'|'desc'",required:!1}]},Round:{description:"Round a number to N decimals (default 0).",params:[{name:"value",type:"number",required:!0},{name:"decimals",type:"number",required:!1}]},Abs:{description:"Absolute value of a number.",params:[{name:"value",type:"number",required:!0}]},Floor:{description:"Round a number down to the nearest integer.",params:[{name:"value",type:"number",required:!0}]},Ceil:{description:"Round a number up to the nearest integer.",params:[{name:"value",type:"number",required:!0}]},Find:{description:"Find the first item matching a field/op/value comparator.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0},{name:"op",type:"'=='|'!='|'>'|'<'|'>='|'<='|'contains'",required:!0},{name:"value",type:"any",required:!0}]},GroupBy:{description:"Group items into `{groupKey: [items…]}` by a field value.",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!0}]},Slice:{description:"Slice an array by `[start, end)` — both indices optional.",params:[{name:"array",type:"any[]",required:!0},{name:"start",type:"number",required:!1},{name:"end",type:"number",required:!1}]},Unique:{description:"Deduplicate. With a `field`, dedupes by that field (first wins).",params:[{name:"array",type:"any[]",required:!0},{name:"field",type:"string",required:!1}]},Reverse:{description:"Return a reversed copy of the array (non-mutating).",params:[{name:"array",type:"any[]",required:!0}]},Range:{description:"Inclusive integer range. Third arg is the step (default 1 / -1).",params:[{name:"start",type:"number",required:!0},{name:"end",type:"number",required:!0},{name:"step",type:"number",required:!1}]},Repeat:{description:"Repeat a value N times. Useful for skeleton/placeholder grids.",params:[{name:"value",type:"any",required:!0},{name:"count",type:"number",required:!0}]},Pick:{description:'Keep only the listed keys from an object — `@Pick(obj, ["a","b"])`.',params:[{name:"object",type:"object",required:!0},{name:"keys",type:"string[]",required:!0}]},Format:{description:"Locale-aware number formatter. Modes: 'currency', 'percent', 'number'.",params:[{name:"value",type:"number",required:!0},{name:"mode",type:"'currency'|'percent'|'number'",required:!1},{name:"currencyOrLocale",type:"string",required:!1},{name:"locale",type:"string",required:!1}]},FormatDate:{description:"Format a date. Pattern tokens (MMM D, YYYY-MM-DD) or named: 'relative', 'date', 'time', 'datetime', 'iso'.",params:[{name:"value",type:"Date|number|string",required:!0},{name:"format",type:"string",required:!1}]},Now:{description:"Current moment as epoch ms — pair with `@FormatDate`.",params:[]},Today:{description:"Today's date at midnight, as an ISO string.",params:[]},AddDays:{description:"Shift a date by N days (negative N moves backward).",params:[{name:"date",type:"Date|number|string",required:!0},{name:"days",type:"number",required:!0}]},AddHours:{description:"Shift a date by N hours (negative N moves backward).",params:[{name:"date",type:"Date|number|string",required:!0},{name:"hours",type:"number",required:!0}]},DiffDays:{description:"Whole-day difference from start to end (end − start).",params:[{name:"start",type:"Date|number|string",required:!0},{name:"end",type:"Date|number|string",required:!0}]},StartOfWeek:{description:"Local Sunday 00:00:00 for the week containing the date.",params:[{name:"date",type:"Date|number|string",required:!0}]},EndOfMonth:{description:"Last moment of the calendar month containing the date.",params:[{name:"date",type:"Date|number|string",required:!0}]},Plural:{description:'Pluralisation: `@Plural(n, "order", "orders")` → "1 order" / "2 orders".',params:[{name:"count",type:"number",required:!0},{name:"singular",type:"string",required:!0},{name:"plural",type:"string",required:!1}]},Capitalize:{description:"Uppercase the first character.",params:[{name:"value",type:"string",required:!0}]},Lowercase:{description:"Lowercase every character.",params:[{name:"value",type:"string",required:!0}]},Uppercase:{description:"Uppercase every character.",params:[{name:"value",type:"string",required:!0}]},Titlecase:{description:"Capitalise the first letter of each word.",params:[{name:"value",type:"string",required:!0}]},Case:{description:'Convert casing — mode: "camel", "snake", "kebab", or "pascal".',params:[{name:"value",type:"string",required:!0},{name:"mode",type:"'camel'|'snake'|'kebab'|'pascal'",required:!0}]},Join:{description:'Join array values into a string (default separator ",").',params:[{name:"array",type:"any[]",required:!0},{name:"separator",type:"string",required:!1}]},Split:{description:'Split a string by a separator (default ",").',params:[{name:"value",type:"string",required:!0},{name:"separator",type:"string",required:!1}]},Trim:{description:"Trim leading and trailing whitespace.",params:[{name:"value",type:"string",required:!0}]},Replace:{description:"Replace all occurrences of search with replacement.",params:[{name:"value",type:"string",required:!0},{name:"search",type:"string",required:!0},{name:"replacement",type:"string",required:!1}]},Substring:{description:"Extract a substring — `start`, optional `end`.",params:[{name:"value",type:"string",required:!0},{name:"start",type:"number",required:!0},{name:"end",type:"number",required:!1}]},StartsWith:{description:"True when the string starts with the given prefix.",params:[{name:"value",type:"string",required:!0},{name:"prefix",type:"string",required:!0}]},EndsWith:{description:"True when the string ends with the given suffix.",params:[{name:"value",type:"string",required:!0},{name:"suffix",type:"string",required:!0}]},Contains:{description:"True when the string contains the given substring.",params:[{name:"value",type:"string",required:!0},{name:"needle",type:"string",required:!0}]},Match:{description:"Test a string against a RegExp pattern (invalid patterns return false).",params:[{name:"value",type:"string",required:!0},{name:"pattern",type:"string",required:!0}]},Clamp:{description:"Clamp a number into `[min, max]`.",params:[{name:"value",type:"number",required:!0},{name:"min",type:"number",required:!0},{name:"max",type:"number",required:!0}]},Pow:{description:"Raise a number to a power — `Math.pow(base, exp)`.",params:[{name:"base",type:"number",required:!0},{name:"exp",type:"number",required:!0}]},Sqrt:{description:"Square root of a number.",params:[{name:"value",type:"number",required:!0}]},Random:{description:"Pseudo-random number in [0, 1) — `Math.random()`.",params:[]},Log:{description:"Natural logarithm — `Math.log(value)`.",params:[{name:"value",type:"number",required:!0}]}},nd=[{name:"Each",category:"iteration",description:'Iterate over an array. The loop variable is scoped to the template. Supports destructuring: "{id, name}" binds those fields per row.',params:[{name:"array",type:"any[]",required:!0},{name:"varName",type:"string",required:!0},{name:"template",type:"Node",required:!0}]},{name:"If",category:"iteration",description:"Lazy conditional renderer — only the selected branch is evaluated. Useful when an unused branch would otherwise read missing loop variables.",params:[{name:"condition",type:"any",required:!0},{name:"trueBranch",type:"Node",required:!0},{name:"falseBranch",type:"Node",required:!1}]},{name:"Switch",category:"iteration",description:"Key-based branch selector. Stringifies `value` and renders the matching property of `cases` (or `default` when no key matches).",params:[{name:"value",type:"any",required:!0},{name:"cases",type:"{key: Node | string, ...}, i.e. {overview: Node, billing: 'Invoice', security: Node}",required:!0},{name:"default",type:"Node",required:!1}]}],od=t=>{const e=t.params.map(r=>r.required?r.name:`${r.name}?`);return`@${t.name}(${e.join(", ")})`},Wt=t=>({...t,signature:od(t)});function gt(){return[...Object.keys(At).map(e=>{const r=id[e];return Wt(r?{name:e,category:"data",...r}:{name:e,category:"data",description:`Data helper: @${e}`,params:[{name:"value",type:"any",required:!0}]})}),...nd.map(Wt)]}function ei(t){const e={};for(const r of t)e[r.name]=r;return e}const D="_app_";function Gt(t,e={}){return e.mode==="chat"?cd(t,e):ld(t,e)}function sd(t){return ft(t)}function ld(t,e){const r=(e.tools?.length??0)>0,a={toolCalls:e.toolCalls??r,bindings:e.bindings??e.toolCalls??r,inlineMode:e.inlineMode??!1,editMode:e.editMode??!1},i=[];i.push(ud(e.preamble)),i.push(dd()),i.push(pd()),a.bindings&&i.push(md()),i.push(gd()),i.push(fd()),i.push(hd()),a.toolCalls&&i.push(bd()),i.push(vd()),i.push(yd()),i.push(xd()),i.push(wd()),(a.toolCalls||a.bindings)&&i.push(kd()),i.push(Sd()),i.push(Cd()),i.push(Td()),i.push($d()),i.push(Nd()),i.push(Ad(t)),a.inlineMode&&i.push(Md()),a.editMode&&i.push(Pd()),e.tools&&e.tools.length>0&&i.push(Gd(e.tools)),e.toolExamples&&e.toolExamples.length>0&&i.push(Kt("Endpoint examples",e.toolExamples));const n=e.examples??Ld();return n.length>0&&i.push(Kt("Examples",n)),e.additionalRules&&e.additionalRules.length>0&&i.push(ti(e.additionalRules)),i.push(Id()),i.push(zd()),i.push(Rd()),i.join(`
23
23
 
24
24
  `).trim()+`
25
- `}function ld(t,e){const r=[];r.push(Ed(e.preamble)),r.push(_d()),r.push(jd(t)),r.push(Bd()),r.push(Dd()),r.push(Fd()),e.tools&&e.tools.length>0&&r.push(Od(e.tools));const a=e.examples??Ud();return a.length>0&&r.push(Wt("Examples",a)),e.additionalRules&&e.additionalRules.length>0&&r.push(ei(e.additionalRules)),r.push(qd()),r.push(Hd()),r.join(`
25
+ `}function cd(t,e){const r=[];r.push(_d(e.preamble)),r.push(jd()),r.push(Bd(t)),r.push(Dd()),r.push(Fd()),r.push(Od()),e.tools&&e.tools.length>0&&r.push(Ud(e.tools));const a=e.examples??qd();return a.length>0&&r.push(Kt("Examples",a)),e.additionalRules&&e.additionalRules.length>0&&r.push(ti(e.additionalRules)),r.push(Hd()),r.push(Vd()),r.join(`
26
26
 
27
27
  `).trim()+`
28
- `}function cd(t){return`${t?.trim()||"You are a full-stack UI engineer building **complete, working applications** in Aktion — a compact, declarative DSL for reactive, streaming-first user interfaces. Treat each prompt as a request to ship a real, production-quality product surface (dashboards, CRUD apps, multi-page websites, settings consoles, inboxes, admin panels, …). Never reply with a one-shot chat card; always produce a substantial, navigable app. Respond ONLY in Aktion — no prose, no JSON, no markdown, no HTML."}
28
+ `}function ud(t){return`${t?.trim()||"You are a full-stack UI engineer building **complete, working applications** in Aktion — a compact, declarative DSL for reactive, streaming-first user interfaces. Treat each prompt as a request to ship a real, production-quality product surface (dashboards, CRUD apps, multi-page websites, settings consoles, inboxes, admin panels, …). Never reply with a one-shot chat card; always produce a substantial, navigable app. Respond ONLY in Aktion — no prose, no JSON, no markdown, no HTML."}
29
29
 
30
- Every response MUST begin with \`${D} = ...\` on the very first line. Use a top-level container (\`${D} = AppShell(...)\` for full apps, \`${D} = Stack(...)\` for landing pages, etc.) or a user-declared component (\`${D} = App()\`). For multi-page apps wrap the main area in \`pages = _router_({ ... })\` and reference \`pages\` from \`${D}\`. Seed realistic mock data inline (5–20 plausible rows per dataset) when the host has no real backend. Wire every visible button to an \`action\`. Use \`$name = value\` for reactive state, \`http({ ... })\` for any data fetch, \`effect [ ...deps ] { … }\` for lifecycle work, \`_router_({ … })\` for navigation. The renderer drops invalid lines, so prefer correctness over verbosity.`}function ud(){return`## Mental model
30
+ Every response MUST begin with \`${D} = ...\` on the very first line. Use a top-level container (\`${D} = AppShell(...)\` for full apps, \`${D} = Stack(...)\` for landing pages, etc.) or a user-declared component (\`${D} = App()\`). For multi-page apps wrap the main area in \`pages = _router_({ ... })\` and reference \`pages\` from \`${D}\`. Seed realistic mock data inline (5–20 plausible rows per dataset) when the host has no real backend. Wire every visible button to an \`action\`. Use \`$name = value\` for reactive state, \`http({ ... })\` for any data fetch, \`effect [ ...deps ] { … }\` for lifecycle work, \`_router_({ … })\` for navigation. The renderer drops invalid lines, so prefer correctness over verbosity.`}function dd(){return`## Mental model
31
31
 
32
32
  Aktion is a streaming-first, declarative DSL. A program is a flat
33
33
  list of \`name = expression\` statements. The renderer evaluates them lazily,
@@ -59,7 +59,7 @@ Three declaration keywords are reserved at the top level:
59
59
 
60
60
  Everything else (\`http({...})\`, \`_router_({...})\`, \`Theme({...})\`,
61
61
  \`i18n({...})\`, \`Toast(...)\`, \`Stack(...)\`) is a regular function /
62
- component call.`}function dd(){return`## Syntax
62
+ component call.`}function pd(){return`## Syntax
63
63
 
64
64
  Source is line-oriented; **newline terminates a statement**. Never use
65
65
  semicolons or statement-level commas. \`{ … }\` braces open blocks (component
@@ -137,7 +137,7 @@ bodies. A lambda body has the same imperative surface as an \`action\` body
137
137
  Statements may **reference names defined later in the program**. The parser
138
138
  resolves them once the full stream lands. This is what makes streaming work:
139
139
  emit the shell (\`${D} = Stack([hero, body])\`) on the first line,
140
- then fill in \`hero\` and \`body\` later.`}function pd(){return'## Reactive State\n\nAktion has **one reactive atom kind**. Every reactive cell is declared\nand read with the same surface:\n\n```\n$count = 0\n$user = { name: "Ada", role: "Engineer" }\n$todos = []\n$theme = "dark"\n```\n\n### Sigil contract\n- `count` (no sigil) is a plain binding — NOT tracked, NOT reactive.\n- `$count` (with sigil) is a tracked atom — reading subscribes the\n surrounding component / effect; writing notifies subscribers.\n\n### Assignment rules\n- **Render position** (top-level bindings, component body output, prop values):\n assignment is forbidden. Use `$name = …` declarations to seed.\n- **Inside `action` / `effect` / lambda bodies**: `= += -= *= /= ??= ++ --`\n are allowed against any `$name` atom.\n- **Nested writes require whole-object replacement.** Direct\n `$user.name = "Alex"` is rejected — spread instead:\n `$user = { ...$user, name: "Alex" }`. Arrays follow the same rule:\n `$todos = [...$todos, item]`, `$todos = @Filter($todos, "id", "!=", id)`.\n\n### Component-scoped state\nA `$name = value` declared **inside** a `component` body is per-instance.\nTwo `<Counter/>` siblings each have their own `count`. Top-level\n`$name` declarations live for the lifetime of the response.\n\n### Computed values\nJust compute — every reference to a `$` atom inside an expression auto-tracks:\n\n```\n$cart = []\n$total = @Sum($cart.price) // re-derives when $cart changes\n$open = @Filter($todos, "done", "==", false)\n```\n\n### URL-synced state\nURL state lives on the router, not as a separate tier:\n- `_route_.path` — current path (read-only).\n- `_route_.params.id` — path parameter; reactive.\n- `_route_.query.tab` — query string; **writable** (assigning updates the URL).\n- `_route_.navigate("/path")` — imperative navigation; only valid inside\n `action` / `effect` bodies.'}function md(){return`## Components and lambdas
140
+ then fill in \`hero\` and \`body\` later.`}function md(){return'## Reactive State\n\nAktion has **one reactive atom kind**. Every reactive cell is declared\nand read with the same surface:\n\n```\n$count = 0\n$user = { name: "Ada", role: "Engineer" }\n$todos = []\n$theme = "dark"\n```\n\n### Sigil contract\n- `count` (no sigil) is a plain binding — NOT tracked, NOT reactive.\n- `$count` (with sigil) is a tracked atom — reading subscribes the\n surrounding component / effect; writing notifies subscribers.\n\n### Assignment rules\n- **Render position** (top-level bindings, component body output, prop values):\n assignment is forbidden. Use `$name = …` declarations to seed.\n- **Inside `action` / `effect` / lambda bodies**: `= += -= *= /= ??= ++ --`\n are allowed against any `$name` atom.\n- **Nested writes require whole-object replacement.** Direct\n `$user.name = "Alex"` is rejected — spread instead:\n `$user = { ...$user, name: "Alex" }`. Arrays follow the same rule:\n `$todos = [...$todos, item]`, `$todos = @Filter($todos, "id", "!=", id)`.\n\n### Component-scoped state\nA `$name = value` declared **inside** a `component` body is per-instance.\nTwo `<Counter/>` siblings each have their own `count`. Top-level\n`$name` declarations live for the lifetime of the response.\n\n### Computed values\nJust compute — every reference to a `$` atom inside an expression auto-tracks:\n\n```\n$cart = []\n$total = @Sum($cart.price) // re-derives when $cart changes\n$open = @Filter($todos, "done", "==", false)\n```\n\n### URL-synced state\nURL state lives on the router, not as a separate tier:\n- `_route_.path` — current path (read-only).\n- `_route_.params.id` — path parameter; reactive.\n- `_route_.query.tab` — query string; **writable** (assigning updates the URL).\n- `_route_.navigate("/path")` — imperative navigation; only valid inside\n `action` / `effect` bodies.'}function gd(){return`## Components and lambdas
141
141
 
142
142
  ### Component declarations
143
143
  \`\`\`
@@ -174,7 +174,7 @@ Use a lambda binding for one-off helpers that don't need their own component:
174
174
  priorityTone = (p) => match p { "high": "danger" "med": "warning" default: "muted" }
175
175
  rowFor = (item) => Stack([Badge(item.label, tone: priorityTone(item.priority)), Text(item.title)])
176
176
  list = for item in $items { rowFor(item) }
177
- \`\`\``}function gd(){return'## Actions — callable side effects\n\nAn `action` is a callable block of imperative statements. Declare at the\ntop level (or inside a component body); invoke from any event-handler prop\n(`onClick`, `onChange`, `onSubmit`) or as an expression.\n\n```\naction save(item) {\n $items = [...$items, item]\n $save = http({ url: "/api/save", method: "POST", body: { item: item } })\n emit "saved" { id: item.id }\n}\n\nsubmitBtn = Button("Save", onClick: save)\n```\n\n### Body grammar\nInside an action body the imperative surface is small:\n- Assignments: `$x = newValue`, `$x += 1`, `$x = { ...$x, field: v }`.\n- `http({ ... })` — fire a request; the result is a reactive resource bag.\n- `emit "event-name" { detail }` — dispatch a `CustomEvent` on the host element.\n- `_route_.navigate("/path")` — programmatic navigation.\n- Statement-form `if` / `match` / `for` — same keywords as the expression\n forms (covered below).\n- `return` — optionally yields a value to the caller.\n- `js{ /* opaque JS */ }` — escape hatch for browser APIs not exposed\n natively (see § JS escape hatch).\n\n### Optional `return`\nActions MAY include a `return` statement. When omitted the action runs for\nits side effects and yields `undefined`. When present the result is\nobservable from `$x = myAction(...)` expressions:\n\n```\naction greet(name) {\n return "Hello, " + name\n}\n$hello = greet("Ada") // re-runs whenever the action call\'s args change\n```\n\n### Inline lambdas — the short form\nFor trivial handlers, skip the `action` declaration entirely:\n\n```\nincBtn = Button("+", onClick: () => $count = $count + 1)\nresetBtn = Button("Reset", onClick: () => { $count = 0 $message = "" })\ncopyBtn = Button("Copy", onClick: () => { js{ navigator.clipboard.writeText("hi") } })\n```'}function fd(){return`## Effects — Declarative side effects
177
+ \`\`\``}function fd(){return'## Actions — callable side effects\n\nAn `action` is a callable block of imperative statements. Declare at the\ntop level (or inside a component body); invoke from any event-handler prop\n(`onClick`, `onChange`, `onSubmit`) or as an expression.\n\n```\naction save(item) {\n $items = [...$items, item]\n $save = http({ url: "/api/save", method: "POST", body: { item: item } })\n emit "saved" { id: item.id }\n}\n\nsubmitBtn = Button("Save", onClick: save)\n```\n\n### Body grammar\nInside an action body the imperative surface is small:\n- Assignments: `$x = newValue`, `$x += 1`, `$x = { ...$x, field: v }`.\n- `http({ ... })` — fire a request; the result is a reactive resource bag.\n- `emit "event-name" { detail }` — dispatch a `CustomEvent` on the host element.\n- `_route_.navigate("/path")` — programmatic navigation.\n- Statement-form `if` / `match` / `for` — same keywords as the expression\n forms (covered below).\n- `return` — optionally yields a value to the caller.\n- `js{ /* opaque JS */ }` — escape hatch for browser APIs not exposed\n natively (see § JS escape hatch).\n\n### Optional `return`\nActions MAY include a `return` statement. When omitted the action runs for\nits side effects and yields `undefined`. When present the result is\nobservable from `$x = myAction(...)` expressions:\n\n```\naction greet(name) {\n return "Hello, " + name\n}\n$hello = greet("Ada") // re-runs whenever the action call\'s args change\n```\n\n### Inline lambdas — the short form\nFor trivial handlers, skip the `action` declaration entirely:\n\n```\nincBtn = Button("+", onClick: () => $count = $count + 1)\nresetBtn = Button("Reset", onClick: () => { $count = 0 $message = "" })\ncopyBtn = Button("Copy", onClick: () => { js{ navigator.clipboard.writeText("hi") } })\n```'}function hd(){return`## Effects — Declarative side effects
178
178
 
179
179
  \`effect\` blocks attach side effects to a component or top-level binding.
180
180
  They are **anonymous** — there is no name, no \`on\` keyword. Every
@@ -200,6 +200,48 @@ brackets doesn't matter.
200
200
  \`effect { ... }\` (no brackets) is equivalent to \`effect [on:mount] { ... }\` —
201
201
  both run the body once on mount.
202
202
 
203
+ ### Scope — top-level vs. component-local
204
+ An effect can live at the program top level OR inside a
205
+ \`component Name() { … }\` body. The syntax is identical; only the
206
+ lifecycle differs:
207
+
208
+ - **Top-level** — mounted once when the program parses, torn down on
209
+ \`setResponse\` / \`clear()\`. Use for global concerns (analytics,
210
+ app-wide shortcuts, hydration of shared atoms).
211
+ - **Component-local** — mounted once per component instance on its
212
+ first render, torn down when the instance disappears from the tree.
213
+ Each instance gets its own timers, watched-atom subscriptions, and
214
+ \`cleanup(fn)\` registrations. Use for per-instance work (per-row
215
+ polling, modal focus management, observers attached to a widget).
216
+
217
+ \`\`\`
218
+ _app_ = App()
219
+ $value = 10
220
+
221
+ # Top-level — one shared interval for the whole program.
222
+ effect [on:every(1000)] {
223
+ $value = $value + 1
224
+ }
225
+
226
+ component App() {
227
+ return Box([Text("Value: " + $value)])
228
+ }
229
+ \`\`\`
230
+
231
+ \`\`\`
232
+ _app_ = App()
233
+ $value = 10
234
+
235
+ component App() {
236
+ # Component-local — interval starts on first render and is cleared
237
+ # automatically when the App instance leaves the tree.
238
+ effect [on:every(1000)] {
239
+ $value = $value + 1
240
+ }
241
+ return Box([Text("Value: " + $value)])
242
+ }
243
+ \`\`\`
244
+
203
245
  ### Examples
204
246
 
205
247
  \`\`\`
@@ -228,7 +270,7 @@ effect [on:mount] {
228
270
 
229
271
  ### Cleanup
230
272
  Use \`cleanup(fn)\` to register teardown for intervals, listeners, observers.
231
- Cleanup fires before the next re-run AND on unmount.`}function hd(){return`## Data — \`http({...})\`
273
+ Cleanup fires before the next re-run AND on unmount.`}function bd(){return`## Data — \`http({...})\`
232
274
 
233
275
  There is exactly one HTTP primitive: the \`http({ ... })\` function. Pass any
234
276
  \`fetch\`-compatible option (\`url\`, \`method\`, \`headers\`, \`body\`,
@@ -290,7 +332,7 @@ $http = Http({
290
332
  timeout: 10000,
291
333
  retry: { count: 2, backoff: "exponential" }
292
334
  })
293
- \`\`\``}function bd(){return'## Control flow\n\nAll three control-flow keywords are **expressions** — they yield a node (or\narray of nodes) that can be assigned, passed as a prop, or returned from a\ncomponent / action body.\n\n### `if` / `else`\n```\nbanner = if $hasError { Banner("Something went wrong", tone: "danger") } else { null }\nactive = if $tab == "billing" { billingPanel } else { overviewPanel }\n```\nA trailing `else` is optional — without it an unmatched `if` evaluates to\n`null` (renders nothing).\n\n### `match`\n```\npanel = match $stage {\n "draft": DraftView()\n "review": ReviewView()\n "shipped": ShippedView()\n default: EmptyState("Pick a stage")\n}\n```\n- Arms use `: value` like object properties (the arrow form `->` is\n not valid).\n- `default:` is the wildcard.\n- Arms can return arbitrary expressions, not just strings.\n\n### `for`\n```\nrows = for item in $todos { TaskRow(item) }\nrowsWithIndex = for (item, idx) in $todos { TaskRow(item, index: idx) }\n```\n`for` produces an array of nodes — assign it and reference the binding\nfrom a container (`Stack(rows)`, `Table([Col("Task", rows)])`). The loop\nvariable is **block-scoped**, so a stale closure can never see the wrong row.\n\n### Statement form inside action / effect bodies\nThe same three keywords also work as statements:\n```\naction submit(payload) {\n if !payload.email { return }\n for tag in payload.tags { $tags = [...$tags, tag] }\n match payload.kind {\n "draft": { $drafts = [...$drafts, payload] }\n default: { $records = [...$records, payload] }\n }\n}\n```'}function vd(){return`## Routing — \`_router_({ … })\`
335
+ \`\`\``}function vd(){return'## Control flow\n\nAll three control-flow keywords are **expressions** — they yield a node (or\narray of nodes) that can be assigned, passed as a prop, or returned from a\ncomponent / action body.\n\n### `if` / `else`\n```\nbanner = if $hasError { Banner("Something went wrong", tone: "danger") } else { null }\nactive = if $tab == "billing" { billingPanel } else { overviewPanel }\n```\nA trailing `else` is optional — without it an unmatched `if` evaluates to\n`null` (renders nothing).\n\n### `match`\n```\npanel = match $stage {\n "draft": DraftView()\n "review": ReviewView()\n "shipped": ShippedView()\n default: EmptyState("Pick a stage")\n}\n```\n- Arms use `: value` like object properties (the arrow form `->` is\n not valid).\n- `default:` is the wildcard.\n- Arms can return arbitrary expressions, not just strings.\n\n### `for`\n```\nrows = for item in $todos { TaskRow(item) }\nrowsWithIndex = for (item, idx) in $todos { TaskRow(item, index: idx) }\n```\n`for` produces an array of nodes — assign it and reference the binding\nfrom a container (`Stack(rows)`, `Table([Col("Task", rows)])`). The loop\nvariable is **block-scoped**, so a stale closure can never see the wrong row.\n\n### Statement form inside action / effect bodies\nThe same three keywords also work as statements:\n```\naction submit(payload) {\n if !payload.email { return }\n for tag in payload.tags { $tags = [...$tags, tag] }\n match payload.kind {\n "draft": { $drafts = [...$drafts, payload] }\n default: { $records = [...$records, payload] }\n }\n}\n```'}function yd(){return`## Routing — \`_router_({ … })\`
294
336
 
295
337
  The router is a plain function call. It returns the matched arm's evaluated
296
338
  value — assign the result to any binding and reference that binding inside
@@ -338,13 +380,13 @@ ${D} = AppShell(MainSidebar(), pages, TopBar())
338
380
  - Forgetting the \`default:\` arm. Without it, unknown paths render \`null\`
339
381
  and the outlet collapses.
340
382
  - Using \`->\` instead of \`:\` for arm bodies. Inside \`_router_({…})\` the
341
- arms are ordinary object properties — separate with \`:\` and commas.`}function yd(){return'## Two-way binding — `bind:`\n\n`bind:value: $name` desugars to `value: $name, onValueChange: (v) => $name = v`.\nThe right-hand side must be a state ref (`$x`), member access\n(`$user.name`), or a form field — never a computed expression.\n\n```\n$search = ""\nbar = SearchBar("q", placeholder: "Search…", bind:value: $search)\nlist = for row in @Filter($rows, "title", "contains", $search) { ListItem(row.title) }\n\n$tags = []\nchips = TagInput("tags", bind:value: $tags)\n```\n\n`bind:` works on any form control whose spec declares a primary value prop:\n`Input`, `TextArea`, `Select`, `Combobox`, `MultiSelect`,\n`Checkbox`, `CheckBoxGroup`, `Switch`, `ToggleGroup`, `Slider`,\n`NumberInput`, `DatePicker`, `DateRangePicker`, `TimePicker`,\n`DateTimePicker`, `SearchBar`, `PinInput`, `PasswordInput`,\n`TagInput`, `MentionInput`, `MaskedInput`, `RichTextEditor`,\n`CodeEditor`, `ColorPicker`, `Rating` (when `interactive: true`),\n`Pagination` (binds `page`).'}function xd(){return'## JS escape hatch — `js{ … }`\n\n`js{ /* opaque JS body */ }` runs raw JavaScript inside an `effect`,\n`action`, or lambda body. Use sparingly — every other surface is preferred —\nbut it is always available for browser APIs not exposed natively (clipboard,\nkeyboard listeners, IntersectionObserver, audio, custom DOM work).\n\nThe body receives a single `ctx` bridge:\n- `ctx.host` — the `<aktion-app>` host element (for `dispatchEvent`).\n- `ctx.state` — `{ get(name), set(name, value) }` for reactive atoms.\n- `ctx.cleanup(fn)` — register teardown (same semantics as `effect` cleanup).\n- `ctx.tools` — host-registered endpoint catalog (rarely needed; prefer `http()`).\n- `ctx.args` — when invoked from an `action` or lambda, the call\'s arguments.\n\n```\neffect [on:mount] {\n js{\n const id = setInterval(() => ctx.state.set("now", Date.now()), 1000)\n ctx.cleanup(() => clearInterval(id))\n }\n}\n\naction copyShareLink() {\n js{ navigator.clipboard.writeText(window.location.href) }\n emit "assistant-message" { message: "Link copied" }\n}\n```'}function wd(){return`## Built-in \`@\`-functions
383
+ arms are ordinary object properties — separate with \`:\` and commas.`}function xd(){return'## Two-way binding — `bind:`\n\n`bind:value: $name` desugars to `value: $name, onValueChange: (v) => $name = v`.\nThe right-hand side must be a state ref (`$x`), member access\n(`$user.name`), or a form field — never a computed expression.\n\n```\n$search = ""\nbar = SearchBar("q", placeholder: "Search…", bind:value: $search)\nlist = for row in @Filter($rows, "title", "contains", $search) { ListItem(row.title) }\n\n$tags = []\nchips = TagInput("tags", bind:value: $tags)\n```\n\n`bind:` works on any form control whose spec declares a primary value prop:\n`Input`, `TextArea`, `Select`, `Combobox`, `MultiSelect`,\n`Checkbox`, `CheckBoxGroup`, `Switch`, `ToggleGroup`, `Slider`,\n`NumberInput`, `DatePicker`, `DateRangePicker`, `TimePicker`,\n`DateTimePicker`, `SearchBar`, `PinInput`, `PasswordInput`,\n`TagInput`, `MentionInput`, `MaskedInput`, `RichTextEditor`,\n`CodeEditor`, `ColorPicker`, `Rating` (when `interactive: true`),\n`Pagination` (binds `page`).'}function wd(){return'## JS escape hatch — `js{ … }`\n\n`js{ /* opaque JS body */ }` runs raw JavaScript inside an `effect`,\n`action`, or lambda body. Use sparingly — every other surface is preferred —\nbut it is always available for browser APIs not exposed natively (clipboard,\nkeyboard listeners, IntersectionObserver, audio, custom DOM work).\n\nThe body receives a single `ctx` bridge:\n- `ctx.host` — the `<aktion-app>` host element (for `dispatchEvent`).\n- `ctx.state` — `{ get(name), set(name, value) }` for reactive atoms.\n- `ctx.cleanup(fn)` — register teardown (same semantics as `effect` cleanup).\n- `ctx.tools` — host-registered endpoint catalog (rarely needed; prefer `http()`).\n- `ctx.args` — when invoked from an `action` or lambda, the call\'s arguments.\n\n```\neffect [on:mount] {\n js{\n const id = setInterval(() => ctx.state.set("now", Date.now()), 1000)\n ctx.cleanup(() => clearInterval(id))\n }\n}\n\naction copyShareLink() {\n js{ navigator.clipboard.writeText(window.location.href) }\n emit "assistant-message" { message: "Link copied" }\n}\n```'}function kd(){return`## Built-in \`@\`-functions
342
384
 
343
385
  All built-ins use the \`@\` prefix and may appear anywhere in an expression.
344
386
  They are **pure** — no side effects, no I/O. Use them for data shaping,
345
387
  formatting, and inline iteration.
346
388
 
347
- ${Vd(gt())}
389
+ ${Wd(gt())}
348
390
 
349
391
  ### Control flow — expression form
350
392
  Use the expression-form \`if\` / \`match\` / \`for\` covered above —
@@ -360,7 +402,7 @@ panel = match $stage { "done": Done() "ready": Ready() default: Pending() }
360
402
  \`Grid(items, columns: {sm: 1, md: 2, lg: 4}, gap: "l")\` — 1 column on mobile,
361
403
  2 on tablet, 4 on desktop. \`Stack(children, direction: {sm: "column", md: "row"})\`
362
404
  — stack on mobile, row on desktop. Both \`columns\` and \`gap\` accept either
363
- a single value or a responsive map.`}function kd(){return'## Standard helper components\n\nAktion keeps the language core small by exposing "frameworky"\nfeatures as library components rather than language keywords:\n\n| Component | Purpose |\n|---|---|\n| `Async(resource, loading:, error:, empty:, data:)` | Branch on an `http({...})` resource\'s state. |\n| `Show(when, fallback?, children)` | Sugar over `if when { children } else { fallback }`. |\n| `Portal(children, target?)` | Render children outside the parent subtree. |\n| `Redirect(path)` | Navigate to `path` and unmount the rest of the subtree. |\n| `Lazy(loader, fallback?, children)` | Defer rendering children until `loader` resolves. |\n| `ErrorBoundary(children, fallback?, onError?)` | Catch render errors thrown by descendants. |\n| `VirtualList(items, key:, render:)` | Virtualised list — preferred for >100 rows. |'}function Sd(){return`## Built-in globals
405
+ a single value or a responsive map.`}function Sd(){return'## Standard helper components\n\nAktion keeps the language core small by exposing "frameworky"\nfeatures as library components rather than language keywords:\n\n| Component | Purpose |\n|---|---|\n| `Async(resource, loading:, error:, empty:, data:)` | Branch on an `http({...})` resource\'s state. |\n| `Show(when, fallback?, children)` | Sugar over `if when { children } else { fallback }`. |\n| `Portal(children, target?)` | Render children outside the parent subtree. |\n| `Redirect(path)` | Navigate to `path` and unmount the rest of the subtree. |\n| `Lazy(loader, fallback?, children)` | Defer rendering children until `loader` resolves. |\n| `ErrorBoundary(children, fallback?, onError?)` | Catch render errors thrown by descendants. |\n| `VirtualList(items, key:, render:)` | Virtualised list — preferred for >100 rows. |'}function Cd(){return`## Built-in globals
364
406
 
365
407
  Two namespace globals are always in scope — no import, no declaration.
366
408
  Invoke them through the standard \`obj.method(args)\` syntax. Named-arg
@@ -393,7 +435,7 @@ console.error("Failed", $error)
393
435
  console.warn("Deprecated path")
394
436
  console.info("Route changed", _route_.path)
395
437
  console.debug({ days: $days, count: $count })
396
- \`\`\``}function Cd(){return'## Internationalisation\n\n```\n$locale = "en"\n$bundle = http({ url: "/i18n/" + $locale + ".json", method: "GET" })\n$i18n = i18n({\n locale: $locale,\n messages: $bundle.data ?? {},\n fallback: "en"\n})\n\nText(t("orders.title")) // "Orders"\nText(t("orders.greeting", { name: $userName })) // "Welcome back, Alex"\n```\n\n- `t(key, vars?)` looks up the translation by dot-pathed key with\n `${name}` interpolation.\n- `Locale()` returns the active locale tag.\n- Formatting builtins (`@Format`, `@FormatDate`) consult `Locale()`\n automatically.'}function Td(){return`## In-script theming
438
+ \`\`\``}function Td(){return'## Internationalisation\n\n```\n$locale = "en"\n$bundle = http({ url: "/i18n/" + $locale + ".json", method: "GET" })\n$i18n = i18n({\n locale: $locale,\n messages: $bundle.data ?? {},\n fallback: "en"\n})\n\nText(t("orders.title")) // "Orders"\nText(t("orders.greeting", { name: $userName })) // "Welcome back, Alex"\n```\n\n- `t(key, vars?)` looks up the translation by dot-pathed key with\n `${name}` interpolation.\n- `Locale()` returns the active locale tag.\n- Formatting builtins (`@Format`, `@FormatDate`) consult `Locale()`\n automatically.'}function $d(){return`## In-script theming
397
439
 
398
440
  Assign a \`Theme({ … })\` call to a top-level binding named \`theme\` (the
399
441
  runtime looks for that exact name) **before** defining \`${D}\`. The
@@ -415,16 +457,16 @@ ${D} = AppShell(...)
415
457
 
416
458
  Top-level token groups: \`colors\`, \`radius\`, \`font\`, \`motion\`,
417
459
  \`elevation\`. Unknown keys inside a group are silently ignored, so typos
418
- fail silent — verify token names against the \`Themes\` reference.`}function Nd(){return'## Icons (Font Awesome)\n\nIcon-typed props accept a Font Awesome name as a string. The host element\nauto-loads the Font Awesome stylesheet — no setup needed.\n\n- Format: `"name"` (defaults to the solid set), e.g. `"house"`,\n `"chart-line"`, `"star"`, `"circle-check"`.\n- Variants: prefix with `"regular:name"` (outline set) or `"brands:name"`\n (brand logos).\n- **Never emit emoji characters in `icon` props.**\n- Use the `Icon(name, variant?, size?)` component to render an icon inline\n anywhere a Node is expected.'}function $d(t){const e=t.componentGroups??[{name:"Components",components:t.components.map(s=>s.name)}],r=new Map(t.components.map(s=>[s.name,s])),a=[];a.push("## Component library"),a.push("Use only these components. Each signature lists props in declaration order; optional props end with `?`. The prop tagged `(positional)` is the canonical positional slot — pass it bare; every other prop is best supplied as a named argument (`prop: value`)."),a.push("");for(const s of e){a.push(`### ${s.name}`);for(const l of s.components){const c=r.get(l);c&&a.push(ft(c))}if(s.notes&&s.notes.length>0){a.push("");for(const l of s.notes)a.push(l)}a.push("")}const i=new Set(e.flatMap(s=>s.components)),n=t.components.filter(s=>!i.has(s.name));if(n.length>0){a.push("### Other");for(const s of n)a.push(ft(s))}return a.join(`
419
- `).trim()}function Ad(){return`## Inline mode
460
+ fail silent — verify token names against the \`Themes\` reference.`}function Nd(){return'## Icons (Font Awesome)\n\nIcon-typed props accept a Font Awesome name as a string. The host element\nauto-loads the Font Awesome stylesheet — no setup needed.\n\n- Format: `"name"` (defaults to the solid set), e.g. `"house"`,\n `"chart-line"`, `"star"`, `"circle-check"`.\n- Variants: prefix with `"regular:name"` (outline set) or `"brands:name"`\n (brand logos).\n- **Never emit emoji characters in `icon` props.**\n- Use the `Icon(name, variant?, size?)` component to render an icon inline\n anywhere a Node is expected.'}function Ad(t){const e=t.componentGroups??[{name:"Components",components:t.components.map(s=>s.name)}],r=new Map(t.components.map(s=>[s.name,s])),a=[];a.push("## Component library"),a.push("Use only these components. Each signature lists props in declaration order; optional props end with `?`. The prop tagged `(positional)` is the canonical positional slot — pass it bare; every other prop is best supplied as a named argument (`prop: value`)."),a.push("");for(const s of e){a.push(`### ${s.name}`);for(const l of s.components){const c=r.get(l);c&&a.push(ft(c))}if(s.notes&&s.notes.length>0){a.push("");for(const l of s.notes)a.push(l)}a.push("")}const i=new Set(e.flatMap(s=>s.components)),n=t.components.filter(s=>!i.has(s.name));if(n.length>0){a.push("### Other");for(const s of n)a.push(ft(s))}return a.join(`
461
+ `).trim()}function Md(){return`## Inline mode
420
462
 
421
463
  You may answer questions in plain text when appropriate. When you do, wrap
422
464
  any UI you produce in a fenced \`\`\`aktion block. Otherwise
423
- output Aktion directly with no surrounding prose.`}function Md(){return`## Edit mode
465
+ output Aktion directly with no surrounding prose.`}function Pd(){return`## Edit mode
424
466
 
425
467
  When the user asks for an incremental change to a prior response, output
426
468
  ONLY the statements that need to change (additions, replacements, removals).
427
- Do NOT re-emit the whole UI. To remove a statement, write \`name = null\`.`}function Pd(){return`## Hoisting & streaming (CRITICAL)
469
+ Do NOT re-emit the whole UI. To remove a statement, write \`name = null\`.`}function Id(){return`## Hoisting & streaming (CRITICAL)
428
470
 
429
471
  Aktion supports hoisting: a reference can be used BEFORE it is
430
472
  defined. The renderer re-parses the program on every streamed chunk and
@@ -444,7 +486,7 @@ response renders progressively without flashing errors.
444
486
  - Never split a single statement across multiple lines unless it sits inside
445
487
  an unmatched bracket (\`[\`, \`(\`, \`{\`).
446
488
  - Do not introduce trailing commas, dangling operators, or open brackets you
447
- don't close on the same line.`}function Id(){return`## Output rules
489
+ don't close on the same line.`}function zd(){return`## Output rules
448
490
 
449
491
  - **Build a complete application.** Reply with a substantive, navigable
450
492
  product surface — page headers, sidebars, multiple pages, data views,
@@ -485,7 +527,7 @@ response renders progressively without flashing errors.
485
527
  - Never declare a state slot named \`route\` yourself. The router exposes
486
528
  its reactive surface through the reserved \`_route_\` handle — read
487
529
  \`_route_.path\` / \`_route_.params\` and call
488
- \`_route_.navigate("/path")\` to navigate.`}function zd(){return`## Final verification
530
+ \`_route_.navigate("/path")\` to navigate.`}function Rd(){return`## Final verification
489
531
 
490
532
  Before finishing, walk your output and verify:
491
533
  1. \`${D} = ...\` is the FIRST line.
@@ -501,7 +543,7 @@ Before finishing, walk your output and verify:
501
543
  8. HTTP uses \`http({ url, method, ... })\`; the reactive bag exposes
502
544
  \`.data\` / \`.error\` / \`.loading\` / \`.status\` / \`.refetch()\` / \`.cancel()\`.
503
545
  9. Router and \`match\` arms use \`:\` (not \`->\`) and \`default\` (not
504
- \`_\`) as the wildcard.`}function Rd(){return[`# Tasks dashboard backed by http()
546
+ \`_\`) as the wildcard.`}function Ld(){return[`# Tasks dashboard backed by http()
505
547
  $tasks = http({ url: "/api/tasks", method: "GET" })
506
548
 
507
549
  action toggle(task) {
@@ -606,7 +648,7 @@ resultCard = if $sent {
606
648
  Card([Callout("success", "Message sent", description: \`Thanks \${$name}, we'll be in touch at \${$email}.\`, icon: "envelope-circle-check")])
607
649
  } else { null }
608
650
 
609
- ${D} = Stack([formCard, resultCard], direction: "column", gap: "l")`]}const Ld=["Stack","StackItem","Grid","GridItem","Box","Container","Spacer","Card","CardHeader","CardFooter","Separator","Tabs","TabItem","Accordion","AccordionItem","Steps","AspectRatio","Text","Markdown","Quote","Callout","CodeBlock","Image","Link","Badge","BadgeList","Icon","Kbd","Spinner","Skeleton","Table","Col","List","ListItem","StatCard","Stats","Sparkline","Tile","Progress","ProgressRing","DescriptionList","DescriptionItem","StatusDot","Tree","TreeNode","BarChart","LineChart","PieChart","RadarChart","ScatterChart","Histogram","Heatmap","Gauge","Series","Avatar","AvatarGroup","PersonChip","Rating","ChatBubble","Banner","Notification","Hero","PageHeader","SectionHeader","EmptyState","Timeline","TimelineItem","ActivityLog","FeatureGrid","FeatureItem","Testimonial","ProfileCard","Comment","MediaCard","LoadingState","ErrorState","SuccessState","DiffViewer","JsonTree","SectionBlock","ListBlock","FollowUpBlock","FollowUpItem"];function Ed(t){return`${t?.trim()||"You are an AI assistant that responds using Aktion — a compact declarative language whose output is rendered as a rich, read-only UI surface. Your entire response must be valid Aktion, with no markdown, no commentary, no JSON."}
651
+ ${D} = Stack([formCard, resultCard], direction: "column", gap: "l")`]}const Ed=["Stack","StackItem","Grid","GridItem","Box","Container","Spacer","Card","CardHeader","CardFooter","Separator","Tabs","TabItem","Accordion","AccordionItem","Steps","AspectRatio","Text","Markdown","Quote","Callout","CodeBlock","Image","Link","Badge","BadgeList","Icon","Kbd","Spinner","Skeleton","Table","Col","List","ListItem","StatCard","Stats","Sparkline","Tile","Progress","ProgressRing","DescriptionList","DescriptionItem","StatusDot","Tree","TreeNode","BarChart","LineChart","PieChart","RadarChart","ScatterChart","Histogram","Heatmap","Gauge","Series","Avatar","AvatarGroup","PersonChip","Rating","ChatBubble","Banner","Notification","Hero","PageHeader","SectionHeader","EmptyState","Timeline","TimelineItem","ActivityLog","FeatureGrid","FeatureItem","Testimonial","ProfileCard","Comment","MediaCard","LoadingState","ErrorState","SuccessState","DiffViewer","JsonTree","SectionBlock","ListBlock","FollowUpBlock","FollowUpItem"];function _d(t){return`${t?.trim()||"You are an AI assistant that responds using Aktion — a compact declarative language whose output is rendered as a rich, read-only UI surface. Your entire response must be valid Aktion, with no markdown, no commentary, no JSON."}
610
652
  Every response MUST start with \`${D} = ...\` on the very first line.
611
653
 
612
654
  You are operating in **read-only UI mode**. Use ONLY the layout, content,
@@ -623,7 +665,7 @@ mode and will not function here:
623
665
  tooltips, dropdown menus, command palettes, context menus).
624
666
 
625
667
  The single exception is \`FollowUpBlock\` — it is a read-only block of
626
- suggested follow-up prompts which the host renders as plain buttons.`}function _d(){return`## Syntax (read-only subset)
668
+ suggested follow-up prompts which the host renders as plain buttons.`}function jd(){return`## Syntax (read-only subset)
627
669
 
628
670
  A program is a flat list of \`name = expression\` statements terminated by
629
671
  newlines. \`${D}\` is the entry point — every program MUST begin
@@ -698,9 +740,9 @@ rows = [
698
740
 
699
741
  Always declare \`${D}\` FIRST. Then container/composition statements
700
742
  (\`heroCard\`, \`statsRow\`, …). Then leaf data arrays last. This produces a
701
- clean top-down reveal as the response streams in.`}function jd(t){const e=t.componentGroups??[{name:"Components",components:t.components.map(i=>i.name)}],r=new Map(t.components.map(i=>[i.name,i])),a=["## Component library (read-only)","Use only these components. Each signature lists props in declaration order; optional props end with `?`. Pass props positionally in order, or as `prop: value` named arguments for clarity."];for(const i of e){const n=i.components.filter(s=>Ld.includes(s));if(n.length!==0){a.push(`
743
+ clean top-down reveal as the response streams in.`}function Bd(t){const e=t.componentGroups??[{name:"Components",components:t.components.map(i=>i.name)}],r=new Map(t.components.map(i=>[i.name,i])),a=["## Component library (read-only)","Use only these components. Each signature lists props in declaration order; optional props end with `?`. Pass props positionally in order, or as `prop: value` named arguments for clarity."];for(const i of e){const n=i.components.filter(s=>Ed.includes(s));if(n.length!==0){a.push(`
702
744
  ### ${i.name}`);for(const s of n){const l=r.get(s);l&&a.push(ft(l))}}}return a.join(`
703
- `)}function Bd(){return'## Icons (Font Awesome)\n\nIcon-typed props (`icon`, `avatarSrc`, etc.) expect a Font Awesome name\nas a string — no `fa-` prefix, no emoji characters.\n\n- Format: `"name"` (defaults to the solid set), e.g. `"house"`,\n `"chart-line"`, `"star"`, `"circle-check"`.\n- Variants: prefix with `"regular:name"` (outline set) or\n `"brands:name"` (brand logos).\n- Render an icon inline anywhere a Node is expected with\n `Icon(name, variant?, size?)`.'}function Dd(){const t=gt(),e=t.filter(n=>n.category==="data"),r=t.filter(n=>n.category==="iteration"),a=e.map(ht).join(`
745
+ `)}function Dd(){return'## Icons (Font Awesome)\n\nIcon-typed props (`icon`, `avatarSrc`, etc.) expect a Font Awesome name\nas a string — no `fa-` prefix, no emoji characters.\n\n- Format: `"name"` (defaults to the solid set), e.g. `"house"`,\n `"chart-line"`, `"star"`, `"circle-check"`.\n- Variants: prefix with `"regular:name"` (outline set) or\n `"brands:name"` (brand logos).\n- Render an icon inline anywhere a Node is expected with\n `Icon(name, variant?, size?)`.'}function Fd(){const t=gt(),e=t.filter(n=>n.category==="data"),r=t.filter(n=>n.category==="iteration"),a=e.map(ht).join(`
704
746
  `),i=r.map(ht).join(`
705
747
  `);return`## Built-in \`@\`-functions
706
748
 
@@ -715,7 +757,7 @@ ${a}
715
757
  ${i}
716
758
 
717
759
  Template literals (\`backticks with \${expr}\`) compose naturally with these
718
- helpers — \`\`\`Found \${@Count(rows)} \${@Plural(@Count(rows), "result", "results")} (\${@Format(@Sum(rows.amount), "currency", "USD")} total)\`\`\``}function Fd(){return`## Hoisting & streaming (CRITICAL)
760
+ helpers — \`\`\`Found \${@Count(rows)} \${@Plural(@Count(rows), "result", "results")} (\${@Format(@Sum(rows.amount), "currency", "USD")} total)\`\`\``}function Od(){return`## Hoisting & streaming (CRITICAL)
719
761
 
720
762
  Aktion supports hoisting: a reference can be used BEFORE it is
721
763
  defined. The output is re-parsed on every streamed chunk, so undefined
@@ -734,8 +776,8 @@ smooth top-down reveal.
734
776
  \`Series\`, \`FollowUpItem\`, etc. — each one streams in independently.
735
777
  - Place large data values on their own trailing lines.
736
778
  - Never split a single statement across multiple lines unless it sits
737
- inside an unmatched \`[\`, \`(\`, or \`{\`.`}function Od(t){const e=["## Available data sources (context only)","These endpoints are available to the host. You cannot call them from read-only mode, but you may incorporate the data they describe when composing the UI:"];for(const r of t)e.push(`- **${r.name}** — ${r.description}`);return e.join(`
738
- `)}function Ud(){return[`# Comparison table reply with template literal summary
779
+ inside an unmatched \`[\`, \`(\`, or \`{\`.`}function Ud(t){const e=["## Available data sources (context only)","These endpoints are available to the host. You cannot call them from read-only mode, but you may incorporate the data they describe when composing the UI:"];for(const r of t)e.push(`- **${r.name}** — ${r.description}`);return e.join(`
780
+ `)}function qd(){return[`# Comparison table reply with template literal summary
739
781
  ${D} = Stack([title, tbl, totals, follow])
740
782
  title = Text("Top languages by users", variant: "large-heavy")
741
783
  tbl = Table([
@@ -789,7 +831,7 @@ answer = CodeBlock("sql", indexSql, showLineNumbers: true)
789
831
  hint = Callout("success", "Composite index cuts query time ~12×", description: "Postgres reads index entries already in the requested order, so the planner skips the sort step entirely.", icon: "lightbulb")
790
832
  follow = FollowUpBlock(["Show EXPLAIN ANALYZE output", "How big is the index?", "Compare to a partial index"])
791
833
 
792
- indexSql = "CREATE INDEX idx_orders_user_status_created\\n ON orders (user_id, status, created_at DESC);"`]}function qd(){return'## Important rules\n\n- **Choose components that best represent the content.** Tables for\n comparisons, charts for trends, `Callout` / `Banner` for highlights,\n `Markdown` for paragraph prose with inline formatting, `Hero` /\n `PageHeader` for top-of-reply titles, `Stats` for KPI strips.\n- **Lead with a clear title.** Use `Text(text, variant: "large-heavy")`,\n `SectionHeader(...)`, `PageHeader(...)`, or `Hero(...)` so the user sees\n what the reply is about at a glance.\n- **Generate realistic data.** When asked about data, write believable\n names, numbers, and dates. Never write Lorem Ipsum.\n- **Tables are column-oriented**: `Table([Col("Label", arr1), Col("Count", arr2, format: "number")])`.\n- **Charts need numeric arrays**, not arrays of objects. Use array pluck:\n `PieChart(rows.label, rows.value)` instead of passing `rows` directly.\n- **End conversational replies with `FollowUpBlock([...])`** — 2–4 short\n next-prompt suggestions keep the conversation flowing.\n- **Use `Markdown`** for rich paragraph prose with bold, lists, code\n fences, links, and headings. Use `Text` for short labelled lines.\n- **Icons are Font Awesome names** (no `fa-` prefix, no emoji). Example\n values: `"house"`, `"chart-line"`, `"star"`, `"circle-check"`.\n- **Use template literals** for any string that mixes copy with values:\n ```${@Count(rows)} results``` instead of `"..." + ... + "..."` concatenation.'}function Hd(){return`## Final verification
834
+ indexSql = "CREATE INDEX idx_orders_user_status_created\\n ON orders (user_id, status, created_at DESC);"`]}function Hd(){return'## Important rules\n\n- **Choose components that best represent the content.** Tables for\n comparisons, charts for trends, `Callout` / `Banner` for highlights,\n `Markdown` for paragraph prose with inline formatting, `Hero` /\n `PageHeader` for top-of-reply titles, `Stats` for KPI strips.\n- **Lead with a clear title.** Use `Text(text, variant: "large-heavy")`,\n `SectionHeader(...)`, `PageHeader(...)`, or `Hero(...)` so the user sees\n what the reply is about at a glance.\n- **Generate realistic data.** When asked about data, write believable\n names, numbers, and dates. Never write Lorem Ipsum.\n- **Tables are column-oriented**: `Table([Col("Label", arr1), Col("Count", arr2, format: "number")])`.\n- **Charts need numeric arrays**, not arrays of objects. Use array pluck:\n `PieChart(rows.label, rows.value)` instead of passing `rows` directly.\n- **End conversational replies with `FollowUpBlock([...])`** — 2–4 short\n next-prompt suggestions keep the conversation flowing.\n- **Use `Markdown`** for rich paragraph prose with bold, lists, code\n fences, links, and headings. Use `Text` for short labelled lines.\n- **Icons are Font Awesome names** (no `fa-` prefix, no emoji). Example\n values: `"house"`, `"chart-line"`, `"star"`, `"circle-check"`.\n- **Use template literals** for any string that mixes copy with values:\n ```${@Count(rows)} results``` instead of `"..." + ... + "..."` concatenation.'}function Vd(){return`## Final verification
793
835
 
794
836
  Before finishing, walk your output and verify:
795
837
  1. \`${D} = ...\` is the FIRST line.
@@ -803,12 +845,12 @@ Before finishing, walk your output and verify:
803
845
  5. No statement is split across multiple lines unless it sits inside an
804
846
  unmatched \`[\`, \`(\`, or \`{\`.
805
847
  6. Tables are column-oriented; charts use numeric arrays (use array pluck
806
- like \`rows.value\` when needed).`}function ft(t){const e=Nt(t),r=t.props.map(a=>{const i=a.enum?a.enum.map(s=>`"${s}"`).join("|"):a.type,n=a===e&&a.positional===!0?" (positional)":"";return`${a.name}${a.optional?"?":""}: ${i}${n}`}).join(", ");return`- ${t.name}(${r}) — ${t.description}`}function Vd(t){const e=t.filter(i=>i.category==="data"),r=t.filter(i=>i.category==="iteration"),a=[];if(e.length>0){a.push("### Data helpers");for(const i of e)a.push(ht(i));a.push("")}if(r.length>0){a.push("### Iteration helpers");for(const i of r)a.push(ht(i))}return a.join(`
807
- `)}function ht(t){return`- \`${t.signature}\` — ${t.description}`}function Wt(t,e){const r=[`## ${t}`];for(const a of e)r.push("```"),r.push(a.trim()),r.push("```");return r.join(`
808
- `)}function ei(t){const e=["## Additional rules"];for(const r of t)e.push(`- ${r}`);return e.join(`
809
- `)}function Wd(t){const e=["## Available endpoints","These endpoints are provided by the host. Fire requests with `http({ url, method, body, headers, ... })` and observe the reactive bag (`.data`, `.error`, `.loading`, `.status`, `.refetch()`)."];for(const r of t){const a=r.kind==="Mutation"?"POST/PUT/PATCH/DELETE":"GET",i=r.argsExample?` example body: ${JSON.stringify(r.argsExample)}`:" example body: {}";e.push(`- ${r.name} (${a}) — ${r.description}
848
+ like \`rows.value\` when needed).`}function ft(t){const e=$t(t),r=t.props.map(a=>{const i=a.enum?a.enum.map(s=>`"${s}"`).join("|"):a.type,n=a===e&&a.positional===!0?" (positional)":"";return`${a.name}${a.optional?"?":""}: ${i}${n}`}).join(", ");return`- ${t.name}(${r}) — ${t.description}`}function Wd(t){const e=t.filter(i=>i.category==="data"),r=t.filter(i=>i.category==="iteration"),a=[];if(e.length>0){a.push("### Data helpers");for(const i of e)a.push(ht(i));a.push("")}if(r.length>0){a.push("### Iteration helpers");for(const i of r)a.push(ht(i))}return a.join(`
849
+ `)}function ht(t){return`- \`${t.signature}\` — ${t.description}`}function Kt(t,e){const r=[`## ${t}`];for(const a of e)r.push("```"),r.push(a.trim()),r.push("```");return r.join(`
850
+ `)}function ti(t){const e=["## Additional rules"];for(const r of t)e.push(`- ${r}`);return e.join(`
851
+ `)}function Gd(t){const e=["## Available endpoints","These endpoints are provided by the host. Fire requests with `http({ url, method, body, headers, ... })` and observe the reactive bag (`.data`, `.error`, `.loading`, `.status`, `.refetch()`)."];for(const r of t){const a=r.kind==="Mutation"?"POST/PUT/PATCH/DELETE":"GET",i=r.argsExample?` example body: ${JSON.stringify(r.argsExample)}`:" example body: {}";e.push(`- ${r.name} (${a}) — ${r.description}
810
852
  ${i}`)}return e.join(`
811
- `)}const ce={colorBg:"#ffffff",colorBgSubtle:"#f8fafc",colorSurface:"#ffffff",colorSurfaceMuted:"#f1f5f9",colorBorder:"#e2e8f0",colorBorderSubtle:"rgba(15, 23, 42, 0.08)",colorText:"#0f172a",colorTextMuted:"#475569",colorPrimary:"#6366f1",colorPrimaryHover:"#4f46e5",colorPrimaryText:"#ffffff",colorAccent:"#6366f1",colorAccentHover:"#4f46e5",colorAccentText:"#ffffff",colorFocusRing:"#6366f1",colorSuccess:"#10b981",colorWarning:"#f59e0b",colorDanger:"#ef4444",colorInfo:"#06b6d4",shadowSm:"0 1px 2px rgba(15, 23, 42, 0.06)",shadowMd:"0 6px 24px rgba(15, 23, 42, 0.08)",shadowLg:"0 18px 60px rgba(15, 23, 42, 0.12)",borderWidth:"1px",chart1:"#6366f1",chart2:"#10b981",chart3:"#f59e0b",chart4:"#ef4444",chart5:"#06b6d4",chart6:"#8b5cf6",...{fontFamily:"system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",fontFamilyHeading:"system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",fontFamilyMono:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"},...{fontSizeBase:"14px",fontSizeSm:"12px",fontSizeLg:"16px",fontSizeHeading:"16px",fontSizeTitle:"22px",fontWeightBody:"400",fontWeightHeading:"700",lineHeightBody:"1.5",lineHeightHeading:"1.2",letterSpacingHeading:"0",headingTextTransform:"none"},...{spacingXs:"4px",spacingS:"8px",spacingM:"12px",spacingL:"20px",spacingXl:"32px"},...{radiusXs:"4px",radiusSm:"6px",radiusMd:"10px",radiusLg:"16px",radiusPill:"999px",radiusButton:"6px",radiusInput:"6px"},...{buttonFontWeight:"600",buttonTextTransform:"none",buttonLetterSpacing:"0",buttonPaddingY:"8px",buttonPaddingX:"14px"},...{transitionDuration:"120ms"}},ti={...ce,colorBg:"#0b1220",colorBgSubtle:"#0f172a",colorSurface:"#111827",colorSurfaceMuted:"#1e293b",colorBorder:"#1f2937",colorBorderSubtle:"rgba(248, 250, 252, 0.08)",colorText:"#f8fafc",colorTextMuted:"#94a3b8",colorPrimary:"#818cf8",colorPrimaryHover:"#6366f1",colorPrimaryText:"#0b1220",colorAccent:"#818cf8",colorAccentHover:"#6366f1",colorAccentText:"#0b1220",colorFocusRing:"#818cf8",shadowSm:"0 1px 2px rgba(0, 0, 0, 0.4)",shadowMd:"0 8px 24px rgba(0, 0, 0, 0.4)",shadowLg:"0 22px 60px rgba(0, 0, 0, 0.55)"},ri={...ce,colorBg:"#05060f",colorBgSubtle:"#0a0c1c",colorSurface:"#0d1024",colorSurfaceMuted:"#161a36",colorBorder:"#2a2f6b",colorBorderSubtle:"rgba(236, 72, 153, 0.18)",colorText:"#f5f3ff",colorTextMuted:"#a5b4fc",colorPrimary:"#ec4899",colorPrimaryHover:"#f472b6",colorPrimaryText:"#05060f",colorAccent:"#22d3ee",colorAccentHover:"#67e8f9",colorAccentText:"#05060f",colorFocusRing:"#ec4899",colorSuccess:"#34d399",colorWarning:"#fbbf24",colorDanger:"#f87171",colorInfo:"#22d3ee",fontFamily:"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",fontFamilyHeading:"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",fontFamilyMono:"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",letterSpacingHeading:"0.02em",radiusXs:"2px",radiusSm:"2px",radiusMd:"4px",radiusLg:"6px",radiusButton:"2px",radiusInput:"2px",shadowSm:"0 0 0 1px rgba(236, 72, 153, 0.25), 0 0 12px rgba(34, 211, 238, 0.18)",shadowMd:"0 0 0 1px rgba(236, 72, 153, 0.35), 0 0 28px rgba(34, 211, 238, 0.22)",shadowLg:"0 0 0 1px rgba(236, 72, 153, 0.45), 0 0 48px rgba(34, 211, 238, 0.35)",spacingXs:"4px",spacingS:"8px",spacingM:"14px",spacingL:"22px",spacingXl:"36px",chart1:"#ec4899",chart2:"#22d3ee",chart3:"#fbbf24",chart4:"#a78bfa",chart5:"#34d399",chart6:"#f472b6"},ai={...ce,colorBg:"#fdf6ff",colorBgSubtle:"#fbf2ff",colorSurface:"#ffffff",colorSurfaceMuted:"#f4ecff",colorBorder:"#ead8ff",colorBorderSubtle:"rgba(168, 132, 232, 0.18)",colorText:"#3b1f56",colorTextMuted:"#7d6193",colorPrimary:"#a78bfa",colorPrimaryHover:"#8b5cf6",colorPrimaryText:"#ffffff",colorAccent:"#5eead4",colorAccentHover:"#2dd4bf",colorAccentText:"#0f3a35",colorFocusRing:"#a78bfa",colorSuccess:"#5eead4",colorWarning:"#fcd34d",colorDanger:"#fda4af",colorInfo:"#93c5fd",fontFamily:"'Quicksand', 'Nunito', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyHeading:"'Quicksand', 'Nunito', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyMono:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",radiusXs:"8px",radiusSm:"12px",radiusMd:"20px",radiusLg:"28px",radiusButton:"16px",radiusInput:"16px",shadowSm:"0 4px 14px rgba(168, 132, 232, 0.12)",shadowMd:"0 18px 40px rgba(168, 132, 232, 0.18)",shadowLg:"0 28px 70px rgba(168, 132, 232, 0.22)",spacingXs:"6px",spacingS:"12px",spacingM:"18px",spacingL:"28px",spacingXl:"44px",chart1:"#a78bfa",chart2:"#5eead4",chart3:"#fcd34d",chart4:"#fda4af",chart5:"#93c5fd",chart6:"#f9a8d4"},ii={...ce,colorBg:"#0f1730",colorBgSubtle:"#13204a",colorSurface:"rgba(255, 255, 255, 0.08)",colorSurfaceMuted:"rgba(255, 255, 255, 0.04)",colorBorder:"rgba(255, 255, 255, 0.18)",colorBorderSubtle:"rgba(255, 255, 255, 0.10)",colorText:"#f1f5ff",colorTextMuted:"#b6c3e6",colorPrimary:"#60a5fa",colorPrimaryHover:"#3b82f6",colorPrimaryText:"#0b132b",colorAccent:"#22d3ee",colorAccentHover:"#67e8f9",colorAccentText:"#0b132b",colorFocusRing:"#60a5fa",colorSuccess:"#34d399",colorWarning:"#fbbf24",colorDanger:"#fb7185",colorInfo:"#22d3ee",fontFamily:"'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyHeading:"'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyMono:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",radiusXs:"6px",radiusSm:"10px",radiusMd:"16px",radiusLg:"24px",radiusButton:"12px",radiusInput:"12px",shadowSm:"0 1px 2px rgba(15, 23, 42, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.08)",shadowMd:"0 18px 50px rgba(7, 14, 33, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.10)",shadowLg:"0 28px 80px rgba(7, 14, 33, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.12)",spacingXs:"4px",spacingS:"10px",spacingM:"16px",spacingL:"24px",spacingXl:"40px",chart1:"#60a5fa",chart2:"#22d3ee",chart3:"#a78bfa",chart4:"#f472b6",chart5:"#34d399",chart6:"#fbbf24"},ni={...ce,colorBg:"#fef9c3",colorBgSubtle:"#fde68a",colorSurface:"#ffffff",colorSurfaceMuted:"#fef3c7",colorBorder:"#0a0a0a",colorBorderSubtle:"#0a0a0a",colorText:"#0a0a0a",colorTextMuted:"#3f3f46",colorPrimary:"#1d4ed8",colorPrimaryHover:"#1e40af",colorPrimaryText:"#ffffff",colorAccent:"#dc2626",colorAccentHover:"#b91c1c",colorAccentText:"#ffffff",colorFocusRing:"#0a0a0a",colorSuccess:"#16a34a",colorWarning:"#ea580c",colorDanger:"#dc2626",colorInfo:"#0891b2",fontFamily:"'Space Grotesk', 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif",fontFamilyHeading:"'Space Grotesk', 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif",fontFamilyMono:"'JetBrains Mono', 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",fontWeightHeading:"800",letterSpacingHeading:"-0.01em",headingTextTransform:"uppercase",radiusXs:"0px",radiusSm:"0px",radiusMd:"0px",radiusLg:"0px",radiusPill:"0px",radiusButton:"0px",radiusInput:"0px",borderWidth:"2px",shadowSm:"3px 3px 0 0 #0a0a0a",shadowMd:"6px 6px 0 0 #0a0a0a",shadowLg:"10px 10px 0 0 #0a0a0a",spacingXs:"4px",spacingS:"10px",spacingM:"16px",spacingL:"22px",spacingXl:"36px",buttonFontWeight:"800",buttonTextTransform:"uppercase",buttonLetterSpacing:"0.02em",chart1:"#dc2626",chart2:"#1d4ed8",chart3:"#16a34a",chart4:"#ea580c",chart5:"#7c3aed",chart6:"#0a0a0a"},oi={...ce,colorBg:"#eff2f7",colorBgSubtle:"#e6ecf3",colorSurface:"#ffffff",colorSurfaceMuted:"#f4f7fb",colorBorder:"#d6deea",colorBorderSubtle:"rgba(13, 27, 58, 0.08)",colorText:"#0d1b3a",colorTextMuted:"#5a6a85",colorPrimary:"#003580",colorPrimaryHover:"#002a66",colorPrimaryText:"#ffffff",colorAccent:"#0095d6",colorAccentHover:"#0078ad",colorAccentText:"#ffffff",colorFocusRing:"#0095d6",colorSuccess:"#1b8f4f",colorWarning:"#c47e00",colorDanger:"#c8362b",colorInfo:"#0095d6",fontFamily:"'Inter', 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyHeading:"'Inter', 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyMono:"'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",radiusXs:"3px",radiusSm:"4px",radiusMd:"6px",radiusLg:"10px",radiusButton:"4px",radiusInput:"4px",shadowSm:"0 1px 0 rgba(13, 27, 58, 0.04), 0 1px 3px rgba(13, 27, 58, 0.06)",shadowMd:"0 4px 16px rgba(13, 27, 58, 0.08), 0 1px 3px rgba(13, 27, 58, 0.04)",shadowLg:"0 16px 40px rgba(13, 27, 58, 0.12), 0 2px 6px rgba(13, 27, 58, 0.06)",spacingXs:"4px",spacingS:"8px",spacingM:"14px",spacingL:"20px",spacingXl:"32px",chart1:"#003580",chart2:"#0095d6",chart3:"#1b8f4f",chart4:"#c47e00",chart5:"#d43594",chart6:"#5a6a85"},Gt={light:ce,dark:ti,neon:ri,pastel:ai,glass:ii,brutalist:ni,skyline:oi},bt={colorBg:"--rui-color-bg",colorBgSubtle:"--rui-color-bg-subtle",colorSurface:"--rui-color-surface",colorSurfaceMuted:"--rui-color-surface-muted",colorBorder:"--rui-color-border",colorBorderSubtle:"--rui-color-border-subtle",colorText:"--rui-color-text",colorTextMuted:"--rui-color-text-muted",colorPrimary:"--rui-color-primary",colorPrimaryHover:"--rui-color-primary-hover",colorPrimaryText:"--rui-color-primary-text",colorAccent:"--rui-color-accent",colorAccentHover:"--rui-color-accent-hover",colorAccentText:"--rui-color-accent-text",colorFocusRing:"--rui-color-focus-ring",colorSuccess:"--rui-color-success",colorWarning:"--rui-color-warning",colorDanger:"--rui-color-danger",colorInfo:"--rui-color-info",fontFamily:"--rui-font-family",fontFamilyHeading:"--rui-font-family-heading",fontFamilyMono:"--rui-font-family-mono",fontSizeBase:"--rui-font-size-base",fontSizeSm:"--rui-font-size-sm",fontSizeLg:"--rui-font-size-lg",fontSizeHeading:"--rui-font-size-heading",fontSizeTitle:"--rui-font-size-title",fontWeightBody:"--rui-font-weight-body",fontWeightHeading:"--rui-font-weight-heading",lineHeightBody:"--rui-line-height-body",lineHeightHeading:"--rui-line-height-heading",letterSpacingHeading:"--rui-letter-spacing-heading",headingTextTransform:"--rui-heading-text-transform",radiusXs:"--rui-radius-xs",radiusSm:"--rui-radius-sm",radiusMd:"--rui-radius-md",radiusLg:"--rui-radius-lg",radiusPill:"--rui-radius-pill",radiusButton:"--rui-radius-button",radiusInput:"--rui-radius-input",borderWidth:"--rui-border-width",shadowSm:"--rui-shadow-sm",shadowMd:"--rui-shadow-md",shadowLg:"--rui-shadow-lg",spacingXs:"--rui-spacing-xs",spacingS:"--rui-spacing-s",spacingM:"--rui-spacing-m",spacingL:"--rui-spacing-l",spacingXl:"--rui-spacing-xl",buttonFontWeight:"--rui-button-font-weight",buttonTextTransform:"--rui-button-text-transform",buttonLetterSpacing:"--rui-button-letter-spacing",buttonPaddingY:"--rui-button-padding-y",buttonPaddingX:"--rui-button-padding-x",transitionDuration:"--rui-transition-duration",chart1:"--rui-chart-1",chart2:"--rui-chart-2",chart3:"--rui-chart-3",chart4:"--rui-chart-4",chart5:"--rui-chart-5",chart6:"--rui-chart-6"};function Kt(t){if(!t)return{name:"light",tokens:ce};if(typeof t=="string"){const e=t.trim().toLowerCase();if(e.startsWith("{"))try{return{name:"custom",tokens:ui(JSON.parse(t))}}catch{return{name:"light",tokens:ce}}const r=Gt[e];return r?{name:e,tokens:r}:{name:"light",tokens:ce}}return{name:"custom",tokens:ui(t)}}function Yt(t,e){const r="tokens"in e?e:{name:"custom",tokens:e};for(const[a,i]of Object.entries(bt))t.style.setProperty(i,r.tokens[a]);t.setAttribute("data-rui-theme",r.name)}function si(t,e){const r=[];for(const a of Object.keys(e)){const i=bt[a];if(!i)continue;const n=e[a];typeof n!="string"||n===""||(t.style.setProperty(i,n),r.push(a))}return r}function li(t,e){for(const r of e){const a=bt[r];a&&t.style.removeProperty(a)}}function ci(t){if(!t||typeof t!="object"||Array.isArray(t))return{};const e={};for(const[r,a]of Object.entries(t))if(r in bt&&a!=null)if(typeof a=="string"){if(a.trim()==="")continue;e[r]=a}else typeof a=="number"&&(e[r]=String(a));return e}function ui(t){return{...ce,...t}}const di=`
853
+ `)}const ce={colorBg:"#ffffff",colorBgSubtle:"#f8fafc",colorSurface:"#ffffff",colorSurfaceMuted:"#f1f5f9",colorBorder:"#e2e8f0",colorBorderSubtle:"rgba(15, 23, 42, 0.08)",colorText:"#0f172a",colorTextMuted:"#475569",colorPrimary:"#6366f1",colorPrimaryHover:"#4f46e5",colorPrimaryText:"#ffffff",colorAccent:"#6366f1",colorAccentHover:"#4f46e5",colorAccentText:"#ffffff",colorFocusRing:"#6366f1",colorSuccess:"#10b981",colorWarning:"#f59e0b",colorDanger:"#ef4444",colorInfo:"#06b6d4",shadowSm:"0 1px 2px rgba(15, 23, 42, 0.06)",shadowMd:"0 6px 24px rgba(15, 23, 42, 0.08)",shadowLg:"0 18px 60px rgba(15, 23, 42, 0.12)",borderWidth:"1px",chart1:"#6366f1",chart2:"#10b981",chart3:"#f59e0b",chart4:"#ef4444",chart5:"#06b6d4",chart6:"#8b5cf6",...{fontFamily:"system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",fontFamilyHeading:"system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",fontFamilyMono:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"},...{fontSizeBase:"14px",fontSizeSm:"12px",fontSizeLg:"16px",fontSizeHeading:"16px",fontSizeTitle:"22px",fontWeightBody:"400",fontWeightHeading:"700",lineHeightBody:"1.5",lineHeightHeading:"1.2",letterSpacingHeading:"0",headingTextTransform:"none"},...{spacingXs:"4px",spacingS:"8px",spacingM:"12px",spacingL:"20px",spacingXl:"32px"},...{radiusXs:"4px",radiusSm:"6px",radiusMd:"10px",radiusLg:"16px",radiusPill:"999px",radiusButton:"6px",radiusInput:"6px"},...{buttonFontWeight:"600",buttonTextTransform:"none",buttonLetterSpacing:"0",buttonPaddingY:"8px",buttonPaddingX:"14px"},...{transitionDuration:"120ms"}},ri={...ce,colorBg:"#0b1220",colorBgSubtle:"#0f172a",colorSurface:"#111827",colorSurfaceMuted:"#1e293b",colorBorder:"#1f2937",colorBorderSubtle:"rgba(248, 250, 252, 0.08)",colorText:"#f8fafc",colorTextMuted:"#94a3b8",colorPrimary:"#818cf8",colorPrimaryHover:"#6366f1",colorPrimaryText:"#0b1220",colorAccent:"#818cf8",colorAccentHover:"#6366f1",colorAccentText:"#0b1220",colorFocusRing:"#818cf8",shadowSm:"0 1px 2px rgba(0, 0, 0, 0.4)",shadowMd:"0 8px 24px rgba(0, 0, 0, 0.4)",shadowLg:"0 22px 60px rgba(0, 0, 0, 0.55)"},ai={...ce,colorBg:"#05060f",colorBgSubtle:"#0a0c1c",colorSurface:"#0d1024",colorSurfaceMuted:"#161a36",colorBorder:"#2a2f6b",colorBorderSubtle:"rgba(236, 72, 153, 0.18)",colorText:"#f5f3ff",colorTextMuted:"#a5b4fc",colorPrimary:"#ec4899",colorPrimaryHover:"#f472b6",colorPrimaryText:"#05060f",colorAccent:"#22d3ee",colorAccentHover:"#67e8f9",colorAccentText:"#05060f",colorFocusRing:"#ec4899",colorSuccess:"#34d399",colorWarning:"#fbbf24",colorDanger:"#f87171",colorInfo:"#22d3ee",fontFamily:"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",fontFamilyHeading:"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",fontFamilyMono:"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",letterSpacingHeading:"0.02em",radiusXs:"2px",radiusSm:"2px",radiusMd:"4px",radiusLg:"6px",radiusButton:"2px",radiusInput:"2px",shadowSm:"0 0 0 1px rgba(236, 72, 153, 0.25), 0 0 12px rgba(34, 211, 238, 0.18)",shadowMd:"0 0 0 1px rgba(236, 72, 153, 0.35), 0 0 28px rgba(34, 211, 238, 0.22)",shadowLg:"0 0 0 1px rgba(236, 72, 153, 0.45), 0 0 48px rgba(34, 211, 238, 0.35)",spacingXs:"4px",spacingS:"8px",spacingM:"14px",spacingL:"22px",spacingXl:"36px",chart1:"#ec4899",chart2:"#22d3ee",chart3:"#fbbf24",chart4:"#a78bfa",chart5:"#34d399",chart6:"#f472b6"},ii={...ce,colorBg:"#fdf6ff",colorBgSubtle:"#fbf2ff",colorSurface:"#ffffff",colorSurfaceMuted:"#f4ecff",colorBorder:"#ead8ff",colorBorderSubtle:"rgba(168, 132, 232, 0.18)",colorText:"#3b1f56",colorTextMuted:"#7d6193",colorPrimary:"#a78bfa",colorPrimaryHover:"#8b5cf6",colorPrimaryText:"#ffffff",colorAccent:"#5eead4",colorAccentHover:"#2dd4bf",colorAccentText:"#0f3a35",colorFocusRing:"#a78bfa",colorSuccess:"#5eead4",colorWarning:"#fcd34d",colorDanger:"#fda4af",colorInfo:"#93c5fd",fontFamily:"'Quicksand', 'Nunito', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyHeading:"'Quicksand', 'Nunito', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyMono:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",radiusXs:"8px",radiusSm:"12px",radiusMd:"20px",radiusLg:"28px",radiusButton:"16px",radiusInput:"16px",shadowSm:"0 4px 14px rgba(168, 132, 232, 0.12)",shadowMd:"0 18px 40px rgba(168, 132, 232, 0.18)",shadowLg:"0 28px 70px rgba(168, 132, 232, 0.22)",spacingXs:"6px",spacingS:"12px",spacingM:"18px",spacingL:"28px",spacingXl:"44px",chart1:"#a78bfa",chart2:"#5eead4",chart3:"#fcd34d",chart4:"#fda4af",chart5:"#93c5fd",chart6:"#f9a8d4"},ni={...ce,colorBg:"#0f1730",colorBgSubtle:"#13204a",colorSurface:"rgba(255, 255, 255, 0.08)",colorSurfaceMuted:"rgba(255, 255, 255, 0.04)",colorBorder:"rgba(255, 255, 255, 0.18)",colorBorderSubtle:"rgba(255, 255, 255, 0.10)",colorText:"#f1f5ff",colorTextMuted:"#b6c3e6",colorPrimary:"#60a5fa",colorPrimaryHover:"#3b82f6",colorPrimaryText:"#0b132b",colorAccent:"#22d3ee",colorAccentHover:"#67e8f9",colorAccentText:"#0b132b",colorFocusRing:"#60a5fa",colorSuccess:"#34d399",colorWarning:"#fbbf24",colorDanger:"#fb7185",colorInfo:"#22d3ee",fontFamily:"'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyHeading:"'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyMono:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",radiusXs:"6px",radiusSm:"10px",radiusMd:"16px",radiusLg:"24px",radiusButton:"12px",radiusInput:"12px",shadowSm:"0 1px 2px rgba(15, 23, 42, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.08)",shadowMd:"0 18px 50px rgba(7, 14, 33, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.10)",shadowLg:"0 28px 80px rgba(7, 14, 33, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.12)",spacingXs:"4px",spacingS:"10px",spacingM:"16px",spacingL:"24px",spacingXl:"40px",chart1:"#60a5fa",chart2:"#22d3ee",chart3:"#a78bfa",chart4:"#f472b6",chart5:"#34d399",chart6:"#fbbf24"},oi={...ce,colorBg:"#fef9c3",colorBgSubtle:"#fde68a",colorSurface:"#ffffff",colorSurfaceMuted:"#fef3c7",colorBorder:"#0a0a0a",colorBorderSubtle:"#0a0a0a",colorText:"#0a0a0a",colorTextMuted:"#3f3f46",colorPrimary:"#1d4ed8",colorPrimaryHover:"#1e40af",colorPrimaryText:"#ffffff",colorAccent:"#dc2626",colorAccentHover:"#b91c1c",colorAccentText:"#ffffff",colorFocusRing:"#0a0a0a",colorSuccess:"#16a34a",colorWarning:"#ea580c",colorDanger:"#dc2626",colorInfo:"#0891b2",fontFamily:"'Space Grotesk', 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif",fontFamilyHeading:"'Space Grotesk', 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif",fontFamilyMono:"'JetBrains Mono', 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",fontWeightHeading:"800",letterSpacingHeading:"-0.01em",headingTextTransform:"uppercase",radiusXs:"0px",radiusSm:"0px",radiusMd:"0px",radiusLg:"0px",radiusPill:"0px",radiusButton:"0px",radiusInput:"0px",borderWidth:"2px",shadowSm:"3px 3px 0 0 #0a0a0a",shadowMd:"6px 6px 0 0 #0a0a0a",shadowLg:"10px 10px 0 0 #0a0a0a",spacingXs:"4px",spacingS:"10px",spacingM:"16px",spacingL:"22px",spacingXl:"36px",buttonFontWeight:"800",buttonTextTransform:"uppercase",buttonLetterSpacing:"0.02em",chart1:"#dc2626",chart2:"#1d4ed8",chart3:"#16a34a",chart4:"#ea580c",chart5:"#7c3aed",chart6:"#0a0a0a"},si={...ce,colorBg:"#eff2f7",colorBgSubtle:"#e6ecf3",colorSurface:"#ffffff",colorSurfaceMuted:"#f4f7fb",colorBorder:"#d6deea",colorBorderSubtle:"rgba(13, 27, 58, 0.08)",colorText:"#0d1b3a",colorTextMuted:"#5a6a85",colorPrimary:"#003580",colorPrimaryHover:"#002a66",colorPrimaryText:"#ffffff",colorAccent:"#0095d6",colorAccentHover:"#0078ad",colorAccentText:"#ffffff",colorFocusRing:"#0095d6",colorSuccess:"#1b8f4f",colorWarning:"#c47e00",colorDanger:"#c8362b",colorInfo:"#0095d6",fontFamily:"'Inter', 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyHeading:"'Inter', 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",fontFamilyMono:"'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",radiusXs:"3px",radiusSm:"4px",radiusMd:"6px",radiusLg:"10px",radiusButton:"4px",radiusInput:"4px",shadowSm:"0 1px 0 rgba(13, 27, 58, 0.04), 0 1px 3px rgba(13, 27, 58, 0.06)",shadowMd:"0 4px 16px rgba(13, 27, 58, 0.08), 0 1px 3px rgba(13, 27, 58, 0.04)",shadowLg:"0 16px 40px rgba(13, 27, 58, 0.12), 0 2px 6px rgba(13, 27, 58, 0.06)",spacingXs:"4px",spacingS:"8px",spacingM:"14px",spacingL:"20px",spacingXl:"32px",chart1:"#003580",chart2:"#0095d6",chart3:"#1b8f4f",chart4:"#c47e00",chart5:"#d43594",chart6:"#5a6a85"},Yt={light:ce,dark:ri,neon:ai,pastel:ii,glass:ni,brutalist:oi,skyline:si},bt={colorBg:"--rui-color-bg",colorBgSubtle:"--rui-color-bg-subtle",colorSurface:"--rui-color-surface",colorSurfaceMuted:"--rui-color-surface-muted",colorBorder:"--rui-color-border",colorBorderSubtle:"--rui-color-border-subtle",colorText:"--rui-color-text",colorTextMuted:"--rui-color-text-muted",colorPrimary:"--rui-color-primary",colorPrimaryHover:"--rui-color-primary-hover",colorPrimaryText:"--rui-color-primary-text",colorAccent:"--rui-color-accent",colorAccentHover:"--rui-color-accent-hover",colorAccentText:"--rui-color-accent-text",colorFocusRing:"--rui-color-focus-ring",colorSuccess:"--rui-color-success",colorWarning:"--rui-color-warning",colorDanger:"--rui-color-danger",colorInfo:"--rui-color-info",fontFamily:"--rui-font-family",fontFamilyHeading:"--rui-font-family-heading",fontFamilyMono:"--rui-font-family-mono",fontSizeBase:"--rui-font-size-base",fontSizeSm:"--rui-font-size-sm",fontSizeLg:"--rui-font-size-lg",fontSizeHeading:"--rui-font-size-heading",fontSizeTitle:"--rui-font-size-title",fontWeightBody:"--rui-font-weight-body",fontWeightHeading:"--rui-font-weight-heading",lineHeightBody:"--rui-line-height-body",lineHeightHeading:"--rui-line-height-heading",letterSpacingHeading:"--rui-letter-spacing-heading",headingTextTransform:"--rui-heading-text-transform",radiusXs:"--rui-radius-xs",radiusSm:"--rui-radius-sm",radiusMd:"--rui-radius-md",radiusLg:"--rui-radius-lg",radiusPill:"--rui-radius-pill",radiusButton:"--rui-radius-button",radiusInput:"--rui-radius-input",borderWidth:"--rui-border-width",shadowSm:"--rui-shadow-sm",shadowMd:"--rui-shadow-md",shadowLg:"--rui-shadow-lg",spacingXs:"--rui-spacing-xs",spacingS:"--rui-spacing-s",spacingM:"--rui-spacing-m",spacingL:"--rui-spacing-l",spacingXl:"--rui-spacing-xl",buttonFontWeight:"--rui-button-font-weight",buttonTextTransform:"--rui-button-text-transform",buttonLetterSpacing:"--rui-button-letter-spacing",buttonPaddingY:"--rui-button-padding-y",buttonPaddingX:"--rui-button-padding-x",transitionDuration:"--rui-transition-duration",chart1:"--rui-chart-1",chart2:"--rui-chart-2",chart3:"--rui-chart-3",chart4:"--rui-chart-4",chart5:"--rui-chart-5",chart6:"--rui-chart-6"};function Jt(t){if(!t)return{name:"light",tokens:ce};if(typeof t=="string"){const e=t.trim().toLowerCase();if(e.startsWith("{"))try{return{name:"custom",tokens:di(JSON.parse(t))}}catch{return{name:"light",tokens:ce}}const r=Yt[e];return r?{name:e,tokens:r}:{name:"light",tokens:ce}}return{name:"custom",tokens:di(t)}}function Xt(t,e){const r="tokens"in e?e:{name:"custom",tokens:e};for(const[a,i]of Object.entries(bt))t.style.setProperty(i,r.tokens[a]);t.setAttribute("data-rui-theme",r.name)}function li(t,e){const r=[];for(const a of Object.keys(e)){const i=bt[a];if(!i)continue;const n=e[a];typeof n!="string"||n===""||(t.style.setProperty(i,n),r.push(a))}return r}function ci(t,e){for(const r of e){const a=bt[r];a&&t.style.removeProperty(a)}}function ui(t){if(!t||typeof t!="object"||Array.isArray(t))return{};const e={};for(const[r,a]of Object.entries(t))if(r in bt&&a!=null)if(typeof a=="string"){if(a.trim()==="")continue;e[r]=a}else typeof a=="number"&&(e[r]=String(a));return e}function di(t){return{...ce,...t}}const pi=`
812
854
  :host {
813
855
  display: block;
814
856
  box-sizing: border-box;
@@ -8342,7 +8384,7 @@ th[data-active="true"] .rui-data-grid-sort-icon { opacity: 1; }
8342
8384
  }
8343
8385
  .rui-lightbox-thumb img { display: block; width: 100%; height: auto; }
8344
8386
  .rui-lightbox-thumb:hover { border-color: var(--rui-color-primary); }
8345
- `,Jt="theme",Ye="streaming",Xt="response",je="showerrors",pi="route";function Gd(t){const e=t.getPath(),r={...t.getParams()},a=t.getActivePattern(),i={};if(typeof window<"u"&&window.location){const n=window.location.search||"";if(n){const s=new URLSearchParams(n.startsWith("?")?n.slice(1):n);for(const[l,c]of s)i[l]=c}}return{path:e,params:r,pattern:a,query:i,navigate(n){typeof n!="string"||!n||t.navigate(n)},toString(){return e}}}function Kd(t,e){if(!t||!e||typeof t!="object"||typeof e!="object")return!1;const r=t,a=e;return r.path!==a.path||r.pattern!==a.pattern?!1:mi(r.params??{},a.params??{})&&mi(r.query??{},a.query??{})}function mi(t,e){const r=Object.keys(t),a=Object.keys(e);if(r.length!==a.length)return!1;for(const i of r)if(t[i]!==e[i])return!1;return!0}let Zt=null,vt=null;function Yd(){if(vt===!1)return null;if(Zt)return Zt;try{if(typeof CSSStyleSheet>"u"||!("replaceSync"in CSSStyleSheet.prototype)||typeof document>"u"||!("adoptedStyleSheets"in Document.prototype))return vt=!1,null;const t=new CSSStyleSheet;return t.replaceSync(di),Zt=t,vt=!0,t}catch{return vt=!1,null}}const xt=class xt extends HTMLElement{constructor(){super();j(this,"state",new Nr);j(this,"router",new Rr);j(this,"library",Ke);j(this,"http",new Ar);j(this,"i18n",new Zr);j(this,"effectRunner");j(this,"actionDeclRunner");j(this,"tools",{});j(this,"renderer");j(this,"context");j(this,"root");j(this,"rootEl");j(this,"errorEl");j(this,"currentResponse","");j(this,"renderScheduled",!1);j(this,"programDirty",!0);j(this,"parseErrors",[]);j(this,"scriptThemeKeys",[]);this.root=this.attachShadow({mode:"open"}),this.errorEl=document.createElement("div"),this.errorEl.className="rui-error-banner",this.errorEl.hidden=!0,this.rootEl=document.createElement("div"),this.rootEl.className="rui-root";const r=Yd();if(r)try{this.root.adoptedStyleSheets=[r],this.root.append(this.errorEl,this.rootEl)}catch{this.root.append(this.buildInlineStyle(),this.errorEl,this.rootEl)}else this.root.append(this.buildInlineStyle(),this.errorEl,this.rootEl);const a=n=>{this.dispatchEvent(new CustomEvent("assistant-message",{detail:{message:n},bubbles:!0,composed:!0}))},i=(n,s)=>{this.dispatchEvent(new CustomEvent(n,{detail:s,bubbles:!0,composed:!0}))};this.effectRunner=new ta({state:this.state,notify:()=>this.scheduleRender(),onEmit:i,host:this,tools:this.tools}),this.actionDeclRunner=new na({state:this.state,notify:()=>this.scheduleRender(),onEmit:i,onAssistantMessage:a,host:this,tools:this.tools}),this.context=Pt(this.state,{router:this.router,library:this.library,http:this.http,i18n:this.i18n,actionRunner:this.actionDeclRunner,notify:()=>this.scheduleRender(),jsBlockExecutor:ia({state:this.state,host:this,tools:this.tools})}),this.renderer=new Ya({library:this.library,state:this.state,router:this.router,onAssistantMessage:a,evaluationContext:()=>this.context}),this.state.subscribe(()=>this.scheduleRender()),this.router.subscribe(n=>this.handleRouteChange(n))}static get observedAttributes(){return[Jt,Ye,Xt,je]}connectedCallback(){eo(this.root),this.applyThemeFromAttribute(),this.startRouter(),this.attachPersistenceAdapter();const r=this.getAttribute(Xt);if(r!==null&&r!==""&&r!==this.currentResponse){this.setResponse(r);return}if(!this.currentResponse){const a=(this.textContent??"").trim();if(a){this.setResponse(a);return}}this.currentResponse&&(this.programDirty=!0,this.scheduleRender())}disconnectedCallback(){this.effectRunner.reset(),this.router.stop()}attributeChangedCallback(r,a,i){if(r===Jt&&this.applyThemeFromAttribute(),r===Ye&&(this.updateErrorBanner(),this.scheduleRender()),r===je&&this.updateErrorBanner(),r===Xt){const n=i??"";n!==this.currentResponse&&this.setResponse(n)}}registerHttpInterceptors(r){this.http.registerInterceptors(r)}setResponse(r){r!==this.currentResponse&&(this.currentResponse=r,this.programDirty=!0,this.state.rebind([]),this.renderer.reset(),this.parseErrors=[],this.scheduleRender())}serializeState(){return this.state.snapshot()}hydrateState(r){this.state.hydrate(r),this.scheduleRender()}applyDelta(r){const a=this.state.snapshot(),i=Wi(this.currentResponse,r);return Object.assign(a,i.stateUpdates),this.loadSnapshot({programText:i.programText,state:a}),i.warnings}loadSnapshot(r){this.currentResponse=r.programText,this.programDirty=!0,this.state.rebind([]),this.renderer.reset(),this.parseErrors=[],this.state.hydrate(r.state),this.scheduleRender()}appendChunk(r){if(r==null)return;const a=typeof r=="string"?r:String(r);a!==""&&(this.currentResponse+=a,this.programDirty=!0,this.scheduleRender())}setTheme(r){Yt(this,Kt(r)),this.scriptThemeKeys=[],this.scheduleRender()}registerComponents(r,a){this.library=yr(this.library,{components:r,root:a}),this.renderer.setLibrary(this.library),this.scheduleRender()}getSystemPrompt(r){return Vt(this.library,r??{})}navigate(r){this.router.navigate(r)}setTools(r){for(const a of Object.keys(this.tools))delete this.tools[a];for(const[a,i]of Object.entries(r??{}))typeof i=="function"&&(this.tools[a]=i)}get route(){return this.router.getPath()}clear(){this.currentResponse="",this.state.rebind([]),this.effectRunner.reset(),this.renderer.reset(),this.programDirty=!0,this.parseErrors=[],this.errorEl.hidden=!0,this.errorEl.replaceChildren(),this.rootEl.replaceChildren(),this.router.setActiveMatch(null,{})}get response(){return this.currentResponse}set response(r){this.setResponse(r)}get streaming(){return gi(this.getAttribute(Ye))}set streaming(r){r?this.setAttribute(Ye,"true"):this.removeAttribute(Ye)}get showErrors(){return gi(this.getAttribute(je))}set showErrors(r){r?this.setAttribute(je,"true"):this.removeAttribute(je)}buildInlineStyle(){const r=document.createElement("style");return r.textContent=di,r}startRouter(){this.router.start(),this.writeRouteState()}writeRouteState(){const r=Gd(this.router);Kd(this.state.get(pi),r)||this.state.set(pi,r)}attachPersistenceAdapter(){const r=typeof window<"u"?window.localStorage:null,a=`rui:${xt.tagName}:${this.id||"default"}`,i=$r(a,r??null);this.state.setPersistenceAdapter(i)}handleRouteChange(r){this.writeRouteState(),this.dispatchEvent(new CustomEvent("route-change",{detail:r,bubbles:!0,composed:!0})),this.scheduleRender()}applyThemeFromAttribute(){const r=this.getAttribute(Jt);Yt(this,Kt(r)),this.scriptThemeKeys=[]}applyScriptThemeOverrides(){this.scriptThemeKeys.length>0&&(li(this,this.scriptThemeKeys),this.scriptThemeKeys=[]);const r=this.context.bindings.get("theme");if(!r)return;let a;try{a=r()}catch{return}if(!Tr(a))return;const i=ci(a.tokens);Object.keys(i).length!==0&&(this.scriptThemeKeys=si(this,i))}scheduleRender(){this.renderScheduled||(this.renderScheduled=!0,queueMicrotask(()=>this.renderNow()))}renderNow(){if(this.renderScheduled=!1,!this.isConnected)return;this.programDirty&&(this.replan(),this.programDirty=!1),this.applyScriptThemeOverrides();const r=this.context.bindings.get("_app_")??this.context.bindings.get("root");let a=null;if(r)try{a=r()}catch(s){console.error("[aktion] _app_ evaluation error",s)}this.renderer.beginRender();const i=this.captureFocus(),n=this.renderer.render(a);Ju(this.rootEl,n),this.renderer.endRender(),this.restoreFocus(i)}captureFocus(){const r=this.root.activeElement;if(!r||!this.rootEl.contains(r))return null;const a=r.id||null;if(!a)return null;const i={id:a,tagName:r.tagName};return(r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement)&&(i.selectionStart=r.selectionStart,i.selectionEnd=r.selectionEnd,i.selectionDirection=r.selectionDirection??null),i}restoreFocus(r){if(!r)return;const a=this.rootEl.querySelector(`#${Jd(r.id)}`);!a||a.tagName!==r.tagName||this.root.activeElement===a||(a.focus(),(a instanceof HTMLInputElement||a instanceof HTMLTextAreaElement)&&r.selectionStart!=null&&r.selectionEnd!=null&&Zd(a,r.selectionStart,r.selectionEnd,r.selectionDirection??"none"))}replan(){this.effectRunner.reset(),this.context=Pt(this.state,{router:this.router,library:this.library,http:this.http,i18n:this.i18n,actionRunner:this.actionDeclRunner,notify:()=>this.scheduleRender(),jsBlockExecutor:ia({state:this.state,host:this,tools:this.tools})});const r=fe(this.currentResponse),a=$t(r,this.library);a.length>0&&(r.errors=[...r.errors,...a]),Hr(r,this.context);const i=[...this.context.effectDecls.values()];i.length>0&&this.effectRunner.syncEffects(i,()=>this.context),this.writeRouteState(),this.parseErrors=[...r.errors.map(n=>`Line ${n.line}: ${n.message}`),...this.effectRunner.getErrors()],this.updateErrorBanner(),r.errors.length>0&&!this.streaming&&this.dispatchEvent(new CustomEvent("error",{detail:{errors:r.errors},bubbles:!0,composed:!0}))}updateErrorBanner(){if(!this.showErrors||this.streaming||this.parseErrors.length===0){this.errorEl.hidden=!0,this.errorEl.replaceChildren();return}this.errorEl.hidden=!1;const r=document.createElement("div");r.textContent=`${this.parseErrors.length} parse issue${this.parseErrors.length===1?"":"s"} (rendered partial UI):`;const a=document.createElement("ul");for(const i of this.parseErrors.slice(0,5)){const n=document.createElement("li");n.textContent=i,a.append(n)}this.errorEl.replaceChildren(r,a)}};j(xt,"tagName","aktion-app");let Be=xt;function Jd(t){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(t):t.replace(/([^A-Za-z0-9_-])/g,"\\$1")}const Xd=new Set(["email","number","tel","url","date","datetime-local","month","week","time","color"]);function Zd(t,e,r,a){if(t instanceof HTMLInputElement&&Xd.has(t.type)){const i=t.type;try{t.type="text",t.setSelectionRange(e,r,a)}catch{}finally{t.type=i}return}try{t.setSelectionRange(e,r,a)}catch{}}function gi(t){if(t===null)return!1;const e=t.trim().toLowerCase();return e===""||e==="true"||e==="1"||e===je}function fi(){customElements.get(Be.tagName)||customElements.define(Be.tagName,Be)}const yt={name:"aktion",atoms:["true","false","null"],operators:["+","-","*","/","%","!","=","<",">","?",":",".",","],operatorsLong:["...","==","!=",">=","<=","&&","||","??","?."],brackets:[{open:"(",close:")"},{open:"[",close:"]"},{open:"{",close:"}"}],comments:{line:"//",extraLine:["#"],blockStart:"/*",blockEnd:"*/"},strings:{singleLineQuotes:['"',"'"],multiLineQuote:"`"},identifier:{start:/[A-Za-z_]/,part:/[A-Za-z0-9_]/},sigils:{builtin:"@",state:"$"}};function hi(t=yt){const e=()=>({inBacktick:!1,inBlockComment:!1}),r=p=>({...p}),a=new Set(t.atoms),i=/^[A-Z][A-Za-z0-9_]*/,n=/^[a-z_][A-Za-z0-9_]*/,s=/^-?\d+(?:\.\d+)?/,l=new Set([...t.operators.join(""),..."=<>!&|"]),c=(p,m)=>{for(;!p.eol();){const g=p.next();if(!g)return;if(g==="\\"){p.next();continue}if(g===m)return}};return{startState:e,copyState:r,token:(p,m)=>{if(m.inBacktick){for(;!p.eol();){const f=p.next();if(f==="\\"){p.next();continue}if(f==="`")return m.inBacktick=!1,"string"}return"string"}if(m.inBlockComment){for(;!p.eol();){if(p.match(t.comments.blockEnd,!0))return m.inBlockComment=!1,"comment";p.next()}return"comment"}if(p.eatWhile(/[ \t]/))return null;if(p.match(t.comments.line,!0))return p.skipToEnd(),"comment";for(const f of t.comments.extraLine)if(p.match(f,!0))return p.skipToEnd(),"comment";if(p.match(t.comments.blockStart,!0)){for(m.inBlockComment=!0;!p.eol();){if(p.match(t.comments.blockEnd,!0))return m.inBlockComment=!1,"comment";p.next()}return"comment"}const g=p.peek();if(g==null)return null;if(t.strings.singleLineQuotes.includes(g)){const f=g;return p.next(),c(p,f),"string"}if(g===t.strings.multiLineQuote){for(p.next();!p.eol();){const f=p.next();if(f==="\\"){p.next();continue}if(f==="`")return"string"}return m.inBacktick=!0,"string"}if(g>="0"&&g<="9"&&p.match(s,!0)||g==="-"&&p.match(/^-\d+(?:\.\d+)?/,!1)&&p.match(s,!0))return"number";if(g===t.sigils.builtin)return p.next(),p.eatWhile(t.identifier.part),"builtin";if(g===t.sigils.state)return p.next(),p.peek()===t.sigils.state&&p.next(),p.eatWhile(t.identifier.part),"state";if(t.identifier.start.test(g)){if(p.match(i,!0))return"component";const h=p.match(n,!0);if(h){const b=h[0];return a.has(b)?"atom":p.peek()==="."?"loopvar":"identifier"}}for(const f of t.operatorsLong)if(p.match(f,!0))return"operator";return g==="."?(p.next(),p.peek()&&t.identifier.start.test(p.peek())?(p.eatWhile(t.identifier.part),"property"):"punctuation"):"()[]{},:?".includes(g)?(p.next(),"punctuation"):l.has(g)?(p.next(),"operator"):(p.next(),null)},languageData:{commentTokens:{line:t.comments.line,block:{open:t.comments.blockStart,close:t.comments.blockEnd}},closeBrackets:{brackets:["(","[","{",'"',"'","`"]},indentOnInput:/^\s*[)\]}]$/}}}const bi={comment:"comment",string:"string",number:"number",atom:"atom",builtin:"keyword",state:"variableName.special",component:"typeName",identifier:"variableName",loopvar:"variableName.local",property:"propertyName",operator:"operator",punctuation:null},Qd=t=>{const e={name:t.name,type:t.type,required:!t.optional};return t.description&&(e.description=t.description),t.enum&&t.enum.length>0&&(e.enumValues=t.enum),e},ep=t=>{const e=t.props.map(r=>r.optional?`${r.name}?`:r.name);return`${t.name}(${e.join(", ")})`},tp=t=>{const e=new Map;for(const r of t.componentGroups??[])for(const a of r.components)e.set(a,r.name);return e};function vi(t=Ke){const e=tp(t);return t.components.map(r=>({name:r.name,group:e.get(r.name)??"Other",description:r.description,params:r.props.map(Qd),signature:ep(r)}))}function yi(t){const e={};for(const r of t)e[r.name]=r;return e}const rp=[{name:"App",description:"Top-level `_app_` binding — every program needs one.",template:'_app_ = Stack([\n ${1:Card([CardHeader("${2:Hello}")])}\n])'},{name:"Card",description:"Card with header + body block.",template:`card\${1} = Card([
8387
+ `,Zt="theme",Ye="streaming",Qt="response",je="showerrors",mi="route";function Kd(t){const e=t.getPath(),r={...t.getParams()},a=t.getActivePattern(),i={};if(typeof window<"u"&&window.location){const n=window.location.search||"";if(n){const s=new URLSearchParams(n.startsWith("?")?n.slice(1):n);for(const[l,c]of s)i[l]=c}}return{path:e,params:r,pattern:a,query:i,navigate(n){typeof n!="string"||!n||t.navigate(n)},toString(){return e}}}function Yd(t,e){if(!t||!e||typeof t!="object"||typeof e!="object")return!1;const r=t,a=e;return r.path!==a.path||r.pattern!==a.pattern?!1:gi(r.params??{},a.params??{})&&gi(r.query??{},a.query??{})}function gi(t,e){const r=Object.keys(t),a=Object.keys(e);if(r.length!==a.length)return!1;for(const i of r)if(t[i]!==e[i])return!1;return!0}let er=null,vt=null;function Jd(){if(vt===!1)return null;if(er)return er;try{if(typeof CSSStyleSheet>"u"||!("replaceSync"in CSSStyleSheet.prototype)||typeof document>"u"||!("adoptedStyleSheets"in Document.prototype))return vt=!1,null;const t=new CSSStyleSheet;return t.replaceSync(pi),er=t,vt=!0,t}catch{return vt=!1,null}}const xt=class xt extends HTMLElement{constructor(){super();j(this,"state",new Ar);j(this,"router",new Er);j(this,"library",Ke);j(this,"http",new Pr);j(this,"i18n",new Qr);j(this,"effectRunner");j(this,"actionDeclRunner");j(this,"tools",{});j(this,"renderer");j(this,"context");j(this,"root");j(this,"rootEl");j(this,"errorEl");j(this,"currentResponse","");j(this,"renderScheduled",!1);j(this,"programDirty",!0);j(this,"parseErrors",[]);j(this,"scriptThemeKeys",[]);this.root=this.attachShadow({mode:"open"}),this.errorEl=document.createElement("div"),this.errorEl.className="rui-error-banner",this.errorEl.hidden=!0,this.rootEl=document.createElement("div"),this.rootEl.className="rui-root";const r=Jd();if(r)try{this.root.adoptedStyleSheets=[r],this.root.append(this.errorEl,this.rootEl)}catch{this.root.append(this.buildInlineStyle(),this.errorEl,this.rootEl)}else this.root.append(this.buildInlineStyle(),this.errorEl,this.rootEl);const a=n=>{this.dispatchEvent(new CustomEvent("assistant-message",{detail:{message:n},bubbles:!0,composed:!0}))},i=(n,s)=>{this.dispatchEvent(new CustomEvent(n,{detail:s,bubbles:!0,composed:!0}))};this.effectRunner=new ra({state:this.state,notify:()=>this.scheduleRender(),onEmit:i,host:this,tools:this.tools}),this.actionDeclRunner=new oa({state:this.state,notify:()=>this.scheduleRender(),onEmit:i,onAssistantMessage:a,host:this,tools:this.tools}),this.context=Pt(this.state,{router:this.router,library:this.library,http:this.http,i18n:this.i18n,actionRunner:this.actionDeclRunner,notify:()=>this.scheduleRender(),jsBlockExecutor:na({state:this.state,host:this,tools:this.tools})}),this.renderer=new Ja({library:this.library,state:this.state,router:this.router,onAssistantMessage:a,evaluationContext:()=>this.context,mountInstanceEffects:(n,s,l)=>this.effectRunner.syncInstanceEffects(n,s,l),unmountInstanceEffects:n=>this.effectRunner.unmountInstance(n)}),this.state.subscribe(()=>this.scheduleRender()),this.router.subscribe(n=>this.handleRouteChange(n))}static get observedAttributes(){return[Zt,Ye,Qt,je]}connectedCallback(){to(this.root),this.applyThemeFromAttribute(),this.startRouter(),this.attachPersistenceAdapter();const r=this.getAttribute(Qt);if(r!==null&&r!==""&&r!==this.currentResponse){this.setResponse(r);return}if(!this.currentResponse){const a=(this.textContent??"").trim();if(a){this.setResponse(a);return}}this.currentResponse&&(this.programDirty=!0,this.scheduleRender())}disconnectedCallback(){this.effectRunner.reset(),this.router.stop()}attributeChangedCallback(r,a,i){if(r===Zt&&this.applyThemeFromAttribute(),r===Ye&&(this.updateErrorBanner(),this.scheduleRender()),r===je&&this.updateErrorBanner(),r===Qt){const n=i??"";n!==this.currentResponse&&this.setResponse(n)}}registerHttpInterceptors(r){this.http.registerInterceptors(r)}setResponse(r){r!==this.currentResponse&&(this.currentResponse=r,this.programDirty=!0,this.state.rebind([]),this.renderer.reset(),this.parseErrors=[],this.scheduleRender())}serializeState(){return this.state.snapshot()}hydrateState(r){this.state.hydrate(r),this.scheduleRender()}applyDelta(r){const a=this.state.snapshot(),i=Gi(this.currentResponse,r);return Object.assign(a,i.stateUpdates),this.loadSnapshot({programText:i.programText,state:a}),i.warnings}loadSnapshot(r){this.currentResponse=r.programText,this.programDirty=!0,this.state.rebind([]),this.renderer.reset(),this.parseErrors=[],this.state.hydrate(r.state),this.scheduleRender()}appendChunk(r){if(r==null)return;const a=typeof r=="string"?r:String(r);a!==""&&(this.currentResponse+=a,this.programDirty=!0,this.scheduleRender())}setTheme(r){Xt(this,Jt(r)),this.scriptThemeKeys=[],this.scheduleRender()}registerComponents(r,a){this.library=wr(this.library,{components:r,root:a}),this.renderer.setLibrary(this.library),this.scheduleRender()}getSystemPrompt(r){return Gt(this.library,r??{})}navigate(r){this.router.navigate(r)}setTools(r){for(const a of Object.keys(this.tools))delete this.tools[a];for(const[a,i]of Object.entries(r??{}))typeof i=="function"&&(this.tools[a]=i)}get route(){return this.router.getPath()}clear(){this.currentResponse="",this.state.rebind([]),this.effectRunner.reset(),this.renderer.reset(),this.programDirty=!0,this.parseErrors=[],this.errorEl.hidden=!0,this.errorEl.replaceChildren(),this.rootEl.replaceChildren(),this.router.setActiveMatch(null,{})}get response(){return this.currentResponse}set response(r){this.setResponse(r)}get streaming(){return fi(this.getAttribute(Ye))}set streaming(r){r?this.setAttribute(Ye,"true"):this.removeAttribute(Ye)}get showErrors(){return fi(this.getAttribute(je))}set showErrors(r){r?this.setAttribute(je,"true"):this.removeAttribute(je)}buildInlineStyle(){const r=document.createElement("style");return r.textContent=pi,r}startRouter(){this.router.start(),this.writeRouteState()}writeRouteState(){const r=Kd(this.router);Yd(this.state.get(mi),r)||this.state.set(mi,r)}attachPersistenceAdapter(){const r=typeof window<"u"?window.localStorage:null,a=`rui:${xt.tagName}:${this.id||"default"}`,i=Mr(a,r??null);this.state.setPersistenceAdapter(i)}handleRouteChange(r){this.writeRouteState(),this.dispatchEvent(new CustomEvent("route-change",{detail:r,bubbles:!0,composed:!0})),this.scheduleRender()}applyThemeFromAttribute(){const r=this.getAttribute(Zt);Xt(this,Jt(r)),this.scriptThemeKeys=[]}applyScriptThemeOverrides(){this.scriptThemeKeys.length>0&&(ci(this,this.scriptThemeKeys),this.scriptThemeKeys=[]);const r=this.context.bindings.get("theme");if(!r)return;let a;try{a=r()}catch{return}if(!Nr(a))return;const i=ui(a.tokens);Object.keys(i).length!==0&&(this.scriptThemeKeys=li(this,i))}scheduleRender(){this.renderScheduled||(this.renderScheduled=!0,queueMicrotask(()=>this.renderNow()))}renderNow(){if(this.renderScheduled=!1,!this.isConnected)return;this.programDirty&&(this.replan(),this.programDirty=!1),this.applyScriptThemeOverrides();const r=this.context.bindings.get("_app_")??this.context.bindings.get("root");let a=null;if(r)try{a=r()}catch(s){console.error("[aktion] _app_ evaluation error",s)}this.renderer.beginRender();const i=this.captureFocus(),n=this.renderer.render(a);Xu(this.rootEl,n),this.renderer.endRender(),this.restoreFocus(i)}captureFocus(){const r=this.root.activeElement;if(!r||!this.rootEl.contains(r))return null;const a=r.id||null;if(!a)return null;const i={id:a,tagName:r.tagName};return(r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement)&&(i.selectionStart=r.selectionStart,i.selectionEnd=r.selectionEnd,i.selectionDirection=r.selectionDirection??null),i}restoreFocus(r){if(!r)return;const a=this.rootEl.querySelector(`#${Xd(r.id)}`);!a||a.tagName!==r.tagName||this.root.activeElement===a||(a.focus(),(a instanceof HTMLInputElement||a instanceof HTMLTextAreaElement)&&r.selectionStart!=null&&r.selectionEnd!=null&&Qd(a,r.selectionStart,r.selectionEnd,r.selectionDirection??"none"))}replan(){this.effectRunner.reset(),this.context=Pt(this.state,{router:this.router,library:this.library,http:this.http,i18n:this.i18n,actionRunner:this.actionDeclRunner,notify:()=>this.scheduleRender(),jsBlockExecutor:na({state:this.state,host:this,tools:this.tools})});const r=fe(this.currentResponse),a=Nt(r,this.library);a.length>0&&(r.errors=[...r.errors,...a]),Wr(r,this.context);const i=[...this.context.effectDecls.values()];i.length>0&&this.effectRunner.syncEffects(i,()=>this.context),this.writeRouteState(),this.parseErrors=[...r.errors.map(n=>`Line ${n.line}: ${n.message}`),...this.effectRunner.getErrors()],this.updateErrorBanner(),r.errors.length>0&&!this.streaming&&this.dispatchEvent(new CustomEvent("error",{detail:{errors:r.errors},bubbles:!0,composed:!0}))}updateErrorBanner(){if(!this.showErrors||this.streaming||this.parseErrors.length===0){this.errorEl.hidden=!0,this.errorEl.replaceChildren();return}this.errorEl.hidden=!1;const r=document.createElement("div");r.textContent=`${this.parseErrors.length} parse issue${this.parseErrors.length===1?"":"s"} (rendered partial UI):`;const a=document.createElement("ul");for(const i of this.parseErrors.slice(0,5)){const n=document.createElement("li");n.textContent=i,a.append(n)}this.errorEl.replaceChildren(r,a)}};j(xt,"tagName","aktion-app");let Be=xt;function Xd(t){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(t):t.replace(/([^A-Za-z0-9_-])/g,"\\$1")}const Zd=new Set(["email","number","tel","url","date","datetime-local","month","week","time","color"]);function Qd(t,e,r,a){if(t instanceof HTMLInputElement&&Zd.has(t.type)){const i=t.type;try{t.type="text",t.setSelectionRange(e,r,a)}catch{}finally{t.type=i}return}try{t.setSelectionRange(e,r,a)}catch{}}function fi(t){if(t===null)return!1;const e=t.trim().toLowerCase();return e===""||e==="true"||e==="1"||e===je}function hi(){customElements.get(Be.tagName)||customElements.define(Be.tagName,Be)}const yt={name:"aktion",atoms:["true","false","null"],operators:["+","-","*","/","%","!","=","<",">","?",":",".",","],operatorsLong:["...","==","!=",">=","<=","&&","||","??","?."],brackets:[{open:"(",close:")"},{open:"[",close:"]"},{open:"{",close:"}"}],comments:{line:"//",extraLine:["#"],blockStart:"/*",blockEnd:"*/"},strings:{singleLineQuotes:['"',"'"],multiLineQuote:"`"},identifier:{start:/[A-Za-z_]/,part:/[A-Za-z0-9_]/},sigils:{builtin:"@",state:"$"}};function bi(t=yt){const e=()=>({inBacktick:!1,inBlockComment:!1}),r=p=>({...p}),a=new Set(t.atoms),i=/^[A-Z][A-Za-z0-9_]*/,n=/^[a-z_][A-Za-z0-9_]*/,s=/^-?\d+(?:\.\d+)?/,l=new Set([...t.operators.join(""),..."=<>!&|"]),c=(p,m)=>{for(;!p.eol();){const g=p.next();if(!g)return;if(g==="\\"){p.next();continue}if(g===m)return}};return{startState:e,copyState:r,token:(p,m)=>{if(m.inBacktick){for(;!p.eol();){const f=p.next();if(f==="\\"){p.next();continue}if(f==="`")return m.inBacktick=!1,"string"}return"string"}if(m.inBlockComment){for(;!p.eol();){if(p.match(t.comments.blockEnd,!0))return m.inBlockComment=!1,"comment";p.next()}return"comment"}if(p.eatWhile(/[ \t]/))return null;if(p.match(t.comments.line,!0))return p.skipToEnd(),"comment";for(const f of t.comments.extraLine)if(p.match(f,!0))return p.skipToEnd(),"comment";if(p.match(t.comments.blockStart,!0)){for(m.inBlockComment=!0;!p.eol();){if(p.match(t.comments.blockEnd,!0))return m.inBlockComment=!1,"comment";p.next()}return"comment"}const g=p.peek();if(g==null)return null;if(t.strings.singleLineQuotes.includes(g)){const f=g;return p.next(),c(p,f),"string"}if(g===t.strings.multiLineQuote){for(p.next();!p.eol();){const f=p.next();if(f==="\\"){p.next();continue}if(f==="`")return"string"}return m.inBacktick=!0,"string"}if(g>="0"&&g<="9"&&p.match(s,!0)||g==="-"&&p.match(/^-\d+(?:\.\d+)?/,!1)&&p.match(s,!0))return"number";if(g===t.sigils.builtin)return p.next(),p.eatWhile(t.identifier.part),"builtin";if(g===t.sigils.state)return p.next(),p.peek()===t.sigils.state&&p.next(),p.eatWhile(t.identifier.part),"state";if(t.identifier.start.test(g)){if(p.match(i,!0))return"component";const h=p.match(n,!0);if(h){const b=h[0];return a.has(b)?"atom":p.peek()==="."?"loopvar":"identifier"}}for(const f of t.operatorsLong)if(p.match(f,!0))return"operator";return g==="."?(p.next(),p.peek()&&t.identifier.start.test(p.peek())?(p.eatWhile(t.identifier.part),"property"):"punctuation"):"()[]{},:?".includes(g)?(p.next(),"punctuation"):l.has(g)?(p.next(),"operator"):(p.next(),null)},languageData:{commentTokens:{line:t.comments.line,block:{open:t.comments.blockStart,close:t.comments.blockEnd}},closeBrackets:{brackets:["(","[","{",'"',"'","`"]},indentOnInput:/^\s*[)\]}]$/}}}const vi={comment:"comment",string:"string",number:"number",atom:"atom",builtin:"keyword",state:"variableName.special",component:"typeName",identifier:"variableName",loopvar:"variableName.local",property:"propertyName",operator:"operator",punctuation:null},ep=t=>{const e={name:t.name,type:t.type,required:!t.optional};return t.description&&(e.description=t.description),t.enum&&t.enum.length>0&&(e.enumValues=t.enum),e},tp=t=>{const e=t.props.map(r=>r.optional?`${r.name}?`:r.name);return`${t.name}(${e.join(", ")})`},rp=t=>{const e=new Map;for(const r of t.componentGroups??[])for(const a of r.components)e.set(a,r.name);return e};function yi(t=Ke){const e=rp(t);return t.components.map(r=>({name:r.name,group:e.get(r.name)??"Other",description:r.description,params:r.props.map(ep),signature:tp(r)}))}function xi(t){const e={};for(const r of t)e[r.name]=r;return e}const ap=[{name:"App",description:"Top-level `_app_` binding — every program needs one.",template:'_app_ = Stack([\n ${1:Card([CardHeader("${2:Hello}")])}\n])'},{name:"Card",description:"Card with header + body block.",template:`card\${1} = Card([
8346
8388
  CardHeader("\${2:Title}", subtitle: "\${3:Subtitle}"),
8347
8389
  Stack([
8348
8390
  Text("\${4:Body copy goes here.}")
@@ -8427,5 +8469,5 @@ list = for u in $users { \${1:UserCard}(u) }`},{name:"If",description:"Expressio
8427
8469
  url: "\${2:/api/items}",
8428
8470
  method: "\${3:GET}",
8429
8471
  headers: { "Content-Type": "application/json" }
8430
- })`},{name:"State",description:"Reactive state atom — declared with `$name = value`.",template:'$${1:name} = ${2:"default"}'},{name:"ResponsiveGrid",description:"Grid with a responsive column map per breakpoint.",template:'cards${1} = Grid(${2:items}, columns: {sm: 1, md: 2, lg: 4}, gap: "${3:l}")'}];function xi(){return rp}function ap(t=Ke){const e=vi(t),r=gt();return{grammar:yt,tokenizer:hi(yt),tagMap:bi,components:e,componentsByName:yi(e),builtins:r,builtinsByName:Qa(r),snippets:xi(),themeNames:Object.keys(Gt),severityTokenMap:{"parse-error":"error"},iconAliases:ip}}const ip=["house","user","users","gear","bell","envelope","magnifying-glass","plus","minus","pen","trash","check","xmark","arrow-right","arrow-left","arrow-up","arrow-down","chevron-right","chevron-left","chevron-down","chevron-up","ellipsis","ellipsis-vertical","star","heart","bookmark","calendar","clock","file","folder","image","video","music","chart-line","chart-bar","chart-pie","gauge","table","circle-info","circle-check","circle-exclamation","circle-question","triangle-exclamation","shield","lock","unlock","key","rocket","bolt","fire","snowflake","sun","moon","cloud","code","terminal","database","server","globe","link","share","download","upload","filter","sort","list","grid","columns","sidebar","bars","tag","tags","flag","trophy","medal","gift","cart-shopping","credit-card","money-bill","receipt","wallet","comment","comments","paper-plane","inbox","paper-clip","phone","video-camera","play","pause","stop","forward","backward","expand","compress","eye","eye-slash","thumbs-up","thumbs-down","thumbtack"];fi();const np=Vt(Ke);return I.ActionDeclRunner=na,I.AktionElement=Be,I.EffectRunner=ta,I.HttpRuntime=Ar,I.I18nRuntime=Zr,I.Renderer=Ya,I.Router=Rr,I.SYSTEM_PROMPT_TEXT=np,I.StateStore=Nr,I.applyPartialTheme=si,I.applyTheme=Yt,I.assertOnePositionalMax=xr,I.brutalistTheme=ni,I.buildFrontier=fr,I.builtInThemes=Gt,I.clearTokenOverrides=li,I.computeFrontier=qi,I.consoleNs=Dr,I.createContext=Pt,I.createHttpResource=Ir,I.createLocalStorageAdapter=$r,I.createStreamTokenizer=hi,I.darkTheme=ti,I.dataBuiltins=At,I.defaultLibrary=Ke,I.defaultTagMap=bi,I.defineElement=fi,I.describeComponentSpec=od,I.evaluate=M,I.evaluateUserComponent=Gr,I.findComponent=Ie,I.findPositionalIndex=Tt,I.findPositionalProp=Nt,I.generatePrompt=Vt,I.getBuiltinCatalog=gt,I.getComponentCatalog=vi,I.getLanguageSpec=ap,I.getSnippets=xi,I.glassTheme=ii,I.grammarSpec=yt,I.indexBuiltins=Qa,I.indexCatalog=yi,I.isComponentNode=Or,I.isQuiescent=Hi,I.isThemeNode=Tr,I.isUserComponentNode=Ur,I.lightTheme=ce,I.mapPositionalArgs=wr,I.matchRoute=zr,I.mergeLibraries=yr,I.neonTheme=ri,I.normalisePath=we,I.parse=fe,I.pastelTheme=ai,I.planProgram=Hr,I.resolveStateAlias=ke,I.resolveTheme=Kt,I.sanitiseThemeTokens=ci,I.skylineTheme=oi,I.storage=Br,I.tokenize=rr,I.validateProgram=Ji,I.validateProgramSchema=$t,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"}),I}({});
8472
+ })`},{name:"State",description:"Reactive state atom — declared with `$name = value`.",template:'$${1:name} = ${2:"default"}'},{name:"ResponsiveGrid",description:"Grid with a responsive column map per breakpoint.",template:'cards${1} = Grid(${2:items}, columns: {sm: 1, md: 2, lg: 4}, gap: "${3:l}")'}];function wi(){return ap}function ip(t=Ke){const e=yi(t),r=gt();return{grammar:yt,tokenizer:bi(yt),tagMap:vi,components:e,componentsByName:xi(e),builtins:r,builtinsByName:ei(r),snippets:wi(),themeNames:Object.keys(Yt),severityTokenMap:{"parse-error":"error"},iconAliases:np}}const np=["house","user","users","gear","bell","envelope","magnifying-glass","plus","minus","pen","trash","check","xmark","arrow-right","arrow-left","arrow-up","arrow-down","chevron-right","chevron-left","chevron-down","chevron-up","ellipsis","ellipsis-vertical","star","heart","bookmark","calendar","clock","file","folder","image","video","music","chart-line","chart-bar","chart-pie","gauge","table","circle-info","circle-check","circle-exclamation","circle-question","triangle-exclamation","shield","lock","unlock","key","rocket","bolt","fire","snowflake","sun","moon","cloud","code","terminal","database","server","globe","link","share","download","upload","filter","sort","list","grid","columns","sidebar","bars","tag","tags","flag","trophy","medal","gift","cart-shopping","credit-card","money-bill","receipt","wallet","comment","comments","paper-plane","inbox","paper-clip","phone","video-camera","play","pause","stop","forward","backward","expand","compress","eye","eye-slash","thumbs-up","thumbs-down","thumbtack"];hi();const op=Gt(Ke);return I.ActionDeclRunner=oa,I.AktionElement=Be,I.EffectRunner=ra,I.HttpRuntime=Pr,I.I18nRuntime=Qr,I.Renderer=Ja,I.Router=Er,I.SYSTEM_PROMPT_TEXT=op,I.StateStore=Ar,I.applyPartialTheme=li,I.applyTheme=Xt,I.assertOnePositionalMax=kr,I.brutalistTheme=oi,I.buildFrontier=br,I.builtInThemes=Yt,I.clearTokenOverrides=ci,I.computeFrontier=Hi,I.consoleNs=Or,I.createContext=Pt,I.createHttpResource=Rr,I.createLocalStorageAdapter=Mr,I.createStreamTokenizer=bi,I.darkTheme=ri,I.dataBuiltins=At,I.defaultLibrary=Ke,I.defaultTagMap=vi,I.defineElement=hi,I.describeComponentSpec=sd,I.evaluate=M,I.evaluateUserComponent=Kr,I.findComponent=Ie,I.findPositionalIndex=Tt,I.findPositionalProp=$t,I.generatePrompt=Gt,I.getBuiltinCatalog=gt,I.getComponentCatalog=yi,I.getLanguageSpec=ip,I.getSnippets=wi,I.glassTheme=ni,I.grammarSpec=yt,I.indexBuiltins=ei,I.indexCatalog=xi,I.isComponentNode=qr,I.isQuiescent=Vi,I.isThemeNode=Nr,I.isUserComponentNode=Hr,I.lightTheme=ce,I.mapPositionalArgs=Sr,I.matchRoute=Lr,I.mergeLibraries=wr,I.neonTheme=ai,I.normalisePath=we,I.parse=fe,I.pastelTheme=ii,I.planProgram=Wr,I.resolveStateAlias=ke,I.resolveTheme=Jt,I.sanitiseThemeTokens=ui,I.skylineTheme=si,I.storage=Fr,I.tokenize=ir,I.validateProgram=Xi,I.validateProgramSchema=Nt,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"}),I}({});
8431
8473
  //# sourceMappingURL=aktion.iife.js.map