meno-core 1.0.41 → 1.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/bin/cli.js +2 -2
  2. package/dist/build-static.js +7 -7
  3. package/dist/chunks/{chunk-MKB2J6AD.js → chunk-24KKYW25.js} +2 -2
  4. package/dist/chunks/{chunk-YSZ5IUFM.js → chunk-5Z5VQRTJ.js} +8 -4
  5. package/dist/chunks/chunk-5Z5VQRTJ.js.map +7 -0
  6. package/dist/chunks/{chunk-IBR2F4IL.js → chunk-6AYGKR6Y.js} +39 -23
  7. package/dist/chunks/chunk-6AYGKR6Y.js.map +7 -0
  8. package/dist/chunks/{chunk-EQOSDQS2.js → chunk-ACK7AURE.js} +5 -5
  9. package/dist/chunks/{chunk-LBWIHPN7.js → chunk-DIYO4RBJ.js} +8 -2
  10. package/dist/chunks/{chunk-LBWIHPN7.js.map → chunk-DIYO4RBJ.js.map} +2 -2
  11. package/dist/chunks/{chunk-IGVQF5GY.js → chunk-ITVPRBD6.js} +19 -5
  12. package/dist/chunks/chunk-ITVPRBD6.js.map +7 -0
  13. package/dist/chunks/{chunk-SK3TLNUP.js → chunk-UGHOL7IP.js} +2289 -125
  14. package/dist/chunks/chunk-UGHOL7IP.js.map +7 -0
  15. package/dist/chunks/{chunk-SNUROC7E.js → chunk-YM5BJZYJ.js} +7 -7
  16. package/dist/chunks/{chunk-SNUROC7E.js.map → chunk-YM5BJZYJ.js.map} +2 -2
  17. package/dist/chunks/{configService-MICL4S2L.js → configService-KK5JEQOZ.js} +3 -3
  18. package/dist/chunks/{constants-ZEU4TZCA.js → constants-JOIPAAAA.js} +2 -2
  19. package/dist/entries/server-router.js +7 -7
  20. package/dist/lib/client/index.js +24 -15
  21. package/dist/lib/client/index.js.map +3 -3
  22. package/dist/lib/server/index.js +3014 -75
  23. package/dist/lib/server/index.js.map +4 -4
  24. package/dist/lib/shared/index.js +15 -11
  25. package/dist/lib/shared/index.js.map +2 -2
  26. package/dist/lib/test-utils/index.js +1 -1
  27. package/lib/client/core/ComponentBuilder.ts +27 -14
  28. package/lib/client/templateEngine.test.ts +4 -4
  29. package/lib/client/templateEngine.ts +45 -42
  30. package/lib/server/astro/nodeToAstro.ts +15 -15
  31. package/lib/server/index.ts +7 -18
  32. package/lib/server/jsonLoader.ts +2 -2
  33. package/lib/server/routes/static.ts +1 -1
  34. package/lib/server/runtime/bundler.ts +9 -4
  35. package/lib/server/ssr/index.ts +4 -0
  36. package/lib/server/ssr/ssrRenderer.test.ts +16 -1
  37. package/lib/server/ssr/ssrRenderer.ts +24 -15
  38. package/lib/shared/constants.ts +3 -0
  39. package/lib/shared/nodeUtils.ts +24 -3
  40. package/lib/shared/registry/nodeTypes/ListNodeType.ts +2 -0
  41. package/lib/shared/styleNodeUtils.ts +36 -8
  42. package/lib/shared/tree/PathBuilder.ts +11 -15
  43. package/package.json +1 -1
  44. package/dist/chunks/chunk-IBR2F4IL.js.map +0 -7
  45. package/dist/chunks/chunk-IGVQF5GY.js.map +0 -7
  46. package/dist/chunks/chunk-SK3TLNUP.js.map +0 -7
  47. package/dist/chunks/chunk-YSZ5IUFM.js.map +0 -7
  48. /package/dist/chunks/{chunk-MKB2J6AD.js.map → chunk-24KKYW25.js.map} +0 -0
  49. /package/dist/chunks/{chunk-EQOSDQS2.js.map → chunk-ACK7AURE.js.map} +0 -0
  50. /package/dist/chunks/{configService-MICL4S2L.js.map → configService-KK5JEQOZ.js.map} +0 -0
  51. /package/dist/chunks/{constants-ZEU4TZCA.js.map → constants-JOIPAAAA.js.map} +0 -0
package/dist/bin/cli.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  createRuntimeServer,
7
7
  setProjectRoot
8
- } from "../chunks/chunk-YSZ5IUFM.js";
8
+ } from "../chunks/chunk-5Z5VQRTJ.js";
9
9
  import {
10
10
  fileExists,
11
11
  serveFile
@@ -82,7 +82,7 @@ function getMatchingHeaders(pathname, headersMap) {
82
82
  return result;
83
83
  }
84
84
  async function startStaticServer(distPath) {
85
- const { SERVE_PORT } = await import("../chunks/constants-ZEU4TZCA.js");
85
+ const { SERVE_PORT } = await import("../chunks/constants-JOIPAAAA.js");
86
86
  const headersMap = parseHeadersFile(distPath);
87
87
  const server = await createRuntimeServer({
88
88
  port: SERVE_PORT,
@@ -9,17 +9,17 @@ import {
9
9
  hashContent,
10
10
  injectTrackingScript,
11
11
  isCMSPage
12
- } from "./chunks/chunk-EQOSDQS2.js";
13
- import "./chunks/chunk-SK3TLNUP.js";
14
- import "./chunks/chunk-MKB2J6AD.js";
15
- import "./chunks/chunk-YSZ5IUFM.js";
12
+ } from "./chunks/chunk-ACK7AURE.js";
13
+ import "./chunks/chunk-UGHOL7IP.js";
14
+ import "./chunks/chunk-24KKYW25.js";
15
+ import "./chunks/chunk-5Z5VQRTJ.js";
16
16
  import "./chunks/chunk-WQFG7PAH.js";
17
17
  import "./chunks/chunk-S2HXJTAF.js";
18
- import "./chunks/chunk-IBR2F4IL.js";
19
- import "./chunks/chunk-IGVQF5GY.js";
18
+ import "./chunks/chunk-6AYGKR6Y.js";
19
+ import "./chunks/chunk-ITVPRBD6.js";
20
20
  import "./chunks/chunk-PGH3ATYI.js";
21
21
  import "./chunks/chunk-UB44F4Z2.js";
22
- import "./chunks/chunk-LBWIHPN7.js";
22
+ import "./chunks/chunk-DIYO4RBJ.js";
23
23
  import "./chunks/chunk-KSBZ2L7C.js";
24
24
  export {
25
25
  buildCMSItemPath,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  projectPaths
3
- } from "./chunk-YSZ5IUFM.js";
3
+ } from "./chunk-5Z5VQRTJ.js";
4
4
  import {
5
5
  fileExists,
6
6
  readTextFile
@@ -205,4 +205,4 @@ export {
205
205
  ConfigService,
206
206
  configService
207
207
  };
208
- //# sourceMappingURL=chunk-MKB2J6AD.js.map
208
+ //# sourceMappingURL=chunk-24KKYW25.js.map
@@ -17,10 +17,14 @@ async function minifyJS(code) {
17
17
  return minifyWithEsbuild(code);
18
18
  }
19
19
  async function validateJS(code) {
20
- if (isBun) {
21
- return validateWithBun(code);
20
+ try {
21
+ if (isBun) {
22
+ return await validateWithBun(code);
23
+ }
24
+ return await validateWithEsbuild(code);
25
+ } catch {
26
+ return null;
22
27
  }
23
- return validateWithEsbuild(code);
24
28
  }
25
29
  async function bundleWithBun(entrypoint, opts) {
26
30
  try {
@@ -460,4 +464,4 @@ export {
460
464
  resolveProjectPath,
461
465
  resolvePackagePath
462
466
  };
463
- //# sourceMappingURL=chunk-YSZ5IUFM.js.map
467
+ //# sourceMappingURL=chunk-5Z5VQRTJ.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../lib/server/runtime/bundler.ts", "../../lib/server/runtime/httpServer.ts", "../../lib/server/runtime/index.ts", "../../lib/server/projectContext.ts"],
4
+ "sourcesContent": ["/**\n * Runtime-agnostic bundler abstraction.\n * Uses Bun.build when available, falls back to esbuild for Node.js.\n */\n\nconst isBun = typeof (globalThis as any).Bun !== 'undefined';\n\nexport interface BundleResult {\n code: string;\n success: boolean;\n errors: string[];\n}\n\nexport interface BundleOptions {\n target?: 'browser' | 'node';\n format?: 'esm' | 'cjs';\n minify?: boolean;\n sourcemap?: 'inline' | 'external' | boolean;\n /** When true, throw on build errors instead of returning them */\n throw?: boolean;\n}\n\n/**\n * Bundle a file entry point.\n * Returns the bundled code as a string.\n */\nexport async function bundleFile(\n entrypoint: string,\n opts: BundleOptions = {},\n): Promise<BundleResult> {\n if (isBun) {\n return bundleWithBun(entrypoint, opts);\n }\n return bundleWithEsbuild(entrypoint, opts);\n}\n\n/**\n * Minify JavaScript code.\n */\nexport async function minifyJS(code: string): Promise<BundleResult> {\n if (isBun) {\n return minifyWithBun(code);\n }\n return minifyWithEsbuild(code);\n}\n\n/**\n * Validate JavaScript syntax (check for errors without producing output).\n */\nexport async function validateJS(code: string): Promise<string | null> {\n try {\n if (isBun) {\n return await validateWithBun(code);\n }\n return await validateWithEsbuild(code);\n } catch {\n // Validation not available (e.g., Cloudflare Workers) \u2014 skip and trust the JS\n return null;\n }\n}\n\n// \u2500\u2500 Bun implementations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function bundleWithBun(\n entrypoint: string,\n opts: BundleOptions,\n): Promise<BundleResult> {\n try {\n const result = await Bun.build({\n entrypoints: [entrypoint],\n target: opts.target || 'browser',\n format: opts.format || 'esm',\n minify: opts.minify ?? false,\n sourcemap: opts.sourcemap === true ? 'inline' : (opts.sourcemap || 'none'),\n throw: opts.throw ?? false,\n });\n\n if (result.success && result.outputs[0]) {\n const code = await result.outputs[0].text();\n return { code, success: true, errors: [] };\n }\n\n const errors = (result.logs || []).map((log: any) => {\n const parts: string[] = [];\n if (log.position?.file) parts.push(`File: ${log.position.file}`);\n if (log.position?.line) parts.push(`Line ${log.position.line}:${log.position.column || 0}`);\n if (log.position?.lineText) parts.push(log.position.lineText);\n if (log.message) parts.push(log.message);\n return parts.length > 0 ? parts.join('\\n') : String(log);\n });\n\n return { code: '', success: false, errors };\n } catch (err: any) {\n if (opts.throw) throw err;\n\n const errors: string[] = [];\n if (err.logs && Array.isArray(err.logs)) {\n for (const log of err.logs) {\n const parts: string[] = [];\n if (log.position?.line) parts.push(`Line ${log.position.line}:${log.position.column || 0}`);\n if (log.position?.lineText) parts.push(log.position.lineText);\n if (log.message) parts.push(log.message);\n errors.push(parts.length > 0 ? parts.join('\\n') : String(log));\n }\n } else {\n errors.push(err.message || String(err));\n }\n\n return { code: '', success: false, errors };\n }\n}\n\nasync function minifyWithBun(code: string): Promise<BundleResult> {\n const { writeFile, rm } = await import('fs/promises');\n const { join } = await import('path');\n const tempFile = join('/tmp', `meno-minify-${Date.now()}.js`);\n\n try {\n await writeFile(tempFile, code, 'utf-8');\n\n const result = await Bun.build({\n entrypoints: [tempFile],\n minify: true,\n throw: true,\n });\n\n if (result.outputs.length > 0) {\n const minified = await result.outputs[0].text();\n return { code: minified, success: true, errors: [] };\n }\n\n return { code: '', success: false, errors: ['Minification produced no output'] };\n } catch (err: any) {\n const { inspect } = await import('./fs');\n let details = '';\n if (err.logs && Array.isArray(err.logs)) {\n details = err.logs.map((log: any) => {\n const parts: string[] = [];\n if (log.position?.line) parts.push(`Line ${log.position.line}:${log.position.column || 0}`);\n if (log.position?.lineText) parts.push(log.position.lineText);\n if (log.message) parts.push(log.message);\n return parts.length > 0 ? parts.join('\\n') : String(log);\n }).join('\\n\\n');\n }\n if (!details) {\n try { details = inspect(err); } catch { details = err.stack || err.message || String(err); }\n }\n return { code: '', success: false, errors: [details] };\n } finally {\n try { const { rm } = await import('fs/promises'); await rm(tempFile, { force: true }); } catch {}\n }\n}\n\nasync function validateWithBun(code: string): Promise<string | null> {\n const { writeFile, rm } = await import('fs/promises');\n const { join } = await import('path');\n const tempFile = join('/tmp', `meno-validate-${Date.now()}-${Math.random().toString(36).slice(2)}.js`);\n\n try {\n await writeFile(tempFile, code, 'utf-8');\n await Bun.build({\n entrypoints: [tempFile],\n minify: true,\n throw: true,\n });\n return null; // Valid\n } catch (err: any) {\n const { inspect } = await import('./fs');\n let details = '';\n if (err.logs && Array.isArray(err.logs)) {\n details = err.logs.map((log: any) => {\n const parts: string[] = [];\n if (log.position?.line) parts.push(`Line ${log.position.line}:${log.position.column || 0}`);\n if (log.position?.lineText) parts.push(log.position.lineText);\n if (log.message) parts.push(log.message);\n return parts.length > 0 ? parts.join('\\n') : String(log);\n }).join('\\n\\n');\n }\n if (!details) {\n try { details = inspect(err); } catch { details = err.stack || err.message || String(err); }\n }\n return details || 'Unknown JavaScript error';\n } finally {\n try { await rm(tempFile, { force: true }); } catch {}\n }\n}\n\n// \u2500\u2500 esbuild implementations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function getEsbuild() {\n return await import('esbuild');\n}\n\nasync function bundleWithEsbuild(\n entrypoint: string,\n opts: BundleOptions,\n): Promise<BundleResult> {\n const esbuild = await getEsbuild();\n\n try {\n const result = await esbuild.build({\n entryPoints: [entrypoint],\n bundle: true,\n write: false,\n platform: opts.target === 'node' ? 'node' : 'browser',\n format: opts.format || 'esm',\n minify: opts.minify ?? false,\n sourcemap: opts.sourcemap === true ? 'inline' : (opts.sourcemap === 'inline' ? 'inline' : opts.sourcemap === 'external' ? true : false),\n jsx: 'automatic',\n jsxImportSource: 'react',\n logLevel: 'silent',\n });\n\n if (result.outputFiles && result.outputFiles.length > 0) {\n return { code: result.outputFiles[0].text, success: true, errors: [] };\n }\n\n return { code: '', success: false, errors: ['Build produced no output'] };\n } catch (err: any) {\n if (opts.throw) throw err;\n\n const errors: string[] = [];\n if (err.errors && Array.isArray(err.errors)) {\n for (const e of err.errors) {\n const parts: string[] = [];\n if (e.location?.file) parts.push(`File: ${e.location.file}`);\n if (e.location?.line) parts.push(`Line ${e.location.line}:${e.location.column || 0}`);\n if (e.location?.lineText) parts.push(e.location.lineText);\n if (e.text) parts.push(e.text);\n errors.push(parts.length > 0 ? parts.join('\\n') : String(e));\n }\n } else {\n errors.push(err.message || String(err));\n }\n\n return { code: '', success: false, errors };\n }\n}\n\nasync function minifyWithEsbuild(code: string): Promise<BundleResult> {\n const esbuild = await getEsbuild();\n\n try {\n const result = await esbuild.transform(code, {\n minify: true,\n loader: 'js',\n });\n\n return { code: result.code, success: true, errors: [] };\n } catch (err: any) {\n const errors: string[] = [];\n if (err.errors && Array.isArray(err.errors)) {\n for (const e of err.errors) {\n const parts: string[] = [];\n if (e.location?.line) parts.push(`Line ${e.location.line}:${e.location.column || 0}`);\n if (e.location?.lineText) parts.push(e.location.lineText);\n if (e.text) parts.push(e.text);\n errors.push(parts.length > 0 ? parts.join('\\n') : String(e));\n }\n } else {\n errors.push(err.message || String(err));\n }\n\n return { code: '', success: false, errors };\n }\n}\n\nasync function validateWithEsbuild(code: string): Promise<string | null> {\n const esbuild = await getEsbuild();\n\n try {\n await esbuild.transform(code, { loader: 'js' });\n return null; // Valid\n } catch (err: any) {\n const errors: string[] = [];\n if (err.errors && Array.isArray(err.errors)) {\n for (const e of err.errors) {\n const parts: string[] = [];\n if (e.location?.line) parts.push(`Line ${e.location.line}:${e.location.column || 0}`);\n if (e.location?.lineText) parts.push(e.location.lineText);\n if (e.text) parts.push(e.text);\n errors.push(parts.length > 0 ? parts.join('\\n') : String(e));\n }\n } else {\n errors.push(err.message || String(err));\n }\n\n return errors.join('\\n\\n') || 'Unknown JavaScript error';\n }\n}\n", "/**\n * Runtime-agnostic HTTP server abstraction.\n * Uses Bun.serve when available, falls back to Node.js http + ws.\n */\n\nconst isBun = typeof globalThis.Bun !== 'undefined';\n\nexport interface RuntimeServer {\n port: number;\n stop(): void;\n}\n\nexport interface RuntimeWSClient {\n send(data: string | ArrayBuffer | Uint8Array): void;\n readyState: number;\n close(code?: number, reason?: string): void;\n}\n\nexport interface ServerOptions {\n port: number;\n hostname?: string;\n fetch: (req: Request, upgradeWebSocket: (req: Request) => boolean) => Promise<Response | undefined>;\n websocket?: {\n open(ws: RuntimeWSClient): void;\n message(ws: RuntimeWSClient, data: string): void;\n close(ws: RuntimeWSClient): void;\n };\n /** Path to upgrade to WebSocket (e.g., \"/__hmr\") */\n wsPath?: string;\n}\n\nexport async function createRuntimeServer(\n options: ServerOptions,\n): Promise<RuntimeServer> {\n if (isBun) {\n return createBunServer(options);\n }\n return createNodeServer(options);\n}\n\n// \u2500\u2500 Bun implementation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction createBunServer(options: ServerOptions): RuntimeServer {\n const { port, hostname, fetch, websocket, wsPath } = options;\n\n const bunConfig: any = {\n port,\n hostname: hostname || 'localhost',\n\n async fetch(req: Request, server: any) {\n // Create upgrade function that delegates to Bun's server.upgrade\n const upgradeWebSocket = (upgradeReq: Request): boolean => {\n return server.upgrade(upgradeReq);\n };\n\n const response = await fetch(req, upgradeWebSocket);\n return response || new Response('Not Found', { status: 404 });\n },\n };\n\n if (websocket) {\n bunConfig.websocket = {\n open(ws: RuntimeWSClient) {\n websocket.open(ws);\n },\n message(ws: RuntimeWSClient, message: unknown) {\n websocket.message(ws, String(message));\n },\n close(ws: RuntimeWSClient) {\n websocket.close(ws);\n },\n };\n }\n\n const server = Bun.serve(bunConfig);\n\n return {\n port: server.port ?? port,\n stop() {\n server.stop();\n },\n };\n}\n\n// \u2500\u2500 Node.js implementation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function createNodeServer(options: ServerOptions): Promise<RuntimeServer> {\n const { port, hostname, fetch, websocket, wsPath } = options;\n const http = await import('http');\n\n const server = http.createServer(async (nodeReq, nodeRes) => {\n try {\n // Convert Node.js IncomingMessage \u2192 Web Request\n const url = `http://${hostname || 'localhost'}:${port}${nodeReq.url || '/'}`;\n const headers = new Headers();\n for (const [key, value] of Object.entries(nodeReq.headers)) {\n if (value) {\n if (Array.isArray(value)) {\n for (const v of value) headers.append(key, v);\n } else {\n headers.set(key, value);\n }\n }\n }\n\n let body: ReadableStream | null = null;\n if (nodeReq.method !== 'GET' && nodeReq.method !== 'HEAD') {\n const { Readable } = await import('stream');\n body = Readable.toWeb(nodeReq) as unknown as ReadableStream;\n }\n\n const request = new Request(url, {\n method: nodeReq.method || 'GET',\n headers,\n body,\n // @ts-ignore - duplex is needed for streaming request bodies in Node\n duplex: body ? 'half' : undefined,\n });\n\n // No-op upgrade function for non-upgrade requests\n const upgradeWebSocket = (): boolean => false;\n\n const response = await fetch(request, upgradeWebSocket);\n if (!response) {\n nodeRes.writeHead(404);\n nodeRes.end('Not Found');\n return;\n }\n\n // Convert Web Response \u2192 Node.js ServerResponse\n nodeRes.writeHead(response.status, Object.fromEntries(response.headers.entries()));\n\n if (response.body) {\n const reader = response.body.getReader();\n const pump = async () => {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n nodeRes.end();\n break;\n }\n const canContinue = nodeRes.write(value);\n if (!canContinue) {\n await new Promise<void>((resolve) => nodeRes.once('drain', resolve));\n }\n }\n };\n await pump();\n } else {\n const text = await response.text();\n nodeRes.end(text);\n }\n } catch (err) {\n console.error('Server error:', err);\n if (!nodeRes.headersSent) {\n nodeRes.writeHead(500);\n nodeRes.end('Internal Server Error');\n }\n }\n });\n\n // WebSocket support via 'ws' package\n if (websocket && wsPath) {\n try {\n const { WebSocketServer } = await import('ws');\n const wss = new WebSocketServer({ noServer: true });\n\n server.on('upgrade', (request, socket, head) => {\n const pathname = new URL(\n request.url || '/',\n `http://${hostname || 'localhost'}:${port}`,\n ).pathname;\n\n if (pathname === wsPath) {\n wss.handleUpgrade(request, socket, head, (ws) => {\n wss.emit('connection', ws, request);\n });\n } else {\n socket.destroy();\n }\n });\n\n wss.on('connection', (ws) => {\n const client: RuntimeWSClient = {\n send(data) {\n if (ws.readyState === 1) { // OPEN\n ws.send(data);\n }\n },\n get readyState() {\n return ws.readyState;\n },\n close(code, reason) {\n ws.close(code, reason);\n },\n };\n\n websocket.open(client);\n\n ws.on('message', (data) => {\n websocket.message(client, data.toString());\n });\n\n ws.on('close', () => {\n websocket.close(client);\n });\n });\n } catch {\n console.warn('WebSocket support requires the \"ws\" package. Install it with: npm install ws');\n }\n }\n\n // Start listening\n return new Promise((resolve, reject) => {\n server.on('error', reject);\n server.listen(port, hostname || 'localhost', () => {\n const addr = server.address();\n const actualPort = typeof addr === 'object' && addr ? addr.port : port;\n\n resolve({\n port: actualPort,\n stop() {\n server.close();\n },\n });\n });\n });\n}\n", "/**\n * Runtime Abstraction\n * Detects Bun vs Node.js and re-exports runtime-agnostic utilities.\n */\n\nexport const isBun = typeof globalThis.Bun !== 'undefined';\n\nexport {\n readTextFile,\n readJsonFile,\n fileExists,\n writeFile,\n serveFile,\n hashContent,\n inspect,\n ensureDir,\n getModuleDir,\n spawnProcess,\n getFileSize,\n getMimeType,\n} from './fs';\n\nexport {\n bundleFile,\n minifyJS,\n validateJS,\n type BundleResult,\n type BundleOptions,\n} from './bundler';\n\nexport {\n createRuntimeServer,\n type RuntimeServer,\n type RuntimeWSClient,\n type ServerOptions,\n} from './httpServer';\n", "import { join, dirname } from 'path';\nimport { getModuleDir } from './runtime';\n\nlet projectRoot: string = process.cwd();\n\n// Package root is where the editor files are installed (2 levels up from this file)\n// In packaged Electron builds, MENO_CORE_ROOT overrides import.meta.url resolution\nconst packageRoot = process.env.MENO_CORE_ROOT\n || join(dirname(getModuleDir(import.meta.url)), '..');\n\nexport function setProjectRoot(root: string): void {\n projectRoot = root;\n}\n\nexport function getProjectRoot(): string {\n return projectRoot;\n}\n\nexport function getPackageRoot(): string {\n return packageRoot;\n}\n\n// Path getters for project files (user's project)\nexport const projectPaths = {\n pages: () => join(projectRoot, 'pages'),\n templates: () => join(projectRoot, 'templates'),\n components: () => join(projectRoot, 'components'),\n fonts: () => join(projectRoot, 'fonts'),\n images: () => join(projectRoot, 'images'),\n videos: () => join(projectRoot, 'videos'),\n assets: () => join(projectRoot, 'assets'),\n icons: () => join(projectRoot, 'icons'),\n cms: () => join(projectRoot, 'cms'),\n libraries: () => join(projectRoot, 'libraries'),\n functions: () => join(projectRoot, 'functions'),\n config: () => join(projectRoot, 'project.config.json'),\n componentsConfig: () => join(projectRoot, 'components.config.json'),\n colors: () => join(projectRoot, 'colors.json'),\n variables: () => join(projectRoot, 'variables.json'),\n enums: () => join(projectRoot, 'enums.json'),\n dist: () => join(projectRoot, 'dist'),\n env: () => join(projectRoot, '.env'),\n get project() { return projectRoot; }, // Direct access to project root\n};\n\n// Path getters for package files (core assets)\n// Note: Editor-specific paths (editorHtml) are now in @meno/studio\nexport const packagePaths = {\n indexHtml: () => join(packageRoot, 'templates', 'index-router.html'),\n clientRouter: () => join(packageRoot, 'entries', 'client-router.tsx'),\n};\n\nexport function resolveProjectPath(...segments: string[]): string {\n return join(projectRoot, ...segments);\n}\n\nexport function resolvePackagePath(...segments: string[]): string {\n return join(packageRoot, ...segments);\n}\n"],
5
+ "mappings": ";;;;;AAKA,IAAM,QAAQ,OAAQ,WAAmB,QAAQ;AAqBjD,eAAsB,WACpB,YACA,OAAsB,CAAC,GACA;AACvB,MAAI,OAAO;AACT,WAAO,cAAc,YAAY,IAAI;AAAA,EACvC;AACA,SAAO,kBAAkB,YAAY,IAAI;AAC3C;AAKA,eAAsB,SAAS,MAAqC;AAClE,MAAI,OAAO;AACT,WAAO,cAAc,IAAI;AAAA,EAC3B;AACA,SAAO,kBAAkB,IAAI;AAC/B;AAKA,eAAsB,WAAW,MAAsC;AACrE,MAAI;AACF,QAAI,OAAO;AACT,aAAO,MAAM,gBAAgB,IAAI;AAAA,IACnC;AACA,WAAO,MAAM,oBAAoB,IAAI;AAAA,EACvC,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAIA,eAAe,cACb,YACA,MACuB;AACvB,MAAI;AACF,UAAM,SAAS,MAAM,IAAI,MAAM;AAAA,MAC7B,aAAa,CAAC,UAAU;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB,QAAQ,KAAK,UAAU;AAAA,MACvB,QAAQ,KAAK,UAAU;AAAA,MACvB,WAAW,KAAK,cAAc,OAAO,WAAY,KAAK,aAAa;AAAA,MACnE,OAAO,KAAK,SAAS;AAAA,IACvB,CAAC;AAED,QAAI,OAAO,WAAW,OAAO,QAAQ,CAAC,GAAG;AACvC,YAAM,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAE,KAAK;AAC1C,aAAO,EAAE,MAAM,SAAS,MAAM,QAAQ,CAAC,EAAE;AAAA,IAC3C;AAEA,UAAM,UAAU,OAAO,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAa;AACnD,YAAM,QAAkB,CAAC;AACzB,UAAI,IAAI,UAAU,KAAM,OAAM,KAAK,SAAS,IAAI,SAAS,IAAI,EAAE;AAC/D,UAAI,IAAI,UAAU,KAAM,OAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,UAAU,CAAC,EAAE;AAC1F,UAAI,IAAI,UAAU,SAAU,OAAM,KAAK,IAAI,SAAS,QAAQ;AAC5D,UAAI,IAAI,QAAS,OAAM,KAAK,IAAI,OAAO;AACvC,aAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG;AAAA,IACzD,CAAC;AAED,WAAO,EAAE,MAAM,IAAI,SAAS,OAAO,OAAO;AAAA,EAC5C,SAAS,KAAU;AACjB,QAAI,KAAK,MAAO,OAAM;AAEtB,UAAM,SAAmB,CAAC;AAC1B,QAAI,IAAI,QAAQ,MAAM,QAAQ,IAAI,IAAI,GAAG;AACvC,iBAAW,OAAO,IAAI,MAAM;AAC1B,cAAM,QAAkB,CAAC;AACzB,YAAI,IAAI,UAAU,KAAM,OAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,UAAU,CAAC,EAAE;AAC1F,YAAI,IAAI,UAAU,SAAU,OAAM,KAAK,IAAI,SAAS,QAAQ;AAC5D,YAAI,IAAI,QAAS,OAAM,KAAK,IAAI,OAAO;AACvC,eAAO,KAAK,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC;AAAA,MAC/D;AAAA,IACF,OAAO;AACL,aAAO,KAAK,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,IACxC;AAEA,WAAO,EAAE,MAAM,IAAI,SAAS,OAAO,OAAO;AAAA,EAC5C;AACF;AAEA,eAAe,cAAc,MAAqC;AAChE,QAAM,EAAE,WAAAA,YAAW,GAAG,IAAI,MAAM,OAAO,aAAa;AACpD,QAAM,EAAE,MAAAC,MAAK,IAAI,MAAM,OAAO,MAAM;AACpC,QAAM,WAAWA,MAAK,QAAQ,eAAe,KAAK,IAAI,CAAC,KAAK;AAE5D,MAAI;AACF,UAAMD,WAAU,UAAU,MAAM,OAAO;AAEvC,UAAM,SAAS,MAAM,IAAI,MAAM;AAAA,MAC7B,aAAa,CAAC,QAAQ;AAAA,MACtB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT,CAAC;AAED,QAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,YAAM,WAAW,MAAM,OAAO,QAAQ,CAAC,EAAE,KAAK;AAC9C,aAAO,EAAE,MAAM,UAAU,SAAS,MAAM,QAAQ,CAAC,EAAE;AAAA,IACrD;AAEA,WAAO,EAAE,MAAM,IAAI,SAAS,OAAO,QAAQ,CAAC,iCAAiC,EAAE;AAAA,EACjF,SAAS,KAAU;AACjB,UAAM,EAAE,SAAAE,SAAQ,IAAI,MAAM,OAAO,kBAAM;AACvC,QAAI,UAAU;AACd,QAAI,IAAI,QAAQ,MAAM,QAAQ,IAAI,IAAI,GAAG;AACvC,gBAAU,IAAI,KAAK,IAAI,CAAC,QAAa;AACnC,cAAM,QAAkB,CAAC;AACzB,YAAI,IAAI,UAAU,KAAM,OAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,UAAU,CAAC,EAAE;AAC1F,YAAI,IAAI,UAAU,SAAU,OAAM,KAAK,IAAI,SAAS,QAAQ;AAC5D,YAAI,IAAI,QAAS,OAAM,KAAK,IAAI,OAAO;AACvC,eAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG;AAAA,MACzD,CAAC,EAAE,KAAK,MAAM;AAAA,IAChB;AACA,QAAI,CAAC,SAAS;AACZ,UAAI;AAAE,kBAAUA,SAAQ,GAAG;AAAA,MAAG,QAAQ;AAAE,kBAAU,IAAI,SAAS,IAAI,WAAW,OAAO,GAAG;AAAA,MAAG;AAAA,IAC7F;AACA,WAAO,EAAE,MAAM,IAAI,SAAS,OAAO,QAAQ,CAAC,OAAO,EAAE;AAAA,EACvD,UAAE;AACA,QAAI;AAAE,YAAM,EAAE,IAAAC,IAAG,IAAI,MAAM,OAAO,aAAa;AAAG,YAAMA,IAAG,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,IAAG,QAAQ;AAAA,IAAC;AAAA,EAClG;AACF;AAEA,eAAe,gBAAgB,MAAsC;AACnE,QAAM,EAAE,WAAAH,YAAW,GAAG,IAAI,MAAM,OAAO,aAAa;AACpD,QAAM,EAAE,MAAAC,MAAK,IAAI,MAAM,OAAO,MAAM;AACpC,QAAM,WAAWA,MAAK,QAAQ,iBAAiB,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,KAAK;AAErG,MAAI;AACF,UAAMD,WAAU,UAAU,MAAM,OAAO;AACvC,UAAM,IAAI,MAAM;AAAA,MACd,aAAa,CAAC,QAAQ;AAAA,MACtB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT,SAAS,KAAU;AACjB,UAAM,EAAE,SAAAE,SAAQ,IAAI,MAAM,OAAO,kBAAM;AACvC,QAAI,UAAU;AACd,QAAI,IAAI,QAAQ,MAAM,QAAQ,IAAI,IAAI,GAAG;AACvC,gBAAU,IAAI,KAAK,IAAI,CAAC,QAAa;AACnC,cAAM,QAAkB,CAAC;AACzB,YAAI,IAAI,UAAU,KAAM,OAAM,KAAK,QAAQ,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,UAAU,CAAC,EAAE;AAC1F,YAAI,IAAI,UAAU,SAAU,OAAM,KAAK,IAAI,SAAS,QAAQ;AAC5D,YAAI,IAAI,QAAS,OAAM,KAAK,IAAI,OAAO;AACvC,eAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG;AAAA,MACzD,CAAC,EAAE,KAAK,MAAM;AAAA,IAChB;AACA,QAAI,CAAC,SAAS;AACZ,UAAI;AAAE,kBAAUA,SAAQ,GAAG;AAAA,MAAG,QAAQ;AAAE,kBAAU,IAAI,SAAS,IAAI,WAAW,OAAO,GAAG;AAAA,MAAG;AAAA,IAC7F;AACA,WAAO,WAAW;AAAA,EACpB,UAAE;AACA,QAAI;AAAE,YAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,IAAG,QAAQ;AAAA,IAAC;AAAA,EACtD;AACF;AAIA,eAAe,aAAa;AAC1B,SAAO,MAAM,OAAO,SAAS;AAC/B;AAEA,eAAe,kBACb,YACA,MACuB;AACvB,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,MAAM;AAAA,MACjC,aAAa,CAAC,UAAU;AAAA,MACxB,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,UAAU,KAAK,WAAW,SAAS,SAAS;AAAA,MAC5C,QAAQ,KAAK,UAAU;AAAA,MACvB,QAAQ,KAAK,UAAU;AAAA,MACvB,WAAW,KAAK,cAAc,OAAO,WAAY,KAAK,cAAc,WAAW,WAAW,KAAK,cAAc,aAAa,OAAO;AAAA,MACjI,KAAK;AAAA,MACL,iBAAiB;AAAA,MACjB,UAAU;AAAA,IACZ,CAAC;AAED,QAAI,OAAO,eAAe,OAAO,YAAY,SAAS,GAAG;AACvD,aAAO,EAAE,MAAM,OAAO,YAAY,CAAC,EAAE,MAAM,SAAS,MAAM,QAAQ,CAAC,EAAE;AAAA,IACvE;AAEA,WAAO,EAAE,MAAM,IAAI,SAAS,OAAO,QAAQ,CAAC,0BAA0B,EAAE;AAAA,EAC1E,SAAS,KAAU;AACjB,QAAI,KAAK,MAAO,OAAM;AAEtB,UAAM,SAAmB,CAAC;AAC1B,QAAI,IAAI,UAAU,MAAM,QAAQ,IAAI,MAAM,GAAG;AAC3C,iBAAW,KAAK,IAAI,QAAQ;AAC1B,cAAM,QAAkB,CAAC;AACzB,YAAI,EAAE,UAAU,KAAM,OAAM,KAAK,SAAS,EAAE,SAAS,IAAI,EAAE;AAC3D,YAAI,EAAE,UAAU,KAAM,OAAM,KAAK,QAAQ,EAAE,SAAS,IAAI,IAAI,EAAE,SAAS,UAAU,CAAC,EAAE;AACpF,YAAI,EAAE,UAAU,SAAU,OAAM,KAAK,EAAE,SAAS,QAAQ;AACxD,YAAI,EAAE,KAAM,OAAM,KAAK,EAAE,IAAI;AAC7B,eAAO,KAAK,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AAAA,MAC7D;AAAA,IACF,OAAO;AACL,aAAO,KAAK,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,IACxC;AAEA,WAAO,EAAE,MAAM,IAAI,SAAS,OAAO,OAAO;AAAA,EAC5C;AACF;AAEA,eAAe,kBAAkB,MAAqC;AACpE,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,UAAU,MAAM;AAAA,MAC3C,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AAED,WAAO,EAAE,MAAM,OAAO,MAAM,SAAS,MAAM,QAAQ,CAAC,EAAE;AAAA,EACxD,SAAS,KAAU;AACjB,UAAM,SAAmB,CAAC;AAC1B,QAAI,IAAI,UAAU,MAAM,QAAQ,IAAI,MAAM,GAAG;AAC3C,iBAAW,KAAK,IAAI,QAAQ;AAC1B,cAAM,QAAkB,CAAC;AACzB,YAAI,EAAE,UAAU,KAAM,OAAM,KAAK,QAAQ,EAAE,SAAS,IAAI,IAAI,EAAE,SAAS,UAAU,CAAC,EAAE;AACpF,YAAI,EAAE,UAAU,SAAU,OAAM,KAAK,EAAE,SAAS,QAAQ;AACxD,YAAI,EAAE,KAAM,OAAM,KAAK,EAAE,IAAI;AAC7B,eAAO,KAAK,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AAAA,MAC7D;AAAA,IACF,OAAO;AACL,aAAO,KAAK,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,IACxC;AAEA,WAAO,EAAE,MAAM,IAAI,SAAS,OAAO,OAAO;AAAA,EAC5C;AACF;AAEA,eAAe,oBAAoB,MAAsC;AACvE,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI;AACF,UAAM,QAAQ,UAAU,MAAM,EAAE,QAAQ,KAAK,CAAC;AAC9C,WAAO;AAAA,EACT,SAAS,KAAU;AACjB,UAAM,SAAmB,CAAC;AAC1B,QAAI,IAAI,UAAU,MAAM,QAAQ,IAAI,MAAM,GAAG;AAC3C,iBAAW,KAAK,IAAI,QAAQ;AAC1B,cAAM,QAAkB,CAAC;AACzB,YAAI,EAAE,UAAU,KAAM,OAAM,KAAK,QAAQ,EAAE,SAAS,IAAI,IAAI,EAAE,SAAS,UAAU,CAAC,EAAE;AACpF,YAAI,EAAE,UAAU,SAAU,OAAM,KAAK,EAAE,SAAS,QAAQ;AACxD,YAAI,EAAE,KAAM,OAAM,KAAK,EAAE,IAAI;AAC7B,eAAO,KAAK,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AAAA,MAC7D;AAAA,IACF,OAAO;AACL,aAAO,KAAK,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,IACxC;AAEA,WAAO,OAAO,KAAK,MAAM,KAAK;AAAA,EAChC;AACF;;;AC5RA,IAAME,SAAQ,OAAO,WAAW,QAAQ;AA0BxC,eAAsB,oBACpB,SACwB;AACxB,MAAIA,QAAO;AACT,WAAO,gBAAgB,OAAO;AAAA,EAChC;AACA,SAAO,iBAAiB,OAAO;AACjC;AAIA,SAAS,gBAAgB,SAAuC;AAC9D,QAAM,EAAE,MAAM,UAAU,OAAO,WAAW,OAAO,IAAI;AAErD,QAAM,YAAiB;AAAA,IACrB;AAAA,IACA,UAAU,YAAY;AAAA,IAEtB,MAAM,MAAM,KAAcC,SAAa;AAErC,YAAM,mBAAmB,CAAC,eAAiC;AACzD,eAAOA,QAAO,QAAQ,UAAU;AAAA,MAClC;AAEA,YAAM,WAAW,MAAM,MAAM,KAAK,gBAAgB;AAClD,aAAO,YAAY,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF;AAEA,MAAI,WAAW;AACb,cAAU,YAAY;AAAA,MACpB,KAAK,IAAqB;AACxB,kBAAU,KAAK,EAAE;AAAA,MACnB;AAAA,MACA,QAAQ,IAAqB,SAAkB;AAC7C,kBAAU,QAAQ,IAAI,OAAO,OAAO,CAAC;AAAA,MACvC;AAAA,MACA,MAAM,IAAqB;AACzB,kBAAU,MAAM,EAAE;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,IAAI,MAAM,SAAS;AAElC,SAAO;AAAA,IACL,MAAM,OAAO,QAAQ;AAAA,IACrB,OAAO;AACL,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AACF;AAIA,eAAe,iBAAiB,SAAgD;AAC9E,QAAM,EAAE,MAAM,UAAU,OAAO,WAAW,OAAO,IAAI;AACrD,QAAM,OAAO,MAAM,OAAO,MAAM;AAEhC,QAAM,SAAS,KAAK,aAAa,OAAO,SAAS,YAAY;AAC3D,QAAI;AAEF,YAAM,MAAM,UAAU,YAAY,WAAW,IAAI,IAAI,GAAG,QAAQ,OAAO,GAAG;AAC1E,YAAM,UAAU,IAAI,QAAQ;AAC5B,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,OAAO,GAAG;AAC1D,YAAI,OAAO;AACT,cAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,uBAAW,KAAK,MAAO,SAAQ,OAAO,KAAK,CAAC;AAAA,UAC9C,OAAO;AACL,oBAAQ,IAAI,KAAK,KAAK;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAEA,UAAI,OAA8B;AAClC,UAAI,QAAQ,WAAW,SAAS,QAAQ,WAAW,QAAQ;AACzD,cAAM,EAAE,SAAS,IAAI,MAAM,OAAO,QAAQ;AAC1C,eAAO,SAAS,MAAM,OAAO;AAAA,MAC/B;AAEA,YAAM,UAAU,IAAI,QAAQ,KAAK;AAAA,QAC/B,QAAQ,QAAQ,UAAU;AAAA,QAC1B;AAAA,QACA;AAAA;AAAA,QAEA,QAAQ,OAAO,SAAS;AAAA,MAC1B,CAAC;AAGD,YAAM,mBAAmB,MAAe;AAExC,YAAM,WAAW,MAAM,MAAM,SAAS,gBAAgB;AACtD,UAAI,CAAC,UAAU;AACb,gBAAQ,UAAU,GAAG;AACrB,gBAAQ,IAAI,WAAW;AACvB;AAAA,MACF;AAGA,cAAQ,UAAU,SAAS,QAAQ,OAAO,YAAY,SAAS,QAAQ,QAAQ,CAAC,CAAC;AAEjF,UAAI,SAAS,MAAM;AACjB,cAAM,SAAS,SAAS,KAAK,UAAU;AACvC,cAAM,OAAO,YAAY;AACvB,iBAAO,MAAM;AACX,kBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,gBAAI,MAAM;AACR,sBAAQ,IAAI;AACZ;AAAA,YACF;AACA,kBAAM,cAAc,QAAQ,MAAM,KAAK;AACvC,gBAAI,CAAC,aAAa;AAChB,oBAAM,IAAI,QAAc,CAAC,YAAY,QAAQ,KAAK,SAAS,OAAO,CAAC;AAAA,YACrE;AAAA,UACF;AAAA,QACF;AACA,cAAM,KAAK;AAAA,MACb,OAAO;AACL,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,gBAAQ,IAAI,IAAI;AAAA,MAClB;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,iBAAiB,GAAG;AAClC,UAAI,CAAC,QAAQ,aAAa;AACxB,gBAAQ,UAAU,GAAG;AACrB,gBAAQ,IAAI,uBAAuB;AAAA,MACrC;AAAA,IACF;AAAA,EACF,CAAC;AAGD,MAAI,aAAa,QAAQ;AACvB,QAAI;AACF,YAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,IAAI;AAC7C,YAAM,MAAM,IAAI,gBAAgB,EAAE,UAAU,KAAK,CAAC;AAElD,aAAO,GAAG,WAAW,CAAC,SAAS,QAAQ,SAAS;AAC9C,cAAM,WAAW,IAAI;AAAA,UACnB,QAAQ,OAAO;AAAA,UACf,UAAU,YAAY,WAAW,IAAI,IAAI;AAAA,QAC3C,EAAE;AAEF,YAAI,aAAa,QAAQ;AACvB,cAAI,cAAc,SAAS,QAAQ,MAAM,CAAC,OAAO;AAC/C,gBAAI,KAAK,cAAc,IAAI,OAAO;AAAA,UACpC,CAAC;AAAA,QACH,OAAO;AACL,iBAAO,QAAQ;AAAA,QACjB;AAAA,MACF,CAAC;AAED,UAAI,GAAG,cAAc,CAAC,OAAO;AAC3B,cAAM,SAA0B;AAAA,UAC9B,KAAK,MAAM;AACT,gBAAI,GAAG,eAAe,GAAG;AACvB,iBAAG,KAAK,IAAI;AAAA,YACd;AAAA,UACF;AAAA,UACA,IAAI,aAAa;AACf,mBAAO,GAAG;AAAA,UACZ;AAAA,UACA,MAAM,MAAM,QAAQ;AAClB,eAAG,MAAM,MAAM,MAAM;AAAA,UACvB;AAAA,QACF;AAEA,kBAAU,KAAK,MAAM;AAErB,WAAG,GAAG,WAAW,CAAC,SAAS;AACzB,oBAAU,QAAQ,QAAQ,KAAK,SAAS,CAAC;AAAA,QAC3C,CAAC;AAED,WAAG,GAAG,SAAS,MAAM;AACnB,oBAAU,MAAM,MAAM;AAAA,QACxB,CAAC;AAAA,MACH,CAAC;AAAA,IACH,QAAQ;AACN,cAAQ,KAAK,8EAA8E;AAAA,IAC7F;AAAA,EACF;AAGA,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,WAAO,GAAG,SAAS,MAAM;AACzB,WAAO,OAAO,MAAM,YAAY,aAAa,MAAM;AACjD,YAAM,OAAO,OAAO,QAAQ;AAC5B,YAAM,aAAa,OAAO,SAAS,YAAY,OAAO,KAAK,OAAO;AAElE,cAAQ;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AACL,iBAAO,MAAM;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;;;AC9NO,IAAMC,SAAQ,OAAO,WAAW,QAAQ;;;ACL/C,SAAS,MAAM,eAAe;AAG9B,IAAI,cAAsB,QAAQ,IAAI;AAItC,IAAM,cAAc,QAAQ,IAAI,kBAC3B,KAAK,QAAQ,aAAa,YAAY,GAAG,CAAC,GAAG,IAAI;AAE/C,SAAS,eAAe,MAAoB;AACjD,gBAAc;AAChB;AAEO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAEO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAGO,IAAM,eAAe;AAAA,EAC1B,OAAO,MAAM,KAAK,aAAa,OAAO;AAAA,EACtC,WAAW,MAAM,KAAK,aAAa,WAAW;AAAA,EAC9C,YAAY,MAAM,KAAK,aAAa,YAAY;AAAA,EAChD,OAAO,MAAM,KAAK,aAAa,OAAO;AAAA,EACtC,QAAQ,MAAM,KAAK,aAAa,QAAQ;AAAA,EACxC,QAAQ,MAAM,KAAK,aAAa,QAAQ;AAAA,EACxC,QAAQ,MAAM,KAAK,aAAa,QAAQ;AAAA,EACxC,OAAO,MAAM,KAAK,aAAa,OAAO;AAAA,EACtC,KAAK,MAAM,KAAK,aAAa,KAAK;AAAA,EAClC,WAAW,MAAM,KAAK,aAAa,WAAW;AAAA,EAC9C,WAAW,MAAM,KAAK,aAAa,WAAW;AAAA,EAC9C,QAAQ,MAAM,KAAK,aAAa,qBAAqB;AAAA,EACrD,kBAAkB,MAAM,KAAK,aAAa,wBAAwB;AAAA,EAClE,QAAQ,MAAM,KAAK,aAAa,aAAa;AAAA,EAC7C,WAAW,MAAM,KAAK,aAAa,gBAAgB;AAAA,EACnD,OAAO,MAAM,KAAK,aAAa,YAAY;AAAA,EAC3C,MAAM,MAAM,KAAK,aAAa,MAAM;AAAA,EACpC,KAAK,MAAM,KAAK,aAAa,MAAM;AAAA,EACnC,IAAI,UAAU;AAAE,WAAO;AAAA,EAAa;AAAA;AACtC;AAIO,IAAM,eAAe;AAAA,EAC1B,WAAW,MAAM,KAAK,aAAa,aAAa,mBAAmB;AAAA,EACnE,cAAc,MAAM,KAAK,aAAa,WAAW,mBAAmB;AACtE;AAEO,SAAS,sBAAsB,UAA4B;AAChE,SAAO,KAAK,aAAa,GAAG,QAAQ;AACtC;AAEO,SAAS,sBAAsB,UAA4B;AAChE,SAAO,KAAK,aAAa,GAAG,QAAQ;AACtC;",
6
+ "names": ["writeFile", "join", "inspect", "rm", "isBun", "server", "isBun"]
7
+ }
@@ -14,12 +14,12 @@ import {
14
14
  normalizeStyle,
15
15
  richTextMarkerToHtml,
16
16
  safeEvaluate
17
- } from "./chunk-IGVQF5GY.js";
17
+ } from "./chunk-ITVPRBD6.js";
18
18
  import {
19
19
  NODE_TYPE,
20
20
  RAW_HTML_PREFIX,
21
21
  init_constants
22
- } from "./chunk-LBWIHPN7.js";
22
+ } from "./chunk-DIYO4RBJ.js";
23
23
 
24
24
  // lib/client/templateEngine.ts
25
25
  init_constants();
@@ -37,15 +37,31 @@ function applyStylesToNode(node, styles, viewportWidth) {
37
37
  }
38
38
  return node;
39
39
  }
40
+ function deepMergeStyles(existing, instance) {
41
+ if (!instance) return existing;
42
+ const bothResponsive = isResponsiveStyle(existing) && isResponsiveStyle(instance);
43
+ if (bothResponsive) {
44
+ const e = existing;
45
+ const i = instance;
46
+ const merged = {};
47
+ const keys = /* @__PURE__ */ new Set([...Object.keys(e), ...Object.keys(i)]);
48
+ for (const key of keys) {
49
+ if (e[key] && i[key] && typeof e[key] === "object" && typeof i[key] === "object") {
50
+ merged[key] = { ...e[key], ...i[key] };
51
+ } else {
52
+ merged[key] = i[key] !== void 0 ? i[key] : e[key];
53
+ }
54
+ }
55
+ return merged;
56
+ }
57
+ return { ...existing, ...instance };
58
+ }
40
59
  function mergeNodeStyles(node, instanceStyles, viewportWidth) {
41
60
  if (!instanceStyles) return node;
42
61
  if (isHtmlNode(node) || isEmbedNode(node) || isListNode(node)) {
43
62
  const existingStyle = node.style;
44
63
  if (existingStyle && typeof existingStyle === "object") {
45
- node.style = {
46
- ...existingStyle,
47
- ...instanceStyles
48
- };
64
+ node.style = deepMergeStyles(existingStyle, instanceStyles);
49
65
  } else {
50
66
  node.style = instanceStyles;
51
67
  }
@@ -55,10 +71,7 @@ function mergeNodeStyles(node, instanceStyles, viewportWidth) {
55
71
  }
56
72
  const existingStyle = node.props.style;
57
73
  if (existingStyle && typeof existingStyle === "object") {
58
- node.props.style = {
59
- ...existingStyle,
60
- ...instanceStyles
61
- };
74
+ node.props.style = deepMergeStyles(existingStyle, instanceStyles);
62
75
  } else {
63
76
  node.props.style = instanceStyles;
64
77
  }
@@ -401,7 +414,7 @@ function processStructure(structure, context, viewportWidth, instanceChildren, p
401
414
  }
402
415
  }
403
416
  } else if (key === "html") {
404
- if (preservedType === NODE_TYPE.EMBED) {
417
+ if (preservedType === NODE_TYPE.EMBED && isEmbedNode(processed)) {
405
418
  if (isHtmlMapping(value)) {
406
419
  const resolved = resolveHtmlMapping(value, context.props);
407
420
  processed.html = resolved ?? "";
@@ -425,20 +438,22 @@ function processStructure(structure, context, viewportWidth, instanceChildren, p
425
438
  } else if (key === "type") {
426
439
  if (typeof value === "string" && isValidNodeType(value)) {
427
440
  if (value === NODE_TYPE.COMPONENT && !isComponentNode(processed)) {
441
+ const p = processed;
428
442
  const newProcessed = {
429
443
  type: NODE_TYPE.COMPONENT,
430
444
  component: "",
431
- props: processed.props || {},
432
- children: processed.children,
433
- style: processed.style
445
+ props: p.props || {},
446
+ children: p.children,
447
+ style: p.style
434
448
  };
435
449
  processed = newProcessed;
436
450
  } else if (value === NODE_TYPE.NODE && !isHtmlNode(processed)) {
451
+ const p = processed;
437
452
  const newProcessed = {
438
453
  type: NODE_TYPE.NODE,
439
- tag: processed.component || "div",
440
- children: processed.children,
441
- style: processed.style
454
+ tag: p.component || "div",
455
+ children: p.children,
456
+ style: p.style
442
457
  };
443
458
  processed = newProcessed;
444
459
  }
@@ -481,14 +496,15 @@ function processStructure(structure, context, viewportWidth, instanceChildren, p
481
496
  }
482
497
  }
483
498
  } else if (key === "hover") {
484
- } else if (key === "href" && preservedType === NODE_TYPE.LINK) {
499
+ } else if (key === "href" && preservedType === NODE_TYPE.LINK && isLinkNode(processed)) {
500
+ const pLink = processed;
485
501
  if (isLinkMapping(value)) {
486
502
  const resolved = resolveLinkMapping(value, context.props);
487
503
  if (resolved) {
488
504
  processed.href = resolved.href;
489
505
  if (resolved.target) {
490
- processed.attributes = {
491
- ...processed.attributes || {},
506
+ pLink.attributes = {
507
+ ...pLink.attributes || {},
492
508
  target: resolved.target
493
509
  };
494
510
  }
@@ -507,8 +523,8 @@ function processStructure(structure, context, viewportWidth, instanceChildren, p
507
523
  }
508
524
  processed.href = linkObj.href;
509
525
  if (linkObj.target) {
510
- processed.attributes = {
511
- ...processed.attributes || {},
526
+ pLink.attributes = {
527
+ ...pLink.attributes || {},
512
528
  target: linkObj.target
513
529
  };
514
530
  }
@@ -603,4 +619,4 @@ export {
603
619
  extractAttributesFromNode,
604
620
  skipEmptyTemplateAttributes
605
621
  };
606
- //# sourceMappingURL=chunk-IBR2F4IL.js.map
622
+ //# sourceMappingURL=chunk-6AYGKR6Y.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../lib/client/templateEngine.ts", "../../lib/shared/styleNodeUtils.ts", "../../lib/shared/attributeNodeUtils.ts"],
4
+ "sourcesContent": ["/**\n * Template Engine\n * Handles template evaluation with {{expression}} syntax and style mappings\n *\n * Security: Uses jsep for safe expression parsing instead of eval/new Function()\n */\n\nimport type { StyleMapping, HtmlMapping, ComponentDefinition, StructuredComponentDefinition, ComponentNode, HtmlNode, ComponentInstanceNode, EmbedNode, SlotMarker, StyleObject, ResponsiveStyleObject, StyleValue, TemplateContext } from '../shared/types';\nimport { isResponsiveStyle } from '../shared/styleUtils';\nimport { normalizeStyle as normalizeStyleShared, mergeResponsiveStyles } from '../shared/responsiveStyleUtils';\nimport { DEFAULT_BREAKPOINTS } from '../shared/breakpoints';\nimport { NODE_TYPE } from '../shared/constants';\nimport { isValidNodeType, isComponentNode, isHtmlNode, isSlotMarker, isEmbedNode, isLocaleListNode, isLinkNode, isCMSListNode, isListNode } from '../shared/nodeUtils';\nimport { applyStylesToNode } from '../shared/styleNodeUtils';\nimport { isRichTextMarker, richTextMarkerToHtml } from '../shared/propResolver';\nimport { isTiptapDocument, tiptapToHtml } from '../shared/richtext';\nimport { hasItemTemplates } from '../shared/itemTemplateUtils';\nimport { safeEvaluate } from '../shared/expressionEvaluator';\nimport { RAW_HTML_PREFIX } from '../shared/constants';\nimport { getGlobalTemplateContext } from '../shared/globalTemplateContext';\n\n// Re-export for backward compatibility\nexport { isResponsiveStyle };\n\n/**\n * Normalize a style value - if it's responsive, merge it; if it's flat, return as-is\n * Uses 'all' strategy for editor compatibility (merges all breakpoints)\n */\nexport function normalizeStyle(style: StyleValue | null | undefined): StyleObject | null {\n return normalizeStyleShared(style, 'all');\n}\n\n/**\n * Helper to add a processed item to an array, handling both single items and arrays\n * Converts numbers to strings to match ComponentNode['children'] type\n */\nfunction addProcessedItemToArray(\n item: ComponentNode | (ComponentNode | string)[] | string | number | Record<string, unknown> | null,\n array: Array<ComponentNode | string>\n): void {\n if (item === null) return;\n\n if (Array.isArray(item)) {\n array.push(...item);\n } else if (typeof item === 'number') {\n // Convert numbers to strings to match ComponentNode['children'] type\n array.push(String(item));\n } else {\n array.push(item as ComponentNode | string);\n }\n}\n\n/**\n * Link mapping interface for link nodes\n */\nexport interface LinkMapping {\n _mapping: true;\n prop: string;\n values?: Record<string, { href: string; target?: string }>;\n}\n\n/**\n * Type guard for link mappings\n */\nexport function isLinkMapping(value: unknown): value is LinkMapping {\n if (!value || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n // values is optional - when empty/missing, acts as passthrough for link-type props\n return obj._mapping === true && typeof obj.prop === 'string' && (obj.values === undefined || typeof obj.values === 'object');\n}\n\n/**\n * Resolves a link mapping object to its actual value based on current props\n *\n * Supports two modes:\n * 1. Value mapping: Maps a prop value to a predefined link object\n * { _mapping: true, prop: \"variant\", values: { primary: { href: \"/products\" } } }\n *\n * 2. Passthrough: When values is empty/missing, uses the prop directly if it's a link object\n * { _mapping: true, prop: \"link\" } - uses props.link directly\n *\n * @example\n * // Value mapping\n * resolveLinkMapping(\n * { _mapping: true, prop: \"variant\", values: { primary: { href: \"/products\" } } },\n * { variant: \"primary\" }\n * ) // { href: \"/products\" }\n *\n * @example\n * // Passthrough mode\n * resolveLinkMapping(\n * { _mapping: true, prop: \"link\" },\n * { link: { href: \"/about\", target: \"_blank\" } }\n * ) // { href: \"/about\", target: \"_blank\" }\n */\nexport function resolveLinkMapping(\n mappingObj: unknown,\n props: Record<string, unknown> | undefined\n): { href: string; target?: string } | undefined {\n if (!isLinkMapping(mappingObj)) {\n return undefined;\n }\n\n // Guard against undefined props\n if (!props) {\n return undefined;\n }\n\n const { prop, values } = mappingObj;\n const propValue = props[prop];\n if (propValue === undefined || propValue === null) {\n return undefined;\n }\n\n // Passthrough mode: if prop value is already a link object, use it directly\n if (typeof propValue === 'object' && propValue !== null && 'href' in propValue) {\n return propValue as { href: string; target?: string };\n }\n\n // Value mapping mode: look up the prop value in the values map\n if (values) {\n const mappedValue = values[String(propValue)];\n return mappedValue;\n }\n\n return undefined;\n}\n\n/**\n * Type guard for HTML mappings (embed node html property)\n */\nexport function isHtmlMapping(value: unknown): value is HtmlMapping {\n if (!value || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n return obj._mapping === true && typeof obj.prop === 'string';\n}\n\n/**\n * Resolves an HTML mapping object to its actual value based on current props\n *\n * Supports two modes:\n * 1. Value mapping: Maps a prop value to a predefined HTML string\n * { _mapping: true, prop: \"icon\", values: { arrow: \"<svg>...</svg>\", check: \"<svg>...</svg>\" } }\n *\n * 2. Passthrough: When values is omitted/empty, uses the prop directly if it's a string\n * { _mapping: true, prop: \"svgContent\" } - uses props.svgContent directly\n */\nexport function resolveHtmlMapping(\n mappingObj: unknown,\n props: Record<string, unknown> | undefined\n): string | undefined {\n if (!isHtmlMapping(mappingObj)) {\n return undefined;\n }\n\n if (!props) {\n return undefined;\n }\n\n const { prop, values } = mappingObj;\n const propValue = props[prop];\n if (propValue === undefined || propValue === null) {\n return undefined;\n }\n\n // Value mapping mode: look up the prop value in the values map\n if (values && Object.keys(values).length > 0) {\n return values[String(propValue)];\n }\n\n // Passthrough mode: use the prop value directly if it's a string\n if (typeof propValue === 'string') {\n return propValue;\n }\n\n return undefined;\n}\n\n/**\n * Resolves a style mapping object to its actual value based on current props\n *\n * @example\n * resolveStyleMapping(\n * { _mapping: true, prop: \"variant\", values: { primary: \"#0070f3\", secondary: \"#f3f4f6\" } },\n * { variant: \"primary\" }\n * ) // \"#0070f3\"\n */\nexport function resolveStyleMapping(\n mappingObj: unknown,\n props: Record<string, unknown> | undefined\n): string | number | undefined {\n if (!mappingObj || typeof mappingObj !== 'object') {\n return undefined;\n }\n\n const mapping = mappingObj as StyleMapping;\n if (!mapping || !mapping._mapping) {\n return undefined;\n }\n\n const { prop, values } = mapping;\n if (!prop || !values || typeof values !== 'object') {\n return undefined;\n }\n\n // Guard against undefined props\n if (!props) {\n return undefined;\n }\n\n const propValue = props[prop];\n if (propValue === undefined || propValue === null) {\n return undefined;\n }\n\n const mappedValue = values[String(propValue)];\n return mappedValue !== undefined ? mappedValue : undefined;\n}\n\n/**\n * Process a single style value - resolves mappings and evaluates templates.\n * Skips item templates ({{item.field}}, {{varName.field}}) which are resolved later during rendering.\n *\n * @param styleValue - The style value to process (may be string, number, or mapping object)\n * @param props - Component props for resolving mappings and templates\n * @returns The processed style value, or undefined if the value should be skipped\n */\nfunction processStyleValue(\n styleValue: unknown,\n props: Record<string, unknown> | undefined\n): string | number | undefined {\n // First try style mapping resolution\n const resolved = resolveStyleMapping(styleValue, props);\n if (resolved !== undefined) {\n return resolved;\n }\n\n // String values - evaluate templates (but skip item templates)\n if (typeof styleValue === 'string') {\n if (hasTemplates(styleValue) && !hasItemTemplates(styleValue)) {\n return processCodeTemplates(styleValue, props);\n }\n return styleValue;\n }\n\n // Number values - pass through\n if (typeof styleValue === 'number') {\n return styleValue;\n }\n\n return undefined;\n}\n\n/**\n * Build evaluation context for template processing.\n * Merges global context, props, componentDef, and optionally itemContext.\n *\n * @param context - The TemplateContext containing props and componentDef\n * @param includeItemContext - Whether to include itemContext from the context object\n * @returns A flat object suitable for template evaluation\n */\nfunction buildEvalContext(\n context: TemplateContext,\n includeItemContext: boolean = false\n): Record<string, unknown> {\n const evalContext: Record<string, unknown> = {\n ...getGlobalTemplateContext(),\n ...context.props\n };\n\n if (context.componentDef && typeof context.componentDef === 'object') {\n Object.assign(evalContext, context.componentDef as Record<string, unknown>);\n }\n\n if (includeItemContext) {\n const itemContext = (context as Record<string, unknown>).itemContext as Record<string, unknown> | undefined;\n if (itemContext) {\n Object.assign(evalContext, itemContext);\n }\n }\n\n return evalContext;\n}\n\n/** Maximum allowed expression length to prevent DoS via complex expressions */\nconst MAX_EXPRESSION_LENGTH = 500;\n\n/** Maximum recursion depth to prevent stack overflow from circular references */\nconst MAX_RECURSION_DEPTH = 100;\n\n/**\n * Evaluates a template string with the given context\n * Template format: {{expression}}\n * Handles undefined variables gracefully by returning undefined instead of throwing\n *\n * Security: Uses jsep for safe expression parsing - only whitelisted AST nodes are evaluated.\n * No eval/new Function is used, preventing arbitrary code execution.\n *\n * @example\n * evaluateTemplate(\"{{name}}\", { name: \"John\" }) // \"John\"\n * evaluateTemplate(\"{{count + 1}}\", { count: 5 }) // 6\n * evaluateTemplate(\"{{undefinedVar}}\", {}) // undefined (no error thrown)\n */\nexport function evaluateTemplate(\n template: string,\n context: Record<string, unknown>\n): unknown {\n if (typeof template !== 'string') return template;\n\n const templateMatch = template.match(/^\\{\\{(.+)\\}\\}$/);\n if (!templateMatch) return template;\n\n const expression = templateMatch[1].trim();\n\n // Security: Expression length limit to prevent DoS\n if (expression.length > MAX_EXPRESSION_LENGTH) {\n console.warn('Template expression too long:', expression.slice(0, 50) + '...');\n return template;\n }\n\n try {\n // Use safe expression evaluator (jsep-based, no eval/new Function)\n const result = safeEvaluate(expression, context);\n // If result is undefined, return template string for backward compatibility\n return result === undefined ? template : result;\n } catch (error) {\n console.error('Template evaluation error:', error, 'Expression:', expression, 'Context:', context);\n // Return original template string on error for backward compatibility\n return template;\n }\n}\n\n/**\n * Checks if a code string contains any template patterns {{...}}\n */\nexport function hasTemplates(code: string): boolean {\n if (typeof code !== 'string') return false;\n return /\\{\\{[^}]+\\}\\}/.test(code);\n}\n\n/**\n * Processes template strings in JavaScript or CSS code\n * Replaces {{propName}} or {{expression}} with evaluated values\n * \n * @example\n * processCodeTemplates(\"console.log('{{name}}');\", { name: \"John\" })\n * // \"console.log('John');\"\n * \n * processCodeTemplates(\".card { color: {{color}}; }\", { color: \"#ff0000\" })\n * // \".card { color: #ff0000; }\"\n */\nexport function processCodeTemplates(\n code: string,\n context: Record<string, unknown> | undefined\n): string {\n if (typeof code !== 'string') return code;\n\n // Guard against undefined context\n if (!context) {\n return code;\n }\n\n // Match all {{...}} patterns in the code\n return code.replace(/\\{\\{([^}]+)\\}\\}/g, (match: string, expression: string): string => {\n const trimmedExpr = expression.trim();\n\n // Security: Expression length limit to prevent DoS\n if (trimmedExpr.length > MAX_EXPRESSION_LENGTH) {\n console.warn('Code template expression too long:', trimmedExpr.slice(0, 50) + '...');\n return match;\n }\n\n try {\n // Use safe expression evaluator (jsep-based, no eval/new Function)\n const result = safeEvaluate(trimmedExpr, context);\n\n // Convert result to string, handling various types\n if (result === null || result === undefined) {\n return '';\n }\n if (typeof result === 'string') {\n return result;\n }\n if (typeof result === 'number' || typeof result === 'boolean') {\n return String(result);\n }\n // Handle rich-text markers - extract HTML content for interpolation\n if (isRichTextMarker(result)) {\n return richTextMarkerToHtml(result);\n }\n // For objects/arrays, stringify them\n return JSON.stringify(result);\n } catch (error) {\n console.error('Code template evaluation error:', error, 'Expression:', trimmedExpr, 'Context:', context);\n // Return original template if evaluation fails\n return match;\n }\n });\n}\n\n/**\n * Processes a component structure recursively, evaluating templates\n * @param context - Template context containing props, componentDef, and extensible namespaces (e.g., cms, page)\n * @param viewportWidth - Optional viewport width for responsive style resolution. If provided, uses 'viewport' strategy; otherwise uses 'all' strategy.\n * @param instanceChildren - Optional children from component instance to replace { type: \"children\" } markers\n * @param preserveResponsiveStyles - Whether to preserve responsive style objects (for SSR)\n * @param depth - Internal recursion depth counter to prevent stack overflow\n */\nexport function processStructure(\n structure: ComponentNode | ComponentNode[] | string | number | null | undefined,\n context: TemplateContext,\n viewportWidth?: number,\n instanceChildren?: ComponentNode['children'],\n preserveResponsiveStyles: boolean = false,\n depth: number = 0\n): ComponentNode | (ComponentNode | string)[] | string | number | Record<string, unknown> | null {\n try {\n // Guard against excessive recursion (circular references or very deep structures)\n if (depth > MAX_RECURSION_DEPTH) {\n console.warn(`processStructure: Maximum recursion depth (${MAX_RECURSION_DEPTH}) exceeded. Possible circular reference.`);\n return null;\n }\n\n // Handle null/undefined\n if (structure === null || structure === undefined) return null;\n\n // Preserve boolean values (don't convert false to null)\n if (typeof structure === 'boolean') {\n return structure;\n }\n\n if (typeof structure === 'string') {\n // Build evaluation context with item context for nested template resolution\n const evalContext = buildEvalContext(context, true);\n\n // Check if entire string is a complete template {{expr}}\n // Use evaluateTemplate to preserve type (objects, arrays, numbers)\n if (/^\\{\\{.+\\}\\}$/.test(structure) && !hasItemTemplates(structure)) {\n const result = evaluateTemplate(structure, evalContext);\n // Check for rich-text marker - extract HTML content with RAW_HTML_PREFIX\n // The prefix signals to ComponentBuilder.processTextNode to render as HTML\n if (isRichTextMarker(result)) {\n return RAW_HTML_PREFIX + richTextMarkerToHtml(result);\n }\n if (typeof result === 'string' || typeof result === 'number') {\n return result;\n }\n if (result === undefined || result === null) {\n return '';\n }\n // Return objects as-is (e.g., link objects { href, target })\n // The caller (e.g., href handling) will process them appropriately\n if (typeof result === 'object') {\n return result as Record<string, unknown>;\n }\n return String(result);\n }\n\n // Check if string contains partial templates like \"heading-{{size}}\"\n // Use processCodeTemplates for string interpolation\n // BUT skip if it contains CMS item templates ({{item.field}}, {{varName.field}}, etc.)\n // Those will be processed later by processItemTemplate with proper context\n if (hasTemplates(structure) && !hasItemTemplates(structure)) {\n return processCodeTemplates(structure, evalContext);\n }\n\n // No templates - return as-is\n return structure;\n }\n \n if (Array.isArray(structure)) {\n const processed: Array<ComponentNode | string> = [];\n for (const item of structure) {\n // Check if this is a slot marker\n if (isSlotMarker(item)) {\n // Replace marker with instance children (if provided)\n if (instanceChildren) {\n const childrenArray = Array.isArray(instanceChildren) ? instanceChildren : [instanceChildren];\n for (const child of childrenArray) {\n const processedChild = processStructure(child, context, viewportWidth, instanceChildren, preserveResponsiveStyles, depth + 1);\n addProcessedItemToArray(processedChild, processed);\n }\n } else if ('default' in item && (item as SlotMarker).default !== undefined) {\n // Fallback: use slot's default content if no instance children provided\n const defaultContent = (item as SlotMarker).default;\n const defaultsArray = Array.isArray(defaultContent) ? defaultContent : [defaultContent];\n for (const defaultChild of defaultsArray) {\n const processedChild = processStructure(defaultChild, context, viewportWidth, undefined, preserveResponsiveStyles, depth + 1);\n addProcessedItemToArray(processedChild, processed);\n }\n }\n // If no instance children AND no default, marker renders nothing (skip it)\n } else {\n // Regular item - process normally\n const processedItem = processStructure(item, context, viewportWidth, instanceChildren, preserveResponsiveStyles, depth + 1);\n addProcessedItemToArray(processedItem, processed);\n }\n }\n return processed;\n }\n \n if (typeof structure === 'object' && !Array.isArray(structure) && structure !== null) {\n // Check if this is a slot marker (shouldn't happen here since we handle it in array processing, but guard anyway)\n if (isSlotMarker(structure)) {\n // This shouldn't happen in object processing, but if it does, return instance children or default\n if (instanceChildren) {\n const processed: Array<ComponentNode | string> = [];\n const childrenArray = Array.isArray(instanceChildren) ? instanceChildren : [instanceChildren];\n for (const child of childrenArray) {\n const processedChild = processStructure(child, context, viewportWidth, instanceChildren, preserveResponsiveStyles, depth + 1);\n addProcessedItemToArray(processedChild, processed);\n }\n return processed.length === 1 ? processed[0] : processed;\n }\n // Fallback: use slot's default content\n if ('default' in structure && (structure as SlotMarker).default !== undefined) {\n const defaultContent = (structure as SlotMarker).default;\n const processed: Array<ComponentNode | string> = [];\n const defaultsArray = Array.isArray(defaultContent) ? defaultContent : [defaultContent];\n for (const defaultChild of defaultsArray) {\n const processedChild = processStructure(defaultChild, context, viewportWidth, undefined, preserveResponsiveStyles, depth + 1);\n addProcessedItemToArray(processedChild, processed);\n }\n return processed.length === 1 ? processed[0] : processed;\n }\n return null;\n }\n \n // Check if this is a valid node structure or a plain object (like props)\n const inputNode = structure as ComponentNode;\n const hasValidNodeType = inputNode.type && isValidNodeType(inputNode.type);\n\n // If no valid node type, treat as plain object and process values recursively\n // This handles props objects like { text: \"{{text}}\", isMarginBottom: false }\n if (!hasValidNodeType) {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(structure)) {\n const processedValue = processStructure(value as ComponentNode | string | number | null, context, viewportWidth, instanceChildren, preserveResponsiveStyles, depth + 1);\n if (processedValue !== null && processedValue !== undefined) {\n result[key] = processedValue;\n }\n }\n return result;\n }\n\n const preservedType = inputNode.type;\n\n // Create base processed object based on type\n let processed: ComponentNode;\n if (preservedType === NODE_TYPE.COMPONENT) {\n processed = {\n type: NODE_TYPE.COMPONENT,\n component: '',\n props: {},\n children: [] as Array<ComponentNode | string>\n } as ComponentInstanceNode;\n } else if (preservedType === NODE_TYPE.EMBED) {\n // Handle embed nodes - they have html content, not children\n processed = {\n type: NODE_TYPE.EMBED,\n html: '',\n } as unknown as ComponentNode;\n } else if (preservedType === NODE_TYPE.LINK) {\n // Handle link nodes - they have href property\n processed = {\n type: NODE_TYPE.LINK,\n href: '',\n children: [] as Array<ComponentNode | string>\n } as unknown as ComponentNode;\n } else if (preservedType === NODE_TYPE.LOCALE_LIST) {\n // Handle locale-list nodes - they have style, itemStyle, activeItemStyle properties\n processed = {\n type: NODE_TYPE.LOCALE_LIST,\n } as unknown as ComponentNode;\n } else if (preservedType === NODE_TYPE.LIST || (preservedType as string) === 'cms-list') {\n // Handle list nodes (unified - handles both prop and collection source types)\n // Also supports legacy 'cms-list' type for migration\n processed = {\n type: NODE_TYPE.LIST,\n source: '',\n children: [] as Array<ComponentNode | string>\n } as unknown as ComponentNode;\n } else {\n processed = {\n type: NODE_TYPE.NODE,\n tag: 'div',\n children: [] as Array<ComponentNode | string>\n } as HtmlNode;\n }\n \n // First pass: process all keys and resolve style mappings\n let resolvedStyle: StyleValue | null = null;\n \n for (const [key, value] of Object.entries(structure)) {\n try {\n if (key === 'children') {\n const processedChildren = processStructure(value as ComponentNode | ComponentNode[] | string | number | null | undefined, context, viewportWidth, instanceChildren, preserveResponsiveStyles, depth + 1);\n if (Array.isArray(processedChildren)) {\n processed.children = processedChildren;\n } else if (processedChildren !== null && processedChildren !== undefined) {\n processed.children = [processedChildren as ComponentNode | string];\n }\n } else if (key === 'tag') {\n // Handle tag for HTML nodes\n if (isHtmlNode(processed)) {\n if (typeof value === 'string') {\n // Process template in tag (e.g., \"h{{size}}\" -> \"h1\")\n const evalContext = buildEvalContext(context, false);\n // Use processCodeTemplates to handle partial templates like \"h{{size}}\"\n processed.tag = processCodeTemplates(value, evalContext);\n } else if (value === false) {\n // Preserve boolean false for fragment mode (no container)\n (processed as Record<string, unknown>).tag = false;\n } else {\n processed.tag = String(value);\n }\n }\n } else if (key === 'component') {\n if (isComponentNode(processed)) {\n if (typeof value === 'string') {\n processed.component = value;\n } else {\n processed.component = String(value);\n }\n }\n } else if (key === 'html') {\n // Handle html property for embed nodes - process templates like {{propName}}\n if (preservedType === NODE_TYPE.EMBED && isEmbedNode(processed)) {\n if (isHtmlMapping(value)) {\n // Resolve HTML mapping to actual content\n const resolved = resolveHtmlMapping(value, context.props);\n processed.html = resolved ?? '';\n } else if (typeof value === 'string') {\n // Build evaluation context with item context for nested template resolution\n const evalContext = buildEvalContext(context, true);\n // Check if entire string is a complete template {{expr}}\n if (/^\\{\\{.+\\}\\}$/.test(value) && !hasItemTemplates(value)) {\n const result = evaluateTemplate(value, evalContext);\n processed.html = result === undefined || result === null ? '' : String(result);\n } else if (hasTemplates(value) && !hasItemTemplates(value)) {\n // Use processCodeTemplates to handle partial templates\n processed.html = processCodeTemplates(value, evalContext);\n } else {\n processed.html = value;\n }\n } else if (typeof value === 'object' && value !== null && (value as Record<string, unknown>)._mapping === true) {\n // HtmlMapping object that isHtmlMapping somehow missed \u2014 resolve it defensively\n const resolved = resolveHtmlMapping(value, context.props);\n processed.html = resolved ?? '';\n } else {\n processed.html = '';\n }\n }\n } else if (key === 'type') {\n // Preserve type field if valid - but don't change the structure type\n if (typeof value === 'string' && isValidNodeType(value)) {\n // Only update if type actually changed\n if (value === NODE_TYPE.COMPONENT && !isComponentNode(processed)) {\n // Convert to component node\n const p = processed as Record<string, unknown>;\n const newProcessed: ComponentInstanceNode = {\n type: NODE_TYPE.COMPONENT,\n component: '',\n props: (p.props || {}) as ComponentInstanceNode['props'],\n children: p.children as ComponentInstanceNode['children'],\n style: p.style as ComponentInstanceNode['style']\n };\n processed = newProcessed;\n } else if (value === NODE_TYPE.NODE && !isHtmlNode(processed)) {\n // Convert to HTML node\n const p = processed as Record<string, unknown>;\n const newProcessed: HtmlNode = {\n type: NODE_TYPE.NODE,\n tag: (p.component as string) || 'div',\n children: p.children as HtmlNode['children'],\n style: p.style as HtmlNode['style']\n };\n processed = newProcessed;\n }\n }\n } else if (key === 'style' && typeof value === 'object' && value !== null) {\n // Process style at top level - DO NOT recursively call processStructure\n // as it would mangle style mapping objects { _mapping: true, prop: \"size\", values: {...} }\n // into ComponentNode structures. Style objects need special handling.\n const processedStyle = value as Record<string, unknown>;\n if (processedStyle && typeof processedStyle === 'object' && !Array.isArray(processedStyle)) {\n // Check if it's a responsive style object\n const styleEvalContext = buildEvalContext(context, false);\n if (isResponsiveStyle(processedStyle as StyleValue)) {\n // Preserve responsive styles (for both SSR and editor)\n // responsiveStylesToClasses will generate prefixed classes (t-, mob-)\n // CSS media queries will handle displaying the correct styles based on viewport\n const resolvedResponsive: ResponsiveStyleObject = {};\n for (const [bkeyName, bkeyValue] of Object.entries(processedStyle)) {\n if (typeof bkeyValue === 'object' && bkeyValue !== null) {\n resolvedResponsive[bkeyName] = {};\n for (const [styleKey, styleValue] of Object.entries(bkeyValue)) {\n const processedValue = processStyleValue(styleValue, styleEvalContext);\n if (processedValue !== undefined) {\n resolvedResponsive[bkeyName]![styleKey] = processedValue;\n }\n }\n }\n }\n resolvedStyle = resolvedResponsive;\n } else {\n // Legacy flat style object - resolve mappings and evaluate templates\n resolvedStyle = {};\n for (const [styleKey, styleValue] of Object.entries(processedStyle)) {\n const processedValue = processStyleValue(styleValue, styleEvalContext);\n if (processedValue !== undefined) {\n resolvedStyle[styleKey] = processedValue;\n }\n }\n }\n }\n } else if (key === 'props' && typeof value === 'object' && value !== null) {\n // Process non-style props (for instance props only)\n const processedProps = processStructure(value as ComponentNode | ComponentNode[] | string | number | null | undefined, context, viewportWidth, instanceChildren, preserveResponsiveStyles, depth + 1);\n // Merge non-style props (style is handled separately at top level)\n if (typeof processedProps === 'object' && !Array.isArray(processedProps) && processedProps !== null && processed.props) {\n const propsObj = processedProps as unknown as Record<string, unknown>;\n Object.assign(processed.props, propsObj);\n // Remove style from props since we handle it at top level\n if ((processed.props as Record<string, unknown>).style !== undefined) {\n delete (processed.props as Record<string, unknown>).style;\n }\n }\n } else if (key === 'hover') {\n // Skip hover for now - it's not a standard React prop\n // Could be implemented with onMouseEnter/onMouseLeave\n } else if (key === 'href' && preservedType === NODE_TYPE.LINK && isLinkNode(processed)) {\n // Special handling for href in link nodes - resolve link mappings\n const pLink = processed as Record<string, unknown>;\n if (isLinkMapping(value)) {\n const resolved = resolveLinkMapping(value, context.props);\n if (resolved) {\n processed.href = resolved.href;\n if (resolved.target) {\n pLink.attributes = {\n ...((pLink.attributes as Record<string, unknown>) || {}),\n target: resolved.target\n };\n }\n } else {\n processed.href = '#';\n }\n } else {\n // Regular href value - process as template\n const processedValue = processStructure(value as ComponentNode | ComponentNode[] | string | number | null | undefined, context, viewportWidth, instanceChildren, preserveResponsiveStyles, depth + 1);\n if (processedValue !== null && processedValue !== undefined) {\n // Check if result is a link object (from link-type prop like {{link}})\n if (typeof processedValue === 'object' && processedValue !== null && 'href' in processedValue) {\n // Unwrap nested link objects (e.g., {href: {href: \"/path\"}} from double-wrapped list item templates)\n let linkObj = processedValue as { href: unknown; target?: string };\n while (typeof linkObj.href === 'object' && linkObj.href !== null && 'href' in (linkObj.href as Record<string, unknown>)) {\n const nested = linkObj.href as { href: unknown; target?: string };\n if (!linkObj.target && nested.target) linkObj = { ...linkObj, target: nested.target };\n linkObj = { ...linkObj, href: nested.href };\n }\n processed.href = linkObj.href as string;\n if (linkObj.target) {\n pLink.attributes = {\n ...((pLink.attributes as Record<string, unknown>) || {}),\n target: linkObj.target\n };\n }\n } else {\n processed.href = processedValue as string;\n }\n }\n }\n } else if (key === 'attributes' && typeof value === 'object' && value !== null) {\n // Special handling for attributes - process templates but don't treat as node structure\n // This preserves type=\"checkbox\" etc. which would otherwise be caught by node type handling\n const processedAttributes: Record<string, unknown> = {};\n const evalContext = buildEvalContext(context, false);\n for (const [attrKey, attrValue] of Object.entries(value)) {\n if (typeof attrValue === 'string' && hasTemplates(attrValue)) {\n // Check if entire string is a complete template {{expr}} - preserve type (boolean, number)\n if (/^\\{\\{.+\\}\\}$/.test(attrValue)) {\n const result = evaluateTemplate(attrValue, evalContext);\n // Skip attribute if complete template resolved to empty string\n if (result === '') continue;\n // Keep the original type (boolean, number, string)\n processedAttributes[attrKey] = result === attrValue ? attrValue : result;\n } else {\n // Partial template like \"prefix-{{value}}\" - always string\n processedAttributes[attrKey] = processCodeTemplates(attrValue, evalContext);\n }\n } else {\n processedAttributes[attrKey] = attrValue;\n }\n }\n (processed as unknown as Record<string, unknown>).attributes = processedAttributes;\n } else if (key === 'interactiveStyles' && Array.isArray(value)) {\n // Special handling for interactiveStyles - preserve as-is without mangling\n // Interactive styles contain StyleMapping objects that shouldn't be converted to nodes\n (processed as unknown as Record<string, unknown>).interactiveStyles = value;\n } else if (key !== 'type' && key !== 'children' && key !== 'style' && key !== 'props') {\n const processedValue = processStructure(value as ComponentNode | ComponentNode[] | string | number | null | undefined, context, viewportWidth, instanceChildren, preserveResponsiveStyles, depth + 1);\n // Only assign if it's a valid value\n if (processedValue !== null && processedValue !== undefined) {\n // Store extra properties on the node object\n (processed as unknown as Record<string, unknown>)[key] = processedValue;\n }\n }\n } catch (error) {\n console.error(`Error processing key \"${key}\":`, error);\n // Continue processing other keys\n }\n }\n \n // Apply resolved styles to the processed node based on its type\n // Both SSR and Editor now preserve responsive styles for proper utility class generation\n if (resolvedStyle && Object.keys(resolvedStyle).length > 0) {\n if (isResponsiveStyle(resolvedStyle)) {\n // Apply responsive styles directly to node.style or props.style\n if (isComponentNode(processed)) {\n (processed as unknown as Record<string, unknown>).style = resolvedStyle as ResponsiveStyleObject;\n } else if (isHtmlNode(processed) || isEmbedNode(processed) || isLocaleListNode(processed) || isLinkNode(processed) || isListNode(processed)) {\n processed.style = resolvedStyle as ResponsiveStyleObject;\n }\n } else {\n // Legacy flat style object\n applyStylesToNode(processed, resolvedStyle);\n }\n }\n \n return processed;\n }\n \n return structure;\n } catch (error) {\n console.error('Error in processStructure:', error);\n throw error; // Re-throw so it can be caught by error boundary\n }\n}\n\n", "/**\n * Utilities for working with styles in ComponentNode structures\n * Provides helper functions for applying and merging styles based on node type\n */\n\nimport type { ComponentNode, HtmlNode, ComponentInstanceNode, StyleValue, ResponsiveStyleObject } from './types';\nimport { isComponentNode, isHtmlNode, isEmbedNode, isListNode } from './nodeUtils';\nimport { isResponsiveStyle } from './styleUtils';\n\n/**\n * Apply styles to a ComponentNode based on its type\n * - HTML nodes: styles go at top level (node.style)\n * - Component instances: styles go in props.style\n */\nexport function applyStylesToNode(\n node: ComponentNode,\n styles: StyleValue | Record<string, string | number> | null | undefined,\n viewportWidth?: number\n): ComponentNode {\n if (!styles) return node;\n\n if (isComponentNode(node)) {\n // Component instance: put styles in props.style\n if (!node.props) {\n node.props = {};\n }\n\n node.props.style = { ...(node.props.style || {}), ...styles };\n } else if (isHtmlNode(node) || isEmbedNode(node) || isListNode(node)) {\n // HTML node, Embed node, and List node: put styles at top level\n node.style = styles as StyleValue;\n }\n\n return node;\n}\n\n/**\n * Deep-merge two style objects, handling responsive breakpoint keys.\n * When both are responsive ({ base, tablet, mobile }), merges per breakpoint\n * so that instance properties override structure properties within each breakpoint\n * rather than replacing the entire breakpoint object.\n */\nfunction deepMergeStyles(\n existing: StyleValue | Record<string, any>,\n instance: StyleValue | Record<string, any> | null | undefined\n): StyleValue {\n if (!instance) return existing as StyleValue;\n\n const bothResponsive =\n isResponsiveStyle(existing as StyleValue) && isResponsiveStyle(instance as StyleValue);\n\n if (bothResponsive) {\n const e = existing as Record<string, any>;\n const i = instance as Record<string, any>;\n const merged: Record<string, any> = {};\n const keys = new Set([...Object.keys(e), ...Object.keys(i)]);\n for (const key of keys) {\n if (e[key] && i[key] && typeof e[key] === 'object' && typeof i[key] === 'object') {\n merged[key] = { ...e[key], ...i[key] };\n } else {\n merged[key] = i[key] !== undefined ? i[key] : e[key];\n }\n }\n return merged as StyleValue;\n }\n\n // Flat styles: shallow merge (instance overrides)\n return { ...(existing as Record<string, any>), ...(instance as Record<string, any>) } as StyleValue;\n}\n\n/**\n * Merge instance styles with structure styles for a ComponentNode\n * Instance styles override structure styles\n */\nexport function mergeNodeStyles(\n node: ComponentNode,\n instanceStyles: StyleValue | Record<string, string | number> | null | undefined,\n viewportWidth?: number\n): ComponentNode {\n if (!instanceStyles) return node;\n\n if (isHtmlNode(node) || isEmbedNode(node) || isListNode(node)) {\n // For HTML nodes, Embed nodes, and List nodes: merge instance styles with existing top-level styles\n const existingStyle = node.style;\n if (existingStyle && typeof existingStyle === 'object') {\n node.style = deepMergeStyles(existingStyle, instanceStyles);\n } else {\n node.style = instanceStyles as StyleValue;\n }\n } else if (isComponentNode(node)) {\n // For component instances: merge into props.style\n if (!node.props) {\n node.props = {};\n }\n const existingStyle = node.props.style;\n if (existingStyle && typeof existingStyle === 'object') {\n node.props.style = deepMergeStyles(existingStyle, instanceStyles);\n } else {\n node.props.style = instanceStyles;\n }\n }\n\n return node;\n}\n\n/**\n * Extract styles from a ComponentNode based on its type\n * Returns a flat style object ready for React props\n */\nexport function extractStylesFromNode(\n node: ComponentNode,\n viewportWidth?: number\n): Record<string, string | number> {\n if (isComponentNode(node)) {\n // Component instance: styles are in props.style\n const style = node.props?.style;\n if (!style) return {};\n\n return style as Record<string, string | number>;\n } else if (isHtmlNode(node) || isEmbedNode(node)) {\n // HTML node and Embed node: styles are at top level\n const style = node.style;\n if (!style) return {};\n\n return style as Record<string, string | number>;\n }\n\n return {};\n}\n\n", "/**\n * Utilities for working with attributes in ComponentNode structures\n * Provides helper functions for extracting and applying attributes based on node type\n */\n\nimport type { ComponentNode } from './types';\nimport { isComponentNode, isHtmlNode } from './nodeUtils';\n\n/**\n * Extract attributes from a ComponentNode\n * Attributes are stored at the top level of the node (like styles)\n * Returns a record of attributes ready for React props\n */\nexport function extractAttributesFromNode(\n node: ComponentNode\n): Record<string, string | number | boolean> {\n if (!node || typeof node !== 'object') {\n return {};\n }\n\n // Attributes are stored at top level for both HTML nodes and component instances\n if ('attributes' in node && node.attributes) {\n return node.attributes as Record<string, string | number | boolean>;\n }\n\n return {};\n}\n\n/**\n * Remove attributes that were entirely template expressions (e.g., \"{{fade}}\")\n * and resolved to empty string \"\". Static attributes and partial templates are unchanged.\n */\nexport function skipEmptyTemplateAttributes(\n original: Record<string, unknown>,\n resolved: Record<string, unknown>\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(resolved)) {\n const orig = original[key];\n if (\n typeof orig === 'string' &&\n /^\\{\\{.+\\}\\}$/.test(orig) &&\n value === ''\n ) {\n continue;\n }\n result[key] = value;\n }\n return result;\n}\n\n/**\n * Apply attributes to a ComponentNode\n * Attributes go at top level (node.attributes)\n */\nexport function applyAttributesToNode(\n node: ComponentNode,\n attributes: Record<string, string | number | boolean> | null | undefined\n): ComponentNode {\n if (!attributes || Object.keys(attributes).length === 0) {\n return node;\n }\n\n if (isComponentNode(node) || isHtmlNode(node)) {\n return {\n ...node,\n attributes: { ...(node.attributes || {}), ...attributes }\n };\n }\n\n return node;\n}\n\n"],
5
+ "mappings": "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",
6
+ "names": ["normalizeStyle", "processed"]
7
+ }
@@ -15,18 +15,18 @@ import {
15
15
  migrateTemplatesDirectory,
16
16
  parseJSON,
17
17
  prepareClientData
18
- } from "./chunk-SK3TLNUP.js";
18
+ } from "./chunk-UGHOL7IP.js";
19
19
  import {
20
20
  minifyJS,
21
21
  projectPaths
22
- } from "./chunk-YSZ5IUFM.js";
22
+ } from "./chunk-5Z5VQRTJ.js";
23
23
  import {
24
24
  inspect
25
25
  } from "./chunk-WQFG7PAH.js";
26
26
  import {
27
27
  isItemDraftForLocale,
28
28
  isItemFullyPublished
29
- } from "./chunk-IGVQF5GY.js";
29
+ } from "./chunk-ITVPRBD6.js";
30
30
  import {
31
31
  isI18nValue,
32
32
  resolveI18nValue
@@ -753,7 +753,7 @@ async function buildStaticPages() {
753
753
  console.log("\u{1F3D7}\uFE0F Building static HTML files...\n");
754
754
  buildErrors.length = 0;
755
755
  clearJSValidationCache();
756
- const { configService } = await import("./configService-MICL4S2L.js");
756
+ const { configService } = await import("./configService-KK5JEQOZ.js");
757
757
  configService.reset();
758
758
  const projectConfig = await loadProjectConfig();
759
759
  const siteUrl = projectConfig.siteUrl?.replace(/\/$/, "");
@@ -1130,4 +1130,4 @@ export {
1130
1130
  injectTrackingScript,
1131
1131
  buildStaticPages
1132
1132
  };
1133
- //# sourceMappingURL=chunk-EQOSDQS2.js.map
1133
+ //# sourceMappingURL=chunk-ACK7AURE.js.map
@@ -168,8 +168,14 @@ var init_constants = __esm({
168
168
  // Editor → Iframe for committed mutations
169
169
  COMPONENT_DEFINITION_COMMITTED: "COMPONENT_DEFINITION_COMMITTED",
170
170
  // Editor → Iframe for component definition updates
171
- CSS_VARIABLE_UPDATE: "CSS_VARIABLE_UPDATE"
171
+ CSS_VARIABLE_UPDATE: "CSS_VARIABLE_UPDATE",
172
172
  // Editor → Iframe for instant CSS variable preview
173
+ INLINE_TEXT_EDIT_START: "INLINE_TEXT_EDIT_START",
174
+ // Editor → Iframe: start inline text editing
175
+ INLINE_TEXT_EDIT_SAVE: "INLINE_TEXT_EDIT_SAVE",
176
+ // Iframe → Editor: save inline text edit
177
+ INLINE_TEXT_EDIT_CANCEL: "INLINE_TEXT_EDIT_CANCEL"
178
+ // Iframe → Editor: cancel inline text edit
173
179
  };
174
180
  NODE_TYPE = {
175
181
  NODE: "node",
@@ -220,4 +226,4 @@ export {
220
226
  RAW_HTML_PREFIX,
221
227
  init_constants
222
228
  };
223
- //# sourceMappingURL=chunk-LBWIHPN7.js.map
229
+ //# sourceMappingURL=chunk-DIYO4RBJ.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../lib/shared/constants.ts"],
4
- "sourcesContent": ["/**\n * Shared constants used across the application\n */\n\n// Read PORT from environment variable, fallback to 3000\n// Safe for browser environments where process is not defined\nexport const SERVER_PORT = typeof process !== 'undefined' && process.env?.PORT\n ? parseInt(process.env.PORT, 10)\n : 3000;\n\n// Port for serving built static files\nexport const SERVE_PORT = 8080;\n\nexport const API_ROUTES = {\n PAGES: '/api/pages',\n COMPONENTS: '/api/components',\n PAGE_CONTENT: '/api/page-content', // Returns raw JSON text for a page\n PAGE_DATA: '/api/page-data', // Returns parsed JSON for a specific page\n COMPONENT_DATA: '/api/component-data', // Returns parsed JSON for a specific component\n SAVE_PAGE: '/api/save-page',\n SAVE_COMPONENT: '/api/save-component',\n SAVE_COMPONENT_JS: '/api/save-component-js', // Save JavaScript to .js file\n SAVE_COMPONENT_CSS: '/api/save-component-css', // Save CSS to .css file\n COMPONENT_CATEGORY: '/api/component-category', // Move component to category folder\n COMPONENT_FOLDER: '/api/component-folder', // Create component folder\n COMPONENT_FOLDERS: '/api/component-folders', // List all component folders\n COMPONENT_JS: '/api/component-js', // Get JavaScript from .js file\n CONFIG: '/api/config', // Get project config\n SAVE_CONFIG: '/api/save-config', // Save project config\n COMPONENTS_CONFIG: '/api/components-config', // Get components config\n SAVE_COMPONENTS_CONFIG: '/api/save-components-config', // Save components config\n SELECTION: '/api/selection', // Editor selection state (for AI integration)\n // CMS API routes\n CMS_COLLECTIONS: '/api/cms/collections', // List all CMS collections\n CMS_BASE: '/api/cms', // Base path for CMS item operations\n // Colors API routes\n COLORS_CONFIG: '/api/colors-config', // Get full colors config\n SAVE_COLORS: '/api/save-colors', // Save colors config\n // Page deletion\n DELETE_PAGE: '/api/delete-page', // Delete a page\n // Page folder management\n PAGE_FOLDER: '/api/page-folder', // Create page folder\n PAGE_FOLDERS: '/api/page-folders', // List all page folders\n MOVE_PAGE: '/api/move-page', // Move page to folder\n // Component preview\n COMPONENT_PREVIEW: '/api/component-preview', // Render component preview HTML\n // Website import\n IMPORT_WEBSITE: '/api/import-website', // Import external website for reference\n IMPORTED_WEBSITES: '/api/imported-websites', // List imported website folders\n ANALYZE_WEBSITE: '/api/analyze-website', // Analyze imported website into section map\n CONVERT_TO_MENO: '/api/convert-to-meno', // Convert imported HTML to flat Meno page JSON\n EXTRACT_CONTENT: '/api/extract-content', // Extract content from imported website for template mapping\n GENERATE_WIREFRAME_PROMPT: '/api/generate-wireframe-prompt', // Generate wireframe conversion prompt from extraction\n GENERATE_DESIGN_TOKEN_PROMPT: '/api/generate-design-token-prompt', // Generate design token extraction prompt\n GENERATE_CONTENT_PROMPT: '/api/generate-content-prompt', // Generate content conversion prompt using existing components\n GENERATE_SIMPLIFIED_PROMPT: '/api/generate-simplified-prompt', // Generate simplified prompt for Claude Code with Chrome extension\n // Multi-page import routes\n FETCH_SITEMAP: '/api/fetch-sitemap', // Fetch & parse sitemap.xml\n IMPORT_PAGE: '/api/import-page', // Import a single subpage\n ANALYZE_PAGE: '/api/analyze-page', // Analyze a subpage\n EXTRACT_PAGE_CONTENT: '/api/extract-page-content', // Extract content from a subpage\n GENERATE_HOMEPAGE_PROMPT: '/api/generate-homepage-prompt', // Homepage prompt with site structure\n GENERATE_PAGE_PROMPT: '/api/generate-page-prompt', // Per-page/template prompt\n LOAD_WEBSITE_IMPORT: '/api/load-website-import', // Load saved website import data from disk\n // Variables API routes\n VARIABLES_STATUS: '/api/variables-status', // Get variables config with status\n VARIABLES_CSS: '/api/variables-css', // Get generated CSS custom properties\n SAVE_VARIABLES: '/api/save-variables', // Save variables config\n // Enums API routes\n ENUMS: '/api/enums', // Get enums config\n SAVE_ENUMS: '/api/save-enums', // Save enums config\n // Component usage\n COMPONENT_USAGE: '/api/component-usage', // Get component usage across project\n} as const;\n\nexport const HMR_ROUTE = '/hmr';\n\nexport const FILE_PATTERNS = {\n PAGES: './pages',\n COMPONENTS: './components',\n} as const;\n\nexport const DEFAULT_TIMEOUT = 5000;\n\nexport const WEBSOCKET_STATES = {\n CONNECTING: 0,\n OPEN: 1,\n CLOSING: 2,\n CLOSED: 3,\n} as const;\n\n// Timeout constants\nexport const NOT_FOUND_TIMEOUT_MS = 300;\nexport const TAB_SWITCH_DELAY_MS = 100;\nexport const IFRAME_HIGHLIGHT_DELAY_MS = 100;\nexport const TREE_SCROLL_DELAY_MS = 200;\nexport const HOVER_HIGHLIGHT_DELAY_MS = 50; // Delay before highlighting tree item after expansion\n\n// Server configuration\nexport const MAX_PORT_ATTEMPTS = 10;\n\n// Message types for iframe-parent communication\nexport const IFRAME_MESSAGE_TYPES = {\n DELETE_ELEMENT: 'DELETE_ELEMENT',\n TOGGLE_SELECTING_MODE: 'TOGGLE_SELECTING_MODE',\n SET_TAB: 'SET_TAB',\n COPY_ELEMENT: 'COPY_ELEMENT',\n PASTE_ELEMENT: 'PASTE_ELEMENT',\n ARROW_UP: 'ARROW_UP',\n ARROW_DOWN: 'ARROW_DOWN',\n ARROW_LEFT: 'ARROW_LEFT',\n ARROW_RIGHT: 'ARROW_RIGHT',\n OPEN_COMMAND_PALETTE: 'OPEN_COMMAND_PALETTE',\n EDIT_COMPONENT: 'EDIT_COMPONENT',\n NAVIGATE_BACK: 'NAVIGATE_BACK',\n TOGGLE_ADDING_STYLE: 'TOGGLE_ADDING_STYLE',\n MOVE_ELEMENT_UP: 'MOVE_ELEMENT_UP',\n MOVE_ELEMENT_DOWN: 'MOVE_ELEMENT_DOWN',\n NEST_INTO_PREVIOUS_SIBLING: 'NEST_INTO_PREVIOUS_SIBLING',\n NEST_INTO_NEXT_SIBLING: 'NEST_INTO_NEXT_SIBLING',\n SELECTION_CHANGED: 'SELECTION_CHANGED',\n CMS_CONTEXT_UPDATE: 'CMS_CONTEXT_UPDATE',\n CMS_CONTEXT_REQUEST: 'CMS_CONTEXT_REQUEST',\n INTERACTIVE_CSS_UPDATE: 'INTERACTIVE_CSS_UPDATE',\n INTERACTIVE_STYLES_UPDATE: 'INTERACTIVE_STYLES_UPDATE', // Registry data from iframe to editor\n UNDO_REQUEST: 'UNDO_REQUEST',\n REDO_REQUEST: 'REDO_REQUEST',\n TOGGLE_INTERACTIVITY_EDITOR: 'TOGGLE_INTERACTIVITY_EDITOR',\n SET_BREAKPOINT: 'SET_BREAKPOINT',\n PAGE_DATA_PREVIEW: 'PAGE_DATA_PREVIEW', // Editor \u2192 Iframe for component hover preview\n PAGE_DATA_PREVIEW_REVERT: 'PAGE_DATA_PREVIEW_REVERT', // Editor \u2192 Iframe to revert preview\n PAGE_DATA_COMMITTED: 'PAGE_DATA_COMMITTED', // Editor \u2192 Iframe for committed mutations\n COMPONENT_DEFINITION_COMMITTED: 'COMPONENT_DEFINITION_COMMITTED', // Editor \u2192 Iframe for component definition updates\n CSS_VARIABLE_UPDATE: 'CSS_VARIABLE_UPDATE', // Editor \u2192 Iframe for instant CSS variable preview\n} as const;\n\n// Component node type constants\nexport const NODE_TYPE = {\n NODE: 'node',\n COMPONENT: 'component',\n SLOT: 'slot',\n EMBED: 'embed',\n LINK: 'link',\n LOCALE_LIST: 'locale-list',\n LIST: 'list',\n} as const;\n\nexport type NodeType = typeof NODE_TYPE[keyof typeof NODE_TYPE];\n\n// Special path identifiers for component editing\nexport const SPECIAL_PATHS = {\n COMPONENT_INTERFACE: 'component_interface',\n COMPONENT_JAVASCRIPT: 'component_javascript',\n COMPONENT_CSS: 'component_css',\n COMPONENT_LIBRARIES: 'component_libraries',\n COMPONENT_ACCEPTS_STYLES: 'component_acceptsStyles',\n STRUCTURE_STYLE: 'structure_style',\n} as const;\n\n// Component type configuration\nexport interface ComponentTypeConfig {\n id: string;\n label: string;\n color: string;\n description?: string;\n}\n\nexport const DEFAULT_COMPONENT_TYPES: ComponentTypeConfig[] = [\n { id: 'ui', label: 'UI', color: '#3b82f6' },\n { id: 'layout', label: 'Layout', color: '#10b981' },\n { id: 'content', label: 'Content', color: '#f59e0b' },\n];\n\nexport const DEFAULT_ICON_COLOR = '#6b7280';\n\n/**\n * Marker for raw HTML content that should not be escaped\n * Used by rich-text fields to signal that content should render as HTML\n */\nexport const RAW_HTML_PREFIX = '<!--MENO_RAW_HTML-->';\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Shared constants used across the application\n */\n\n// Read PORT from environment variable, fallback to 3000\n// Safe for browser environments where process is not defined\nexport const SERVER_PORT = typeof process !== 'undefined' && process.env?.PORT\n ? parseInt(process.env.PORT, 10)\n : 3000;\n\n// Port for serving built static files\nexport const SERVE_PORT = 8080;\n\nexport const API_ROUTES = {\n PAGES: '/api/pages',\n COMPONENTS: '/api/components',\n PAGE_CONTENT: '/api/page-content', // Returns raw JSON text for a page\n PAGE_DATA: '/api/page-data', // Returns parsed JSON for a specific page\n COMPONENT_DATA: '/api/component-data', // Returns parsed JSON for a specific component\n SAVE_PAGE: '/api/save-page',\n SAVE_COMPONENT: '/api/save-component',\n SAVE_COMPONENT_JS: '/api/save-component-js', // Save JavaScript to .js file\n SAVE_COMPONENT_CSS: '/api/save-component-css', // Save CSS to .css file\n COMPONENT_CATEGORY: '/api/component-category', // Move component to category folder\n COMPONENT_FOLDER: '/api/component-folder', // Create component folder\n COMPONENT_FOLDERS: '/api/component-folders', // List all component folders\n COMPONENT_JS: '/api/component-js', // Get JavaScript from .js file\n CONFIG: '/api/config', // Get project config\n SAVE_CONFIG: '/api/save-config', // Save project config\n COMPONENTS_CONFIG: '/api/components-config', // Get components config\n SAVE_COMPONENTS_CONFIG: '/api/save-components-config', // Save components config\n SELECTION: '/api/selection', // Editor selection state (for AI integration)\n // CMS API routes\n CMS_COLLECTIONS: '/api/cms/collections', // List all CMS collections\n CMS_BASE: '/api/cms', // Base path for CMS item operations\n // Colors API routes\n COLORS_CONFIG: '/api/colors-config', // Get full colors config\n SAVE_COLORS: '/api/save-colors', // Save colors config\n // Page deletion\n DELETE_PAGE: '/api/delete-page', // Delete a page\n // Page folder management\n PAGE_FOLDER: '/api/page-folder', // Create page folder\n PAGE_FOLDERS: '/api/page-folders', // List all page folders\n MOVE_PAGE: '/api/move-page', // Move page to folder\n // Component preview\n COMPONENT_PREVIEW: '/api/component-preview', // Render component preview HTML\n // Website import\n IMPORT_WEBSITE: '/api/import-website', // Import external website for reference\n IMPORTED_WEBSITES: '/api/imported-websites', // List imported website folders\n ANALYZE_WEBSITE: '/api/analyze-website', // Analyze imported website into section map\n CONVERT_TO_MENO: '/api/convert-to-meno', // Convert imported HTML to flat Meno page JSON\n EXTRACT_CONTENT: '/api/extract-content', // Extract content from imported website for template mapping\n GENERATE_WIREFRAME_PROMPT: '/api/generate-wireframe-prompt', // Generate wireframe conversion prompt from extraction\n GENERATE_DESIGN_TOKEN_PROMPT: '/api/generate-design-token-prompt', // Generate design token extraction prompt\n GENERATE_CONTENT_PROMPT: '/api/generate-content-prompt', // Generate content conversion prompt using existing components\n GENERATE_SIMPLIFIED_PROMPT: '/api/generate-simplified-prompt', // Generate simplified prompt for Claude Code with Chrome extension\n // Multi-page import routes\n FETCH_SITEMAP: '/api/fetch-sitemap', // Fetch & parse sitemap.xml\n IMPORT_PAGE: '/api/import-page', // Import a single subpage\n ANALYZE_PAGE: '/api/analyze-page', // Analyze a subpage\n EXTRACT_PAGE_CONTENT: '/api/extract-page-content', // Extract content from a subpage\n GENERATE_HOMEPAGE_PROMPT: '/api/generate-homepage-prompt', // Homepage prompt with site structure\n GENERATE_PAGE_PROMPT: '/api/generate-page-prompt', // Per-page/template prompt\n LOAD_WEBSITE_IMPORT: '/api/load-website-import', // Load saved website import data from disk\n // Variables API routes\n VARIABLES_STATUS: '/api/variables-status', // Get variables config with status\n VARIABLES_CSS: '/api/variables-css', // Get generated CSS custom properties\n SAVE_VARIABLES: '/api/save-variables', // Save variables config\n // Enums API routes\n ENUMS: '/api/enums', // Get enums config\n SAVE_ENUMS: '/api/save-enums', // Save enums config\n // Component usage\n COMPONENT_USAGE: '/api/component-usage', // Get component usage across project\n} as const;\n\nexport const HMR_ROUTE = '/hmr';\n\nexport const FILE_PATTERNS = {\n PAGES: './pages',\n COMPONENTS: './components',\n} as const;\n\nexport const DEFAULT_TIMEOUT = 5000;\n\nexport const WEBSOCKET_STATES = {\n CONNECTING: 0,\n OPEN: 1,\n CLOSING: 2,\n CLOSED: 3,\n} as const;\n\n// Timeout constants\nexport const NOT_FOUND_TIMEOUT_MS = 300;\nexport const TAB_SWITCH_DELAY_MS = 100;\nexport const IFRAME_HIGHLIGHT_DELAY_MS = 100;\nexport const TREE_SCROLL_DELAY_MS = 200;\nexport const HOVER_HIGHLIGHT_DELAY_MS = 50; // Delay before highlighting tree item after expansion\n\n// Server configuration\nexport const MAX_PORT_ATTEMPTS = 10;\n\n// Message types for iframe-parent communication\nexport const IFRAME_MESSAGE_TYPES = {\n DELETE_ELEMENT: 'DELETE_ELEMENT',\n TOGGLE_SELECTING_MODE: 'TOGGLE_SELECTING_MODE',\n SET_TAB: 'SET_TAB',\n COPY_ELEMENT: 'COPY_ELEMENT',\n PASTE_ELEMENT: 'PASTE_ELEMENT',\n ARROW_UP: 'ARROW_UP',\n ARROW_DOWN: 'ARROW_DOWN',\n ARROW_LEFT: 'ARROW_LEFT',\n ARROW_RIGHT: 'ARROW_RIGHT',\n OPEN_COMMAND_PALETTE: 'OPEN_COMMAND_PALETTE',\n EDIT_COMPONENT: 'EDIT_COMPONENT',\n NAVIGATE_BACK: 'NAVIGATE_BACK',\n TOGGLE_ADDING_STYLE: 'TOGGLE_ADDING_STYLE',\n MOVE_ELEMENT_UP: 'MOVE_ELEMENT_UP',\n MOVE_ELEMENT_DOWN: 'MOVE_ELEMENT_DOWN',\n NEST_INTO_PREVIOUS_SIBLING: 'NEST_INTO_PREVIOUS_SIBLING',\n NEST_INTO_NEXT_SIBLING: 'NEST_INTO_NEXT_SIBLING',\n SELECTION_CHANGED: 'SELECTION_CHANGED',\n CMS_CONTEXT_UPDATE: 'CMS_CONTEXT_UPDATE',\n CMS_CONTEXT_REQUEST: 'CMS_CONTEXT_REQUEST',\n INTERACTIVE_CSS_UPDATE: 'INTERACTIVE_CSS_UPDATE',\n INTERACTIVE_STYLES_UPDATE: 'INTERACTIVE_STYLES_UPDATE', // Registry data from iframe to editor\n UNDO_REQUEST: 'UNDO_REQUEST',\n REDO_REQUEST: 'REDO_REQUEST',\n TOGGLE_INTERACTIVITY_EDITOR: 'TOGGLE_INTERACTIVITY_EDITOR',\n SET_BREAKPOINT: 'SET_BREAKPOINT',\n PAGE_DATA_PREVIEW: 'PAGE_DATA_PREVIEW', // Editor \u2192 Iframe for component hover preview\n PAGE_DATA_PREVIEW_REVERT: 'PAGE_DATA_PREVIEW_REVERT', // Editor \u2192 Iframe to revert preview\n PAGE_DATA_COMMITTED: 'PAGE_DATA_COMMITTED', // Editor \u2192 Iframe for committed mutations\n COMPONENT_DEFINITION_COMMITTED: 'COMPONENT_DEFINITION_COMMITTED', // Editor \u2192 Iframe for component definition updates\n CSS_VARIABLE_UPDATE: 'CSS_VARIABLE_UPDATE', // Editor \u2192 Iframe for instant CSS variable preview\n INLINE_TEXT_EDIT_START: 'INLINE_TEXT_EDIT_START', // Editor \u2192 Iframe: start inline text editing\n INLINE_TEXT_EDIT_SAVE: 'INLINE_TEXT_EDIT_SAVE', // Iframe \u2192 Editor: save inline text edit\n INLINE_TEXT_EDIT_CANCEL: 'INLINE_TEXT_EDIT_CANCEL', // Iframe \u2192 Editor: cancel inline text edit\n} as const;\n\n// Component node type constants\nexport const NODE_TYPE = {\n NODE: 'node',\n COMPONENT: 'component',\n SLOT: 'slot',\n EMBED: 'embed',\n LINK: 'link',\n LOCALE_LIST: 'locale-list',\n LIST: 'list',\n} as const;\n\nexport type NodeType = typeof NODE_TYPE[keyof typeof NODE_TYPE];\n\n// Special path identifiers for component editing\nexport const SPECIAL_PATHS = {\n COMPONENT_INTERFACE: 'component_interface',\n COMPONENT_JAVASCRIPT: 'component_javascript',\n COMPONENT_CSS: 'component_css',\n COMPONENT_LIBRARIES: 'component_libraries',\n COMPONENT_ACCEPTS_STYLES: 'component_acceptsStyles',\n STRUCTURE_STYLE: 'structure_style',\n} as const;\n\n// Component type configuration\nexport interface ComponentTypeConfig {\n id: string;\n label: string;\n color: string;\n description?: string;\n}\n\nexport const DEFAULT_COMPONENT_TYPES: ComponentTypeConfig[] = [\n { id: 'ui', label: 'UI', color: '#3b82f6' },\n { id: 'layout', label: 'Layout', color: '#10b981' },\n { id: 'content', label: 'Content', color: '#f59e0b' },\n];\n\nexport const DEFAULT_ICON_COLOR = '#6b7280';\n\n/**\n * Marker for raw HTML content that should not be escaped\n * Used by rich-text fields to signal that content should render as HTML\n */\nexport const RAW_HTML_PREFIX = '<!--MENO_RAW_HTML-->';\n\n"],
5
+ "mappings": ";;;;;AAAA,IAMa,aAKA,YAEA,YA8DA,WAEA,eAKA,iBAEA,kBAQA,sBACA,qBACA,2BACA,sBACA,0BAGA,mBAGA,sBAsCA,WAaA,eAiBA,yBAMA,oBAMA;AAtLb;AAAA;AAMO,IAAM,cAAc,OAAO,YAAY,eAAe,QAAQ,KAAK,OACtE,SAAS,QAAQ,IAAI,MAAM,EAAE,IAC7B;AAGG,IAAM,aAAa;AAEnB,IAAM,aAAa;AAAA,MACxB,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,cAAc;AAAA;AAAA,MACd,WAAW;AAAA;AAAA,MACX,gBAAgB;AAAA;AAAA,MAChB,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,mBAAmB;AAAA;AAAA,MACnB,oBAAoB;AAAA;AAAA,MACpB,oBAAoB;AAAA;AAAA,MACpB,kBAAkB;AAAA;AAAA,MAClB,mBAAmB;AAAA;AAAA,MACnB,cAAc;AAAA;AAAA,MACd,QAAQ;AAAA;AAAA,MACR,aAAa;AAAA;AAAA,MACb,mBAAmB;AAAA;AAAA,MACnB,wBAAwB;AAAA;AAAA,MACxB,WAAW;AAAA;AAAA;AAAA,MAEX,iBAAiB;AAAA;AAAA,MACjB,UAAU;AAAA;AAAA;AAAA,MAEV,eAAe;AAAA;AAAA,MACf,aAAa;AAAA;AAAA;AAAA,MAEb,aAAa;AAAA;AAAA;AAAA,MAEb,aAAa;AAAA;AAAA,MACb,cAAc;AAAA;AAAA,MACd,WAAW;AAAA;AAAA;AAAA,MAEX,mBAAmB;AAAA;AAAA;AAAA,MAEnB,gBAAgB;AAAA;AAAA,MAChB,mBAAmB;AAAA;AAAA,MACnB,iBAAiB;AAAA;AAAA,MACjB,iBAAiB;AAAA;AAAA,MACjB,iBAAiB;AAAA;AAAA,MACjB,2BAA2B;AAAA;AAAA,MAC3B,8BAA8B;AAAA;AAAA,MAC9B,yBAAyB;AAAA;AAAA,MACzB,4BAA4B;AAAA;AAAA;AAAA,MAE5B,eAAe;AAAA;AAAA,MACf,aAAa;AAAA;AAAA,MACb,cAAc;AAAA;AAAA,MACd,sBAAsB;AAAA;AAAA,MACtB,0BAA0B;AAAA;AAAA,MAC1B,sBAAsB;AAAA;AAAA,MACtB,qBAAqB;AAAA;AAAA;AAAA,MAErB,kBAAkB;AAAA;AAAA,MAClB,eAAe;AAAA;AAAA,MACf,gBAAgB;AAAA;AAAA;AAAA,MAEhB,OAAO;AAAA;AAAA,MACP,YAAY;AAAA;AAAA;AAAA,MAEZ,iBAAiB;AAAA;AAAA,IACnB;AAEO,IAAM,YAAY;AAElB,IAAM,gBAAgB;AAAA,MAC3B,OAAO;AAAA,MACP,YAAY;AAAA,IACd;AAEO,IAAM,kBAAkB;AAExB,IAAM,mBAAmB;AAAA,MAC9B,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAGO,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAC5B,IAAM,4BAA4B;AAClC,IAAM,uBAAuB;AAC7B,IAAM,2BAA2B;AAGjC,IAAM,oBAAoB;AAG1B,IAAM,uBAAuB;AAAA,MAClC,gBAAgB;AAAA,MAChB,uBAAuB;AAAA,MACvB,SAAS;AAAA,MACT,cAAc;AAAA,MACd,eAAe;AAAA,MACf,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,sBAAsB;AAAA,MACtB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,iBAAiB;AAAA,MACjB,mBAAmB;AAAA,MACnB,4BAA4B;AAAA,MAC5B,wBAAwB;AAAA,MACxB,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,MACpB,qBAAqB;AAAA,MACrB,wBAAwB;AAAA,MACxB,2BAA2B;AAAA;AAAA,MAC3B,cAAc;AAAA,MACd,cAAc;AAAA,MACd,6BAA6B;AAAA,MAC7B,gBAAgB;AAAA,MAChB,mBAAmB;AAAA;AAAA,MACnB,0BAA0B;AAAA;AAAA,MAC1B,qBAAqB;AAAA;AAAA,MACrB,gCAAgC;AAAA;AAAA,MAChC,qBAAqB;AAAA;AAAA,MACrB,wBAAwB;AAAA;AAAA,MACxB,uBAAuB;AAAA;AAAA,MACvB,yBAAyB;AAAA;AAAA,IAC3B;AAGO,IAAM,YAAY;AAAA,MACvB,MAAM;AAAA,MACN,WAAW;AAAA,MACX,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,MAAM;AAAA,IACR;AAKO,IAAM,gBAAgB;AAAA,MAC3B,qBAAqB;AAAA,MACrB,sBAAsB;AAAA,MACtB,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,0BAA0B;AAAA,MAC1B,iBAAiB;AAAA,IACnB;AAUO,IAAM,0BAAiD;AAAA,MAC5D,EAAE,IAAI,MAAM,OAAO,MAAM,OAAO,UAAU;AAAA,MAC1C,EAAE,IAAI,UAAU,OAAO,UAAU,OAAO,UAAU;AAAA,MAClD,EAAE,IAAI,WAAW,OAAO,WAAW,OAAO,UAAU;AAAA,IACtD;AAEO,IAAM,qBAAqB;AAM3B,IAAM,kBAAkB;AAAA;AAAA;",
6
6
  "names": []
7
7
  }