rosefc 0.0.0-stage → 0.2.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.
@@ -0,0 +1,1693 @@
1
+ import*as C from"fs";import*as _ from"path";import*as as from"os";import{pathToFileURL as Zs,fileURLToPath as Rt}from"url";import*as ft from"esbuild";var T=class extends Error{code;file;line;hint;constructor(s,n,t={}){super(n),this.name="RoseError",this.code=s,this.file=t.file,this.line=t.line,this.hint=t.hint}info(){let s={code:this.code};return this.file!==void 0&&(s.file=this.file),this.line!==void 0&&(s.line=this.line),s.message=this.message,this.hint!==void 0&&(s.hint=this.hint),s}};function ot(e,s){let n=1,t=Math.min(s,e.length);for(let r=0;r<t;r++)e[r]===`
2
+ `&&n++;return n}function ve(e,s){return s&&s.index!==void 0?ot(e,s.index):void 0}function Ms(e){return e instanceof T?e.info():{code:"E-UNKNOWN",message:e instanceof Error?e.message:String(e)}}function Ns(e,s,n={}){let t=Math.max(0,n.radius??1),r=e.split(`
3
+ `),i=Math.max(1,s-t),o=Math.min(r.length,s+t),l=String(o).length,a=[];for(let u=i;u<=o;u++){let g=r[u-1]??"";a.push(` ${String(u).padStart(l)} | ${g}`),u===s&&n.column!==void 0&&a.push(` ${" ".repeat(l)} | ${" ".repeat(Math.max(0,n.column-1))}^`)}return a.join(`
4
+ `)}function Ls(e,s){return`$setState('${e}', ${s})`}function Is(e){if(!e)return[];let s=[];for(let n of e.matchAll(/\b(?:let|const|var)\s+([A-Za-z_$][\w$]*)\s*(?::[^=;\n]*)?=\s*\$derived\b/g))s.includes(n[1])||s.push(n[1]);return s}function Fs(e){let s="",n=0;for(;n<e.length;){let t=e[n];if(t==="/"&&(e[n+1]==="/"||e[n+1]==="*")){let r=e[n+1]==="/"?e.indexOf(`
5
+ `,n)<0?e.length:e.indexOf(`
6
+ `,n):e.indexOf("*/",n)<0?e.length:e.indexOf("*/",n)+2;s+=e.slice(n,r).replace(/[^\n]/g," "),n=r;continue}if(t==="'"||t==='"'||t==="`"){let r=n+1;for(;r<e.length&&e[r]!==t;)e[r]==="\\"?r+=2:r++;r=Math.min(r+1,e.length),s+=t+" ".repeat(Math.max(0,r-n-2))+(r-n>1?t:""),n=r;continue}s+=t,n++}return s}function Cn(e){if(!e)return null;let s=Fs(e);for(let n of Is(e))if(new RegExp(`(?<![\\w$.]|\\b(?:let|const|var)\\s{1,4})\\b${n}\\s*(?:\\+\\+|--|\\+=|-=|\\*=|/=|%=|=(?!=))|(?:\\+\\+|--)(?:\\s{1,4})${n}\\b(?![\\w$.])`).test(s))return n;return null}var Ds=["+=","-=","*=","/=","%="],An=[/[(,.<>=!&|+\-*/%?:]$/,/(?:&&|\|\||=>|\.\.)$/];function Yt(e,s,n=Ls){if(!e)return e;let t=/(?:^|[^\w$])(?:let|const|var|function|class|new|case|import|export|interface|type)\s+$/,r=f=>!!f&&/[A-Za-z_$]/.test(f),i="",o="",l=(f,h)=>{if(i+=f,!h)return;let p=f.replace(/\s+$/,"");p&&(o=(o+p).slice(-64))},a=()=>o.endsWith("=>")?"=>":o.replace(/\s+$/,"").slice(-1),u=0,g=f=>{let h=e[f],p=f+1;for(;p<e.length&&e[p]!==h;){if(e[p]==="\\"){p+=2;continue}if(h==="`"&&e[p]==="$"&&e[p+1]==="{"){let w=1;for(p+=2;p<e.length&&w>0;)e[p]==="{"?w++:e[p]==="}"&&w--,p++;continue}p++}return Math.min(p+1,e.length)},c=f=>{let h=f,p=0;for(;h<e.length;){let w=e[h];if(w==="'"||w==='"'||w==="`"){h=g(h);continue}if(w==="/"&&(e[h+1]==="/"||e[h+1]==="*")){h=e[h+1]==="/"?e.indexOf(`
7
+ `,h)<0?e.length:e.indexOf(`
8
+ `,h):e.indexOf("*/",h)<0?e.length:e.indexOf("*/",h)+2;continue}if(w==="("||w==="["||w==="{"){p++,h++;continue}if(w===")"||w==="]"||w==="}"){if(p===0)return h;p--,h++;continue}if(p>0){h++;continue}if(w===";")return h;if(w===`
9
+ `){let y=e.slice(f,h).replace(/\s+$/,"");if(y===""||An[0].test(y)||An[1].test(y)){h++;continue}return h}h++}return h};for(;u<e.length;){let f=e[u];if(f==="'"||f==='"'||f==="`"){let A=g(u);l(e.slice(u,A),!0),u=A;continue}if(f==="/"&&e[u+1]==="/"){let A=e.indexOf(`
10
+ `,u),D=A<0?e.length:A;l(e.slice(u,D),!1),u=D;continue}if(f==="/"&&e[u+1]==="*"){let A=e.indexOf("*/",u),D=A<0?e.length:A+2;l(e.slice(u,D),!1),u=D;continue}if((f==="+"||f==="-")&&e[u+1]===f&&["",";","{","}","(",",","=>"].includes(a())){let A=u+2;for(;A<e.length&&e[A]!==`
11
+ `&&/[ \t]/.test(e[A]);)A++;if(r(e[A])&&!(A>0&&/[\w$.]/.test(e[A-1]))){let D=A;for(;D<e.length&&/[\w$]/.test(e[D]);)D++;let J=e.slice(A,D);if(s(J)&&!t.test(o)){l(n(J,`${J}() ${f==="-"?"-":"+"} 1`),!0),u=D;continue}}l(f,!0),u++;continue}if(!r(f)||u>0&&/[\w$.]/.test(e[u-1])){l(f,!0),u++;continue}let h=u;for(;h<e.length&&/[\w$]/.test(e[h]);)h++;let p=e.slice(u,h);if(!s(p)||t.test(o)){l(p,!0),u=h;continue}let w=e.slice(h).match(/^[ \t]*/)[0].length,y=e.slice(h+w),m=a();if((y.startsWith("++")||y.startsWith("--"))&&!/[\w$.]/.test(y.slice(2,3))&&["",";","{","}","(",")",",","=>"].includes(m)){l(n(p,`${p}() ${y.startsWith("--")?"-":"+"} 1`),!0),u=h+w+2;continue}let v=null,x=1;for(let A of Ds)if(y.startsWith(A)){v=A.slice(0,-1),x=2;break}if((v!==null||/^=(?!=)/.test(y))&&["",";","{","}",")","=>"].includes(m)){let A=h+w+x,D=c(A),J=e.slice(A,D).trim();if(J){if(v===null){let N=new RegExp(`^(?:--\\s*${p}$|${p}\\s*--$)`).test(J),ee=new RegExp(`^\\+\\+\\s*${p}$|^${p}\\s*\\+\\+$`).test(J);if(N||ee){l(n(p,`${p}() ${N?"-":"+"} 1`),!0),u=D;continue}}l(n(p,v===null?J:`${p}() ${v} (${J})`),!0),u=D;continue}}l(p,!0),u=h}return i}import kt from"node:fs";import en from"node:path";var Tn=64,Bs=30*60*1e3;async function qs(e){for(let s=0;;s++)try{await kt.promises.rm(e,{force:!0});return}catch(n){if(s>=2||!/EPERM|EBUSY|EACCES/.test(String(n)))throw n;await new Promise(t=>setTimeout(t,50*(s+1)))}}async function Ws(e){for(let s=0;s<e.length;s+=Tn)await Promise.all(e.slice(s,s+Tn).map(qs))}async function Js(e){try{return await kt.promises.readdir(e,{withFileTypes:!0})}catch{return[]}}async function Et(e){let s=await Js(e),n=[],t=[];for(let r of s)r.isDirectory()?t.push(en.join(e,r.name)):n.push(en.join(e,r.name));await Ws(n),await Promise.all(t.map(r=>Et(r))),await kt.promises.rmdir(e).catch(()=>{})}function On(e){kt.promises.readdir(e).then(s=>{let n=Date.now();for(let t of s){let r=en.join(e,t);kt.promises.stat(r).then(i=>{i.isDirectory()&&n-i.mtimeMs>Bs&&Et(r).catch(()=>{})}).catch(()=>{})}}).catch(()=>{})}function qt(e){let s=2166136261,n=typeof e=="string"?new TextEncoder().encode(e):e;for(let t=0;t<n.length;t++)s^=n[t],s=Math.imul(s,16777619);return(s>>>0).toString(36)}var jn={"mini-program":["weapp","qq","alipay","baidu","toutiao"],miniprogram:["weapp","qq","alipay","baidu","toutiao"],native:["flutter","android","arkts","xcode"],desktop:["electron","python","dotnet","java","cpp"],web:["web"]},Hs=new Set(["weapp","qq","alipay","baidu","toutiao","flutter","android","arkts","xcode","electron","python","dotnet","java","cpp","web"]),Pn={"mp-weixin":"weapp","mp-qq":"qq","mp-alipay":"alipay","mp-baidu":"baidu","mp-toutiao":"toutiao"};function Mn(e,s){let n=s.toLowerCase(),t=e.trim().toLowerCase(),r=Pn[t]??t,i=jn[r];return i?i.includes(n):r===n}function Nn(e){let s=e.trim().toLowerCase();return Pn[s]?!0:jn[s]!==void 0||Hs.has(s)}function Ln(e,s="web",n=[]){let t=/^[ \t]*(?:\/\/|<!--|\/\*)\s*#(ifdef|ifndef|endif)\b([ \t\S]*?)(?:\*\/|-->)?[ \t]*$/gm,r=e.split(`
12
+ `),i=[],o=[],l=()=>o.every(Boolean);for(let a of r){let u=t.exec(a);if(t.lastIndex=0,u){let g=u[1],c=(u[2]??"").trim().split(/\s+/)[0].toLowerCase();if(g==="endif"){o.length?o.pop():n.push("#endif with no matching #ifdef - left as written");continue}Nn(c)||n.push(`#${g} ${c} names an unknown target or family - treated as false`);let f=Mn(c,s);o.push(g==="ifdef"?f:!f);continue}l()&&i.push(a)}return o.length&&n.push(`${o.length} #ifdef without #endif - the tail is kept as written`),i.join(`
13
+ `)}function In(e,s="web",n=[]){let t=s.toLowerCase(),r=e;for(let i=0;i<40;i++){let o=/\{#(ifdef|ifndef)\s+([^}]*)\}/.exec(r);if(!o)break;let l=o[1],a=o[2].trim().toLowerCase(),u=Mn(a,t),g=l==="ifdef"?u:!u;Nn(a)||n.push(`{#${l} ${a}} names an unknown target or family - treated as false`);let c=o.index+o[0].length,f=1,h=-1,p=-1,w=/\{#(ifdef|ifndef)\b|\{:(else)\b|\{\/(ifdef|ifndef)\}/g;w.lastIndex=c;for(let v=w.exec(r);v;v=w.exec(r))if(v[1])f++;else if(v[3]){if(f--,f===0){p=v.index;break}}else v[2]&&f===1&&(h=v.index);if(p<0){n.push(`{#${l} ${a}} has no {/${l}} - left as written`);break}let y=h>=0?h+7:p,m=h>=0?g?r.slice(c,h):r.slice(y,p):g?r.slice(c,p):"";r=r.slice(0,o.index)+m+r.slice(p+l.length+3)}return r}import Xe from"node:fs";function Fn(e){try{let s=Xe.openSync(e,"r"),n=Buffer.alloc(64),t=Xe.readSync(s,n,0,64,0);return Xe.closeSync(s),t<24?null:n[0]===137&&n[1]===80&&n[2]===78&&n[3]===71?{width:n.readUInt32BE(16),height:n.readUInt32BE(20)}:n.slice(0,3).toString("latin1")==="GIF"?{width:n.readUInt16LE(6),height:n.readUInt16LE(8)}:n.slice(0,4).toString("latin1")==="RIFF"&&n.slice(8,12).toString("latin1")==="WEBP"?zs(n):n[0]===255&&n[1]===216?Us(e):null}catch{return null}}function zs(e){let s=e.slice(12,16).toString("latin1");if(s==="VP8 ")return{width:e.readUInt16LE(26)&16383,height:e.readUInt16LE(28)&16383};if(s==="VP8L"){let n=e.readUInt32LE(21);return{width:(n&16383)+1,height:(n>>14&16383)+1}}if(s==="VP8X"){let n=e.readUIntLE(24,3)+1,t=e.readUIntLE(27,3)+1;return{width:n,height:t}}return null}function Us(e){let s=Xe.openSync(e,"r");try{let n=Buffer.alloc(4),t=2;for(let r=0;r<64;r++){if(Xe.readSync(s,n,0,4,t)<4)return null;if(n[0]!==255){t+=1;continue}let i=n[1];if(i===216||i===1||i>=208&&i<=215){t+=2;continue}let o=Xe.readSync(s,n,0,2,t+2)<2?0:n.readUInt16BE(2);if(i>=192&&i<=207&&i!==196&&i!==200&&i!==204){let l=Buffer.alloc(8);return Xe.readSync(s,l,0,8,t+4),{width:l.readUInt16BE(3),height:l.readUInt16BE(1)}}t+=2+o}return null}finally{Xe.closeSync(s)}}import Wt from"node:fs";import Dn from"node:path";function Vs(e){if(!e.startsWith("---"))return{frontmatter:{},body:e};let s=e.indexOf(`
14
+ ---`,3);if(s<0)return{frontmatter:{},body:e};let n=e.slice(4,s),t=e.slice(e.indexOf(`
15
+ `,s+1)+1).replace(/^\s*\n/,""),r={};for(let i of n.split(`
16
+ `)){let o=/^(\w[\w-]*):\s*(.*)$/.exec(i.trim());if(!o)continue;let[,l,a]=o,u=/^\[(.+)\]$/.exec(a.trim());r[l]=u?u[1].split(",").map(g=>g.trim().replace(/^["']|["']$/g,"")):a.trim().replace(/^["']|["']$/g,"")}return{frontmatter:r,body:t}}function Gs(e,s){return e.replace(/{{(\w[\w.]*)}}/g,(n,t)=>{let r=t.split(".").reduce((i,o)=>i==null?i:i[o],s);return r==null?"":String(r)})}function Bn(e,s){s&&(e=Gs(e,s));let n=[],t=e.replace(/```(\w*)\n([\s\S]*?)```/g,(a,u,g)=>(n.push(`<pre data-lang="${u}"><code>${g.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}</code></pre>`),`\0CODE${n.length-1}\0`)),r=a=>a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/`([^`]+)`/g,"<code>$1</code>").replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>").replace(/\*([^*]+)\*/g,"<em>$1</em>").replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" rel="noopener">$1</a>'),i=[],o=null,l=()=>{o&&(i.push(`</${o}>`),o=null)};for(let a of t.split(`
17
+ `)){let u=/^(#{1,4})\s+(.*)$/.exec(a),g=/^\s*[-*]\s+(.*)$/.exec(a),c=/^\s*\d+\.\s+(.*)$/.exec(a);u?(l(),i.push(`<h${u[1].length}>${r(u[2])}</h${u[1].length}>`)):g?(o!=="ul"&&(l(),i.push("<ul>"),o="ul"),i.push(`<li>${r(g[1])}</li>`)):c?(o!=="ol"&&(l(),i.push("<ol>"),o="ol"),i.push(`<li>${r(c[1])}</li>`)):a.trim()===""?l():a.startsWith("\0CODE")?(l(),i.push(a)):(l(),i.push(`<p>${r(a)}</p>`))}return l(),i.join(`
18
+ `).replace(/\u0000CODE(\d+)\u0000/g,(a,u)=>n[Number(u)])}function qn(e){let s={};if(!Wt.existsSync(e))return s;for(let n of Wt.readdirSync(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let t=[],r=Dn.join(e,n.name);for(let i of Wt.readdirSync(r)){if(!i.endsWith(".md"))continue;let o=Wt.readFileSync(Dn.join(r,i),"utf-8"),{frontmatter:l,body:a}=Vs(o);if(String(l.draft??"").toLowerCase()==="true")continue;let u=i.replace(/\.md$/,""),g=Bn(a),c=a.replace(/[#*`\[\]()>-]/g," ").split(/\s+/).filter(Boolean).length,f=[],h=g.replace(/<h([1-4])>([^<]+)<\/h\1>/g,(p,w,y)=>{let m=y.toLowerCase().replace(/[^\w\s-]/g,"").trim().replace(/\s+/g,"-");return f.push({level:Number(w),text:y,id:m}),`<h${w} id="${m}">${y}</h${w}>`});t.push({slug:u,frontmatter:l,body:a,html:h,readingTime:Math.max(1,Math.round(c/200)),wordCount:c,toc:f,excerpt:String(l.summary??"")||(g.match(/<p>([\s\S]*?)<\/p>/)?.[1]??"").replace(/<[^>]+>/g,"").slice(0,160)})}t.sort((i,o)=>String(o.frontmatter.date??"").localeCompare(String(i.frontmatter.date??""))),s[n.name]=t}return s}globalThis.__rosefcContentMk=Bn;var tn=new Map;function et(e,s,n){let t=sr(),r={...s,define:{...rr(),...s.define??{}}};if(e+=`|env:${t}`,!n||s.splitting)return ft.build(r);let i=tn.get(e);return i?i.rebuild().catch(o=>{throw tn.delete(e),o}):ft.context(r).then(o=>(tn.set(e,o),o.rebuild()))}var ct=/<script>([\s\S]*?)<\/script>/,cs=/<template>([\s\S]*?)<\/template>/,on=/<head>([\s\S]*?)<\/head>/,an=/<style>([\s\S]*?)<\/style>/,Wn=/(?<=^|[;}{\n])[ \t]*(?:let|const|var)\s+(\w+)[^\n;{}=]*=\s*\$(state|data|kv|persist|derived)\b/g,Xs=/^\s+as\s+[^;\n]+/,Ks=/\$setState\(([^,]+),\s*([^)]+)\)/g;var Qs=/<slot\s*\/>|<slot>([\s\S]*?)<\/slot>/g,Ys=/<slot\s+((?=[^>]*\bname\s*=)[^>]*?)(?:\/>|>([\s\S]*?)<\/slot>)/g;function Jn(e){let s=/\bname\s*=\s*["'](\w+)["']/.exec(e)?.[1];if(!s)throw new T("E-TEMPLATE",'<slot> with attributes must declare a name: <slot name="row" ... />',{hint:'a slot carrying attributes is a NAMED slot - it must declare which one: <slot name="row" item={post} />'});let n=[...e.matchAll(/\b(\w+)\s*=\s*\{([^}]*)\}/g)].filter(t=>t[1]!=="name").map(t=>`['${t[1]}', (${t[2].trim()})]`);return`${JSON.stringify(s)}, [${n.join(", ")}]`}var er="<p>This section failed to render.</p>",tr=new Set(["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]),it={loader:{".js":"ts"}},At="ROSEFC_PUBLIC_",nr=/^[A-Za-z_$][\w$]*$/,mn=()=>Object.entries(process.env).filter(e=>e[0].startsWith(At)&&typeof e[1]=="string").sort(([e],[s])=>e<s?-1:e>s?1:0),sr=()=>Vt(JSON.stringify(mn()));function rr(){let e=Object.fromEntries(mn()),s={};for(let[n,t]of Object.entries(e))nr.test(n)&&(s[`import.meta.env.${n}`]=JSON.stringify(t).replace(/</g,"\\u003c"));return s["import.meta.env"]=JSON.stringify(e).replace(/</g,"\\u003c"),s}function Hn(e){return[...e.matchAll(/\bimport\.meta\.env\.([A-Za-z_$][\w$]*)/g)].map(s=>s[1])}function nn(e,s){let n={"(":")","[":"]","{":"}"}[e[s]]??"";if(!n)return-1;let t=0;for(let r=s;r<e.length;r++)if(e[r]===e[s])t++;else if(e[r]===n&&(t--,t===0))return r;return-1}function or(e,s){let n={")":"(","]":"[","}":"{"}[e[s]]??"";if(!n)return-1;let t=0;for(let r=s;r>=0;r--)if(e[r]===e[s])t++;else if(e[r]===n&&(t--,t===0))return r;return-1}function ir(e,s){let n=0;for(let t=s;t<e.length;t++){let r=e[t];if(r==="("||r==="["||r==="{"){n++;continue}if(r===")"||r==="]"||r==="}"){if(n===0)return t;n--;continue}if(n===0&&(r===","||r===";"))return t}return e.length}function ar(e){let s=Jt(e),n=[],t=(r,i)=>{let o=[];for(let l of s.slice(r,i).matchAll(/\b(?:const|let|var|function|class)\s+([A-Za-z_$][\w$]*)/g))o.push(l[1]);return o};for(let r of s.matchAll(/\bfunction\b/g)){let i=r.index+r[0].length;for(;i<s.length&&/\s/.test(s[i]);)i++;for(s[i]==="*"&&i++;i<s.length&&/[A-Za-z_$]/.test(s[i]);)i++;for(;i<s.length&&/\s/.test(s[i]);)i++;if(s[i]!=="(")continue;let o=nn(s,i);if(o<0)continue;let l=o+1;for(;l<s.length&&/\s/.test(s[l]);)l++;if(s[l]!=="{")continue;let a=nn(s,l);if(a<0)continue;let u=new Set(Ot(e.slice(i+1,o)));for(let g of t(l,a))u.add(g);n.push({start:i,end:a+1,names:u})}for(let r of s.matchAll(/=>/g)){let i=r.index,o=i-1;for(;o>=0&&/\s/.test(s[o]);)o--;let l="",a=i;if(s[o]===")"){let f=or(s,o);if(f<0)continue;l=e.slice(f+1,o),a=f}else if(/[A-Za-z_$]/.test(s[o]??"")){let f=o;for(;f>=0&&/[\w$]/.test(s[f]);)f--;l=e.slice(f+1,o+1),a=f+1}else continue;let u=i+2;for(;u<s.length&&/\s/.test(s[u]);)u++;let g=s[u]==="{"?nn(s,u)+1:ir(s,u);if(g<=0)continue;let c=new Set(Ot(l));n.push({start:a,end:g,names:c})}return n.sort((r,i)=>r.start-i.start)}function ze(e,s,n){if(s.length===0&&!n)return e;let t=ar(e),r=(o,l)=>{for(let a of t){if(a.start>o)break;if(o<a.end&&a.names.has(l))return!0}return!1},i=(o,l=0)=>{let a="",u=0;for(;u<o.length;){let g=o[u];if(g==="'"||g==='"'){let c=u+1;for(;c<o.length&&o[c]!==g;)o[c]==="\\"&&c++,c++;a+=o.slice(u,Math.min(c+1,o.length)),u=c+1;continue}if(g==="`"){for(a+=g,u++;u<o.length&&o[u]!=="`";){if(o[u]==="\\"){a+=o.slice(u,u+2),u+=2;continue}if(o[u]==="$"&&o[u+1]==="{"){let c=1,f=u+2;for(;f<o.length&&c>0&&(o[f]==="{"?c++:o[f]==="}"&&c--,c!==0);)f++;a+="${"+i(o.slice(u+2,f),l+u+2)+"}",u=f+1;continue}a+=o[u],u++}a+="`",u++;continue}if(g==="/"&&o[u+1]==="/"){let c=o.indexOf(`
19
+ `,u),f=c===-1?o.length:c;a+=o.slice(u,f),u=f;continue}if(g==="/"&&o[u+1]==="*"){let c=o.indexOf("*/",u+2),f=c===-1?o.length:c+2;a+=o.slice(u,f),u=f;continue}if(/[A-Za-z_$]/.test(g)){let c=u;for(;c<o.length&&/[\w$]/.test(o[c]);)c++;let f=o.slice(u,c),h=a.length?a[a.length-1]:"",p=o[c]??"",w=h==="@",y=!/[\w$.]/.test(h)&&!/[\w$:(]/.test(p),m=y&&!w&&s.includes(f)&&!r(l+u,f),v=y&&n!=null&&Object.prototype.hasOwnProperty.call(n,f);a+=m?`${f}()`:v?`${n[f]}()`:f,u=c;continue}a+=g,u++}return a};return i(e)}var ls=/^\s*#(?:if|each|await|key|snippet|boundary|island|defer)\b/,us=/^\s*\/(?:if|each|await|key|snippet|boundary|island|defer)\s*$/,ds=/^\s*:(?:else|then|catch|fallback)\b/,cr=/^\s*#each\s+([\s\S]+?)\s+as\s+(\{[^{}]*\}|\[[^[\]]*\]|\w+)(?:\s*,\s*(\w+))?(?:\s*\(([\s\S]+)\))?\s*$/,lr=/^\s*#snippet\s+(\w+)(?:\s*\(([\s\S]*)\))?\s*$/,ur=/^\s*:(?:then|catch)\s+([A-Za-z_$][\w$]*)\s*$/;function Ot(e){return e.replace(/^[{[]/,"").replace(/[}\]]$/,"").split(",").map(n=>{let t=n.split("=")[0].trim(),r=t.indexOf(":");return r>=0?t.slice(r+1).trim():t}).filter(n=>/^[A-Za-z_$][\w$]*$/.test(n))}function fs(e,s){let n=[],t=0;for(;t<e.length;){let r=no(e.slice(t),s);if(!r)break;if(r.selfClosing){t+=r.end;continue}let i=zt(e,t+r.end,r.name),o=i>=0?i+r.name.length+3:e.length;n.push([t+r.start,o]),t=o}return n}function dr(e,s){let n=[],t=0,r=s.size>0?fs(e,s):[],i=0,o=-1;for(let l of ut(e)){for(;i<r.length&&r[i][0]<=l.start;)o=r[i++][1];if(l.start<o)continue;let a=l.expr;if(us.test(a)){t>0&&t--;continue}if(ls.test(a)){t++;continue}if(!ds.test(a)&&t===0){let u=/^\s*@const\s+([A-Za-z_$][\w$]*)\s*=/.exec(a);u&&n.push(u[1])}}return n}function cn(e,s,n,t){if(s.length===0&&!n)return e;let r="",i=0,o=[new Set],l=()=>o[o.length-1],a=h=>o.some(p=>p.has(h)),u=t?.ownScope?h=>{for(let p=o.length-1;p>=0;p--)if(o[p].has(h))return p===0;return!1}:h=>!a(h),g=()=>[s.filter(h=>!a(h)),n?Object.fromEntries(Object.entries(n).filter(([h])=>u(h))):void 0],c=[];if(t?.comps&&t.comps.size>0)for(let[h,p]of fs(e,t.comps))c.push({pos:h,open:!0}),c.push({pos:p,open:!1});let f=0;for(let h of ut(e)){for(;f<c.length&&c[f].pos<=h.start;)c[f].open?o.push(new Set):o.length>1&&o.pop(),f++;let p=h.expr;if(us.test(p)){o.length>1&&o.pop(),r+=e.slice(i,h.end+1),i=h.end+1;continue}if(ls.test(p)){let v=cr.exec(p);if(v){let[,D,J,N,ee]=v,[H,U]=g(),te=` as ${J}${N?`, ${N}`:""}`;o.push(new Set([...Ot(J),...N?[N]:[]]));let ce=ee!=null&&ee.trim()!==""?` (${ze(ee,...g())})`:"";r+=e.slice(i,h.start)+`{#each ${ze(D,H,U)}${te}${ce}}`,i=h.end+1;continue}let x=lr.exec(p);if(x){o.push(new Set(x[2]?Ot(x[2]):[])),r+=e.slice(i,h.end+1),i=h.end+1;continue}let[S,A]=g();r+=e.slice(i,h.start)+"{"+ze(p,S,A)+"}",o.push(new Set),i=h.end+1;continue}if(ds.test(p)){l().clear();let v=ur.exec(p);if(v){l().add(v[1]),r+=e.slice(i,h.end+1),i=h.end+1;continue}let[x,S]=g();r+=e.slice(i,h.start)+"{"+ze(p,x,S)+"}",i=h.end+1;continue}let w=/^\s*@const\s+([A-Za-z_$][\w$]*)\s*=([\s\S]*)$/.exec(p),[y,m]=g();if(w){let v=w[2],x=ze(v,y,m);l().add(w[1]),r+=e.slice(i,h.start)+(x===v?e.slice(h.start,h.end+1):`{@const ${w[1]} =${x}}`),i=h.end+1;continue}r+=e.slice(i,h.start)+"{"+ze(p,y,m)+"}",i=h.end+1}return r+e.slice(i)}function ut(e){let s=[],n=0;for(;n<e.length;){if(e[n]==="{"){let t=jt(e,n);if(t>n+1){s.push({start:n,end:t,expr:e.slice(n+1,t)}),n=t+1;continue}}n++}return s}function fr(e,s){let n=s;for(;n<e.length;){if(e[n]==="{"){let t=jt(e,n);if(t>n+1)return{index:n,end:t,expr:e.slice(n+1,t)}}n++}return null}function jt(e,s){let n=0,t=s;for(;t<e.length;){let r=e[t];if(r==="'"||r==='"'){t=Ve(e,t);continue}if(r==="`"){t=Ut(e,t);continue}if(r==="/"){let i=tt(e,t);if(i!==null){t=i;continue}}if(r==="{")n++;else if(r==="}"&&--n===0)return t;t++}return-1}function Ue(e,s){let n=s+2,t=1;for(;n<e.length;){let r=e[n];if(r==="'"||r==='"'){n=Ve(e,n);continue}if(r==="`"){n=Ut(e,n);continue}if(r==="{")t++;else if(r==="}"&&--t===0)return n+1;n++}return-1}function Ve(e,s){let n=e[s],t=s+1;for(;t<e.length;){if(e[t]==="\\"){t+=2;continue}if(e[t]===n)return t+1;t++}return t}function Ut(e,s){let n=s+1;for(;n<e.length;){let t=e[n];if(t==="\\"){n+=2;continue}if(t==="`")return n+1;if(t==="$"&&e[n+1]==="{"){let r=jt(e,n+1);n=r<0?e.length:r+1;continue}n++}return n}function hs(e,s){let n=s;for(;n>=0&&/[\w$]/.test(e[n]);)n--;return n===s?"":e.slice(n+1,s+1)}function tt(e,s){let n=e[s];if(n==='"'||n==="'")return Ve(e,s);if(n==="`")return Ut(e,s);if(n!=="/"||e[s+1]==="/"||e[s+1]==="*")return null;let t=s-1;for(;t>=0&&/\s/.test(e[t]);)t--;if(t>=0&&!"(,=:[!&|?{};+-*%~^".includes(e[t])){let o=hs(e,t);if(!["return","typeof","case","in","of","new","delete","void","do","else","instanceof","yield","await"].includes(o))return null}let r=s+1,i=!1;for(;r<e.length;){let o=e[r];if(o==="\\"){r+=2;continue}if(o===`
20
+ `)return null;if(i)o==="]"&&(i=!1);else if(o==="[")i=!0;else if(o==="/"){r++;break}r++}if(r>e.length)return null;for(;r<e.length&&/[dgimsuvy]/.test(e[r]);)r++;return r}function zn(e){let s="",n=0;for(;n<e.length;){let t=tt(e,n);if(t!==null){s+=e.slice(n,t),n=t;continue}if(e.startsWith("//",n)){for(;n<e.length&&e[n]!==`
21
+ `;)n++;continue}if(e.startsWith("/*",n)){for(n+=2;n<e.length&&!e.startsWith("*/",n);)n++;n=Math.min(n+2,e.length);continue}if(e.startsWith("<!--",n)){for(n+=4;n<e.length&&!e.startsWith("-->",n);)n++;n=Math.min(n+3,e.length);continue}s+=e[n++]}return s}function hr(e){let s=/typeof\s+(?:window|document|navigator|location|localStorage|sessionStorage)\s*(!==|===)\s*["']undefined["']/y,n=c=>{for(;c<e.length&&/\s/.test(e[c]);)c++;return c},t=c=>{let f=0,h=c+1;for(;h<e.length;){let p=e[h],w=tt(e,h);if(w!==null){h=w;continue}if(p==="("||p==="["||p==="{")f++;else if(p===")"||p==="]"||p==="}"){if(f--,f<0)return-1}else{if(f===0&&p===":")return h;if(f===0&&p==="?"){let y=t(h);if(y<0)return-1;h=y+1;continue}}h++}return-1},r=c=>{let f=0;for(;c<e.length;){let h=e[c],p=tt(e,c);if(p!==null){c=p;continue}if(h==="("||h==="["||h==="{")f++;else if(h===")"||h==="]"||h==="}"){if(f===0)return c;f--}else{if(f===0&&(h===","||h===";"))return c;if(f===0&&h==="?"){let w=t(c);if(w<0)return e.length;c=w+1;continue}}c++}return e.length},i=c=>{let f=0,h=c;for(;h<e.length;){let p=e[h],w=tt(e,h);if(w!==null){h=w;continue}if(p==="{")f++;else if(p==="}"&&(f--,f===0))return h;h++}return e.length},o=c=>{let f=0;for(;c<e.length;){let h=e[c],p=tt(e,c);if(p!==null){c=p;continue}if(h==="("||h==="["||h==="{")f++;else if(h===")"||h==="]"||h==="}"){if(f===0)return c;f--}else if(f===0&&(h===";"||h===`
22
+ `))return c;c++}return e.length},l=(c,f)=>{let h=f-1;for(;h>=0&&/\s/.test(c[h]);)h--;if(h<0||c[h]!=="(")return!1;for(h--;h>=0&&/\s/.test(c[h]);)h--;return h>=1&&c[h]==="f"&&c[h-1]==="i"&&(h<2||!/[\w$]/.test(c[h-2]))},a=[],u=0;for(;u<e.length;){let c=tt(e,u);if(c!==null){u=c;continue}s.lastIndex=u;let f=s.exec(e);if(!f){u++;continue}let h=f[1]==="!==",p=n(u+f[0].length),w=e.slice(p,p+2);if(w==="&&"&&h)a.push([p+2,r(p+2)]);else if(w==="||"&&!h)a.push([p+2,r(p+2)]);else if(e[p]==="?"){let y=t(p);y<0?h&&a.push([p+1,e.length]):h?a.push([p+1,y]):a.push([y+1,r(y+1)])}else if(e[p]===")"&&l(e,u)){let y,m=n(p+1);e[m]==="{"?(y=i(m),h&&a.push([m+1,y])):(y=o(m),h&&a.push([m,y]));let v=n(y+1);if(e.startsWith("else",v)){let x=n(v+4);if(e[x]==="{"){let S=i(x);h||a.push([x+1,S])}else{let S=o(x);h||a.push([x,S])}}}u=p}if(a.length===0)return e;let g=[...e];for(let[c,f]of a)for(let h=c;h<f&&h<g.length;h++)g[h]!==`
23
+ `&&(g[h]=" ");return g.join("")}function Uo(e){return e.match(ct)?.[1]??null}async function ps(e){let s=_.join(e,"rosefc.config.js");if(!C.existsSync(s))return{plugins:[],i18n:{}};let n=await import(Zs(s).href+`?t=${Date.now()}`);return{plugins:n.default??[],i18n:n.i18n??{},pwa:n.pwa??void 0,brotli:n.brotli??void 0,csp:n.csp??void 0,watch:n.watch??void 0}}async function Vo(e){return(await ps(e)).plugins}function Un(e,s,n){let t=[],r=(o,l)=>{let a=_.resolve(_.dirname(s),o),u=n.get(a);if(!u)throw new T("E-IMPORT",`${_.basename(s)}: cannot import '${o}' - no .rose file at ${a}. A component lives under src/components/ (or src/pages/) and is imported by relative path.`,{file:s,line:ot(e,l),hint:`create ${a} (a .rose component) or fix the import path - a .rose import resolves to a file, never to a package`});return u},i=e.replace(/import\s+(\w+)\s+from\s*(['"])([^'"]+\.rose)\2/g,(o,l,a,u,g)=>{let c=r(u,g);return t.push({name:l,specifier:u,index:c.index}),`import { render as ${l} } from ${a}__rose_${c.index}__${a}`});return i=i.replace(/import\s*(\{[^}]*\})\s+from\s*(['"])([^'"]+\.rose)\2/g,(o,l,a,u,g)=>{let c=r(u,g),f=/\bas\s+(\w+)/.exec(l)?.[1]??"render";return t.push({name:f,specifier:u,index:c.index}),`import ${l} from ${a}__rose_${c.index}__${a}`}),{script:i,imports:t}}function sn(e,s){return e.replace(/from\s*(['"])__rose_(\d+)__\1/g,(n,t,r)=>`from ${t}./comp-${r}.${s}.js${t}`)}var pr=/^(?:node:|(?:fs|path|os|crypto|http|https|net|tls|stream|child_process|worker_threads|dns|cluster|better-sqlite3|sqlite3|pg|mysql2|mongodb|redis|ioredis)$)/;function gr(e){let s=[];for(let n of e.matchAll(/import\s+(type\s+)?[\s\S]*?from\s*['"]([^'"]+)['"]/g))n[1]||pr.test(n[2])&&s.push(n[2]);return s}function mr(e){let s=[];for(let n=0;;){let t=at(e,"each",n);if(!t)break;n=t.index+1;let r=Ue(e,t.index),i=t[5];r<0||i==null||s.push({names:new Set([...Ot(t[2]??""),...t[3]?[t[3]]:[]]),contentStart:r,contentEnd:r+i.length})}return s}function wr(e,s,n){let t=0;for(let r of e.slice(s,n).matchAll(/\{#(?:snippet|key|await)\b|\{\/(?:snippet|key|await)\s*\}/g))if(t+=r[0][1]==="/"?-1:1,t>0)return!0;return!1}function br(e,s,n="<template>",t=""){let r=[],i=0,o=null,l="",a=e,u=0,g={window:"w",document:"d"},c={preventDefault:()=>"e.preventDefault()",stopPropagation:()=>"e.stopPropagation()",self:p=>`const __self = e.target.closest && e.target.closest('[data-${p}-' + e.type + ']'); if (__self && e.target !== __self) return;`},f={once:p=>`const __o = e.target && e.target.closest ? e.target.closest('[data-${p}-' + e.type + ']') : null; if (__o) __o.removeAttribute('data-${p}-' + e.type);`},h=[...Object.keys(c),...Object.keys(f),...Object.keys(g)];for(;;){let p=/\bon:(\w+)((?:\|\w+)*)\s*=\s*\{/.exec(a);if(!p){l+=a;break}let w=!1,y=p[2]?p[2].slice(1).split("|"):[],m=y.filter(N=>g[N]);if(m.length>1)throw new T("E-TEMPLATE",`${n}: on:${p[1]} carries both |${m.join(" and |")}`,{hint:"a handler binds to one target - the element (default), |window or |document"});let v=m.length?"on"+g[m[0]]:"on";for(let N of y)if(!h.includes(N))throw new T("E-TEMPLATE",`${n}: unknown event modifier |${N}`,{hint:`the supported modifiers are ${h.map(ee=>"|"+ee).join(" ")} - capture/passive are listener options a delegated listener cannot carry per element; anything else belongs inside the handler body`});l+=a.slice(0,p.index);let x=p.index+p[0].length,S=1;for(;x<a.length;){let N=a[x];if(N==='"'||N==="'"){x=Ve(a,x);continue}if(N==="`"){x=Ut(a,x);continue}if(N==="{")S++;else if(N==="}"&&(S--,S===0))break;x++}let A=a.slice(p.index+p[0].length,x).trim(),D=new Set;for(let N of e.matchAll(/\{#each\s+[\s\S]+?\s+as\s+([A-Za-z_$][\w$]*)\s*(?:,\s*([A-Za-z_$][\w$]*))?/g))D.add(N[1]),N[2]&&D.add(N[2]);if(/=>/.test(A)&&!/^\w+$/.test(A)){let N=[...D].filter(ee=>new RegExp(`\\b${ee}\\b`).test(A));if(N.length>0){let ee=u+p.index,H=(o??=mr(e)).filter(te=>ee>=te.contentStart&&ee<te.contentEnd).sort((te,ce)=>te.contentStart-ce.contentStart).pop()??null;if(H!=null&&!wr(e,H.contentStart,ee)&&N.every(te=>H.names.has(te)))w=!0;else{let te=N.find(ce=>!H||!H.names.has(ce))??N[0];throw new T("E-TEMPLATE",`${n}: this inline handler reads the {#each} variable "${te}" but is hoisted to the page module, where it does not exist`,{file:n,line:ot(e,u+p.index),hint:`name the handler in the script block (function onX(e) { ... }) and write on:${p[1]}={onX} - the named form closes over nothing and works for every item`})}}}let J=N=>{if(!y.length)return N;let ee=y.filter(U=>c[U]).map(U=>c[U](v)),H=y.filter(U=>f[U]).map(U=>f[U](v));return`(e) => {${ee.length?" "+ee.join("; ")+";":""} (${N})(e);${H.length?" "+H.join("; ")+";":""} }`};if(y.length&&s.has(A))throw new T("E-TEMPLATE",`${n}: event modifiers are not supported on the server action ${A}`,{hint:"$action already preventDefaults - drop the modifiers, or bind a local handler that calls $action"});if(w){let N=t?`__rh_${t}_`:"__rh_";l+=`data-${v}-${p[1]}={__rhreg(${JSON.stringify(N)}, ${y.length?J(A):A})}`,i++}else if(y.length){let N=t?`__h_${t}_${r.length}`:`__h${r.length}`;l+=`data-${v}-${p[1]}="${N}"`,r.push({event:p[1],fn:`${N}: ${J(A)}`})}else if(s.has(A))l+=`data-on-${p[1]}="$action:${A}"`;else if(/^\w+$/.test(A))l+=`data-on-${p[1]}="${A}"`,r.push({event:p[1],fn:A});else{let N=t?`__h_${t}_${r.length}`:`__h${r.length}`;l+=`data-on-${p[1]}="${N}"`,r.push({event:p[1],fn:`${N}: ${A}`})}u+=x+1,a=a.slice(x+1)}return{template:l,bindings:r,inlineCount:i}}function $r(e){let s;try{s=C.readFileSync(e,"utf-8")}catch{return[]}let t=s.replace(ct,"").replace(an,""),r=t.match(cs)?.[1]??t.replace(on,"").trim(),i=[];for(let o of r.matchAll(/<slot\s+([^>]*?)\/?>/g)){let l=/\bname\s*=\s*["'](\w+)["']/.exec(o[1]);if(!l)continue;let a=[...o[1].matchAll(/\b(\w+)\s*=\s*\{/g)].map(u=>u[1]).filter(u=>u!=="name");i.push({name:l[1],props:a})}return i}function Vn(e){let s=[],n=[],t=null,r=0,i=o=>r<=0&&/from\s*['"][^'"]+['"]\s*;?\s*$/.test(o);for(let o of e.split(`
24
+ `)){if(t){t.push(o);for(let l of o)l==="{"||l==="("?r++:(l==="}"||l===")")&&r--;i(o)&&(s.push(t.join(`
25
+ `)),t=null);continue}if(/^\s*import\b/.test(o)){t=[o],r=0;for(let l of o)l==="{"||l==="("?r++:(l==="}"||l===")")&&r--;i(o)&&(s.push(o),t=null);continue}n.push(o)}return t&&s.push(t.join(`
26
+ `)),{imports:s.join(`
27
+ `),rest:n.join(`
28
+ `)}}var St=new Map,Gn=new Map;function gs(e){let s=Gn.get(e);return s||(s=new Set,Gn.set(e,s)),s}var ms=[],yr=2e3,Zn=new WeakMap,Xn=new WeakMap;function _r(e){let s=Zn.get(e);if(s===void 0){let n=[];for(let[t,r]of e)n.push(`${t}#${r.index}:${r.scopeKey}:${r.slots.join("|")}`);s=n.join(";"),Zn.set(e,s)}return s}function xr(e){let s=Xn.get(e);if(s===void 0){let n=[];for(let t of e){if(!t.transform)continue;let r;try{r=String(t.transform)}catch{r="opaque"}n.push(`${t.name}${Vt(r)}`)}s=n.join(""),Xn.set(e,s)}return s}function vr(e,s,n,t,r){let i;try{i=C.statSync(e)}catch{return null}let o=[e,String(i.mtimeMs),String(i.size),s,n?"1":"0",_r(t),xr(r)],l=gs(e);for(let a of l)try{o.push(`${a}${String(C.statSync(a).mtimeMs)}`)}catch{o.push(`${a}gone`)}for(let a of ms)try{o.push(`watch:${a}${String(C.statSync(a).mtimeMs)}`)}catch{}return o.join("\0")}var kr=(()=>{try{return String(C.statSync(Rt(import.meta.url)).mtimeMs)}catch{return"noid"}})(),lt=(()=>{try{let e=_.join(as.tmpdir(),"rosefc-compile-cache");return C.mkdirSync(e,{recursive:!0}),e}catch{return null}})(),Er=0;function Vt(e){let s=2166136261;for(let n=0;n<e.length;n++)s^=e.charCodeAt(n),s=Math.imul(s,16777619);return(s>>>0).toString(16).padStart(8,"0")}function ws(e){return _.join(lt,Vt(e+"|"+kr)+".json")}function Sr(e){if(!lt||process.env.ROSEFC_NO_DISK_CACHE==="1")return null;try{let s=JSON.parse(C.readFileSync(ws(e),"utf-8"));if(s&&typeof s=="object"&&typeof s.ssr=="string")return s}catch{}return null}function Rr(e,s){if(!lt||process.env.ROSEFC_NO_DISK_CACHE==="1")return;let n=ws(e),t=JSON.stringify(s);C.promises.writeFile(n,t).catch(()=>{C.promises.mkdir(lt,{recursive:!0}).then(()=>C.promises.writeFile(n,t)).catch(()=>{})});try{if(!(Er++&511)){let r=C.readdirSync(lt);if(r.length>5e3)for(let i of r)try{C.unlinkSync(_.join(lt,i))}catch{}}}catch{}}async function Ar(e,s,n,t,r,i){let o=vr(e,n,t,i,r);if(o){let a=St.get(o);if(a)return{...a};let u=Sr(o);if(u)return u}let l=await Cr(e,s,n,t,r,i);if(o){if(St.size>=yr){let a=St.keys().next().value;a!==void 0&&St.delete(a)}St.set(o,l),Rr(o,l)}return l}function Kn(e,s){let n=e.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+hotVary\s*=\s*\[([\s\S]*?)\]\s*;?/);if(!n)return;let t=[];for(let r of n[1].split(",")){let i=r.trim().replace(/^['"`]|['"`]$/g,"");if(!i)continue;let o=i.toLowerCase();if(!/^[a-z0-9!#$%&'*+.^_`|~-]+$/.test(o))throw new T("E-EXPORT",`${s}: export const hotVary must list request header names (got '${i}')`,{file:s,line:ve(e,n),hint:"hotVary is a list of the request headers this route negotiates on, e.g. export const hotVary = ['x-locale', 'x-rv-url']"});if(o==="accept-encoding")throw new T("E-EXPORT",`${s}: hotVary must not name accept-encoding - the server stores raw bytes and re-negotiates the encoding on every request`,{file:s,line:ve(e,n),hint:"drop accept-encoding from hotVary; it is already handled per request"});o==="cookie"||o==="accept-language"||t.includes(o)||t.push(o)}return t.length?t:void 0}async function Cr(e,s,n,t=!1,r=[],i=new Map){let o=await C.promises.readFile(e,"utf-8");for(let $ of r)if($.transform)try{let k=await $.transform(o,e);if(typeof k=="string")o=k;else{o=k.code;for(let R of k.deps??[])gs(e).add(R)}}catch(k){throw new T("E-PLUGIN",`plugin ${$.name} failed on ${_.basename(e)}: ${k instanceof Error?k.message:String(k)}`,{file:e,hint:"the error above came from inside the plugin - fix its transform() (or remove the plugin from rosefc.config.js)"})}if(o=Ln(o,"web"),t){let k=o.match(ct)?.[1]??"",R=[...new Set([...[...k.matchAll(/(?:^|\n)\s*export\s+(?:async\s+)?function\s+(\w+)\s*\(/g)].map(xe=>xe[1]),...[...k.matchAll(/(?:^|\n)\s*export\s+(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s*)?(?:function\b|(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>)/g)].map(xe=>xe[1])])].filter(xe=>tr.has(xe)),W=/getContext\s*\(/.test(k)||/\$store\s*\(/.test(k)||/\$query\s*\(/.test(k),Q=/\$store\s*\(/.test(k),ne=k.includes("__rosefcAuth"),ge=!W&&/(?:^|\n)\s*export\s+(?:const|let|var)\s+prerender\s*=\s*true\b/.test(k),_e=Vn(Un(k,e,i).script),Le=new Set([...k.matchAll(/import\s*\{([^}]*)\}\s*from\s*['"]\.\/runtime\.js['"]/g)].flatMap(xe=>xe[1].split(",").map(Ce=>Ce.trim().split(/\s+as\s+/)[0]).filter(Boolean))),Ze=$o.filter(xe=>!Le.has(xe)),he=Ze.length>0?`import { ${Ze.join(", ")} } from './runtime.js';
29
+ `:"";return{ssr:"",client:"",stateKeys:[],actionNames:[],guardName:null,style:"",hasParams:!1,api:`${he}${sn(`${_e.imports}
30
+ ${_e.rest}`,"ssr").trim()}`,apiMethods:R,hasPrerender:ge,usesContext:W,usesStore:Q,usesRosefcAuth:ne,hotVary:Kn(k,e)}}let l=o.replace(ct,""),a=l.replace(on,""),u=a.match(an),g=n==="_layout"||n.endsWith("/_layout"),c=u?.[1]?g?bs(u[1]):$s(u[1],n):"",f=a.replace(an,""),h=o.match(ct),p=Un(h?.[1]??"",e,i),w=p.script,y=w.includes("__rosefcAuth"),m=p.imports,{imports:v,rest:x}=Vn(w);if(_.basename(e)!=="_middleware.rose")for(let $ of gr(v)){let k=v.indexOf($);throw new T("E-NODE-ONLY",`${e}: cannot import '${$}' in a page or component - it never reaches the browser. This module's script ships to the client (its $data bodies included), so move the import to src/pages/_middleware.rose or a pages/api/*.rose handler: those are server-only, and the rows travel to the page through getContext() / $data.`,{file:e,line:k>=0?ot(v,k):void 0,hint:`'${$}' is a server-only module: import it inside src/pages/_middleware.rose (or a pages/api/*.rose handler) instead - a page/component script ships to the browser`})}let S=i.get(e)?.scopeKey.startsWith("components/")??!1;if(S&&/\$data\s*\(/.test(w))throw new T("E-EXPORT",`${e}: $data() is not allowed in a component - an imported component renders synchronously inside its parent. Fetch in the page's $data (or pages/_middleware.rose) and pass the value down as a prop: <Card user={user()}>.`,{file:e,hint:"move the fetch to the page (or the middleware) and pass the value down as a prop"});let A=/getContext\s*\(/.test(w)||/\$store\s*\(/.test(w)||/\$query\s*\(/.test(w),D=/\$store\s*\(/.test(w),J=/(?:^|\n)\s*export\s+(?:(?:const|let|var)\s+|(?:async\s+)?function\s+)params\b/.test(w),N=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+revalidate\s*=\s*(\d+)\s*;?/),ee=N?Number(N[1]):void 0,H=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+cache\s*=\s*(\d+)\s*;?/),U=H?Number(H[1]):void 0,te=Kn(w,e),ce=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+prefetch\s*=\s*['"`](\w+)['"`]\s*;?/),Te=ce?ce[1]:void 0;if(Te&&!["off","hover","viewport","all"].includes(Te))throw new T("E-EXPORT",`${e}: export const prefetch must be 'off', 'hover', 'viewport' or 'all'`,{file:e,line:ve(w,ce),hint:"prefetch is the app-global link strategy, declared once in the root _layout.rose: 'off' | 'hover' (default) | 'viewport' | 'all'"});let O=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+lazyHydration\s*=\s*(true|false)\s*;?/),Z=O?O[1]==="true":void 0;if(O&&!Z)throw new T("E-EXPORT",`${e}: export const lazyHydration must be true (or be absent - hydration is eager by default)`,{file:e,line:ve(w,O),hint:"omit the export entirely, or set it to exactly true - lazy hydration is opt-in per app, declared once in the root _layout.rose"});let Y=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+vitals\s*=\s*([^;\n]+)\s*;?/),we=Y?Y[1].trim()==="true":void 0;if(Y&&!we)throw new T("E-EXPORT",`${e}: export const vitals must be true (or be absent - the hook ships only when an app asks for it)`,{file:e,line:ve(w,Y),hint:"omit the export entirely, or set it to exactly true - the web-vitals hook is opt-in per app"});let Ee=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+bundle\s*=\s*['"`](\w+)['"`]\s*;?/),je=Ee?Ee[1]:void 0;if(je&&!["inline","split","sliced"].includes(je))throw new T("E-EXPORT",`${e}: export const bundle must be 'inline', 'split' or 'sliced'`,{file:e,line:ve(w,Ee),hint:"'inline' (default) is the single-document mode; 'split' is mode B for large apps - route-level chunks, loaded on demand; 'sliced' inlines the runtime plus each route's own render chain and shares the rest via a nav chunk"});let Pe=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+csr\s*=\s*(true|false)\s*;?/),Me=Pe?Pe[1]!=="false":void 0,le=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+shell\s*=\s*(true|false)\s*;?/),E=le?le[1]!=="false":void 0,pe=w.match(/(?:^|\n)\s*export\s+(?:const|let|var)\s+buffer\s*=\s*(true|false)\s*;?/),ke=pe?pe[1]!=="false":void 0,z=/\b(?:redirect|notFound)\s*\(/.test(w)||void 0;if(Me===!1){let $=/\son:[a-z]+\s*=/.exec(o)??/\b(?:onMount|onCleanup|refresh)\s*\(/.exec(w);if($){let k=$===(/\son:[a-z]+\s*=/.exec(o)??void 0)?o:w;throw new T("E-EXPORT",`${e}: csr = false cannot ship ${$[0].trim()} - event wiring, onMount/onCleanup and refresh() all need the client bundle. (Forms still work without JS: a native POST runs the server action.)`,{file:e,line:ve(k,$),hint:'drop csr = false (let the compiler decide), or remove the client-only code - a native <form method="POST"> server action works without the bundle'})}}let j,F=es(w,"headers");if(F){let $;try{$=new Function(`return ${F}`)()}catch{throw new T("E-EXPORT",`${e}: export const headers must be an object literal`,{file:e,hint:"write it as one literal: export const headers = { 'x-robots-tag': 'noindex' }"})}if(!$||typeof $!="object"||Array.isArray($)||Object.values($).some(k=>typeof k!="string"))throw new T("E-EXPORT",`${e}: export const headers must be a flat map of string -> string`,{file:e,hint:"every value must be a string literal (a number or an array fails here instead of shipping verbatim)"});j=$}let X,re=es(w,"csp");if(re){let $;try{$=new Function(`return ${re}`)()}catch{throw new T("E-EXPORT",`${e}: export const csp must be an object literal`,{file:e,hint:"write it as one literal: export const csp = { nonce: true }"})}let k=$?.nonce;if(k!==void 0&&typeof k!="boolean")throw new T("E-EXPORT",`${e}: csp.nonce must be a boolean`,{file:e,hint:"csp.nonce is a switch: true (per-request nonce, the route becomes dynamic) or absent (the default hashed policy)"});X=k===!0}let{clean:G,exports:oe,actions:ue,props:V,guard:ie}=Or(x),P=G,de=new Set(ue.map($=>$.name)),se=[];/\son:[a-z]+\s*=/.test(o)&&se.push("event wiring (on:)"),(/<form[^>]*\son:[a-z]+\s*=/i.test(o)||/\$action:|data-on-/.test(o))&&se.push("a form bound to a client dispatch ($action)");let $e=w.match(/\b(?:onMount|onCleanup|refresh|adopt)\s*\(|(?:\$action|\$effect)\s*\(/);$e&&se.push(`${$e[0].replace(/\s*\($/,"")}()`),o.includes("{#defer")&&se.push("{#defer} progressive content"),o.includes("{#await")&&se.push("{#await} async block");let Ie=se.length>0,Se=[];if(!Ie){let $=zn(o),k=zn(w),R=hr(k);/\son[a-z]+\s*=\s*["'][^"']*["']/i.test($)&&Se.push('an inline on* attribute (e.g. onclick="...") - it cannot fire without the bundle; use on:click or set csr = true'),/javascript:/i.test($)&&Se.push("a javascript: URL - it needs the bundle to run; link to a real route"),/\b(?:eval|new Function)\s*\(/.test(R)&&Se.push("eval()/new Function() - client code the predicate cannot see"),/\b(?:document|window|localStorage|sessionStorage)\s*\.|\b(?:add|remove)EventListener\s*\(|\brequestAnimationFrame\s*\(|\bMutationObserver\b|\bnavigator\s*\.|\blocation\s*\.\s*(?:href|assign|replace|reload|pathname|search|hash|origin)\b|\b(?:setTimeout|setInterval)\s*\(/.test(R)&&Se.push("browser-only code (document./window./addEventListener/a timer/...) - a JS-free document never ships this script to the browser, so it throws on the server or runs there and never reaches the client; if the route needs the browser, set csr = true")}let fe=f.match(cs),Re=l.match(on)?.[1]??"",qe=fe?fe[1]:f.replace(ct,"").trim(),Fe=c?Tr(rs(qe,s),n):rs(qe,s),De=Pr(P),Ge=De.filter($=>$.kind==="state"||$.kind==="kv"||$.kind==="persist"),Mt=De.filter($=>$.kind==="derived").map($=>$.name),ht=[...Ge.map($=>$.name),...Mt],Ae=new Map;Ge.forEach($=>Ae.set($.name,`set${He($.name)}`));{let $=Jt(w),k=new Set;for(let R of $.matchAll(/(?:^|\n)\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/g))k.add(R[1]);for(let R of $.matchAll(/(?:^|\n)\s*(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)/g))k.add(R[1]);for(let R of Ge){let W=Ae.get(R.name);if(k.has(W))throw new T("E-SCRIPT",`${e}: the automatic setter "${W}" for $state("${R.name}") collides with a same-named declaration in the script`,{file:e,hint:`rename your function, or drop the auto setter and write $setState("${R.name}", v) - the explicit form never collides`})}}let pt=(()=>{let $=["state","derived","kv","persist"],k=De.map((ne,ge)=>({d:ne,i:ge})).filter(({d:ne})=>$.includes(ne.kind)),R=new Set(k.map(({d:ne})=>ne.name)),W=[],Q=new Set;for(let ne=0;ne<=k.length;ne++){let ge=!1;for(let{d:_e,i:Le}of k){if(Q.has(_e.name))continue;[...new Set([..._e.expr.matchAll(/\b([A-Za-z_$][\w$]*)\b/g)].map(he=>he[1]))].filter(he=>R.has(he)&&he!==_e.name).every(he=>Q.has(he))&&(W.push(Le),Q.add(_e.name),ge=!0)}if(!ge)break}return W})(),Ke=$=>{let k=S?`${n}:${$.name}`:$.name;if($.kind==="state")return`const [${$.name}, ${Ae.get($.name)}] = state(${JSON.stringify(k)}, ${$.expr});`;let W=$.expr.includes("=>")||$.expr.startsWith("function")?$.expr:`() => (${$.expr})`;if($.kind==="persist")return`const [${$.name}, ${Ae.get($.name)}] = persistState(${JSON.stringify(k)}, ${$.expr});`;if($.kind==="derived")return`const ${$.name} = () => (${ze($.expr,ht)});`;if($.kind==="kv"){let Q=/^(.*)\s*,\s*(\d+)\s*$/s.exec($.expr),ne=Q?Q[1]:$.expr,ge=Q?Q[2]:"300";return`const __seeded_${$.name} = isSeeded(${JSON.stringify(k)});
31
+ const [${$.name}, set${He($.name)}] = state(${JSON.stringify(k)}, null);
32
+ if (!__seeded_${$.name}) { const __v_${$.name} = await globalThis.__rosefcKvApi.kvMemo(${JSON.stringify("__kvh:"+n+":"+$.name)}, ${ne}, ${ge}); set${He($.name)}(__v_${$.name}); markSeeded(${JSON.stringify(k)}); }`}return`const __seeded_${$.name} = isSeeded(${JSON.stringify(k)});
33
+ const [${$.name}, set${He($.name)}] = state(${JSON.stringify(k)}, null);
34
+ if (!__seeded_${$.name}) { const __v_${$.name} = await $data(${W}); set${He($.name)}(__v_${$.name}); markSeeded(${JSON.stringify(k)}); }`},gt=[],st="",rt=0;De.forEach(($,k)=>{let R=Mr(P,$.start)===0;if(!R){if($.kind==="derived")throw new Error(`${e}: $derived must be a top-level declaration - inside a function body a plain const arrow already does this natively`);gt.push($)}st+=P.slice(rt,$.start)+(R?`'__rvdecl${k}__';`:""),rt=$.end}),st+=P.slice(rt);let Zt=new Set(Ge.map($=>$.name)),Nt=$=>Zt.has($),mt=Cn(P);if(mt)throw new T("E-STATE",`${e}: ${mt} is a $derived value and is written here - a $derived is read-only`,{hint:`make ${mt} a $state, or derive a different name from it`});let Oe=Yt(st,Nt).replace(Ks,($,k,R)=>{let W=k.trim().replace(/^['"`]|['"`]$/g,"");if(Mt.includes(W))throw new Error(`${e}: $setState('${W}', ...) - a $derived value is read-only; make it $state or derive a different expression`);return`${Ae.get(W)||`set${He(W)}`}(${R})`});if(Oe=ze(Oe,ht),[...Oe.matchAll(/'__rvdecl(\d+)__';/g)].length===pt.length){let k=0;Oe=Oe.replace(/'__rvdecl(\d+)__';/g,(R,W)=>Ke(De[pt[k++]??Number(W)]))}else Oe=Oe.replace(/'__rvdecl(\d+)__';/g,(k,R)=>Ke(De[Number(R)]));let wt=gt.filter($=>$.kind==="state").map(Ke).join(`
35
+ `),It=gt.filter($=>$.kind==="data").map(Ke).join(`
36
+ `),Ft=cn(Yt(Fe,Nt),ht).replace(/<img\b(?![^>]*?\sloading=)/gi,'<img loading="lazy"').replace(/<img\b(?![^>]*?\sdecoding=)/gi,'<img decoding="async"'),Xt=e.replace(/[^\w]/g,"_").replace(/^_+|_+$/g,"").slice(-40),Qe=br(Ft,de,e,Xt),Dt=Qe.inlineCount,We=De.filter($=>$.kind!=="derived").map($=>$.name),Ne=[],Ye=0,Bt=new Set(m.map($=>$.name)),bt=new Set(V.map($=>$.name)),$t=Qe.template.replace(/\sbind:(value|checked|this|open)\s*=\s*\{([\w$]+)(?:\(\))?\}/g,($,k,R,W,Q)=>{let ne=Q.lastIndexOf("<",W),ge=ne>=0?Q.slice(ne,W):"",_e=/^<([a-zA-Z][^\s/>]*)/.exec(ge)?.[1]??"";if(!We.includes(R)&&!bt.has(R))throw new Error(`${e}: bind:${k}={${R}} must name a $state declaration`+(We.length?` (state keys here: ${We.join(", ")})`:" (this file declares no $state)"));if(k==="this")return` data-bind-this="${R}"`;if(!We.includes(R)){let Ce="on"+He(k)+"Change",me=`__rvbind_${n.replace(/\W/g,"_")}_${Ye++}`;return/^<select[\s>]/i.test(ge)&&/\smultiple\b/i.test(ge)?(Ne.push({event:"change",fn:`${me}: (e) => __p.${Ce}?.(Array.from(e.target.selectedOptions, (o) => o.value))`}),` data-selmulti={(__rvlive('value', ${R}) || []).join(',')} data-on-change="${me}"`):k==="checked"?(Ne.push({event:"change",fn:`${me}: (e) => __p.${Ce}?.(e.target.checked)`}),` checked={__rvlive('checked', ${R})} data-on-change="${me}"`):k==="open"?(Ne.push({event:"toggle",fn:`${me}: (e) => __p.${Ce}?.(e.target.open)`}),` open={__rvlive('open', ${R})} data-on-toggle="${me}"`):(Ne.push({event:"input",fn:`${me}: (e) => { const t = e.target; const raw = t.type === 'number' || t.type === 'range' ? t.valueAsNumber : t.value; __p.${Ce}?.(typeof raw === 'number' && Number.isNaN(raw) ? null : raw); }`}),` value={__rvlive('value', ${R})} data-on-input="${me}" data-on-change="${me}"`)}if(_e&&Bt.has(_e)){let Ce=Ae.get(R),me="on"+He(k)+"Change";return` ${k}={${R}()} __live-${k}={${R}} ${me}={${Ce}}`}if(k==="value"&&/^<select[\s>]/i.test(ge)&&/\smultiple\b/i.test(ge)){let Ce=Ae.get(R),me=`__rvbind_${n.replace(/\W/g,"_")}_${Ye++}`;return Ne.push({event:"change",fn:`${me}: (e) => ${Ce}(Array.from(e.target.selectedOptions, (o) => o.value))`}),` data-selmulti={${R}().join(',')} data-on-change="${me}"`}if(k==="open"){let Ce=Ae.get(R),me=`__rvbind_${n.replace(/\W/g,"_")}_${Ye++}`;return Ne.push({event:"toggle",fn:`${me}: (e) => ${Ce}(e.target.open)`}),` open={${R}()} data-on-toggle="${me}"`}let Le=Ae.get(R),Ze=k==="checked"?"change":"input",he=`__rvbind_${n.replace(/\W/g,"_")}_${Ye++}`;Ne.push({event:Ze,fn:k==="checked"?`${he}: (e) => ${Le}(e.target.checked)`:`${he}: (e) => { const t = e.target; const raw = t.type === 'number' || t.type === 'range' ? t.valueAsNumber : t.value; ${Le}(typeof raw === 'number' && Number.isNaN(raw) ? null : raw); }`});let xe=k==="checked"?` data-on-change="${he}"`:` data-on-input="${he}" data-on-change="${he}"`;return` ${k}={${R}()}${xe}`}),yt=new Map(m.map($=>{let k=_.resolve(_.dirname(e),$.specifier),R=i.get(k);return[$.name,{index:R.index,slots:R.slots}]})),_t=[],xt=0,d=!bt.size||!/<(input|textarea|select)[\s>]/i.test($t)?$t:dt($t,$=>{let{tag:k,attrs:R}=$;if(!/^(input|textarea|select)$/i.test(k)||/\sdata-on-input=|\sdata-selmulti=/.test(R))return null;let W=/\svalue\s*=\s*\{([\w$]+)\}/.exec(R);if(!W||!bt.has(W[1]))return null;let Q=W[1],ne=`__rvbind_${n.replace(/\W/g,"_")}_${Ye++}`;Ne.push({event:"input",fn:`${ne}: (e) => { const t = e.target; const raw = t.type === 'number' || t.type === 'range' ? t.valueAsNumber : t.value; __p.onValueChange?.(typeof raw === 'number' && Number.isNaN(raw) ? null : raw); }`});let ge=/^select$/i.test(k)&&/\smultiple\b/i.test(R),_e=R.replace(W[0],` value={__rvlive('value', ${Q})}`),Le=ge?` data-selmulti={(__rvlive('value', ${Q}) || []).join(',')} data-on-change="${ne}"`:` data-on-input="${ne}" data-on-change="${ne}"`;return _e+Le}),b=d.includes("bind:group")?dt(d,$=>{let{tag:k,attrs:R}=$,W=/\sbind:group\s*=\s*\{([\w$]+)(?:\(\))?\}/.exec(R);if(!W)return null;let Q=W[1],ne=!We.includes(Q);if(ne&&!bt.has(Q))throw new T("E-TEMPLATE",`${e}: bind:group={${Q}} must name a $state declaration`,{hint:"the group state holds the selected value (radio) or an ARRAY of checked values (checkbox) - declare it: let "+Q+' = $state("")'});if(!ne&&Bt.has(k)){let Ps=Ae.get(Q);return R.replace(W[0],` group={${Q}()} __live-group={${Q}} onGroupChange={${Ps}}`)}if(!/\stype\s*=\s*["'](radio|checkbox)["']/.test(R))throw new T("E-TEMPLATE",`${e}: bind:group is for radio and checkbox inputs`,{hint:'<input type="radio" value="v" bind:group={state}> holds the selected value; type="checkbox" holds an ARRAY of the checked values (declare the state as $state([]))'});let ge=/\stype\s*=\s*["']checkbox["']/.test(R),_e=/\svalue\s*=\s*"([^"]*)"|\svalue\s*=\s*'([^']*)'/.exec(R);if(!_e||/\{/.test(_e[0]))throw new T("E-TEMPLATE",`${e}: a bind:group input needs a static value attribute`,{hint:'<input type="radio" value="free" bind:group={plan}> - the value IS what the state receives'});if(/\schecked\s*=/.test(R))throw new T("E-TEMPLATE",`${e}: a bind:group input cannot also carry checked=`,{hint:"the group state alone decides which inputs are checked"});let Le=ne?"":Ae.get(Q),Ze=`__rvbg_${n.replace(/\W/g,"_")}_${xt++}`,he=JSON.stringify(_e[1]??_e[2]),xe=ne?`__rvlive('group', ${Q})`:`${Q}()`,Ce=ge?`${xe}.includes(${he})`:`${xe} === ${he}`,me=ge?ne?`__p.onGroupChange?.(e.target.checked ? [...${xe}, ${he}] : ${xe}.filter((x) => x !== ${he}))`:`${Le}(e.target.checked ? [...${Q}(), ${he}] : ${Q}().filter((x) => x !== ${he}))`:ne?"__p.onGroupChange?.(e.target.value)":`${Le}(e.target.value)`;return _t.push({event:"change",fn:`${Ze}: (e) => { ${me}; }`}),R.replace(W[0],` checked={${Ce}} data-on-change="${Ze}"`)}):d,M=Qe.bindings.concat(Ne,_t),B=b.replace(/\suse:([\w-]+)(\s*=\s*\{([\s\S]*?)\})?/g,($,k,R,W)=>R?` data-use="${k}" data-use-param={JSON.stringify(${W})}`:` data-use="${k}"`),q=In(B,"web"),L=qr(q,e),I=Dr(L),K=Hr(I,e),ye=Wr(K,e),be=Jr(ye,e),Je=Ir(be,e),Rs=Ur(Je),Kt=Vr(Rs),Qt=Zr(Kt.template,e),As=zr(Qt.template,e),$n=to(As.replace(Ys,($,k,R)=>{let W=`{__slot(${Jn(k)})}`;if(R){if(/\{[^{}]*\}/.test(R))throw new T("E-TEMPLATE",`${e}: slot fallback content must be static markup`,{hint:"a {expr} inside a slot fallback has no reactive scope here - render the dynamic part in the parent and pass it as the slot content"});return`{__slot(${Jn(k)}, ${JSON.stringify(R)})}`}return W}).replace(Qs,($,k)=>k&&k.trim()?`{__slotDefault(${JSON.stringify(k)})}`:"{__slot__}"),yt);eo($n,e);let yn=new Set;{let $=Jt(w),k=new Set(Ge.map(W=>W.name)),R=W=>/^(?:async\s*)?(?:function\b|\([^)]*\)\s*=>)/.test(W)||/^(?:async\s*)?\(/.test(W)&&W.includes("=>")||/^(?:async\s+)?[A-Za-z_$][\w$]*\s*=>/.test(W);for(let W of $.matchAll(/(?:^|\n)\s*(?:export\s+)?(?:const|let)\s+([A-Za-z_$][\w$]*)\s*=\s*([^;]{0,200})/g))k.has(W[1])||/^\s*\$state\b/.test(W[2])||R(W[2].trim())||yn.add(W[1])}ln=0,Ct=e,Ht=new Set,un=!0,hn=new Set(yn);let _n=Be($n,"h","__c",null,0,!0,yt);un=!1,hn=new Set;let xn=dn,Cs=fn;dn="",fn={},Ht=new Set;let vn=pn;if(pn=null,vn)throw new T("E-TEMPLATE",`${e}: {@const ${vn}} is declared twice at the top level`,{file:e,hint:"a const cannot be redeclared in the same scope - rename one of them, or wrap the second in a block ({#if}/{#each}) where it shadows the first instead of colliding with it"});for(let $ of M)/^\w+$/.test($.fn)||($.fn=ze($.fn,[],Cs));let vt=Re.trim()?Kr(Re):"";if(!S&&c){let k=`<style id="${"rosefc-style-"+n.replace(/[^a-zA-Z0-9_-]/g,"-")}">${c}</style>`;vt=(vt?vt+`
37
+ `:"")+`__hd += ${JSON.stringify(k)};`}let kn=/<slot\s+[^>]*\bname\s*=/.test(Fe),En=ue.length>0?`${oe}
38
+ ${ue.map($=>$.stmt).join(`
39
+ `)}`:oe,Sn=ie?`
40
+ ${ie}`:"",Ts=_.basename(e)==="_middleware.rose",Rn=Gr(Kt.count,Kt.holds)+(Qt.blocks.length?`
41
+ `+Xr(Qt.blocks):""),Os=Ts?`${Pt}
42
+
43
+ ${v}
44
+
45
+ ${En}
46
+ ${Sn}
47
+
48
+ ${Oe}
49
+ `:yo(Oe+Rn,_n,wt,En,vt,V,kn,v,S,Sn,ue.length>0,It,xn,Dt>0),js=_o(Oe+Rn,_n,wt,M,oe,vt,V,kn,v,S,It,xn,Dt>0);return{ssr:sn(Os,"ssr"),client:sn(js,"client"),stateKeys:We,actionNames:[...de],guardName:ie?"beforeAction":null,style:c,hasParams:J,usesContext:A,usesStore:D,revalidate:ee,cache:U,hotVary:te,csr:Me,shell:E,buffer:ke,controlSignal:z,prefetch:Te,lazyHydration:Z,vitals:we,bundle:je,needsClient:Ie,clientReasons:se,jsWarnings:Se,headers:j,cspNonce:X,usesRosefcAuth:y,props:V,roseImports:m,isComponent:S}}function bs(e){return e.replace(/(-?\d*\.?\d+)rpx/g,(s,n)=>{let t=Number(n)/2;return t===0?"0":`${Math.round(t*100)/100}px`})}function Qn(e){return e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|[^"']+/g,s=>s[0]==='"'||s[0]==="'"?s:s.replace(/\s+/g," ").replace(/\s*([:;{},])\s*/g,"$1").trim()).trim()}function $s(e,s){let n=`[data-rosefc-c="${s}"]`,t=a=>{let u=a.trim();if(!u.includes(":global"))return`${n} ${u}, ${n}${u}`;let g=u.replace(/:global\([^()]*\)/g,f=>f.slice(8,-1)).trim();return u.replace(/:global\([^()]*\)/g,"").trim()?`${n} ${g}, ${n}${g}`:g},r=bs(e.replace(/\/\*[\s\S]*?\*\//g,"")),i="",o="",l=0;for(;l<r.length;){let a=r[l];if(a==="{"){let u=1,g=l+1;for(;g<r.length&&u>0;)r[g]==="{"?u++:r[g]==="}"&&u--,g++;let c=r.slice(l+1,g-1),f=o.trim();if(f.startsWith("@"))i+=`${f}{${/^@(?:-[\w]+-)?keyframes/.test(f)?Qn(c):$s(c,s)}}`;else if(f){let h=f.split(",").map(p=>t(p)).join(",");i+=`${h}{${Qn(c)}}`}o="",l=g;continue}a!=="}"&&a!==`
50
+ `&&a!=="\r"?o+=a:a==="}"&&(o=""),l++}return i.trim()}function Tr(e,s){let n=` data-rosefc-c="${s}"`,t="",r=0,i=0;for(;i<e.length;){let o=e.indexOf("<",i);if(o===-1){t+=e.slice(i);break}t+=e.slice(i,o);let l=o+1,a="",u=0,g=0;for(;l<e.length;){let w=e[l];if(a)w===a&&(a="");else if(w==='"'||w==="'")a=w;else if(w==="(")u++;else if(w===")")u=Math.max(0,u-1);else if(w==="{")g++;else if(w==="}")g=Math.max(0,g-1);else if(w===">"&&u===0&&g===0)break;l++}let c=e.slice(o,l+1),f=/^<\//.test(c),h=c.match(/^<\/?([a-zA-Z][\w-]*)/),p=/\/>$/.test(c)||h&&ys.has(h[1].toLowerCase());if(h&&!f&&r===0&&!p){let w=c.endsWith("/>")?c.length-2:c.length-1;t+=c.slice(0,w)+n+c.slice(w),r++}else t+=c,h&&(r+=f?-1:p?0:1);i=l+1}return t}var ys=new Set(["img","br","hr","input","meta","link","source","wbr"]),Yn=/^[ \t]*export\s+(?:(const|let|var)|(?:async\s+)?function)\s+(\w+)/gm;function es(e,s){let n=new RegExp(`(?:^|\\n)\\s*export\\s+(?:const|let|var)\\s+${s}\\s*=\\s*`).exec(e);if(!n)return null;let t=n.index+n[0].length;if(e[t]!=="{")return null;let r=t,i=0;for(;t<e.length;t++){let o=e[t];if(o==="{")i++;else if(o==="}"&&(i--,i===0)){t++;break}}return e.slice(r,t)}function Or(e){let s=[],n=[],t=[],r=[],i="",o=0,l;for(Yn.lastIndex=0;l=Yn.exec(e);){let a=l[1],u=l.index+l[0].indexOf("export"),g=u+l[0].length-l[0].indexOf("export");if(a){let p=0;for(;g<e.length;){let w=e[g];if(w==="("||w==="{"||w==="[")p++;else if(w===")"||w==="}"||w==="]"){if(p--,p===0){g++;break}}else if(p===0&&w===";"){g++;break}else if(p===0&&w===`
51
+ `){let y=e.slice(g+1);if(!/^\s*[.([{+\-*/?:,=&|]/.test(y)){g++;break}}g++}e[g]===";"&&g++}else{for(;g<e.length&&e[g]!=="{";)g++;let p=0;for(;g<e.length;){let w=e[g];if(w==="{")p++;else if(w==="}"&&(p--,p===0)){g++;break}g++}}i+=e.slice(o,u);let c=e.slice(u,g).trim(),f=c.match(/^export\s+async\s+function\s+(\w+)/);if(c.match(/^export\s+(?:async\s+)?function\s+(\w+)/)?.[1]==="beforeAction")r.push(c);else if(f)n.push({name:f[1],stmt:c});else if(a==="let"){let p=c.match(/^export\s+let\s+(\w+)\s*(?:=\s*([\s\S]*?))?\s*;?$/);p?t.push({name:p[1],def:p[2]?.trim()??null}):s.push(c)}else s.push(c);o=g}return i+=e.slice(o),{clean:i,exports:s.join(`
52
+ `),actions:n,props:t,guard:r.join(`
53
+ `)}}var jr=new Set("(,=:[!&|?{};+-*%<>~^".split(""));function _s(e,s){let n=s-1;for(;n>=0&&/\s/.test(e[n]);)n--;if(n<0)return!0;let t=e[n];if(jr.has(t))return!0;if(/[A-Za-z0-9_$]/.test(t)){let r=hs(e,n);return r?["return","typeof","instanceof","in","of","new","delete","void","throw","case","do","else"].includes(r):!1}return!1}function Pr(e){let s=[],n=Jt(e);Wn.lastIndex=0;let t;for(;t=Wn.exec(n);){let r=t.index+t[0].length,i=()=>{for(;r<e.length&&/\s/.test(e[r]);)r++};if(i(),e[r]==="<"){let c=0;for(;r<e.length;){let f=e[r];if(f==="<")c++;else if(f===">"&&e[r-1]!=="="){if(c--,c===0){r++;break}}else f==="="&&e[r+1]===">"&&r++;r++}i()}if(e[r]!=="(")continue;let o=r+1,l=1,a=o;for(;a<e.length&&l>0;){let c=e[a];c==="("?l++:c===")"&&l--,a++}let u=a,g=Xs.exec(e.slice(a));g&&(u=a+g[0].length),e[u]===";"&&u++,s.push({name:t[1],kind:t[2],expr:e.slice(o,a-1).trim(),start:t.index,end:u})}return s}function Mr(e,s){let n=0,t=0;for(;t<s;){let r=e[t];if(r==="'"||r==='"'||r==="`"){let i=r;for(t++;t<s;){if(e[t]==="\\"){t+=2;continue}if(e[t]===i){t++;break}if(i==="`"&&e[t]==="$"&&e[t+1]==="{"){let o=1;for(t+=2;t<s&&o>0;)e[t]==="{"?o++:e[t]==="}"&&o--,t++;continue}t++}continue}if(r==="/"&&e[t+1]==="/"){let i=e.indexOf(`
54
+ `,t);t=i===-1?e.length:i;continue}if(r==="/"&&e[t+1]==="*"){let i=e.indexOf("*/",t+2);t=i===-1?e.length:i+2;continue}if(r==="/"&&_s(e,t)){t++;let i=!1;for(;t<s;){let o=e[t];if(o==="\\"){t+=2;continue}if(i){o==="]"&&(i=!1),t++;continue}if(o==="["){i=!0,t++;continue}if(o==="/"){t++;break}if(o===`
55
+ `)break;t++}for(;t<s&&/[a-z]/.test(e[t]);)t++;continue}r==="{"?n++:r==="}"&&n--,t++}return n}function Jt(e){let s="",n=0,t=(r,i)=>{for(let o=r;o<i&&o<e.length;o++)s+=e[o]===`
56
+ `?`
57
+ `:" "};for(;n<e.length;){let r=e[n];if(r==="'"||r==='"'||r==="`"){let i=r,o=n+1;for(;o<e.length;){if(e[o]==="\\"){o+=2;continue}if(e[o]===i){o++;break}if(i==="`"&&e[o]==="$"&&e[o+1]==="{"){let l=jt(e,o+1);o=l<0?e.length:l+1;continue}o++}t(n,Math.min(o,e.length)),n=o;continue}if(r==="/"&&e[n+1]==="/"){let i=e.indexOf(`
58
+ `,n),o=i===-1?e.length:i;t(n,o),n=o;continue}if(r==="/"&&e[n+1]==="*"){let i=e.indexOf("*/",n+2),o=i===-1?e.length:i+2;t(n,o),n=o;continue}if(r==="/"&&_s(e,n)){let i=n+1,o=!1;for(;i<e.length;){let l=e[i];if(l==="\\"){i+=2;continue}if(o){l==="]"&&(o=!1),i++;continue}if(l==="[")o=!0;else if(l==="/"){i++;break}else if(l===`
59
+ `)break;i++}for(;i<e.length&&/[a-z]/.test(e[i]);)i++;t(n,i),n=i;continue}s+=r,n++}return s}var Nr=new Set(["true","false","null","undefined","NaN","Infinity"]);function ts(e){let s=e.trim();return/^[A-Za-z_$][\w$]*$/.test(s)&&hn.has(s)?s:/^[A-Za-z_$][\w$]*$/.test(s)&&s!=="__s"&&!Nr.has(s)?`${s}()`:s}var Lr=!0;function Ir(e,s){if(!e.includes("{#key"))return e;for(let n=0;n<10;n++){let t=/\{#key\b/g;t.lastIndex=0;let r=t.exec(e);if(!r)return e;let i=Ue(e,r.index);if(i<0)return e;let o=e.slice(r.index+5,i-1).trim();if(!o)return e;let l=i,a=/\{[#\/](?:key|if|each|boundary|island)\b/g;a.lastIndex=l;let u=1,g=-1,c;for(;c=a.exec(e);){if(c[0].startsWith("{#")){let f=Ue(e,c.index);f>=0&&(a.lastIndex=f),u++;continue}if(u--,u===0){g=c.index;break}}if(g<0)throw new T("E-TEMPLATE",`${s}: {#key ${o}} is never closed`,{hint:"every {#key} needs its {/key}"});e=e.slice(0,r.index)+`{#each [${o}] as __rvkv}`+e.slice(l,g)+"{/each}"+e.slice(g+6)}return e}function Fr(e){let s=/\{#(?:if|each|boundary|island)\b|\{\/(?:if|each|boundary|island)\s*\}|\{:else(?:\s+if\s+[^}]*)?\}/g,n="",t=0,r=!1;for(;;){let i=e.slice(t),l=/\{#(if|each)\b/g.exec(i);if(!l){n+=e.slice(t);break}let a=l[1],u=Ue(i,l.index);if(u<0){n+=e.slice(t);break}let g=i.slice(l.index+2+a.length,u-1),c=t+l.index,f=t+u,h=wn(a,g);if(!h){n+=e.slice(t,f),t=f;continue}let p=a==="if"?h[0].trim():"";n+=e.slice(t,c),s.lastIndex=f;let w=1,y=-1,m=0,v=[],x;for(;x=s.exec(e);){let H=x[0];if(H.startsWith("{:else")){if(w===1){let U=/^\{:else\s+if\s+([^}]*)\}$/.exec(H);v.push({at:x.index,len:H.length,cond:U?U[1].trim():null})}continue}if(H.startsWith("{#")){let U=Ue(e,x.index);U>=0&&(s.lastIndex=U),w++;continue}if(w--,w===0){y=x.index,m=H.length;break}}if(y<0){n+=e.slice(c);break}if(v.length===0){n+=e.slice(c,f),t=f,r=!0;continue}let S=e.slice(f,y);if(a==="each"){let H=[...v].reverse().find(O=>O.cond===null);if(!H){n+=e.slice(c,y+m),t=y+m;continue}let U=H.at-f,te=S.slice(0,U),ce=S.slice(U+H.len),Te=h[0];n+=e.slice(c,f)+te+`{/each}{#if !(${Te}.length)}${ce}{/if}`,t=y+m,r=!0;continue}let A=[],D=0;for(let H=0;H<v.length;H++){let U=v[H],te=U.at-f;A.push({cond:H===0?null:v[H-1].cond,body:S.slice(D,te)}),D=te+U.len}A.push({cond:v[v.length-1].cond,body:S.slice(D)});let J=A.shift(),N=H=>{if(!H.length)return"";let U=H[0],te=H.slice(1);if(U.cond==null)return U.body;let ce=`{#if ${U.cond}}${U.body}{/if}`;return te.length&&(ce+=`{#if !(${U.cond})}`+N(te)+"{/if}"),ce},ee=`{#if ${p}}${J.body}{/if}`;A.length&&(ee+=`{#if !(${p})}`+N(A)+"{/if}"),n+=ee,t=y+m,r=!0}return{template:n,changed:r}}function Dr(e){if(!/\sclass\s*=\s*"/.test(e)||!/\sclass\s*=\s*\{/.test(e))return e;let s=/<([a-zA-Z][^\s>/]*)((?:[^>"']|"[^"]*"|'[^']*')*?)(\/?)>/g,n="",t=0,r;for(s.lastIndex=0;r=s.exec(e);){let[i,o,l,a]=r,u=/\sclass\s*=\s*"([^"]*)"/.exec(l);if(!u)continue;let g=/\sclass\s*=\s*\{/.exec(l);if(!g||g.index===u.index)continue;let c=l.indexOf("{",g.index),f=1,h=c+1;for(;h<l.length&&f>0;){let S=l[h];if(S==='"'||S==="'"){h=Ve(l,h);continue}S==="{"?f++:S==="}"&&f--,h++}if(f!==0)continue;let p=l.slice(c+1,h-1),w=JSON.stringify(u[1]),y=` class={((v) => v == null ? ${w} : typeof v === 'object' ? ({ ${w}: true, ...v }) : (${w} + ' ' + v))(${p})}`,m=Math.min(u.index,g.index),v=Math.max(u.index+u[0].length,h),x=l.slice(0,m)+y+l.slice(v);n+=e.slice(t,r.index)+`<${o}${x}${a}>`,t=r.index+i.length}return n+=e.slice(t),n}function Br(e,s){let n=/^<([a-zA-Z][^\s>/]*)/.exec(e.slice(s));if(!n)return null;let t=s+n[0].length,r="",i=0;for(;t<e.length;){let o=e[t];if(r)o===r&&(r="");else if(o==='"'||o==="'")r=o;else if(o==="{")i++;else if(o==="}")i=Math.max(0,i-1);else if(o===">"&&i===0){let a=e.slice(s,t+1).endsWith("/>")?"/":"",u=a?t-1:t;return{start:s,end:t+1,tag:n[1],attrs:e.slice(s+n[0].length,u),selfClose:a}}t++}return null}function dt(e,s){let n="",t=0,r=0;for(;r<e.length;){let i=e.indexOf("<",r);if(i<0)break;let o=Br(e,i);if(!o){r=i+1;continue}let l=s(o);n+=e.slice(t,o.start)+(l===null?e.slice(o.start,o.end):`<${o.tag}${l}${o.selfClose}>`),t=o.end,r=o.end}return n+=e.slice(t),n}function qr(e,s){return e.includes("class:")?dt(e,n=>{let t=n.attrs;if(!t.includes("class:"))return null;let r=[],i=/\sclass:([\w-]+)\s*=\s*\{/g,o;for(;o=i.exec(t);){let f=o.index+o[0].length,h=1;for(;f<t.length&&h>0;){let p=t[f];if(p==='"'||p==="'"){f=Ve(t,f);continue}p==="{"?h++:p==="}"&&h--,f++}if(h!==0)throw new T("E-TEMPLATE",`${s}: class:${o[1]}={...} is missing its closing brace`,{file:s,hint:"the binding expression needs a matching } before the tag ends"});r.push({name:o[1],expr:t.slice(o.index+o[0].length,f-1),start:o.index,end:f})}let l=/(\sclass\s*=\s*)("([^"]*)"|'([^']*)'|\{[^}]*\})/,a=l.exec(t);if(a&&a[2].startsWith("{"))throw new T("E-TEMPLATE",`${s}: <${n.tag}> has both class={...} and class: directives`,{file:s,hint:'merge them: move the dynamic part into a class:NAME={expr} and keep the rest in class="..."'});let u=a?a[3]??a[4]??"":"",g=`(${JSON.stringify(u)}`;for(let f of r)g+=`+((${f.expr})?${JSON.stringify(" "+f.name)}:'')`;g+=")";let c=t;for(let f=r.length-1;f>=0;f--)c=c.slice(0,r[f].start)+c.slice(r[f].end);return a?c=c.replace(l,` class={${g}}`):c=` class={${g}}`+c,c}):e}function Wr(e,s){return/\s(?:transition|in|out):/.test(e)?dt(e,n=>{let t=n.attrs;if(!t.includes("transition:")&&!/\s(?:in|out):/.test(t))return null;let r=[],i=/\s(transition|in|out):([\w-]+)(?:\s*=\s*\{)?/g,o;for(;o=i.exec(t);){let c=o.index,f=o.index+o[0].length,h="";if(o[0].endsWith("{")){let p=1,w=f;for(;w<t.length&&p>0;){let y=t[w];if(y==='"'||y==="'"){w=Ve(t,w);continue}y==="{"?p++:y==="}"&&p--,w++}if(p!==0)throw new T("E-TEMPLATE",`${s}: transition:${o[1]}={...} is missing its closing brace`,{file:s,hint:"the transition params expression needs a matching } before the tag ends"});h=t.slice(f,w-1),f=w}r.push({dir:o[1]==="transition"?"":o[1],name:o[2],params:h,start:c,end:f})}if(r.length===0)return null;let l="";for(let c of r)l&&(l+="|"),l+=(c.dir?c.dir+":":"")+c.name+(c.params?":"+c.params:"");let a=t;for(let c=r.length-1;c>=0;c--)a=a.slice(0,r[c].start)+a.slice(r[c].end);let u=/\sdata-transition\s*=\s*("([^"]*)"|'([^']*)'|\{[^}]*\})/,g=u.exec(a);if(g){let c=g[2]??g[3]??"";a=a.replace(u,` data-transition="${c}${l?(c?"|":"")+l:""}"`)}else a=` data-transition="${l}"`+a;return a}):e}function Jr(e,s){return e.includes("animate:")?dt(e,n=>{let t=n.attrs;if(!t.includes("animate:"))return null;let r=[],i=/\sanimate:([\w-]+)(?:\s*=\s*\{)?/g,o;for(;o=i.exec(t);){let c=o.index,f=o.index+o[0].length,h="";if(o[0].endsWith("{")){let p=1,w=f;for(;w<t.length&&p>0;){let y=t[w];if(y==='"'||y==="'"){w=Ve(t,w);continue}y==="{"?p++:y==="}"&&p--,w++}if(p!==0)throw new T("E-TEMPLATE",`${s}: animate:${o[1]}={...} is missing its closing brace`,{file:s,hint:"the animate params expression needs a matching } before the tag ends"});h=t.slice(f,w-1),f=w}r.push({name:o[1],params:h,start:c,end:f})}let l="";for(let c of r)l&&(l+="|"),l+=c.name+(c.params?":"+c.params:"");let a=t;for(let c=r.length-1;c>=0;c--)a=a.slice(0,r[c].start)+a.slice(r[c].end);let u=/\sdata-animate\s*=\s*("([^"]*)"|'([^']*)'|\{[^}]*\})/,g=u.exec(a);if(g){let c=g[2]??g[3]??"";a=a.replace(u,` data-animate="${c}${l?(c?"|":"")+l:""}"`)}else a=` data-animate="${l}"`+a;return a}):e}function Hr(e,s){return e.includes("style:")?dt(e,n=>{let t=n.attrs;if(!t.includes("style:"))return null;let r=[],i=/\sstyle:([\w-]+)\s*=\s*\{/g,o;for(;o=i.exec(t);){let f=o.index+o[0].length,h=1;for(;f<t.length&&h>0;){let p=t[f];if(p==='"'||p==="'"){f=Ve(t,f);continue}p==="{"?h++:p==="}"&&h--,f++}if(h!==0)throw new T("E-TEMPLATE",`${s}: style:${o[1]}={...} is missing its closing brace`,{file:s,hint:"the binding expression needs a matching } before the tag ends"});r.push({prop:o[1],expr:t.slice(o.index+o[0].length,f-1),start:o.index,end:f})}let l=/(\sstyle\s*=\s*)("([^"]*)"|'([^']*)'|\{[^}]*\})/,a=l.exec(t);if(a&&a[2].startsWith("{"))throw new T("E-TEMPLATE",`${s}: <${n.tag}> has both style={...} and style: directives`,{file:s,hint:'keep the static declarations in style="..." and move the dynamic ones to style:PROP={expr}'});let u=a?a[3]??a[4]??"":"",g=`${JSON.stringify(u.endsWith(";")||u===""?u:u+";")}`;for(let f of r)g+=`+${JSON.stringify(f.prop+":")}+(${f.expr})+';'`;let c=t;for(let f=r.length-1;f>=0;f--)c=c.slice(0,r[f].start)+c.slice(r[f].end);return a?c=c.replace(l,` style={${g}}`):c=` style={${g}}`+c,c}):e}function zr(e,s){if(!e.includes("{:fallback"))return e;for(let n=0;n<10;n++){let t=/\{#boundary\}|\{\/boundary\}|\{:fallback\}/g,r="",i=0,o=!1,l;for(;l=t.exec(e);){if(l[0]!=="{#boundary}")continue;let a=l.index,u=a+l[0].length,g=1,c=-1,f;for(;f=t.exec(e);){if(f[0]==="{#boundary}"){g++;continue}if(f[0]==="{/boundary}"&&(g--,g===0)){c=f.index;break}}if(c<0)break;let h=e.slice(u,c),p=/\{#(boundary|if|each|key|island)(?:\s+[^}]*)?\}|\{\/(?:boundary|if|each|key|island)\s*\}|\{:fallback\}/g,w=["boundary"],y=1,m=-1,v=0,x;for(p.lastIndex=0;x=p.exec(h);){let J=x[0];if(J==="{:fallback}"){if(w[w.length-1]!=="boundary")throw new T("E-TEMPLATE",`${s}: {:fallback} must sit directly inside a {#boundary} block`,{hint:"move it out of the {#if}/{#each} it sits in, or keep the conditional fallback in the parent"});if(m>=0)throw new T("E-TEMPLATE",`${s}: a {#boundary} can carry only one {:fallback}`,{hint:"remove the extra {:fallback} segment"});m=x.index,v=J.length;continue}if(J.startsWith("{#")){y++,w.push(J.slice(2,J.length-1).trim().split(/\s/)[0]);continue}y--,w.pop()}if(m<0)continue;let S=h.slice(0,m),A=h.slice(m+v),D=Buffer.from(A,"utf-8").toString("base64");r+=e.slice(i,a)+`{#boundary __fb="${D}"}`+S+"{/boundary}",i=c+11,o=!0}if(!o)break;e=r+e.slice(i)}return e}function Ur(e){for(let s=0;s<40;s++){if(!/\{:else\b/.test(e))return e;let n=Fr(e);if(e=n.template,!n.changed)return e}return e}function Vr(e){if(!Lr){let o=/\{#defer(?:\s+hold=\\d+)?\}/g,l="",a=0;for(;;){o.lastIndex=a;let u=o.exec(e);if(!u)break;let g=u.index,c=u[0].length,f=e.indexOf("{/defer}",g+c);if(f<0)break;l+=e.slice(a,g)+e.slice(g+c,f),a=f+8}return{template:a===0?e:l,count:0,holds:[]}}let s=0,n=[],t="",r=0,i=/\{#defer(?:\s+hold=(\d+))?\}/g;for(;;){i.lastIndex=r;let o=i.exec(e);if(!o)break;let l=o.index,a=o[0].length,u=o[1]?Number(o[1]):0,g=1,c=l+a,f=-1;for(;c<e.length;){i.lastIndex=c;let w=i.exec(e),y=w?w.index:-1,m=e.indexOf("{/defer}",c);if(m<0)break;if(y>=0&&y<m){g++,c=y+w[0].length;continue}if(g--,g===0){f=m;break}c=m+8}if(f<0)break;let h=e.slice(l+a,f);n.push(u);let p=++s;t+=e.slice(r,l),t+="{#if __rvDefer"+p+"()}"+h+`{/if}
60
+ {#if !__rvDefer`+p+'()}<div class="rv-defer-loading"></div>{/if}',r=f+8}return s===0?{template:e,count:0,holds:[]}:(t+=e.slice(r),{template:t,count:s,holds:n})}function Gr(e,s=[]){let n="";for(let t=1;t<=e;t++){n+="const [__rvDefer"+t+", set__rvDefer"+t+'] = state("__rvdefer'+t+`", false);
61
+ `;let r=s[t-1]||0;n+=r>0?"onMount(function () { setTimeout(function () { set__rvDefer"+t+"(true); }, "+r+`); });
62
+ `:"onMount(function () { requestAnimationFrame(function () { requestAnimationFrame(function () { set__rvDefer"+t+`(true); }); }); });
63
+ `}return n}function Zr(e,s){let n="",t=0,r=0,i=[];for(;;){let o=e.indexOf("{#await",t);if(o<0)break;let l=o+7,a=1;for(;l<e.length&&a>0;){let we=e[l];we==="{"?a++:we==="}"&&a--,l++}if(a!==0)break;let u=l-o,g=e.slice(o+7,l-1).trim();if(!g)throw new T("E-TEMPLATE",`${s}: {#await} needs a promise expression`,{file:s,hint:"write {#await fetchUsers()}...{:then users}...{/await}"});let c=/\b(then|catch)\s+[A-Za-z_$][\w$]*\s*$/.exec(g);if(c)throw new T("E-TEMPLATE",`${s}: {#await ${g}} puts the ${c[1]} branch in the opener`,{file:s,hint:`write the branch on its own line inside the block:
64
+ {#await ${g.replace(/\s+(then|catch)\s+[A-Za-z_$][\w$]*\s*$/,"")}}
65
+ \u95B3\u30EE\u6D0Aending\u95B3\u30EE\u6CDCn{:${c[1]} ${c[0].trim().split(/\s+/)[1]}}
66
+ \u95B3?{inlineBranch[1] === 'then' ? 'fulfilled' : 'rejected'}\u95B3\u30EE\u6CDCn{/await}`});let f=/\{\#(if|each|boundary|island|await)\b/g,h=/\{\/(if|each|boundary|island|await)\}/g,p=/\{:then\b([^}]*)\}/g,w=/\{:catch\b([^}]*)\}/g,y=1,m=l,v=-1,x=-1,S=-1,A="",D="";for(;;){f.lastIndex=m,h.lastIndex=m,p.lastIndex=m,w.lastIndex=m;let we=f.exec(e),Ee=h.exec(e),je=p.exec(e),Pe=w.exec(e),Me=1/0,le="",E=null,pe=(ke,z)=>{ke&&ke.index<Me&&(Me=ke.index,le=z,E=ke)};if(pe(we,"open"),pe(Ee,"close"),pe(je,"then"),pe(Pe,"catch"),!E)break;if(le==="open"){y++,m=E.index+E[0].length;continue}if(le==="close"){if(y===1&&E[1]==="await"){S=E.index;break}y--,m=E.index+E[0].length;continue}y===1&&(le==="then"&&v<0?(v=E.index,A=E[1]):le==="catch"&&x<0&&(x=E.index,D=E[1])),m=E.index+E[0].length}if(S<0||v<0)break;let J=v+7+A.length,N=x>=0?x+8+D.length:-1,ee=e.slice(l,v),H=e.slice(J,x>=0?x:S),U=x>=0?e.slice(N,S):"",te=A.trim(),ce=D.trim(),Te=/^\w+$/.test(te)?te:`__rvAwaitThen${r+1}`,O=x>=0?/^\w+$/.test(ce)?ce:`__rvAwaitCatch${r+1}`:"";r++;let Z=r,Y=`__rvAwait${Z}`;i.push({n:Z,expr:g,thenVar:Te,catchVar:O}),n+=e.slice(t,o),n+=`{#if ${Y}().status === 'pending'}`+ee+`{/if}
67
+ `,n+=`{#each (${Y}().status === 'resolved' ? [${Y}().value] : []) as ${Te}}`+H+`{/each}
68
+ `,x>=0&&(n+=`{#each (${Y}().status === 'rejected' ? [${Y}().error] : []) as ${O}}`+U+`{/each}
69
+ `),t=S+8}return r===0?{template:e,blocks:i}:(n+=e.slice(t),{template:n,blocks:i})}function Xr(e){let s="";for(let n of e){let t=`__rvAwait${n.n}`;s+=`const [${t}, set${t}] = state("__rvawait${n.n}", { status: 'pending', value: null, error: null });
70
+ `,s+=`onMount(function () {
71
+ `,s+=` Promise.resolve(${n.expr}).then(function (__rvAwaitVal) {
72
+ `,s+=` set${t}({ status: 'resolved', value: __rvAwaitVal });
73
+ `,s+=` }).catch(function (__rvAwaitErr) {
74
+ `,s+=` set${t}({ status: 'rejected', error: __rvAwaitErr });
75
+ `,s+=` });
76
+ `,s+=`});
77
+ `}return s}function wn(e,s){if(e==="if"){let t=/^\s*([\s\S]+?)\s*$/.exec(s);return t?[t[1]]:null}if(e==="each"){let t=/^\s*([\s\S]+?)\s+as\s+(\{[^{}]*\}|\[[^[\]]*\]|\w+)(?:\s*,\s*(\w+))?(?:\s*\(([\s\S]+)\))?\s*$/.exec(s);return t?[t[1],t[2],t[3]??"",t[4]??""]:null}if(e==="boundary")return[s];if(e==="island"){let t=/^\s*(?:name="([^"]*)")?(?:\s*hydrate="([^"]*)")?\s*$/.exec(s);return t?[t[1]??"",t[2]??""]:null}let n=/^\s*(\w+)(?:\s*\(([\s\S]+)\))?\s*$/.exec(s);return n?[n[1],n[2]??""]:null}function at(e,s,n){let t=new RegExp(`\\{#${s}\\b`,"g"),r=new RegExp(`\\{/${s}\\}`,"g");t.lastIndex=n;let i;for(;i=t.exec(e);){let o=i.index,l=Ue(e,o);if(l<0)continue;let a=wn(s,e.slice(o+2+s.length,l-1));if(!a)continue;let u=1,g=l;for(;;){t.lastIndex=g,r.lastIndex=g;let c=t.exec(e),f=r.exec(e);if(!f)break;if(c&&c.index<f.index){let h=Ue(e,c.index);u++,g=h<0?c.index+c[0].length:h;continue}if(g=f.index+f[0].length,--u===0){let h=e.slice(l,f.index),p=[e.slice(o,g),...a,h];return p.index=o,p}}t.lastIndex=l}return null}function Kr(e){let s=/<(style|script|noscript)\b[^>]*>/iy,n="",t="",r=0,i=0,o=()=>{t.trim()&&(n+=Be(t,"__hd","__hc",null,r++,!1)),t=""};for(;i<e.length;){if(e.startsWith("<!--",i)){let a=e.indexOf("-->",i+4);i=a<0?e.length:a+3;continue}s.lastIndex=i;let l=s.exec(e);if(l){let a=l[1].toLowerCase(),u=e.toLowerCase().indexOf(`</${a}`,i+l[0].length),g=u<0?-1:e.indexOf(">",u),c=g<0?e.length:g+1;o(),n+=vs(l[0],"__hd","__hc",null),n+=ao(e.slice(i+l[0].length,c),"__hd","__hc",null),i=c;continue}t+=e[i++]}return o(),n}var Qr=new Set(["if","each","boundary","island","await","snippet"]),ns=new Map;function Yr(e){let s=ns.get(e);return s||(s={open:new RegExp(`\\{#${e}\\b`,"g"),close:new RegExp(`\\{/${e}\\}`,"g")},ns.set(e,s)),s}function eo(e,s){let n=[],t=/<(style|script|noscript)\b[^>]*>/gi,r;for(;r=t.exec(e);){let c=r[1].toLowerCase(),f=e.toLowerCase().indexOf(`</${c}`,r.index+r[0].length),h=f<0?-1:e.indexOf(">",f),p=h<0?e.length:h+1;n.push([r.index,p]),t.lastIndex=p}let i=/<!--[\s\S]*?-->/g,o;for(;o=i.exec(e);)n.push([o.index,o.index+o[0].length]);n.sort((c,f)=>c[0]-f[0]);let l=c=>n.some(([f,h])=>c>=f&&c<h),a=/\{([:/])(\w+)\}/g,u;for(;u=a.exec(e);){if(l(u.index))continue;let[,c,f]=u;if(!(c==="/"&&Qr.has(f))){if(c==="/")throw new T("E-TEMPLATE",`${s}: {/${f}} does not close anything`,{file:s,line:ve(e,u),hint:"the closers are {/if}, {/each} and {/boundary} - one per block you opened"});if(f==="else"){let h=(y,m,v)=>{let x=0,S;for(y.lastIndex=0;(S=y.exec(e))&&!(S.index>=v);)l(S.index)||x++;let A=new RegExp(m,"g"),D=0;for(;(S=A.exec(e))&&!(S.index>=v);)l(S.index)||D++;return x-D},p=h(/\{#if\b/g,"\\{/if\\b",u.index),w=h(/\{#each\b/g,"\\{/each\\b",u.index);if(p<=0&&w<=0)throw new T("E-TEMPLATE",`${s}: a stray {:else} with no {#if} or {#each} above it`,{file:s,line:ve(e,u),hint:"{:else} belongs inside an {#if} ... {/if} or {#each} ... {/each} block"});continue}if(f==="fallback")throw new T("E-TEMPLATE",`${s}: a stray {:fallback} with no {#boundary} above it`,{file:s,line:ve(e,u),hint:"{:fallback} belongs directly inside a {#boundary} ... {/boundary} block"});if(f==="then"||f==="catch"){let h=(y,m)=>{y.lastIndex=0;let v=0,x;for(;(x=y.exec(e))&&!(x.index>=m);)l(x.index)||v++;return v},p=h(/\{#await\b/g,u.index),w=h(/\{\/await\b/g,u.index);if(p<=w)throw new T("E-TEMPLATE",`${s}: a stray {:${f}} with no {#await} above it`,{file:s,line:ve(e,u),hint:"{:then} / {:catch} belong inside an {#await} ... {/await} block"});continue}throw new T("E-TEMPLATE",`${s}: {:${f}} is not a Rosefc directive`,{file:s,line:ve(e,u),hint:"Rosefc templates support {#if}/{:else}, {#each} and {#boundary}"})}}let g=/\{#(if|each|boundary|island|await)\b/g;for(;u=g.exec(e);){if(l(u.index))continue;let c=u[1],f=Ue(e,u.index);if(f<0)continue;let h=e.slice(u.index+2+c.length,f-1);if(c==="each"&&!wn("each",h))throw new T("E-TEMPLATE",`${s}: {#each ${h.trim()}} is missing its item name`,{file:s,line:ve(e,u),hint:"write {#each items() as item} - the name after `as` is what the block body reads (item.id, item.name)"});let{open:p,close:w}=Yr(c),y=1,m=f;for(;;){p.lastIndex=m,w.lastIndex=m;let v=p.exec(e),x=w.exec(e);if(!x)break;if(v&&v.index<x.index){let S=Ue(e,v.index);m=S<0?v.index+v[0].length:S;continue}if(m=x.index+x[0].length,--y===0)break}if(y!==0)throw new T("E-TEMPLATE",`${s}: unclosed {#${c}} - every block needs its {/${c}}`,{file:s,line:ve(e,u),hint:`add the matching {/${c}} (an inner {#if} or {#each} closes first, deepest first)`})}}function to(e,s){let n=/<([a-zA-Z][\w-]*)((?:\s+[\w:-]+(?:=(?:"[^"]*"|'[^']*'|`[^`]*`|[^\s"'>]+))?)*)\s*(\/?)>/g;return e.replace(n,(t,r,i,o)=>{if(s.has(r)||!/\{/.test(i))return t;let l=i.replace(/([\w:-]+)=("([^"]*)"|'([^']*)'|`([^`]*)`)/g,(a,u,g,c,f,h)=>{let p=c??f??h??"";if(!/\{/.test(p)||h===void 0&&p.includes("`"))return a;let w=ut(p);if(w.length===0)return a;let y="",m=0;for(let v of w)m<v.start&&(y+=(y?" + ":"")+JSON.stringify(p.slice(m,v.start))),y+=(y?" + ":"")+`(${v.expr})`,m=v.end+1;return m<p.length&&(y+=(y?" + ":"")+JSON.stringify(p.slice(m))),`${u}={${y}}`});return`<${r}${l}${o?" /":""}>`})}var ln=0,un=!1,dn="",fn={},Ht=new Set,hn=new Set,pn=null,Ct="";function Be(e,s,n,t,r,i=!0,o=new Map,l=0){let a="",u=e,g=0,c=0,f=0,h=/\{#island\b/.test(e),p=i&&(!h||l>0),w=()=>`${r}_${f++}`;r===0&&(a+=`const __snip = {};
78
+ `);let y=new Map,m=dr(e,o),v=new Set(m).size===m.length;if(m.length>0&&v){let O={};for(let Z of m){let Y=`__rvct${ln++}`;y.set(Z,Y),O[Z]=Y}u=cn(e,[],O,{ownScope:!0,comps:o})}let x=O=>{let Z,Y=-1;return()=>((Y!==c||Z===void 0||Z!==null&&Z.index<g)&&(Z=O(g),Y=c),Z)},S=/<(style|script|noscript)\b[^>]*>/g,A=null,D=x(O=>at(u,"if",O)),J=x(O=>at(u,"each",O)),N=x(O=>at(u,"boundary",O)),ee=x(O=>at(u,"island",O)),H=x(O=>at(u,"snippet",O)),U=x(O=>fr(u,O)),te=x(O=>{let Z=o.size>0?xs(u,O,o):null;return Z?{index:Z.start,tag:Z}:null}),ce=x(O=>{S.lastIndex=O;let Z=S.exec(u);return Z?{index:Z.index,tag:Z[0],name:Z[1].toLowerCase()}:null}),Te=x(O=>{let Z=u.indexOf("<!--",O);if(Z<0)return null;let Y=u.indexOf("-->",Z+4);return{index:Z,end:Y<0?u.length:Y+3}});for(;g<u.length;){let O=D(),Z=J(),Y=N(),we=U(),Ee=we?Object.assign([u.slice(we.index,we.end+1),we.expr],{index:we.index}):null,je=te()?.tag??null,Pe=ee(),Me=H(),le=[];O?.index!==void 0&&le.push({type:"if",match:O,index:O.index}),Z?.index!==void 0&&le.push({type:"each",match:Z,index:Z.index}),Y?.index!==void 0&&le.push({type:"boundary",match:Y,index:Y.index}),Pe?.index!==void 0&&le.push({type:"island",match:Pe,index:Pe.index}),Me?.index!==void 0&&le.push({type:"snippet",match:Me,index:Me.index}),Ee?.index!==void 0&&le.push({type:"expr",match:Ee,index:Ee.index}),je&&le.push({type:"comp",match:Ee,index:je.start,tag:je});let E=le.length>0?le.reduce((z,j)=>z.index<=j.index?z:j):null,pe=ce();if(pe&&E&&pe.index<E.index){A===null&&(A=u.toLowerCase());let z=A.indexOf(`</${pe.name}`,pe.index+pe.tag.length),j=z<0?-1:u.indexOf(">",z),F=j<0?u.length:j+1;a+=ae(u.slice(g,pe.index),s,n,t),a+=vs(pe.tag,s,n,t),a+=ae(u.slice(pe.index+pe.tag.length,F),s,n,t),g=F;continue}let ke=Te();if(ke&&(!E||ke.index<E.index)){a+=ae(u.slice(g,ke.end),s,n,t),g=ke.end;continue}if(!E){a+=ae(u.slice(g),s,n,t);break}if(E.type==="if"){let[,z,j]=E.match,F=u.slice(g,E.index);F&&(a+=ae(F,s,n,t));let X=ts(z),re=w(),G=t??"__s",oe=Be(j.trim(),"h","__c",G,r+1,p,o,l);a+=`const __b${re} = (__s, __c) => { let h = ''; ${oe} return h; };
79
+ `,p?a+=`${s} += ifMark(${n}, () => (${X}), __b${re}${t?`, ${t}`:""});
80
+ `:a+=`${s} += (${X}) ? __b${re}(${t??"undefined"}, []) : '';
81
+ `,g=E.index+E.match[0].length}else if(E.type==="each"){let[,z,j,F,X,re]=E.match,G=u.slice(g,E.index);G&&(a+=ae(G,s,n,t));let oe=ts(z),ue=w(),V=/^[{[]/.test(j),ie=V?null:new RegExp(`\\b${j}\\b`,"g"),P=F?new RegExp(`\\b${F}\\b`,"g"):null,de="",se=0;for(let fe of ut(re.trim())){let Re=ie?fe.expr.replace(ie,"__s"):fe.expr;P&&(Re=Re.replace(P,"__i")),de+=re.trim().slice(se,fe.start)+"{"+Re+"}",se=fe.end+1}de+=re.trim().slice(se);let $e=Be(de,"h","__c","__s",r+1,p,o,l),Ie=V?`const ${j} = __s; ${$e}`:$e,Se="";if(X){if(V)throw new T("E-TEMPLATE",`${Ct}: a keyed {#each} keys on a named item's property - write {#each xs as x (x.id)}, not a destructuring pattern`,{file:Ct,hint:"name the item first, then key on one of its properties"});let fe=X.trim();ie&&(fe=fe.replace(ie,"__s")),P&&(fe=fe.replace(P,"__i")),Se=`, (__s, __i) => (${fe})`}if(a+=`const __b${ue} = (__s, __c${F?", __i":""}) => { let h = ''; ${Ie} return h; };
82
+ `,p)a+=`${s} += eachMark(${n}, () => (${oe}), __b${ue}${Se});
83
+ `;else{let fe=V?"__s":j;a+=`${s} += (${oe}).map((${fe}${F?", __i":""}) => __b${ue}(${fe}, []${F?", __i":""})).join('');
84
+ `}g=E.index+E.match[0].length}else if(E.type==="boundary"){let[,z,j]=E.match,F="";if(z){let ie=/__fb="([A-Za-z0-9+/=]*)"/.exec(z);ie&&(F=Buffer.from(ie[1],"base64").toString("utf-8"))}let X=j,re=u.slice(g,E.index);re&&(a+=ae(re,s,n,t));let G=w(),oe=/\$action:|<form[\s>]/.test(X),ue=Be(X.trim(),"h",n,t,r+1,p,o,l);a+=`const __b${G} = (__c) => { let h = ''; ${ue} return h; };
85
+ `;let V="";if(F.trim()){let ie=Be(F.trim(),"h",n,t,r+1,p,o,l);V=`const __bf${G} = (__c) => { let h = ''; ${ie} return h; };
86
+ `}a+=V,a+=`let __bd${G} = '';
87
+ `,a+=oe?`try { $actionErrorOrThrow(); __bd${G} = __b${G}(${n}); } catch (e) { $setBoundaryError(e); __bd${G} = ${V?`__bf${G}(${n})`:"$boundaryFallback(e)"}; }
88
+ `:`try { __bd${G} = __b${G}(${n}); } catch (e) { $setBoundaryError(e); __bd${G} = ${V?`__bf${G}(${n})`:JSON.stringify(er)}; }
89
+ `,a+=`${s} += __bd${G};
90
+ `,g=E.index+E.match[0].length}else if(E.type==="snippet"){let[,z,j,F]=E.match,X=u.slice(g,E.index);X&&(a+=ae(X,s,n,t));let re=w(),G=j?j.split(",").map(ue=>ue.trim()).filter(Boolean).join(","):"",oe=Be(F.trim(),"h","__c","__s",r+1,p,o,l);a+=`__snip.${z} = (__s, __c${G?","+G:""}) => { let h = ''; ${oe} return h; };
91
+ `,g=E.index+E.match[0].length}else if(E.type==="comp"){let z=E.tag;z.start>g&&(a+=ae(u.slice(g,z.start),s,n,t));let j=o.get(z.name),F=w(),X="";if(z.selfClosing)g=z.end;else{let P=zt(u,z.end,z.name);if(P<0)throw new T("E-TEMPLATE",`unclosed <${z.name}> - every component tag needs its matching close tag`,{hint:`add the matching </${z.name}> (or close the tag with /> when it takes no children)`});X=u.slice(z.end,P),g=P+z.name.length+3}let{def:re,named:G}=oo(X),oe=re.trim().length>0;oe&&(a+=`const __ch${F} = (__s, __c) => { let h = ''; ${Be(re,"h","__c",t,r+1,p,o,l)} return h; };
92
+ `);let ue=G.map(([P,de])=>{let se=j.slots.find(Ie=>Ie.name===P),$e=de;for(let Ie of se?.props??[]){let Se=new RegExp(`\\b${Ie}\\b`,"g"),fe="",Re=0;for(let qe of ut($e))fe+=$e.slice(Re,qe.start)+"{"+qe.expr.replace(Se,`__s.${Ie}`)+"}",Re=qe.end+1;$e=fe+$e.slice(Re)}return`${JSON.stringify(P)}: (__s, __c) => { let h = ''; ${Be($e,"h","__c",t,r+1,p,o,l)} return h; }`}),V=so(z.attrs).filter(P=>P.name!=="slot").map(P=>{if(P.kind==="spread")return`...(${P.value})`;let de=P.name.startsWith("on:")?`on${He(P.name.slice(3))}`:P.name,se=P.kind==="expr"?`(${P.value})`:P.kind==="str"?JSON.stringify(P.value):"true";return`${JSON.stringify(de)}: ${se}`}).join(", "),ie=oe?`__ch${F}(${t??"undefined"}, ${n})`:"''";a+=`${s} += ${z.name}(${n}, ${ie}, { ${V} }, { ${ue.join(", ")} });
93
+ `}else if(E.type==="island"){let[,z,j,F]=E.match,X=u.slice(g,E.index);X&&(a+=ae(X,s,n,t));let re=j==="visible"||j==="idle"?` data-rv-island-hydrate="${j}"`:"";a+=`${s} += ${JSON.stringify(`<div data-rv-island="${z||""}"${re}>`)};
94
+ `;let G=Be(F.trim(),"h","__c",t,r+1,i,o,l+1);a+=G,a+=`${s} += '</div>';
95
+ `,g=E.index+E.match[0].length}else{let[,z]=E.match,j=z.trim(),F=u.slice(g,E.index),X=/^@const\s+([A-Za-z_$][\w$]*)\s*=\s*([\s\S]+)$/.exec(j);if(X){F&&(a+=ae(F,s,n,t));let P=X[1],de=u.slice(E.index+E.match[0].length),se=y.get(P);g=E.index+E.match[0].length,se===void 0&&(se=`__rvct${ln++}`,u=cn(de,[],{[P]:se}),g=0,c++);let $e=`const ${se} = () => (${X[2].trim()});
96
+ `;un&&r===0?(Ht.has(P)?pn=P:Ht.add(P),dn+=$e,fn[P]=se):a+=$e;continue}if(j==="__slot__"){F&&(a+=ae(F,s,n,t)),a+=bo(s),g=E.index+E.match[0].length;continue}let re=/^__slotDefault\(("(?:[^"\\]|\\.)*")\)$/.exec(j);if(re){F&&(a+=ae(F,s,n,t)),a+=`${s} += __slotDefault(children, ${re[1]});
97
+ `,g=E.index+E.match[0].length;continue}let G=/^__slot\((['"])(\w+)\1, \[([\s\S]*?)\](?:,\s*("(?:[^"\\]|\\.)*"))?\)$/.exec(j);if(G){F&&(a+=ae(F,s,n,t));let P=G[4]?`, ${G[4]}`:"";a+=`${s} += __slotBlock(${n}, __sl, ${JSON.stringify(G[2])}, [${G[3]}]${P});
98
+ `,g=E.index+E.match[0].length;continue}let oe=/^@html\s+([\s\S]+)$/.exec(j);if(oe){F&&(a+=ae(F,s,n,t));let P=oe[1].trim();if(!p)a+=`${s} += String(${P} ?? '');
99
+ `;else{let de=t?`(${t}) => (${P})`:`() => (${P})`;a+=`${s} += rawMark(${n}, ${de}${t?`, ${t}`:""});
100
+ `}g=E.index+E.match[0].length;continue}let ue=/^@debug\b([\s\S]*)$/.exec(j);if(ue){F&&(a+=ae(F,s,n,t));let P=ue[1].trim().replace(/,$/,"");a+=P?`console.log('[rosefc:debug]', { ${P} });
101
+ `:`console.log('[rosefc:debug]'); debugger;
102
+ `,g=E.index+E.match[0].length;continue}let V=/^@render\s+([A-Za-z_$][\w$]*)\s*\(([\s\S]*)\)\s*$/.exec(j);if(V){if(new RegExp(`\\{#snippet\\s+${V[1]}\\b`).test(u.slice(E.index+E.match[0].length)))throw new T("E-TEMPLATE",`${Ct}: {@render ${V[1]}} runs before its {#snippet ${V[1]}} is defined`,{file:Ct,hint:"move the {#snippet} definition above the {@render} call - definitions register as the statement stream reaches them"});F&&(a+=ae(F,s,n,t));let de=V[2].trim();a+=`${s} += ((__snip && __snip.${V[1]}) ? __snip.${V[1]}(${t??"null"}, ${n}${de?", "+de:""}) : '');
103
+ `,g=E.index+E.match[0].length;continue}let ie=io(u,E.index)?/([\w-]+)=\s*$/.exec(F)??null:null;if(ie){let P=F.slice(0,F.length-ie[0].length);P&&(a+=ae(P,s,n,t)),a+=wo(ie[1],j,s,n,t,p)}else{F&&(a+=ae(F,s,n,t));let P=u.slice(E.index+E.match[0].length);if(/=[\"'][^\"']*$/.test(F))a+=`${s} += esc(${j});
104
+ `;else{let se=P.length>0&&!/^<[a-zA-Z/!]/.test(P)&&!P.startsWith("{");a+=go(j,s,n,t,p,se)}}g=E.index+E.match[0].length}}return a=a.replace(/\+= "\s*([a-zA-Z][\w-]*)=";\r?\n\s*\w+\s*\+=\s*textMark\((\w+), (.+?), 1, ([^;]+?)\);/g,(O,Z,Y,we,Ee)=>`+= attrMark(${Y}, ${we}, '${Z}', ${Ee});`),a}function Gt(e,s){let n=s+1,t="",r=0;for(;n<e.length;){let i=e[n];if(t)i===t&&(t="");else if(i==='"'||i==="'")t=i;else if(i==="{")r++;else if(i==="}")r=Math.max(0,r-1);else if(i===">"&&r===0)return n+1;n++}return-1}function xs(e,s,n){let t=s;for(;t<e.length;){let r=e.indexOf("<",t);if(r<0)return null;let i=/^<([a-zA-Z][\w-]*)/.exec(e.slice(r,r+64));if(i&&n.has(i[1])){let o=Gt(e,r);if(o>0){let l=e.slice(r,o),a=/\/>$/.test(l);return{start:r,end:o,name:i[1],attrs:l.slice(1+i[1].length,a?-2:-1),selfClosing:a}}}t=r+1}return null}function no(e,s){return xs(e,0,s)}function zt(e,s,n){let t=new RegExp(`<(/?)${n}(?=[\\s/>])`,"g");t.lastIndex=s;let r=1,i;for(;i=t.exec(e);){let o=Gt(e,i.index);if(o<0)return-1;if(i[1]==="/"){if(r--,r===0)return i.index}else/\/>$/.test(e.slice(i.index,o))||r++}return-1}function so(e){let s=[],n=0;for(;n<e.length;){let t=/^\s*\{\.\.\.([^}]*)\}/.exec(e.slice(n));if(t){s.push({name:"...",kind:"spread",value:t[1].trim()}),n+=t[0].length;continue}let r=/^\s*([\w:.-]+)/.exec(e.slice(n));if(!r)break;n+=r[0].length;let i=/^\s*=\s*/.exec(e.slice(n));if(!i){s.push({name:r[1],kind:"bool",value:""});continue}n+=i[0].length;let o=e[n];if(o==="{"){let l=1,a=n+1;for(;a<e.length&&l>0;)e[a]==="{"?l++:e[a]==="}"&&l--,a++;s.push({name:r[1],kind:"expr",value:e.slice(n+1,a-1).trim()}),n=a}else if(o==='"'||o==="'"){let l=e.indexOf(o,n+1);s.push({name:r[1],kind:"str",value:e.slice(n+1,l<0?e.length:l)}),n=l<0?e.length:l+1}else break}return s}function ro(e,s){let n=0;for(;n<e.length;){let t=e.indexOf("<",n);if(t<0)return;let r=/^<(\/?)([a-zA-Z][\w-]*)/.exec(e.slice(t,t+64));if(!r){n=t+1;continue}let i=Gt(e,t);if(i<0)return;let o=/\bslot\s*=\s*["'](\w+)["']/.exec(e.slice(t,i));if(o&&r[1]!=="/")throw new T("E-TEMPLATE",`slot="${o[1]}" on <${r[2]}> is nested inside slot="${s}" - a slot must be a direct child of the component`,{hint:"move the inner <slot> out of the outer one - a slot is a direct child of the component tag, never nested in another slot"});n=i}}function oo(e){let s="",n=new Map,t=0,r=0,i=0,o=[];for(;t<e.length;){let l=e.indexOf("<",t),a=e.indexOf("{#",t),u=e.indexOf("{/",t),g=[l,a,u].filter(v=>v>=0);if(g.length===0){s+=e.slice(t);break}let c=Math.min(...g);if(c>t&&(s+=e.slice(t,c)),c===a||c===u){let v=e.indexOf("}",c),x=e.slice(c,v<0?e.length:v+1);if(c===a){let S=/^\{#(\w+)/.exec(x);o.push({header:x,type:S?S[1]:""}),i++}else i=Math.max(0,i-1),o.length&&o.pop();s+=x,t=c+x.length;continue}let f=/^<(\/?)([a-zA-Z][\w-]*)/.exec(e.slice(c,c+64));if(!f){s+="<",t=c+1;continue}let h=Gt(e,c);if(h<0){s+=e.slice(c);break}let p=e.slice(c,h),w=/\/>$/.test(p),y=ys.has(f[2].toLowerCase());if(f[1]==="/"){r=Math.max(0,r-1),s+=p,t=h;continue}!w&&!y&&r++;let m=/\bslot\s*=\s*["'](\w+)["']/.exec(p)?.[1];if(m&&r===1&&i===0){if(w||y)n.set(m,(n.get(m)??"")+p.replace(/\s*slot\s*=\s*["']\w+["']/,""));else{let v=zt(e,h,f[2]);if(v<0)throw new T("E-TEMPLATE",`unclosed <${f[2]}> inside slot="${m}"`,{hint:`add the matching </${f[2]}>`});let x=`</${f[2]}>`,S=e.slice(h,v);ro(S,m),n.set(m,(n.get(m)??"")+p.replace(/\s*slot\s*=\s*["']\w+["']/,"")+S+x),r=Math.max(0,r-1),t=v+x.length;continue}t=h;continue}if(m&&i>0){let v=p.replace(/\s*slot\s*=\s*["']\w+["']/,""),x="";for(let D of o)x+=D.header;if(x+=v,w||y){for(let D=o.length-1;D>=0;D--)x+=`{/${o[D].type}}`;n.set(m,(n.get(m)??"")+x),t=h;continue}let S=zt(e,h,f[2]);if(S<0)throw new T("E-TEMPLATE",`unclosed <${f[2]}> inside slot="${m}"`,{hint:`add the matching </${f[2]}>`});let A=`</${f[2]}>`;x+=e.slice(h,S)+A;for(let D=o.length-1;D>=0;D--)x+=`{/${o[D].type}}`;n.set(m,(n.get(m)??"")+x),r=Math.max(0,r-1),t=S+A.length;continue}if(m)throw new T("E-TEMPLATE",`slot="${m}" on <${f[2]}> must be a direct child of the component, or wrapped only by an {#if}/{#each}/{#boundary} block - it is nested inside another element`,{hint:'place the element with slot="..." directly inside the component tag, or inside a single {#if}/{#each} block - wrapping it in another element is not yet supported'});s+=p,t=h}return{def:s,named:[...n.entries()]}}function io(e,s){let t=e.slice(0,s).lastIndexOf("<");if(t<0||!/^<[a-zA-Z]/.test(e.slice(t)))return!1;let r=t+1,i="",o=0;for(;r<s;){let l=e[r];if(i)l===i&&(i="");else if(l==='"'||l==="'")i=l;else if(l==="{")o++;else if(l==="}")o=Math.max(0,o-1);else if(l===">"&&o===0)return!1;r++}return!0}function ae(e,s,n,t){return e?`${s} += ${JSON.stringify(e)};
105
+ `:""}function ao(e,s,n,t){if(!e.includes("{@html"))return ae(e,s,n,t);let r="",i=0,o=e.indexOf("{@html");for(;o!==-1;){let a=jt(e,o);if(a<0)break;let u=/^@html\s+([\s\S]+)$/.exec(e.slice(o+1,a));if(u){let g=e.slice(i,o);g&&(r+=`${s} += ${JSON.stringify(g)};
106
+ `),r+=`${s} += String(${u[1].trim()} ?? '');
107
+ `,i=a+1}o=e.indexOf("{@html",a+1)}if(i===0)return ae(e,s,n,t);let l=e.slice(i);return l&&(r+=`${s} += ${JSON.stringify(l)};
108
+ `),r}function vs(e,s,n,t){let r=ut(e);if(r.length===0)return ae(e,s,n,t);let i=`${s} += `,o=0;return r.forEach((l,a)=>{let u=e.slice(o,l.start),g=u.endsWith("=");a>0&&(i+=" + "),i+=JSON.stringify(g?u+'"':u),i+=` + esc(${l.expr})`,g&&(i+=` + '"'`),o=l.end+1}),o<e.length&&(i+=" + "+JSON.stringify(e.slice(o))),i+`;
109
+ `}var co=/<img\b(?:[^<>]|\{[^{}]*\})*>/g,lo={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".ico":"image/x-icon"},uo=4096,fo=16384;function ho(e,s){let n=_.extname(s),t=_.basename(s,n),r=s.slice(0,s.length-(t+n).length),i;try{i=C.readdirSync(_.join(e,_.dirname(s)))}catch{return[]}let o=new RegExp("^"+t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"\\.w(\\d+)"+n.replace(".","\\.")+"$","i"),l=[];for(let a of i){let u=o.exec(a),g=u?Number(u[1]):0;g>0&&l.push({url:`${r}${t}.w${g}${n}`,width:g})}return l.sort((a,u)=>a.width-u.width)}var ss=new Map;function po(e){let s;try{s=C.statSync(e)}catch{return null}let n=ss.get(e);if(n&&n.mtime===s.mtimeMs)return{buffer:n.buffer,dims:n.dims};let t;try{t=C.readFileSync(e)}catch{return null}let r=Fn(e),i={mtime:s.mtimeMs,buffer:t,dims:r};return ss.set(e,i),{buffer:t,dims:i.dims}}function rs(e,s){return e.replace(co,n=>{let t=n.match(/\bsrc="(\/[^"{}]+)"/);if(!t)return n;let r=_.extname(t[1]).toLowerCase(),i=lo[r];if(!i)return n;let o=_.join(s,t[1]),l=po(o);if(!l)return n;let a=l.buffer,g=/\swidth=/.test(n)||/\sheight=/.test(n)?null:l.dims,c=p=>g?p.replace(/<img\b/,`<img width="${g.width}" height="${g.height}"`):p,f=r===".svg"?fo:uo;if(a.length>f){let w=/\ssrcset=/.test(n)||/\ssizes=/.test(n)?[]:ho(s,t[1]);if(!w.length)return c(n);let y=w.map(m=>`${m.url} ${m.width}w`).join(", ");return c(n.replace(/<img\b/,`<img srcset="${y}"`))}let h=r===".svg"?`data:image/svg+xml,${a.toString("utf-8").replace(/%/g,"%25").replace(/#/g,"%23").replace(/"/g,"%22")}`:`data:${i};base64,${a.toString("base64")}`;return c(n.replace(t[0],`src="${h}"`))})}function go(e,s,n,t,r=!0,i=!1){if(!r)return`${s} += esc(${e});
110
+ `;let o=t?`(${t}) => (${e})`:`() => (${e})`,l=i?", 1":t?", 0":"";return t&&(l+=`, ${t}`),`${s} += textMark(${n}, ${o}${l});
111
+ `}var mo=new Set(["checked","disabled","readonly","required","selected","multiple","autofocus","open"]);function wo(e,s,n,t,r,i=!0){if(!i)return`${n} += '${e}="' + esc(${s}) + '"';
112
+ `;let o=r?`(${r}) => (${s})`:`() => (${s})`,l=r?`, ${r}`:"";return mo.has(e)?`${n} += boolAttrMark(${t}, ${o}, '${e}'${l});
113
+ `:`${n} += attrMark(${t}, ${o}, '${e}'${l});
114
+ `}function bo(e){return`${e} += String(children);
115
+ `}var Pt="import { state, setState, persistState, $data, hasState, isSeeded, markSeeded, esc, refresh, onMount, onCleanup, $effect, getContext, $query, $t, bestLocale, localeDir, ensureLocale, loadLocale, handlers, directives, $cookies, $sessionCookie, $store, $udp, $tcp, $listen, $websocket, $mqtt, parseLoRaWAN, ActionError, $actionError, $actionErrorOrThrow, $actionPending, $boundaryFallback, $setBoundaryError, $boundaryError, $append, $prepend, $merge, applyStateDeltas, textMark, attrMark, boolAttrMark, ifMark, eachMark, headMark, rawMark, slotBlockMark, redirect, notFound, aggregate, loader, encodeSdui, decodeSdui } from './runtime.js';",$o=Pt.replace(/^import\s*\{/,"").replace(/\}\s*from[\s\S]*$/,"").split(",").map(e=>e.trim()).filter(Boolean);function ks(e){return e.length===0?"":e.map(s=>`const ${s.name} = __p.${s.name}${s.def?` ?? (${s.def})`:""};`).join(`
116
+ `)}var Es=`const __slot = (sl, name, pairs) => {
117
+ const fn = sl[name];
118
+ if (typeof fn !== 'function') return null;
119
+ const o = {};
120
+ for (let i = 0; i < pairs.length; i++) o[pairs[i][0]] = pairs[i][1];
121
+ return { o, fn };
122
+ };
123
+ const __slotBlock = (closes, sl, name, pairs, fallback) => {
124
+ const hit = __slot(sl, name, pairs);
125
+ if (hit) return slotBlockMark(closes, hit);
126
+ return fallback || '';
127
+ };
128
+ const __slotDefault = (children, fallback) => {
129
+ const c = children == null ? '' : String(children);
130
+ if (c.trim()) return c;
131
+ return fallback || '';
132
+ };`,Ss=`
133
+ // R259: an inline handler inside {#each} registers HERE, inside the render
134
+ // closure - the arrow captures the row's \`__s\` (the item), which module
135
+ // scope never had (BUG.md BE). The key is prefix + this document's shared
136
+ // closes-array counter: one array per document render, shared by every
137
+ // layout/page/component instance, so rows and instances never collide and
138
+ // the FIRST render's sequence matches the server's (adopt-by-index contract)
139
+ // - which is the key wire()'s direct listener captures at bind time. A
140
+ // closure mints once and re-evaluations (wire's attribute pass) reuse the
141
+ // minted key, so nothing re-mints and the registry does not grow per pass.
142
+ const __rhreg = (prefix, fn) => {
143
+ if (typeof fn === 'function' && fn.__rhk) return fn.__rhk;
144
+ const n = (closes.__rhn = (closes.__rhn || 0) + 1) - 1;
145
+ const k = prefix + n;
146
+ handlers[k] = fn;
147
+ if (typeof fn === 'function') fn.__rhk = k;
148
+ return k;
149
+ };
150
+ `;function yo(e,s,n,t="",r="",i=[],o=!1,l="",a=!1,u="",g=!1,c="",f="",h=!1){let p=r?`
151
+ const __head = () => { let __hd = ''; ${r} return __hd; };
152
+ __html += headMark(closes, __head);`:"",w=g||h?`
153
+ const $setState = (key, value) => setState(key, value);`:"",y=h?Ss:"";return`
154
+ ${Pt}
155
+
156
+ ${l}
157
+
158
+ ${t}
159
+ ${u}
160
+ ${w}
161
+
162
+ ${o?Es:""}
163
+
164
+ export ${a?"function":"async function"} render(closes, children, __props, __slots) {
165
+ ${i.length>0?"const __p = __props || {};":""}
166
+ ${o?"const __sl = __slots || {};":""}
167
+ ${ks(i)}
168
+ ${i.length>0?"const __rvlive = (k, v) => { const g = __p['__live-' + k]; return typeof g === 'function' ? g() : v; };":""}
169
+ ${e}
170
+ ${n}
171
+ ${c}
172
+ ${f}
173
+ ${y}
174
+
175
+ ${a?"":"applyStateDeltas();"}
176
+ const __root = (__c, children) => { let h = ''; ${s} return h; };
177
+ let __html = ${a?"":"await "}__root(closes, children);${p}
178
+ return __html;
179
+ }
180
+ `}function _o(e,s,n,t,r="",i="",o=[],l=!1,a="",u=!1,g="",c="",f=!1){let h=new Set,p=t.filter(x=>h.has(x.fn)?!1:(h.add(x.fn),!0)),w=p.length>0?`Object.assign(handlers, { ${p.map(x=>x.fn).join(", ")} });`:"",y=p.length>0||f?"const $setState = (key, value) => setState(key, value);":"",m=f?Ss:"",v=i?`
181
+ const __head = () => { let __hd = ''; ${i} return __hd; };
182
+ __html += headMark(closes, __head);`:"";return`
183
+ ${Pt}
184
+
185
+ ${a}
186
+
187
+ ${r}
188
+ ${y?`
189
+ ${y}
190
+ `:""}
191
+ ${l?Es:""}
192
+
193
+ export ${u?"function":"async function"} render(closes, children, __props, __slots) {
194
+ ${o.length>0?"const __p = __props || {};":""}
195
+ ${l?"const __sl = __slots || {};":""}
196
+ ${ks(o)}
197
+ ${o.length>0?"const __rvlive = (k, v) => { const g = __p['__live-' + k]; return typeof g === 'function' ? g() : v; };":""}
198
+ ${e}
199
+ ${n}
200
+ ${g}
201
+ ${c}
202
+ ${w}
203
+ ${m}
204
+ const __root = (__c, children) => { let h = ''; ${s} return h; };
205
+ let __html = ${u?"":"await "}__root(closes, children);${v}
206
+ return __html;
207
+ }
208
+ `}var nt=(e,s)=>e.map((n,t)=>({li:n,i:t})).filter(({li:n})=>n.isLayout&&Eo(n.filePath,e[s].filePath)).sort((n,t)=>t.li.filePath.length-n.li.filePath.length).map(({i:n})=>n),Tt=(e,s,n)=>s[n].csr===!0||s[n].needsClient||gn(e,s,n)?!1:!nt(e,n).some(t=>s[t].needsClient),gn=(e,s,n)=>s[n].shell===!1||nt(e,n).some(t=>s[t].shell===!1);function xo(e,s){return e.map((n,t)=>({info:n,i:t})).filter(({info:n})=>!n.isLayout&&!n.isNotFound&&!n.isError&&!n.isApi&&!n.isMiddleware&&!n.isComponent).map(({info:n,i:t})=>{if(Tt(e,s,t))return`${n.routePath} zero-JS nothing in the chain needs the client`;let r=[t,...nt(e,t)].filter(o=>s[o].needsClient).map(o=>`${(s[o].clientReasons??["needs the client"]).join(" + ")} in ${_.basename(e[o].filePath)}`).join("; "),i=s[t].csr===!0?" (csr = true forces the bundle)":"";return`${n.routePath} client JS ${r}${i}`})}var os=`
209
+
210
+ import { start, postForm } from '/client.js';
211
+
212
+ for (const el of document.querySelectorAll('[data-rosefc]')) {
213
+ const route = el.getAttribute('data-rosefc');
214
+ const doc = await fetch(route).then((r) => (r.ok ? r.text() : ''));
215
+ const parsed = new DOMParser().parseFromString(doc, 'text/html');
216
+ // A JS-shipping document wraps its content in #app; a zero-JS route's content is the body's own (no wrapper).
217
+ const app = parsed.getElementById('app');
218
+ if (app) {
219
+ el.innerHTML = app.innerHTML;
220
+ } else {
221
+ for (const node of Array.from(parsed.body.children)) {
222
+ if (!/^(?:SCRIPT|LINK|STYLE)$/.test(node.tagName)) el.appendChild(node);
223
+ }
224
+ }
225
+ // start() resumes from #__rosefc_state (zero hydration), so the state
226
+ const state = parsed.getElementById('__rosefc_state');
227
+ if (state) el.appendChild(state);
228
+
229
+ const rendered = state ? JSON.parse(state.textContent || '{}').__route : null;
230
+ await start(el, route, rendered === route);
231
+ if (state) state.remove();
232
+
233
+ el.addEventListener('click', (e) => {
234
+ const a = e.target.closest && e.target.closest('a[href^="/"]');
235
+ if (!a || !el.contains(a)) return;
236
+ e.preventDefault();
237
+ el.setAttribute('data-rosefc', a.getAttribute('href'));
238
+ start(el, a.getAttribute('href'), false);
239
+ });
240
+ // Progressive-enhancement forms work inside a mount too: the native POST would replace the HOST page.
241
+ el.addEventListener('submit', (e) => {
242
+ const f = e.target;
243
+ if (!f || f.tagName !== 'FORM' || f.hasAttribute('data-on-submit')) return;
244
+ if ((f.getAttribute('method') || '').toLowerCase() !== 'post') return;
245
+ e.preventDefault();
246
+ postForm(new FormData(f), el, el.getAttribute('data-rosefc'));
247
+ });
248
+ }
249
+ `,rn=new Map,is=null;async function Qo(e,s,n={}){let t=_.resolve(e),r=_.resolve(s),i=n.minify!==!1,o=n.incremental===!0;await C.promises.mkdir(r,{recursive:!0});let l=(await C.promises.readdir(r)).filter(d=>/^(?:comp-\d+\.(?:ssr|client)|runtime|(?:server|client)-entry)\.js$/.test(d));await Promise.all(l.map(d=>C.promises.rm(_.join(r,d),{force:!0})));let[a,u]=await Promise.all([vo(t),ko(t)]),g=[...a,...u];if(a.length===0)throw new T("E-ROUTE",`no .rose pages found under ${_.join(t,"src","pages")} - run rosefc from a project root, or pass one: rosefc build <dir>`,{file:_.join(t,"src","pages"),hint:"create src/pages/index.rose in that directory (or run the command from the project root)"});let c=g.map(d=>({...So(d,t)})),f=await ps(t);ms=(f.watch??[]).map(d=>_.isAbsolute(d)?d:_.join(t,d));let h=f.plugins,p=g.map((d,b)=>{let M=c[b].isComponent?_.join(t,"src"):_.join(t,"src","pages");return _.relative(M,d).replace(/\\/g,"/").replace(/\.rose$/,"")}),w=new Map(g.map((d,b)=>[d,{index:b,scopeKey:p[b],slots:$r(d)}])),y=ft.transform("export default 0",{loader:"js"}).catch(()=>{}),m=await Promise.all(g.map((d,b)=>Ar(d,_.join(t,"public"),p[b],c[b].isApi,h,w)));await y;{let d=new Set(mn().map(([B])=>B)),b=[],M=new Set;for(let B=0;B<m.length;B++)for(let q of[...Hn(m[B].ssr),...Hn(m[B].client)]){if(d.has(q)||M.has(q))continue;M.add(q);let L=`${_.relative(t,g[B]).replace(/\\/g,"/")} reads import.meta.env.${q}`;b.push(q.startsWith(At)?` ${L}
250
+ -> it has the public prefix but is not set in this build's environment (an unset public var is undefined in the bundle; the server render does not fall back to it)`:` ${L}
251
+ -> only ${At}* is exposed to the client; rename it to ${At}${q} if it is public config, or keep it server-only (it stays undefined here, in dev and in the bundle)`)}b.length>0&&console.warn(`Rosefc warning: import.meta.env.<name> carries only ${At}* variables:
252
+ ${b.join(`
253
+ `)}`)}let v=new Map;g.forEach((d,b)=>{let M=[];for(let B of m[b].roseImports??[]){let q=_.resolve(_.dirname(g[b]),B.specifier),L=w.get(q);L&&M.push(L.index)}v.set(b,M)});let x=(d,b=new Set)=>{if(m[d].needsClient)return _.basename(g[d]);if(b.has(d))return null;b.add(d);for(let M of v.get(d)??[]){let B=x(M,b);if(B)return B}return null};m.forEach((d,b)=>{if(d.needsClient)return;let M=x(b);M&&(d.needsClient=!0,d.clientReasons=[...d.clientReasons??[],`imported component ${M} needs the client`])});let S=new Set,A=d=>{if(!S.has(d)){S.add(d);for(let b of m[d].roseImports??[]){let M=_.resolve(_.dirname(g[d]),b.specifier),B=w.get(M);B&&A(B.index)}}};g.forEach((d,b)=>{c[b].isComponent||A(b)});let D=m.map((d,b)=>S.has(b)&&c[b].isComponent?d.style:"").filter(Boolean).join(`
254
+ `);D?await C.promises.writeFile(_.join(r,"styles.css"),D):await C.promises.rm(_.join(r,"styles.css"),{force:!0});let J={};try{let d=_.join(t,"src","locales"),b=(await C.promises.readdir(d)).filter(B=>B.endsWith(".json")),M=await Promise.all(b.map(async B=>[B.slice(0,-5),JSON.parse(await C.promises.readFile(_.join(d,B),"utf-8"))]));J=Object.fromEntries(M)}catch{J={}}let N=J.en?"en":Object.keys(J).sort()[0]??"en",ee=JSON.stringify(J).replace(/</g,"\\u003c"),H=f.i18n.preload??Object.keys(J),U=Object.keys(J).filter(d=>!H.includes(d));for(let d of H)J[d]||console.warn(`Rosefc: i18n.preload lists '${d}' but there is no src/locales/${d}.json - ignored`);if(await C.promises.rm(_.join(r,"locales"),{recursive:!0,force:!0}),U.length>0){let d=_.join(r,"locales");await C.promises.mkdir(d,{recursive:!0});for(let b of U)await C.promises.writeFile(_.join(d,`${b}.json`),JSON.stringify(J[b]))}let te=Object.fromEntries(Object.keys(J).filter(d=>!U.includes(d)).map(d=>[d,J[d]])),ce=JSON.stringify(te).replace(/</g,"\\u003c"),Te=_.join(t,".rosefc-build"),O=_.join(Te,`${process.pid}-${Vt(_.resolve(t))}`),Z=C.existsSync(O);await C.promises.mkdir(O,{recursive:!0});let Y=new Date;await C.promises.utimes(O,Y,Y),(!Z||is!==O)&&(rn.clear(),is=O),On(Te);let we=[_.join(_.dirname(Rt(import.meta.url)),"..","cli","content.ts"),_.join(_.dirname(Rt(import.meta.url)),"..","src","cli","content.ts")],Ee=we.find(d=>C.existsSync(d))??we[0];C.copyFileSync(Ee,_.join(O,"content-md.ts"));let je=h.filter(d=>d&&(d.onRequest||d.onResponse));if(je.length>0){let d=_.relative(O,_.join(t,"rosefc.config.js")).replace(/\\/g,"/");await C.promises.writeFile(_.join(O,"plugins.js"),`
255
+ import config from ${JSON.stringify(d)};
256
+
257
+ const list = Array.isArray(config) ? config : [];
258
+ export const hooks = list
259
+ .filter((p) => p && (p.onRequest || p.onResponse))
260
+ .map((p) => ({ name: p.name, onRequest: p.onRequest ? p.onRequest.bind(p) : null, onResponse: p.onResponse ? p.onResponse.bind(p) : null }));
261
+
262
+ export const hasRequestHooks = hooks.some((p) => p.onRequest);
263
+ export const hasResponseHooks = hooks.some((p) => p.onResponse);
264
+ `)}let Pe=["../runtime/index.ts","../src/runtime/index.ts"].map(d=>Rt(new URL(d,import.meta.url))).find(d=>C.existsSync(d));if(!Pe)throw new T("E-INTERNAL","Rosefc: the runtime source (src/runtime/index.ts) was not found next to the compiler",{hint:"the published package ships src/ beside dist-cli/ - reinstall it, or run from a checkout"});let Me=et(Pe,{entryPoints:[Pe],bundle:!0,outfile:_.join(O,"runtime.js"),format:"esm",platform:"browser",write:!0},o),le=(()=>{let d=_.dirname(Rt(import.meta.url));for(let b of[_.join(d,"..","cli","prod-server.ts"),_.join(d,"..","src","cli","prod-server.ts")])if(C.existsSync(b))return b;return _.join(d,"..","cli","prod-server.ts")})(),E="import { createRequire as __cr } from 'node:module'; import { fileURLToPath as __f2p } from 'node:url'; import { dirname as __dn } from 'node:path'; const require = __cr(import.meta.url); const __filename = __f2p(import.meta.url); const __dirname = __dn(__filename);",pe=o?Promise.resolve({}):et(le,{entryPoints:[le],bundle:!0,outfile:_.join(r,"prod.mjs"),format:"esm",platform:"node",write:!0,banner:{js:E},...it,...i?{minify:!0,keepNames:!0}:{}},o);Me.catch(()=>{}),pe.catch(()=>{});let ke=[],z=(d,b)=>{rn.get(d)!==b&&(rn.set(d,b),ke.push(C.promises.writeFile(_.join(O,d),b)))};for(let d=0;d<m.length;d++){let b=m[d].api??m[d].ssr;z(`comp-${d}.ssr.js`,b),c[d].isApi||z(`comp-${d}.client.js`,m[d].client)}for(let d=0;d<ke.length;d+=64)await Promise.all(ke.slice(d,d+64));let j=c.map((d,b)=>({info:d,i:b})).filter(({info:d})=>!d.isLayout&&!d.isNotFound&&!d.isError&&!d.isApi&&!d.isMiddleware&&!d.isComponent).sort((d,b)=>{let M=L=>{let I=L.split("/");return[I.filter(K=>K.startsWith("**")).length,I.filter(K=>K.startsWith("*")).length,I.filter(K=>K.startsWith(":")).length]},B=M(d.info.pattern),q=M(b.info.pattern);for(let L=0;L<3;L++)if(B[L]!==q[L])return B[L]-q[L];return d.info.filePath<b.info.filePath?-1:1}),F=c.map((d,b)=>({info:d,i:b})).filter(({info:d})=>d.isApi).sort((d,b)=>{let M=L=>{let I=L.split("/");return[I.filter(K=>K.startsWith("**")).length,I.filter(K=>K.startsWith("*")).length,I.filter(K=>K.startsWith(":")).length]},B=M(d.info.pattern),q=M(b.info.pattern);for(let L=0;L<3;L++)if(B[L]!==q[L])return B[L]-q[L];return d.info.filePath<b.info.filePath?-1:1}),X=d=>{let b=`render_${d}`;for(let M of nt(c,d))b=`(async (closes, children) => await render_${M}(closes, await (${b})(closes, children)))`;return b},re=_.join(t,"src","pages","_layout.rose"),G=g.findIndex((d,b)=>m[b].bundle&&d!==re);if(G>=0)throw new T("E-BUNDLE",`${_.basename(g[G])}: export const bundle switches the whole app's bundle mode, so it belongs in the root layout (src/pages/_layout.rose)`,{file:g[G],hint:"move `export const bundle = 'split'` (or 'inline') to src/pages/_layout.rose - the mode is per-app, not per-page"});let oe=m[g.indexOf(re)]?.bundle??"inline",ue=oe==="split",V=oe==="sliced",ie=d=>"s"+qt(d).toString(36),P=Pt.replace(/^import\s*\{/,"").replace(/\}\s*from[\s\S]*$/,"").split(",").map(d=>d.trim()).filter(Boolean),de=(()=>{let d=M=>M.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),b=new Set;for(let M of m){if(!M.client)continue;let B=M.client.replace(/^import\s*\{[^}]*\}\s*from\s*'\.\/runtime\.js';/m,"");for(let q of P)b.has(q)||new RegExp(`(?<![\\w$])${d(q)}(?![\\w$])`).test(B)&&b.add(q)}return P.filter(M=>b.has(M))})(),se=d=>[d,...nt(c,d)],$e=d=>`load: () => loadChain([${se(d).map(b=>`() => import('./comp-${b}.client.js')`).join(", ")}])`,Ie=d=>`{ ${$e(d)} }`,Se=d=>Tt(c,m,d),fe=m.map((d,b)=>{if(!S.has(b))return"";if(c[b].isMiddleware)return`import * as middlewareMod from './comp-${b}.ssr.js';`;if(c[b].isApi){let ye=(m[b].apiMethods??[]).map(be=>`${be} as ${be}_${b}`).join(", ");return ye?`import { ${ye} } from './comp-${b}.ssr.js';`:`import './comp-${b}.ssr.js';`}let M=!c[b].isLayout&&!c[b].isNotFound,q=(M?m[b].actionNames:[]).map(K=>`${K} as ${K}_${b}`).join(", "),L=M&&m[b].guardName?`beforeAction as beforeAction_${b}`:"",I=[q,L].filter(Boolean).join(", ");return I?`import { render as render_${b}, ${I} } from './comp-${b}.ssr.js';`:`import { render as render_${b} } from './comp-${b}.ssr.js';`}).join(`
265
+ `),Re=c.map((d,b)=>({info:d,i:b})).filter(({info:d})=>d.isNotFound).map(({info:d,i:b})=>{let M=_.relative(_.join(t,"src","pages"),d.filePath).replace(/\\/g,"/"),B=_.posix.dirname(M),q=B==="."?"/":"/"+B,L=[];gn(c,m,b)&&L.push("shell: false"),Tt(c,m,b)&&L.push("csr: false");let I=L.length?`, { ${L.join(", ")} }`:"";return{prefix:q,render:X(b),flags:I}}).sort((d,b)=>b.prefix.length-d.prefix.length),qe=`[
266
+ ${Re.map(d=>` ['${d.prefix}', ${d.render}${d.flags}],`).join(`
267
+ `)}
268
+ ]`,Fe=c.findIndex(d=>d.isError),De=Fe>=0?X(Fe):"null",Ge=Fe>=0?Tt(c,m,Fe):!1,Mt=c.findIndex(d=>d.isMiddleware),ht=j.map(({info:d,i:b})=>{let M=m[b].actionNames.map(be=>`${be}: ${be}_${b}`).join(", ");if(m[b].csr===!1&&m[b].needsClient)throw new T("E-EXPORT",`${d.filePath}: csr = false but this route needs the client bundle (${(m[b].clientReasons??["needs the client"]).join(" + ")}).`,{file:d.filePath,hint:"remove csr = false (the compiler decides zero-JS by itself), or remove the client-only code listed above"});if(m[b].csr===!1){let be=nt(c,b).find(Je=>m[Je].needsClient);if(be!==void 0)throw new T("E-EXPORT",`${d.filePath}: csr = false cannot ship under ${c[be].filePath} - the layout needs the client bundle (event wiring, onMount/onCleanup, refresh() or a server action).`,{file:d.filePath,hint:"a layout needing the runtime bundles every route under it - drop csr = false here, or make the layout content-only"})}let B=Se(b)?", csr: false":"",q=gn(c,m,b)?", shell: false":"",L=m[b].buffer?", buffer: true":"",I=m[b].controlSignal?", signal: true":"",K=m[b].guardName?`, guard: beforeAction_${b}`:"",ye=V&&!Se(b)?`, slice: '${ie(d.pattern)}'`:"";return`{ pattern: '${d.pattern}', path: '${d.routePath}', render: ${X(b)}, actions: ${M?`{ ${M} }`:"null"}${K}${B}${q}${L}${I}${ye} }`}).join(`,
269
+ `),Ae=m.some(d=>d.usesRosefcAuth),pt=m.some(d=>/\$(?:udp|tcp|listen|mqtt)\s*\(/.test((d.ssr||"")+(d.client||"")+(d.api||""))),Ke=m.some(d=>/\$websocket\s*\(/.test((d.ssr||"")+(d.client||"")+(d.api||""))),gt=`
270
+ ${fe}
271
+ import { renderMarkdown } from './content-md.ts';
272
+ ${Ae?"import crypto from 'node:crypto';":"// no route references __rosefcAuth: the node:crypto auth helpers are omitted, keeping the bundle edge-loadable"}
273
+ ${pt?`import * as __rosefcDgram from 'node:dgram';
274
+ import * as __rosefcNet from 'node:net';`:"// no route opens a network listener ($udp/$tcp/$listen): the node:dgram/node:net imports are omitted, keeping the bundle edge-loadable"}
275
+ ${Ke?`import * as __rosefcHttp from 'node:http';
276
+ import * as __rosefcCrypto from 'node:crypto';`:"// no route opens a WebSocket server ($websocket): the node:http/node:crypto imports are omitted, keeping the bundle edge-loadable"}
277
+ import { setState, persistState, clearRequestState, isolateRender, serializeState, resetRequestContext, installContextStore, setRequestQuery, getRequestQuery, getContext, isLocale, setLocales, localeList, localeDir, setStoreTransport, applyStorePatch, ActionError, StateDelta, setStateDelta, esc, __startNetwork, __stopNetwork, $udp, $tcp, $listen, $websocket, $mqtt } from './runtime.js';
278
+ export { __startNetwork, __stopNetwork };
279
+ ${je.length>0?"import { hooks as __pluginHooks, hasRequestHooks as __hasRequestHooks, hasResponseHooks as __hasResponseHooks } from './plugins.js';":`// no plugin declares a runtime hook, so there is no plugins
280
+ // module to import - the runners below stay no-ops and the servers call them
281
+ // unconditionally (one code path, no flags to keep in sync).
282
+ const __pluginHooks = [];
283
+ const __hasRequestHooks = false;
284
+ const __hasResponseHooks = false;`}
285
+
286
+
287
+ export async function runRequestHooks(ctx) {
288
+ for (const p of __pluginHooks) {
289
+ if (!p.onRequest) continue;
290
+ try {
291
+ const r = await p.onRequest(ctx);
292
+ if (r instanceof Response) return r;
293
+ } catch (err) {
294
+ console.error('Rosefc: plugin', p.name, 'onRequest failed:', err instanceof Error ? err.message : err);
295
+ }
296
+ }
297
+ return null;
298
+ }
299
+
300
+ export async function runResponseHooks(ctx, res) {
301
+ let out = res;
302
+ for (const p of __pluginHooks) {
303
+ if (!p.onResponse) continue;
304
+ try {
305
+ const r = await p.onResponse(ctx, out);
306
+ if (r instanceof Response) out = r;
307
+ } catch (err) {
308
+ console.error('Rosefc: plugin', p.name, 'onResponse failed:', err instanceof Error ? err.message : err);
309
+ }
310
+ }
311
+ return out;
312
+ }
313
+
314
+
315
+ export const hasRequestHooks = __hasRequestHooks;
316
+ export const hasResponseHooks = __hasResponseHooks;
317
+
318
+ // P0-1: the query of the request being rendered, for $query().
319
+ export function setQuery(query) {
320
+ setRequestQuery(query || {});
321
+ }
322
+
323
+
324
+ setLocales(${ee}, '${N}');
325
+
326
+
327
+ // Live store channel: every $store write fans out to the browsers holding an open
328
+ // SSE connection AND (when forked) to sibling workers. The client set lives on
329
+ // globalThis so a dev hot-re-import (a fresh module instance) keeps serving the
330
+ // same live connections. __addStoreClient/__removeStoreClient are called by the
331
+ // host (cli serve worker / devWrap) as SSE connections open and close.
332
+ const __storeClients: Set<any> = (globalThis as any).__rosefc_storeClients || ((globalThis as any).__rosefc_storeClients = new Set());
333
+ function __broadcastStore(name: string, value: unknown): void {
334
+ if (__storeClients.size === 0) return;
335
+ const frame = 'event: store\\ndata: ' + JSON.stringify({ name: name, value: value }) + '\\n\\n';
336
+ for (const res of __storeClients) {
337
+ try { res.write(frame); } catch { __storeClients.delete(res); }
338
+ }
339
+ }
340
+ setStoreTransport((name, value) => {
341
+ __broadcastStore(name, value);
342
+ if (typeof process !== 'undefined' && typeof process.send === 'function') process.send({ type: 'rosefc:store', name, value });
343
+ });
344
+ if (typeof process !== 'undefined' && typeof process.send === 'function') {
345
+ process.on('message', (msg) => {
346
+ if (msg && msg.type === 'rosefc:store') {
347
+ applyStorePatch(msg.name, msg.value);
348
+ __broadcastStore(msg.name, msg.value);
349
+ }
350
+ });
351
+ }
352
+ export function __addStoreClient(res: any): void { __storeClients.add(res); }
353
+ export function __removeStoreClient(res: any): void { __storeClients.delete(res); }
354
+
355
+
356
+ // (the cross-machine seam): the cluster relay above covers ONE machine.
357
+ export function __installStoreTransport(send: (name: string, value: unknown) => void): void {
358
+ // Wrap, not replace: a cross-machine transport (a plugin's LISTEN/NOTIFY bus)
359
+ // still fans out to this machine's live browsers on every patch.
360
+ setStoreTransport((name, value) => { __broadcastStore(name, value); send(name, value); });
361
+ }
362
+ export function __deliverStorePatch(name: string, value: unknown): void {
363
+ applyStorePatch(name, value);
364
+ __broadcastStore(name, value);
365
+ }
366
+
367
+ export { localeList };
368
+ export const defaultLocale = '${N}';
369
+
370
+ // Route params maps, re-exported for the build's prerender step: routePath -> the component's exported params (a static map or a function).
371
+ ${j.filter(({i:d})=>m[d].hasParams).map(({i:d})=>`import * as comp_${d} from './comp-${d}.ssr.js';`).join(`
372
+ `)}
373
+
374
+ export const routeParams = {
375
+ ${j.filter(({info:d,i:b})=>m[b].hasParams).map(({info:d,i:b})=>`'${d.routePath}': comp_${b}.params`).join(`,
376
+ `)}
377
+ };
378
+
379
+ // Routes whose component reads the request context (getContext()), mutates a shared store ($store()), reads the query ($query(), P0-1)
380
+ export const dynamicRoutes = [
381
+ ${j.filter(({i:d})=>m[d].usesContext||m[d].cspNonce||m[d].buffer||m[d].controlSignal||m[d].needsClient).map(({info:d})=>`'${d.routePath}'`).join(`,
382
+ `)}
383
+ ];
384
+
385
+ // Routes that the prerender function should skip (not bake into static files).
386
+ export const prerenderSkipRoutes = [
387
+ ${j.filter(({i:d})=>m[d].usesContext||m[d].cspNonce||m[d].buffer||m[d].controlSignal).map(({info:d})=>`'${d.routePath}'`).join(`,
388
+ `)}
389
+ ];
390
+
391
+ // Which api routes opt into build-time baking (export const prerender = true): routePath -> boolean.
392
+ ${F.filter(({i:d})=>m[d].hasPrerender).map(({i:d})=>`import * as api_${d} from './comp-${d}.ssr.js';`).join(`
393
+ `)}
394
+
395
+ export const apiPrerender = {
396
+ ${F.map(({info:d,i:b})=>`'${d.routePath}': ${m[b].hasPrerender?`api_${b}.prerender === true`:"false"}`).join(`,
397
+ `)}
398
+ };
399
+
400
+
401
+ export const revalidate = [
402
+ ${j.filter(({i:d})=>m[d].revalidate!==void 0&&!m[d].usesContext).map(({info:d,i:b})=>`{ pattern: '${d.pattern}', seconds: ${m[b].revalidate} }`).join(`,
403
+ `)}
404
+ ];
405
+
406
+ // Per-request render memo (export const cache = N): a dynamic route's whole renderPage result is memoized for N seconds.
407
+ // R256: a page that reads getContext() holds per-request state (the middleware
408
+ // put the caller's identity there), so its render must not be memoized: the
409
+ // second request in the window replayed the FIRST request's whole page -
410
+ // another user's context, in the same slot. The revalidate list above
411
+ // already refuses such a page; the memo did not, and now it does too.
412
+ export const routeCaches = [
413
+ ${j.filter(({i:d})=>m[d].cache!==void 0&&!m[d].usesContext).map(({info:d,i:b})=>`{ pattern: '${d.pattern}', seconds: ${m[b].cache} }`).join(`,
414
+ `)}
415
+ ];
416
+
417
+ // Hot-cache key dimensions (export const hotVary = ['x-locale']): the shared
418
+ // server caches key on URL + cookie + accept-language only, so a route whose
419
+ // representation is negotiated on its own private header had one client's
420
+ // bytes replayed to another for a whole TTL (BUG.md AB) - and the app's only
421
+ // exits were a query tag (?l=, ?rv=) or no-store, which switches the cache off
422
+ // for the route entirely. Naming the headers here folds them into the key AND
423
+ // into the warm render that fills it, so every value gets its own entry and
424
+ // the cache keeps working.
425
+ export const routeHotVary = [
426
+ ${[...j,...F].filter(({i:d})=>m[d].hotVary).map(({info:d,i:b})=>`{ pattern: '${d.pattern}', dims: ${JSON.stringify(m[b].hotVary)} }`).join(`,
427
+ `)}
428
+ ];
429
+ export function hotVaryFor(pathname: string): string[] | null {
430
+ for (const r of routeHotVary) if (matchRoute(r.pattern, pathname)) return r.dims;
431
+ return null;
432
+ }
433
+ const __dynCache = new Map();
434
+ export function invalidateRenderCache(): void {
435
+ __dynCache.clear();
436
+ }
437
+
438
+
439
+ // Application KV cache primitive (server-side, per-worker in-memory): a zero-dependency store for expensive computations.
440
+ const __kvStore = new Map<string, { v: unknown; exp: number }>();
441
+ // Content collections: src/content/<coll>/*.md scanned once at build time,
442
+ const contentCollections = ${JSON.stringify(qn(_.join(t,"src","content")))};
443
+ export const kv = {
444
+ get(key: string): unknown {
445
+ const e = __kvStore.get(key);
446
+ if (!e) return undefined;
447
+ if (e.exp < Date.now()) { __kvStore.delete(key); return undefined; }
448
+ return e.v;
449
+ },
450
+ set(key: string, value: unknown, ttlSeconds = 300): void {
451
+ if (__kvStore.size > 1000) {
452
+ const cutoff = Date.now();
453
+ for (const [k, e] of __kvStore) { if (e.exp < cutoff) __kvStore.delete(k); }
454
+ if (__kvStore.size > 2000) __kvStore.clear();
455
+ }
456
+ __kvStore.set(key, { v: value, exp: Date.now() + ttlSeconds * 1000 });
457
+ },
458
+ del(key: string): void { __kvStore.delete(key); },
459
+ has(key: string): boolean {
460
+ const e = __kvStore.get(key);
461
+ return !!e && e.exp >= Date.now();
462
+ },
463
+ };
464
+ globalThis.__rosefcKvApi = { kv, kvMemo: $kv };
465
+ globalThis.__rosefcContent = {
466
+ list: (coll: string, filter?: { tag: string }) => {
467
+ let items = contentCollections[coll] ?? [];
468
+ if (filter?.tag) items = items.filter((e) => ((e.frontmatter.tags as string[] | undefined) ?? []).includes(filter.tag));
469
+ return items.map((e) => ({ slug: e.slug, ...e.frontmatter }));
470
+ },
471
+ rss: (coll: string, opts: { title: string; origin: string; description?: string }) => {
472
+ return buildRss(contentCollections[coll] ?? [], opts);
473
+ },
474
+ get: (coll: string, slug: string, vars?: Record<string, unknown>) => {
475
+ const e = (contentCollections[coll] ?? []).find((x) => x.slug === slug);
476
+ if (!e) return null;
477
+ return { slug: e.slug, ...e.frontmatter, html: renderMarkdown(e.body, vars), toc: e.toc, readingTime: e.readingTime, wordCount: e.wordCount, excerpt: e.excerpt };
478
+ },
479
+ };
480
+
481
+ const v = {
482
+ validate(body: Record<string, unknown>, rules: Record<string, string[]>): { ok: boolean; errors: Record<string, string>; values: Record<string, unknown> } {
483
+ const errors: Record<string, string> = {};
484
+ const values: Record<string, unknown> = {};
485
+ for (const [field, ruleList] of Object.entries(rules)) {
486
+ let val = body[field];
487
+ for (const rule of ruleList) {
488
+ if (val === undefined || val === null || val === "") {
489
+ if (rule === "required") errors[field] = field + " is required";
490
+ else if (rule.startsWith("default:")) val = rule.slice(8);
491
+ continue;
492
+ }
493
+ if (rule === "string") val = String(val);
494
+ else if (rule === "trim") val = String(val).trim();
495
+ else if (rule === "number") {
496
+ const num = Number(val);
497
+ if (Number.isNaN(num)) errors[field] = field + " must be a number";
498
+ else val = num;
499
+ } else if (rule === "email") {
500
+ if (!/^[^s@]+@[^s@]+.[^s@]+$/.test(String(val))) errors[field] = field + " must be a valid email";
501
+ } else if (rule.startsWith("min:")) {
502
+ const min = Number(rule.slice(4));
503
+ if (typeof val === "number" ? val < min : String(val).length < min) errors[field] = field + " must be at least " + min;
504
+ } else if (rule.startsWith("max:")) {
505
+ const max = Number(rule.slice(4));
506
+ if (typeof val === "number" ? val > max : String(val).length > max) errors[field] = field + " must be at most " + max;
507
+ }
508
+ }
509
+ values[field] = val;
510
+ }
511
+ return { ok: Object.keys(errors).length === 0, errors, values };
512
+ },
513
+ };
514
+
515
+ const jobs = {
516
+ _timers: new Map<string, ReturnType<typeof setInterval>>(),
517
+ every(name: string, seconds: number, fn: () => void | Promise<void>): void {
518
+ if (this._timers.has(name)) return;
519
+ const t = setInterval(() => { Promise.resolve(fn()).catch(() => {}); }, seconds * 1000);
520
+ this._timers.set(name, t as any);
521
+ },
522
+ cancel(name: string): void {
523
+ const t = this._timers.get(name);
524
+ if (t) { clearInterval(t); this._timers.delete(name); }
525
+ },
526
+ cancelAll(): void { for (const t of this._timers.values()) clearInterval(t); this._timers.clear(); }
527
+ };
528
+
529
+ function sse(handler: (send: (event: string, data: unknown) => void) => Promise<void> | void): Response {
530
+ const encoder = new TextEncoder();
531
+ const stream = new ReadableStream({
532
+ async start(controller) {
533
+ let closed = false;
534
+ const send = (event: string, data: unknown) => {
535
+ if (closed) return;
536
+ controller.enqueue(encoder.encode("event: " + event + "\\ndata: " + JSON.stringify(data) + "\\n\\n"));
537
+ };
538
+ try {
539
+ await handler(send);
540
+ } finally {
541
+ closed = true;
542
+ try { controller.close(); } catch { }
543
+ }
544
+ },
545
+ });
546
+ return new Response(stream, {
547
+ headers: { "content-type": "text/event-stream; charset=utf-8", "cache-control": "no-cache", "connection": "keep-alive" },
548
+ });
549
+ }
550
+ ${pt?`// The isomorphic runtime's $udp/$tcp reach Node's dgram/net only through these globals; injecting them at server boot is what lets __startNetwork() turn a registered spec into a bound socket.
551
+ (globalThis as any).__rosefc_dgram = __rosefcDgram;
552
+ (globalThis as any).__rosefc_net = __rosefcNet;`:""}
553
+ ${Ke?`// The isomorphic runtime's $websocket performs the RFC 6455 handshake (sha1) on a node:http upgrade socket; both reach it only through these globals.
554
+ (globalThis as any).__rosefc_http = __rosefcHttp;
555
+ (globalThis as any).__rosefc_crypto = __rosefcCrypto;`:""}
556
+ globalThis.__rosefcExtras = { v, jobs, sse, udp: $udp, tcp: $tcp, listen: $listen, websocket: $websocket, mqtt: $mqtt };
557
+ ${Ae?`
558
+ const auth = {
559
+ hashPassword(password: string): string {
560
+ const salt = crypto.randomBytes(16).toString("hex");
561
+ const hash = crypto.scryptSync(password, salt, 32).toString("hex");
562
+ return salt + ":" + hash;
563
+ },
564
+ verifyPassword(password: string, stored: string): boolean {
565
+ const [salt, hash] = stored.split(":");
566
+ if (!salt || !hash) return false;
567
+ return crypto.timingSafeEqual(Buffer.from(hash, "hex"), crypto.scryptSync(password, salt, 32));
568
+ },
569
+ signSession(data: Record<string, unknown>, secret: string, ttlSeconds = 86400): string {
570
+ const payload = Buffer.from(JSON.stringify({ ...data, exp: Date.now() + ttlSeconds * 1000 })).toString("base64url");
571
+ const sig = crypto.createHmac("sha256", secret).update(payload).digest("base64url");
572
+ return payload + "." + sig;
573
+ },
574
+ verifySession<T = Record<string, unknown>>(token: string, secret: string): T | null {
575
+ const dot = token.lastIndexOf(".");
576
+ if (dot < 0) return null;
577
+ const payload = token.slice(0, dot);
578
+ const sig = token.slice(dot + 1);
579
+ const expect = crypto.createHmac("sha256", secret).update(payload).digest("base64url");
580
+ try {
581
+ if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expect))) return null;
582
+ } catch { return null; }
583
+ try {
584
+ const data = JSON.parse(Buffer.from(payload, "base64url").toString());
585
+ if (data.exp < Date.now()) return null;
586
+ return data as T;
587
+ } catch { return null; }
588
+ },
589
+ csrfToken(secret: string, sessionId: string): string {
590
+ return crypto.createHmac("sha256", secret).update(sessionId).digest("hex");
591
+ },
592
+ verifyCsrf(token: string, secret: string, sessionId: string): boolean {
593
+ try {
594
+ return crypto.timingSafeEqual(Buffer.from(token), Buffer.from(this.csrfToken(secret, sessionId)));
595
+ } catch { return false; }
596
+ },
597
+ };
598
+ globalThis.__rosefcAuth = auth;
599
+ `:"// __rosefcAuth helpers omitted: no route references them (keeps the bundle free of node:crypto and edge-loadable)"}
600
+
601
+ // Concurrent missers on a cold key share ONE compute through this inflight map - the check-then-set shape alone lets N simultaneous cold readers hammer.
602
+ const __kvInflight = new Map<string, Promise<unknown>>();
603
+ export async function $kv(key: string, compute: () => unknown | Promise<unknown>, ttlSeconds = 300): Promise<unknown> {
604
+ const hit = kv.get(key);
605
+ if (hit !== undefined) return hit;
606
+ let p = __kvInflight.get(key);
607
+ if (!p) {
608
+ p = (async () => {
609
+ const v = await compute();
610
+ if (v !== undefined) kv.set(key, v, ttlSeconds);
611
+ return v;
612
+ })();
613
+ __kvInflight.set(key, p);
614
+ p.finally(() => { __kvInflight.delete(key); }).catch(() => {});
615
+ }
616
+ return p;
617
+ }
618
+ export function isCachedRoute(pathname: string): boolean {
619
+ return routeClass(pathname).cache !== null;
620
+ }
621
+ export function invalidatePath(pathname: string): number {
622
+ let n = 0;
623
+ for (const key of [...__dynCache.keys()]) {
624
+ if (key.startsWith(pathname + '|')) { __dynCache.delete(key); n++; }
625
+ }
626
+ return n;
627
+ }
628
+ // The render memo is a shared store, so its key has to name the whole
629
+ // representation: URL + cookie alone let one visitor's render be replayed to
630
+ // another for the entire memo TTL whenever the route negotiates on a request
631
+ // header - accept-language first (BUG.md AB), then whatever the route itself
632
+ // declared with export const hotVary. dims is the caller-built negotiation
633
+ // fingerprint (accept-language plus the declared headers); it folds in here.
634
+ function __dynKey(pathname: string, cookieHeader: string, search: string, dims: string): string {
635
+ let h = 0x811c9dc5;
636
+ const c = (cookieHeader || '') + '\\u0000' + (dims || '');
637
+ for (let i = 0; i < c.length; i++) {
638
+ h ^= c.charCodeAt(i);
639
+ h = (h * 0x01000193) >>> 0;
640
+ }
641
+ // The query string is part of the cache key: routes like /search?q= or /archives?year= render different documents per query.
642
+ return pathname + '|' + (search || '') + '|' + h.toString(16);
643
+ }
644
+ export function peekRenderCache(pathname: string, cookieHeader: string, search = '', dims = ''): ReturnType<typeof renderPage> | null {
645
+ const cfg = routeClass(pathname).cache;
646
+ if (!cfg) return null;
647
+ const hit = __dynCache.get(__dynKey(pathname, cookieHeader, search, dims));
648
+ return hit && hit.expires > Date.now() ? hit.page : null;
649
+ }
650
+ // NOTE (R74): this memo caches renderPage's RETURN VALUE - pure HTML/state, NO
651
+ // set-cookie header (see the { html, state, head, status, ... } object at
652
+ // compiler/index.ts:5756). Set-Cookie is read only at the exit layer from the
653
+ // full Response (R57 list-header fix) and guarded at fillHot/refetchHot in
654
+ // R60, NOT here - there is nothing to guard in this layer. Do NOT add a
655
+ // set-cookie guard to this memo.
656
+ export async function renderPageCached(pathname: string, cookieHeader: string, search = '', dims = ''): Promise<ReturnType<typeof renderPage>> {
657
+ const cfg = routeClass(pathname).cache;
658
+ if (!cfg) return renderPage(pathname);
659
+ const key = __dynKey(pathname, cookieHeader, search, dims);
660
+ const hit = __dynCache.get(key);
661
+ if (hit && hit.expires > Date.now()) {
662
+ __dynCache.delete(key);
663
+ __dynCache.set(key, hit);
664
+ return hit.page;
665
+ }
666
+ // Stale-while-revalidate: an EXPIRED entry still answers instantly while one background render refreshes it - the TTL boundary never spikes.
667
+ if (hit && !hit.refreshing) {
668
+ hit.refreshing = true;
669
+ // BUG.md A: this refresh runs AFTER the live response returned, so the module-global
670
+ // requestQuery may already belong to a later request. Re-seed it from THIS entry's
671
+ // search and restore the snapshot afterward, so the cached refresh reflects this query.
672
+ const __q: Record<string, string> = {};
673
+ new URLSearchParams(search || '').forEach((v, k) => { __q[k] = v; });
674
+ const __prevQ = getRequestQuery();
675
+ setRequestQuery(__q);
676
+ renderPage(pathname).then((fresh: any) => {
677
+ setRequestQuery(__prevQ);
678
+ if (fresh.status === 200 && !fresh.redirect) {
679
+ __dynCache.set(key, { page: fresh, expires: Date.now() + cfg.seconds * 1000 });
680
+ } else {
681
+ __dynCache.delete(key);
682
+ }
683
+ }).catch(() => { setRequestQuery(__prevQ); __dynCache.delete(key); });
684
+ return hit.page;
685
+ }
686
+ // Miss: render with this request's query. The caller (edge/cli) already seeded
687
+ // requestQuery; re-seed from the key's search so the cached entry stays self-consistent
688
+ // even if a concurrent request overwrote the global during the await.
689
+ const __q0: Record<string, string> = {};
690
+ new URLSearchParams(search || '').forEach((v, k) => { __q0[k] = v; });
691
+ setRequestQuery(__q0);
692
+ const page = await renderPage(pathname);
693
+ if (page.status === 200 && !page.redirect) {
694
+ __dynCache.set(key, { page, expires: Date.now() + cfg.seconds * 1000 });
695
+ if (__dynCache.size > 300) {
696
+ __dynCache.delete(__dynCache.keys().next().value as string);
697
+ }
698
+ }
699
+ return page;
700
+ }
701
+
702
+ // Pages/_middleware.rose: a Web-standard request handler that runs before every render on the server (pages, POSTs, api calls alike).
703
+ export const middleware = ${Mt>=0?"middlewareMod.handle ?? null":"null"};
704
+
705
+ // Routes whose DOCUMENTS ship without the client bundle ( decided by the compiler since #29): HTML + CSS only - no runtime, no state script.
706
+ export const noJsRoutes = [
707
+ ${j.filter(({i:d})=>Se(d)).map(({info:d})=>`'${d.pattern}'`).join(`,
708
+ `)}
709
+ ];
710
+
711
+ export function isNoJs(pathname) {
712
+ return routeClass(pathname).noJs;
713
+ }
714
+
715
+ // P0-2 (bug report): routes that exported "buffer = true".
716
+ export function isBuffered(pathname) {
717
+ return routeClass(pathname).buffered;
718
+ }
719
+
720
+
721
+ export const routeHeaders = [
722
+ ${j.filter(({i:d})=>m[d].headers).map(({info:d,i:b})=>`{ pattern: '${d.pattern}', headers: ${JSON.stringify(m[b].headers)} }`).join(`,
723
+ `)}
724
+ ];
725
+
726
+ export function headersFor(pathname) {
727
+ return routeClass(pathname).headers;
728
+ }
729
+
730
+
731
+ export const cspNonceRoutes = [
732
+ ${j.filter(({i:d})=>m[d].cspNonce).map(({info:d})=>`'${d.routePath}'`).join(`,
733
+ `)}
734
+ ];
735
+
736
+ export function cspNonce(pathname) {
737
+ return routeClass(pathname).nonce;
738
+ }
739
+
740
+ // A Web-standard Request from whatever the host provides: the edge adapter passes one already; the Node server passes its IncomingMessage (plus).
741
+ function toWebRequest(raw, form) {
742
+ if (raw instanceof Request) return raw;
743
+ const init = { method: raw.method || 'GET', headers: new Headers(raw.headers || {}) };
744
+ if (form) init.body = form;
745
+ let u = raw.url || '/';
746
+ if (u.startsWith('http://') || u.startsWith('https://')) {
747
+ try { const p = new URL(u); u = p.pathname + p.search; } catch { u = '/'; }
748
+ }
749
+ return new Request('http://' + (raw.headers?.host || 'localhost') + u, init);
750
+ }
751
+
752
+
753
+ export async function runMiddleware(rawReq, form) {
754
+ resetRequestContext();
755
+ if (!middleware || !rawReq) return null;
756
+ const res = await middleware(toWebRequest(rawReq, form));
757
+ return res || null;
758
+ }
759
+
760
+ const routes = [
761
+ ${ht}
762
+ ];
763
+
764
+ // API routes (pages/api/*.rose): pattern -> HTTP-method handlers. They never render HTML and never reach the client bundle.
765
+ const apiRoutes = [
766
+ ${F.map(({info:d,i:b})=>{let M=(m[b].apiMethods??[]).map(B=>`${B}: ${B}_${b}`).join(", ");return`{ pattern: '${d.pattern}', path: '${d.routePath}', handlers: { ${M} } }`}).join(`,
767
+ `)}
768
+ ];
769
+
770
+ // Not-found pages, deepest segment first: the root 404.rose ('/') and any
771
+ // pages/<seg>/_notfound.rose, each already composed with its layout chain.
772
+ // notFoundFor picks the nearest one up the path - an /admin miss answers
773
+ // the admin 404, a public miss the site's - and notFoundPage is the whole
774
+ // answer (real 404 status, or the built-in plain 404 when the app has none).
775
+ const notFoundRoutes = ${qe};
776
+ const notFoundFor = (pathname) => {
777
+ for (const [prefix, render] of notFoundRoutes) {
778
+ if (prefix === '/' || pathname === prefix || pathname.startsWith(prefix + '/')) return render;
779
+ }
780
+ return null;
781
+ };
782
+
783
+ const notFoundFlags = (pathname) => {
784
+ for (const [prefix, render, flags] of notFoundRoutes) {
785
+ if (prefix === '/' || pathname === prefix || pathname.startsWith(prefix + '/')) return flags || null;
786
+ }
787
+ return null;
788
+ };
789
+ const notFoundPage = async (pathname) => {
790
+ const nf = notFoundFor(pathname);
791
+ if (nf) {
792
+ const flags = notFoundFlags(pathname) || {};
793
+ // A zero-JS not-found document carries no state script (the shell drops it)
794
+ const noJs = flags.csr === false;
795
+ const page = await renderFallback(pathname, nf, noJs);
796
+ // __notFound stamps the document so the client boot paints THIS route instead of re-rendering the matched one: a catch-all whose resolver threw.
797
+ return { ...page, ...flags, status: 404, state: noJs ? '{}' : JSON.stringify({ __notFound: true, ...JSON.parse(page.state) }) };
798
+ }
799
+ return { html: '<h1>404</h1><p>Page not found</p>', state: JSON.stringify({ __route: pathname, __notFound: true }), head: [], status: 404, ...docAttrs(pathname) };
800
+ };
801
+
802
+
803
+ const errorPage = ${De};
804
+
805
+
806
+ export function docAttrs(pathname) {
807
+ const c = routeClass(pathname);
808
+ return { lang: c.lang, dir: c.dir };
809
+ }
810
+
811
+ // Paint a fallback page (404/500) and serialize its state.
812
+ async function renderFallback(pathname, render, noJs = false) {
813
+ // Split mode: the not-found entry's render is a loader object \u95B3?resolve it through getRender (which memoizes the composed function) exactly like.
814
+ let fn = render;
815
+ if (typeof fn !== 'function' && fn && typeof fn.load === 'function') {
816
+
817
+ fn = (await fn.load()).render;
818
+ }
819
+ const { html, head } = extractHead(await fn([], ''));
820
+ const state = noJs ? '{}' : JSON.stringify({ __route: pathname, ...JSON.parse(serializeState()) });
821
+ return { html, state, head, ...docAttrs(pathname) };
822
+ }
823
+
824
+ export function matchRoute(pattern, pathname) {
825
+ // Q0 (bug report): one canonical URL per route.
826
+ pathname = pathname.replace(/\\/+$/, '') || '/';
827
+ const patternParts = pattern.split('/');
828
+ const pathParts = pathname.split('/');
829
+
830
+ const last = patternParts[patternParts.length - 1];
831
+ if (last && (last.startsWith('*') || last.startsWith('**'))) {
832
+ const fixed = patternParts.slice(0, -1);
833
+ if (pathParts.length < fixed.length) return false;
834
+ if (last.startsWith('*') && !last.startsWith('**') && pathParts.length === fixed.length) return false;
835
+ for (let i = 0; i < fixed.length; i++) {
836
+ if (fixed[i].startsWith(':')) continue;
837
+ if (fixed[i] !== pathParts[i]) return false;
838
+ }
839
+ return true;
840
+ }
841
+ if (patternParts.length !== pathParts.length) return false;
842
+ for (let i = 0; i < patternParts.length; i++) {
843
+ if (patternParts[i].startsWith(':')) continue;
844
+ if (patternParts[i] !== pathParts[i]) return false;
845
+ }
846
+ return true;
847
+ }
848
+
849
+ // Every predicate the servers ask before a render - canStream, isNoJs, isBuffered, shellOff, cspNonce, headersFor, docAttrs.
850
+ function routeClass(pathname) {
851
+ let c = __routeClass.get(pathname);
852
+ if (c) return c;
853
+ let route = null;
854
+ let stream = false;
855
+ let buffered = false;
856
+ let shell = false;
857
+ let lang = defaultLocale;
858
+ let dir = localeDir(defaultLocale);
859
+ let first = true;
860
+ for (const r of routes) {
861
+ if (!matchRoute(r.pattern, pathname)) continue;
862
+ if (route === null) route = r;
863
+ if (r.shell === false) shell = true;
864
+ if (r.buffer || r.signal) buffered = true;
865
+ const langIdx = r.pattern.split('/').indexOf(':lang');
866
+ if (langIdx < 0) {
867
+ stream = true;
868
+ } else if (isLocale(pathname.split('/')[langIdx])) {
869
+ stream = true;
870
+ // docAttrs answers from the FIRST matching route alone: its locale, or
871
+ if (first) {
872
+ const l = pathname.split('/')[langIdx];
873
+ lang = l;
874
+ dir = localeDir(l);
875
+ }
876
+ }
877
+ first = false;
878
+ }
879
+ let noJs = false;
880
+ for (const p of noJsRoutes) if (matchRoute(p, pathname)) { noJs = true; break; }
881
+ let nonce = false;
882
+ for (const p of cspNonceRoutes) if (matchRoute(p, pathname)) { nonce = true; break; }
883
+ let headers = null;
884
+ for (const r of routeHeaders) if (matchRoute(r.pattern, pathname)) { headers = r.headers; break; }
885
+ let cache = null;
886
+ for (const r of routeCaches) if (matchRoute(r.pattern, pathname)) { cache = r; break; }
887
+ c = { route, stream, buffered, shell, noJs, nonce, headers, cache, lang, dir, slice: route ? (route.slice ?? null) : null };
888
+ if (__routeClass.size >= 2000) {
889
+ const oldest = __routeClass.keys().next().value;
890
+ if (oldest !== undefined) __routeClass.delete(oldest);
891
+ }
892
+ __routeClass.set(pathname, c);
893
+ return c;
894
+ }
895
+ const __routeClass = new Map();
896
+
897
+ // Sliced inline: which dist/slices/<key>.js this pathname's document inlines.
898
+ // null for a path that matches no route (the 404 document inlines the
899
+ // runtime-only core) and for a zero-JS route (no script at all). The CLI and
900
+ // the edge adapter ask this instead of re-deriving pattern -> file; the
901
+ // export's existence is also how the edge adapter detects sliced mode.
902
+ ${V?`export function sliceKeyFor(pathname) {
903
+ return routeClass(pathname).slice;
904
+ }`:"// inline/split mode: no per-route bundle files exist"}
905
+
906
+ // Head blocks (one per component in the route chain) are pulled out of the page html: the shell injects them into <head>.
907
+ function extractHead(rendered) {
908
+ const head = [];
909
+ const html = rendered.replace(/<!--\u27E6h:(\\d+)\u27E7-->([\\s\\S]*?)<!--\u27E6\\/h:\\1\u27E7-->/g, (_, id, content) => {
910
+ head.push(content);
911
+ return '<!--\u27E6h:' + id + '\u27E7--><!--\u27E6/h:' + id + '\u27E7-->';
912
+ });
913
+ return { html, head };
914
+ }
915
+
916
+ // Form: the submitted FormData of a progressive-enhancement POST.
917
+ export async function renderPage(pathname, form, options) {
918
+ // Renders DO overlap in one process: prod-server warms every route in the background at startup.
919
+ return isolateRender(() => renderPageIsolated(pathname, form, options));
920
+ }
921
+
922
+ async function renderPageIsolated(pathname, form, options) {
923
+ clearRequestState();
924
+ // Cold-start readiness gate (Oboext #8): await the app's published DB-ready promise before any $data() read.
925
+ const appReady = globalThis.__rosefcAppReady;
926
+ if (appReady) await appReady;
927
+ const route = routeClass(pathname).route;
928
+ if (route) {
929
+ const patternParts = route.pattern.split('/');
930
+ const pathParts = pathname.split('/');
931
+ for (let i = 0; i < patternParts.length; i++) {
932
+ const seg = patternParts[i];
933
+ if (seg.startsWith(':')) setState(seg.slice(1), pathParts[i]);
934
+
935
+ else if (seg.startsWith('*')) setState(seg.replace(/^\\*+/, ''), pathParts.slice(i));
936
+ }
937
+ // I18n: a [lang] segment naming no dictionary is a 404 - the URL is the contract.
938
+ const langIdx = patternParts.indexOf(':lang');
939
+ if (langIdx >= 0 && !isLocale(pathParts[langIdx])) {
940
+
941
+ return await notFoundPage(pathname);
942
+ }
943
+
944
+ const docLang = langIdx >= 0 ? pathParts[langIdx] : defaultLocale;
945
+ // The action dispatch. The page's guard (exported beforeAction) runs FIRST and vetoes with an ActionError - the action-level permission check.
946
+ let actionStatus = 0;
947
+ if (form && route.actions) {
948
+ const actionName = form.get('__action') || 'action';
949
+ const fn = route.actions[actionName];
950
+ if (fn) {
951
+ try {
952
+ if (route.guard) await route.guard(actionName, form);
953
+ const patch = await fn(form);
954
+ if (patch && typeof patch === 'object') {
955
+ for (const key of Object.keys(patch)) {
956
+ const v = patch[key];
957
+ // An incremental patch is RECORDED, not applied: the render's own state declarations apply.
958
+ if (v instanceof StateDelta) setStateDelta(key, v);
959
+ else setState(key, v);
960
+ }
961
+ }
962
+ } catch (err) {
963
+ if (err instanceof ActionError) {
964
+ setState('actionError', { action: actionName, message: err.message, code: err.code, field: err.field });
965
+ actionStatus = err.code;
966
+ } else if (err && err.__rosefc === 'redirect') {
967
+
968
+ return { redirect: err.path, status: err.status ?? 303, ...docAttrs(pathname) };
969
+ } else if (err && err.__rosefc === 'notFound') {
970
+
971
+ return await notFoundPage(pathname);
972
+ } else {
973
+ throw err;
974
+ }
975
+ }
976
+ }
977
+ }
978
+ let rendered;
979
+ try {
980
+ rendered = extractHead(await route.render([], ''));
981
+ } catch (err) {
982
+ // The control-flow pair: redirect() and notFound() are THROWN from inside the render (a $data body resolving a slug that no longer exists).
983
+ const signal = err && err.__rosefc;
984
+ if (signal === 'redirect') {
985
+ return { redirect: err.path, status: err.status ?? 307, ...docAttrs(pathname) };
986
+ }
987
+ if (signal === 'notFound') {
988
+ return await notFoundPage(pathname);
989
+ }
990
+
991
+ console.error('Rosefc: render failed for', pathname, err instanceof Error ? err.message : err);
992
+ // F10: in dev the response body carries the real error \u95B3?message, file:line and the fix hint.
993
+ let devDetail = '';
994
+ if (process.env.ROSEFC_DEV === '1' && err) {
995
+ const msg = esc(err instanceof Error ? err.message : String(err));
996
+ const file = esc(String(err.file || ''));
997
+ const line = err.line != null ? esc(String(err.line)) : '';
998
+ const hint = esc(String(err.hint || ''));
999
+ const stack = esc(err instanceof Error ? (err.stack || '').split('\\n').slice(1, 7).join('\\n') : '');
1000
+ devDetail = '<div style="margin:24px auto;max-width:860px;font:13px/1.6 ui-monospace,monospace;background:#1b1b1f;color:#e6e6ea;border:1px solid #3a3a42;border-radius:10px;padding:20px 24px;text-align:left;white-space:pre-wrap;word-break:break-word">'
1001
+ + '<div style="font:600 15px/1.4 system-ui,sans-serif;color:#ff8b8b">Render failed: ' + esc(pathname) + '</div>'
1002
+ + '<div style="margin:10px 0 0;color:#ffd479">' + msg + '</div>'
1003
+ + (file ? '<div style="margin:6px 0 0;color:#9ad1ff">' + file + (line ? ':' + line : '') + '</div>' : '')
1004
+ + (hint ? '<div style="margin:10px 0 0;color:#9fe8b0">Fix: ' + hint + '</div>' : '')
1005
+ + (stack ? '<pre style="margin:12px 0 0;color:#8f8f9a">' + stack + '</pre>' : '')
1006
+ + '</div>';
1007
+ }
1008
+ if (errorPage) {
1009
+ // ErrorNoJs is a compile-time constant (see the errorNoJs declaration beside errorRender): a zero-JS site's 500 carries no state script.
1010
+ const fb = await renderFallback(pathname, errorPage, ${Ge});
1011
+ return { ...fb, html: fb.html + devDetail, status: 500${Ge?", csr: false":""} };
1012
+ }
1013
+ return { html: '<h1>500</h1><p>Something went wrong rendering this page.</p>' + devDetail, state: '{}', head: [], status: 500, ...docAttrs(pathname) };
1014
+ }
1015
+ // __route tells the bootstrap which route this document was rendered for.
1016
+ // A zero-JS route ships no state script - but a NATIVE client asking for the
1017
+ // JSON half of the render (the /__rosefc/data channel) still needs the values
1018
+ // its $data produced, so the withState option asks for them explicitly.
1019
+ const noJs = route.csr === false && !(options && options.withState);
1020
+ let state = '{}';
1021
+ if (!noJs || actionStatus !== 0) {
1022
+ const s = serializeState();
1023
+ state = '{"__route":' + JSON.stringify(pathname) + (s.length > 2 ? ',' + s.slice(1) : '}');
1024
+ }
1025
+ // Csr ( auto since #29): false when the compiler found nothing in the route's chain that needs the client (or the route asserted csr = false) .
1026
+ return { html: rendered.html, state, head: rendered.head, status: actionStatus || 200, csr: route.csr !== false, shell: route.shell !== false, lang: docLang, dir: localeDir(docLang) };
1027
+ }
1028
+ return await notFoundPage(pathname);
1029
+ }
1030
+
1031
+ // Would renderPageStream handle this path? (matched route = stream, anything
1032
+ export function canStream(pathname) {
1033
+ return routeClass(pathname).stream;
1034
+ }
1035
+
1036
+
1037
+ export function shellOff(pathname) {
1038
+ return routeClass(pathname).shell;
1039
+ }
1040
+
1041
+ // === API routes === The /api namespace answers JSON, never HTML: an API client that hits an unknown path must not receive the SPA shell.
1042
+ export function isApi(pathname) {
1043
+ return pathname === '/api' || pathname.startsWith('/api/');
1044
+ }
1045
+
1046
+ function toResponse(out) {
1047
+ if (out instanceof Response) return out;
1048
+ if (out === undefined || out === null) return new Response(null, { status: 204 });
1049
+ return new Response(JSON.stringify(out), {
1050
+ status: 200,
1051
+ headers: { 'content-type': 'application/json' },
1052
+ });
1053
+ }
1054
+
1055
+ export async function handleApi(method, pathname, request) {
1056
+ for (const route of apiRoutes) {
1057
+ if (matchRoute(route.pattern, pathname)) {
1058
+ // HEAD answers like GET with the body dropped by the host, which is the
1059
+ // HTTP contract every static server here already honors. It used to 405
1060
+ // on every route that only exported GET - the one method a health
1061
+ // check, an uptime monitor or a head-of-request probe actually sends.
1062
+ const verb = method === 'HEAD' && !route.handlers.HEAD ? 'GET' : method;
1063
+ // hasOwn, not a bare index: the handlers table is an object literal, so a
1064
+ // request line naming constructor, toString or valueOf used to find
1065
+ // Object.prototype's member and CALL it as the handler - a 200 whose
1066
+ // body was the prototype's return value, or a TypeError from the
1067
+ // dispatch. Not reachable through Node's HTTP parser (it rejects those
1068
+ // methods), but the edge adapter and rosefc/test pass the method through.
1069
+ const fn = Object.prototype.hasOwnProperty.call(route.handlers, verb) ? route.handlers[verb] : null;
1070
+ if (!fn) {
1071
+ return new Response(JSON.stringify({ error: 'method not allowed' }), {
1072
+ status: 405,
1073
+ headers: { 'content-type': 'application/json', allow: Object.keys(route.handlers).join(', ') },
1074
+ });
1075
+ }
1076
+ // A dynamic segment's value reaches the handler through the request
1077
+ // context: getContext().params.id for pages/api/posts/[id].rose. The
1078
+ // pattern MATCHED before, but the captured value went nowhere - the
1079
+ // docs promised "dynamic segments work", and a handler that cannot
1080
+ // read its own param is a 200-shaped lie. The bag is per-request
1081
+ // (the servers run each request in its own context scope), so this
1082
+ // cannot leak across requests.
1083
+ try {
1084
+ const patternParts = route.pattern.split('/');
1085
+ const pathParts = pathname.split('/');
1086
+ const params = {};
1087
+ for (let i = 0; i < patternParts.length && i < pathParts.length; i++) {
1088
+ const seg = patternParts[i];
1089
+ if (seg.startsWith(':')) params[seg.slice(1)] = decodeURIComponent(pathParts[i]);
1090
+ else if (seg.startsWith('*')) params[seg.replace(/^\\*+/, '')] = pathParts.slice(i).map(decodeURIComponent);
1091
+ }
1092
+ // The bag must describe THIS request: a host without a context store
1093
+ // (the edge adapter, rosefc/test) reuses one module-level object, so a
1094
+ // static route used to inherit the previous request's params - a
1095
+ // /api/posts/42 call made /api/health report an id it was never sent.
1096
+ // Assigning (rather than only when non-empty) drops the stale value.
1097
+ getContext().params = params;
1098
+ getContext().url = pathname + (new URL(request.url).search || '');
1099
+ } catch { /* a malformed segment must not kill the dispatch */ }
1100
+ try {
1101
+ // HEAD runs the GET handler and returns its Response untouched: the
1102
+ // host drops the body, and the headers a HEAD must report (the app's
1103
+ // own, plus the framework ETag the exit derives from the bytes) stay
1104
+ // exactly those of the GET. Returning an empty body here instead would
1105
+ // hand the caller a response with no validator at all.
1106
+ return toResponse(await fn(request));
1107
+ } catch (err) {
1108
+
1109
+ const signal = err && err.__rosefc;
1110
+ if (signal === 'redirect') {
1111
+ return new Response(JSON.stringify({ error: 'redirect', location: err.path }), {
1112
+ status: err.status ?? 307,
1113
+ headers: { 'content-type': 'application/json', location: err.path },
1114
+ });
1115
+ }
1116
+ if (signal === 'notFound') {
1117
+ return new Response(JSON.stringify({ error: 'not found' }), {
1118
+ status: 404,
1119
+ headers: { 'content-type': 'application/json' },
1120
+ });
1121
+ }
1122
+ throw err;
1123
+ }
1124
+ }
1125
+ }
1126
+ return new Response(JSON.stringify({ error: 'not found' }), {
1127
+ status: 404,
1128
+ headers: { 'content-type': 'application/json' },
1129
+ });
1130
+ }
1131
+
1132
+ // === Streaming SSR === The static shell (doctype, <head>, body + container open) flushes BEFORE the - possibly slow - render completes: the first byte.
1133
+ export async function renderPageStream(pathname, write, shellOpen, clientTag) {
1134
+ // Isolated for the same reason as renderPage: a streaming render awaits inside route.render()
1135
+ return isolateRender(() => renderPageStreamIsolated(pathname, write, shellOpen, clientTag));
1136
+ }
1137
+
1138
+ async function renderPageStreamIsolated(pathname, write, shellOpen, clientTag) {
1139
+ clearRequestState();
1140
+ // Cold-start readiness gate (Oboext #8): same contract as renderPage \u95B3?await the app's published DB-ready promise before streaming the shell.
1141
+ const appReady = globalThis.__rosefcAppReady;
1142
+ if (appReady) await appReady;
1143
+ const route = routeClass(pathname).route;
1144
+ if (route) {
1145
+ const patternParts = route.pattern.split('/');
1146
+ const pathParts = pathname.split('/');
1147
+ for (let i = 0; i < patternParts.length; i++) {
1148
+ const seg = patternParts[i];
1149
+ if (seg.startsWith(':')) setState(seg.slice(1), pathParts[i]);
1150
+
1151
+ else if (seg.startsWith('*')) setState(seg.replace(/^\\*+/, ''), pathParts.slice(i));
1152
+ }
1153
+ // i18n: an unknown locale must 404 BEFORE the shell flushes - a
1154
+ const langIdx = patternParts.indexOf(':lang');
1155
+ if (langIdx >= 0 && !isLocale(pathParts[langIdx])) return 404;
1156
+ write(shellOpen);
1157
+ let html;
1158
+ try {
1159
+ // nonce routes: an un-nonced inline <style> would be CSP-blocked, so strip to markers (applyHead re-injects under the nonce). Otherwise keep the head content in the streamed body so page/layout <style> applies on first paint (no FOUC) and no-JS routes stay styled.
1160
+ html = routeClass(pathname).nonce ? extractHead(await route.render([], '')).html : await route.render([], '');
1161
+ } catch (err) {
1162
+ console.error('Rosefc: render failed for', pathname, err instanceof Error ? err.message : err);
1163
+ // F10: dev carries the real error in the body here too \u95B3?the shell
1164
+ let devDetail = '';
1165
+ if (process.env.ROSEFC_DEV === '1' && err) {
1166
+ const msg = esc(err instanceof Error ? err.message : String(err));
1167
+ const file = esc(String(err.file || ''));
1168
+ const line = err.line != null ? esc(String(err.line)) : '';
1169
+ const hint = esc(String(err.hint || ''));
1170
+ const stack = esc(err instanceof Error ? (err.stack || '').split('\\n').slice(1, 7).join('\\n') : '');
1171
+ devDetail = '<div style="margin:24px auto;max-width:860px;font:13px/1.6 ui-monospace,monospace;background:#1b1b1f;color:#e6e6ea;border:1px solid #3a3a42;border-radius:10px;padding:20px 24px;text-align:left;white-space:pre-wrap;word-break:break-word">'
1172
+ + '<div style="font:600 15px/1.4 system-ui,sans-serif;color:#ff8b8b">Render failed: ' + esc(pathname) + '</div>'
1173
+ + '<div style="margin:10px 0 0;color:#ffd479">' + msg + '</div>'
1174
+ + (file ? '<div style="margin:6px 0 0;color:#9ad1ff">' + file + (line ? ':' + line : '') + '</div>' : '')
1175
+ + (hint ? '<div style="margin:10px 0 0;color:#9fe8b0">Fix: ' + hint + '</div>' : '')
1176
+ + (stack ? '<pre style="margin:12px 0 0;color:#8f8f9a">' + stack + '</pre>' : '')
1177
+ + '</div>';
1178
+ }
1179
+ html = errorPage ? (routeClass(pathname).nonce ? extractHead(await errorPage([], '')).html : await errorPage([], '')) + devDetail : '<h1>500</h1><p>Something went wrong rendering this page.</p>' + devDetail;
1180
+ }
1181
+ write(html);
1182
+ // Csr: false ( auto since #29): a no-JS route's document ends here - no state script, no inlined bundle.
1183
+ if (route.csr === false) {
1184
+ write('</div>\\n</body>\\n</html>');
1185
+ return 200;
1186
+ }
1187
+ const state = JSON.stringify({ __route: pathname, ...JSON.parse(serializeState()) });
1188
+ // P1-6 (bug report): the JSON data block is embedded in the document.
1189
+ const stateSafe = state.replace(/</g, '\\\\u003c');
1190
+ write('</div>\\n <script type="application/json" id="__rosefc_state">' + stateSafe + '</script>\\n ' + clientTag + '\\n</body>\\n</html>');
1191
+ return 200;
1192
+ }
1193
+ return 404;
1194
+ }
1195
+ // Prevent tree-shaking of invalidateRenderCache (called from prod-server.ts / edge.ts on non-GET writes).
1196
+ void invalidateRenderCache;
1197
+
1198
+ // Same reason, for the per-request context store: prod-server.ts installs an AsyncLocalStorage adapter.
1199
+ export { installContextStore };
1200
+ `;try{let d=[...j,...F].map(({info:ye})=>ye.pattern),b=[...new Set(d)].sort(),M=b.map(ye=>JSON.stringify(ye)).join(" | ")||"'/'",B=ye=>(ye.match(/:[\w]+|\*\*[\w]+|\*[\w]+/g)??[]).map(be=>be.replace(/^[*:]+/,"")),q=b.map(ye=>{let be=B(ye);return be.length?" "+JSON.stringify(ye)+": { "+be.map(Je=>Je+": string | number").join("; ")+` };
1201
+ `:""}).join(""),L=_.join(t,"src",".rosefc");await C.promises.mkdir(L,{recursive:!0});let I=["// GENERATED by rosefc build - do not edit.","export type RoutePath = "+M+";","export const routePatterns = "+JSON.stringify(b)+" as const;","export type RouteParams = {",q,"};","/** Build a URL from a route pattern and its params. */","export function url("," path: RoutePath,"," params: RouteParams[keyof RouteParams] = {} as never,","): string {"," let out = path as string;"," for (const [k, v] of Object.entries(params as Record<string, string | number>)) {"," out = out.replace(new RegExp('[:*]+' + k, 'g'), String(v));"," }"," return out;","}"].join(`
1202
+ `)+`
1203
+ `,K=_.join(L,"routes.ts");try{await C.promises.readFile(K,"utf8")!==I&&await C.promises.writeFile(K,I)}catch{await C.promises.writeFile(K,I)}}catch{}await C.promises.writeFile(_.join(O,"server-entry.js"),gt),await Me;let st=et(_.join(O,"server-entry.js"),{entryPoints:[_.join(O,"server-entry.js")],bundle:!0,outfile:_.join(r,"server.js"),format:"esm",platform:"node",write:!0,...it,...i?{minify:!0,keepNames:!0}:{}},o);st.catch(()=>{});let rt=m.map((d,b)=>({i:b})).filter(({i:d})=>!c[d].isApi&&!c[d].isMiddleware&&S.has(d)).map(({i:d})=>`import { render as render_${d} } from './comp-${d}.client.js';`).join(`
1204
+ `),Zt=ue||V?"":rt,Nt=ue?j.map(({info:d,i:b})=>`{ pattern: '${d.pattern}', ${$e(b)} }`).join(`,
1205
+ `):j.map(({info:d,i:b})=>`{ pattern: '${d.pattern}', render: ${X(b)} }`).join(`,
1206
+ `),mt=d=>`load: () => __navRoute(${JSON.stringify(d)})`,Lt=d=>{let b=d===null?null:new Set(se(d)),M=[V?`import { ${de.join(", ")} } from './runtime.js';`:"",b?m.map((q,L)=>({i:L})).filter(({i:q})=>b.has(q)&&!c[q].isApi&&!c[q].isMiddleware&&S.has(q)).map(({i:q})=>`import { render as render_${q} } from './comp-${q}.client.js';`).join(`
1207
+ `):""].filter(Boolean).join(`
1208
+ `),B=j.map(({info:q,i:L})=>d!==null&&L===d?`{ pattern: '${q.pattern}', render: ${X(L)} }`:`{ pattern: '${q.pattern}', ${mt(q.pattern)} }`).join(`,
1209
+ `);return{imports:M,routes:B}},Oe=`[
1210
+ ${Re.map(d=>` ['${d.prefix}', { load: () => __navNotFound(${JSON.stringify(d.prefix)}) }${d.flags}],`).join(`
1211
+ `)}
1212
+ ]`,wt=Fe>=0?"{ load: () => __navError() }":"null",It=m.find(d=>d.prefetch)?.prefetch??"all",bn=m.find(d=>d.lazyHydration)?.lazyHydration??!1,Ft=m.some(d=>d.vitals===!0),Xt=Ft?`
1213
+
1214
+
1215
+ reportVitals();
1216
+ `:"",Qe=c.some(d=>d.pattern.includes(":lang")),Dt=Qe?`
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+ // (dist/mount.js) renders into a foreign page, whose language and
1223
+
1224
+ const seg = langIdx >= 0 ? pathname.split('/')[langIdx] : '';
1225
+ const known = !seg || isLocale(seg);
1226
+ if (container === document.getElementById('app')) {
1227
+ const docLang = known && seg ? seg : __defLocale;
1228
+ document.documentElement.lang = docLang;
1229
+ const docDir = localeDir(docLang);
1230
+ if (docDir) document.documentElement.setAttribute('dir', docDir);
1231
+ else document.documentElement.removeAttribute('dir');
1232
+ }
1233
+ if (!known) {`:" if (langIdx >= 0 && !isLocale(pathname.split('/')[langIdx])) {",We=d=>`
1234
+ ${d.imports}
1235
+ import { state, setState, resumeState, clearRequestState, resetEffects, wire, isolateStateAsync, restoreState, setRefreshHook, clearMounts, flushMounts, adoptCleanups, handlers, setActionDispatcher, setLocales, setLocalePacks, ensureLocale, isLocale, localeDir, setPrefetchOverride, serializeState, setFxOwner, resetContainerFx, esc, applyStorePatch } from './runtime.js';
1236
+ ${d.publish}
1237
+ ${m.some(b=>b.usesStore)?`
1238
+ // Live store channel: an app that reads a shared $store() keeps one EventSource to
1239
+ // /__rosefc_store. A server-side write ($store.set/update from a network listener,
1240
+ // a job, or an action) is pushed here as an {name,value} patch; applyStorePatch
1241
+ // writes it into the reactive store box, re-running the wire() effects that render
1242
+ // {store.get()} / {#each store.get()}. No store in the app - no connection.
1243
+ if (typeof window !== 'undefined' && typeof EventSource !== 'undefined') {
1244
+ try {
1245
+ var __storeEs = new EventSource('/__rosefc_store');
1246
+ __storeEs.addEventListener('store', function (m) {
1247
+ try { var p = JSON.parse(m.data); applyStorePatch(p.name, p.value); } catch (e) {}
1248
+ });
1249
+ } catch (e) {}
1250
+ }`:""}
1251
+
1252
+ // I18n: the dictionaries baked at build time - the client renders any PRELOADED locale from the bundle.
1253
+ setLocales(${ce}, '${N}');
1254
+ setLocalePacks(${JSON.stringify(U)});
1255
+ ${Qe?`// the default locale, kept beside setLocales' own copy so <html lang> can
1256
+ // follow a route that carries no [lang] segment (a non-i18n page)
1257
+ const __defLocale = '${N}';`:""}
1258
+ ${Ft?`// the app asked for web-vitals. The import is what keeps
1259
+ // reportVitals alive through minification and tree-shaking; the call is one
1260
+ // statement at boot, before the first render.
1261
+ import { reportVitals } from './runtime.js';`:""}
1262
+ // Lazy hydration: when the app opts in (export const lazyHydration = true in
1263
+ // the root _layout.rose), the bootstrap defers the initial wire() to
1264
+ // requestIdleCallback. The flag is set here (module eval runs before the
1265
+ // bootstrap's start() call) so the bootstrap can read it without a second channel.
1266
+ if (typeof window !== 'undefined') window.__rosefcLazy = ${JSON.stringify(bn)};
1267
+ // The two pack doors, re-exported for an app that wants to warm a language before its visitor asks for it (ensureLocale) or to feed a dictionary.
1268
+ export { ensureLocale, loadLocale } from './runtime.js';
1269
+ ${d.prefetchDoor}
1270
+ ${Xt}
1271
+ ${d.nav}
1272
+ const routes = [
1273
+ ${d.routes}
1274
+ ];
1275
+
1276
+ // === Mode B: lazy route chunks === Split mode's registry entries arrive without a render function: loadChain loads the route's module graph (the page).
1277
+ const loadChain = async (loaders) => {
1278
+ const mods = await Promise.all(loaders.map((load) => load()));
1279
+ let expr = (closes, children) => mods[0].render(closes, children);
1280
+ for (let k = 1; k < mods.length; k++) {
1281
+ const inner = expr;
1282
+ const outer = mods[k].render;
1283
+ expr = async (closes, children) => await outer(closes, await inner(closes, children));
1284
+ }
1285
+ return { render: expr };
1286
+ };
1287
+ const getRender = async (route) => {
1288
+ if (typeof route === 'function') return route;
1289
+ // inline mode: the render itself
1290
+ return (route.render ??= (await route.load()).render);
1291
+ };
1292
+
1293
+ // Not-found pages, deepest segment first (the server's table, client half): the root 404.rose ('/') and any pages/<seg>/_notfound.rose.
1294
+ const notFoundRoutes = ${d.notFoundTable};
1295
+ const notFoundFor = (pathname) => {
1296
+ for (const [prefix, render] of notFoundRoutes) {
1297
+ if (prefix === '/' || pathname === prefix || pathname.startsWith(prefix + '/')) return render;
1298
+ }
1299
+ return null;
1300
+ };
1301
+
1302
+ // whose render throws degrades to this instead of failing the response.
1303
+ const errorPage = ${d.errorRender};
1304
+
1305
+ // Paint a fallback page (404/500) into the container, wired like any render.
1306
+ async function paintFallback(container, page, builtin, keepState = false) {
1307
+ if (!keepState) __navReset(container);
1308
+ clearMounts();
1309
+ // a failed render leaves stale mounts behind
1310
+ const render = page ? await getRender(page) : null;
1311
+ if (render) {
1312
+ // a packed locale's dictionary lands before the render
1313
+ const closes = [];
1314
+ await __withOwner(container, async () => {
1315
+
1316
+ const html = await render(closes, '');
1317
+ container.innerHTML = html;
1318
+ wire(container, closes);
1319
+ bindEvents(container);
1320
+ flushMounts();
1321
+ });
1322
+
1323
+ return;
1324
+ }
1325
+ container.innerHTML = builtin;
1326
+ }
1327
+
1328
+
1329
+ export async function startNotFound(container, pathname) {
1330
+ const el = document.getElementById('__rosefc_state');
1331
+ if (el) resumeState(el.textContent);
1332
+ await paintFallback(container, notFoundFor(pathname), '<h1>404</h1><p>Page not found</p>', true);
1333
+ }
1334
+
1335
+ export function matchRoute(pattern, pathname) {
1336
+ // Q0 (bug report): one canonical URL per route.
1337
+ pathname = pathname.replace(/\\/+$/, '') || '/';
1338
+ const patternParts = pattern.split('/');
1339
+ const pathParts = pathname.split('/');
1340
+
1341
+ const last = patternParts[patternParts.length - 1];
1342
+ if (last && (last.startsWith('*') || last.startsWith('**'))) {
1343
+ const fixed = patternParts.slice(0, -1);
1344
+ if (pathParts.length < fixed.length) return false;
1345
+ if (last.startsWith('*') && !last.startsWith('**') && pathParts.length === fixed.length) return false;
1346
+ for (let i = 0; i < fixed.length; i++) {
1347
+ if (fixed[i].startsWith(':')) continue;
1348
+ if (fixed[i] !== pathParts[i]) return false;
1349
+ }
1350
+ return true;
1351
+ }
1352
+ if (patternParts.length !== pathParts.length) return false;
1353
+ for (let i = 0; i < patternParts.length; i++) {
1354
+ if (patternParts[i].startsWith(':')) continue;
1355
+ if (patternParts[i] !== pathParts[i]) return false;
1356
+ }
1357
+ return true;
1358
+ }
1359
+
1360
+ // === Link prefetch === Hover / focus / touch an internal link and the target route renders NOW - $data included - against a throwaway signal map.
1361
+ let prefetchMode = ${JSON.stringify(It)};
1362
+ export function setPrefetchMode(mode) { prefetchMode = mode; }
1363
+ const PREFETCH_BUDGET = 8;
1364
+ const PREFETCH_MAX_CACHED = 4;
1365
+ const prefetchCache = new Map();
1366
+
1367
+ let prefetchQueue = Promise.resolve();
1368
+ let prefetchPending = 0;
1369
+
1370
+
1371
+ async function applyParams(route, pathname) {
1372
+ const patternParts = route.pattern.split('/');
1373
+ const pathParts = pathname.split('/');
1374
+ for (let i = 0; i < patternParts.length; i++) {
1375
+ const seg = patternParts[i];
1376
+ if (seg.startsWith(':')) setState(seg.slice(1), pathParts[i]);
1377
+
1378
+ else if (seg.startsWith('*')) setState(seg.replace(/^\\*+/, ''), pathParts.slice(i));
1379
+ }
1380
+ // streamed response cannot change its status afterwards
1381
+ const langIdx = patternParts.indexOf(':lang');
1382
+ if (langIdx >= 0) await ensureLocale(pathParts[langIdx]);
1383
+ }
1384
+
1385
+
1386
+ function __netOk() {
1387
+ const c = navigator.connection;
1388
+ if (!c) return true;
1389
+ if (c.saveData) return false;
1390
+ const t = c.effectiveType;
1391
+ return t !== 'slow-2g' && t !== '2g';
1392
+ }
1393
+
1394
+ export function prefetch(pathname, source = 'hover') {
1395
+ if (prefetchMode === 'off') return;
1396
+ if (prefetchMode === 'hover' && source !== 'hover') return;
1397
+ if (prefetchMode === 'viewport' && source !== 'viewport') return;
1398
+ if (!__netOk()) return;
1399
+ // save-data / 2g: no bytes before the click
1400
+ if (prefetchCache.has(pathname)) return;
1401
+ if (pathname === location.pathname) return;
1402
+
1403
+ const route = routes.find((r) => matchRoute(r.pattern, pathname));
1404
+ if (!route) return;
1405
+ if (prefetchPending >= PREFETCH_BUDGET) return;
1406
+ // Budget spent: drop it, a later hover retries P0-1: the link may carry a query (/search?q=cats).
1407
+ const qi = pathname.indexOf('?');
1408
+ const qOverride = qi >= 0 ? Object.fromEntries(new URLSearchParams(pathname.slice(qi))) : null;
1409
+ const p = prefetchQueue.then(async () => {
1410
+ try {
1411
+ setPrefetchOverride(qOverride);
1412
+ // The isolated render also captures the onMount callbacks the route queued and the onCleanup disposers it registered: the paint that consumes.
1413
+ const { result, state, mounts, cleanups } = await isolateStateAsync(async () => {
1414
+ await applyParams(route, pathname);
1415
+ const closes = [];
1416
+ const render = await getRender(route);
1417
+ const html = await render(closes, '');
1418
+ return { html, closes };
1419
+ });
1420
+ const entry = { ...result, state, mounts, cleanups };
1421
+ prefetchCache.set(pathname, entry);
1422
+ // Promise -> result evict oldest-first; in-flight promises are never evicted (evicting one would only force a duplicate render)
1423
+ while (prefetchCache.size > PREFETCH_MAX_CACHED) {
1424
+ const oldest = prefetchCache.keys().next().value;
1425
+ if (prefetchCache.get(oldest) instanceof Promise) break;
1426
+ prefetchCache.delete(oldest);
1427
+ }
1428
+ return entry;
1429
+ } catch {
1430
+ prefetchCache.delete(pathname);
1431
+ return null;
1432
+ } finally {
1433
+ setPrefetchOverride(null);
1434
+ prefetchPending--;
1435
+ }
1436
+ });
1437
+ prefetchPending++;
1438
+ prefetchCache.set(pathname, p);
1439
+ prefetchQueue = p;
1440
+ }
1441
+
1442
+ export function prefetchStats() {
1443
+ return { cached: prefetchCache.size, pending: prefetchPending, mode: prefetchMode, network: __netOk() };
1444
+ }
1445
+
1446
+ // One delegated listener per event type on the app container: survives DOM swaps and cloned blocks, so handlers never need re-binding.
1447
+ const DELEGATED = ['click', 'input', 'change', 'submit'];
1448
+ function bindEvents(container) {
1449
+ if (container.__rosefc_bound) return;
1450
+ container.__rosefc_bound = true;
1451
+ for (const ev of DELEGATED) {
1452
+ container.addEventListener(ev, (e) => {
1453
+ const el = e.target.closest('[data-on-' + ev + ']');
1454
+ if (!el || !container.contains(el)) return;
1455
+ const fn = el.getAttribute('data-on-' + ev);
1456
+ if (fn.startsWith('$action:')) return $action(fn.slice(8), e);
1457
+ const h = handlers[fn];
1458
+ if (h) h(e);
1459
+ });
1460
+ }
1461
+ }
1462
+
1463
+ // === Server actions from any event === POST the body to the current route and adopt the response in place: the server runs the selected action.
1464
+ async function postForm(body, container, pathname) {
1465
+
1466
+ const box = container || document.getElementById('app');
1467
+ const route = pathname || location.pathname;
1468
+ const res = await fetch(route, { method: 'POST', body });
1469
+ const html = await res.text();
1470
+ const doc = new DOMParser().parseFromString(html, 'text/html');
1471
+ const next = doc.getElementById('app');
1472
+ const st = doc.getElementById('__rosefc_state');
1473
+ const paint = () => {
1474
+ adopt(box, next ? next.innerHTML : '', st ? st.textContent : '{}', route);
1475
+ };
1476
+ if (document.startViewTransition) document.startViewTransition(paint);
1477
+ else paint();
1478
+ }
1479
+
1480
+ // Call a page's server action by name from any event handler: <button on:click={like}> compiles to $action('like').
1481
+ export async function $action(name, e) {
1482
+ if (e && e.preventDefault) e.preventDefault();
1483
+ // F34: the pending flag is ordinary signal state - {#if $actionPending()}
1484
+ const [__rvPending, __rvSetPending] = state('actionPending', false);
1485
+ __rvSetPending(true);
1486
+ const body = new FormData();
1487
+ body.append('__action', name);
1488
+ // An event inside a mount belongs to that mount - the attribute is kept in step with what is currently mounted.
1489
+ const box = e && e.target && e.target.closest ? e.target.closest('[data-rosefc]') : null;
1490
+ try {
1491
+ return await postForm(body, box || undefined, box ? box.getAttribute('data-rosefc') : undefined);
1492
+ } finally {
1493
+ __rvSetPending(false);
1494
+ }
1495
+ }
1496
+ // F17: hand the dispatcher to the runtime, so wire() can serve a server action bound to a non-delegated event (on:keydown="$action:save") the same way.
1497
+ setActionDispatcher($action);
1498
+
1499
+ export { postForm };
1500
+
1501
+ // The live signal graph as JSON - the same serializeState the zero-hydration resume uses.
1502
+ export { serializeState };
1503
+
1504
+
1505
+ // Initial=true: adopt the SSR DOM (zero hydration) - wire reactive markers to the existing nodes and bind events.
1506
+ function __ownsDoc(container) {
1507
+ return container === document.getElementById('app');
1508
+ }
1509
+ function __navReset(container) {
1510
+ if (__ownsDoc(container)) {
1511
+ resetEffects();
1512
+ clearRequestState();
1513
+ } else {
1514
+ resetContainerFx(container);
1515
+ }
1516
+ }
1517
+ // Attribute everything a render creates (state keys, effects, onCleanups) to
1518
+ async function __withOwner(container, fn) {
1519
+ if (__ownsDoc(container)) return fn();
1520
+ setFxOwner(container);
1521
+ try {
1522
+ return await fn();
1523
+ } finally {
1524
+ setFxOwner(null);
1525
+ }
1526
+ }
1527
+ // View Transition on SPA swaps (B9): the DOM swap rides one cross-fade when the browser supports it; reduced-motion users and environments without.
1528
+ async function __swap(container, html) {
1529
+ const reduce = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
1530
+ if (typeof document.startViewTransition === 'function' && !reduce) {
1531
+ const vt = document.startViewTransition(() => { container.innerHTML = html; });
1532
+ await vt.updateCallbackDone.catch(() => {});
1533
+ } else {
1534
+ container.innerHTML = html;
1535
+ }
1536
+ }
1537
+
1538
+ export async function start(container, pathname, initial) {
1539
+ clearMounts();
1540
+ // stale mounts from a failed render never fire
1541
+ if (initial) {
1542
+ const el = document.getElementById('__rosefc_state');
1543
+ if (el) resumeState(el.textContent);
1544
+ }
1545
+ for (const route of routes) {
1546
+ if (matchRoute(route.pattern, pathname)) {
1547
+ // I18n: an unknown locale paints the 404 page, same as the server (before the prefetch check: a cached entry for a bogus locale is discarded).
1548
+ const langIdx = route.pattern.split('/').indexOf(':lang');
1549
+ ${Dt}
1550
+
1551
+ await paintFallback(container, notFoundFor(pathname), '<h1>404</h1><p>Page not found</p>');
1552
+
1553
+ return;
1554
+ }
1555
+ // Prefetched on hover/focus/touch: the render already ran, so paint its HTML and adopt its signal entries - events then patch the very nodes we.
1556
+ let hit = initial ? undefined : prefetchCache.get(pathname);
1557
+ if (hit && typeof hit.then === 'function') hit = await hit;
1558
+ // in-flight: land it first
1559
+ if (hit) {
1560
+ prefetchCache.delete(pathname);
1561
+
1562
+ __navReset(container);
1563
+ restoreState(hit.state);
1564
+ await __swap(container, hit.html);
1565
+ await __withOwner(container, () => {
1566
+ wire(container, hit.closes);
1567
+ bindEvents(container);
1568
+ hit.mounts.forEach((fn) => fn());
1569
+ adoptCleanups(hit.cleanups);
1570
+ });
1571
+
1572
+ return;
1573
+ }
1574
+ if (!initial) __navReset(container);
1575
+ let broken = false;
1576
+ let signal = null;
1577
+ await __withOwner(container, async () => {
1578
+ await applyParams(route, pathname);
1579
+ const closes = [];
1580
+ let html;
1581
+ try {
1582
+ const render = await getRender(route);
1583
+
1584
+ html = await render(closes, '');
1585
+ } catch (err) {
1586
+
1587
+ if (err && err.__rosefc === 'notFound') { signal = 'notFound'; return; }
1588
+ if (err && err.__rosefc === 'redirect') { signal = err.path; return; }
1589
+
1590
+ console.error('Rosefc: client render failed for', pathname, err instanceof Error ? err.message : err);
1591
+ broken = true;
1592
+ return;
1593
+ }
1594
+ if (!initial) await __swap(container, html);
1595
+ wire(container, closes);
1596
+ bindEvents(container);
1597
+ flushMounts();
1598
+ });
1599
+ if (signal === 'notFound') {
1600
+ if (!initial) { try { location.assign(pathname); return; } catch { } }
1601
+ await paintFallback(container, notFoundFor(pathname), '<h1>404</h1><p>Page not found</p>');
1602
+ return;
1603
+ }
1604
+ if (signal) {
1605
+ location.href = signal;
1606
+ return;
1607
+ }
1608
+ if (broken) {
1609
+ await paintFallback(container, errorPage, '<h1>500</h1><p>Something went wrong rendering this page.</p>');
1610
+ }
1611
+ return;
1612
+ }
1613
+ }
1614
+ // Unmatched route: the nearest not-found page renders (with its head + interactivity) - a segment's _notfound.rose or the root 404.rose - else //.
1615
+ ${Qe?` // the same app-root gate as above - a mount never touches the
1616
+ // host document's language or direction.
1617
+ if (container === document.getElementById('app')) {
1618
+ document.documentElement.lang = __defLocale;
1619
+ document.documentElement.removeAttribute('dir');
1620
+ }`:""}
1621
+ await paintFallback(container, notFoundFor(pathname), '<h1>404</h1><p>Page not found</p>');
1622
+ }
1623
+
1624
+ // Adopt a server-rendered response in place - the JS-enabled half of progressive-enhancement forms: the bootstrap POSTs a <form method="POST">.
1625
+ export async function adopt(container, html, stateJson, pathname) {
1626
+
1627
+ const route0 = pathname || location.pathname;
1628
+ __navReset(container);
1629
+ clearMounts();
1630
+ // stale mounts from a failed render never fire
1631
+ resumeState(stateJson);
1632
+ container.innerHTML = html;
1633
+
1634
+ const st = document.getElementById('__rosefc_state');
1635
+ if (st) st.textContent = stateJson;
1636
+ for (const route of routes) {
1637
+ if (matchRoute(route.pattern, route0)) {
1638
+ await __withOwner(container, async () => {
1639
+ await applyParams(route, route0);
1640
+ const closes = [];
1641
+ try {
1642
+ const render = await getRender(route);
1643
+
1644
+ await render(closes, '');
1645
+ } catch {
1646
+ return;
1647
+ }
1648
+ wire(container, closes);
1649
+ bindEvents(container);
1650
+ flushMounts();
1651
+ });
1652
+ return;
1653
+ }
1654
+ }
1655
+ }
1656
+ // === refresh() implementation === Re-render the current route in place: the client half of router.refresh() (a router refresh) / (a full invalidation).
1657
+ setRefreshHook(async () => {
1658
+ prefetchCache.delete(location.pathname);
1659
+ await start(document.getElementById('app'), location.pathname, false);
1660
+ });
1661
+ `,Ne=V?`
1662
+ // === Sliced mode: the runtime bridge === The routes this document did NOT
1663
+ // inline ride the shared nav chunk, whose components resolve the runtime
1664
+ // through this object instead of bundling a second copy. Published before any
1665
+ // render runs; the chunk's shim throws if it loads first.
1666
+ globalThis.__rosefc_rt = { ${de.join(", ")} };`:"",Ye=d=>V?`
1667
+ // === Sliced mode: the shared nav chunk === One file holds every route's
1668
+ // render chain this document did not inline, fetched on the first cross-route
1669
+ // navigation (or a hover prefetch). __rosefc_navImport is the override seam
1670
+ // (tests, or a host page with its own loader); the browser default is a plain
1671
+ // dynamic import of the versioned URL, which 'self' in the CSP allows.
1672
+ const __navUrl = ${JSON.stringify(d)};
1673
+ const __navImport = globalThis.__rosefc_navImport || ((u) => import(u));
1674
+ let __navMod = null;
1675
+ const __nav = async () => (__navMod ??= await __navImport(__navUrl));
1676
+ const __navRoute = async (pattern) => (await __nav()).navRenders[pattern];
1677
+ const __navNotFound = async (prefix) => (await __nav()).navNotFound[prefix];
1678
+ const __navError = async () => (await __nav()).navError;
1679
+ `:"",Bt=We({imports:V?Lt(null).imports:Zt,routes:V?Lt(null).routes:Nt,publish:"",nav:"",notFoundTable:V?Oe:qe,errorRender:V?wt:De,prefetchDoor:""});V||await C.promises.writeFile(_.join(O,"client-entry.js"),Bt);let $t=V?(async()=>{z("runtime-global.js",["// Sliced-mode bridge (generated): the nav chunk resolves the runtime","// through the copy the route slice published, so a page runs exactly one","// runtime. Exports are tree-shaken to what the chunk references.","const __rt = globalThis.__rosefc_rt;","if (!__rt) throw new Error('rosefc: the sliced bundle bridge is missing - the route slice did not publish the runtime before the nav chunk loaded');",...P.map(I=>`export const ${I} = __rt.${I};`)].join(`
1680
+ `)+`
1681
+ `);let d=[];for(let I=0;I<m.length;I++)c[I].isApi||!S.has(I)||!m[I].client||d.push(C.promises.writeFile(_.join(O,`nav-comp-${I}.client.js`),m[I].client.replace(/from '\.\/runtime\.js'/g,"from './runtime-global.js'").replace(/from '\.\/comp-(\d+)\.client\.js'/g,"from './nav-comp-$1.client.js'")));let b=`
1682
+ ${rt.replace(/from '\.\/comp-(\d+)\.client\.js'/g,"from './nav-comp-$1.client.js'")}
1683
+ export const navRenders = {
1684
+ ${j.map(({info:I,i:K})=>`'${I.pattern}': { render: ${X(K)} },`).join(`
1685
+ `)}
1686
+ };
1687
+ export const navNotFound = {
1688
+ ${Re.map(I=>`'${I.prefix}': { render: ${I.render} },`).join(`
1689
+ `)}
1690
+ };
1691
+ export const navError = ${Fe>=0?`{ render: ${X(Fe)} }`:"null"};
1692
+ `;await Promise.all([...d,C.promises.writeFile(_.join(O,"nav-entry.js"),b)]),await et(_.join(O,"nav-entry.js"),{entryPoints:[_.join(O,"nav-entry.js")],bundle:!0,outfile:_.join(r,"nav.js"),format:"esm",platform:"browser",minify:!0,write:!0,...it},o);let M=await C.promises.readFile(_.join(r,"nav.js")),B="/nav.js?v="+qt(M);await Et(_.join(r,"slices")),await C.promises.mkdir(_.join(r,"slices"),{recursive:!0});let q=[{entryFile:"client-entry.js",outFile:_.join(r,"client.js"),own:null},...j.map(({i:I})=>{let K=ie(c[I].pattern);return{entryFile:`slice-entry-${K}.js`,outFile:_.join(r,"slices",`${K}.js`),own:I}})],L=[];for(let{entryFile:I,outFile:K,own:ye}of q){let be=Lt(ye),Je=_.join(O,I);await C.promises.writeFile(Je,We({imports:be.imports,routes:be.routes,publish:Ne,nav:Ye(B),notFoundTable:Oe,errorRender:wt,prefetchDoor:`
1693
+ export { setPrefetchOverride } from './runtime.js';`})),L.push(et(Je+":slice",{entryPoints:[Je],bundle:!0,outfile:K,format:"esm",platform:"browser",minify:!0,write:!0,...it},o))}return await Promise.all(L),{}})():ue?(async()=>(await Et(_.join(r,"chunks")),et(_.join(O,"client-entry.js")+":split",{entryPoints:[_.join(O,"client-entry.js")],bundle:!0,format:"esm",platform:"browser",minify:!0,splitting:!0,outdir:r,entryNames:"client",chunkNames:"chunks/[name]-[hash]",write:!0,...it},o)))():et(_.join(O,"client-entry.js"),{entryPoints:[_.join(O,"client-entry.js")],bundle:!0,outfile:_.join(r,"client.js"),format:"esm",platform:"browser",minify:!0,write:!0,...it},o);await Promise.all([st,$t,pe]);for(let d of[_.join(r,"server.js"),_.join(r,"prod.mjs")])try{if(!C.existsSync(d))continue;let b=await C.promises.readFile(d,"utf8");if(b.startsWith(E))continue;(/Dynamic require of/.test(b)||/(?<![\w$])require\s*\(/.test(b))&&await C.promises.writeFile(d,E+b,"utf8")}catch{}let yt=os;try{let d=C.readFileSync(_.join(r,"client.js"));yt=os.replace("from '/client.js'",`from '/client.js?v=${qt(d)}'`)}catch{}await C.promises.writeFile(_.join(r,"mount.js"),yt);let _t=_.join(t,"public");C.existsSync(_t)&&await C.promises.cp(_t,_.join(r,"public"),{recursive:!0}),console.log("Rosefc zero-JS report:");for(let d of xo(c,m))console.log(" "+d);let xt=new Map;for(let{info:d,i:b}of j)if(Tt(c,m,b))for(let M of[b,...nt(c,b)])for(let B of m[M].jsWarnings??[]){let q=xt.get(B);q||(q={why:B,files:new Map},xt.set(B,q));let L=_.relative(t,c[M].filePath).replace(/\\/g,"/"),I=q.files.get(L);I||(I=new Set,q.files.set(L,I)),I.add(d.routePath)}for(let d of xt.values()){let b=new Set;for(let L of d.files.values())for(let I of L)b.add(I);let M=[...d.files.entries()].sort((L,I)=>I[1].size-L[1].size).map(([L,I])=>`${L} (${I.size===1?[...I][0]:`${I.size} routes`})`),B=M.slice(0,4).join(", "),q=M.length>4?`, +${M.length-4} more files`:"";console.warn(`Rosefc warning: ${b.size} routes ship zero JavaScript while their chain contains ${d.why} - ${B}${q}`)}return{routes:j.map(({info:d})=>d),bundle:oe,config:f}}async function vo(e){let s=_.join(e,"src","pages");if(!C.existsSync(s))return[];async function n(t){let r=await C.promises.readdir(t,{withFileTypes:!0}),i=[];for(let o of r){let l=_.join(t,o.name);o.isDirectory()?i.push(...await n(l)):o.name.endsWith(".rose")&&i.push(l)}return i}return n(s)}async function ko(e){let s=_.join(e,"src","components");if(!C.existsSync(s))return[];async function n(t){let r=await C.promises.readdir(t,{withFileTypes:!0}),i=[];for(let o of r){let l=_.join(t,o.name);o.isDirectory()?i.push(...await n(l)):o.name.endsWith(".rose")&&i.push(l)}return i}return n(s)}function Eo(e,s){let n=_.dirname(e),t=_.dirname(s);return t===n||t.startsWith(n+_.sep)}function So(e,s){let n=_.join(s,"src","pages"),r=_.relative(n,e).replace(/\\/g,"/").replace(/\.rose$/,""),i=_.posix.basename(r),o=e.replace(/\\/g,"/").includes("/src/components/"),l=!o&&i==="_layout",a=!o&&(i==="404"||i==="_notfound"),u=!o&&i==="500",g=!o&&(r==="api"||r.startsWith("api/")),c=!o&&r==="_middleware",f=r.split("/").filter(m=>m!=="_layout"&&m!=="_notfound");f.length>1&&f[f.length-1]==="index"&&(f=f.slice(0,-1));let h=/^\[\.\.\.(\w+)\]$/,p=/^\[\[\.\.\.(\w+)\]\]$/,w=f.map(m=>{let v=p.exec(m);if(v)return`**${v[1]}`;let x=h.exec(m);return x?`*${x[1]}`:m.startsWith("[")&&m.endsWith("]")?`:${m.slice(1,-1)}`:m}),y;return w.length===0||w.length===1&&w[0]==="index"?y="/":y="/"+w.join("/"),{filePath:e,routePath:y,pattern:y,paramNames:f.flatMap(m=>{let v=p.exec(m);if(v)return[v[1]];let x=h.exec(m);return x?[x[1]]:m.startsWith("[")&&m.endsWith("]")?[m.slice(1,-1)]:[]}),isLayout:l,isNotFound:a,isError:u,isApi:g,isMiddleware:c,isComponent:o}}function He(e){return e.charAt(0).toUpperCase()+e.slice(1)}export{T as RoseError,Qo as buildProject,xo as buildReport,Ns as codeFrame,Cr as compileComponent,Ms as errorInfo,Or as extractExports,ve as lineAt,ot as lineOf,ps as loadConfig,Vo as loadPlugins,ko as scanComponentFiles,vo as scanRoseFiles,$s as scopeCss,Uo as scriptOf,ut as templateExprSpans};