@stacksjs/stx 0.2.82 → 0.2.84

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.
Files changed (62) hide show
  1. package/dist/app-shell.js +21 -11
  2. package/dist/build-assets.js +19 -9
  3. package/dist/build-mode-detector.js +22 -12
  4. package/dist/build-views.js +22 -12
  5. package/dist/build.js +21 -11
  6. package/dist/caching.js +19 -9
  7. package/dist/cli.js +22 -12
  8. package/dist/component-processing.js +21 -11
  9. package/dist/component-renderer.js +21 -11
  10. package/dist/components.js +22 -12
  11. package/dist/conditionals.js +1 -1
  12. package/dist/custom-directives.js +1 -1
  13. package/dist/dev-server/index.js +22 -12
  14. package/dist/dev-server/serve-app.js +21 -11
  15. package/dist/dev-server/serve-file.js +21 -11
  16. package/dist/dev-server/serve-markdown.js +22 -12
  17. package/dist/dev-server/serve-multi.js +21 -11
  18. package/dist/dev-server.js +21 -11
  19. package/dist/docs.js +22 -12
  20. package/dist/dynamic-components.js +21 -11
  21. package/dist/error-handling.js +1 -1
  22. package/dist/errors/formatter.js +1 -1
  23. package/dist/errors/index.js +1 -1
  24. package/dist/i18n.js +1 -1
  25. package/dist/includes.js +21 -11
  26. package/dist/index.js +21 -11
  27. package/dist/interactive.js +22 -12
  28. package/dist/lazy-loader.js +98 -88
  29. package/dist/misc-directives.js +1 -1
  30. package/dist/plugin.js +21 -11
  31. package/dist/process.js +21 -11
  32. package/dist/production-builder.js +21 -11
  33. package/dist/production-server.js +21 -11
  34. package/dist/pwa/index.js +22 -12
  35. package/dist/pwa/offline.js +22 -12
  36. package/dist/pwa.js +21 -11
  37. package/dist/reactive.js +1 -1
  38. package/dist/render.js +22 -12
  39. package/dist/runtime-injection.js +19 -9
  40. package/dist/seo.js +1 -1
  41. package/dist/serve.js +22 -12
  42. package/dist/signal-processing.js +41 -31
  43. package/dist/signals.js +19 -9
  44. package/dist/site-builder/build.js +22 -12
  45. package/dist/site-builder/index.js +22 -12
  46. package/dist/ssg.js +21 -11
  47. package/dist/ssr.js +22 -12
  48. package/dist/store-loader.js +18 -18
  49. package/dist/story/cli.js +22 -12
  50. package/dist/story/commands/dev.js +22 -12
  51. package/dist/story/commands/index.js +22 -12
  52. package/dist/story/index.js +22 -12
  53. package/dist/story/renderer.js +22 -12
  54. package/dist/story/server.js +22 -12
  55. package/dist/story/visual-testing.js +22 -12
  56. package/dist/streaming.js +21 -11
  57. package/dist/template-compiler.js +22 -12
  58. package/dist/template-hydrator.js +22 -12
  59. package/dist/testing.js +147 -137
  60. package/dist/utils.js +21 -11
  61. package/dist/web-components.js +22 -12
  62. package/package.json +5 -5
@@ -1783,7 +1783,7 @@ ${W}`)}if($.suggestion)z.push(`
1783
1783
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),z.join("")}function lK($,Z,Y){let X=$.split(`
1784
1784
  `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G=[];for(let K=J;K<=Q;K++){let q=(K+1).toString().padStart(4),z=K===Z-1?">":" ";G.push(`${z}${q} | ${X[K]}`)}return G.join(`
1785
1785
  `)}function cK($,Z,Y){let X=$.split(`
1786
- `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G="\x1B[90m",K="\x1B[31m",q="\x1B[0m",z=[];for(let U=J;U<=Q;U++){let W=(U+1).toString().padStart(4),_=U===Z-1,B=_?"\x1B[31m>\x1B[0m":" ",j=_?`\x1B[31m${X[U]}\x1B[0m`:`\x1B[90m${X[U]}`;z.push(`${B}${W}\x1B[0m | ${j}`)}return z.join(`
1786
+ `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G="\x1B[90m",K="\x1B[31m",q="\x1B[0m",z=[];for(let U=J;U<=Q;U++){let W=(U+1).toString().padStart(4),_=U===Z-1,B=_?"\x1B[31m>\x1B[0m":" ",j=_?`\x1B[31m${X[U]}\x1B[0m`:`\x1B[90m${X[U]}\x1B[0m`;z.push(`${B}\x1B[90m${W}\x1B[0m | ${j}`)}return z.join(`
1787
1787
  `)}function QZ($){return $.replace(/--/g,"- -").replace(/>/g,"&gt;")}function GZ($,Z){let X=$.substring(0,Z).split(`
1788
1788
  `);return{line:X.length,column:X[X.length-1].length}}function o($,Z,Y){return t7({type:$,message:Z,code:Y,format:"html"}).formatted}function pK($,Z,Y,X,J){return t7({type:$,message:Z,code:J,filePath:Y,line:X,format:"console"}).formatted}function iK($,Z,Y){let X=Y.template.split(`
1789
1789
  `),J=GZ(Y.template,Y.offset),Q=`[${$} Error at line ${J.line} in ${Y.filePath}]: ${Z}
@@ -3756,7 +3756,7 @@ window.__stx_reactive = (function() {
3756
3756
 
3757
3757
  return { initScope: initScope, reactive: reactive };
3758
3758
  })();
3759
- `}function cZ($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=g0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=g0(J,Z,!0);if(Q===void 0)return X;return JSON.stringify(Q)}catch{return X}}),Y}function $z($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=cZ(X.stateExpr,Z),G=X.initExpr?cZ(X.initExpr,Z):null,K=JSON.stringify(Q),q=G?JSON.stringify(G):"null";return`
3759
+ `}function cZ($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=g0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=g0(J,Z,!0);if(Q===void 0)return X;if(typeof Q==="string"){let G=Q.trim();if(G.startsWith("{")&&G.endsWith("}")||G.startsWith("[")&&G.endsWith("]"))try{return JSON.parse(G),G}catch{}}return JSON.stringify(Q)}catch{return X}}),Y}function $z($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=cZ(X.stateExpr,Z),G=X.initExpr?cZ(X.initExpr,Z):null,K=JSON.stringify(Q),q=G?JSON.stringify(G):"null";return`
3760
3760
  (function() {
3761
3761
  var scopeEl = document.querySelector('${X.selector}');
3762
3762
  if (!scopeEl) return;
@@ -5996,6 +5996,13 @@ catch (e2) {
5996
5996
 
5997
5997
  // Known directive names to exclude from generic :attr binding
5998
5998
  var DIRECTIVE_NAMES = {class:1, style:1, text:1, html:1, show:1, model:1, 'if':1, 'for':1, ref:1};
5999
+ // SVG attributes are case-sensitive, but the HTML parser lowercases
6000
+ // prefixed attribute names \u2014 ':viewBox' arrives as ':viewbox' because
6001
+ // the spec's "adjust SVG attributes" step only covers unprefixed names.
6002
+ // Without restoring the canonical casing, setAttribute('viewbox') creates
6003
+ // a dead duplicate attribute and the real viewBox never updates.
6004
+ var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
6005
+ var SVG_NS = 'http://www.w3.org/2000/svg';
5999
6006
  var EVENT_RE = /^(click|dblclick|mousedown|mouseup|mousemove|mouseenter|mouseleave|keydown|keyup|keypress|input|change|submit|focus|blur|scroll|resize|touchstart|touchend|touchmove|contextmenu|wheel|pointerdown|pointerup|pointermove)/;
6000
6007
  var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
6001
6008
 
@@ -6020,7 +6027,8 @@ catch (e2) {
6020
6027
  if (name.startsWith('@bind:') || name.startsWith('x-bind:')
6021
6028
  || (name.startsWith(':') && !name.startsWith('::') && !DIRECTIVE_NAMES[name.slice(1).split('.')[0]] && !EVENT_RE.test(name.slice(1)))
6022
6029
  || (name.startsWith('x-') && !X_HANDLED[name.split('.')[0]] && !X_HANDLED[name])) {
6023
- const attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6030
+ let attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6031
+ if (el.namespaceURI === SVG_NS && SVG_ATTR_CASE[attrName]) attrName = SVG_ATTR_CASE[attrName];
6024
6032
  effect(() => {
6025
6033
  const v = evalAttrExpr(value);
6026
6034
  if (v === false || v === null || v === undefined) {
@@ -6399,10 +6407,12 @@ else {
6399
6407
  });
6400
6408
  }
6401
6409
  else if (Array.isArray(value)) {
6402
- el.className = originalClasses + ' ' + value.filter(Boolean).join(' ');
6410
+ var _clsArr = originalClasses + ' ' + value.filter(Boolean).join(' ');
6411
+ if (typeof el.className === 'string') el.className = _clsArr; else el.setAttribute('class', _clsArr);
6403
6412
  }
6404
6413
  else {
6405
- el.className = originalClasses + (value ? ' ' + value : '');
6414
+ var _clsStr = originalClasses + (value ? ' ' + value : '');
6415
+ if (typeof el.className === 'string') el.className = _clsStr; else el.setAttribute('class', _clsStr);
6406
6416
  }
6407
6417
  });
6408
6418
  }
@@ -8726,10 +8736,10 @@ else {
8726
8736
  var root = scriptEl ? scriptEl.nextElementSibling : null;
8727
8737
  if (!root && scriptEl) root = scriptEl.previousElementSibling || scriptEl.parentElement;
8728
8738
 
8729
- // SPA fallback: during router navigation, script is appended to <body>
8739
+ // SPA fallback: during router navigation, script is appended to body>
8730
8740
  // (not inside the content container), so nextElementSibling won't find the page content.
8731
8741
  // Only use fallback when we genuinely couldn't find a suitable root element.
8732
- // Do NOT fallback just because the script is in <body> \u2014 layout scripts in <body>
8742
+ // Do NOT fallback just because the script is in body> \u2014 layout scripts in body>
8733
8743
  // with valid siblings (e.g. sidebar <aside>) should use those siblings as root.
8734
8744
  var needsFallback = !root || root === document.body
8735
8745
  || (root && root.tagName === 'SCRIPT');
@@ -9048,7 +9058,7 @@ else {
9048
9058
  mountCallbacks.forEach(fn => fn());
9049
9059
  });
9050
9060
 
9051
- // Multi-root fragment fix: a no-<body> setup page tags only the FIRST
9061
+ // Multi-root fragment fix: a no-body> setup page tags only the FIRST
9052
9062
  // top-level element with data-stx (signal-processing.ts marks one element),
9053
9063
  // so sibling root elements were orphaned \u2014 their :if / :for / {{ }} / x-text
9054
9064
  // never hydrated, which read as "{{ }} doesn't work under :if/:for". The
@@ -9145,7 +9155,7 @@ else {
9145
9155
  el.querySelectorAll('[x-cloak]').forEach(function(c) { c.removeAttribute('x-cloak'); });
9146
9156
  });
9147
9157
 
9148
- // Process <head> elements (title, meta) that may contain {{ }} expressions
9158
+ // Process head> elements (title, meta) that may contain {{ }} expressions
9149
9159
  // Use componentScope which now contains variables from processed components
9150
9160
  const headElements = document.querySelectorAll('head title, head meta[content]');
9151
9161
  headElements.forEach(el => {
@@ -9341,7 +9351,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9341
9351
 
9342
9352
  // Apply new page's SFC setup function. During SPA navigation, re-executed page
9343
9353
  // scripts set window.stx._latestSetup to the new setup function. This takes priority
9344
- // over the stale data-stx attribute on <body> (which has the PREVIOUS page's function name).
9354
+ // over the stale data-stx attribute on body> (which has the PREVIOUS page's function name).
9345
9355
  var usedLatestSetup = false;
9346
9356
  if (window.stx._latestSetup && typeof window.stx._latestSetup === 'function') {
9347
9357
  try {
@@ -9425,7 +9435,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9425
9435
 
9426
9436
  // Process the container content \u2014 bind {{ }}, :attr, @event directives.
9427
9437
  // Run synchronously (not in setTimeout) so componentScope is captured correctly.
9428
- // The DOMContentLoaded path processes <body> synchronously \u2014 the SPA path must match.
9438
+ // The DOMContentLoaded path processes body> synchronously \u2014 the SPA path must match.
9429
9439
  console.log('[stx:load] container:', container.tagName, '__stx_scope:', !!container.__stx_scope, 'scope keys:', Object.keys(componentScope).slice(0, 10));
9430
9440
  if (!container.__stx_scope) {
9431
9441
  // Dispose previous effects on the container (from prior navigation)
@@ -9535,7 +9545,7 @@ ${_}${U}
9535
9545
  return { ${W} };
9536
9546
  }
9537
9547
  if(window.stx)window.stx._latestSetup=${G};
9538
- </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"];j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/i,(L,F,O)=>{if(H.includes(F.toLowerCase()))return L;return`<${F}${O} data-stx="${G}">`})}return{output:j,setupCode:B}}function LX($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",q=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9548
+ </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"],L=!1;j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/gi,(F,O,V)=>{if(L||H.includes(O.toLowerCase()))return F;return L=!0,`<${O}${V} data-stx="${G}">`})}return{output:j,setupCode:B}}function LX($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",q=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9539
9549
  `)return;Q++}},z=()=>{if(!K)return!0;if(/[\w)\]]/.test(K))return!1;return!0},U=(j)=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]===j){Q++;return}Q++}},W=()=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]==="`"){Q++;return}if(Z[Q]==="$"&&Z[Q+1]==="{"){Q+=2;let j=1;while(Q<G&&j>0)if(Z[Q]==="{")j++,Q++;else if(Z[Q]==="}")j--,Q++;else if(Z[Q]==="'"||Z[Q]==='"')U(Z[Q]);else if(Z[Q]==="`")W();else Q++;continue}Q++}},_=()=>{if(Z[Q]==="/"&&Z[Q+1]==="/"){while(Q<G&&Z[Q]!==`
9540
9550
  `)Q++;return!0}if(Z[Q]==="/"&&Z[Q+1]==="*"){Q+=2;while(Q<G-1&&!(Z[Q]==="*"&&Z[Q+1]==="/"))Q++;return Q+=2,!0}return!1},B=()=>{if(J!==0)return;let j=Z.slice(Q).match(/^(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/);if(j){let V=j[2];if(!X.has(V))Y.push(V),X.add(V);return}let H=Z.slice(Q).match(/^(?:const|let|var)\s+\{([^}]+)\}\s*=/);if(H){H[1].split(",").forEach((V)=>{let A=V.trim();if(!A)return;let w=A.indexOf(":"),N=(w>=0?A.slice(w+1).trim():A).split(/[\s=]/)[0];if(N&&!X.has(N))Y.push(N),X.add(N)});return}let L=Z.slice(Q).match(/^(?:const|let|var)\s+\[([^\]]+)\]\s*=/);if(L){L[1].split(",").forEach((V)=>{let A=V.trim().replace(/^\.\.\./,"");if(!A)return;let w=A.split(/[\s=]/)[0];if(w&&!X.has(w))Y.push(w),X.add(w)});return}let F=Z.slice(Q).match(/^function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(F){let V=F[1];if(!X.has(V))Y.push(V),X.add(V);return}let O=Z.slice(Q).match(/^async\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(O){let V=O[1];if(!X.has(V))Y.push(V),X.add(V)}};while(Q<G){if(_())continue;if(Z[Q]==="'"||Z[Q]==='"'){U(Z[Q]),K=Z[Q-1];continue}if(Z[Q]==="`"){W(),K="`";continue}if(Z[Q]==="/"&&Z[Q+1]!=="/"&&Z[Q+1]!=="*"&&z()){q(),K="/";continue}if(Z[Q]==="{"){J++,K="{",Q++;continue}if(Z[Q]==="}"){J--,K="}",Q++;continue}if(J===0&&/[a-z]/i.test(Z[Q])&&(Q===0||/\s|[;{}()]/.test(Z[Q-1])))B();if(!/\s/.test(Z[Q]))K=Z[Q];Q++}return Y.join(", ")}async function i6($,Z,Y,X){if(!m4($))return $;let J=$;if(Z.skipSignalsRuntime)return J;let{output:Q,setupCode:G}=await OX(J,Y,X);if(J=Q,J=await qX(J,Z),J=KX(J),G)if(J.includes("</head>"))J=J.replace("</head>",`${G}
9541
9551
  </head>`);else if(J.includes("<body"))J=J.replace(/<body([^>]*)>/,`<body$1>
@@ -58,7 +58,7 @@ ${F}`)}if(J.suggestion)q.push(`
58
58
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),q.join("")}function MZ(J,W,Z){let $=J.split(`
59
59
  `),Q=Math.max(0,W-Z-1),Y=Math.min($.length-1,W+Z-1),U=[];for(let X=Q;X<=Y;X++){let V=(X+1).toString().padStart(4),q=X===W-1?">":" ";U.push(`${q}${V} | ${$[X]}`)}return U.join(`
60
60
  `)}function RZ(J,W,Z){let $=J.split(`
61
- `),Q=Math.max(0,W-Z-1),Y=Math.min($.length-1,W+Z-1),U="\x1B[90m",X="\x1B[31m",V="\x1B[0m",q=[];for(let H=Q;H<=Y;H++){let F=(H+1).toString().padStart(4),_=H===W-1,B=_?"\x1B[31m>\x1B[0m":" ",K=_?`\x1B[31m${$[H]}\x1B[0m`:`\x1B[90m${$[H]}`;q.push(`${B}${F}\x1B[0m | ${K}`)}return q.join(`
61
+ `),Q=Math.max(0,W-Z-1),Y=Math.min($.length-1,W+Z-1),U="\x1B[90m",X="\x1B[31m",V="\x1B[0m",q=[];for(let H=Q;H<=Y;H++){let F=(H+1).toString().padStart(4),_=H===W-1,B=_?"\x1B[31m>\x1B[0m":" ",K=_?`\x1B[31m${$[H]}\x1B[0m`:`\x1B[90m${$[H]}\x1B[0m`;q.push(`${B}\x1B[90m${F}\x1B[0m | ${K}`)}return q.join(`
62
62
  `)}function vJ(J){return J.replace(/--/g,"- -").replace(/>/g,"&gt;")}function gJ(J,W){let $=J.substring(0,W).split(`
63
63
  `);return{line:$.length,column:$[$.length-1].length}}function o(J,W,Z){return FJ({type:J,message:W,code:Z,format:"html"}).formatted}function DZ(J,W,Z,$,Q){return FJ({type:J,message:W,code:Q,filePath:Z,line:$,format:"console"}).formatted}function LZ(J,W,Z){let $=Z.template.split(`
64
64
  `),Q=gJ(Z.template,Z.offset),Y=`[${J} Error at line ${Q.line} in ${Z.filePath}]: ${W}
@@ -27,7 +27,7 @@ ${Q}`)}if(F.suggestion)V.push(`
27
27
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),V.join("")}function vF(F,U,O){let j=F.split(`
28
28
  `),J=Math.max(0,U-O-1),N=Math.min(j.length-1,U+O-1),Y=[];for(let $=J;$<=N;$++){let Z=($+1).toString().padStart(4),V=$===U-1?">":" ";Y.push(`${V}${Z} | ${j[$]}`)}return Y.join(`
29
29
  `)}function xF(F,U,O){let j=F.split(`
30
- `),J=Math.max(0,U-O-1),N=Math.min(j.length-1,U+O-1),Y="\x1B[90m",$="\x1B[31m",Z="\x1B[0m",V=[];for(let B=J;B<=N;B++){let Q=(B+1).toString().padStart(4),W=B===U-1,q=W?"\x1B[31m>\x1B[0m":" ",G=W?`\x1B[31m${j[B]}\x1B[0m`:`\x1B[90m${j[B]}`;V.push(`${q}${Q}\x1B[0m | ${G}`)}return V.join(`
30
+ `),J=Math.max(0,U-O-1),N=Math.min(j.length-1,U+O-1),Y="\x1B[90m",$="\x1B[31m",Z="\x1B[0m",V=[];for(let B=J;B<=N;B++){let Q=(B+1).toString().padStart(4),W=B===U-1,q=W?"\x1B[31m>\x1B[0m":" ",G=W?`\x1B[31m${j[B]}\x1B[0m`:`\x1B[90m${j[B]}\x1B[0m`;V.push(`${q}\x1B[90m${Q}\x1B[0m | ${G}`)}return V.join(`
31
31
  `)}function FF(F){return F.replace(/--/g,"- -").replace(/>/g,"&gt;")}function OF(F,U){let j=F.substring(0,U).split(`
32
32
  `);return{line:j.length,column:j[j.length-1].length}}function L(F,U,O){return g({type:F,message:U,code:O,format:"html"}).formatted}function yF(F,U,O,j,J){return g({type:F,message:U,code:J,filePath:O,line:j,format:"console"}).formatted}function gF(F,U,O){let j=O.template.split(`
33
33
  `),J=OF(O.template,O.offset),N=`[${F} Error at line ${J.line} in ${O.filePath}]: ${U}
@@ -1783,7 +1783,7 @@ ${U}`)}if($.suggestion)z.push(`
1783
1783
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),z.join("")}function rK($,Z,Y){let X=$.split(`
1784
1784
  `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G=[];for(let K=J;K<=Q;K++){let q=(K+1).toString().padStart(4),z=K===Z-1?">":" ";G.push(`${z}${q} | ${X[K]}`)}return G.join(`
1785
1785
  `)}function aK($,Z,Y){let X=$.split(`
1786
- `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G="\x1B[90m",K="\x1B[31m",q="\x1B[0m",z=[];for(let W=J;W<=Q;W++){let U=(W+1).toString().padStart(4),_=W===Z-1,B=_?"\x1B[31m>\x1B[0m":" ",j=_?`\x1B[31m${X[W]}\x1B[0m`:`\x1B[90m${X[W]}`;z.push(`${B}${U}\x1B[0m | ${j}`)}return z.join(`
1786
+ `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G="\x1B[90m",K="\x1B[31m",q="\x1B[0m",z=[];for(let W=J;W<=Q;W++){let U=(W+1).toString().padStart(4),_=W===Z-1,B=_?"\x1B[31m>\x1B[0m":" ",j=_?`\x1B[31m${X[W]}\x1B[0m`:`\x1B[90m${X[W]}\x1B[0m`;z.push(`${B}\x1B[90m${U}\x1B[0m | ${j}`)}return z.join(`
1787
1787
  `)}function KZ($){return $.replace(/--/g,"- -").replace(/>/g,"&gt;")}function qZ($,Z){let X=$.substring(0,Z).split(`
1788
1788
  `);return{line:X.length,column:X[X.length-1].length}}function a($,Z,Y){return e3({type:$,message:Z,code:Y,format:"html"}).formatted}function tK($,Z,Y,X,J){return e3({type:$,message:Z,code:J,filePath:Y,line:X,format:"console"}).formatted}function eK($,Z,Y){let X=Y.template.split(`
1789
1789
  `),J=qZ(Y.template,Y.offset),Q=`[${$} Error at line ${J.line} in ${Y.filePath}]: ${Z}
@@ -3756,7 +3756,7 @@ window.__stx_reactive = (function() {
3756
3756
 
3757
3757
  return { initScope: initScope, reactive: reactive };
3758
3758
  })();
3759
- `}function cZ($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=g0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=g0(J,Z,!0);if(Q===void 0)return X;return JSON.stringify(Q)}catch{return X}}),Y}function Kz($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=cZ(X.stateExpr,Z),G=X.initExpr?cZ(X.initExpr,Z):null,K=JSON.stringify(Q),q=G?JSON.stringify(G):"null";return`
3759
+ `}function cZ($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=g0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=g0(J,Z,!0);if(Q===void 0)return X;if(typeof Q==="string"){let G=Q.trim();if(G.startsWith("{")&&G.endsWith("}")||G.startsWith("[")&&G.endsWith("]"))try{return JSON.parse(G),G}catch{}}return JSON.stringify(Q)}catch{return X}}),Y}function Kz($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=cZ(X.stateExpr,Z),G=X.initExpr?cZ(X.initExpr,Z):null,K=JSON.stringify(Q),q=G?JSON.stringify(G):"null";return`
3760
3760
  (function() {
3761
3761
  var scopeEl = document.querySelector('${X.selector}');
3762
3762
  if (!scopeEl) return;
@@ -5996,6 +5996,13 @@ catch (e2) {
5996
5996
 
5997
5997
  // Known directive names to exclude from generic :attr binding
5998
5998
  var DIRECTIVE_NAMES = {class:1, style:1, text:1, html:1, show:1, model:1, 'if':1, 'for':1, ref:1};
5999
+ // SVG attributes are case-sensitive, but the HTML parser lowercases
6000
+ // prefixed attribute names \u2014 ':viewBox' arrives as ':viewbox' because
6001
+ // the spec's "adjust SVG attributes" step only covers unprefixed names.
6002
+ // Without restoring the canonical casing, setAttribute('viewbox') creates
6003
+ // a dead duplicate attribute and the real viewBox never updates.
6004
+ var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
6005
+ var SVG_NS = 'http://www.w3.org/2000/svg';
5999
6006
  var EVENT_RE = /^(click|dblclick|mousedown|mouseup|mousemove|mouseenter|mouseleave|keydown|keyup|keypress|input|change|submit|focus|blur|scroll|resize|touchstart|touchend|touchmove|contextmenu|wheel|pointerdown|pointerup|pointermove)/;
6000
6007
  var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
6001
6008
 
@@ -6020,7 +6027,8 @@ catch (e2) {
6020
6027
  if (name.startsWith('@bind:') || name.startsWith('x-bind:')
6021
6028
  || (name.startsWith(':') && !name.startsWith('::') && !DIRECTIVE_NAMES[name.slice(1).split('.')[0]] && !EVENT_RE.test(name.slice(1)))
6022
6029
  || (name.startsWith('x-') && !X_HANDLED[name.split('.')[0]] && !X_HANDLED[name])) {
6023
- const attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6030
+ let attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6031
+ if (el.namespaceURI === SVG_NS && SVG_ATTR_CASE[attrName]) attrName = SVG_ATTR_CASE[attrName];
6024
6032
  effect(() => {
6025
6033
  const v = evalAttrExpr(value);
6026
6034
  if (v === false || v === null || v === undefined) {
@@ -6399,10 +6407,12 @@ else {
6399
6407
  });
6400
6408
  }
6401
6409
  else if (Array.isArray(value)) {
6402
- el.className = originalClasses + ' ' + value.filter(Boolean).join(' ');
6410
+ var _clsArr = originalClasses + ' ' + value.filter(Boolean).join(' ');
6411
+ if (typeof el.className === 'string') el.className = _clsArr; else el.setAttribute('class', _clsArr);
6403
6412
  }
6404
6413
  else {
6405
- el.className = originalClasses + (value ? ' ' + value : '');
6414
+ var _clsStr = originalClasses + (value ? ' ' + value : '');
6415
+ if (typeof el.className === 'string') el.className = _clsStr; else el.setAttribute('class', _clsStr);
6406
6416
  }
6407
6417
  });
6408
6418
  }
@@ -8726,10 +8736,10 @@ else {
8726
8736
  var root = scriptEl ? scriptEl.nextElementSibling : null;
8727
8737
  if (!root && scriptEl) root = scriptEl.previousElementSibling || scriptEl.parentElement;
8728
8738
 
8729
- // SPA fallback: during router navigation, script is appended to <body>
8739
+ // SPA fallback: during router navigation, script is appended to body>
8730
8740
  // (not inside the content container), so nextElementSibling won't find the page content.
8731
8741
  // Only use fallback when we genuinely couldn't find a suitable root element.
8732
- // Do NOT fallback just because the script is in <body> \u2014 layout scripts in <body>
8742
+ // Do NOT fallback just because the script is in body> \u2014 layout scripts in body>
8733
8743
  // with valid siblings (e.g. sidebar <aside>) should use those siblings as root.
8734
8744
  var needsFallback = !root || root === document.body
8735
8745
  || (root && root.tagName === 'SCRIPT');
@@ -9048,7 +9058,7 @@ else {
9048
9058
  mountCallbacks.forEach(fn => fn());
9049
9059
  });
9050
9060
 
9051
- // Multi-root fragment fix: a no-<body> setup page tags only the FIRST
9061
+ // Multi-root fragment fix: a no-body> setup page tags only the FIRST
9052
9062
  // top-level element with data-stx (signal-processing.ts marks one element),
9053
9063
  // so sibling root elements were orphaned \u2014 their :if / :for / {{ }} / x-text
9054
9064
  // never hydrated, which read as "{{ }} doesn't work under :if/:for". The
@@ -9145,7 +9155,7 @@ else {
9145
9155
  el.querySelectorAll('[x-cloak]').forEach(function(c) { c.removeAttribute('x-cloak'); });
9146
9156
  });
9147
9157
 
9148
- // Process <head> elements (title, meta) that may contain {{ }} expressions
9158
+ // Process head> elements (title, meta) that may contain {{ }} expressions
9149
9159
  // Use componentScope which now contains variables from processed components
9150
9160
  const headElements = document.querySelectorAll('head title, head meta[content]');
9151
9161
  headElements.forEach(el => {
@@ -9341,7 +9351,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9341
9351
 
9342
9352
  // Apply new page's SFC setup function. During SPA navigation, re-executed page
9343
9353
  // scripts set window.stx._latestSetup to the new setup function. This takes priority
9344
- // over the stale data-stx attribute on <body> (which has the PREVIOUS page's function name).
9354
+ // over the stale data-stx attribute on body> (which has the PREVIOUS page's function name).
9345
9355
  var usedLatestSetup = false;
9346
9356
  if (window.stx._latestSetup && typeof window.stx._latestSetup === 'function') {
9347
9357
  try {
@@ -9425,7 +9435,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9425
9435
 
9426
9436
  // Process the container content \u2014 bind {{ }}, :attr, @event directives.
9427
9437
  // Run synchronously (not in setTimeout) so componentScope is captured correctly.
9428
- // The DOMContentLoaded path processes <body> synchronously \u2014 the SPA path must match.
9438
+ // The DOMContentLoaded path processes body> synchronously \u2014 the SPA path must match.
9429
9439
  console.log('[stx:load] container:', container.tagName, '__stx_scope:', !!container.__stx_scope, 'scope keys:', Object.keys(componentScope).slice(0, 10));
9430
9440
  if (!container.__stx_scope) {
9431
9441
  // Dispose previous effects on the container (from prior navigation)
@@ -9535,7 +9545,7 @@ ${_}${W}
9535
9545
  return { ${U} };
9536
9546
  }
9537
9547
  if(window.stx)window.stx._latestSetup=${G};
9538
- </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"];j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/i,(L,F,O)=>{if(H.includes(F.toLowerCase()))return L;return`<${F}${O} data-stx="${G}">`})}return{output:j,setupCode:B}}function FX($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",q=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9548
+ </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"],L=!1;j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/gi,(F,O,V)=>{if(L||H.includes(O.toLowerCase()))return F;return L=!0,`<${O}${V} data-stx="${G}">`})}return{output:j,setupCode:B}}function FX($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",q=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9539
9549
  `)return;Q++}},z=()=>{if(!K)return!0;if(/[\w)\]]/.test(K))return!1;return!0},W=(j)=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]===j){Q++;return}Q++}},U=()=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]==="`"){Q++;return}if(Z[Q]==="$"&&Z[Q+1]==="{"){Q+=2;let j=1;while(Q<G&&j>0)if(Z[Q]==="{")j++,Q++;else if(Z[Q]==="}")j--,Q++;else if(Z[Q]==="'"||Z[Q]==='"')W(Z[Q]);else if(Z[Q]==="`")U();else Q++;continue}Q++}},_=()=>{if(Z[Q]==="/"&&Z[Q+1]==="/"){while(Q<G&&Z[Q]!==`
9540
9550
  `)Q++;return!0}if(Z[Q]==="/"&&Z[Q+1]==="*"){Q+=2;while(Q<G-1&&!(Z[Q]==="*"&&Z[Q+1]==="/"))Q++;return Q+=2,!0}return!1},B=()=>{if(J!==0)return;let j=Z.slice(Q).match(/^(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/);if(j){let V=j[2];if(!X.has(V))Y.push(V),X.add(V);return}let H=Z.slice(Q).match(/^(?:const|let|var)\s+\{([^}]+)\}\s*=/);if(H){H[1].split(",").forEach((V)=>{let A=V.trim();if(!A)return;let w=A.indexOf(":"),N=(w>=0?A.slice(w+1).trim():A).split(/[\s=]/)[0];if(N&&!X.has(N))Y.push(N),X.add(N)});return}let L=Z.slice(Q).match(/^(?:const|let|var)\s+\[([^\]]+)\]\s*=/);if(L){L[1].split(",").forEach((V)=>{let A=V.trim().replace(/^\.\.\./,"");if(!A)return;let w=A.split(/[\s=]/)[0];if(w&&!X.has(w))Y.push(w),X.add(w)});return}let F=Z.slice(Q).match(/^function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(F){let V=F[1];if(!X.has(V))Y.push(V),X.add(V);return}let O=Z.slice(Q).match(/^async\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(O){let V=O[1];if(!X.has(V))Y.push(V),X.add(V)}};while(Q<G){if(_())continue;if(Z[Q]==="'"||Z[Q]==='"'){W(Z[Q]),K=Z[Q-1];continue}if(Z[Q]==="`"){U(),K="`";continue}if(Z[Q]==="/"&&Z[Q+1]!=="/"&&Z[Q+1]!=="*"&&z()){q(),K="/";continue}if(Z[Q]==="{"){J++,K="{",Q++;continue}if(Z[Q]==="}"){J--,K="}",Q++;continue}if(J===0&&/[a-z]/i.test(Z[Q])&&(Q===0||/\s|[;{}()]/.test(Z[Q-1])))B();if(!/\s/.test(Z[Q]))K=Z[Q];Q++}return Y.join(", ")}async function o6($,Z,Y,X){if(!u4($))return $;let J=$;if(Z.skipSignalsRuntime)return J;let{output:Q,setupCode:G}=await LX(J,Y,X);if(J=Q,J=await zX(J,Z),J=qX(J),G)if(J.includes("</head>"))J=J.replace("</head>",`${G}
9541
9551
  </head>`);else if(J.includes("<body"))J=J.replace(/<body([^>]*)>/,`<body$1>
@@ -3849,7 +3849,7 @@ window.__stx_reactive = (function() {
3849
3849
 
3850
3850
  return { initScope: initScope, reactive: reactive };
3851
3851
  })();
3852
- `}function xU($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=o0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=o0(J,Z,!0);if(Q===void 0)return X;return JSON.stringify(Q)}catch{return X}}),Y}function _w($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=xU(X.stateExpr,Z),G=X.initExpr?xU(X.initExpr,Z):null,K=JSON.stringify(Q),W=G?JSON.stringify(G):"null";return`
3852
+ `}function xU($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=o0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=o0(J,Z,!0);if(Q===void 0)return X;if(typeof Q==="string"){let G=Q.trim();if(G.startsWith("{")&&G.endsWith("}")||G.startsWith("[")&&G.endsWith("]"))try{return JSON.parse(G),G}catch{}}return JSON.stringify(Q)}catch{return X}}),Y}function _w($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=xU(X.stateExpr,Z),G=X.initExpr?xU(X.initExpr,Z):null,K=JSON.stringify(Q),W=G?JSON.stringify(G):"null";return`
3853
3853
  (function() {
3854
3854
  var scopeEl = document.querySelector('${X.selector}');
3855
3855
  if (!scopeEl) return;
@@ -5974,6 +5974,13 @@ catch (e2) {
5974
5974
 
5975
5975
  // Known directive names to exclude from generic :attr binding
5976
5976
  var DIRECTIVE_NAMES = {class:1, style:1, text:1, html:1, show:1, model:1, 'if':1, 'for':1, ref:1};
5977
+ // SVG attributes are case-sensitive, but the HTML parser lowercases
5978
+ // prefixed attribute names \u2014 ':viewBox' arrives as ':viewbox' because
5979
+ // the spec's "adjust SVG attributes" step only covers unprefixed names.
5980
+ // Without restoring the canonical casing, setAttribute('viewbox') creates
5981
+ // a dead duplicate attribute and the real viewBox never updates.
5982
+ var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
5983
+ var SVG_NS = 'http://www.w3.org/2000/svg';
5977
5984
  var EVENT_RE = /^(click|dblclick|mousedown|mouseup|mousemove|mouseenter|mouseleave|keydown|keyup|keypress|input|change|submit|focus|blur|scroll|resize|touchstart|touchend|touchmove|contextmenu|wheel|pointerdown|pointerup|pointermove)/;
5978
5985
  var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
5979
5986
 
@@ -5998,7 +6005,8 @@ catch (e2) {
5998
6005
  if (name.startsWith('@bind:') || name.startsWith('x-bind:')
5999
6006
  || (name.startsWith(':') && !name.startsWith('::') && !DIRECTIVE_NAMES[name.slice(1).split('.')[0]] && !EVENT_RE.test(name.slice(1)))
6000
6007
  || (name.startsWith('x-') && !X_HANDLED[name.split('.')[0]] && !X_HANDLED[name])) {
6001
- const attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6008
+ let attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6009
+ if (el.namespaceURI === SVG_NS && SVG_ATTR_CASE[attrName]) attrName = SVG_ATTR_CASE[attrName];
6002
6010
  effect(() => {
6003
6011
  const v = evalAttrExpr(value);
6004
6012
  if (v === false || v === null || v === undefined) {
@@ -6377,10 +6385,12 @@ else {
6377
6385
  });
6378
6386
  }
6379
6387
  else if (Array.isArray(value)) {
6380
- el.className = originalClasses + ' ' + value.filter(Boolean).join(' ');
6388
+ var _clsArr = originalClasses + ' ' + value.filter(Boolean).join(' ');
6389
+ if (typeof el.className === 'string') el.className = _clsArr; else el.setAttribute('class', _clsArr);
6381
6390
  }
6382
6391
  else {
6383
- el.className = originalClasses + (value ? ' ' + value : '');
6392
+ var _clsStr = originalClasses + (value ? ' ' + value : '');
6393
+ if (typeof el.className === 'string') el.className = _clsStr; else el.setAttribute('class', _clsStr);
6384
6394
  }
6385
6395
  });
6386
6396
  }
@@ -8704,10 +8714,10 @@ else {
8704
8714
  var root = scriptEl ? scriptEl.nextElementSibling : null;
8705
8715
  if (!root && scriptEl) root = scriptEl.previousElementSibling || scriptEl.parentElement;
8706
8716
 
8707
- // SPA fallback: during router navigation, script is appended to <body>
8717
+ // SPA fallback: during router navigation, script is appended to body>
8708
8718
  // (not inside the content container), so nextElementSibling won't find the page content.
8709
8719
  // Only use fallback when we genuinely couldn't find a suitable root element.
8710
- // Do NOT fallback just because the script is in <body> \u2014 layout scripts in <body>
8720
+ // Do NOT fallback just because the script is in body> \u2014 layout scripts in body>
8711
8721
  // with valid siblings (e.g. sidebar <aside>) should use those siblings as root.
8712
8722
  var needsFallback = !root || root === document.body
8713
8723
  || (root && root.tagName === 'SCRIPT');
@@ -9026,7 +9036,7 @@ else {
9026
9036
  mountCallbacks.forEach(fn => fn());
9027
9037
  });
9028
9038
 
9029
- // Multi-root fragment fix: a no-<body> setup page tags only the FIRST
9039
+ // Multi-root fragment fix: a no-body> setup page tags only the FIRST
9030
9040
  // top-level element with data-stx (signal-processing.ts marks one element),
9031
9041
  // so sibling root elements were orphaned \u2014 their :if / :for / {{ }} / x-text
9032
9042
  // never hydrated, which read as "{{ }} doesn't work under :if/:for". The
@@ -9123,7 +9133,7 @@ else {
9123
9133
  el.querySelectorAll('[x-cloak]').forEach(function(c) { c.removeAttribute('x-cloak'); });
9124
9134
  });
9125
9135
 
9126
- // Process <head> elements (title, meta) that may contain {{ }} expressions
9136
+ // Process head> elements (title, meta) that may contain {{ }} expressions
9127
9137
  // Use componentScope which now contains variables from processed components
9128
9138
  const headElements = document.querySelectorAll('head title, head meta[content]');
9129
9139
  headElements.forEach(el => {
@@ -9319,7 +9329,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9319
9329
 
9320
9330
  // Apply new page's SFC setup function. During SPA navigation, re-executed page
9321
9331
  // scripts set window.stx._latestSetup to the new setup function. This takes priority
9322
- // over the stale data-stx attribute on <body> (which has the PREVIOUS page's function name).
9332
+ // over the stale data-stx attribute on body> (which has the PREVIOUS page's function name).
9323
9333
  var usedLatestSetup = false;
9324
9334
  if (window.stx._latestSetup && typeof window.stx._latestSetup === 'function') {
9325
9335
  try {
@@ -9403,7 +9413,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9403
9413
 
9404
9414
  // Process the container content \u2014 bind {{ }}, :attr, @event directives.
9405
9415
  // Run synchronously (not in setTimeout) so componentScope is captured correctly.
9406
- // The DOMContentLoaded path processes <body> synchronously \u2014 the SPA path must match.
9416
+ // The DOMContentLoaded path processes body> synchronously \u2014 the SPA path must match.
9407
9417
  console.log('[stx:load] container:', container.tagName, '__stx_scope:', !!container.__stx_scope, 'scope keys:', Object.keys(componentScope).slice(0, 10));
9408
9418
  if (!container.__stx_scope) {
9409
9419
  // Dispose previous effects on the container (from prior navigation)
@@ -9513,7 +9523,7 @@ ${z}${B}
9513
9523
  return { ${_} };
9514
9524
  }
9515
9525
  if(window.stx)window.stx._latestSetup=${G};
9516
- </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"];j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/i,(O,F,L)=>{if(H.includes(F.toLowerCase()))return O;return`<${F}${L} data-stx="${G}">`})}return{output:j,setupCode:q}}function Uz($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",W=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9526
+ </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"],O=!1;j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/gi,(F,L,V)=>{if(O||H.includes(L.toLowerCase()))return F;return O=!0,`<${L}${V} data-stx="${G}">`})}return{output:j,setupCode:q}}function Uz($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",W=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9517
9527
  `)return;Q++}},U=()=>{if(!K)return!0;if(/[\w)\]]/.test(K))return!1;return!0},B=(j)=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]===j){Q++;return}Q++}},_=()=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]==="`"){Q++;return}if(Z[Q]==="$"&&Z[Q+1]==="{"){Q+=2;let j=1;while(Q<G&&j>0)if(Z[Q]==="{")j++,Q++;else if(Z[Q]==="}")j--,Q++;else if(Z[Q]==="'"||Z[Q]==='"')B(Z[Q]);else if(Z[Q]==="`")_();else Q++;continue}Q++}},z=()=>{if(Z[Q]==="/"&&Z[Q+1]==="/"){while(Q<G&&Z[Q]!==`
9518
9528
  `)Q++;return!0}if(Z[Q]==="/"&&Z[Q+1]==="*"){Q+=2;while(Q<G-1&&!(Z[Q]==="*"&&Z[Q+1]==="/"))Q++;return Q+=2,!0}return!1},q=()=>{if(J!==0)return;let j=Z.slice(Q).match(/^(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/);if(j){let V=j[2];if(!X.has(V))Y.push(V),X.add(V);return}let H=Z.slice(Q).match(/^(?:const|let|var)\s+\{([^}]+)\}\s*=/);if(H){H[1].split(",").forEach((V)=>{let N=V.trim();if(!N)return;let A=N.indexOf(":"),R=(A>=0?N.slice(A+1).trim():N).split(/[\s=]/)[0];if(R&&!X.has(R))Y.push(R),X.add(R)});return}let O=Z.slice(Q).match(/^(?:const|let|var)\s+\[([^\]]+)\]\s*=/);if(O){O[1].split(",").forEach((V)=>{let N=V.trim().replace(/^\.\.\./,"");if(!N)return;let A=N.split(/[\s=]/)[0];if(A&&!X.has(A))Y.push(A),X.add(A)});return}let F=Z.slice(Q).match(/^function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(F){let V=F[1];if(!X.has(V))Y.push(V),X.add(V);return}let L=Z.slice(Q).match(/^async\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(L){let V=L[1];if(!X.has(V))Y.push(V),X.add(V)}};while(Q<G){if(z())continue;if(Z[Q]==="'"||Z[Q]==='"'){B(Z[Q]),K=Z[Q-1];continue}if(Z[Q]==="`"){_(),K="`";continue}if(Z[Q]==="/"&&Z[Q+1]!=="/"&&Z[Q+1]!=="*"&&U()){W(),K="/";continue}if(Z[Q]==="{"){J++,K="{",Q++;continue}if(Z[Q]==="}"){J--,K="}",Q++;continue}if(J===0&&/[a-z]/i.test(Z[Q])&&(Q===0||/\s|[;{}()]/.test(Z[Q-1])))q();if(!/\s/.test(Z[Q]))K=Z[Q];Q++}return Y.join(", ")}async function B9($,Z,Y,X){if(!IZ($))return $;let J=$;if(Z.skipSignalsRuntime)return J;let{output:Q,setupCode:G}=await Wz(J,Y,X);if(J=Q,J=await Zz(J,Z),J=$z(J),G)if(J.includes("</head>"))J=J.replace("</head>",`${G}
9519
9529
  </head>`);else if(J.includes("<body"))J=J.replace(/<body([^>]*)>/,`<body$1>
@@ -3977,7 +3977,7 @@ window.__stx_reactive = (function() {
3977
3977
 
3978
3978
  return { initScope: initScope, reactive: reactive };
3979
3979
  })();
3980
- `}function HU($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=a0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=a0(J,Z,!0);if(Q===void 0)return X;return JSON.stringify(Q)}catch{return X}}),Y}function bA($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=HU(X.stateExpr,Z),G=X.initExpr?HU(X.initExpr,Z):null,K=JSON.stringify(Q),W=G?JSON.stringify(G):"null";return`
3980
+ `}function HU($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=a0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=a0(J,Z,!0);if(Q===void 0)return X;if(typeof Q==="string"){let G=Q.trim();if(G.startsWith("{")&&G.endsWith("}")||G.startsWith("[")&&G.endsWith("]"))try{return JSON.parse(G),G}catch{}}return JSON.stringify(Q)}catch{return X}}),Y}function bA($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=HU(X.stateExpr,Z),G=X.initExpr?HU(X.initExpr,Z):null,K=JSON.stringify(Q),W=G?JSON.stringify(G):"null";return`
3981
3981
  (function() {
3982
3982
  var scopeEl = document.querySelector('${X.selector}');
3983
3983
  if (!scopeEl) return;
@@ -5808,6 +5808,13 @@ catch (e2) {
5808
5808
 
5809
5809
  // Known directive names to exclude from generic :attr binding
5810
5810
  var DIRECTIVE_NAMES = {class:1, style:1, text:1, html:1, show:1, model:1, 'if':1, 'for':1, ref:1};
5811
+ // SVG attributes are case-sensitive, but the HTML parser lowercases
5812
+ // prefixed attribute names \u2014 ':viewBox' arrives as ':viewbox' because
5813
+ // the spec's "adjust SVG attributes" step only covers unprefixed names.
5814
+ // Without restoring the canonical casing, setAttribute('viewbox') creates
5815
+ // a dead duplicate attribute and the real viewBox never updates.
5816
+ var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
5817
+ var SVG_NS = 'http://www.w3.org/2000/svg';
5811
5818
  var EVENT_RE = /^(click|dblclick|mousedown|mouseup|mousemove|mouseenter|mouseleave|keydown|keyup|keypress|input|change|submit|focus|blur|scroll|resize|touchstart|touchend|touchmove|contextmenu|wheel|pointerdown|pointerup|pointermove)/;
5812
5819
  var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
5813
5820
 
@@ -5832,7 +5839,8 @@ catch (e2) {
5832
5839
  if (name.startsWith('@bind:') || name.startsWith('x-bind:')
5833
5840
  || (name.startsWith(':') && !name.startsWith('::') && !DIRECTIVE_NAMES[name.slice(1).split('.')[0]] && !EVENT_RE.test(name.slice(1)))
5834
5841
  || (name.startsWith('x-') && !X_HANDLED[name.split('.')[0]] && !X_HANDLED[name])) {
5835
- const attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
5842
+ let attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
5843
+ if (el.namespaceURI === SVG_NS && SVG_ATTR_CASE[attrName]) attrName = SVG_ATTR_CASE[attrName];
5836
5844
  effect(() => {
5837
5845
  const v = evalAttrExpr(value);
5838
5846
  if (v === false || v === null || v === undefined) {
@@ -6211,10 +6219,12 @@ else {
6211
6219
  });
6212
6220
  }
6213
6221
  else if (Array.isArray(value)) {
6214
- el.className = originalClasses + ' ' + value.filter(Boolean).join(' ');
6222
+ var _clsArr = originalClasses + ' ' + value.filter(Boolean).join(' ');
6223
+ if (typeof el.className === 'string') el.className = _clsArr; else el.setAttribute('class', _clsArr);
6215
6224
  }
6216
6225
  else {
6217
- el.className = originalClasses + (value ? ' ' + value : '');
6226
+ var _clsStr = originalClasses + (value ? ' ' + value : '');
6227
+ if (typeof el.className === 'string') el.className = _clsStr; else el.setAttribute('class', _clsStr);
6218
6228
  }
6219
6229
  });
6220
6230
  }
@@ -8538,10 +8548,10 @@ else {
8538
8548
  var root = scriptEl ? scriptEl.nextElementSibling : null;
8539
8549
  if (!root && scriptEl) root = scriptEl.previousElementSibling || scriptEl.parentElement;
8540
8550
 
8541
- // SPA fallback: during router navigation, script is appended to <body>
8551
+ // SPA fallback: during router navigation, script is appended to body>
8542
8552
  // (not inside the content container), so nextElementSibling won't find the page content.
8543
8553
  // Only use fallback when we genuinely couldn't find a suitable root element.
8544
- // Do NOT fallback just because the script is in <body> \u2014 layout scripts in <body>
8554
+ // Do NOT fallback just because the script is in body> \u2014 layout scripts in body>
8545
8555
  // with valid siblings (e.g. sidebar <aside>) should use those siblings as root.
8546
8556
  var needsFallback = !root || root === document.body
8547
8557
  || (root && root.tagName === 'SCRIPT');
@@ -8860,7 +8870,7 @@ else {
8860
8870
  mountCallbacks.forEach(fn => fn());
8861
8871
  });
8862
8872
 
8863
- // Multi-root fragment fix: a no-<body> setup page tags only the FIRST
8873
+ // Multi-root fragment fix: a no-body> setup page tags only the FIRST
8864
8874
  // top-level element with data-stx (signal-processing.ts marks one element),
8865
8875
  // so sibling root elements were orphaned \u2014 their :if / :for / {{ }} / x-text
8866
8876
  // never hydrated, which read as "{{ }} doesn't work under :if/:for". The
@@ -8957,7 +8967,7 @@ else {
8957
8967
  el.querySelectorAll('[x-cloak]').forEach(function(c) { c.removeAttribute('x-cloak'); });
8958
8968
  });
8959
8969
 
8960
- // Process <head> elements (title, meta) that may contain {{ }} expressions
8970
+ // Process head> elements (title, meta) that may contain {{ }} expressions
8961
8971
  // Use componentScope which now contains variables from processed components
8962
8972
  const headElements = document.querySelectorAll('head title, head meta[content]');
8963
8973
  headElements.forEach(el => {
@@ -9153,7 +9163,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9153
9163
 
9154
9164
  // Apply new page's SFC setup function. During SPA navigation, re-executed page
9155
9165
  // scripts set window.stx._latestSetup to the new setup function. This takes priority
9156
- // over the stale data-stx attribute on <body> (which has the PREVIOUS page's function name).
9166
+ // over the stale data-stx attribute on body> (which has the PREVIOUS page's function name).
9157
9167
  var usedLatestSetup = false;
9158
9168
  if (window.stx._latestSetup && typeof window.stx._latestSetup === 'function') {
9159
9169
  try {
@@ -9237,7 +9247,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9237
9247
 
9238
9248
  // Process the container content \u2014 bind {{ }}, :attr, @event directives.
9239
9249
  // Run synchronously (not in setTimeout) so componentScope is captured correctly.
9240
- // The DOMContentLoaded path processes <body> synchronously \u2014 the SPA path must match.
9250
+ // The DOMContentLoaded path processes body> synchronously \u2014 the SPA path must match.
9241
9251
  console.log('[stx:load] container:', container.tagName, '__stx_scope:', !!container.__stx_scope, 'scope keys:', Object.keys(componentScope).slice(0, 10));
9242
9252
  if (!container.__stx_scope) {
9243
9253
  // Dispose previous effects on the container (from prior navigation)
@@ -9347,7 +9357,7 @@ ${z}${B}
9347
9357
  return { ${_} };
9348
9358
  }
9349
9359
  if(window.stx)window.stx._latestSetup=${G};
9350
- </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"];j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/i,(O,F,L)=>{if(H.includes(F.toLowerCase()))return O;return`<${F}${L} data-stx="${G}">`})}return{output:j,setupCode:q}}function uB($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",W=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9360
+ </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"],O=!1;j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/gi,(F,L,V)=>{if(O||H.includes(L.toLowerCase()))return F;return O=!0,`<${L}${V} data-stx="${G}">`})}return{output:j,setupCode:q}}function uB($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",W=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9351
9361
  `)return;Q++}},U=()=>{if(!K)return!0;if(/[\w)\]]/.test(K))return!1;return!0},B=(j)=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]===j){Q++;return}Q++}},_=()=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]==="`"){Q++;return}if(Z[Q]==="$"&&Z[Q+1]==="{"){Q+=2;let j=1;while(Q<G&&j>0)if(Z[Q]==="{")j++,Q++;else if(Z[Q]==="}")j--,Q++;else if(Z[Q]==="'"||Z[Q]==='"')B(Z[Q]);else if(Z[Q]==="`")_();else Q++;continue}Q++}},z=()=>{if(Z[Q]==="/"&&Z[Q+1]==="/"){while(Q<G&&Z[Q]!==`
9352
9362
  `)Q++;return!0}if(Z[Q]==="/"&&Z[Q+1]==="*"){Q+=2;while(Q<G-1&&!(Z[Q]==="*"&&Z[Q+1]==="/"))Q++;return Q+=2,!0}return!1},q=()=>{if(J!==0)return;let j=Z.slice(Q).match(/^(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/);if(j){let V=j[2];if(!X.has(V))Y.push(V),X.add(V);return}let H=Z.slice(Q).match(/^(?:const|let|var)\s+\{([^}]+)\}\s*=/);if(H){H[1].split(",").forEach((V)=>{let N=V.trim();if(!N)return;let A=N.indexOf(":"),R=(A>=0?N.slice(A+1).trim():N).split(/[\s=]/)[0];if(R&&!X.has(R))Y.push(R),X.add(R)});return}let O=Z.slice(Q).match(/^(?:const|let|var)\s+\[([^\]]+)\]\s*=/);if(O){O[1].split(",").forEach((V)=>{let N=V.trim().replace(/^\.\.\./,"");if(!N)return;let A=N.split(/[\s=]/)[0];if(A&&!X.has(A))Y.push(A),X.add(A)});return}let F=Z.slice(Q).match(/^function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(F){let V=F[1];if(!X.has(V))Y.push(V),X.add(V);return}let L=Z.slice(Q).match(/^async\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(L){let V=L[1];if(!X.has(V))Y.push(V),X.add(V)}};while(Q<G){if(z())continue;if(Z[Q]==="'"||Z[Q]==='"'){B(Z[Q]),K=Z[Q-1];continue}if(Z[Q]==="`"){_(),K="`";continue}if(Z[Q]==="/"&&Z[Q+1]!=="/"&&Z[Q+1]!=="*"&&U()){W(),K="/";continue}if(Z[Q]==="{"){J++,K="{",Q++;continue}if(Z[Q]==="}"){J--,K="}",Q++;continue}if(J===0&&/[a-z]/i.test(Z[Q])&&(Q===0||/\s|[;{}()]/.test(Z[Q-1])))q();if(!/\s/.test(Z[Q]))K=Z[Q];Q++}return Y.join(", ")}async function eJ($,Z,Y,X){if(!a8($))return $;let J=$;if(Z.skipSignalsRuntime)return J;let{output:Q,setupCode:G}=await dB(J,Y,X);if(J=Q,J=await yB(J,Z),J=CB(J),G)if(J.includes("</head>"))J=J.replace("</head>",`${G}
9353
9363
  </head>`);else if(J.includes("<body"))J=J.replace(/<body([^>]*)>/,`<body$1>