@symbo.ls/brender 3.14.671 → 3.14.673

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # @symbo.ls/brender
2
2
 
3
+ ## 3.14.673
4
+
5
+ ### Patch Changes
6
+
7
+ - 2e9abb3: The three brender registry writers moved out of the `@symbo.ls/utils` index into a new server entry, `@symbo.ls/utils/server`: `brenderRegistryBlock`, `encodeBrenderRegistry`, `brenderRegistryTreeBlock`.
8
+
9
+ - Why: every `@symbo.ls/utils` index export is spread into `context.utils`, so the writers rode in every browser bundle (about 1.2 KB raw, 330 B Brotli) and no browser code calls them.
10
+ - `el.call('brenderRegistryBlock' | 'encodeBrenderRegistry' | 'brenderRegistryTreeBlock', …)` no longer reaches them, and `smbls` (which re-exports the utils index) no longer exports them.
11
+ - Server or build code that writes a registry: `import { brenderRegistryBlock, encodeBrenderRegistry, brenderRegistryTreeBlock } from '@symbo.ls/utils/server'` (ESM and CJS).
12
+ - The client half stays in the index: `BRENDER_REGISTRY_BLOCK`, `BRENDER_REGISTRY_TREE_BLOCK`, `decodeBrenderRegistry`, `readJsonDataBlock`, `jsonForScript`.
13
+ - `@symbo.ls/brender` imports the writers from the new entry, so it needs the `@symbo.ls/utils` release that ships `@symbo.ls/utils/server`. The pages it writes are byte-identical.
14
+
15
+ - Updated dependencies [2e9abb3]
16
+ - @symbo.ls/utils@3.14.849
17
+ - smbls@3.14.851
18
+
19
+ ## 3.14.672
20
+
21
+ ### Patch Changes
22
+
23
+ - 77f0e31: Release note (XMA, round 8 E13): the element-path registry of a built page has a new tag. A step after `smbls build` that looks for the old tag does not find it.
24
+
25
+ - Old tag: `<script type="application/json" data-brender="registry">`. Its content is an object, element path → `br-<n>`.
26
+ - New tag, written by `smbls build` (`renderPage({ registryFormat: 'auto' })`) when the page's own smbls reads it (smbls 3.14.848 or later, cli 3.14.814 or later): `<script type="application/json" data-brender="registry-tree">`. Its content is the same registry as a tree, `{ "f": "tree", "e": [...] }` (`@symbo.ls/utils` `encodeBrenderRegistry` / `decodeBrenderRegistry`). It is about a third of the bytes.
27
+ - A registry that cannot be a tree (a value that is not `br-<n>`) still ships in the old tag. `renderPage` called directly still writes the old tag by default (`registryFormat: 'paths'`).
28
+ - To keep the old tag in `smbls build`, set `"brender": { "registryFormat": "paths" }` in `symbols.json`.
29
+
30
+ How a post-build step finds the end of the page markup:
31
+
32
+ - The markup is inserted right after `<body>`. The page's data blocks come directly after it, then the shell's own body content.
33
+ - The first data block after the markup is one of these: `<script type="application/json" data-brender="registry">`, `<script type="application/json" data-brender="registry-tree">`, or `<script type="application/json" data-fetch-seed>` (the recorded answers). A page with `brender.hydrate: false` has no registry block. A page that made no anonymous request has no fetch-seed block.
34
+ - Match all three, not one full tag. For example: `/<script type="application\/json" data-(?:brender="registry(?:-tree)?"|fetch-seed\b)/`. Do not match the full old tag text.
35
+ - When none of them is there, the markup ends where the shell's own body content starts (its first `<script`). Another way: read the elements that carry `data-br`. Every element of the markup carries one.
36
+
37
+ - 75fc737: Round 8, XMA ("on a slow desktop, data holds still"): the text of a page built ahead no longer falls back to the system font while the app takes the page over.
38
+
39
+ - Cause: Chrome makes new, unloaded `FontFace` objects when the style sheet that holds a page's `@font-face` rules changes. The takeover changed it twice. First, smbls inserted the framework's default `SourceSans` face, a face with no file (`src: ;`). Second, it removed the server's styles and copied their faces into a new `<style data-smbls-faces>`. Each time the text drew in the fallback font for one to three frames, and every text block changed size. Measured on a fixture page of 40 data blocks, desktop 1440 px, CPU 6x slower: 45,828 px of layout change in 2 frames with `build.prepareDesignSystem` on, 68,742 px in 3 frames with `{ shell: false, pages: false }`. Now 0 px in both, 4 of 4 runs.
40
+ - `@symbo.ls/brender` `renderPage` writes the page's `@font-face` rules in a `<style data-smbls-faces>` of their own, ahead of `<style data-brender>`. They are no longer in `<style data-emotion="smbls">`. The takeover does not select that sheet, so it stays for the page's life and keeps its faces loaded. `splitCapturedCSS` does not change.
41
+ - `smbls` `applyFontFaces` does not insert a face that names no file.
42
+ - A post-build step that moves the `@font-face` rules out of the server's styles finds none there now. It can leave `<style data-smbls-faces>` where it is.
43
+
44
+ - Updated dependencies [75fc737]
45
+ - smbls@3.14.850
46
+
3
47
  ## 3.14.671
4
48
 
5
49
  ### Patch Changes
@@ -1,22 +1,25 @@
1
- import{resolve as m,join as He,dirname as _}from"path";import{existsSync as h,unlinkSync as Ue,readFileSync as z,realpathSync as We}from"fs";import{resolvePackageEntry as Je}from"./packageEntry.js";import{tmpdir as Ye}from"os";import{randomBytes as ze}from"crypto";import{createRequire as le}from"module";import{pathToFileURL as Ve}from"url";import{createEnv as Se}from"./env.js";import{resetKeys as Re,assignKeys as ke,mapKeysToElements as we}from"./keys.js";import{extractMetadata as pe,generateHeadHtml as Xe}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as Qe}from"./shell.js";import{trimSpriteToPage as Ze,classRulesForPage as et,markupClasses as tt,trimVariablesToPage as ot}from"./pageWeight.js";import{fetchSSRTranslations as nt}from"./prefetch.js";import{createEarlySeedScript as st}from"@symbo.ls/fetch";import{headerEntries as rt}from"@symbo.ls/fetch/rest";import{brenderRegistryBlock as ct,brenderRegistryTreeBlock as it,brenderStampMeta as at,escapeRegExp as lt,jsonForScript as pt,polyglotFallbackLang as oe,polyglotLangStorageKey as ft,polyglotAddressLang as ut,polyglotStartupScript as mt}from"@symbo.ls/utils";let ne=null;const dt=async()=>{if(ne)return ne;try{return ne=(await import("@symbo.ls/funcql")).funcqlPlugin,ne}catch{return null}};import"linkedom";import{createEarlySeedBlock as gt}from"@symbo.ls/fetch";import{reset as ht}from"@symbo.ls/css";const se=(e,t)=>{if(!e||!t)return;if(e[t]!==void 0)return e[t];const o=t.split(".");let n=e;for(const s of o){if(n==null||typeof n!="object")return;n=n[s]}return n},re=(e,t)=>oe(e?.lang,t),xe=(e,t,o,n)=>{if(o?.translations){const r=o.translations[t];if(r){const i=se(r,e);if(i!==void 0)return i}}if(n?.translations){const r=n.translations[t];if(r){const i=se(r,e);if(i!==void 0)return i}}const s=oe(void 0,o);if(s!==t&&o?.translations){const r=o.translations[s];if(r){const i=se(r,e);if(i!==void 0)return i}}},yt=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,s=this?.state?.root||o?.state?.root,r=xe(e,t||re(s,n),n,s);if(r!==void 0)return r;const i=de(me);return n&&i&&i.labelKeys.add(e),e},je=function(){return re(this?.state?.root,this?.context?.polyglot)},L=(e,t=new WeakMap)=>{if(e===null||typeof e!="object")return e;if(t.has(e))return t.get(e);if(Array.isArray(e)){const n=[];t.set(e,n);for(const s of e)n.push(typeof s=="object"&&s!==null?L(s,t):s);return n}const o={};t.set(e,o);for(const n of Object.keys(e)){const s=e[n];o[n]=typeof s=="object"&&s!==null?L(s,t):s}return o};let O=null;try{import.meta.url&&(O=le(import.meta.url))}catch{}const bt=()=>{if(!import.meta.url||!O)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:l=>l};const e=We(new URL(".",import.meta.url).pathname),t=m(e,"../..");if(h(m(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const l=O.resolve("smbls/package.json");n=_(l)}catch{let l=e;for(;l!==_(l);){const g=m(l,"node_modules","smbls");if(h(m(g,"package.json"))){n=g;break}l=_(l)}}let s=O;if(n)try{s=le(m(n,"package.json"))}catch{}let r,i=process.cwd();for(;i!==_(i);){if(h(m(i,"package.json"))){r=i;break}i=_(i)}let f=s;if(r)try{f=le(m(r,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:r,_smblsRequire:s,_projectRequire:f}},H=(e,t)=>{const o=e.isMonorepo?[O]:[e._smblsRequire,e._projectRequire,O].filter(Boolean);for(const n of o)try{return n.resolve(t)}catch{}return null},Co=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"packages",t,...o);const n=H(e,`${t}/package.json`);return n?m(_(n),...o):null},qo=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"plugins",t,...o);const n=H(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null},fe=(e,t,...o)=>{if(e.isMonorepo){for(const s of["packages","plugins"]){const r=m(e.monorepoRoot,s,t,...o);if(h(r))return r}return null}const n=H(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null},Ee=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"packages","domql","packages",t,...o);const n=H(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null};let ce=null;const Te="smbls/ssr",St=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},_e=()=>(ce||(ce=Rt().catch(e=>{throw ce=null,e})),ce),Rt=async()=>{const e=bt();let t;if(O&&e.isMonorepo)t=m(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let p;try{return await St()}catch(a){p=a}if(!O)throw new Error(`brender: ${Te} is not available in this bundled runtime (${p.message}). Bundle smbls \u2265 the release that adds the smbls/ssr export alongside @symbo.ls/brender.`);const c=e.smblsRoot&&m(e.smblsRoot,"src","createDomql.js");if(c&&h(c))t=c;else throw new Error(`brender: cannot load ${Te} (${p.message}). Server rendering needs smbls installed in this project, at a release that exports smbls/ssr`+(e.smblsRoot?` (found smbls at ${e.smblsRoot}).`:" (no smbls package found)."))}const o=await import("esbuild"),n=He(Ye(),`br_createDomql_${ze(6).toString("hex")}.mjs`),s=Je,r=e.isMonorepo?await import(Ve(m(e.monorepoRoot,"scripts","vite-workspace-source.mjs")).href):null,i=r?new Set(r.workspacePackageRoots().map(p=>r.workspacePackageAt(p).name)):null,f=/^(?:smbls(?:\/.*)?|domql|css-in-props(?:\/.*)?|@symbo\.ls\/[^/]+)$/,l={name:"workspace-resolve",setup(p){r&&(p.onResolve({filter:/^[^./]/},c=>{if(f.test(c.path))return;const a=c.path.split("/"),u=c.path.startsWith("@")?a.slice(0,2).join("/"):a[0];if(!i.has(u))return;const d=r.resolveWorkspaceSource(c.path,c.importer||t);return d?{path:d}:{errors:[{text:`"${c.path}" names no source file in the workspace`}]}}),p.onLoad({filter:/[\\/]dist[\\/]/},c=>r.isWorkspaceDist(c.path)?{errors:[{text:`${c.path} is a BUILD of a workspace package \u2014 the render bundles source`}]}:void 0)),p.onResolve({filter:/^smbls/},c=>{const a=c.path.replace(/^smbls\/?/,""),u=e.isMonorepo?m(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!u)return;if(!a){const E=s(u);return E?{path:E}:void 0}const d=m(u,a);if(h(d))return{path:d};if(h(d+".js"))return{path:d+".js"};const b=m(d,"index.js");if(h(b))return{path:b}}),p.onResolve({filter:/^domql$/},c=>{if(e.isMonorepo){const a=m(e.monorepoRoot,"packages","domql","src","index.js");if(h(a))return{path:a};const u=m(e.monorepoRoot,"packages","domql","index.js");if(h(u))return{path:u}}else try{const a=_require.resolve("domql/package.json"),u=s(_(a));if(u)return{path:u}}catch{}}),p.onResolve({filter:/^@symbo\.ls\//},c=>{const a=c.path.replace("@symbo.ls/","");if(a==="sync")return{path:"sync-stub",namespace:"brender-stub"};if(e.isMonorepo){for(const d of["packages","plugins"]){const b=m(e.monorepoRoot,d,a,"src","index.js");if(h(b))return{path:b};const E=m(e.monorepoRoot,d,a,"index.js");if(h(E))return{path:E}}const u=m(e.monorepoRoot,"packages","default-config","blank","index.js");if(a==="default-config"&&h(u))return{path:u}}else{const u=fe(e,a,"src","index.js");if(u&&h(u))return{path:u};const d=fe(e,a,"index.js");if(d&&h(d))return{path:d};if(a==="default-config"){const b=fe(e,"default-config","blank","index.js");if(b&&h(b))return{path:b}}}}),p.onResolve({filter:/^@domql\//},c=>{const a=c.path.replace("@symbo.ls/","");if(e.isMonorepo){const u=m(e.monorepoRoot,"packages","domql","packages",a,"src","index.js");if(h(u))return{path:u};const d=m(e.monorepoRoot,"packages","domql","packages",a,"index.js");if(h(d))return{path:d}}else{const u=Ee(e,a,"src","index.js");if(u&&h(u))return{path:u};const d=Ee(e,a,"index.js");if(d&&h(d))return{path:d}}}),p.onResolve({filter:/^css-in-props/},c=>{let a;if(e.isMonorepo)a=m(e.monorepoRoot,"packages","css-in-props");else{const b=H(e,"css-in-props/package.json");b&&(a=_(b))}if(!a)return;const u=c.path.replace(/^css-in-props\/?/,"");if(u){const b=m(a,u),E=m(b,"index.js");if(h(E))return{path:E};if(h(b+".js"))return{path:b+".js"};if(h(b))return{path:b}}const d=s(a);if(d)return{path:d}}),p.onResolve({filter:/^@emotion\//},c=>{let a;if(e.isMonorepo)a=m(e.monorepoRoot,"node_modules",c.path);else{const u=H(e,`${c.path}/package.json`);if(!u)return;a=_(u)}if(h(a)){const u=m(a,"package.json");if(h(u))try{const d=JSON.parse(z(u,"utf8")),b=d.module||d.main||"dist/emotion-css.esm.js";return{path:m(a,b)}}catch{}return{path:a}}}),p.onResolve({filter:/\.json$/},c=>{if(c.resolveDir){const a=m(c.resolveDir,c.path);if(h(a))return{path:a}}}),p.onLoad({filter:/smbls\/.*options\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("options.js"))return;let a=z(c.path,"utf8");return a=a.replace(/import\s*\{[^}]*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"][^;\n]*/,"const version = '0.0.0'"),a=a.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:a,loader:"js"}}),p.onLoad({filter:/smbls\/.*init\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("init.js"))return;let a=z(c.path,"utf8");return a=a.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:a,loader:"js"}}),p.onLoad({filter:/.*/,namespace:"brender-stub"},()=>({contents:"export const SyncComponent = {}; export const Inspect = {}; export const Notifications = {}; export const syncPlugin = () => ({}); export const notificationsPlugin = () => ({}); export const seedRawDesignSystem = () => {}; export const inspectPlugin = () => ({}); export default {}",loader:"js"})),p.onLoad({filter:/smbls\/src\/router\.js$/},async c=>{let a=z(c.path,"utf8");return a=a.replace(/import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,"const Link = { tag: 'a', attr: { href: (el) => el.href } }"),{contents:a,loader:"js"}}),p.onLoad({filter:/fetchOnCreate\.js$/},async c=>{if(!c.path.includes("smbls/"))return;let a=z(c.path,"utf8");return a=a.replace(/window\s*&&\s*window\.location\s*\?\s*window\.location\.host\.includes/g,"window && window.location && window.location.host ? window.location.host.includes"),{contents:a,loader:"js"}})}};await o.build({entryPoints:[t],bundle:!0,format:"esm",platform:"node",outfile:n,write:!0,logLevel:"warning",plugins:[l],nodePaths:e.isMonorepo?[m(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[m(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[m(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[m(e.smblsRoot,"..","..","node_modules")]:[]].filter(p=>h(p)),supported:{"import-attributes":!1},external:["fs","path","os","crypto","url","http","https","stream","util","events","buffer","child_process","worker_threads","net","tls","dns","dgram","zlib","assert","querystring","string_decoder","readline","perf_hooks","async_hooks","v8","vm","cluster","inspector","module","process","tty","color-contrast-checker","linkedom"]});const g=await import(`file://${n}`);if(process.env.BRENDER_DEBUG)console.log("[brender] Bundle saved:",n);else try{Ue(n)}catch{}return g},kt={Box:{},Focusable:{},Block:{display:"block"},Inline:{display:"inline"},Flex:{display:"flex"},InlineFlex:{display:"inline-flex"},Grid:{display:"grid"},InlineGrid:{display:"inline-grid"},Link:{tag:"a",attr:{href:e=>e.href,target:e=>e.target,rel:e=>e.rel}},A:{extends:"Link"},RouteLink:{extends:"Link"},Img:{tag:"img",attr:{src:e=>{let t=e.src;return typeof t=="string"&&t.includes("{{")&&(t=e.call("replaceLiteralsWithObjectFields",t,e.state)),t},alt:e=>e.alt,loading:e=>e.loading}},Image:{extends:"Img"},Button:{tag:"button"},FocusableComponent:{tag:"button"},Form:{tag:"form"},Input:{tag:"input"},TextArea:{tag:"textarea"},Textarea:{tag:"textarea"},Select:{tag:"select"},Label:{tag:"label"},Iframe:{tag:"iframe"},Video:{tag:"video"},Audio:{tag:"audio"},Canvas:{tag:"canvas"},Span:{tag:"span"},P:{tag:"p"},H1:{tag:"h1"},H2:{tag:"h2"},H3:{tag:"h3"},H4:{tag:"h4"},H5:{tag:"h5"},H6:{tag:"h6"},Svg:{tag:"svg",attr:{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}},Text:{tag:"span"}},wt=(e,t)=>{const o={};return ve(e,(n,s)=>{if(!s.__brKey)return;const r=t(n);o[r===""?"__root":r]=s.__brKey}),o},ve=(e,t)=>{const o=n=>{const s=n&&n.__ref;if(s&&(t(n,s),s.__children))for(const r of s.__children)o(n[r])};o(e)},xt=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let U=0;const Le=Symbol.for("brender.fetchTracked"),ue=()=>U,jt=256*1024,Et=1024*1024,Tt=new Set(["accept-language","accept"]),De={renders:0,record:null},_t=50,me={renders:0,record:null},$e=(e,t)=>{e.renders++,e.renders===1?e.record=t():e.record&&(e.record.tainted=!0);const o=e.record;return{record:o,close:()=>{e.renders--,e.record===o&&(e.record=null)}}},de=e=>e.record&&!e.record.tainted?e.record:null,vt=e=>{try{const t=new URL(e);return t.origin+t.pathname}catch{return String(e).split("?")[0]}},ge=(e,t,o)=>{!e||e.tainted||e.failures.length>=_t||e.failures.push({url:vt(t),reason:o})},Ae=e=>e&&typeof e=="object"&&typeof e.url=="string"?e.url:String(e),Lt=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",s=Ae(t),r=String(o&&o.method||n&&t.method||"GET").toUpperCase(),i={},f=l=>{if(!l)return;const g=!Array.isArray(l)&&typeof l.entries!="function";for(const[p,c]of rt(l))g&&c==null||(i[String(p).toLowerCase()]=String(c))};return n&&f(t.headers),o&&f(o.headers),{url:s,method:r,headers:i}},Dt=(e,t,o,n)=>{if(!o||!o.ok||typeof o.clone!="function")return;const s=o.headers&&o.headers.get&&o.headers.get("content-type")||"";if(!/json|^text\//i.test(s))return;let r;try{r=o.clone()}catch{return}n(r.text().then(i=>{e.tainted||i.length>jt||e.bytes+i.length>Et||(e.bytes+=i.length,e.entries.push({url:t.url,lang:t.headers["accept-language"]||"",status:o.status,type:s,body:i}))},()=>{}))},$t=()=>{const e=globalThis.fetch;if(typeof e!="function"||e[Le])return;const t=function(...o){U++;let n=!1;const s=()=>{n||(n=!0,U--)},r=c=>{U++,c.then(()=>{U--},()=>{U--})},i=de(De),f=de(me);let l=null;if(i)try{l=Lt(o),(l.method!=="GET"||!/^https?:/i.test(l.url)||Object.keys(l.headers).some(c=>!Tt.has(c)))&&(l=null)}catch{l=null}const g=()=>Ae(o[0]);let p;try{p=e.apply(this,o)}catch(c){throw ge(f,g(),c&&c.message||"failed"),s(),c}return p&&typeof p.then=="function"?p.then(c=>{l&&Dt(i,l,c,r),f&&c&&c.ok===!1&&ge(f,g(),"HTTP "+c.status),s()},c=>{ge(f,g(),c&&c.message||"network error"),s()}):s(),p};t[Le]=!0,globalThis.fetch=t},Mo=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=pt(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
2
- `+st(t):""):`<script>window.__BR_REGISTRY__=${n}<\/script>`},At=3e4,Ct=2147483647;let Ce=Promise.resolve();const qe=()=>{},qt=e=>{const t=Ce.then(e);return Ce=t.then(qe,qe),t},Mt=e=>{if(e===void 0)return At;if(e===0||e===!1||e===1/0)return 0;if(typeof e!="number"||!(e>0))throw new TypeError(`brender: options.timeout is a number of milliseconds, or 0 / false for no limit \u2014 not ${JSON.stringify(e)}`);return Math.min(e,Ct)},It=(e,t)=>{const o=e.route||"/",n=e.pathname||o,s=n===o?o:`${n} (route ${o})`,r=new Error(`brender: the render of ${s} did not finish within ${t} ms and was abandoned, so the renders after it can run (options.timeout)`);return r.code="BRENDER_RENDER_TIMEOUT",r.route=o,r.pathname=n,r.timeout=t,r},Ot=e=>{e.closed=!0;for(const t of e.undo.splice(0))t()},Pt=e=>{let t=!1;return()=>{t||(t=!0,e())}},Me=(e,t={})=>{let o;try{o=Mt(t.timeout)}catch(n){return Promise.reject(n)}return qt(()=>Ft(e,t,o))},Ft=async(e,t,o)=>{await _e();const n={closed:!1,undo:[]},s=Bt(e,t,n);if(!o)return s;let r;const i=new Promise((f,l)=>{r=setTimeout(()=>{Ot(n),l(It(t,o))},o)});try{return await Promise.race([s,i])}finally{clearTimeout(r)}},Bt=async(e,t,o)=>{const{route:n="/",pathname:s,state:r,context:i,prefetch:f=!1}=t,l=s||n;$t();const g=$e(me,()=>({failures:[],labelKeys:new Set,tainted:!1}));try{return await Kt(e,{route:n,locationPath:l,stateOverrides:r,contextOverrides:i,prefetch:f},g.record,o)}finally{g.close()}},Kt=async(e,{route:t,locationPath:o,stateOverrides:n,contextOverrides:s,prefetch:r},i,f)=>{const l=()=>{if(f.closed)throw new Error("brender: this render was abandoned at its timeout")};let g;if(r){try{g=await nt(e)}catch(d){f.closed||console.warn("[brender] SSR translation fetch failed:",d.message)}l()}const{window:p,document:c}=Se(),a=c.body;p.location.pathname=o;const u=[ie("document",c),ie("location",p.location),ie("localStorage",p.localStorage),ie("sessionStorage",p.sessionStorage)].map(Pt);f.undo.push(...u);try{const{createDomqlElement:d,PRERENDER_REGISTRY_FORMATS:b}=await _e();l();const E=L(e.app||{}),x={...e.config||{}};e.polyglot&&!x.polyglot&&(x.polyglot=e.polyglot),e.fetch&&!x.fetch&&(x.fetch=e.fetch),e.router&&!x.router&&(x.router=e.router);for(const y of Jt)e[y]!=null&&x[y]==null&&(x[y]=e[y]);const w=x.polyglot?{...x.polyglot}:void 0,X=ut(o,w);X&&p.localStorage.setItem(ft(w),X),g&&w&&(w.translations={...w.translations||{},...g});const v=L(e.state||{});(g||w)&&(v.root||(v.root={}),w&&(v.root.lang=oe(v.root.lang,w)),g&&(v.root.translations={...v.root.translations||{},...g})),ht();const P={};for(const y in e){if(xt.has(y))continue;const k=e[y];P[y]=k&&typeof k=="object"?L(k):k}const A={...P,state:v,...n?{state:{...v,...n}}:{},dependencies:L(e.dependencies||{}),components:L(e.components||{}),snippets:L(e.snippets||{}),pages:L(e.pages||{}),functions:{...e.functions||{},polyglot:yt,getActiveLang:je,getLang:je},methods:e.methods||{},designSystem:L(e.designSystem||{}),files:e.files||{},sharedLibraries:e.sharedLibraries||[],...x,...w?{polyglot:w}:{},document:c,window:p,parent:{node:a},initOptions:{},domqlOptions:{sourcemap:!1},firstRender:!1,sync:!1,inspect:!1,notifications:!1,isolateDesignSystem:!0,isolateFetchCache:!0,captureDesignSystem:!0,...s||{}},G=await dt();l(),G&&(A.plugins=A.plugins||[],A.plugins.some(y=>y.name==="funcql")||A.plugins.push(G)),Re();const S=$e(De,()=>({entries:[],bytes:0,tainted:!1})),C=S.record;let j;try{j=await d(E,A),l();const y=Date.now(),k=r?2e3:50,K=ae=>new Promise(Ne=>setTimeout(Ne,ae));for(await K(Math.min(50,k));r&&!f.closed&&ue()>0&&Date.now()-y<k;)await K(10),ue()===0&&await K(Math.max(0,Math.min(50,k-(Date.now()-y))));if(l(),r&&await Gt(j,w)){l();const ae=Date.now();for(await K(Math.min(50,k));!f.closed&&ue()>0&&Date.now()-ae<k;)await K(10);l()}}finally{S.close()}const q=C&&!C.tainted&&!(x.fetch&&x.fetch.seed===!1)?C.entries.slice():[];ke(a);const W=we(j),{elementPath:M}=await import("@symbo.ls/element");l();const be=wt(j,M),Q=j?.context?.routerOptions?.contentElementKey||"content",F=j&&j[Q],Z=F&&typeof F=="object"&&F.__ref?F:void 0,ee=pe(e,t,j,j?.state,Z),B=[],I=c.head||c.querySelector("head");if(I)for(const y of I.querySelectorAll("style")){if(y.sheet&&y.sheet.cssRules)for(const k of y.sheet.cssRules)k.cssText&&B.push(k);if(!B.length){const k=y.textContent||"";k&&B.push({cssText:k})}}const J=B.map(y=>y.cssText),{globalCSS:Y,classRules:N}=Zt(B);let D=Pe(a.innerHTML);const $=j?.state?.root,te=re($,w),R=Nt(g,$);R&&(D=Oe(D,Ie(R,te,w)));const T=i&&!i.tainted?{failedRequests:i.failures.slice(),rawLabelKeys:Wt(i.labelKeys,D,te,w,$)}:null;return{html:D,metadata:ee,registry:W,brRegistry:be,element:j,emotionCSS:J,globalCSS:Y,classRules:N,fetchSeed:q,document:c,window:p,ssrTranslations:R||void 0,activeLang:te,diagnostics:T,preparedDesignSystem:A.preparedDesignSystem||null,registryFormats:Array.isArray(b)?b.slice():["paths"]}}finally{for(const d of u)d()}},ie=(e,t)=>{const o=Object.getOwnPropertyDescriptor(globalThis,e);return o&&!o.configurable?!o.writable&&!o.set?()=>{}:(globalThis[e]=t,()=>{}):(Object.defineProperty(globalThis,e,{value:t,writable:!0,configurable:!0,enumerable:!0}),()=>{o?Object.defineProperty(globalThis,e,o):delete globalThis[e]})},Gt=async(e,t)=>{if(!t||!t.fetch||!e||typeof e.call!="function")return!1;const o=e.state&&e.state.root;if(!o)return!1;const n=re(o,t),s=o.translations&&o.translations[n];if(s&&typeof s=="object"&&Object.keys(s).length||t.translations&&t.translations[n])return!1;try{await e.call("loadTranslations",n,{inFlight:!0})}catch{}return!0},he=/\{\{\s*([^|{}]+?)\s*\|\s*polyglot\s*\}\}/g,ye=e=>e&&typeof e.parse=="function"?e.parse():e,Nt=(e,t)=>{const o=ye(t?.translations),n={};for(const s of[e,o])if(!(!s||typeof s!="object"))for(const r in s){const i=ye(s[r]);i&&typeof i=="object"&&(n[r]={...n[r]||{},...i})}return Object.keys(n).length?n:null},Ie=(e,t,o)=>e[t]||e[oe(void 0,o)]||Object.values(e)[0]||{},Oe=(e,t)=>e.replace(he,(o,n)=>se(t,n.trim())??o),Ht=/<script\b[^>]*\btype\s*=\s*["']?application\/json["']?[^>]*>[\s\S]*?<\/script\s*>/gi,Ut=(e,t)=>new RegExp(`(?:^|[^\\w.-])${lt(t)}(?![\\w-]|\\.\\w)`).test(e),Wt=(e,t,o,n,s)=>{const r=new Set,i=t.replace(Ht,"");for(const f of e)/\s/.test(f)||xe(f,o,n,s)===void 0&&Ut(i,f)&&r.add(f);for(const f of i.matchAll(he))r.add(f[1].trim());return[...r]},Io=async(e,t={})=>{const{context:o={}}=t,{window:n,document:s}=Se(),r=s.body,{create:i}=await import("@symbo.ls/element"),f=await import("@symbo.ls/utils"),l={...kt,...o.components||{}},g={...f,...o.utils||{},...o.functions||{}};Re();let p;try{p=i(e,{node:r},"root",{context:{document:s,window:n,...o,components:l,utils:g}})}catch{}ke(r);const c=p?we(p):{};return{html:Pe(r.innerHTML),registry:c,element:p}},Pe=e=>e.replace(/(<svg\b[^>]*>)([\s\S]*?)(<\/svg>)/gi,(t,o,n,s)=>{if(n.includes("&lt;")){const r=n.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&#39;/g,"'");return o+r+s}return t}),Jt=["globalTheme","themeStorageKey","themeRoot","useReset","useVariable","useFontImport","useIconSprite","useSvgSprite","useDocumentTheme","useDefaultConfig","useDefaultIcons","useThemeSuffixedVars","verbose","semanticIcons"],Yt=new Set(["auto","system"]),Fe=e=>{if(!e||typeof e!="object")return null;const t=e.config&&typeof e.config=="object"?e.config:{};if((t.themeRoot!=null?t.themeRoot:e.themeRoot)!=null)return null;const n=t.globalTheme!=null?t.globalTheme:e.globalTheme;if(typeof n!="string")return null;const s=n.trim();return!s||Yt.has(s)?null:s},zt=e=>String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Vt=/\.[A-Za-z_\\-]/,Xt=e=>{if(typeof e!="string"||!e)return!1;const t=e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,'""').replace(/\[[^\]]*\]/g,"[]");return!Vt.test(t)},Qt=/^\s*(:root|\[data-theme|\[data-skin)/,Be=e=>{const t=e&&e.cssText;if(typeof t!="string")return null;if(/^@(-webkit-)?keyframes\b/.test(t))return"keyframes";if(t.startsWith("@font-face"))return null;if(typeof e.selectorText=="string")return Xt(e.selectorText)?Qt.test(e.selectorText)?"root":"reset":null;const o=e.cssRules&&Array.from(e.cssRules);if(o&&o.length&&/^@(media|supports|container)\b/.test(t)){const n=new Set(o.map(Be));return n.has(null)||n.size!==1?n.has(null)?null:"reset":[...n][0]}return null},Zt=e=>{const t={root:[],reset:[],keyframes:[]},o=[];for(const n of e||[]){const s=Be(n);s?t[s].push(n.cssText):n&&n.cssText&&o.push(n.cssText)}return{globalCSS:{rootRule:t.root.join(`
1
+ import{resolve as m,join as Je,dirname as _}from"path";import{existsSync as h,unlinkSync as Ye,readFileSync as X,realpathSync as ze}from"fs";import{resolvePackageEntry as Ve}from"./packageEntry.js";import{tmpdir as Xe}from"os";import{randomBytes as Qe}from"crypto";import{createRequire as fe}from"module";import{pathToFileURL as Ze}from"url";import{createEnv as Re}from"./env.js";import{resetKeys as ke,assignKeys as we,mapKeysToElements as xe}from"./keys.js";import{extractMetadata as pe,generateHeadHtml as et}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as tt}from"./shell.js";import{trimSpriteToPage as ot,classRulesForPage as nt,markupClasses as st,trimVariablesToPage as rt}from"./pageWeight.js";import{fetchSSRTranslations as ct}from"./prefetch.js";import{createEarlySeedScript as at}from"@symbo.ls/fetch";import{headerEntries as it}from"@symbo.ls/fetch/rest";import{brenderStampMeta as lt,escapeRegExp as ft,jsonForScript as pt,polyglotFallbackLang as oe,polyglotLangStorageKey as ut,polyglotAddressLang as mt,polyglotStartupScript as dt}from"@symbo.ls/utils";import{brenderRegistryBlock as gt,brenderRegistryTreeBlock as ht}from"@symbo.ls/utils/server";let ne=null;const yt=async()=>{if(ne)return ne;try{return ne=(await import("@symbo.ls/funcql")).funcqlPlugin,ne}catch{return null}};import"linkedom";import{createEarlySeedBlock as bt}from"@symbo.ls/fetch";import{reset as St}from"@symbo.ls/css";const se=(e,t)=>{if(!e||!t)return;if(e[t]!==void 0)return e[t];const o=t.split(".");let n=e;for(const s of o){if(n==null||typeof n!="object")return;n=n[s]}return n},re=(e,t)=>oe(e?.lang,t),je=(e,t,o,n)=>{if(o?.translations){const r=o.translations[t];if(r){const a=se(r,e);if(a!==void 0)return a}}if(n?.translations){const r=n.translations[t];if(r){const a=se(r,e);if(a!==void 0)return a}}const s=oe(void 0,o);if(s!==t&&o?.translations){const r=o.translations[s];if(r){const a=se(r,e);if(a!==void 0)return a}}},Rt=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,s=this?.state?.root||o?.state?.root,r=je(e,t||re(s,n),n,s);if(r!==void 0)return r;const a=ge(de);return n&&a&&a.labelKeys.add(e),e},Te=function(){return re(this?.state?.root,this?.context?.polyglot)},$=(e,t=new WeakMap)=>{if(e===null||typeof e!="object")return e;if(t.has(e))return t.get(e);if(Array.isArray(e)){const n=[];t.set(e,n);for(const s of e)n.push(typeof s=="object"&&s!==null?$(s,t):s);return n}const o={};t.set(e,o);for(const n of Object.keys(e)){const s=e[n];o[n]=typeof s=="object"&&s!==null?$(s,t):s}return o};let O=null;try{import.meta.url&&(O=fe(import.meta.url))}catch{}const kt=()=>{if(!import.meta.url||!O)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:l=>l};const e=ze(new URL(".",import.meta.url).pathname),t=m(e,"../..");if(h(m(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const l=O.resolve("smbls/package.json");n=_(l)}catch{let l=e;for(;l!==_(l);){const g=m(l,"node_modules","smbls");if(h(m(g,"package.json"))){n=g;break}l=_(l)}}let s=O;if(n)try{s=fe(m(n,"package.json"))}catch{}let r,a=process.cwd();for(;a!==_(a);){if(h(m(a,"package.json"))){r=a;break}a=_(a)}let p=s;if(r)try{p=fe(m(r,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:r,_smblsRequire:s,_projectRequire:p}},U=(e,t)=>{const o=e.isMonorepo?[O]:[e._smblsRequire,e._projectRequire,O].filter(Boolean);for(const n of o)try{return n.resolve(t)}catch{}return null},Oo=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"packages",t,...o);const n=U(e,`${t}/package.json`);return n?m(_(n),...o):null},Po=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"plugins",t,...o);const n=U(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null},ue=(e,t,...o)=>{if(e.isMonorepo){for(const s of["packages","plugins"]){const r=m(e.monorepoRoot,s,t,...o);if(h(r))return r}return null}const n=U(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null},Ee=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"packages","domql","packages",t,...o);const n=U(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null};let ce=null;const _e="smbls/ssr",wt=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},ve=()=>(ce||(ce=xt().catch(e=>{throw ce=null,e})),ce),xt=async()=>{const e=kt();let t;if(O&&e.isMonorepo)t=m(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let f;try{return await wt()}catch(i){f=i}if(!O)throw new Error(`brender: ${_e} is not available in this bundled runtime (${f.message}). Bundle smbls \u2265 the release that adds the smbls/ssr export alongside @symbo.ls/brender.`);const c=e.smblsRoot&&m(e.smblsRoot,"src","createDomql.js");if(c&&h(c))t=c;else throw new Error(`brender: cannot load ${_e} (${f.message}). Server rendering needs smbls installed in this project, at a release that exports smbls/ssr`+(e.smblsRoot?` (found smbls at ${e.smblsRoot}).`:" (no smbls package found)."))}const o=await import("esbuild"),n=Je(Xe(),`br_createDomql_${Qe(6).toString("hex")}.mjs`),s=Ve,r=e.isMonorepo?await import(Ze(m(e.monorepoRoot,"scripts","vite-workspace-source.mjs")).href):null,a=r?new Set(r.workspacePackageRoots().map(f=>r.workspacePackageAt(f).name)):null,p=/^(?:smbls(?:\/.*)?|domql|css-in-props(?:\/.*)?|@symbo\.ls\/[^/]+)$/,l={name:"workspace-resolve",setup(f){r&&(f.onResolve({filter:/^[^./]/},c=>{if(p.test(c.path))return;const i=c.path.split("/"),u=c.path.startsWith("@")?i.slice(0,2).join("/"):i[0];if(!a.has(u))return;const d=r.resolveWorkspaceSource(c.path,c.importer||t);return d?{path:d}:{errors:[{text:`"${c.path}" names no source file in the workspace`}]}}),f.onLoad({filter:/[\\/]dist[\\/]/},c=>r.isWorkspaceDist(c.path)?{errors:[{text:`${c.path} is a BUILD of a workspace package \u2014 the render bundles source`}]}:void 0)),f.onResolve({filter:/^smbls/},c=>{const i=c.path.replace(/^smbls\/?/,""),u=e.isMonorepo?m(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!u)return;if(!i){const E=s(u);return E?{path:E}:void 0}const d=m(u,i);if(h(d))return{path:d};if(h(d+".js"))return{path:d+".js"};const b=m(d,"index.js");if(h(b))return{path:b}}),f.onResolve({filter:/^domql$/},c=>{if(e.isMonorepo){const i=m(e.monorepoRoot,"packages","domql","src","index.js");if(h(i))return{path:i};const u=m(e.monorepoRoot,"packages","domql","index.js");if(h(u))return{path:u}}else try{const i=_require.resolve("domql/package.json"),u=s(_(i));if(u)return{path:u}}catch{}}),f.onResolve({filter:/^@symbo\.ls\//},c=>{const i=c.path.replace("@symbo.ls/","");if(i==="sync")return{path:"sync-stub",namespace:"brender-stub"};if(e.isMonorepo){for(const d of["packages","plugins"]){const b=m(e.monorepoRoot,d,i,"src","index.js");if(h(b))return{path:b};const E=m(e.monorepoRoot,d,i,"index.js");if(h(E))return{path:E}}const u=m(e.monorepoRoot,"packages","default-config","blank","index.js");if(i==="default-config"&&h(u))return{path:u}}else{const u=ue(e,i,"src","index.js");if(u&&h(u))return{path:u};const d=ue(e,i,"index.js");if(d&&h(d))return{path:d};if(i==="default-config"){const b=ue(e,"default-config","blank","index.js");if(b&&h(b))return{path:b}}}}),f.onResolve({filter:/^@domql\//},c=>{const i=c.path.replace("@symbo.ls/","");if(e.isMonorepo){const u=m(e.monorepoRoot,"packages","domql","packages",i,"src","index.js");if(h(u))return{path:u};const d=m(e.monorepoRoot,"packages","domql","packages",i,"index.js");if(h(d))return{path:d}}else{const u=Ee(e,i,"src","index.js");if(u&&h(u))return{path:u};const d=Ee(e,i,"index.js");if(d&&h(d))return{path:d}}}),f.onResolve({filter:/^css-in-props/},c=>{let i;if(e.isMonorepo)i=m(e.monorepoRoot,"packages","css-in-props");else{const b=U(e,"css-in-props/package.json");b&&(i=_(b))}if(!i)return;const u=c.path.replace(/^css-in-props\/?/,"");if(u){const b=m(i,u),E=m(b,"index.js");if(h(E))return{path:E};if(h(b+".js"))return{path:b+".js"};if(h(b))return{path:b}}const d=s(i);if(d)return{path:d}}),f.onResolve({filter:/^@emotion\//},c=>{let i;if(e.isMonorepo)i=m(e.monorepoRoot,"node_modules",c.path);else{const u=U(e,`${c.path}/package.json`);if(!u)return;i=_(u)}if(h(i)){const u=m(i,"package.json");if(h(u))try{const d=JSON.parse(X(u,"utf8")),b=d.module||d.main||"dist/emotion-css.esm.js";return{path:m(i,b)}}catch{}return{path:i}}}),f.onResolve({filter:/\.json$/},c=>{if(c.resolveDir){const i=m(c.resolveDir,c.path);if(h(i))return{path:i}}}),f.onLoad({filter:/smbls\/.*options\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("options.js"))return;let i=X(c.path,"utf8");return i=i.replace(/import\s*\{[^}]*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"][^;\n]*/,"const version = '0.0.0'"),i=i.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:i,loader:"js"}}),f.onLoad({filter:/smbls\/.*init\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("init.js"))return;let i=X(c.path,"utf8");return i=i.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:i,loader:"js"}}),f.onLoad({filter:/.*/,namespace:"brender-stub"},()=>({contents:"export const SyncComponent = {}; export const Inspect = {}; export const Notifications = {}; export const syncPlugin = () => ({}); export const notificationsPlugin = () => ({}); export const seedRawDesignSystem = () => {}; export const inspectPlugin = () => ({}); export default {}",loader:"js"})),f.onLoad({filter:/smbls\/src\/router\.js$/},async c=>{let i=X(c.path,"utf8");return i=i.replace(/import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,"const Link = { tag: 'a', attr: { href: (el) => el.href } }"),{contents:i,loader:"js"}}),f.onLoad({filter:/fetchOnCreate\.js$/},async c=>{if(!c.path.includes("smbls/"))return;let i=X(c.path,"utf8");return i=i.replace(/window\s*&&\s*window\.location\s*\?\s*window\.location\.host\.includes/g,"window && window.location && window.location.host ? window.location.host.includes"),{contents:i,loader:"js"}})}};await o.build({entryPoints:[t],bundle:!0,format:"esm",platform:"node",outfile:n,write:!0,logLevel:"warning",plugins:[l],nodePaths:e.isMonorepo?[m(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[m(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[m(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[m(e.smblsRoot,"..","..","node_modules")]:[]].filter(f=>h(f)),supported:{"import-attributes":!1},external:["fs","path","os","crypto","url","http","https","stream","util","events","buffer","child_process","worker_threads","net","tls","dns","dgram","zlib","assert","querystring","string_decoder","readline","perf_hooks","async_hooks","v8","vm","cluster","inspector","module","process","tty","color-contrast-checker","linkedom"]});const g=await import(`file://${n}`);if(process.env.BRENDER_DEBUG)console.log("[brender] Bundle saved:",n);else try{Ye(n)}catch{}return g},jt={Box:{},Focusable:{},Block:{display:"block"},Inline:{display:"inline"},Flex:{display:"flex"},InlineFlex:{display:"inline-flex"},Grid:{display:"grid"},InlineGrid:{display:"inline-grid"},Link:{tag:"a",attr:{href:e=>e.href,target:e=>e.target,rel:e=>e.rel}},A:{extends:"Link"},RouteLink:{extends:"Link"},Img:{tag:"img",attr:{src:e=>{let t=e.src;return typeof t=="string"&&t.includes("{{")&&(t=e.call("replaceLiteralsWithObjectFields",t,e.state)),t},alt:e=>e.alt,loading:e=>e.loading}},Image:{extends:"Img"},Button:{tag:"button"},FocusableComponent:{tag:"button"},Form:{tag:"form"},Input:{tag:"input"},TextArea:{tag:"textarea"},Textarea:{tag:"textarea"},Select:{tag:"select"},Label:{tag:"label"},Iframe:{tag:"iframe"},Video:{tag:"video"},Audio:{tag:"audio"},Canvas:{tag:"canvas"},Span:{tag:"span"},P:{tag:"p"},H1:{tag:"h1"},H2:{tag:"h2"},H3:{tag:"h3"},H4:{tag:"h4"},H5:{tag:"h5"},H6:{tag:"h6"},Svg:{tag:"svg",attr:{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}},Text:{tag:"span"}},Tt=(e,t)=>{const o={};return Le(e,(n,s)=>{if(!s.__brKey)return;const r=t(n);o[r===""?"__root":r]=s.__brKey}),o},Le=(e,t)=>{const o=n=>{const s=n&&n.__ref;if(s&&(t(n,s),s.__children))for(const r of s.__children)o(n[r])};o(e)},Et=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let W=0;const $e=Symbol.for("brender.fetchTracked"),me=()=>W,_t=256*1024,vt=1024*1024,Lt=new Set(["accept-language","accept"]),De={renders:0,record:null},$t=50,de={renders:0,record:null},Ae=(e,t)=>{e.renders++,e.renders===1?e.record=t():e.record&&(e.record.tainted=!0);const o=e.record;return{record:o,close:()=>{e.renders--,e.record===o&&(e.record=null)}}},ge=e=>e.record&&!e.record.tainted?e.record:null,Dt=e=>{try{const t=new URL(e);return t.origin+t.pathname}catch{return String(e).split("?")[0]}},he=(e,t,o)=>{!e||e.tainted||e.failures.length>=$t||e.failures.push({url:Dt(t),reason:o})},Ce=e=>e&&typeof e=="object"&&typeof e.url=="string"?e.url:String(e),At=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",s=Ce(t),r=String(o&&o.method||n&&t.method||"GET").toUpperCase(),a={},p=l=>{if(!l)return;const g=!Array.isArray(l)&&typeof l.entries!="function";for(const[f,c]of it(l))g&&c==null||(a[String(f).toLowerCase()]=String(c))};return n&&p(t.headers),o&&p(o.headers),{url:s,method:r,headers:a}},Ct=(e,t,o,n)=>{if(!o||!o.ok||typeof o.clone!="function")return;const s=o.headers&&o.headers.get&&o.headers.get("content-type")||"";if(!/json|^text\//i.test(s))return;let r;try{r=o.clone()}catch{return}n(r.text().then(a=>{e.tainted||a.length>_t||e.bytes+a.length>vt||(e.bytes+=a.length,e.entries.push({url:t.url,lang:t.headers["accept-language"]||"",status:o.status,type:s,body:a}))},()=>{}))},qt=()=>{const e=globalThis.fetch;if(typeof e!="function"||e[$e])return;const t=function(...o){W++;let n=!1;const s=()=>{n||(n=!0,W--)},r=c=>{W++,c.then(()=>{W--},()=>{W--})},a=ge(De),p=ge(de);let l=null;if(a)try{l=At(o),(l.method!=="GET"||!/^https?:/i.test(l.url)||Object.keys(l.headers).some(c=>!Lt.has(c)))&&(l=null)}catch{l=null}const g=()=>Ce(o[0]);let f;try{f=e.apply(this,o)}catch(c){throw he(p,g(),c&&c.message||"failed"),s(),c}return f&&typeof f.then=="function"?f.then(c=>{l&&Ct(a,l,c,r),p&&c&&c.ok===!1&&he(p,g(),"HTTP "+c.status),s()},c=>{he(p,g(),c&&c.message||"network error"),s()}):s(),f};t[$e]=!0,globalThis.fetch=t},Fo=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=pt(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
2
+ `+at(t):""):`<script>window.__BR_REGISTRY__=${n}<\/script>`},Mt=3e4,It=2147483647;let qe=Promise.resolve();const Me=()=>{},Ot=e=>{const t=qe.then(e);return qe=t.then(Me,Me),t},Pt=e=>{if(e===void 0)return Mt;if(e===0||e===!1||e===1/0)return 0;if(typeof e!="number"||!(e>0))throw new TypeError(`brender: options.timeout is a number of milliseconds, or 0 / false for no limit \u2014 not ${JSON.stringify(e)}`);return Math.min(e,It)},Ft=(e,t)=>{const o=e.route||"/",n=e.pathname||o,s=n===o?o:`${n} (route ${o})`,r=new Error(`brender: the render of ${s} did not finish within ${t} ms and was abandoned, so the renders after it can run (options.timeout)`);return r.code="BRENDER_RENDER_TIMEOUT",r.route=o,r.pathname=n,r.timeout=t,r},Bt=e=>{e.closed=!0;for(const t of e.undo.splice(0))t()},Kt=e=>{let t=!1;return()=>{t||(t=!0,e())}},Ie=(e,t={})=>{let o;try{o=Pt(t.timeout)}catch(n){return Promise.reject(n)}return Ot(()=>Gt(e,t,o))},Gt=async(e,t,o)=>{await ve();const n={closed:!1,undo:[]},s=Nt(e,t,n);if(!o)return s;let r;const a=new Promise((p,l)=>{r=setTimeout(()=>{Bt(n),l(Ft(t,o))},o)});try{return await Promise.race([s,a])}finally{clearTimeout(r)}},Nt=async(e,t,o)=>{const{route:n="/",pathname:s,state:r,context:a,prefetch:p=!1}=t,l=s||n;qt();const g=Ae(de,()=>({failures:[],labelKeys:new Set,tainted:!1}));try{return await Ht(e,{route:n,locationPath:l,stateOverrides:r,contextOverrides:a,prefetch:p},g.record,o)}finally{g.close()}},Ht=async(e,{route:t,locationPath:o,stateOverrides:n,contextOverrides:s,prefetch:r},a,p)=>{const l=()=>{if(p.closed)throw new Error("brender: this render was abandoned at its timeout")};let g;if(r){try{g=await ct(e)}catch(d){p.closed||console.warn("[brender] SSR translation fetch failed:",d.message)}l()}const{window:f,document:c}=Re(),i=c.body;f.location.pathname=o;const u=[ae("document",c),ae("location",f.location),ae("localStorage",f.localStorage),ae("sessionStorage",f.sessionStorage)].map(Kt);p.undo.push(...u);try{const{createDomqlElement:d,PRERENDER_REGISTRY_FORMATS:b}=await ve();l();const E=$(e.app||{}),x={...e.config||{}};e.polyglot&&!x.polyglot&&(x.polyglot=e.polyglot),e.fetch&&!x.fetch&&(x.fetch=e.fetch),e.router&&!x.router&&(x.router=e.router);for(const y of Vt)e[y]!=null&&x[y]==null&&(x[y]=e[y]);const w=x.polyglot?{...x.polyglot}:void 0,Q=mt(o,w);Q&&f.localStorage.setItem(ut(w),Q),g&&w&&(w.translations={...w.translations||{},...g});const v=$(e.state||{});(g||w)&&(v.root||(v.root={}),w&&(v.root.lang=oe(v.root.lang,w)),g&&(v.root.translations={...v.root.translations||{},...g})),St();const P={};for(const y in e){if(Et.has(y))continue;const k=e[y];P[y]=k&&typeof k=="object"?$(k):k}const D={...P,state:v,...n?{state:{...v,...n}}:{},dependencies:$(e.dependencies||{}),components:$(e.components||{}),snippets:$(e.snippets||{}),pages:$(e.pages||{}),functions:{...e.functions||{},polyglot:Rt,getActiveLang:Te,getLang:Te},methods:e.methods||{},designSystem:$(e.designSystem||{}),files:e.files||{},sharedLibraries:e.sharedLibraries||[],...x,...w?{polyglot:w}:{},document:c,window:f,parent:{node:i},initOptions:{},domqlOptions:{sourcemap:!1},firstRender:!1,sync:!1,inspect:!1,notifications:!1,isolateDesignSystem:!0,isolateFetchCache:!0,captureDesignSystem:!0,...s||{}},N=await yt();l(),N&&(D.plugins=D.plugins||[],D.plugins.some(y=>y.name==="funcql")||D.plugins.push(N)),ke();const S=Ae(De,()=>({entries:[],bytes:0,tainted:!1})),A=S.record;let j;try{j=await d(E,D),l();const y=Date.now(),k=r?2e3:50,R=T=>new Promise(G=>setTimeout(G,T));for(await R(Math.min(50,k));r&&!p.closed&&me()>0&&Date.now()-y<k;)await R(10),me()===0&&await R(Math.max(0,Math.min(50,k-(Date.now()-y))));if(l(),r&&await Ut(j,w)){l();const T=Date.now();for(await R(Math.min(50,k));!p.closed&&me()>0&&Date.now()-T<k;)await R(10);l()}}finally{S.close()}const C=A&&!A.tainted&&!(x.fetch&&x.fetch.seed===!1)?A.entries.slice():[];we(i);const J=xe(j),{elementPath:Y}=await import("@symbo.ls/element");l();const Z=Tt(j,Y),z=j?.context?.routerOptions?.contentElementKey||"content",F=j&&j[z],q=F&&typeof F=="object"&&F.__ref?F:void 0,Se=pe(e,t,j,j?.state,q),M=[],V=c.head||c.querySelector("head");if(V)for(const y of V.querySelectorAll("style")){if(y.sheet&&y.sheet.cssRules)for(const k of y.sheet.cssRules)k.cssText&&M.push(k);if(!M.length){const k=y.textContent||"";k&&M.push({cssText:k})}}const ee=M.map(y=>y.cssText),{globalCSS:te,classRules:le}=oo(M);let L=Fe(i.innerHTML);const B=j?.state?.root,K=re(B,w),I=Wt(g,B);I&&(L=Pe(L,Oe(I,K,w)));const H=a&&!a.tainted?{failedRequests:a.failures.slice(),rawLabelKeys:zt(a.labelKeys,L,K,w,B)}:null;return{html:L,metadata:Se,registry:J,brRegistry:Z,element:j,emotionCSS:ee,globalCSS:te,classRules:le,fetchSeed:C,document:c,window:f,ssrTranslations:I||void 0,activeLang:K,diagnostics:H,preparedDesignSystem:D.preparedDesignSystem||null,registryFormats:Array.isArray(b)?b.slice():["paths"]}}finally{for(const d of u)d()}},ae=(e,t)=>{const o=Object.getOwnPropertyDescriptor(globalThis,e);return o&&!o.configurable?!o.writable&&!o.set?()=>{}:(globalThis[e]=t,()=>{}):(Object.defineProperty(globalThis,e,{value:t,writable:!0,configurable:!0,enumerable:!0}),()=>{o?Object.defineProperty(globalThis,e,o):delete globalThis[e]})},Ut=async(e,t)=>{if(!t||!t.fetch||!e||typeof e.call!="function")return!1;const o=e.state&&e.state.root;if(!o)return!1;const n=re(o,t),s=o.translations&&o.translations[n];if(s&&typeof s=="object"&&Object.keys(s).length||t.translations&&t.translations[n])return!1;try{await e.call("loadTranslations",n,{inFlight:!0})}catch{}return!0},ye=/\{\{\s*([^|{}]+?)\s*\|\s*polyglot\s*\}\}/g,be=e=>e&&typeof e.parse=="function"?e.parse():e,Wt=(e,t)=>{const o=be(t?.translations),n={};for(const s of[e,o])if(!(!s||typeof s!="object"))for(const r in s){const a=be(s[r]);a&&typeof a=="object"&&(n[r]={...n[r]||{},...a})}return Object.keys(n).length?n:null},Oe=(e,t,o)=>e[t]||e[oe(void 0,o)]||Object.values(e)[0]||{},Pe=(e,t)=>e.replace(ye,(o,n)=>se(t,n.trim())??o),Jt=/<script\b[^>]*\btype\s*=\s*["']?application\/json["']?[^>]*>[\s\S]*?<\/script\s*>/gi,Yt=(e,t)=>new RegExp(`(?:^|[^\\w.-])${ft(t)}(?![\\w-]|\\.\\w)`).test(e),zt=(e,t,o,n,s)=>{const r=new Set,a=t.replace(Jt,"");for(const p of e)/\s/.test(p)||je(p,o,n,s)===void 0&&Yt(a,p)&&r.add(p);for(const p of a.matchAll(ye))r.add(p[1].trim());return[...r]},Bo=async(e,t={})=>{const{context:o={}}=t,{window:n,document:s}=Re(),r=s.body,{create:a}=await import("@symbo.ls/element"),p=await import("@symbo.ls/utils"),l={...jt,...o.components||{}},g={...p,...o.utils||{},...o.functions||{}};ke();let f;try{f=a(e,{node:r},"root",{context:{document:s,window:n,...o,components:l,utils:g}})}catch{}we(r);const c=f?xe(f):{};return{html:Fe(r.innerHTML),registry:c,element:f}},Fe=e=>e.replace(/(<svg\b[^>]*>)([\s\S]*?)(<\/svg>)/gi,(t,o,n,s)=>{if(n.includes("&lt;")){const r=n.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&#39;/g,"'");return o+r+s}return t}),Vt=["globalTheme","themeStorageKey","themeRoot","useReset","useVariable","useFontImport","useIconSprite","useSvgSprite","useDocumentTheme","useDefaultConfig","useDefaultIcons","useThemeSuffixedVars","verbose","semanticIcons"],Xt=new Set(["auto","system"]),Be=e=>{if(!e||typeof e!="object")return null;const t=e.config&&typeof e.config=="object"?e.config:{};if((t.themeRoot!=null?t.themeRoot:e.themeRoot)!=null)return null;const n=t.globalTheme!=null?t.globalTheme:e.globalTheme;if(typeof n!="string")return null;const s=n.trim();return!s||Xt.has(s)?null:s},Qt=e=>String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Zt=/\.[A-Za-z_\\-]/,eo=e=>{if(typeof e!="string"||!e)return!1;const t=e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,'""').replace(/\[[^\]]*\]/g,"[]");return!Zt.test(t)},to=/^\s*(:root|\[data-theme|\[data-skin)/,Ke=e=>{const t=e&&e.cssText;if(typeof t!="string")return null;if(/^@(-webkit-)?keyframes\b/.test(t))return"keyframes";if(t.startsWith("@font-face"))return null;if(typeof e.selectorText=="string")return eo(e.selectorText)?to.test(e.selectorText)?"root":"reset":null;const o=e.cssRules&&Array.from(e.cssRules);if(o&&o.length&&/^@(media|supports|container)\b/.test(t)){const n=new Set(o.map(Ke));return n.has(null)||n.size!==1?n.has(null)?null:"reset":[...n][0]}return null},Ge=e=>typeof e=="string"&&/^\s*@font-face\b/i.test(e),oo=e=>{const t={root:[],reset:[],keyframes:[]},o=[];for(const n of e||[]){const s=Ke(n);s?t[s].push(n.cssText):n&&n.cssText&&o.push(n.cssText)}return{globalCSS:{rootRule:t.root.join(`
3
3
  `),resetRules:t.reset.join(`
4
4
  `),keyframeRules:t.keyframes.join(`
5
- `),fontFaceCSS:""},classRules:o}};let V=new Set;const Oo=()=>{V=new Set},Po=()=>Array.from(V).join(`
6
- `),Fo=(e,t)=>e.replace(/<style data-emotion="smbls">[\s\S]*?<\/style>/,t?`<style data-emotion="smbls">
5
+ `),fontFaceCSS:""},classRules:o}};let ie=new Set;const Ko=()=>{ie=new Set},Go=()=>Array.from(ie).join(`
6
+ `),No=(e,t)=>e.replace(/<style data-emotion="smbls">[\s\S]*?<\/style>/,t?`<style data-emotion="smbls">
7
7
  ${t}
8
- </style>`:""),Bo=async(e,t={})=>{const{route:o="/",pathname:n,prefetch:s=!0,timeout:r}=t,i=await Me(e,{route:o,pathname:n,prefetch:s,timeout:r});if(!i)return null;const f=e.designSystem||{},l=i.globalCSS;let g=null;try{const c=eo(i.element);Object.keys(c).length&&(g=c)}catch{}const p=i.activeLang;return{html:i.html,css:i.classRules.join(`
9
- `),classRules:i.classRules.slice(),globalCSS:l,resetCss:l.resetRules,fontLinks:Ge(f),metadata:i.metadata||pe(e,o),brKeyCount:i.registry?Object.keys(i.registry).length:0,brRegistry:i.brRegistry||{},fetchSeed:i.fetchSeed||[],ssrTranslations:i.ssrTranslations,prefetchedState:g,activeLang:p,theme:Fe(e),diagnostics:i.diagnostics,preparedDesignSystem:i.preparedDesignSystem||null}},eo=e=>{const t={};return ve(e,o=>{const n=o.fetch;if(!(!n||typeof n!="object"||!o.state))for(const s of Array.isArray(n)?n:[n]){const r=s&&typeof s=="object"&&typeof s.as=="string"?s.as:null;if(!r)continue;const i=r.startsWith("~/"),f=i?r.slice(2):r,l=i?o.state.root:o.state,g=ye(l&&l[f]);f&&g!=null&&typeof g!="function"&&(t[f]=g)}}),t},Ko=async(e,t="/",o={})=>{const{lang:n,themeColor:s,isr:r,hydrate:i=!0,prefetch:f=!0,shell:l,adoptDom:g=!1,pathname:p,eagerImages:c=Ke,preloadScripts:a=!0,nonce:u,timeout:d,stamp:b,time:E,spriteIcons:x="all",cssClasses:w="all",cssVariables:X="all",registryFormat:v="paths"}=o,P=co(u),A=n||e.state?.lang||e.app?.metadata?.lang||"en",G=Fe(e),S=await Me(e,{route:t,pathname:p,prefetch:f,timeout:d});if(!S)return null;const C={...S.metadata};if(s&&(C["theme-color"]=s),typeof l=="string"&&!e.name){const R="\0brender-undeclared-title\0";if(pe({...e,name:R},t,S.element,S.element?.state).title===R)for(const y of["title","og:title","twitter:title"])C[y]===S.metadata.title&&delete C[y]}const j=Xe(C);for(const R of S.classRules)R&&V.add(R);let q=no(S.html,c);x==="page"&&(q=Ze(q,typeof l=="string"?l:"").html);const W=w==="page"?et(Array.from(V),tt(q,typeof l=="string"?l:"")).join(`
10
- `):Array.from(V).join(`
11
- `),M=S.globalCSS,Q=`<style data-brender>
12
- ${(X==="page"?ot(M.rootRule||"",M.resetRules,M.keyframeRules,W,q,typeof l=="string"?l:"").css:M.rootRule)||""}
13
- ${M.resetRules||""}
14
- ${M.keyframeRules||""}
15
- </style>`,F=W?`<style data-emotion="smbls">
16
- ${W}
17
- </style>`:"",Z=Ge(e.designSystem||{}),ee=Object.keys(S.registry).length,B=v==="tree"||v==="auto"&&(S.registryFormats||[]).includes("tree"),I=so({brRegistry:S.brRegistry,fetchSeed:S.fetchSeed,adoptDom:g,stamp:b,time:E,registryFormat:B?"tree":"paths"});let J="";if(r&&r.clientScript){const R=Number.isInteger(o.depth)?o.depth:t==="/"?0:t.replace(/^\/|\/$/g,"").split("/").length,T=R>0?"../".repeat(R):"./";if(i){const y=mt({polyglot:e.polyglot||e.config?.polyglot,translations:S.ssrTranslations,lang:S.activeLang,pathname:p||t,attrs:P}),k=y?y+`
18
- `:"",K=I.blocks?I.blocks+`
19
- `:"";J=`${k}${K}<script type="module" src="${T}${r.clientScript}"${P}><\/script>`}else J=`<script type="module"${P}>
8
+ </style>`:""),Ho=async(e,t={})=>{const{route:o="/",pathname:n,prefetch:s=!0,timeout:r}=t,a=await Ie(e,{route:o,pathname:n,prefetch:s,timeout:r});if(!a)return null;const p=e.designSystem||{},l=a.globalCSS;let g=null;try{const c=no(a.element);Object.keys(c).length&&(g=c)}catch{}const f=a.activeLang;return{html:a.html,css:a.classRules.join(`
9
+ `),classRules:a.classRules.slice(),globalCSS:l,resetCss:l.resetRules,fontLinks:He(p),metadata:a.metadata||pe(e,o),brKeyCount:a.registry?Object.keys(a.registry).length:0,brRegistry:a.brRegistry||{},fetchSeed:a.fetchSeed||[],ssrTranslations:a.ssrTranslations,prefetchedState:g,activeLang:f,theme:Be(e),diagnostics:a.diagnostics,preparedDesignSystem:a.preparedDesignSystem||null}},no=e=>{const t={};return Le(e,o=>{const n=o.fetch;if(!(!n||typeof n!="object"||!o.state))for(const s of Array.isArray(n)?n:[n]){const r=s&&typeof s=="object"&&typeof s.as=="string"?s.as:null;if(!r)continue;const a=r.startsWith("~/"),p=a?r.slice(2):r,l=a?o.state.root:o.state,g=be(l&&l[p]);p&&g!=null&&typeof g!="function"&&(t[p]=g)}}),t},Uo=async(e,t="/",o={})=>{const{lang:n,themeColor:s,isr:r,hydrate:a=!0,prefetch:p=!0,shell:l,adoptDom:g=!1,pathname:f,eagerImages:c=Ne,preloadScripts:i=!0,nonce:u,timeout:d,stamp:b,time:E,spriteIcons:x="all",cssClasses:w="all",cssVariables:Q="all",registryFormat:v="paths"}=o,P=lo(u),D=n||e.state?.lang||e.app?.metadata?.lang||"en",N=Be(e),S=await Ie(e,{route:t,pathname:f,prefetch:p,timeout:d});if(!S)return null;const A={...S.metadata};if(s&&(A["theme-color"]=s),typeof l=="string"&&!e.name){const R="\0brender-undeclared-title\0";if(pe({...e,name:R},t,S.element,S.element?.state).title===R)for(const G of["title","og:title","twitter:title"])A[G]===S.metadata.title&&delete A[G]}const j=et(A);for(const R of S.classRules)R&&ie.add(R);let C=co(S.html,c);x==="page"&&(C=ot(C,typeof l=="string"?l:"").html);const J=Array.from(ie),Y=J.filter(Ge),Z=Y.length?J.filter(R=>!Ge(R)):J,z=w==="page"?nt(Z,st(C,typeof l=="string"?l:"")).join(`
10
+ `):Z.join(`
11
+ `),F=Y.length?`<style data-smbls-faces>
12
+ ${Y.join(`
13
+ `)}
14
+ </style>`:"",q=S.globalCSS,M=`<style data-brender>
15
+ ${(Q==="page"?rt(q.rootRule||"",q.resetRules,q.keyframeRules,z,C,typeof l=="string"?l:"").css:q.rootRule)||""}
16
+ ${q.resetRules||""}
17
+ ${q.keyframeRules||""}
18
+ </style>`,V=z?`<style data-emotion="smbls">
19
+ ${z}
20
+ </style>`:"",ee=He(e.designSystem||{}),te=Object.keys(S.registry).length,le=v==="tree"||v==="auto"&&(S.registryFormats||[]).includes("tree"),L=ao({brRegistry:S.brRegistry,fetchSeed:S.fetchSeed,adoptDom:g,stamp:b,time:E,registryFormat:le?"tree":"paths"});let B="";if(r&&r.clientScript){const R=Number.isInteger(o.depth)?o.depth:t==="/"?0:t.replace(/^\/|\/$/g,"").split("/").length,T=R>0?"../".repeat(R):"./";if(a){const G=dt({polyglot:e.polyglot||e.config?.polyglot,translations:S.ssrTranslations,lang:S.activeLang,pathname:f||t,attrs:P}),Ue=G?G+`
21
+ `:"",We=L.blocks?L.blocks+`
22
+ `:"";B=`${Ue}${We}<script type="module" src="${T}${r.clientScript}"${P}><\/script>`}else B=`<script type="module"${P}>
20
23
  {
21
24
  const brEls = document.querySelectorAll('body > :not(script):not(style)')
22
25
  const observer = new MutationObserver((mutations) => {
@@ -33,23 +36,23 @@ ${W}
33
36
  observer.observe(document.body, { childList: true })
34
37
  }
35
38
  <\/script>
36
- <script type="module" src="${T}${r.clientScript}"${P}><\/script>`}const Y={...e.config||{}};e.polyglot&&!Y.polyglot&&(Y.polyglot=e.polyglot);const N=Y.polyglot;let D=j;if(N){const R={...N.translations||{}};for(const T in S.ssrTranslations||{})R[T]={...R[T]||{},...S.ssrTranslations[T]};D=Oe(j,Ie(R,S.activeLang,N))}const $=S.diagnostics;if($)for(const R of D.matchAll(he)){const T=R[1].trim();$.rawLabelKeys.includes(T)||$.rawLabelKeys.push(T)}return typeof l=="string"?{html:Qe(l,{headTags:`${D}
37
- ${I.meta}`,headEnd:[Z,Q,F].filter(Boolean).join(`
38
- `),body:q,depth:Number.isInteger(o.depth)?o.depth:0,bootScripts:I.blocks,lang:n||(N?S.activeLang:void 0),theme:G,preloadScripts:a}),route:t,brKeyCount:ee,shell:!0,diagnostics:$,preparedDesignSystem:S.preparedDesignSystem||null}:{html:`<!DOCTYPE html>
39
- <html lang="${A}"${G?` data-theme="${zt(G)}"`:""}>
39
+ <script type="module" src="${T}${r.clientScript}"${P}><\/script>`}const K={...e.config||{}};e.polyglot&&!K.polyglot&&(K.polyglot=e.polyglot);const I=K.polyglot;let H=j;if(I){const R={...I.translations||{}};for(const T in S.ssrTranslations||{})R[T]={...R[T]||{},...S.ssrTranslations[T]};H=Pe(j,Oe(R,S.activeLang,I))}const y=S.diagnostics;if(y)for(const R of H.matchAll(ye)){const T=R[1].trim();y.rawLabelKeys.includes(T)||y.rawLabelKeys.push(T)}return typeof l=="string"?{html:tt(l,{headTags:`${H}
40
+ ${L.meta}`,headEnd:[ee,F,M,V].filter(Boolean).join(`
41
+ `),body:C,depth:Number.isInteger(o.depth)?o.depth:0,bootScripts:L.blocks,lang:n||(I?S.activeLang:void 0),theme:N,preloadScripts:i}),route:t,brKeyCount:te,shell:!0,diagnostics:y,preparedDesignSystem:S.preparedDesignSystem||null}:{html:`<!DOCTYPE html>
42
+ <html lang="${D}"${N?` data-theme="${Qt(N)}"`:""}>
40
43
  <head>
41
- ${D}${r&&r.clientScript&&i?`
42
- ${I.meta}`:""}
43
- ${Z}
44
-
45
- ${Q}
44
+ ${H}${r&&r.clientScript&&a?`
45
+ ${L.meta}`:""}
46
+ ${ee}
46
47
  ${F}
48
+ ${M}
49
+ ${V}
47
50
  </head>
48
51
  <body>
49
- ${q}
50
- ${J}
52
+ ${C}
53
+ ${B}
51
54
  </body>
52
- </html>`,route:t,brKeyCount:ee,diagnostics:$,preparedDesignSystem:S.preparedDesignSystem||null}},Ke=2,to=/<img\b(?:[^>"']|"[^"]*"|'[^']*')*>/gi,oo=/\sloading\s*=/i,no=(e,t=Ke)=>{if(t===!1||t==null||typeof e!="string")return e;const o=Math.max(0,Number(t)||0);let n=0;return e.replace(to,s=>n++<o||oo.test(s)?s:s.replace(/^<img\b/i,'<img loading="lazy"'))},Ge=e=>{if(!e)return"";const t=e.font_family||e.fontFamily||{},o=new Set;for(const s of Object.values(t)){if(typeof s!="string")continue;const r=s.match(/'([^']+)'/);r&&o.add(r[1])}return o.size?['<link rel="preconnect" href="https://fonts.googleapis.com">','<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>',`<link href="https://fonts.googleapis.com/css2?${[...o].map(s=>`family=${s.replace(/\s+/g,"+")}:wght@300;400;500;600;700`).join("&")}&display=swap" rel="stylesheet">`].join(`
53
- `):""},so=({brRegistry:e,fetchSeed:t,adoptDom:o=!1,stamp:n,time:s,registryFormat:r="paths"}={})=>{const f=o&&e&&Object.keys(e).length?r==="tree"&&it(e)||ct(e):"",l=gt(t);return{meta:`<meta name="brender" content="${f?"hydrate":"replace"}">
54
- `+at(ro(n,s)),blocks:[f,l].filter(Boolean).join(`
55
- `)}},ro=(e,t)=>{const o=typeof t=="number"&&isFinite(t)?Math.round(t):Date.now();return{stamp:e!=null&&e!==""?String(e):new Date(o).toISOString(),time:o}},co=e=>{if(e==null||e==="")return"";const t=String(e);if(!/^[A-Za-z0-9+/=_-]+$/.test(t))throw new Error("brender: a nonce is base64 or base64url text");return` nonce="${t}"`};export{Ke as EAGER_IMAGES_DEFAULT,Te as SMBLS_SSR_SPECIFIER,Mo as adoptionScripts,ro as buildStamp,Fe as fixedThemeOf,Po as getAccumulatedEmotionCSS,no as markLazyImages,so as prerenderParts,Me as render,Io as renderElement,Ko as renderPage,Bo as renderRoute,Fo as replaceEmotionCSS,Oo as resetGlobalCSSCache,Zt as splitCapturedCSS};
55
+ </html>`,route:t,brKeyCount:te,diagnostics:y,preparedDesignSystem:S.preparedDesignSystem||null}},Ne=2,so=/<img\b(?:[^>"']|"[^"]*"|'[^']*')*>/gi,ro=/\sloading\s*=/i,co=(e,t=Ne)=>{if(t===!1||t==null||typeof e!="string")return e;const o=Math.max(0,Number(t)||0);let n=0;return e.replace(so,s=>n++<o||ro.test(s)?s:s.replace(/^<img\b/i,'<img loading="lazy"'))},He=e=>{if(!e)return"";const t=e.font_family||e.fontFamily||{},o=new Set;for(const s of Object.values(t)){if(typeof s!="string")continue;const r=s.match(/'([^']+)'/);r&&o.add(r[1])}return o.size?['<link rel="preconnect" href="https://fonts.googleapis.com">','<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>',`<link href="https://fonts.googleapis.com/css2?${[...o].map(s=>`family=${s.replace(/\s+/g,"+")}:wght@300;400;500;600;700`).join("&")}&display=swap" rel="stylesheet">`].join(`
56
+ `):""},ao=({brRegistry:e,fetchSeed:t,adoptDom:o=!1,stamp:n,time:s,registryFormat:r="paths"}={})=>{const p=o&&e&&Object.keys(e).length?r==="tree"&&ht(e)||gt(e):"",l=bt(t);return{meta:`<meta name="brender" content="${p?"hydrate":"replace"}">
57
+ `+lt(io(n,s)),blocks:[p,l].filter(Boolean).join(`
58
+ `)}},io=(e,t)=>{const o=typeof t=="number"&&isFinite(t)?Math.round(t):Date.now();return{stamp:e!=null&&e!==""?String(e):new Date(o).toISOString(),time:o}},lo=e=>{if(e==null||e==="")return"";const t=String(e);if(!/^[A-Za-z0-9+/=_-]+$/.test(t))throw new Error("brender: a nonce is base64 or base64url text");return` nonce="${t}"`};export{Ne as EAGER_IMAGES_DEFAULT,_e as SMBLS_SSR_SPECIFIER,Fo as adoptionScripts,io as buildStamp,Be as fixedThemeOf,Go as getAccumulatedEmotionCSS,co as markLazyImages,ao as prerenderParts,Ie as render,Bo as renderElement,Uo as renderPage,Ho as renderRoute,No as replaceEmotionCSS,Ko as resetGlobalCSSCache,oo as splitCapturedCSS};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbo.ls/brender",
3
- "version": "3.14.671",
3
+ "version": "3.14.673",
4
4
  "license": "CC-BY-NC-4.0",
5
5
  "type": "module",
6
6
  "module": "./dist/esm/index.js",
@@ -52,12 +52,12 @@
52
52
  "@symbo.ls/fetch": "^3.14.669",
53
53
  "@symbo.ls/helmet": "^3.14.671",
54
54
  "@symbo.ls/scratch": "^3.14.795",
55
- "@symbo.ls/utils": "^3.14.848",
55
+ "@symbo.ls/utils": "^3.14.849",
56
56
  "esbuild": "^0.28.1",
57
57
  "linkedom": "^0.16.8"
58
58
  },
59
59
  "peerDependencies": {
60
- "smbls": "^3.14.848"
60
+ "smbls": "^3.14.851"
61
61
  },
62
62
  "optionalDependencies": {
63
63
  "@symbo.ls/funcql": "^3.14.0"
package/render.js CHANGED
@@ -14,7 +14,8 @@ import { trimSpriteToPage, classRulesForPage, markupClasses, trimVariablesToPage
14
14
  import { fetchSSRTranslations } from './prefetch.js'
15
15
  import { createEarlySeedScript } from '@symbo.ls/fetch'
16
16
  import { headerEntries } from '@symbo.ls/fetch/rest'
17
- import { brenderRegistryBlock, brenderRegistryTreeBlock, brenderStampMeta, escapeRegExp, jsonForScript, polyglotFallbackLang, polyglotLangStorageKey, polyglotAddressLang, polyglotStartupScript } from '@symbo.ls/utils'
17
+ import { brenderStampMeta, escapeRegExp, jsonForScript, polyglotFallbackLang, polyglotLangStorageKey, polyglotAddressLang, polyglotStartupScript } from '@symbo.ls/utils'
18
+ import { brenderRegistryBlock, brenderRegistryTreeBlock } from '@symbo.ls/utils/server'
18
19
 
19
20
  // funcql plugin — enables evaluation of funcql schemas as property values
20
21
  // during SSR. Async-imported to avoid polluting non-funcql codepaths.
@@ -1693,6 +1694,9 @@ const classifyRule = (rule) => {
1693
1694
  return null
1694
1695
  }
1695
1696
 
1697
+ // An @font-face rule's text (renderPage keeps them apart, see facesStyle).
1698
+ const isFontFaceText = (text) => typeof text === 'string' && /^\s*@font-face\b/i.test(text)
1699
+
1696
1700
  export const splitCapturedCSS = (rules) => {
1697
1701
  const groups = { root: [], reset: [], keyframes: [] }
1698
1702
  const rest = []
@@ -1887,7 +1891,7 @@ const collectFetchedState = (element) => {
1887
1891
  * not read, so it is the project's choice (`brender.cssVariables`)
1888
1892
  * @param {'paths'|'tree'|'auto'} [options.registryFormat='paths'] - with
1889
1893
  * `adoptDom`: the element-path registry as paths, as a tree (the same data
1890
- * in a third of the bytes — @symbo.ls/utils encodeBrenderRegistry), or the
1894
+ * in a third of the bytes — @symbo.ls/utils/server encodeBrenderRegistry), or the
1891
1895
  * tree when the smbls the page renders with reads it
1892
1896
  * @returns {Promise<{ html: string, route: string, brKeyCount: number, shell?: true }>}
1893
1897
  */
@@ -1949,9 +1953,25 @@ export const renderPage = async (data, route = '/', options = {}) => {
1949
1953
  // `cssClasses: 'page'` — of the rules every page so far needed, the ones
1950
1954
  // this page's markup can match (pageWeight.js classRulesForPage, XMA round
1951
1955
  // 8, E12): the client writes the rules of each element it creates itself.
1956
+ //
1957
+ // The @font-face rules go in a <style data-smbls-faces> of their own, ahead
1958
+ // of the server's styles (XMA round 8, "data holds still" on a slow
1959
+ // desktop). The app removes the server's styles once its own are in, and
1960
+ // smbls kept the faces by moving them into a new <style data-smbls-faces> —
1961
+ // a new style sheet, so Chrome made new, unloaded FontFace objects for them:
1962
+ // the text fell back to the system font for a frame or more while the files
1963
+ // were read again, and every block of text changed size during the takeover.
1964
+ // Deleting the other rules from the server's sheet re-creates them too. A
1965
+ // sheet the takeover never touches keeps them loaded; smbls applyFontFaces
1966
+ // finds them declared and adds none of its own (smbls prerender.js
1967
+ // serverStyles does not select it, so it stays for the page's life).
1968
+ const accumulated = Array.from(_accumulatedEmotionCSS)
1969
+ const faceRules = accumulated.filter(isFontFaceText)
1970
+ const classRules = faceRules.length ? accumulated.filter((rule) => !isFontFaceText(rule)) : accumulated
1952
1971
  const emotionCSS = cssClasses === 'page'
1953
- ? classRulesForPage(Array.from(_accumulatedEmotionCSS), markupClasses(bodyHtml, typeof shell === 'string' ? shell : '')).join('\n')
1954
- : Array.from(_accumulatedEmotionCSS).join('\n')
1972
+ ? classRulesForPage(classRules, markupClasses(bodyHtml, typeof shell === 'string' ? shell : '')).join('\n')
1973
+ : classRules.join('\n')
1974
+ const facesStyle = faceRules.length ? `<style data-smbls-faces>\n${faceRules.join('\n')}\n</style>` : ''
1955
1975
 
1956
1976
  // Global CSS (variables, reset, keyframes): this render's own init output.
1957
1977
  // The style tags, built once for both documents below.
@@ -2072,7 +2092,7 @@ export const renderPage = async (data, route = '/', options = {}) => {
2072
2092
  if (typeof shell === 'string') {
2073
2093
  const html = composeIntoShell(shell, {
2074
2094
  headTags: `${resolvedHeadTags}\n${prerender.meta}`,
2075
- headEnd: [fontLinks, brenderStyle, emotionStyle].filter(Boolean).join('\n'),
2095
+ headEnd: [fontLinks, facesStyle, brenderStyle, emotionStyle].filter(Boolean).join('\n'),
2076
2096
  body: bodyHtml,
2077
2097
  depth: Number.isInteger(options.depth) ? options.depth : 0,
2078
2098
  bootScripts: prerender.blocks,
@@ -2086,14 +2106,14 @@ export const renderPage = async (data, route = '/', options = {}) => {
2086
2106
  return { html, route, brKeyCount, shell: true, diagnostics, preparedDesignSystem: result.preparedDesignSystem || null }
2087
2107
  }
2088
2108
 
2089
- // (The empty line after the font links held a @font-face <style> that
2090
- // splitCapturedCSS never fills — @font-face stays in the class stream.)
2109
+ // The line after the font links holds the page's @font-face rules in a
2110
+ // <style data-smbls-faces> of their own (see facesStyle above).
2091
2111
  const html = `<!DOCTYPE html>
2092
2112
  <html lang="${htmlLang}"${htmlTheme ? ` data-theme="${escapeAttr(htmlTheme)}"` : ''}>
2093
2113
  <head>
2094
2114
  ${resolvedHeadTags}${isr && isr.clientScript && hydrate ? `\n${prerender.meta}` : ''}
2095
2115
  ${fontLinks}
2096
-
2116
+ ${facesStyle}
2097
2117
  ${brenderStyle}
2098
2118
  ${emotionStyle}
2099
2119
  </head>