meno-astro 0.1.3 → 0.1.4

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.
@@ -348,7 +348,8 @@ function emitHref(href, ctx) {
348
348
  return `href={i18n(${serializeLiteral(href, { indent: INDENT, width: ctx.width })})}`;
349
349
  }
350
350
  needRuntime(ctx, "href");
351
- return `href={href(${serializeLiteral(href, { indent: INDENT, width: ctx.width })})}`;
351
+ const hrefLit = serializeLiteral(href, { indent: INDENT, width: ctx.width });
352
+ return ctx.propsVar ? `href={href(${hrefLit}, ${ctx.propsVar})}` : `href={href(${hrefLit})}`;
352
353
  }
353
354
  function renderEmbed(node, ctx) {
354
355
  needRuntimeComponent(ctx, "Embed");
@@ -363,7 +364,10 @@ function renderEmbed(node, ctx) {
363
364
  }
364
365
  } else {
365
366
  needRuntime(ctx, "embedHtml");
366
- attrs.push(`html={embedHtml(${serializeLiteral(node.html, { indent: INDENT, width: ctx.width })})}`);
367
+ const htmlLit = serializeLiteral(node.html, { indent: INDENT, width: ctx.width });
368
+ attrs.push(
369
+ ctx.propsVar ? `html={embedHtml(${htmlLit}, ${ctx.propsVar})}` : `html={embedHtml(${htmlLit})}`
370
+ );
367
371
  }
368
372
  const cls = emitClassAttr(node, ctx);
369
373
  if (cls) attrs.push(cls);
@@ -929,8 +933,8 @@ function interpretExprValue(expr, ctx) {
929
933
  const e = expr.trim();
930
934
  if (ctx.embedConsts.has(e)) return ctx.embedConsts.get(e);
931
935
  if (e.startsWith("i18n(")) return parseLiteral(callArgsOf(e));
932
- if (e.startsWith("href(")) return parseLiteral(callArgsOf(e));
933
- if (e.startsWith("embedHtml(")) return parseLiteral(callArgsOf(e));
936
+ if (e.startsWith("href(")) return parseLiteral(splitTopLevel(callArgsOf(e), ",")[0]);
937
+ if (e.startsWith("embedHtml(")) return parseLiteral(splitTopLevel(callArgsOf(e), ",")[0]);
934
938
  if (e[0] === "`") return reverseTemplate(e.slice(1, -1));
935
939
  if (e[0] === "{" || e[0] === "[") return parseLiteral(e);
936
940
  if (e[0] === '"') return parseLiteral(e);
@@ -1526,4 +1530,4 @@ export {
1526
1530
  emit,
1527
1531
  parse
1528
1532
  };
1529
- //# sourceMappingURL=chunk-YU23XI6A.js.map
1533
+ //# sourceMappingURL=chunk-ACHLFXXY.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../lib/dialect/emit/emitContext.ts", "../../lib/dialect/emit/serialize.ts", "../../lib/dialect/emit/emitNode.ts", "../../lib/dialect/emit/frontmatter.ts", "../../lib/dialect/cmsRoute.ts", "../../lib/dialect/emit/emitPage.ts", "../../lib/dialect/emit/emitComponent.ts", "../../lib/dialect/parse/parseLiteral.ts", "../../lib/dialect/parse/scan.ts", "../../lib/dialect/parse/callArgs.ts", "../../lib/dialect/parse/parseValue.ts", "../../lib/dialect/parse/parseContext.ts", "../../lib/dialect/parse/parseFrontmatter.ts", "../../lib/dialect/parse/parseBody.ts", "../../lib/dialect/parse/parseFile.ts", "../../lib/dialect/normalize.ts", "../../lib/dialect/lineMap.ts", "../../lib/dialect/index.ts"],
4
+ "sourcesContent": ["/**\n * EmitContext \u2014 accumulates everything a single `.astro` file needs that is\n * discovered while walking the node tree: component imports, `meno-astro` runtime\n * symbols/components, and frontmatter const declarations (CMS collection queries).\n *\n * The node walker writes the template body; the page/component assembler reads the\n * context afterwards to emit a deterministic frontmatter (alphabetized imports, then\n * the collected consts).\n */\n\nexport interface EmitContext {\n /** Names of components referenced by `type:\"component\"` instances (need a local import). */\n components: Set<string>;\n /** Symbols imported from `meno-astro` (e.g. style, i18n, list, getCollectionList, when, embedHtml). */\n runtime: Set<string>;\n /** Astro components imported from `meno-astro/components` (e.g. LocaleList, MenoImage). */\n runtimeComponents: Set<string>;\n /** Frontmatter `const \u2026 = \u2026` lines (collection-list queries), in insertion order. */\n frontmatterConsts: string[];\n /**\n * Stack of active list loop-item variable names (e.g. `post` inside a\n * `blogList.map((post, \u2026) => \u2026)`). A component instance emitted inside a list\n * passes these so a CMS-card component bound to `{{post.title}}` receives the item\n * (which it declares from `Astro.props` \u2014 see emitComponent's item bindings).\n */\n loopVars: string[];\n /**\n * True when the file emits a CMS collection list, so the page/component must\n * `import { getCollection } from 'astro:content'` and pass it to getCollectionList\n * (meno-astro never imports astro:content itself \u2014 see runtime/collectionList).\n */\n needsContentApi: boolean;\n /**\n * Name of the resolved-props object to pass into `style()` (and href/embed) so\n * prop-`_mapping`s resolve \u2014 `'__props'` inside a component, undefined on a page\n * (pages have no props). Set by emitComponent before the body is walked.\n */\n propsVar?: string;\n /** Monotonic counter for generating unique frontmatter binding names. */\n listCounter: number;\n /** Monotonic counter for hoisted verbatim consts (multi-line embed HTML). */\n hoistCounter: number;\n /** Monotonic counter for dynamic-tag consts (`const Tag_0 = \\`h${size}\\``). */\n tagCounter: number;\n /** Max literal line width before objects/arrays expand. */\n width: number;\n}\n\nexport function createEmitContext(width = 80): EmitContext {\n return {\n components: new Set(),\n runtime: new Set(),\n runtimeComponents: new Set(),\n frontmatterConsts: [],\n loopVars: [],\n needsContentApi: false,\n listCounter: 0,\n hoistCounter: 0,\n tagCounter: 0,\n width,\n };\n}\n\n/**\n * Per-file emit options threaded from the converter (and editor save path) so\n * component imports resolve across category subfolders. Absent for flat projects\n * (and tests), where emit falls back to flat `./Name.astro` / `../components/Name.astro`.\n */\nexport interface EmitOptions {\n /** Component name \u2192 its path under `components/` without extension (e.g. `section/Error404`). */\n componentPaths?: Record<string, string>;\n /** For component emit: this component's own path under `components/` (e.g. `ui/Card`). */\n selfPath?: string;\n}\n\n/**\n * POSIX relative import path from a directory to a target (both '/'-separated,\n * extensionless). `relativeComponentImport('ui', 'section/Hero')` \u2192 `'../section/Hero'`.\n */\nexport function relativeComponentImport(fromDir: string, target: string): string {\n const f = fromDir ? fromDir.split('/').filter(Boolean) : [];\n const t = target.split('/').filter(Boolean);\n let i = 0;\n while (i < f.length && i < t.length && f[i] === t[i]) i++;\n const parts = [...Array(f.length - i).fill('..'), ...t.slice(i)];\n const rel = parts.join('/');\n return rel.startsWith('.') ? rel : './' + rel;\n}\n\n/** Register a `meno-astro` runtime symbol and return its name (for fluent use). */\nexport function needRuntime(ctx: EmitContext, name: string): string {\n ctx.runtime.add(name);\n return name;\n}\n\n/** Register a `meno-astro/components` Astro component and return its tag name. */\nexport function needRuntimeComponent(ctx: EmitContext, name: string): string {\n ctx.runtimeComponents.add(name);\n return name;\n}\n", "/**\n * Deterministic JS-literal serializer \u2014 the round-trip linchpin.\n *\n * Every non-structural payload in the meno-astro dialect (style objects, component\n * props, `export const meta`, the `resolveProps(Astro, {\u2026})` argument, i18n values,\n * list config, mappings) is emitted as the literal argument of a known call or a named\n * const. This serializer\n * produces those literals so that:\n * - the output is valid JS (embeds cleanly in `.astro` frontmatter + JSX expressions),\n * - it is parseable back verbatim by a tiny total evaluator (Phase 2 parser),\n * - it is deterministic + diff-stable (stable key order, canonical formatting).\n *\n * Formatting: small values render inline; values whose inline form would exceed\n * `width` columns expand to one entry per line (clean git diffs). Strings use JSON\n * double-quote escaping. Object keys are emitted unquoted when they are valid JS\n * identifiers, quoted otherwise.\n */\n\nconst DEFAULT_WIDTH = 80;\nconst INDENT_STEP = 2;\n\nconst IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/** Whether a key can be emitted unquoted as a JS object key. */\nexport function isIdentifier(key: string): boolean {\n return IDENT_RE.test(key);\n}\n\nfunction renderKey(key: string): string {\n return isIdentifier(key) ? key : JSON.stringify(key);\n}\n\nfunction renderString(value: string): string {\n // JSON string escaping is valid JS string escaping (and single-line).\n return JSON.stringify(value);\n}\n\nfunction renderNumber(value: number): string {\n return Number.isFinite(value) ? String(value) : 'null';\n}\n\n/** Object entries with `undefined` values dropped (JSON semantics; the model should not carry undefined). */\nfunction definedEntries(obj: Record<string, unknown>): Array<[string, unknown]> {\n return Object.entries(obj).filter(([, v]) => v !== undefined);\n}\n\n/** Always-inline rendering (never emits newlines). Used for fit-testing and for short values. */\nfunction renderInline(value: unknown): string {\n if (value === null) return 'null';\n if (value === undefined) return 'undefined';\n switch (typeof value) {\n case 'string':\n return renderString(value);\n case 'number':\n return renderNumber(value);\n case 'boolean':\n return String(value);\n case 'object': {\n if (Array.isArray(value)) {\n if (value.length === 0) return '[]';\n return '[' + value.map(renderInline).join(', ') + ']';\n }\n const entries = definedEntries(value as Record<string, unknown>);\n if (entries.length === 0) return '{}';\n return (\n '{ ' +\n entries.map(([k, v]) => `${renderKey(k)}: ${renderInline(v)}`).join(', ') +\n ' }'\n );\n }\n default:\n // functions/symbols/bigint are not part of the model\n return 'null';\n }\n}\n\nexport interface SerializeOptions {\n /** Column at which continuation lines of this value are indented. Default 0. */\n indent?: number;\n /** Max line width before an object/array expands to multi-line. Default 80. */\n width?: number;\n /**\n * Column where this value begins on the current line (drives the top-level\n * inline-fit test). Defaults to `indent`. Set this when the value is emitted to\n * the right of a prefix (e.g. `resolveProps(Astro, <here>)`) but its\n * continuation lines should still indent relative to `indent`.\n */\n startCol?: number;\n}\n\n/**\n * Serialize a model value to a deterministic JS literal string.\n * The returned string has no leading indentation; continuation lines are indented\n * relative to `opts.indent` (the column where the value starts).\n */\nexport function serializeLiteral(value: unknown, opts: SerializeOptions = {}): string {\n const width = opts.width ?? DEFAULT_WIDTH;\n const baseIndent = opts.indent ?? 0;\n const startCol = opts.startCol ?? baseIndent;\n\n /**\n * @param v value to render\n * @param contIndent indentation (spaces) for continuation lines of this value\n * @param startCol column where this value begins on the current line (for the inline-fit test)\n */\n const render = (v: unknown, contIndent: number, startCol: number): string => {\n // Primitives are always inline.\n if (v === null || typeof v !== 'object') return renderInline(v);\n\n const inline = renderInline(v);\n if (startCol + inline.length <= width) return inline;\n\n const pad = ' '.repeat(contIndent + INDENT_STEP);\n const closePad = ' '.repeat(contIndent);\n\n if (Array.isArray(v)) {\n if (v.length === 0) return '[]';\n const items = v.map(\n (item) => pad + render(item, contIndent + INDENT_STEP, contIndent + INDENT_STEP),\n );\n return '[\\n' + items.join(',\\n') + '\\n' + closePad + ']';\n }\n\n const entries = definedEntries(v as Record<string, unknown>);\n if (entries.length === 0) return '{}';\n const lines = entries.map(([k, val]) => {\n const prefix = pad + renderKey(k) + ': ';\n return prefix + render(val, contIndent + INDENT_STEP, prefix.length);\n });\n return '{\\n' + lines.join(',\\n') + '\\n' + closePad + '}';\n };\n\n return render(value, baseIndent, startCol);\n}\n", "/**\n * Node walker \u2014 turns a Meno node tree into meno-astro dialect markup.\n *\n * Model: every node renders into a self-contained block at *column 0*; a placer\n * (`placeChild`) then shifts that block to its target indent and, when the node has\n * an `if`, wraps it in `{cond && ( \u2026 )}`. This separates structure from placement so\n * indentation and conditionals stay simple and deterministic.\n *\n * Two render shapes:\n * - `element` \u2192 JSX markup (`<div \u2026>\u2026</div>`), placed as-is.\n * - `expr` \u2192 a JS expression (list `.map(\u2026)`, or an `if`-wrapped node), placed\n * inside `{ \u2026 }`.\n */\n\nimport { singularize } from 'meno-core/shared';\nimport { serializeLiteral } from './serialize';\nimport { type EmitContext, needRuntime, needRuntimeComponent } from './emitContext';\n\ntype Node = Record<string, any>;\n\nexport type Rendered =\n | { kind: 'element'; markup: string }\n | { kind: 'expr'; expr: string };\n\nconst INDENT = 2;\n\nfunction pad(n: number): string {\n return ' '.repeat(n);\n}\n\n/** Shift every line of a column-0 block to start at `indent`. */\nfunction shift(block: string, indent: number): string {\n const p = pad(indent);\n return block\n .split('\\n')\n .map((line) => (line.length ? p + line : line))\n .join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Templates: Meno uses `{{ expr }}`. Convert to a JS expression for `{ \u2026 }`.\n// ---------------------------------------------------------------------------\n\nconst TEMPLATE_RE = /\\{\\{([\\s\\S]*?)\\}\\}/g;\n\nexport function hasTemplate(s: string): boolean {\n return /\\{\\{[\\s\\S]*?\\}\\}/.test(s);\n}\n\n/** Escape literal text for inclusion inside a backtick template literal. */\nfunction escapeBacktick(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`').replace(/\\$\\{/g, '\\\\${');\n}\n\n/**\n * Convert a Meno template string to the JS expression that goes inside `{ \u2026 }`.\n * - `\"{{ expr }}\"` (whole string) \u2192 `expr`\n * - `\"Hi {{name}}!\"` \u2192 `` `Hi ${name}!` ``\n */\nexport function templateToExpr(s: string): string {\n const matches = [...s.matchAll(TEMPLATE_RE)];\n // Exactly one template spanning the entire string \u2192 bare expression.\n if (matches.length === 1 && matches[0].index === 0 && matches[0][0].length === s.length) {\n return matches[0][1].trim();\n }\n // Otherwise build a backtick template literal.\n let out = '';\n let last = 0;\n for (const m of matches) {\n out += escapeBacktick(s.slice(last, m.index!));\n out += '${' + m[1].trim() + '}';\n last = m.index! + m[0].length;\n }\n out += escapeBacktick(s.slice(last));\n return '`' + out + '`';\n}\n\n/** Globals/keywords that look like identifiers but are never item bindings. */\nconst NON_BINDING_ROOTS = new Set([\n 'Astro', 'Math', 'JSON', 'Object', 'Array', 'Date', 'Number', 'String', 'Boolean',\n 'true', 'false', 'null', 'undefined', 'this',\n]);\n\n/**\n * Scan a component's structure for the root identifiers its `{{root.\u2026}}` / `{{root}}`\n * templates reference that are NOT declared props and NOT bound by an inner list's\n * loop var \u2014 i.e. CMS-item bindings like `post` that the component receives from its\n * parent list. The component declares these from `Astro.props` so its `post.title`\n * references resolve (the parent list passes them; see renderComponentInstance).\n */\nexport function collectItemBindings(root: unknown, declaredProps: Iterable<string>): string[] {\n const free = new Set<string>();\n const rootOf = (expr: string): string | undefined =>\n expr.trim().match(/^[A-Za-z_$][\\w$]*/)?.[0];\n\n const walk = (node: unknown, bound: Set<string>): void => {\n if (node == null) return;\n if (typeof node === 'string') {\n for (const m of node.matchAll(TEMPLATE_RE)) {\n const r = rootOf(m[1]);\n if (r && !bound.has(r) && !NON_BINDING_ROOTS.has(r)) free.add(r);\n }\n return;\n }\n if (Array.isArray(node)) {\n for (const n of node) walk(n, bound);\n return;\n }\n if (typeof node !== 'object') return;\n const obj = node as Record<string, unknown>;\n // A list node binds its own loop vars for its children only; its own fields\n // (source/filter) still reference the surrounding scope.\n let childBound = bound;\n if (obj.type === 'list') {\n const itemVar = (obj.itemAs as string) ?? (obj.sourceType === 'collection' ? singularize(obj.source as string) : 'item');\n childBound = new Set(bound).add(itemVar).add(`${itemVar}Index`);\n }\n for (const [k, v] of Object.entries(obj)) {\n walk(v, k === 'children' || k === 'default' ? childBound : bound);\n }\n };\n\n walk(root, new Set(declaredProps));\n return [...free];\n}\n\nfunction isI18nValue(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && (v as any)._i18n === true;\n}\n\n// ---------------------------------------------------------------------------\n// Attribute / prop emission\n// ---------------------------------------------------------------------------\n\n/** Render one `name=\u2026` attribute (used for HTML attributes and component props). */\nfunction emitAttr(name: string, value: unknown, ctx: EmitContext): string {\n if (isI18nValue(value)) {\n needRuntime(ctx, 'i18n');\n return `${name}={i18n(${serializeLiteral(value, { indent: INDENT, width: ctx.width })})}`;\n }\n if (typeof value === 'string') {\n if (hasTemplate(value)) return `${name}={${templateToExpr(value)}}`;\n if (!value.includes('\"') && !value.includes('\\n')) return `${name}=\"${value}\"`;\n return `${name}={${JSON.stringify(value)}}`;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return `${name}={${value}}`;\n }\n if (value === null || value === undefined) return `${name}={null}`;\n // objects (link values, arbitrary structured props) \u2192 literal\n return `${name}={${serializeLiteral(value, { indent: INDENT, width: ctx.width })}}`;\n}\n\n/**\n * Build the `class={style(styleLit[, metaLit])}` attribute for a node, or null when\n * the node carries no style/interactive/label metadata.\n */\nfunction emitClassAttr(node: Node, ctx: EmitContext, extraMeta?: Record<string, unknown>): string | null {\n const meta: Record<string, unknown> = { ...extraMeta };\n if (node.interactiveStyles !== undefined) meta.interactive = node.interactiveStyles;\n if (node.label !== undefined) meta.label = node.label;\n if (node.generateElementClass !== undefined) meta.genClass = node.generateElementClass;\n\n const hasStyle = hasStyleContent(node.style);\n const hasMeta = Object.keys(meta).length > 0;\n if (!hasStyle && !hasMeta) return null;\n\n needRuntime(ctx, 'style');\n const styleLit = serializeLiteral(node.style ?? {}, { indent: INDENT, width: ctx.width });\n // Pass the resolved props object so prop-`_mapping`s resolve (in a component it's\n // `__props`; a page has none). The parser skips the props arg and reads meta from the\n // object-literal arg, so both `style(obj, props, meta)` and `style(obj)` round-trip.\n const propsArg = ctx.propsVar;\n if (!hasMeta) return propsArg ? `class={style(${styleLit}, ${propsArg})}` : `class={style(${styleLit})}`;\n const metaLit = serializeLiteral(meta, { indent: INDENT, width: ctx.width });\n return `class={style(${styleLit}, ${propsArg ?? 'undefined'}, ${metaLit})}`;\n}\n\n/** Whether a style value has any non-empty content worth emitting. */\nfunction hasStyleContent(style: unknown): boolean {\n if (!style || typeof style !== 'object') return false;\n for (const v of Object.values(style as Record<string, unknown>)) {\n if (v === undefined || v === null) continue;\n if (typeof v === 'object') {\n if (Object.keys(v as object).length > 0) return true;\n } else {\n return true;\n }\n }\n return false;\n}\n\n/** HTML `attributes` map \u2192 attribute strings. */\nfunction emitAttributes(node: Node, ctx: EmitContext): string[] {\n if (!node.attributes || typeof node.attributes !== 'object') return [];\n return Object.entries(node.attributes).map(([k, v]) => emitAttr(k, v, ctx));\n}\n\n// ---------------------------------------------------------------------------\n// Children\n// ---------------------------------------------------------------------------\n\nconst VOID_ELEMENTS = new Set([\n 'img', 'br', 'hr', 'input', 'meta', 'link', 'area', 'base', 'col',\n 'embed', 'param', 'source', 'track', 'wbr',\n]);\n\n/** locale-list keys emitted explicitly (so the passthrough loop skips them). */\nconst LOCALE_KNOWN_KEYS = new Set([\n 'type', 'if', 'showCurrent', 'showSeparator', 'showFlag', 'displayType',\n 'style', 'itemStyle', 'activeItemStyle', 'separatorStyle', 'flagStyle',\n 'interactiveStyles', 'label', 'generateElementClass',\n]);\n\n/**\n * Render a string child (text node) at column 0. When the text has siblings\n * (`forceExpr`), it is emitted as a `{\"\u2026\"}` expression so adjacent text nodes stay\n * distinct on parse; a sole text child may stay pretty raw (`<h1>Hello</h1>`). Both\n * forms parse back to the same text node.\n */\nfunction emitTextChild(text: string, forceExpr = false): string {\n if (hasTemplate(text)) return `{${templateToExpr(text)}}`;\n const safeRaw = !forceExpr && text.length > 0 && text === text.trim() && !/[{}<>]/.test(text);\n return safeRaw ? text : `{${JSON.stringify(text)}}`;\n}\n\n/** Render a children value (string | array) to an array of column-0 child blocks. */\nfunction emitChildrenList(children: unknown, ctx: EmitContext): string[] {\n if (children === undefined || children === null) return [];\n if (typeof children === 'string') {\n return children.length ? [emitTextChild(children)] : [];\n }\n if (!Array.isArray(children)) return [];\n const multi = children.length > 1;\n return children.map((child) =>\n typeof child === 'string'\n ? emitTextChild(child, multi)\n : placeChild(renderNode(child as Node, ctx), 0),\n );\n}\n\n/**\n * Compose an element: `<tag attrs>children</tag>` (or self-closing). Returns markup\n * at column 0. Inlines a single one-line child for compactness.\n */\nfunction composeElement(tag: string, attrs: string[], childBlocks: string[], forceVoid = false): string {\n const attrStr = attrs.length ? ' ' + attrs.join(' ') : '';\n if (forceVoid || childBlocks.length === 0) {\n return `<${tag}${attrStr} />`;\n }\n if (childBlocks.length === 1 && !childBlocks[0].includes('\\n')) {\n return `<${tag}${attrStr}>${childBlocks[0]}</${tag}>`;\n }\n const inner = childBlocks.map((c) => shift(c, INDENT)).join('\\n');\n return `<${tag}${attrStr}>\\n${inner}\\n</${tag}>`;\n}\n\n// ---------------------------------------------------------------------------\n// Per-node renderers (build at column 0)\n// ---------------------------------------------------------------------------\n\nfunction renderHtml(node: Node, ctx: EmitContext): Rendered {\n let tag = node.tag as string;\n // Dynamic tag (e.g. \"h{{size}}\") \u2192 a frontmatter const referenced as <Tag_N>.\n if (typeof tag === 'string' && hasTemplate(tag)) {\n const varName = `Tag_${ctx.tagCounter++}`;\n ctx.frontmatterConsts.push(`const ${varName} = ${tagToTemplateLiteral(tag)};`);\n tag = varName;\n }\n const attrs = [emitClassAttr(node, ctx), ...emitAttributes(node, ctx)].filter(Boolean) as string[];\n const isVoid = VOID_ELEMENTS.has(String(node.tag).toLowerCase());\n const childBlocks = isVoid ? [] : emitChildrenList(node.children, ctx);\n return { kind: 'element', markup: composeElement(tag, attrs, childBlocks, isVoid) };\n}\n\n/** A tag string with `{{\u2026}}` \u2192 an Astro template-literal const value, e.g. `` `h${size}` ``. */\nfunction tagToTemplateLiteral(tag: string): string {\n const body = tag.replace(TEMPLATE_RE, (_m, e) => '${' + String(e).trim() + '}');\n return '`' + body + '`';\n}\n\nfunction renderComponentInstance(node: Node, ctx: EmitContext): Rendered {\n const tag = astroComponentName(node.component);\n ctx.components.add(node.component);\n const attrs: string[] = [];\n const explicitProps = node.props && typeof node.props === 'object' ? (node.props as Record<string, unknown>) : {};\n for (const [k, v] of Object.entries(explicitProps)) attrs.push(emitAttr(k, v, ctx));\n // A PROP-LESS component instance inside a list is an item-bound card (e.g. a\n // BlogListCard whose own body renders `{{post.title}}`): forward the active list\n // loop variables so it receives the item, which it declares from `Astro.props`\n // (see emitComponent). A component that already takes explicit props gets its data\n // that way and needs nothing extra.\n if (Object.keys(explicitProps).length === 0) {\n for (const v of ctx.loopVars) attrs.push(`${v}={${v}}`);\n }\n const cls = emitClassAttr(node, ctx, hasStyleContent(node.style) ? { instance: true } : undefined);\n if (cls) attrs.push(cls);\n const childBlocks = emitChildrenList(node.children, ctx);\n return { kind: 'element', markup: composeElement(tag, attrs, childBlocks) };\n}\n\nfunction renderSlot(node: Node, ctx: EmitContext): Rendered {\n const def = node.default;\n if (def === undefined) return { kind: 'element', markup: '<slot />' };\n const childBlocks = emitChildrenList(def, ctx);\n return { kind: 'element', markup: composeElement('slot', [], childBlocks) };\n}\n\nfunction renderLink(node: Node, ctx: EmitContext): Rendered {\n needRuntimeComponent(ctx, 'Link');\n const attrs: string[] = [emitHref(node.href, ctx)];\n const cls = emitClassAttr(node, ctx);\n if (cls) attrs.push(cls);\n attrs.push(...emitAttributes(node, ctx));\n const childBlocks = emitChildrenList(node.children, ctx);\n return { kind: 'element', markup: composeElement('Link', attrs.filter(Boolean), childBlocks) };\n}\n\nfunction emitHref(href: unknown, ctx: EmitContext): string {\n if (typeof href === 'string') {\n if (hasTemplate(href)) return `href={${templateToExpr(href)}}`;\n return `href=\"${href}\"`;\n }\n // LinkMapping / i18n \u2192 carry the literal through a runtime resolver.\n if (isI18nValue(href)) {\n needRuntime(ctx, 'i18n');\n return `href={i18n(${serializeLiteral(href, { indent: INDENT, width: ctx.width })})}`;\n }\n needRuntime(ctx, 'href');\n // Thread the host component's resolved props (like style()) so a prop-bound LinkMapping\n // resolves at render. Pages have no props scope \u2192 1-arg form (mapping degrades to \"#\").\n const hrefLit = serializeLiteral(href, { indent: INDENT, width: ctx.width });\n return ctx.propsVar ? `href={href(${hrefLit}, ${ctx.propsVar})}` : `href={href(${hrefLit})}`;\n}\n\nfunction renderEmbed(node: Node, ctx: EmitContext): Rendered {\n needRuntimeComponent(ctx, 'Embed');\n const attrs: string[] = [];\n if (typeof node.html === 'string') {\n if (node.html.includes('\\n')) {\n // Multi-line verbatim HTML must not be re-indented by the placer \u2014 hoist it to a\n // frontmatter const (column 0, never shifted) and reference it by name.\n const name = `__embed${ctx.hoistCounter++}`;\n ctx.frontmatterConsts.push(`const ${name} = \\`${escapeBacktick(node.html)}\\`;`);\n attrs.push(`html={${name}}`);\n } else {\n attrs.push(`html={\\`${escapeBacktick(node.html)}\\`}`);\n }\n } else {\n needRuntime(ctx, 'embedHtml');\n // Thread props (like style()/href()) so a prop-bound HtmlMapping resolves at render.\n const htmlLit = serializeLiteral(node.html, { indent: INDENT, width: ctx.width });\n attrs.push(\n ctx.propsVar ? `html={embedHtml(${htmlLit}, ${ctx.propsVar})}` : `html={embedHtml(${htmlLit})}`,\n );\n }\n const cls = emitClassAttr(node, ctx);\n if (cls) attrs.push(cls);\n attrs.push(...emitAttributes(node, ctx));\n return { kind: 'element', markup: composeElement('Embed', attrs, [], true) };\n}\n\nfunction renderLocaleList(node: Node, ctx: EmitContext): Rendered {\n needRuntimeComponent(ctx, 'LocaleList');\n const attrs: string[] = [];\n const boolProps = ['showCurrent', 'showSeparator', 'showFlag'] as const;\n for (const p of boolProps) if (node[p] !== undefined) attrs.push(emitAttr(p, node[p], ctx));\n if (node.displayType !== undefined) attrs.push(emitAttr('displayType', node.displayType, ctx));\n const styleProps = ['style', 'itemStyle', 'activeItemStyle', 'separatorStyle', 'flagStyle'] as const;\n for (const sp of styleProps) {\n if (hasStyleContent(node[sp])) {\n needRuntime(ctx, 'style');\n attrs.push(`${sp}={style(${serializeLiteral(node[sp], { indent: INDENT, width: ctx.width })})}`);\n }\n }\n if (node.interactiveStyles !== undefined || node.label !== undefined || node.generateElementClass !== undefined) {\n const meta: Record<string, unknown> = {};\n if (node.interactiveStyles !== undefined) meta.interactive = node.interactiveStyles;\n if (node.label !== undefined) meta.label = node.label;\n if (node.generateElementClass !== undefined) meta.genClass = node.generateElementClass;\n attrs.push(`meta={${serializeLiteral(meta, { indent: INDENT, width: ctx.width })}}`);\n }\n // Preserve any passthrough scalar props (e.g. a legacy `separator` text).\n for (const [k, v] of Object.entries(node)) {\n if (LOCALE_KNOWN_KEYS.has(k)) continue;\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n attrs.push(emitAttr(k, v, ctx));\n }\n }\n return { kind: 'element', markup: composeElement('LocaleList', attrs, [], true) };\n}\n\nfunction renderList(node: Node, ctx: EmitContext): Rendered {\n const sourceType = node.sourceType ?? 'prop';\n // Compute the loop-item var BEFORE emitting children, and make it visible on the\n // loopVars stack while they emit \u2014 so a component instance used as the item\n // template receives the item as a prop (e.g. `<BlogListCard post={post} />`).\n const itemVar = node.itemAs ?? (sourceType === 'collection' ? singularize(node.source) : 'item');\n const indexVar = `${itemVar}Index`;\n\n ctx.loopVars.push(itemVar);\n const childBlocks = emitChildrenList(node.children, ctx);\n ctx.loopVars.pop();\n const childRenderedAt2 = childBlocks.map((c) => shift(c, INDENT)).join('\\n');\n\n if (sourceType === 'collection') {\n needRuntime(ctx, 'getCollectionList');\n ctx.needsContentApi = true; // page/component must import + pass getCollection\n const query = listQueryLiteral(node, ctx, ['filter', 'sort', 'limit', 'offset', 'items', 'excludeCurrentItem', 'emitTemplate']);\n const binding = uniqueBinding(ctx, `${sanitizeIdent(node.source)}List`);\n ctx.frontmatterConsts.push(\n `const ${binding} = await getCollectionList(${JSON.stringify(node.source)}${query ? ', ' + query : ''}, Astro, getCollection);`,\n );\n const expr = `${binding}.map((${itemVar}, ${indexVar}) => (\\n${childRenderedAt2}\\n))`;\n return { kind: 'expr', expr };\n }\n\n // prop list\n needRuntime(ctx, 'list');\n const sourceExpr =\n typeof node.source === 'string' && hasTemplate(node.source)\n ? templateToExpr(node.source)\n : sanitizeIdent(String(node.source));\n const opts = listQueryLiteral(node, ctx, ['limit', 'offset']);\n const listCall = opts ? `list(${sourceExpr}, ${opts})` : `list(${sourceExpr})`;\n const expr = `${listCall}.map((${itemVar}, ${indexVar}) => (\\n${childRenderedAt2}\\n))`;\n return { kind: 'expr', expr };\n}\n\n/** Build a `{ \u2026 }` literal from selected list fields, or '' when none are set. */\nfunction listQueryLiteral(node: Node, ctx: EmitContext, keys: string[]): string {\n const obj: Record<string, unknown> = {};\n for (const k of keys) if (node[k] !== undefined) obj[k] = node[k];\n if (Object.keys(obj).length === 0) return '';\n return serializeLiteral(obj, { indent: INDENT, width: ctx.width });\n}\n\nfunction uniqueBinding(ctx: EmitContext, base: string): string {\n const existing = ctx.frontmatterConsts.some((l) => l.startsWith(`const ${base} `));\n if (!existing) return base;\n return `${base}_${ctx.listCounter++}`;\n}\n\nfunction sanitizeIdent(s: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(s) ? s : s.replace(/[^A-Za-z0-9_$]/g, '_');\n}\n\n/** Astro component tag: components must be Capitalized identifiers. */\nexport function astroComponentName(name: string): string {\n const cleaned = name.replace(/[^A-Za-z0-9_$]/g, '');\n return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);\n}\n\n// ---------------------------------------------------------------------------\n// Dispatch + placement\n// ---------------------------------------------------------------------------\n\nexport function renderNode(node: Node, ctx: EmitContext): Rendered {\n let rendered: Rendered;\n switch (node.type) {\n case 'node': rendered = renderHtml(node, ctx); break;\n case 'component': rendered = renderComponentInstance(node, ctx); break;\n case 'slot': rendered = renderSlot(node, ctx); break;\n case 'link': rendered = renderLink(node, ctx); break;\n case 'embed': rendered = renderEmbed(node, ctx); break;\n case 'locale-list': rendered = renderLocaleList(node, ctx); break;\n case 'list': rendered = renderList(node, ctx); break;\n default:\n // Unknown node type \u2192 preserve as a comment so nothing is silently dropped.\n rendered = { kind: 'element', markup: `{/* meno:unknown ${JSON.stringify(node.type)} */}` };\n }\n return applyIf(node, rendered);\n}\n\n/** Wrap a rendered node in `cond && ( \u2026 )` when it has an `if` that is not literally `true`. */\nfunction applyIf(node: Node, rendered: Rendered): Rendered {\n if (node.if === undefined || node.if === true) return rendered;\n const cond = ifConditionExpr(node.if);\n if (rendered.kind === 'element') {\n return { kind: 'expr', expr: `${cond} && (\\n${shift(rendered.markup, INDENT)}\\n)` };\n }\n return { kind: 'expr', expr: `${cond} && (${rendered.expr})` };\n}\n\nfunction ifConditionExpr(cond: unknown): string {\n if (cond === false) return 'false';\n if (cond === true) return 'true';\n if (typeof cond === 'string') return hasTemplate(cond) ? templateToExpr(cond) : cond;\n // BooleanMapping `{ _mapping, prop, values }` \u2192 carry literal through `when()`.\n return `when(${serializeLiteral(cond)})`;\n}\n\n/** Shift a rendered node to `indent`, wrapping `expr` nodes in `{ \u2026 }`. */\nexport function placeChild(rendered: Rendered, indent: number): string {\n if (rendered.kind === 'element') return shift(rendered.markup, indent);\n return shift(`{${rendered.expr}}`, indent);\n}\n\n/** Public entry: render a node (and any `if`) to placed markup at `indent`. */\nexport function emitNode(node: Node | string, ctx: EmitContext, indent: number): string {\n if (typeof node === 'string') return shift(emitTextChild(node), indent);\n return placeChild(renderNode(node, ctx), indent);\n}\n", "/**\n * Frontmatter helpers shared by the page + component assemblers: deterministic\n * import lines and the `resolveProps(Astro, {\u2026})` prop block.\n */\n\nimport type { EmitContext } from './emitContext';\nimport { astroComponentName } from './emitNode';\nimport { serializeLiteral } from './serialize';\n\nexport interface ImportOptions {\n /** Type-only symbols from `meno-astro` (e.g. MenoComponentMeta, MenoPageMeta). */\n typeImports?: string[];\n /** Relative path prefix for local component imports (e.g. './' or '../components/'). */\n componentPrefix: string;\n /**\n * Optional override producing the full relative import path for a referenced\n * component by name (used when components live in category subfolders so imports\n * resolve to `\u2026/section/Error404.astro` instead of a flat `\u2026/Error404.astro`).\n * When absent, falls back to `${componentPrefix}${name}.astro`.\n */\n componentImportPath?: (name: string) => string;\n}\n\n/** Build deterministic, alphabetized import lines from the emit context. */\nexport function buildImportLines(ctx: EmitContext, opts: ImportOptions): string[] {\n const lines: string[] = [];\n const types = [...new Set(opts.typeImports ?? [])].sort();\n if (types.length) lines.push(`import type { ${types.join(', ')} } from 'meno-astro';`);\n if (ctx.runtime.size) {\n lines.push(`import { ${[...ctx.runtime].sort().join(', ')} } from 'meno-astro';`);\n }\n if (ctx.runtimeComponents.size) {\n lines.push(`import { ${[...ctx.runtimeComponents].sort().join(', ')} } from 'meno-astro/components';`);\n }\n for (const name of [...ctx.components].sort()) {\n const path = opts.componentImportPath ? opts.componentImportPath(name) : `${opts.componentPrefix}${name}.astro`;\n lines.push(`import ${astroComponentName(name)} from '${path}';`);\n }\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// resolveProps(Astro, {\u2026}) \u2014 the single authoritative prop block.\n//\n// The `{\u2026}` literal is the authoritative prop definition (`serializeLiteral` of\n// `def.interface`); the parser reads it back. The destructured names are emit-only\n// (the prop names, minus `children`, plus `class: className`); the parser ignores\n// them. TS types of the locals are inferred from the literal by `resolveProps`.\n// ---------------------------------------------------------------------------\n\nconst WIDTH = 80;\nconst CALL_PREFIX = 'resolveProps(Astro, ';\n\ntype PropDef = Record<string, any>;\n\n/**\n * Build the `const { \u2026names\u2026, class: className } = resolveProps(Astro, {\u2026});`\n * block. Always binds `class: className` so instances can carry wrapper styles, and\n * always emits the call (even for an empty interface: `resolveProps(Astro, {})`).\n */\nexport function buildPropsBlock(propInterface: Record<string, PropDef> | undefined): string[] {\n const def = propInterface ?? {};\n const names: string[] = [];\n for (const name of Object.keys(def)) {\n if (name === 'children') continue;\n names.push(name);\n }\n names.push('class: className');\n\n // Two statements:\n // const __props = resolveProps(Astro, {\u2026}); \u2190 the authoritative prop definition\n // const { x, y, class: className } = __props; \u2190 the destructured locals\n // `__props` (the resolved object) is what style()/href()/embedHtml() receive so that\n // prop-`_mapping`s resolve; the destructure feeds the template's `{x}` references.\n const head = `const __props = ${CALL_PREFIX}`;\n // Serialize the prop literal at its true start column; reserve 2 cols for `);`.\n const literal = serializeLiteral(def, { indent: 0, startCol: head.length + 2, width: WIDTH });\n const assign = `${head}${literal});`;\n\n const destrHead = `const { ${names.join(', ')} } = __props;`;\n const destructure =\n destrHead.length <= WIDTH\n ? destrHead\n : ['const {', ...names.map((n) => ` ${n},`), '} = __props;'].join('\\n');\n\n return [assign, destructure];\n}\n", "/**\n * CMS template-page route helpers \u2014 the single source of truth for \"is this page a\n * CMS template?\" and \"where on disk does it live?\". Shared by the emitter\n * (`emitPage`), the page/CMS providers, and the project converter so they all agree\n * on the `src/pages/<collection>/[slug].astro` layout.\n *\n * A CMS template page is a normal page model whose `meta.source === 'cms'` and which\n * carries a `meta.cms` schema. Its body renders the *current* item via `{{cms.field}}`\n * templates; on disk it becomes an Astro dynamic route with `getStaticPaths()`.\n */\n\n/** The dynamic route filename \u2014 Astro maps `[slug].astro` to a `slug` param. */\nexport const CMS_ROUTE_FILE = '[slug].astro';\n\n/** Minimal shape of the `meta.cms` schema this module reads. */\nexport interface CmsMetaLike {\n id?: string;\n slugField?: string;\n urlPattern?: string;\n}\n\n/** A page-model-ish value with the meta we care about. */\ninterface PageLike {\n meta?: { source?: unknown; cms?: CmsMetaLike } | Record<string, unknown>;\n}\n\n/** True when `page` is a CMS template page (`meta.source === 'cms'` + a `meta.cms` schema). */\nexport function isCmsTemplatePage(page: unknown): page is { meta: { source: 'cms'; cms: CmsMetaLike } } {\n if (!page || typeof page !== 'object') return false;\n const meta = (page as PageLike).meta as Record<string, unknown> | undefined;\n return !!meta && meta.source === 'cms' && !!meta.cms && typeof meta.cms === 'object';\n}\n\n/**\n * Derive the route *directory* (relative to `src/pages`) from a CMS `urlPattern`.\n *\n * \"/blog/{{slug}}\" -> \"blog\"\n * \"/case-studies/{{slug}}\" -> \"case-studies\"\n * \"/docs/guides/{{slug}}\" -> \"docs/guides\" (multi-segment: kept verbatim)\n * \"/{{slug}}\" / \"\" / \u2026 -> \"\" (degrade: file lands at pages root)\n *\n * Mirrors the one-way exporter's `extractPathPrefix` (cmsPageEmitter.ts): everything\n * before the FIRST `{{\u2026}}` placeholder is the static prefix. Locale-prefixed patterns\n * like \"/{{locale}}/blog/{{slug}}\" therefore degrade to \"\" (their first placeholder is\n * the locale) \u2014 those aren't specially handled here (the dialect is single-locale).\n */\nexport function cmsRouteDirFromUrlPattern(urlPattern: string | undefined): string {\n if (!urlPattern) return '';\n const withoutLeading = urlPattern.replace(/^\\/+/, '');\n const idx = withoutLeading.indexOf('{{');\n const prefix = idx < 0 ? withoutLeading : withoutLeading.slice(0, idx);\n // Strip a trailing slash and any stray surrounding slashes.\n return prefix.replace(/^\\/+|\\/+$/g, '');\n}\n\n/**\n * The `.astro` file path (relative to `src/pages`, POSIX separators) for a CMS\n * template page. `\"/blog/{{slug}}\"` \u2192 `\"blog/[slug].astro\"`; a pattern with no static\n * prefix \u2192 just `\"[slug].astro\"`.\n */\nexport function cmsRouteRelPath(urlPattern: string | undefined): string {\n const dir = cmsRouteDirFromUrlPattern(urlPattern);\n return dir ? `${dir}/${CMS_ROUTE_FILE}` : CMS_ROUTE_FILE;\n}\n\n/**\n * The `getStaticPaths()` + `const { cms } = Astro.props;` frontmatter boilerplate for a\n * CMS template page. Deterministic, derived solely from the collection id + slug field\n * (mirrors `core`'s `cmsPageEmitter.buildGetStaticPaths`, single-locale form). This is\n * emit-only: the parser recognizes and SKIPS it, regenerating it from `meta.cms`.\n */\nexport function buildGetStaticPaths(cms: CmsMetaLike): string {\n const collectionId = cms.id ?? '';\n const slugField = cms.slugField || 'slug';\n return [\n `export async function getStaticPaths() {`,\n ` const entries = await getCollection(${JSON.stringify(collectionId)});`,\n ` return entries.map((entry) => ({`,\n ` params: { slug: entry.data.${slugField} ?? entry.id },`,\n ` props: { cms: entry.data },`,\n ` }));`,\n `}`,\n ``,\n `const { cms } = Astro.props;`,\n ].join('\\n');\n}\n", "/**\n * Page assembler \u2014 a `JSONPage` \u2192 a full `.astro` page file.\n *\n * The page `meta` becomes `export const meta = {\u2026} satisfies MenoPageMeta` and the\n * node tree is wrapped in `<BaseLayout meta={meta}>`.\n *\n * **CMS template pages** (`meta.source === 'cms'` + a `meta.cms` schema) emit as an\n * idiomatic Astro dynamic route: an extra `getCollection` import plus a deterministic\n * `getStaticPaths()` + `const { cms } = Astro.props;` block (derived from `meta.cms`)\n * sit ahead of `export const meta`. That block is emit-only boilerplate \u2014 the parser\n * recognizes and SKIPS it (like `interface Props`/`resolveProps` for components), so\n * the model round-trips unchanged. The body is identical to a regular page.\n */\n\nimport type { JSONPage } from 'meno-core/shared/types';\nimport { createEmitContext, needRuntimeComponent, type EmitOptions } from './emitContext';\nimport { emitNode } from './emitNode';\nimport { serializeLiteral } from './serialize';\nimport { buildImportLines } from './frontmatter';\nimport { isCmsTemplatePage, buildGetStaticPaths, cmsRouteDirFromUrlPattern, type CmsMetaLike } from '../cmsRoute';\n\nexport function emitPage(page: JSONPage, opts?: EmitOptions): string {\n const ctx = createEmitContext();\n // Body sits two spaces in, inside <BaseLayout>.\n const body = page.root ? emitNode(page.root as any, ctx, 2) : '';\n needRuntimeComponent(ctx, 'BaseLayout');\n\n const isCms = isCmsTemplatePage(page);\n\n // Component import prefix is relative to the page file's directory. Regular pages\n // sit at `src/pages/<name>.astro` (depth 0 \u2192 `../components/`). A CMS template route\n // lives at `src/pages/<routeDir>/[slug].astro`, so its depth (and thus the number of\n // `../` hops up to `src/components/`) is derived from `meta.cms.urlPattern`. This keeps\n // emit a pure function of the model while emitting a correct relative import.\n const routeDir = isCms ? cmsRouteDirFromUrlPattern((page.meta as { cms: CmsMetaLike }).cms.urlPattern) : '';\n const depth = routeDir ? routeDir.split('/').length : 0;\n const componentPrefix = `${'../'.repeat(depth + 1)}components/`;\n\n // With a component\u2192path map (categorized projects), resolve each import to its\n // subfolder (e.g. `../components/section/Error404.astro`); otherwise stay flat.\n const componentImportPath = opts?.componentPaths\n ? (name: string) => `${componentPrefix}${opts.componentPaths![name] ?? name}.astro`\n : undefined;\n\n const importLines = buildImportLines(ctx, {\n // No `satisfies MenoPageMeta` type annotation is emitted (see below), so there's\n // no type import to add. `satisfies` is a TS-only operator that breaks the\n // esbuild/astro frontmatter parse on build, and the published runtime ships no\n // types anyway \u2014 so the annotation was pure build-time fragility.\n typeImports: [],\n componentPrefix,\n componentImportPath,\n });\n\n const fm: string[] = [];\n // Pull entries from Astro's content layer: CMS template routes need it for\n // getStaticPaths; any page with a CMS collection list needs it to pass into\n // getCollectionList (meno-astro never imports astro:content itself).\n if (isCms || ctx.needsContentApi) fm.push(`import { getCollection } from 'astro:content';`);\n fm.push(...importLines);\n fm.push('');\n if (isCms) {\n // Deterministic boilerplate, derived from meta.cms (emit-only; parser skips it).\n fm.push(buildGetStaticPaths((page.meta as { cms: CmsMetaLike }).cms));\n fm.push('');\n }\n fm.push(`export const meta = ${serializeLiteral(page.meta ?? {}, { indent: 0 })};`);\n if (ctx.frontmatterConsts.length) {\n fm.push('');\n fm.push(...ctx.frontmatterConsts);\n }\n\n const wrapped = body\n ? `<BaseLayout meta={meta}>\\n${body}\\n</BaseLayout>`\n : `<BaseLayout meta={meta} />`;\n return `---\\n${fm.join('\\n')}\\n---\\n${wrapped}\\n`;\n}\n", "/**\n * Component assembler \u2014 a `StructuredComponentDefinition` \u2192 a full `.astro` component\n * file (frontmatter + body + optional <style>/<script>).\n *\n * The single `const { \u2026 } = resolveProps(Astro, {\u2026})` call is the authoritative\n * prop block: its `{\u2026}` argument is the serialized prop interface (the parser reads\n * it), and the destructured locals (typed by inference) are emit-only convenience.\n * `__meno` carries the remaining component metadata (category, acceptsStyles,\n * libraries). `defineVars` is NOT in `__meno`: a component's JS that needs its props\n * is emitted as `<script define:vars={{\u2026}}>` (native Astro), reconstructed on parse.\n */\n\nimport type { StructuredComponentDefinition } from 'meno-core/shared/types';\nimport { createEmitContext, relativeComponentImport, type EmitOptions } from './emitContext';\nimport { emitNode, collectItemBindings } from './emitNode';\nimport { serializeLiteral } from './serialize';\nimport { buildImportLines, buildPropsBlock } from './frontmatter';\n\nconst META_KEYS = ['category', 'acceptsStyles', 'libraries'] as const;\n\n/**\n * The prop names injected into the client `<script>` via Astro's `define:vars`.\n * `true` \u2192 every interface prop (key order, minus `children`); a `string[]` \u2192 as given.\n */\nfunction defineVarNames(def: StructuredComponentDefinition): string[] {\n if (def.defineVars === true) {\n return Object.keys(def.interface ?? {}).filter((k) => k !== 'children');\n }\n return def.defineVars ?? [];\n}\n\n/**\n * The client `<script>` block. When `defineVars` is set, emit Astro's native\n * `<script define:vars={{ a, b }}>` (which already forces inline \u2014 no `is:inline`);\n * otherwise a plain `<script is:inline>`. No script when there is no `javascript`.\n */\nfunction buildScriptBlock(def: StructuredComponentDefinition): string {\n if (!def.javascript) return '';\n if (def.defineVars) {\n const names = defineVarNames(def);\n return `\\n\\n<script define:vars={{ ${names.join(', ')} }}>\\n${def.javascript}\\n</script>`;\n }\n return `\\n\\n<script is:inline>\\n${def.javascript}\\n</script>`;\n}\n\nfunction pickComponentMeta(def: StructuredComponentDefinition): Record<string, unknown> {\n const meta: Record<string, unknown> = {};\n for (const k of META_KEYS) {\n const v = (def as Record<string, unknown>)[k];\n if (v !== undefined) meta[k] = v;\n }\n return meta;\n}\n\nexport function emitComponent(def: StructuredComponentDefinition, opts?: EmitOptions): string {\n const ctx = createEmitContext();\n // Every component exposes its resolved props as `__props` (see buildPropsBlock); the\n // body's style()/href()/embedHtml() calls pass it so prop-`_mapping`s resolve.\n ctx.propsVar = '__props';\n const body = def.structure ? emitNode(def.structure as any, ctx, 0) : '<slot />';\n\n const componentMeta = pickComponentMeta(def);\n const hasMeta = Object.keys(componentMeta).length > 0;\n\n // `resolveProps` is the authoritative prop block; every component imports it.\n ctx.runtime.add('resolveProps');\n\n // No `satisfies MenoComponentMeta` annotation is emitted (see below) \u2014 `satisfies`\n // is TS-only and breaks the esbuild/astro frontmatter parse on build, and no types\n // ship with the runtime \u2014 so there's no type import to add.\n const typeImports: string[] = [];\n\n // Categorized projects: resolve sibling-component imports relative to THIS\n // component's own folder (e.g. a `section/` component importing `ui/Button`\n // emits `../ui/Button.astro`). Flat projects keep `./Button.astro`.\n const selfDir = opts?.selfPath ? opts.selfPath.split('/').slice(0, -1).join('/') : '';\n const componentImportPath = opts?.componentPaths\n ? (name: string) => `${relativeComponentImport(selfDir, opts.componentPaths![name] ?? name)}.astro`\n : undefined;\n\n const importLines = buildImportLines(ctx, { typeImports, componentPrefix: './', componentImportPath });\n const propsBlock = buildPropsBlock(def.interface);\n\n // CMS-item bindings: identifiers the template references (e.g. `post` in\n // `{{post.title}}`) that aren't declared props or inner-list loop vars. The parent\n // list passes them as props (renderComponentInstance); declare them here so the\n // references resolve in this component's own module scope.\n const itemBindings = collectItemBindings(def.structure, Object.keys(def.interface ?? {}));\n\n const fm: string[] = [];\n // A component containing a CMS collection list must import astro:content's\n // getCollection and pass it to getCollectionList (see runtime/collectionList).\n if (ctx.needsContentApi) fm.push(`import { getCollection } from 'astro:content';`);\n fm.push(...importLines);\n fm.push('');\n fm.push(...propsBlock);\n if (itemBindings.length) {\n fm.push(`const { ${itemBindings.join(', ')} } = Astro.props;`);\n }\n if (hasMeta) {\n fm.push('');\n fm.push(`const __meno = ${serializeLiteral(componentMeta, { indent: 0 })};`);\n }\n if (ctx.frontmatterConsts.length) {\n fm.push('');\n fm.push(...ctx.frontmatterConsts);\n }\n\n const styleBlock = def.css ? `\\n\\n<style>\\n${def.css}\\n</style>` : '';\n const scriptBlock = buildScriptBlock(def);\n\n return `---\\n${fm.join('\\n')}\\n---\\n${body}\\n${styleBlock}${scriptBlock}`.replace(/\\n+$/, '\\n');\n}\n", "/**\n * Recursive-descent parser for the JS-literal subset that `serialize.ts` emits \u2014\n * its exact inverse. Grammar: object | array | string | number | boolean | null,\n * with identifier-or-quoted object keys and JSON string escaping. Total over that\n * grammar; throws on anything outside it (which, for in-dialect input, never occurs).\n *\n * This is the \"tiny total evaluator\" that reads back `style(\u2026)`, `i18n(\u2026)`,\n * `export const meta = \u2026`, the `resolveProps(Astro, {\u2026})` argument, etc. \u2014 no\n * `eval`, no JS engine.\n */\n\nexport interface LiteralResult {\n value: unknown;\n /** Index just past the parsed value. */\n end: number;\n}\n\nconst WS = new Set([' ', '\\t', '\\r', '\\n']);\nconst IDENT_START = /[A-Za-z_$]/;\nconst IDENT_CHAR = /[A-Za-z0-9_$]/;\n\nfunction skipWs(src: string, i: number): number {\n while (i < src.length && WS.has(src[i])) i++;\n return i;\n}\n\nfunction fail(src: string, i: number, msg: string): never {\n const around = src.slice(Math.max(0, i - 20), i + 20);\n throw new Error(`parseLiteral: ${msg} at index ${i} (\u2026${around}\u2026)`);\n}\n\nfunction parseString(src: string, i: number): LiteralResult {\n // src[i] === '\"'. Scan to the matching unescaped quote, then JSON.parse the span.\n let j = i + 1;\n while (j < src.length) {\n const c = src[j];\n if (c === '\\\\') { j += 2; continue; }\n if (c === '\"') { j++; break; }\n j++;\n }\n const raw = src.slice(i, j);\n return { value: JSON.parse(raw) as string, end: j };\n}\n\nfunction parseNumber(src: string, i: number): LiteralResult {\n let j = i;\n while (j < src.length && /[-+0-9.eE]/.test(src[j])) j++;\n const raw = src.slice(i, j);\n const n = Number(raw);\n if (Number.isNaN(n) && raw !== 'NaN') fail(src, i, `invalid number \"${raw}\"`);\n return { value: n, end: j };\n}\n\nfunction parseKey(src: string, i: number): LiteralResult {\n if (src[i] === '\"') return parseString(src, i);\n if (!IDENT_START.test(src[i])) fail(src, i, 'expected object key');\n let j = i + 1;\n while (j < src.length && IDENT_CHAR.test(src[j])) j++;\n return { value: src.slice(i, j), end: j };\n}\n\nfunction parseObject(src: string, i: number): LiteralResult {\n const obj: Record<string, unknown> = {};\n let j = skipWs(src, i + 1);\n if (src[j] === '}') return { value: obj, end: j + 1 };\n for (;;) {\n j = skipWs(src, j);\n const key = parseKey(src, j);\n j = skipWs(src, key.end);\n if (src[j] !== ':') fail(src, j, 'expected \":\"');\n j = skipWs(src, j + 1);\n const val = parseValueAt(src, j);\n obj[key.value as string] = val.value;\n j = skipWs(src, val.end);\n if (src[j] === ',') { j++; continue; }\n if (src[j] === '}') return { value: obj, end: j + 1 };\n fail(src, j, 'expected \",\" or \"}\"');\n }\n}\n\nfunction parseArray(src: string, i: number): LiteralResult {\n const arr: unknown[] = [];\n let j = skipWs(src, i + 1);\n if (src[j] === ']') return { value: arr, end: j + 1 };\n for (;;) {\n j = skipWs(src, j);\n const val = parseValueAt(src, j);\n arr.push(val.value);\n j = skipWs(src, val.end);\n if (src[j] === ',') { j++; continue; }\n if (src[j] === ']') return { value: arr, end: j + 1 };\n fail(src, j, 'expected \",\" or \"]\"');\n }\n}\n\n/** Parse a single literal value starting at `i` (after leading whitespace). */\nexport function parseValueAt(src: string, i: number): LiteralResult {\n i = skipWs(src, i);\n const c = src[i];\n if (c === '{') return parseObject(src, i);\n if (c === '[') return parseArray(src, i);\n if (c === '\"') return parseString(src, i);\n if (src.startsWith('true', i)) return { value: true, end: i + 4 };\n if (src.startsWith('false', i)) return { value: false, end: i + 5 };\n if (src.startsWith('null', i)) return { value: null, end: i + 4 };\n if (c === '-' || c === '+' || (c >= '0' && c <= '9')) return parseNumber(src, i);\n return fail(src, i, `unexpected character \"${c ?? '<eof>'}\"`);\n}\n\n/** Parse a whole literal string (the entire trimmed input must be one literal). */\nexport function parseLiteral(src: string): unknown {\n const { value, end } = parseValueAt(src, 0);\n const rest = skipWs(src, end);\n if (rest !== src.length) fail(src, rest, 'trailing content after literal');\n return value;\n}\n", "/**\n * Low-level scanners for the parser: skip strings / template literals and find\n * matching delimiters, so higher layers can treat `{ \u2026 }`, `( \u2026 )`, `[ \u2026 ]` as\n * opaque balanced spans without tripping over braces inside strings or `${\u2026}`.\n */\n\nconst CLOSERS: Record<string, string> = { '{': '}', '(': ')', '[': ']' };\n\n/** From a quote at `i`, return the index just past the matching closing quote. */\nexport function scanString(src: string, i: number): number {\n const q = src[i];\n let j = i + 1;\n while (j < src.length) {\n if (src[j] === '\\\\') { j += 2; continue; }\n if (src[j] === q) return j + 1;\n j++;\n }\n throw new Error(`scanString: unterminated string from ${i}`);\n}\n\n/** From a backtick at `i`, return the index just past the matching backtick (handles `${\u2026}`). */\nexport function scanTemplate(src: string, i: number): number {\n let j = i + 1;\n while (j < src.length) {\n if (src[j] === '\\\\') { j += 2; continue; }\n if (src[j] === '`') return j + 1;\n if (src[j] === '$' && src[j + 1] === '{') { j = scanBalanced(src, j + 1); continue; }\n j++;\n }\n throw new Error(`scanTemplate: unterminated template from ${i}`);\n}\n\n/** From an opening delimiter at `i` ({ ( [), return the index just past its match. */\nexport function scanBalanced(src: string, i: number): number {\n if (!CLOSERS[src[i]]) throw new Error(`scanBalanced: no open delimiter at ${i} (\"${src[i]}\")`);\n let depth = 0;\n let j = i;\n while (j < src.length) {\n const c = src[j];\n if (c === '\"' || c === \"'\") { j = scanString(src, j); continue; }\n if (c === '`') { j = scanTemplate(src, j); continue; }\n if (c === '{' || c === '(' || c === '[') { depth++; j++; continue; }\n if (c === '}' || c === ')' || c === ']') {\n depth--;\n j++;\n if (depth === 0) return j;\n continue;\n }\n j++;\n }\n throw new Error(`scanBalanced: unbalanced from ${i}`);\n}\n\n/**\n * Find the first top-level `openChar \u2026 close` group whose close is the very end of\n * `expr` (e.g. the `( \u2026 )` of `cond && ( \u2026 )` or `head.map(\u2026)`). Returns the inner\n * content, or null. Skips strings/templates/nested groups.\n */\nexport function findTrailingGroup(\n expr: string,\n openChar: '(' | '{' | '[' = '(',\n): { open: number; inner: string } | null {\n let j = 0;\n while (j < expr.length) {\n const c = expr[j];\n if (c === '\"' || c === \"'\") { j = scanString(expr, j); continue; }\n if (c === '`') { j = scanTemplate(expr, j); continue; }\n if (c === '{' || c === '(' || c === '[') {\n const end = scanBalanced(expr, j);\n if (c === openChar && end === expr.length) {\n return { open: j, inner: expr.slice(j + 1, end - 1) };\n }\n j = end;\n continue;\n }\n j++;\n }\n return null;\n}\n\n/** Split `src` on a single-character separator at top level (ignores strings/groups). */\nexport function splitTopLevel(src: string, sep: string): string[] {\n const parts: string[] = [];\n let start = 0;\n let j = 0;\n while (j < src.length) {\n const c = src[j];\n if (c === '\"' || c === \"'\") { j = scanString(src, j); continue; }\n if (c === '`') { j = scanTemplate(src, j); continue; }\n if (c === '{' || c === '(' || c === '[') { j = scanBalanced(src, j); continue; }\n if (c === sep) { parts.push(src.slice(start, j)); start = j + 1; j++; continue; }\n j++;\n }\n parts.push(src.slice(start));\n return parts.map((s) => s.trim());\n}\n", "import { scanBalanced } from './scan';\n\n/** Inner text of the first `( \u2026 )` call group in `expr` (e.g. `style( <here> )`). */\nexport function callArgsOf(expr: string): string {\n const open = expr.indexOf('(');\n const end = scanBalanced(expr, open);\n return expr.slice(open + 1, end - 1);\n}\n", "/**\n * Value reversers \u2014 the inverse of the emitter's value/attribute encoders. Turn a\n * JSX attribute/expression string back into the Meno model value it came from.\n */\n\nimport { parseLiteral } from './parseLiteral';\nimport { scanBalanced, splitTopLevel } from './scan';\nimport { callArgsOf } from './callArgs';\nimport type { ParseContext } from './parseContext';\n\n/** Reverse `escapeBacktick` + `${expr}` interpolation: backtick content \u2192 Meno string. */\nexport function reverseTemplate(content: string): string {\n let out = '';\n let i = 0;\n while (i < content.length) {\n const c = content[i];\n if (c === '\\\\') {\n const n = content[i + 1];\n // escapeBacktick produced \\\\, \\` and \\${ \u2014 undo each (\\$ leaves the following { literal).\n out += n === '\\\\' ? '\\\\' : n === '`' ? '`' : n === '$' ? '$' : n;\n i += 2;\n continue;\n }\n if (c === '$' && content[i + 1] === '{') {\n const end = scanBalanced(content, i + 1);\n out += '{{' + content.slice(i + 2, end - 1).trim() + '}}';\n i = end;\n continue;\n }\n out += c;\n i++;\n }\n return out;\n}\n\n/**\n * Interpret a JSX expression-attribute value (the inner of `name={ \u2026 }`) back into a\n * Meno model value.\n */\nexport function interpretExprValue(expr: string, ctx: ParseContext): unknown {\n const e = expr.trim();\n\n if (ctx.embedConsts.has(e)) return ctx.embedConsts.get(e);\n if (e.startsWith('i18n(')) return parseLiteral(callArgsOf(e));\n // href()/embedHtml() may carry a threaded `__props` arg after the literal mapping (the\n // emitter passes the host component's props). Take only the first top-level arg.\n if (e.startsWith('href(')) return parseLiteral(splitTopLevel(callArgsOf(e), ',')[0]);\n if (e.startsWith('embedHtml(')) return parseLiteral(splitTopLevel(callArgsOf(e), ',')[0]);\n if (e[0] === '`') return reverseTemplate(e.slice(1, -1));\n if (e[0] === '{' || e[0] === '[') return parseLiteral(e);\n if (e[0] === '\"') return parseLiteral(e);\n if (e === 'true') return true;\n if (e === 'false') return false;\n if (e === 'null') return null;\n if (/^[-+]?(\\d|\\.\\d)/.test(e) && !Number.isNaN(Number(e))) return Number(e);\n // Bare expression / identifier / member / ternary \u2192 a Meno template.\n return `{{${e}}}`;\n}\n\n/** Reverse a `class={style(LIT[, META])}` attribute into { style, \u2026meta fields }. */\nexport function interpretStyleCall(expr: string): {\n style?: unknown;\n interactiveStyles?: unknown;\n label?: unknown;\n generateElementClass?: unknown;\n} {\n const args = callArgsOf(expr); // inside style( \u2026 )\n const parts = splitTopLevel(args, ',').filter((p) => p.length > 0);\n const out: Record<string, unknown> = {};\n if (parts[0]) out.style = parseLiteral(parts[0]);\n // Meta is the object-literal argument after the style object. Handles both the legacy\n // `style(obj, meta)` form and the current `style(obj, props, meta)` form \u2014 the `props`\n // argument is a bare identifier (`__props`/`undefined`) and is skipped.\n const metaPart = parts.slice(1).find((p) => p.trimStart().startsWith('{'));\n if (metaPart) {\n const meta = parseLiteral(metaPart) as Record<string, unknown>;\n if (meta.interactive !== undefined) out.interactiveStyles = meta.interactive;\n if (meta.label !== undefined) out.label = meta.label;\n if (meta.genClass !== undefined) out.generateElementClass = meta.genClass;\n // `instance` / `kind` are emit-only markers \u2014 intentionally dropped.\n }\n return out;\n}\n\n/** Reverse an `if` condition expression back into a Meno `if` value. */\nexport function reverseCondition(cond: string): boolean | string | unknown {\n const c = cond.trim();\n if (c === 'false') return false;\n if (c === 'true') return true;\n if (c.startsWith('when(')) return parseLiteral(callArgsOf(c));\n return `{{${c}}}`;\n}\n", "/**\n * Shared state the body parser needs from the frontmatter: collection-list bindings,\n * hoisted embed consts, and the set of imported component tag names.\n */\n\nexport interface CollectionBinding {\n source: string;\n query?: Record<string, unknown>;\n}\n\n/** Absolute byte span of a model node in the original source: `[start, end)`. */\nexport interface NodeSpan {\n start: number;\n end: number;\n}\n\nexport interface ParseContext {\n /** `const blogList = await getCollectionList(\"blog\", {\u2026}, Astro)` \u2192 binding name \u2192 info. */\n collectionBindings: Map<string, CollectionBinding>;\n /** `const __embed0 = \\`\u2026\\`` \u2192 const name \u2192 verbatim (un-escaped) HTML. */\n embedConsts: Map<string, string>;\n /** `const Tag_0 = \\`h${size}\\`` \u2192 const name \u2192 the Meno tag string (`h{{size}}`). */\n tagConsts: Map<string, string>;\n /** Component tag names brought in by local imports (`import X from './X.astro'`). */\n componentNames: Set<string>;\n /**\n * Optional sink for source-line mapping: when present, the body parser records the\n * absolute source span of every object node it produces (keyed by node identity).\n * Off by default (the round-trip codec never sets it) so normal parsing is unchanged;\n * `buildAstroLineMap` opts in to recover `.astro` line ranges for the editor/selection.\n */\n spans?: Map<object, NodeSpan>;\n}\n\nexport function createParseContext(): ParseContext {\n return {\n collectionBindings: new Map(),\n embedConsts: new Map(),\n tagConsts: new Map(),\n componentNames: new Set(),\n };\n}\n", "/**\n * Frontmatter parser \u2014 extracts the named consts/exports the emitter wrote:\n * `export const meta`, the `resolveProps(Astro, {\u2026})` prop literal, `const __meno`,\n * hoisted `__embedN` template consts, `getCollectionList` bindings, and local\n * component imports.\n */\n\nimport { parseValueAt, parseLiteral } from './parseLiteral';\nimport { scanBalanced, scanTemplate, splitTopLevel } from './scan';\nimport { reverseTemplate } from './parseValue';\nimport { createParseContext, type ParseContext } from './parseContext';\n\nexport interface Frontmatter {\n kind: 'page' | 'component';\n ctx: ParseContext;\n meta?: unknown;\n propsInterface?: Record<string, unknown>;\n componentMeta: Record<string, unknown>;\n}\n\n/** Read the literal RHS that follows an anchor like `export const meta = `. */\nfunction literalAfter(code: string, anchor: string): unknown | undefined {\n const idx = code.indexOf(anchor);\n if (idx < 0) return undefined;\n return parseValueAt(code, idx + anchor.length).value;\n}\n\nexport function parseFrontmatter(code: string): Frontmatter {\n const ctx = createParseContext();\n\n // Local component imports: `import Name from './Name.astro'` or a `\u2026/components/Name.astro`\n // path with one-or-more `../` hops (top-level page \u2192 `../components/`; a nested CMS\n // template route at src/pages/<col>/[slug].astro \u2192 `../../components/`).\n for (const m of code.matchAll(/import\\s+(\\w+)\\s+from\\s+'(?:\\.\\/|(?:\\.\\.\\/)+components\\/)[\\w.-]+\\.astro'/g)) {\n ctx.componentNames.add(m[1]);\n }\n\n // Hoisted embed consts: `const __embed0 = ` + backtick template.\n for (const m of code.matchAll(/const\\s+(__embed\\d+)\\s*=\\s*/g)) {\n const tickStart = code.indexOf('`', m.index! + m[0].length);\n if (tickStart < 0) continue;\n const tickEnd = scanTemplate(code, tickStart);\n ctx.embedConsts.set(m[1], reverseTemplate(code.slice(tickStart + 1, tickEnd - 1)));\n }\n\n // Dynamic-tag consts: `const Tag_0 = ` + backtick template \u2192 Meno tag string.\n for (const m of code.matchAll(/const\\s+(Tag_\\d+)\\s*=\\s*/g)) {\n const tickStart = code.indexOf('`', m.index! + m[0].length);\n if (tickStart < 0) continue;\n const tickEnd = scanTemplate(code, tickStart);\n ctx.tagConsts.set(m[1], reverseTemplate(code.slice(tickStart + 1, tickEnd - 1)));\n }\n\n // Collection-list bindings:\n // const X = await getCollectionList(\"src\"[, {query}], Astro, getCollection)\n // The optional `{query}` is the only object-literal arg; the trailing `Astro` and\n // `getCollection` identifiers are emit-only plumbing and ignored.\n for (const m of code.matchAll(/const\\s+(\\w+)\\s*=\\s*await\\s+getCollectionList\\(/g)) {\n const open = m.index! + m[0].length - 1; // the '(' of getCollectionList(\n const inner = code.slice(open + 1, scanBalanced(code, open) - 1);\n const args = splitTopLevel(inner, ',').filter(Boolean);\n const source = parseLiteral(args[0]) as string;\n const query = args[1]?.trim().startsWith('{')\n ? (parseLiteral(args[1]) as Record<string, unknown>)\n : undefined;\n ctx.collectionBindings.set(m[1], { source, query });\n }\n\n // The authoritative prop definition is the second argument of the single\n // `resolveProps(Astro, {\u2026})` call. `literalAfter` scans the balanced `{\u2026}`\n // literal that follows the anchor and stops at its matching brace, so the trailing\n // `)`/`;` are ignored. The (cosmetic) destructured names are never read.\n const propsInterface = literalAfter(code, 'resolveProps(Astro, ') as Record<string, unknown> | undefined;\n const componentMeta = (literalAfter(code, 'const __meno = ') as Record<string, unknown>) ?? {};\n const meta = literalAfter(code, 'export const meta = ');\n const kind: Frontmatter['kind'] = code.includes('resolveProps(') ? 'component' : 'page';\n\n return { kind, ctx, meta, propsInterface, componentMeta };\n}\n", "/**\n * Markup parser \u2014 the inverse of the node walker. Parses meno-astro dialect template\n * markup back into the Meno node tree, reversing every emitter encoding (style()/i18n()\n * calls, {{}} templates, {cond && (\u2026)} conditionals, list .map(), runtime components).\n */\n\nimport { singularize } from 'meno-core/shared/types';\nimport { scanBalanced, findTrailingGroup, splitTopLevel } from './scan';\nimport { parseLiteral } from './parseLiteral';\nimport {\n interpretExprValue,\n interpretStyleCall,\n reverseCondition,\n} from './parseValue';\nimport { callArgsOf } from './callArgs';\nimport type { ParseContext } from './parseContext';\n\ntype Node = Record<string, any>;\ntype Child = Node | string;\n\nconst WS = new Set([' ', '\\t', '\\r', '\\n']);\nconst RUNTIME_TAGS = new Set(['Link', 'Embed', 'LocaleList', 'BaseLayout']);\nconst LOCALE_STYLE_PROPS = new Set([\n 'style', 'itemStyle', 'activeItemStyle', 'separatorStyle', 'flagStyle',\n]);\n\nfunction skipWs(src: string, i: number): number {\n while (i < src.length && WS.has(src[i])) i++;\n return i;\n}\n\ninterface Attr {\n name: string;\n raw: string;\n isExpr: boolean;\n shorthand?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Tag + attribute scanning\n// ---------------------------------------------------------------------------\n\nfunction readTagName(src: string, i: number): { name: string; end: number } {\n let j = i;\n while (j < src.length && /[A-Za-z0-9.\\-_]/.test(src[j])) j++;\n return { name: src.slice(i, j), end: j };\n}\n\nfunction parseAttributes(src: string, i: number): { attrs: Attr[]; end: number; selfClose: boolean } {\n const attrs: Attr[] = [];\n let j = i;\n for (;;) {\n j = skipWs(src, j);\n if (src[j] === '/' && src[j + 1] === '>') return { attrs, end: j + 2, selfClose: true };\n if (src[j] === '>') return { attrs, end: j + 1, selfClose: false };\n const { name, end } = readTagName(src, j);\n if (!name) throw new Error(`parseAttributes: expected attribute name at ${j} (\"${src.slice(j, j + 15)}\")`);\n j = end;\n if (src[j] === '=') {\n j++;\n if (src[j] === '\"' || src[j] === \"'\") {\n const q = src[j];\n let k = j + 1;\n while (k < src.length && src[k] !== q) { if (src[k] === '\\\\') k++; k++; }\n attrs.push({ name, raw: src.slice(j + 1, k), isExpr: false });\n j = k + 1;\n } else if (src[j] === '{') {\n const close = scanBalanced(src, j);\n attrs.push({ name, raw: src.slice(j + 1, close - 1), isExpr: true });\n j = close;\n } else {\n throw new Error(`parseAttributes: bad attribute value for \"${name}\" at ${j}`);\n }\n } else {\n attrs.push({ name, raw: '', isExpr: false, shorthand: true });\n }\n }\n}\n\nfunction attrValue(a: Attr, ctx: ParseContext): unknown {\n if (a.shorthand) return true;\n if (!a.isExpr) return a.raw;\n return interpretExprValue(a.raw, ctx);\n}\n\n// ---------------------------------------------------------------------------\n// Element + children\n// ---------------------------------------------------------------------------\n\n/**\n * `base` is the absolute offset (in the original full source) of `src[0]`, so recorded\n * spans are absolute even though parsing happens on extracted substrings. It defaults\n * to 0 and is only consulted when `ctx.spans` is set (line-map mode); normal parsing\n * ignores it entirely.\n */\nexport function parseElement(src: string, i: number, ctx: ParseContext, base = 0): { node: Child; end: number } {\n i = skipWs(src, i);\n if (src[i] !== '<') throw new Error(`parseElement: expected \"<\" at ${i}`);\n const { name: tag, end: afterTag } = readTagName(src, i + 1);\n const { attrs, end: afterAttrs, selfClose } = parseAttributes(src, afterTag);\n\n let children: Child[] = [];\n let end = afterAttrs;\n if (!selfClose) {\n // Children share `src` (and therefore `base`) \u2014 only `{\u2026}`/substring re-parsing shifts it.\n const inner = parseNodes(src, afterAttrs, ctx, tag, base);\n children = inner.nodes;\n const close = src.indexOf('>', inner.end);\n end = close + 1;\n }\n return { node: elementToNode(tag, attrs, children, ctx), end };\n}\n\n/** Record an object node's absolute span when the line-map sink is active. */\nfunction recordSpan(ctx: ParseContext, node: Child, start: number, end: number): void {\n if (ctx.spans && node && typeof node === 'object') ctx.spans.set(node, { start, end });\n}\n\nexport function parseNodes(\n src: string,\n i: number,\n ctx: ParseContext,\n stopTag?: string,\n base = 0,\n): { nodes: Child[]; end: number } {\n const nodes: Child[] = [];\n let j = i;\n while (j < src.length) {\n const k = skipWs(src, j);\n if (k >= src.length) { j = k; break; }\n if (stopTag && src[k] === '<' && src[k + 1] === '/') return { nodes, end: k };\n if (src[k] === '<') {\n const { node, end } = parseElement(src, k, ctx, base);\n recordSpan(ctx, node, base + k, base + end);\n nodes.push(node);\n j = end;\n continue;\n }\n if (src[k] === '{') {\n const end = scanBalanced(src, k);\n const child = interpretChildExpr(src.slice(k + 1, end - 1), ctx, base + k + 1);\n if (child !== undefined && child !== null && child !== '') {\n // Record the whole `{\u2026}` span for the resulting node (list / if-wrapped element).\n recordSpan(ctx, child, base + k, base + end);\n nodes.push(child);\n }\n j = end;\n continue;\n }\n // text run until the next tag/expression\n let t = k;\n while (t < src.length && src[t] !== '<' && src[t] !== '{') t++;\n const text = src.slice(k, t).trim();\n if (text.length) nodes.push(text);\n j = t;\n }\n return { nodes, end: j };\n}\n\n// ---------------------------------------------------------------------------\n// Expression children: if-wrappers, list .map(), text/value\n// ---------------------------------------------------------------------------\n\nexport function interpretChildExpr(inner: string, ctx: ParseContext, base = 0): Child | undefined {\n const e = inner.trim();\n if (!e) return undefined;\n const eBase = base + leadingWs(inner);\n\n const grp = findTrailingGroup(e, '(');\n if (grp) {\n const before = e.slice(0, grp.open).trim();\n if (before.endsWith('&&')) {\n const cond = before.slice(0, -2).trim();\n const bodyRaw = grp.inner;\n const body = bodyRaw.trim();\n const bodyBase = eBase + grp.open + 1 + leadingWs(bodyRaw);\n const node = body.startsWith('<')\n ? parseElement(body, 0, ctx, bodyBase).node\n : interpretChildExpr(body, ctx, bodyBase);\n if (node && typeof node === 'object') node.if = reverseCondition(cond);\n return node;\n }\n if (before.endsWith('.map')) {\n return parseMapExpr(e, ctx, eBase);\n }\n }\n\n const val = interpretExprValue(e, ctx);\n return val as Child;\n}\n\n/** Count of leading whitespace characters (how far `s.trim()` shifts `s`'s start). */\nfunction leadingWs(s: string): number {\n return s.length - s.trimStart().length;\n}\n\nfunction parseMapExpr(e: string, ctx: ParseContext, base = 0): Node {\n const mapIdx = e.indexOf('.map(');\n const head = e.slice(0, mapIdx).trim();\n const argOpen = mapIdx + 4; // '(' of '.map('\n const argEnd = scanBalanced(e, argOpen);\n const argRaw = e.slice(argOpen + 1, argEnd - 1); // interior of `.map( \u2026 )`\n const arg = argRaw.trim(); // (item, index) => ( children )\n const argBase = base + argOpen + 1 + leadingWs(argRaw);\n\n const paramsEnd = scanBalanced(arg, 0);\n const params = splitTopLevel(arg.slice(1, paramsEnd - 1), ',').filter(Boolean);\n const itemVar = params[0];\n const afterParams = arg.slice(paramsEnd);\n const bodyGrp = findTrailingGroup(afterParams.trim(), '(');\n let children: Child[] = [];\n if (bodyGrp) {\n const childrenBase = argBase + paramsEnd + leadingWs(afterParams) + bodyGrp.open + 1;\n children = parseNodes(bodyGrp.inner, 0, ctx, undefined, childrenBase).nodes;\n }\n\n if (head.startsWith('list(')) {\n const inner = callArgsOf(head);\n const parts = splitTopLevel(inner, ',').filter(Boolean);\n const opts = parts[1] ? (parseLiteral(parts[1]) as Record<string, unknown>) : {};\n const node: Node = {\n type: 'list',\n sourceType: 'prop',\n source: `{{${parts[0]}}}`,\n ...opts,\n children,\n };\n if (itemVar && itemVar !== 'item') node.itemAs = itemVar;\n return node;\n }\n\n const binding = ctx.collectionBindings.get(head);\n const source = binding?.source ?? head;\n const node: Node = {\n type: 'list',\n sourceType: 'collection',\n source,\n ...(binding?.query ?? {}),\n children,\n };\n if (itemVar && itemVar !== singularize(source)) node.itemAs = itemVar;\n return node;\n}\n\n// ---------------------------------------------------------------------------\n// Element \u2192 node\n// ---------------------------------------------------------------------------\n\nfunction applyClass(node: Node, attrs: Attr[]): void {\n const cls = attrs.find((a) => a.name === 'class');\n if (!cls) return;\n const parsed = interpretStyleCall(cls.raw);\n if (parsed.style !== undefined) node.style = parsed.style;\n if (parsed.interactiveStyles !== undefined) node.interactiveStyles = parsed.interactiveStyles;\n if (parsed.label !== undefined) node.label = parsed.label;\n if (parsed.generateElementClass !== undefined) node.generateElementClass = parsed.generateElementClass;\n}\n\nfunction otherAttrs(attrs: Attr[], ctx: ParseContext, skip: Set<string>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const a of attrs) {\n if (skip.has(a.name)) continue;\n out[a.name] = attrValue(a, ctx);\n }\n return out;\n}\n\nfunction elementToNode(tag: string, attrs: Attr[], children: Child[], ctx: ParseContext): Node {\n // Dynamic tag: `<Tag_0 \u2026>` \u2192 an HTML node whose tag is the original `h{{size}}`.\n if (ctx.tagConsts.has(tag)) {\n const node: Node = { type: 'node', tag: ctx.tagConsts.get(tag)! };\n applyClass(node, attrs);\n const attributes = otherAttrs(attrs, ctx, new Set(['class']));\n if (Object.keys(attributes).length) node.attributes = attributes;\n if (children.length) node.children = children;\n return node;\n }\n\n if (tag === 'slot') {\n const node: Node = { type: 'slot' };\n if (children.length) node.default = children;\n return node;\n }\n\n if (tag === 'Link') {\n const node: Node = { type: 'link' };\n const href = attrs.find((a) => a.name === 'href');\n if (href) node.href = attrValue(href, ctx);\n applyClass(node, attrs);\n const rest = otherAttrs(attrs, ctx, new Set(['href', 'class']));\n if (Object.keys(rest).length) node.attributes = rest;\n if (children.length) node.children = children;\n return node;\n }\n\n if (tag === 'Embed') {\n const node: Node = { type: 'embed' };\n const html = attrs.find((a) => a.name === 'html');\n if (html) node.html = attrValue(html, ctx);\n applyClass(node, attrs);\n const rest = otherAttrs(attrs, ctx, new Set(['html', 'class']));\n if (Object.keys(rest).length) node.attributes = rest;\n return node;\n }\n\n if (tag === 'LocaleList') {\n const node: Node = { type: 'locale-list' };\n for (const a of attrs) {\n if (LOCALE_STYLE_PROPS.has(a.name) && a.isExpr && a.raw.trimStart().startsWith('style(')) {\n node[a.name] = parseLiteral(callArgsOf(a.raw));\n } else if (a.name === 'meta' && a.isExpr) {\n const meta = parseLiteral(a.raw) as Record<string, unknown>;\n if (meta.interactive !== undefined) node.interactiveStyles = meta.interactive;\n if (meta.label !== undefined) node.label = meta.label;\n if (meta.genClass !== undefined) node.generateElementClass = meta.genClass;\n } else {\n node[a.name] = attrValue(a, ctx);\n }\n }\n return node;\n }\n\n // Component instance (Capitalized, or a known imported component).\n const isComponent = /^[A-Z]/.test(tag) && !RUNTIME_TAGS.has(tag);\n if (isComponent) {\n const node: Node = { type: 'component', component: tag };\n applyClass(node, attrs);\n const props = otherAttrs(attrs, ctx, new Set(['class']));\n if (Object.keys(props).length) node.props = props;\n if (children.length) node.children = children;\n return node;\n }\n\n // HTML element.\n const node: Node = { type: 'node', tag };\n applyClass(node, attrs);\n const attributes = otherAttrs(attrs, ctx, new Set(['class']));\n if (Object.keys(attributes).length) node.attributes = attributes;\n if (children.length) node.children = children;\n return node;\n}\n", "/**\n * File orchestrator \u2014 split `---` frontmatter from body, parse both, and reassemble\n * the Meno model (a `{ component }` file or a `JSONPage`).\n */\n\nimport { parseFrontmatter } from './parseFrontmatter';\nimport { parseElement, parseNodes } from './parseBody';\nimport type { ParseContext } from './parseContext';\n\nimport type { NodeSpan } from './parseContext';\n\nexport interface ParsedFile {\n model: Record<string, unknown>;\n /** Absolute source spans per object node, only present when `collectSpans` is set. */\n spans?: Map<object, NodeSpan>;\n}\n\nexport interface ParseFileOptions {\n /** Record each node's absolute source span (for `buildAstroLineMap`). Off by default. */\n collectSpans?: boolean;\n}\n\n/** Leading-whitespace count \u2014 how far `s.trim()` shifts `s`'s start. */\nfunction leadingWs(s: string): number {\n return s.length - s.trimStart().length;\n}\n\nfunction splitFrontmatter(source: string): { code: string; body: string; bodyStart: number } {\n const m = source.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n // The body is always the suffix of `source`, so its start offset is exact.\n const body = m ? m[2] : source;\n return { code: m ? m[1] : '', body, bodyStart: source.length - body.length };\n}\n\n/** Extract the shorthand names from a `define:vars={{ a, b }}` attribute, or undefined. */\nfunction parseDefineVars(openTag: string): string[] | undefined {\n const m = openTag.match(/define:vars=\\{\\{([^}]*)\\}\\}/);\n if (!m) return undefined;\n return m[1]\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nfunction splitComponentBody(\n body: string,\n ctx: ParseContext,\n bodyStart: number,\n): { structure?: unknown; css?: string; javascript?: string; defineVars?: string[] } {\n let rest = body;\n let javascript: string | undefined;\n let defineVars: string[] | undefined;\n let css: string | undefined;\n\n // The client script is either `<script is:inline>` or `<script define:vars={{\u2026}}>`\n // (native Astro \u2014 the latter injects the listed props into the inline script).\n const scriptM = rest.match(/\\n*<script([^>]*)>\\n([\\s\\S]*?)\\n<\\/script>\\s*$/);\n if (scriptM) {\n javascript = scriptM[2];\n defineVars = parseDefineVars(scriptM[1]);\n rest = rest.slice(0, scriptM.index);\n }\n const styleM = rest.match(/\\n*<style>\\n([\\s\\S]*?)\\n<\\/style>\\s*$/);\n if (styleM) {\n css = styleM[1];\n rest = rest.slice(0, styleM.index);\n }\n\n const markup = rest.trim();\n // `rest` keeps `body`'s start, so the markup's absolute base is bodyStart + its leading ws.\n const base = bodyStart + leadingWs(rest);\n const structure = markup ? parseNodes(markup, 0, ctx, undefined, base).nodes[0] : undefined;\n return { structure, css, javascript, defineVars };\n}\n\nfunction parsePageRoot(body: string, ctx: ParseContext, bodyStart: number): unknown {\n const trimmed = body.trim();\n if (!trimmed.startsWith('<')) return undefined;\n const base = bodyStart + leadingWs(body);\n const wrapper = parseElement(trimmed, 0, ctx, base).node as Record<string, unknown>;\n const children = wrapper.children;\n return Array.isArray(children) ? children[0] : undefined;\n}\n\nexport function parseFile(source: string, opts: ParseFileOptions = {}): ParsedFile {\n const { code, body, bodyStart } = splitFrontmatter(source);\n const front = parseFrontmatter(code);\n const spans = opts.collectSpans ? new Map<object, NodeSpan>() : undefined;\n if (spans) front.ctx.spans = spans;\n\n if (front.kind === 'component') {\n const { structure, css, javascript, defineVars } = splitComponentBody(body, front.ctx, bodyStart);\n const def: Record<string, unknown> = {};\n if (front.propsInterface && Object.keys(front.propsInterface).length) {\n def.interface = front.propsInterface;\n }\n if (structure !== undefined) def.structure = structure;\n Object.assign(def, front.componentMeta);\n if (css !== undefined) def.css = css;\n if (javascript !== undefined) def.javascript = javascript;\n // `defineVars` is reconstructed from the script's `define:vars={{\u2026}}` attribute\n // (it's no longer carried in `__meno`). normalizeModel canonicalizes it.\n if (defineVars !== undefined) def.defineVars = defineVars;\n return { model: { component: def }, spans };\n }\n\n const root = parsePageRoot(body, front.ctx, bodyStart);\n const page: Record<string, unknown> = {};\n if (front.meta !== undefined) page.meta = front.meta;\n if (root !== undefined) page.root = root;\n return { model: page, spans };\n}\n", "/**\n * Canonicalization for the round-trip contract. The emitter drops content-free\n * defaults (empty styles, empty `children`, empty `meta`) and a single text child is\n * indistinguishable from a one-element array on parse. `normalizeModel` puts a model\n * into the canonical form the parser produces, so the contract is:\n *\n * parse(emit(x)) === normalizeModel(x) (exact up to normalization)\n * parse(emit(normalizeModel(x))) === normalizeModel(x) (exact on canonical input)\n *\n * The codec applies this on load, so the editor always works with canonical models.\n */\n\nimport { singularize } from 'meno-core/shared/types';\n\nfunction hasStyleContent(style: unknown): boolean {\n if (!style || typeof style !== 'object') return false;\n for (const v of Object.values(style as Record<string, unknown>)) {\n if (v === undefined || v === null) continue;\n if (typeof v === 'object') {\n if (Object.keys(v as object).length > 0) return true;\n } else {\n return true;\n }\n }\n return false;\n}\n\n/** Canonicalize a children/default list: normalize items, drop if empty, collapse a lone string. */\nfunction normalizeChildren(children: unknown): unknown {\n if (typeof children === 'string') return children;\n if (!Array.isArray(children)) return undefined;\n const items = children.map(normalizeChild);\n if (items.length === 0) return undefined;\n if (items.length === 1 && typeof items[0] === 'string') return items[0];\n return items;\n}\n\nfunction normalizeChild(child: unknown): unknown {\n return typeof child === 'string' ? child : normalizeNode(child);\n}\n\n/** Migrate legacy node types (cms-list, image) to the unified model. */\nfunction migrateLegacy(n: Record<string, unknown>): Record<string, unknown> {\n if (n.type === 'cms-list') {\n const { type, collection, style, attributes, children, ...rest } = n;\n const list: Record<string, unknown> = {\n type: 'list',\n sourceType: 'collection',\n source: collection,\n ...rest,\n };\n // Legacy cms-list children reference `{{item.*}}`, so bind the loop to `item`\n // (otherwise the migrated collection list would default to singularize(source)\n // and the generated loop var wouldn't match the children's templates).\n if (list.itemAs === undefined) list.itemAs = 'item';\n if (children !== undefined) list.children = children;\n // A cms-list bundled a styled container + repeater \u2192 split into div > list.\n if (style !== undefined || attributes !== undefined) {\n const wrapper: Record<string, unknown> = { type: 'node', tag: 'div' };\n if (style !== undefined) wrapper.style = style;\n if (attributes !== undefined) wrapper.attributes = attributes;\n wrapper.children = [list];\n return wrapper;\n }\n return list;\n }\n if (n.type === 'image') {\n const { type, src, alt, style, attributes, ...rest } = n;\n const attrs: Record<string, unknown> = { ...(attributes as object) };\n if (src !== undefined) attrs.src = src;\n if (alt !== undefined) attrs.alt = alt;\n const img: Record<string, unknown> = { type: 'node', tag: 'img', ...rest };\n if (Object.keys(attrs).length) img.attributes = attrs;\n if (style !== undefined) img.style = style;\n return img;\n }\n return n;\n}\n\nfunction normalizeNode(node: unknown): unknown {\n if (typeof node === 'string') return node;\n if (!node || typeof node !== 'object') return node;\n const out = migrateLegacy({ ...(node as Record<string, unknown>) });\n\n if ('style' in out && !hasStyleContent(out.style)) delete out.style;\n\n // Legacy HTML `props` is the old way of specifying attributes (backward-compat\n // field on `node`). Merge it into `attributes` (newer wins) and drop it.\n if (out.type === 'node' && out.props && typeof out.props === 'object') {\n out.attributes = { ...(out.props as object), ...((out.attributes as object) ?? {}) };\n delete out.props;\n }\n\n if (out.type === 'list') {\n const sourceType = (out.sourceType as string) ?? 'prop';\n // Prop-list source: bare `items` \u2261 `{{items}}` (canonical form the editor uses).\n if (sourceType !== 'collection' && typeof out.source === 'string' && !out.source.includes('{{')) {\n out.source = `{{${out.source}}}`;\n }\n // Drop a redundant `itemAs` that equals the implicit default.\n const defaultItem = sourceType === 'collection' ? singularize(String(out.source)) : 'item';\n if (out.itemAs === defaultItem) delete out.itemAs;\n }\n\n if ('children' in out) {\n const c = normalizeChildren(out.children);\n if (c === undefined) delete out.children;\n else out.children = c;\n }\n if ('default' in out) {\n const d = normalizeChildren(out.default);\n if (d === undefined) delete out.default;\n else out.default = d;\n }\n return out;\n}\n\n/**\n * Canonicalize a component's `defineVars` so round-trip is exact (mutates `comp`):\n *\n * - **Collapse \"all props\" \u2192 `true`.** A `string[]` whose set equals all interface\n * prop names (excluding `children`) becomes `true`. So model `true` \u2192 emit\n * `define:vars={{ \u2026all\u2026 }}` \u2192 parse `[\u2026all\u2026]` \u2192 normalize back to `true`. An\n * explicit list that happens to name every prop is semantically identical and is\n * canonicalized the same way (matching how the editor regenerates props on save).\n * - **Drop a meaningless `defineVars`.** With no `javascript` there is no `<script>`\n * to carry the directive, so `defineVars` round-trips as absent \u2192 drop it here.\n *\n * Idempotent: re-running over canonical output is a no-op.\n */\nfunction normalizeDefineVars(comp: Record<string, unknown>): void {\n if (comp.defineVars === undefined) return;\n\n // No script \u2192 no `define:vars` directive emitted \u2192 drop the meaningless field.\n if (!comp.javascript) {\n delete comp.defineVars;\n return;\n }\n\n if (Array.isArray(comp.defineVars)) {\n const names = comp.defineVars as string[];\n const all = Object.keys((comp.interface as Record<string, unknown>) ?? {}).filter(\n (k) => k !== 'children',\n );\n const sameSet =\n names.length === all.length && new Set(names).size === all.length && all.every((k) => names.includes(k));\n if (sameSet) comp.defineVars = true;\n }\n}\n\nexport function normalizeModel(model: unknown): unknown {\n if (!model || typeof model !== 'object') return model;\n const m = model as Record<string, unknown>;\n\n // Component file: { component: { structure, \u2026 } }\n if (m.component && typeof m.component === 'object') {\n const comp = { ...(m.component as Record<string, unknown>) };\n if ('interface' in comp && (!comp.interface || Object.keys(comp.interface as object).length === 0)) {\n delete comp.interface;\n }\n if (comp.structure !== undefined) comp.structure = normalizeNode(comp.structure);\n normalizeDefineVars(comp);\n return { ...m, component: comp };\n }\n\n // Page: { meta?, root?, \u2026 }\n const out: Record<string, unknown> = { ...m };\n if ('meta' in out && (!out.meta || Object.keys(out.meta as object).length === 0)) delete out.meta;\n if (out.root !== undefined) out.root = normalizeNode(out.root);\n return out;\n}\n", "/**\n * `.astro` line mapper \u2014 the dialect counterpart to meno-core's `buildLineMap` for JSON.\n *\n * The Studio editor and the `.meno/selection.json` writer locate a selected node by a\n * `filePath:lineStart-lineEnd` pointer. For JSON projects the line range comes from\n * `buildLineMap(jsonText)`. For `.astro` projects the on-disk file bears no relation to\n * the JSON-stringified model, so we recover ranges from the `.astro` source directly:\n * parse it once with source-span collection on, then walk the node tree assigning the\n * SAME path keys meno-core's mapper uses (`\"\"` = root, `\"0\"`/`\"1,2\"` = child index\n * chains, following only `children` arrays). Keys therefore line up 1:1 with the editor's\n * selection paths, so a selection resolves to the right `.astro` lines.\n *\n * Built from the raw parsed model (pre-normalize), which for `.astro` input has the same\n * `children` shape the editor indexes into \u2014 the only divergence (a lone string child\n * collapsing array\u2192string) adds harmless extra keys the editor never requests.\n */\n\nimport { parseFile } from './parse/parseFile';\nimport type { NodeSpan } from './parse/parseContext';\n\nexport interface LineRange {\n startLine: number;\n endLine: number;\n}\n\nexport type LineMap = Map<string, LineRange>;\n\ntype Node = Record<string, unknown>;\n\n/** Per-character line-number lookup (1-based), matching meno-core's jsonLineMapper. */\nfunction buildCharToLine(source: string): number[] {\n const charToLine = new Array<number>(source.length);\n let line = 1;\n for (let i = 0; i < source.length; i++) {\n charToLine[i] = line;\n if (source[i] === '\\n') line++;\n }\n return charToLine;\n}\n\n/** The tracked root node of a parsed model: a page's `root` or a component's `structure`. */\nfunction rootNode(model: Record<string, unknown>): Node | undefined {\n const component = model.component as Record<string, unknown> | undefined;\n const candidate = component ? component.structure : model.root;\n return candidate && typeof candidate === 'object' ? (candidate as Node) : undefined;\n}\n\n/**\n * Build a `path-key \u2192 line range` map for an `.astro` source, keyed identically to\n * meno-core's `buildLineMap` so selection/copy line lookups work unchanged. Returns an\n * empty map for unparseable input (best-effort, never throws).\n */\nexport function buildAstroLineMap(source: string): LineMap {\n const lineMap: LineMap = new Map();\n try {\n const { model, spans } = parseFile(source, { collectSpans: true });\n if (!spans) return lineMap;\n const root = rootNode(model);\n if (!root) return lineMap;\n\n const charToLine = buildCharToLine(source);\n const toRange = (span: NodeSpan): LineRange => ({\n startLine: charToLine[span.start] ?? 1,\n endLine: charToLine[span.end - 1] ?? charToLine[span.start] ?? 1,\n });\n\n const walk = (node: Node, key: string): void => {\n const span = spans.get(node);\n if (span) lineMap.set(key, toRange(span));\n const children = node.children;\n if (Array.isArray(children)) {\n children.forEach((child, i) => {\n if (child && typeof child === 'object') {\n walk(child as Node, key === '' ? String(i) : `${key},${i}`);\n }\n });\n }\n };\n walk(root, '');\n } catch {\n // Best-effort: a malformed file yields an empty map rather than breaking the editor.\n }\n return lineMap;\n}\n", "/**\n * meno-astro/dialect \u2014 the editor/build-only codec between the Meno in-memory\n * model and the round-trippable `.astro` dialect.\n *\n * This module is NOT shipped to generated projects' runtime; it is used by the\n * Studio editor (read/save) and the build/convert tooling.\n *\n * emit(model) -> .astro source (deterministic, git-stable)\n * parse(source) -> { model, regions }\n *\n * Round-trip contract:\n * - parse(emit(x)) === x (exact: every payload read back verbatim)\n * - emit(parse(y)) === y (stable up to canonical formatting)\n *\n * Bodies are implemented in Phase 1 (emit) and Phase 2 (parse). This file pins\n * the public types/signatures so later phases and downstream callers compile\n * against a stable contract.\n */\n\nimport type { JSONPage, StructuredComponentDefinition } from 'meno-core/shared/types';\nimport { emitPage } from './emit/emitPage';\nimport { emitComponent } from './emit/emitComponent';\nimport { parseFile } from './parse/parseFile';\nimport { normalizeModel } from './normalize';\nimport type { EmitOptions } from './emit/emitContext';\n\nexport type { EmitOptions };\n\nexport { normalizeModel };\nexport { buildAstroLineMap, type LineMap, type LineRange } from './lineMap';\n\n/** The on-disk component file shape: `{ component: StructuredComponentDefinition }`. */\nexport interface ComponentFile {\n component: StructuredComponentDefinition;\n}\n\n/** A page or a component definition \u2014 the two top-level things a `.astro` file maps to. */\nexport type DialectModel = JSONPage | StructuredComponentDefinition | ComponentFile;\n\n/**\n * A tracked span of the source file. The parser returns these so the emitter can\n * re-emit non-dialect / hand-written regions verbatim (escape hatch) and so editing\n * one section never reformats an untouched region.\n */\nexport interface MenoRegion {\n /** Stable id of the model node this region corresponds to, if any. */\n nodeId?: string;\n /**\n * - `editable`: in-dialect, fully round-tripped.\n * - `rawClass`: foreign `class=\"\u2026\"` captured as read-only passthrough.\n * - `verbatim`: arbitrary Astro/JS preserved byte-for-byte.\n */\n kind: 'editable' | 'rawClass' | 'verbatim';\n /** Byte offset start (inclusive) in the source. */\n start: number;\n /** Byte offset end (exclusive) in the source. */\n end: number;\n}\n\nexport interface ParseResult {\n model: DialectModel;\n regions: MenoRegion[];\n}\n\n/** Serialize the Meno model to deterministic `.astro` dialect source. */\nexport function emit(model: DialectModel, opts?: EmitOptions): string {\n // Canonicalize first (migrate legacy types, drop empties) so emit accepts raw models\n // and always produces canonical .astro. Symmetric with parse() normalizing its output.\n const m = normalizeModel(model) as Record<string, any>;\n if (m && typeof m === 'object') {\n // On-disk component file: { component: { \u2026 } }\n if (m.component && typeof m.component === 'object') return emitComponent(m.component, opts);\n // Raw component definition (structure/interface/js/css at the top level).\n if (\n m.structure !== undefined ||\n m.interface !== undefined ||\n m.javascript !== undefined ||\n m.css !== undefined\n ) {\n return emitComponent(m as StructuredComponentDefinition, opts);\n }\n }\n // Otherwise it's a page (meta / root / components).\n return emitPage(m as JSONPage, opts);\n}\n\n/** Parse `.astro` dialect source back into the Meno model (+ tracked regions). */\nexport function parse(source: string): ParseResult {\n const { model } = parseFile(source);\n // Output is canonicalized so the editor always sees a normalized model.\n // Region tracking (escape hatches for hand-edited / non-dialect spans) lands next.\n return { model: normalizeModel(model) as DialectModel, regions: [] };\n}\n"],
5
+ "mappings": ";;;;;AAgDO,SAAS,kBAAkB,QAAQ,IAAiB;AACzD,SAAO;AAAA,IACL,YAAY,oBAAI,IAAI;AAAA,IACpB,SAAS,oBAAI,IAAI;AAAA,IACjB,mBAAmB,oBAAI,IAAI;AAAA,IAC3B,mBAAmB,CAAC;AAAA,IACpB,UAAU,CAAC;AAAA,IACX,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,cAAc;AAAA,IACd,YAAY;AAAA,IACZ;AAAA,EACF;AACF;AAkBO,SAAS,wBAAwB,SAAiB,QAAwB;AAC/E,QAAM,IAAI,UAAU,QAAQ,MAAM,GAAG,EAAE,OAAO,OAAO,IAAI,CAAC;AAC1D,QAAM,IAAI,OAAO,MAAM,GAAG,EAAE,OAAO,OAAO;AAC1C,MAAI,IAAI;AACR,SAAO,IAAI,EAAE,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG;AACtD,QAAM,QAAQ,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,EAAE,KAAK,IAAI,GAAG,GAAG,EAAE,MAAM,CAAC,CAAC;AAC/D,QAAM,MAAM,MAAM,KAAK,GAAG;AAC1B,SAAO,IAAI,WAAW,GAAG,IAAI,MAAM,OAAO;AAC5C;AAGO,SAAS,YAAY,KAAkB,MAAsB;AAClE,MAAI,QAAQ,IAAI,IAAI;AACpB,SAAO;AACT;AAGO,SAAS,qBAAqB,KAAkB,MAAsB;AAC3E,MAAI,kBAAkB,IAAI,IAAI;AAC9B,SAAO;AACT;;;ACjFA,IAAM,gBAAgB;AACtB,IAAM,cAAc;AAEpB,IAAM,WAAW;AAGV,SAAS,aAAa,KAAsB;AACjD,SAAO,SAAS,KAAK,GAAG;AAC1B;AAEA,SAAS,UAAU,KAAqB;AACtC,SAAO,aAAa,GAAG,IAAI,MAAM,KAAK,UAAU,GAAG;AACrD;AAEA,SAAS,aAAa,OAAuB;AAE3C,SAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,SAAS,aAAa,OAAuB;AAC3C,SAAO,OAAO,SAAS,KAAK,IAAI,OAAO,KAAK,IAAI;AAClD;AAGA,SAAS,eAAe,KAAwD;AAC9E,SAAO,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS;AAC9D;AAGA,SAAS,aAAa,OAAwB;AAC5C,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,UAAU,OAAW,QAAO;AAChC,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AACH,aAAO,aAAa,KAAK;AAAA,IAC3B,KAAK;AACH,aAAO,aAAa,KAAK;AAAA,IAC3B,KAAK;AACH,aAAO,OAAO,KAAK;AAAA,IACrB,KAAK,UAAU;AACb,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,eAAO,MAAM,MAAM,IAAI,YAAY,EAAE,KAAK,IAAI,IAAI;AAAA,MACpD;AACA,YAAM,UAAU,eAAe,KAAgC;AAC/D,UAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,aACE,OACA,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,EAAE,EAAE,KAAK,IAAI,IACxE;AAAA,IAEJ;AAAA,IACA;AAEE,aAAO;AAAA,EACX;AACF;AAqBO,SAAS,iBAAiB,OAAgB,OAAyB,CAAC,GAAW;AACpF,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,aAAa,KAAK,UAAU;AAClC,QAAM,WAAW,KAAK,YAAY;AAOlC,QAAM,SAAS,CAAC,GAAY,YAAoBA,cAA6B;AAE3E,QAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,QAAO,aAAa,CAAC;AAE9D,UAAM,SAAS,aAAa,CAAC;AAC7B,QAAIA,YAAW,OAAO,UAAU,MAAO,QAAO;AAE9C,UAAMC,OAAM,IAAI,OAAO,aAAa,WAAW;AAC/C,UAAM,WAAW,IAAI,OAAO,UAAU;AAEtC,QAAI,MAAM,QAAQ,CAAC,GAAG;AACpB,UAAI,EAAE,WAAW,EAAG,QAAO;AAC3B,YAAM,QAAQ,EAAE;AAAA,QACd,CAAC,SAASA,OAAM,OAAO,MAAM,aAAa,aAAa,aAAa,WAAW;AAAA,MACjF;AACA,aAAO,QAAQ,MAAM,KAAK,KAAK,IAAI,OAAO,WAAW;AAAA,IACvD;AAEA,UAAM,UAAU,eAAe,CAA4B;AAC3D,QAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,UAAM,QAAQ,QAAQ,IAAI,CAAC,CAAC,GAAG,GAAG,MAAM;AACtC,YAAM,SAASA,OAAM,UAAU,CAAC,IAAI;AACpC,aAAO,SAAS,OAAO,KAAK,aAAa,aAAa,OAAO,MAAM;AAAA,IACrE,CAAC;AACD,WAAO,QAAQ,MAAM,KAAK,KAAK,IAAI,OAAO,WAAW;AAAA,EACvD;AAEA,SAAO,OAAO,OAAO,YAAY,QAAQ;AAC3C;;;AC7GA,IAAM,SAAS;AAEf,SAAS,IAAI,GAAmB;AAC9B,SAAO,IAAI,OAAO,CAAC;AACrB;AAGA,SAAS,MAAM,OAAe,QAAwB;AACpD,QAAM,IAAI,IAAI,MAAM;AACpB,SAAO,MACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAU,KAAK,SAAS,IAAI,OAAO,IAAK,EAC7C,KAAK,IAAI;AACd;AAMA,IAAM,cAAc;AAEb,SAAS,YAAY,GAAoB;AAC9C,SAAO,mBAAmB,KAAK,CAAC;AAClC;AAGA,SAAS,eAAe,GAAmB;AACzC,SAAO,EAAE,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,EAAE,QAAQ,SAAS,MAAM;AAC9E;AAOO,SAAS,eAAe,GAAmB;AAChD,QAAM,UAAU,CAAC,GAAG,EAAE,SAAS,WAAW,CAAC;AAE3C,MAAI,QAAQ,WAAW,KAAK,QAAQ,CAAC,EAAE,UAAU,KAAK,QAAQ,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,QAAQ;AACvF,WAAO,QAAQ,CAAC,EAAE,CAAC,EAAE,KAAK;AAAA,EAC5B;AAEA,MAAI,MAAM;AACV,MAAI,OAAO;AACX,aAAW,KAAK,SAAS;AACvB,WAAO,eAAe,EAAE,MAAM,MAAM,EAAE,KAAM,CAAC;AAC7C,WAAO,OAAO,EAAE,CAAC,EAAE,KAAK,IAAI;AAC5B,WAAO,EAAE,QAAS,EAAE,CAAC,EAAE;AAAA,EACzB;AACA,SAAO,eAAe,EAAE,MAAM,IAAI,CAAC;AACnC,SAAO,MAAM,MAAM;AACrB;AAGA,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAU;AAAA,EACxE;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAa;AACxC,CAAC;AASM,SAAS,oBAAoB,MAAe,eAA2C;AAC5F,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAS,CAAC,SACd,KAAK,KAAK,EAAE,MAAM,mBAAmB,IAAI,CAAC;AAE5C,QAAM,OAAO,CAAC,MAAe,UAA6B;AACxD,QAAI,QAAQ,KAAM;AAClB,QAAI,OAAO,SAAS,UAAU;AAC5B,iBAAW,KAAK,KAAK,SAAS,WAAW,GAAG;AAC1C,cAAM,IAAI,OAAO,EAAE,CAAC,CAAC;AACrB,YAAI,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,IAAI,CAAC,EAAG,MAAK,IAAI,CAAC;AAAA,MACjE;AACA;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,iBAAW,KAAK,KAAM,MAAK,GAAG,KAAK;AACnC;AAAA,IACF;AACA,QAAI,OAAO,SAAS,SAAU;AAC9B,UAAM,MAAM;AAGZ,QAAI,aAAa;AACjB,QAAI,IAAI,SAAS,QAAQ;AACvB,YAAM,UAAW,IAAI,WAAsB,IAAI,eAAe,eAAe,YAAY,IAAI,MAAgB,IAAI;AACjH,mBAAa,IAAI,IAAI,KAAK,EAAE,IAAI,OAAO,EAAE,IAAI,GAAG,OAAO,OAAO;AAAA,IAChE;AACA,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AACxC,WAAK,GAAG,MAAM,cAAc,MAAM,YAAY,aAAa,KAAK;AAAA,IAClE;AAAA,EACF;AAEA,OAAK,MAAM,IAAI,IAAI,aAAa,CAAC;AACjC,SAAO,CAAC,GAAG,IAAI;AACjB;AAEA,SAAS,YAAY,GAA0C;AAC7D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAS,EAAU,UAAU;AACrE;AAOA,SAAS,SAAS,MAAc,OAAgB,KAA0B;AACxE,MAAI,YAAY,KAAK,GAAG;AACtB,gBAAY,KAAK,MAAM;AACvB,WAAO,GAAG,IAAI,UAAU,iBAAiB,OAAO,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC,CAAC;AAAA,EACvF;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,YAAY,KAAK,EAAG,QAAO,GAAG,IAAI,KAAK,eAAe,KAAK,CAAC;AAChE,QAAI,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,SAAS,IAAI,EAAG,QAAO,GAAG,IAAI,KAAK,KAAK;AAC3E,WAAO,GAAG,IAAI,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,EAC1C;AACA,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AAC3D,WAAO,GAAG,IAAI,KAAK,KAAK;AAAA,EAC1B;AACA,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO,GAAG,IAAI;AAEzD,SAAO,GAAG,IAAI,KAAK,iBAAiB,OAAO,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC,CAAC;AAClF;AAMA,SAAS,cAAc,MAAY,KAAkB,WAAoD;AACvG,QAAM,OAAgC,EAAE,GAAG,UAAU;AACrD,MAAI,KAAK,sBAAsB,OAAW,MAAK,cAAc,KAAK;AAClE,MAAI,KAAK,UAAU,OAAW,MAAK,QAAQ,KAAK;AAChD,MAAI,KAAK,yBAAyB,OAAW,MAAK,WAAW,KAAK;AAElE,QAAM,WAAW,gBAAgB,KAAK,KAAK;AAC3C,QAAM,UAAU,OAAO,KAAK,IAAI,EAAE,SAAS;AAC3C,MAAI,CAAC,YAAY,CAAC,QAAS,QAAO;AAElC,cAAY,KAAK,OAAO;AACxB,QAAM,WAAW,iBAAiB,KAAK,SAAS,CAAC,GAAG,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC;AAIxF,QAAM,WAAW,IAAI;AACrB,MAAI,CAAC,QAAS,QAAO,WAAW,gBAAgB,QAAQ,KAAK,QAAQ,OAAO,gBAAgB,QAAQ;AACpG,QAAM,UAAU,iBAAiB,MAAM,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC;AAC3E,SAAO,gBAAgB,QAAQ,KAAK,YAAY,WAAW,KAAK,OAAO;AACzE;AAGA,SAAS,gBAAgB,OAAyB;AAChD,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,aAAW,KAAK,OAAO,OAAO,KAAgC,GAAG;AAC/D,QAAI,MAAM,UAAa,MAAM,KAAM;AACnC,QAAI,OAAO,MAAM,UAAU;AACzB,UAAI,OAAO,KAAK,CAAW,EAAE,SAAS,EAAG,QAAO;AAAA,IAClD,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,eAAe,MAAY,KAA4B;AAC9D,MAAI,CAAC,KAAK,cAAc,OAAO,KAAK,eAAe,SAAU,QAAO,CAAC;AACrE,SAAO,OAAO,QAAQ,KAAK,UAAU,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,SAAS,GAAG,GAAG,GAAG,CAAC;AAC5E;AAMA,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAC5D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AACvC,CAAC;AAGD,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAe;AAAA,EAAiB;AAAA,EAAY;AAAA,EAC1D;AAAA,EAAS;AAAA,EAAa;AAAA,EAAmB;AAAA,EAAkB;AAAA,EAC3D;AAAA,EAAqB;AAAA,EAAS;AAChC,CAAC;AAQD,SAAS,cAAc,MAAc,YAAY,OAAe;AAC9D,MAAI,YAAY,IAAI,EAAG,QAAO,IAAI,eAAe,IAAI,CAAC;AACtD,QAAM,UAAU,CAAC,aAAa,KAAK,SAAS,KAAK,SAAS,KAAK,KAAK,KAAK,CAAC,SAAS,KAAK,IAAI;AAC5F,SAAO,UAAU,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC;AAClD;AAGA,SAAS,iBAAiB,UAAmB,KAA4B;AACvE,MAAI,aAAa,UAAa,aAAa,KAAM,QAAO,CAAC;AACzD,MAAI,OAAO,aAAa,UAAU;AAChC,WAAO,SAAS,SAAS,CAAC,cAAc,QAAQ,CAAC,IAAI,CAAC;AAAA,EACxD;AACA,MAAI,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO,CAAC;AACtC,QAAM,QAAQ,SAAS,SAAS;AAChC,SAAO,SAAS;AAAA,IAAI,CAAC,UACnB,OAAO,UAAU,WACb,cAAc,OAAO,KAAK,IAC1B,WAAW,WAAW,OAAe,GAAG,GAAG,CAAC;AAAA,EAClD;AACF;AAMA,SAAS,eAAe,KAAa,OAAiB,aAAuB,YAAY,OAAe;AACtG,QAAM,UAAU,MAAM,SAAS,MAAM,MAAM,KAAK,GAAG,IAAI;AACvD,MAAI,aAAa,YAAY,WAAW,GAAG;AACzC,WAAO,IAAI,GAAG,GAAG,OAAO;AAAA,EAC1B;AACA,MAAI,YAAY,WAAW,KAAK,CAAC,YAAY,CAAC,EAAE,SAAS,IAAI,GAAG;AAC9D,WAAO,IAAI,GAAG,GAAG,OAAO,IAAI,YAAY,CAAC,CAAC,KAAK,GAAG;AAAA,EACpD;AACA,QAAM,QAAQ,YAAY,IAAI,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI;AAChE,SAAO,IAAI,GAAG,GAAG,OAAO;AAAA,EAAM,KAAK;AAAA,IAAO,GAAG;AAC/C;AAMA,SAAS,WAAW,MAAY,KAA4B;AAC1D,MAAI,MAAM,KAAK;AAEf,MAAI,OAAO,QAAQ,YAAY,YAAY,GAAG,GAAG;AAC/C,UAAM,UAAU,OAAO,IAAI,YAAY;AACvC,QAAI,kBAAkB,KAAK,SAAS,OAAO,MAAM,qBAAqB,GAAG,CAAC,GAAG;AAC7E,UAAM;AAAA,EACR;AACA,QAAM,QAAQ,CAAC,cAAc,MAAM,GAAG,GAAG,GAAG,eAAe,MAAM,GAAG,CAAC,EAAE,OAAO,OAAO;AACrF,QAAM,SAAS,cAAc,IAAI,OAAO,KAAK,GAAG,EAAE,YAAY,CAAC;AAC/D,QAAM,cAAc,SAAS,CAAC,IAAI,iBAAiB,KAAK,UAAU,GAAG;AACrE,SAAO,EAAE,MAAM,WAAW,QAAQ,eAAe,KAAK,OAAO,aAAa,MAAM,EAAE;AACpF;AAGA,SAAS,qBAAqB,KAAqB;AACjD,QAAM,OAAO,IAAI,QAAQ,aAAa,CAAC,IAAI,MAAM,OAAO,OAAO,CAAC,EAAE,KAAK,IAAI,GAAG;AAC9E,SAAO,MAAM,OAAO;AACtB;AAEA,SAAS,wBAAwB,MAAY,KAA4B;AACvE,QAAM,MAAM,mBAAmB,KAAK,SAAS;AAC7C,MAAI,WAAW,IAAI,KAAK,SAAS;AACjC,QAAM,QAAkB,CAAC;AACzB,QAAM,gBAAgB,KAAK,SAAS,OAAO,KAAK,UAAU,WAAY,KAAK,QAAoC,CAAC;AAChH,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,aAAa,EAAG,OAAM,KAAK,SAAS,GAAG,GAAG,GAAG,CAAC;AAMlF,MAAI,OAAO,KAAK,aAAa,EAAE,WAAW,GAAG;AAC3C,eAAW,KAAK,IAAI,SAAU,OAAM,KAAK,GAAG,CAAC,KAAK,CAAC,GAAG;AAAA,EACxD;AACA,QAAM,MAAM,cAAc,MAAM,KAAK,gBAAgB,KAAK,KAAK,IAAI,EAAE,UAAU,KAAK,IAAI,MAAS;AACjG,MAAI,IAAK,OAAM,KAAK,GAAG;AACvB,QAAM,cAAc,iBAAiB,KAAK,UAAU,GAAG;AACvD,SAAO,EAAE,MAAM,WAAW,QAAQ,eAAe,KAAK,OAAO,WAAW,EAAE;AAC5E;AAEA,SAAS,WAAW,MAAY,KAA4B;AAC1D,QAAM,MAAM,KAAK;AACjB,MAAI,QAAQ,OAAW,QAAO,EAAE,MAAM,WAAW,QAAQ,WAAW;AACpE,QAAM,cAAc,iBAAiB,KAAK,GAAG;AAC7C,SAAO,EAAE,MAAM,WAAW,QAAQ,eAAe,QAAQ,CAAC,GAAG,WAAW,EAAE;AAC5E;AAEA,SAAS,WAAW,MAAY,KAA4B;AAC1D,uBAAqB,KAAK,MAAM;AAChC,QAAM,QAAkB,CAAC,SAAS,KAAK,MAAM,GAAG,CAAC;AACjD,QAAM,MAAM,cAAc,MAAM,GAAG;AACnC,MAAI,IAAK,OAAM,KAAK,GAAG;AACvB,QAAM,KAAK,GAAG,eAAe,MAAM,GAAG,CAAC;AACvC,QAAM,cAAc,iBAAiB,KAAK,UAAU,GAAG;AACvD,SAAO,EAAE,MAAM,WAAW,QAAQ,eAAe,QAAQ,MAAM,OAAO,OAAO,GAAG,WAAW,EAAE;AAC/F;AAEA,SAAS,SAAS,MAAe,KAA0B;AACzD,MAAI,OAAO,SAAS,UAAU;AAC5B,QAAI,YAAY,IAAI,EAAG,QAAO,SAAS,eAAe,IAAI,CAAC;AAC3D,WAAO,SAAS,IAAI;AAAA,EACtB;AAEA,MAAI,YAAY,IAAI,GAAG;AACrB,gBAAY,KAAK,MAAM;AACvB,WAAO,cAAc,iBAAiB,MAAM,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC,CAAC;AAAA,EACnF;AACA,cAAY,KAAK,MAAM;AAGvB,QAAM,UAAU,iBAAiB,MAAM,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC;AAC3E,SAAO,IAAI,WAAW,cAAc,OAAO,KAAK,IAAI,QAAQ,OAAO,cAAc,OAAO;AAC1F;AAEA,SAAS,YAAY,MAAY,KAA4B;AAC3D,uBAAqB,KAAK,OAAO;AACjC,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,KAAK,SAAS,UAAU;AACjC,QAAI,KAAK,KAAK,SAAS,IAAI,GAAG;AAG5B,YAAM,OAAO,UAAU,IAAI,cAAc;AACzC,UAAI,kBAAkB,KAAK,SAAS,IAAI,QAAQ,eAAe,KAAK,IAAI,CAAC,KAAK;AAC9E,YAAM,KAAK,SAAS,IAAI,GAAG;AAAA,IAC7B,OAAO;AACL,YAAM,KAAK,WAAW,eAAe,KAAK,IAAI,CAAC,KAAK;AAAA,IACtD;AAAA,EACF,OAAO;AACL,gBAAY,KAAK,WAAW;AAE5B,UAAM,UAAU,iBAAiB,KAAK,MAAM,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC;AAChF,UAAM;AAAA,MACJ,IAAI,WAAW,mBAAmB,OAAO,KAAK,IAAI,QAAQ,OAAO,mBAAmB,OAAO;AAAA,IAC7F;AAAA,EACF;AACA,QAAM,MAAM,cAAc,MAAM,GAAG;AACnC,MAAI,IAAK,OAAM,KAAK,GAAG;AACvB,QAAM,KAAK,GAAG,eAAe,MAAM,GAAG,CAAC;AACvC,SAAO,EAAE,MAAM,WAAW,QAAQ,eAAe,SAAS,OAAO,CAAC,GAAG,IAAI,EAAE;AAC7E;AAEA,SAAS,iBAAiB,MAAY,KAA4B;AAChE,uBAAqB,KAAK,YAAY;AACtC,QAAM,QAAkB,CAAC;AACzB,QAAM,YAAY,CAAC,eAAe,iBAAiB,UAAU;AAC7D,aAAW,KAAK,UAAW,KAAI,KAAK,CAAC,MAAM,OAAW,OAAM,KAAK,SAAS,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;AAC1F,MAAI,KAAK,gBAAgB,OAAW,OAAM,KAAK,SAAS,eAAe,KAAK,aAAa,GAAG,CAAC;AAC7F,QAAM,aAAa,CAAC,SAAS,aAAa,mBAAmB,kBAAkB,WAAW;AAC1F,aAAW,MAAM,YAAY;AAC3B,QAAI,gBAAgB,KAAK,EAAE,CAAC,GAAG;AAC7B,kBAAY,KAAK,OAAO;AACxB,YAAM,KAAK,GAAG,EAAE,WAAW,iBAAiB,KAAK,EAAE,GAAG,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC,CAAC,IAAI;AAAA,IACjG;AAAA,EACF;AACA,MAAI,KAAK,sBAAsB,UAAa,KAAK,UAAU,UAAa,KAAK,yBAAyB,QAAW;AAC/G,UAAM,OAAgC,CAAC;AACvC,QAAI,KAAK,sBAAsB,OAAW,MAAK,cAAc,KAAK;AAClE,QAAI,KAAK,UAAU,OAAW,MAAK,QAAQ,KAAK;AAChD,QAAI,KAAK,yBAAyB,OAAW,MAAK,WAAW,KAAK;AAClE,UAAM,KAAK,SAAS,iBAAiB,MAAM,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC,CAAC,GAAG;AAAA,EACrF;AAEA,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,GAAG;AACzC,QAAI,kBAAkB,IAAI,CAAC,EAAG;AAC9B,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,OAAO,MAAM,WAAW;AAC5E,YAAM,KAAK,SAAS,GAAG,GAAG,GAAG,CAAC;AAAA,IAChC;AAAA,EACF;AACA,SAAO,EAAE,MAAM,WAAW,QAAQ,eAAe,cAAc,OAAO,CAAC,GAAG,IAAI,EAAE;AAClF;AAEA,SAAS,WAAW,MAAY,KAA4B;AAC1D,QAAM,aAAa,KAAK,cAAc;AAItC,QAAM,UAAU,KAAK,WAAW,eAAe,eAAe,YAAY,KAAK,MAAM,IAAI;AACzF,QAAM,WAAW,GAAG,OAAO;AAE3B,MAAI,SAAS,KAAK,OAAO;AACzB,QAAM,cAAc,iBAAiB,KAAK,UAAU,GAAG;AACvD,MAAI,SAAS,IAAI;AACjB,QAAM,mBAAmB,YAAY,IAAI,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI;AAE3E,MAAI,eAAe,cAAc;AAC/B,gBAAY,KAAK,mBAAmB;AACpC,QAAI,kBAAkB;AACtB,UAAM,QAAQ,iBAAiB,MAAM,KAAK,CAAC,UAAU,QAAQ,SAAS,UAAU,SAAS,sBAAsB,cAAc,CAAC;AAC9H,UAAM,UAAU,cAAc,KAAK,GAAG,cAAc,KAAK,MAAM,CAAC,MAAM;AACtE,QAAI,kBAAkB;AAAA,MACpB,SAAS,OAAO,8BAA8B,KAAK,UAAU,KAAK,MAAM,CAAC,GAAG,QAAQ,OAAO,QAAQ,EAAE;AAAA,IACvG;AACA,UAAMC,QAAO,GAAG,OAAO,SAAS,OAAO,KAAK,QAAQ;AAAA,EAAW,gBAAgB;AAAA;AAC/E,WAAO,EAAE,MAAM,QAAQ,MAAAA,MAAK;AAAA,EAC9B;AAGA,cAAY,KAAK,MAAM;AACvB,QAAM,aACJ,OAAO,KAAK,WAAW,YAAY,YAAY,KAAK,MAAM,IACtD,eAAe,KAAK,MAAM,IAC1B,cAAc,OAAO,KAAK,MAAM,CAAC;AACvC,QAAM,OAAO,iBAAiB,MAAM,KAAK,CAAC,SAAS,QAAQ,CAAC;AAC5D,QAAM,WAAW,OAAO,QAAQ,UAAU,KAAK,IAAI,MAAM,QAAQ,UAAU;AAC3E,QAAM,OAAO,GAAG,QAAQ,SAAS,OAAO,KAAK,QAAQ;AAAA,EAAW,gBAAgB;AAAA;AAChF,SAAO,EAAE,MAAM,QAAQ,KAAK;AAC9B;AAGA,SAAS,iBAAiB,MAAY,KAAkB,MAAwB;AAC9E,QAAM,MAA+B,CAAC;AACtC,aAAW,KAAK,KAAM,KAAI,KAAK,CAAC,MAAM,OAAW,KAAI,CAAC,IAAI,KAAK,CAAC;AAChE,MAAI,OAAO,KAAK,GAAG,EAAE,WAAW,EAAG,QAAO;AAC1C,SAAO,iBAAiB,KAAK,EAAE,QAAQ,QAAQ,OAAO,IAAI,MAAM,CAAC;AACnE;AAEA,SAAS,cAAc,KAAkB,MAAsB;AAC7D,QAAM,WAAW,IAAI,kBAAkB,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,IAAI,GAAG,CAAC;AACjF,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,GAAG,IAAI,IAAI,IAAI,aAAa;AACrC;AAEA,SAAS,cAAc,GAAmB;AACxC,SAAO,qBAAqB,KAAK,CAAC,IAAI,IAAI,EAAE,QAAQ,mBAAmB,GAAG;AAC5E;AAGO,SAAS,mBAAmB,MAAsB;AACvD,QAAM,UAAU,KAAK,QAAQ,mBAAmB,EAAE;AAClD,SAAO,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC;AAC1D;AAMO,SAAS,WAAW,MAAY,KAA4B;AACjE,MAAI;AACJ,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AAAQ,iBAAW,WAAW,MAAM,GAAG;AAAG;AAAA,IAC/C,KAAK;AAAa,iBAAW,wBAAwB,MAAM,GAAG;AAAG;AAAA,IACjE,KAAK;AAAQ,iBAAW,WAAW,MAAM,GAAG;AAAG;AAAA,IAC/C,KAAK;AAAQ,iBAAW,WAAW,MAAM,GAAG;AAAG;AAAA,IAC/C,KAAK;AAAS,iBAAW,YAAY,MAAM,GAAG;AAAG;AAAA,IACjD,KAAK;AAAe,iBAAW,iBAAiB,MAAM,GAAG;AAAG;AAAA,IAC5D,KAAK;AAAQ,iBAAW,WAAW,MAAM,GAAG;AAAG;AAAA,IAC/C;AAEE,iBAAW,EAAE,MAAM,WAAW,QAAQ,oBAAoB,KAAK,UAAU,KAAK,IAAI,CAAC,OAAO;AAAA,EAC9F;AACA,SAAO,QAAQ,MAAM,QAAQ;AAC/B;AAGA,SAAS,QAAQ,MAAY,UAA8B;AACzD,MAAI,KAAK,OAAO,UAAa,KAAK,OAAO,KAAM,QAAO;AACtD,QAAM,OAAO,gBAAgB,KAAK,EAAE;AACpC,MAAI,SAAS,SAAS,WAAW;AAC/B,WAAO,EAAE,MAAM,QAAQ,MAAM,GAAG,IAAI;AAAA,EAAU,MAAM,SAAS,QAAQ,MAAM,CAAC;AAAA,GAAM;AAAA,EACpF;AACA,SAAO,EAAE,MAAM,QAAQ,MAAM,GAAG,IAAI,QAAQ,SAAS,IAAI,IAAI;AAC/D;AAEA,SAAS,gBAAgB,MAAuB;AAC9C,MAAI,SAAS,MAAO,QAAO;AAC3B,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,SAAS,SAAU,QAAO,YAAY,IAAI,IAAI,eAAe,IAAI,IAAI;AAEhF,SAAO,QAAQ,iBAAiB,IAAI,CAAC;AACvC;AAGO,SAAS,WAAW,UAAoB,QAAwB;AACrE,MAAI,SAAS,SAAS,UAAW,QAAO,MAAM,SAAS,QAAQ,MAAM;AACrE,SAAO,MAAM,IAAI,SAAS,IAAI,KAAK,MAAM;AAC3C;AAGO,SAAS,SAAS,MAAqB,KAAkB,QAAwB;AACtF,MAAI,OAAO,SAAS,SAAU,QAAO,MAAM,cAAc,IAAI,GAAG,MAAM;AACtE,SAAO,WAAW,WAAW,MAAM,GAAG,GAAG,MAAM;AACjD;;;AC9dO,SAAS,iBAAiB,KAAkB,MAA+B;AAChF,QAAM,QAAkB,CAAC;AACzB,QAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK;AACxD,MAAI,MAAM,OAAQ,OAAM,KAAK,iBAAiB,MAAM,KAAK,IAAI,CAAC,uBAAuB;AACrF,MAAI,IAAI,QAAQ,MAAM;AACpB,UAAM,KAAK,YAAY,CAAC,GAAG,IAAI,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,uBAAuB;AAAA,EAClF;AACA,MAAI,IAAI,kBAAkB,MAAM;AAC9B,UAAM,KAAK,YAAY,CAAC,GAAG,IAAI,iBAAiB,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,kCAAkC;AAAA,EACvG;AACA,aAAW,QAAQ,CAAC,GAAG,IAAI,UAAU,EAAE,KAAK,GAAG;AAC7C,UAAM,OAAO,KAAK,sBAAsB,KAAK,oBAAoB,IAAI,IAAI,GAAG,KAAK,eAAe,GAAG,IAAI;AACvG,UAAM,KAAK,UAAU,mBAAmB,IAAI,CAAC,UAAU,IAAI,IAAI;AAAA,EACjE;AACA,SAAO;AACT;AAWA,IAAM,QAAQ;AACd,IAAM,cAAc;AASb,SAAS,gBAAgB,eAA8D;AAC5F,QAAM,MAAM,iBAAiB,CAAC;AAC9B,QAAM,QAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO,KAAK,GAAG,GAAG;AACnC,QAAI,SAAS,WAAY;AACzB,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,QAAM,KAAK,kBAAkB;AAO7B,QAAM,OAAO,mBAAmB,WAAW;AAE3C,QAAM,UAAU,iBAAiB,KAAK,EAAE,QAAQ,GAAG,UAAU,KAAK,SAAS,GAAG,OAAO,MAAM,CAAC;AAC5F,QAAM,SAAS,GAAG,IAAI,GAAG,OAAO;AAEhC,QAAM,YAAY,WAAW,MAAM,KAAK,IAAI,CAAC;AAC7C,QAAM,cACJ,UAAU,UAAU,QAChB,YACA,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,KAAK,CAAC,GAAG,GAAG,cAAc,EAAE,KAAK,IAAI;AAE3E,SAAO,CAAC,QAAQ,WAAW;AAC7B;;;AC3DO,SAAS,kBAAkB,MAAsE;AACtG,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,OAAQ,KAAkB;AAChC,SAAO,CAAC,CAAC,QAAQ,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,OAAO,OAAO,KAAK,QAAQ;AAC9E;AAeO,SAAS,0BAA0B,YAAwC;AAChF,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,iBAAiB,WAAW,QAAQ,QAAQ,EAAE;AACpD,QAAM,MAAM,eAAe,QAAQ,IAAI;AACvC,QAAM,SAAS,MAAM,IAAI,iBAAiB,eAAe,MAAM,GAAG,GAAG;AAErE,SAAO,OAAO,QAAQ,cAAc,EAAE;AACxC;AAkBO,SAAS,oBAAoB,KAA0B;AAC5D,QAAM,eAAe,IAAI,MAAM;AAC/B,QAAM,YAAY,IAAI,aAAa;AACnC,SAAO;AAAA,IACL;AAAA,IACA,yCAAyC,KAAK,UAAU,YAAY,CAAC;AAAA,IACrE;AAAA,IACA,kCAAkC,SAAS;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;;;AChEO,SAAS,SAAS,MAAgB,MAA4B;AACnE,QAAM,MAAM,kBAAkB;AAE9B,QAAM,OAAO,KAAK,OAAO,SAAS,KAAK,MAAa,KAAK,CAAC,IAAI;AAC9D,uBAAqB,KAAK,YAAY;AAEtC,QAAM,QAAQ,kBAAkB,IAAI;AAOpC,QAAM,WAAW,QAAQ,0BAA2B,KAAK,KAA8B,IAAI,UAAU,IAAI;AACzG,QAAM,QAAQ,WAAW,SAAS,MAAM,GAAG,EAAE,SAAS;AACtD,QAAM,kBAAkB,GAAG,MAAM,OAAO,QAAQ,CAAC,CAAC;AAIlD,QAAM,sBAAsB,MAAM,iBAC9B,CAAC,SAAiB,GAAG,eAAe,GAAG,KAAK,eAAgB,IAAI,KAAK,IAAI,WACzE;AAEJ,QAAM,cAAc,iBAAiB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,IAKxC,aAAa,CAAC;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,KAAe,CAAC;AAItB,MAAI,SAAS,IAAI,gBAAiB,IAAG,KAAK,gDAAgD;AAC1F,KAAG,KAAK,GAAG,WAAW;AACtB,KAAG,KAAK,EAAE;AACV,MAAI,OAAO;AAET,OAAG,KAAK,oBAAqB,KAAK,KAA8B,GAAG,CAAC;AACpE,OAAG,KAAK,EAAE;AAAA,EACZ;AACA,KAAG,KAAK,uBAAuB,iBAAiB,KAAK,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG;AAClF,MAAI,IAAI,kBAAkB,QAAQ;AAChC,OAAG,KAAK,EAAE;AACV,OAAG,KAAK,GAAG,IAAI,iBAAiB;AAAA,EAClC;AAEA,QAAM,UAAU,OACZ;AAAA,EAA6B,IAAI;AAAA,iBACjC;AACJ,SAAO;AAAA,EAAQ,GAAG,KAAK,IAAI,CAAC;AAAA;AAAA,EAAU,OAAO;AAAA;AAC/C;;;AC1DA,IAAM,YAAY,CAAC,YAAY,iBAAiB,WAAW;AAM3D,SAAS,eAAe,KAA8C;AACpE,MAAI,IAAI,eAAe,MAAM;AAC3B,WAAO,OAAO,KAAK,IAAI,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,UAAU;AAAA,EACxE;AACA,SAAO,IAAI,cAAc,CAAC;AAC5B;AAOA,SAAS,iBAAiB,KAA4C;AACpE,MAAI,CAAC,IAAI,WAAY,QAAO;AAC5B,MAAI,IAAI,YAAY;AAClB,UAAM,QAAQ,eAAe,GAAG;AAChC,WAAO;AAAA;AAAA,yBAA8B,MAAM,KAAK,IAAI,CAAC;AAAA,EAAS,IAAI,UAAU;AAAA;AAAA,EAC9E;AACA,SAAO;AAAA;AAAA;AAAA,EAA2B,IAAI,UAAU;AAAA;AAClD;AAEA,SAAS,kBAAkB,KAA6D;AACtF,QAAM,OAAgC,CAAC;AACvC,aAAW,KAAK,WAAW;AACzB,UAAM,IAAK,IAAgC,CAAC;AAC5C,QAAI,MAAM,OAAW,MAAK,CAAC,IAAI;AAAA,EACjC;AACA,SAAO;AACT;AAEO,SAAS,cAAc,KAAoC,MAA4B;AAC5F,QAAM,MAAM,kBAAkB;AAG9B,MAAI,WAAW;AACf,QAAM,OAAO,IAAI,YAAY,SAAS,IAAI,WAAkB,KAAK,CAAC,IAAI;AAEtE,QAAM,gBAAgB,kBAAkB,GAAG;AAC3C,QAAM,UAAU,OAAO,KAAK,aAAa,EAAE,SAAS;AAGpD,MAAI,QAAQ,IAAI,cAAc;AAK9B,QAAM,cAAwB,CAAC;AAK/B,QAAM,UAAU,MAAM,WAAW,KAAK,SAAS,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,IAAI;AACnF,QAAM,sBAAsB,MAAM,iBAC9B,CAAC,SAAiB,GAAG,wBAAwB,SAAS,KAAK,eAAgB,IAAI,KAAK,IAAI,CAAC,WACzF;AAEJ,QAAM,cAAc,iBAAiB,KAAK,EAAE,aAAa,iBAAiB,MAAM,oBAAoB,CAAC;AACrG,QAAM,aAAa,gBAAgB,IAAI,SAAS;AAMhD,QAAM,eAAe,oBAAoB,IAAI,WAAW,OAAO,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC;AAExF,QAAM,KAAe,CAAC;AAGtB,MAAI,IAAI,gBAAiB,IAAG,KAAK,gDAAgD;AACjF,KAAG,KAAK,GAAG,WAAW;AACtB,KAAG,KAAK,EAAE;AACV,KAAG,KAAK,GAAG,UAAU;AACrB,MAAI,aAAa,QAAQ;AACvB,OAAG,KAAK,WAAW,aAAa,KAAK,IAAI,CAAC,mBAAmB;AAAA,EAC/D;AACA,MAAI,SAAS;AACX,OAAG,KAAK,EAAE;AACV,OAAG,KAAK,kBAAkB,iBAAiB,eAAe,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG;AAAA,EAC7E;AACA,MAAI,IAAI,kBAAkB,QAAQ;AAChC,OAAG,KAAK,EAAE;AACV,OAAG,KAAK,GAAG,IAAI,iBAAiB;AAAA,EAClC;AAEA,QAAM,aAAa,IAAI,MAAM;AAAA;AAAA;AAAA,EAAgB,IAAI,GAAG;AAAA,YAAe;AACnE,QAAM,cAAc,iBAAiB,GAAG;AAExC,SAAO;AAAA,EAAQ,GAAG,KAAK,IAAI,CAAC;AAAA;AAAA,EAAU,IAAI;AAAA,EAAK,UAAU,GAAG,WAAW,GAAG,QAAQ,QAAQ,IAAI;AAChG;;;AC/FA,IAAM,KAAK,oBAAI,IAAI,CAAC,KAAK,KAAM,MAAM,IAAI,CAAC;AAC1C,IAAM,cAAc;AACpB,IAAM,aAAa;AAEnB,SAAS,OAAO,KAAa,GAAmB;AAC9C,SAAO,IAAI,IAAI,UAAU,GAAG,IAAI,IAAI,CAAC,CAAC,EAAG;AACzC,SAAO;AACT;AAEA,SAAS,KAAK,KAAa,GAAW,KAAoB;AACxD,QAAM,SAAS,IAAI,MAAM,KAAK,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE;AACpD,QAAM,IAAI,MAAM,iBAAiB,GAAG,aAAa,CAAC,WAAM,MAAM,SAAI;AACpE;AAEA,SAAS,YAAY,KAAa,GAA0B;AAE1D,MAAI,IAAI,IAAI;AACZ,SAAO,IAAI,IAAI,QAAQ;AACrB,UAAM,IAAI,IAAI,CAAC;AACf,QAAI,MAAM,MAAM;AAAE,WAAK;AAAG;AAAA,IAAU;AACpC,QAAI,MAAM,KAAK;AAAE;AAAK;AAAA,IAAO;AAC7B;AAAA,EACF;AACA,QAAM,MAAM,IAAI,MAAM,GAAG,CAAC;AAC1B,SAAO,EAAE,OAAO,KAAK,MAAM,GAAG,GAAa,KAAK,EAAE;AACpD;AAEA,SAAS,YAAY,KAAa,GAA0B;AAC1D,MAAI,IAAI;AACR,SAAO,IAAI,IAAI,UAAU,aAAa,KAAK,IAAI,CAAC,CAAC,EAAG;AACpD,QAAM,MAAM,IAAI,MAAM,GAAG,CAAC;AAC1B,QAAM,IAAI,OAAO,GAAG;AACpB,MAAI,OAAO,MAAM,CAAC,KAAK,QAAQ,MAAO,MAAK,KAAK,GAAG,mBAAmB,GAAG,GAAG;AAC5E,SAAO,EAAE,OAAO,GAAG,KAAK,EAAE;AAC5B;AAEA,SAAS,SAAS,KAAa,GAA0B;AACvD,MAAI,IAAI,CAAC,MAAM,IAAK,QAAO,YAAY,KAAK,CAAC;AAC7C,MAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,EAAG,MAAK,KAAK,GAAG,qBAAqB;AACjE,MAAI,IAAI,IAAI;AACZ,SAAO,IAAI,IAAI,UAAU,WAAW,KAAK,IAAI,CAAC,CAAC,EAAG;AAClD,SAAO,EAAE,OAAO,IAAI,MAAM,GAAG,CAAC,GAAG,KAAK,EAAE;AAC1C;AAEA,SAAS,YAAY,KAAa,GAA0B;AAC1D,QAAM,MAA+B,CAAC;AACtC,MAAI,IAAI,OAAO,KAAK,IAAI,CAAC;AACzB,MAAI,IAAI,CAAC,MAAM,IAAK,QAAO,EAAE,OAAO,KAAK,KAAK,IAAI,EAAE;AACpD,aAAS;AACP,QAAI,OAAO,KAAK,CAAC;AACjB,UAAM,MAAM,SAAS,KAAK,CAAC;AAC3B,QAAI,OAAO,KAAK,IAAI,GAAG;AACvB,QAAI,IAAI,CAAC,MAAM,IAAK,MAAK,KAAK,GAAG,cAAc;AAC/C,QAAI,OAAO,KAAK,IAAI,CAAC;AACrB,UAAM,MAAM,aAAa,KAAK,CAAC;AAC/B,QAAI,IAAI,KAAe,IAAI,IAAI;AAC/B,QAAI,OAAO,KAAK,IAAI,GAAG;AACvB,QAAI,IAAI,CAAC,MAAM,KAAK;AAAE;AAAK;AAAA,IAAU;AACrC,QAAI,IAAI,CAAC,MAAM,IAAK,QAAO,EAAE,OAAO,KAAK,KAAK,IAAI,EAAE;AACpD,SAAK,KAAK,GAAG,qBAAqB;AAAA,EACpC;AACF;AAEA,SAAS,WAAW,KAAa,GAA0B;AACzD,QAAM,MAAiB,CAAC;AACxB,MAAI,IAAI,OAAO,KAAK,IAAI,CAAC;AACzB,MAAI,IAAI,CAAC,MAAM,IAAK,QAAO,EAAE,OAAO,KAAK,KAAK,IAAI,EAAE;AACpD,aAAS;AACP,QAAI,OAAO,KAAK,CAAC;AACjB,UAAM,MAAM,aAAa,KAAK,CAAC;AAC/B,QAAI,KAAK,IAAI,KAAK;AAClB,QAAI,OAAO,KAAK,IAAI,GAAG;AACvB,QAAI,IAAI,CAAC,MAAM,KAAK;AAAE;AAAK;AAAA,IAAU;AACrC,QAAI,IAAI,CAAC,MAAM,IAAK,QAAO,EAAE,OAAO,KAAK,KAAK,IAAI,EAAE;AACpD,SAAK,KAAK,GAAG,qBAAqB;AAAA,EACpC;AACF;AAGO,SAAS,aAAa,KAAa,GAA0B;AAClE,MAAI,OAAO,KAAK,CAAC;AACjB,QAAM,IAAI,IAAI,CAAC;AACf,MAAI,MAAM,IAAK,QAAO,YAAY,KAAK,CAAC;AACxC,MAAI,MAAM,IAAK,QAAO,WAAW,KAAK,CAAC;AACvC,MAAI,MAAM,IAAK,QAAO,YAAY,KAAK,CAAC;AACxC,MAAI,IAAI,WAAW,QAAQ,CAAC,EAAG,QAAO,EAAE,OAAO,MAAM,KAAK,IAAI,EAAE;AAChE,MAAI,IAAI,WAAW,SAAS,CAAC,EAAG,QAAO,EAAE,OAAO,OAAO,KAAK,IAAI,EAAE;AAClE,MAAI,IAAI,WAAW,QAAQ,CAAC,EAAG,QAAO,EAAE,OAAO,MAAM,KAAK,IAAI,EAAE;AAChE,MAAI,MAAM,OAAO,MAAM,OAAQ,KAAK,OAAO,KAAK,IAAM,QAAO,YAAY,KAAK,CAAC;AAC/E,SAAO,KAAK,KAAK,GAAG,yBAAyB,KAAK,OAAO,GAAG;AAC9D;AAGO,SAAS,aAAa,KAAsB;AACjD,QAAM,EAAE,OAAO,IAAI,IAAI,aAAa,KAAK,CAAC;AAC1C,QAAM,OAAO,OAAO,KAAK,GAAG;AAC5B,MAAI,SAAS,IAAI,OAAQ,MAAK,KAAK,MAAM,gCAAgC;AACzE,SAAO;AACT;;;AC7GA,IAAM,UAAkC,EAAE,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI;AAGhE,SAAS,WAAW,KAAa,GAAmB;AACzD,QAAM,IAAI,IAAI,CAAC;AACf,MAAI,IAAI,IAAI;AACZ,SAAO,IAAI,IAAI,QAAQ;AACrB,QAAI,IAAI,CAAC,MAAM,MAAM;AAAE,WAAK;AAAG;AAAA,IAAU;AACzC,QAAI,IAAI,CAAC,MAAM,EAAG,QAAO,IAAI;AAC7B;AAAA,EACF;AACA,QAAM,IAAI,MAAM,wCAAwC,CAAC,EAAE;AAC7D;AAGO,SAAS,aAAa,KAAa,GAAmB;AAC3D,MAAI,IAAI,IAAI;AACZ,SAAO,IAAI,IAAI,QAAQ;AACrB,QAAI,IAAI,CAAC,MAAM,MAAM;AAAE,WAAK;AAAG;AAAA,IAAU;AACzC,QAAI,IAAI,CAAC,MAAM,IAAK,QAAO,IAAI;AAC/B,QAAI,IAAI,CAAC,MAAM,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK;AAAE,UAAI,aAAa,KAAK,IAAI,CAAC;AAAG;AAAA,IAAU;AACpF;AAAA,EACF;AACA,QAAM,IAAI,MAAM,4CAA4C,CAAC,EAAE;AACjE;AAGO,SAAS,aAAa,KAAa,GAAmB;AAC3D,MAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAG,OAAM,IAAI,MAAM,sCAAsC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI;AAC7F,MAAI,QAAQ;AACZ,MAAI,IAAI;AACR,SAAO,IAAI,IAAI,QAAQ;AACrB,UAAM,IAAI,IAAI,CAAC;AACf,QAAI,MAAM,OAAO,MAAM,KAAK;AAAE,UAAI,WAAW,KAAK,CAAC;AAAG;AAAA,IAAU;AAChE,QAAI,MAAM,KAAK;AAAE,UAAI,aAAa,KAAK,CAAC;AAAG;AAAA,IAAU;AACrD,QAAI,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK;AAAE;AAAS;AAAK;AAAA,IAAU;AACnE,QAAI,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK;AACvC;AACA;AACA,UAAI,UAAU,EAAG,QAAO;AACxB;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM,IAAI,MAAM,iCAAiC,CAAC,EAAE;AACtD;AAOO,SAAS,kBACd,MACA,WAA4B,KACY;AACxC,MAAI,IAAI;AACR,SAAO,IAAI,KAAK,QAAQ;AACtB,UAAM,IAAI,KAAK,CAAC;AAChB,QAAI,MAAM,OAAO,MAAM,KAAK;AAAE,UAAI,WAAW,MAAM,CAAC;AAAG;AAAA,IAAU;AACjE,QAAI,MAAM,KAAK;AAAE,UAAI,aAAa,MAAM,CAAC;AAAG;AAAA,IAAU;AACtD,QAAI,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK;AACvC,YAAM,MAAM,aAAa,MAAM,CAAC;AAChC,UAAI,MAAM,YAAY,QAAQ,KAAK,QAAQ;AACzC,eAAO,EAAE,MAAM,GAAG,OAAO,KAAK,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE;AAAA,MACtD;AACA,UAAI;AACJ;AAAA,IACF;AACA;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,cAAc,KAAa,KAAuB;AAChE,QAAM,QAAkB,CAAC;AACzB,MAAI,QAAQ;AACZ,MAAI,IAAI;AACR,SAAO,IAAI,IAAI,QAAQ;AACrB,UAAM,IAAI,IAAI,CAAC;AACf,QAAI,MAAM,OAAO,MAAM,KAAK;AAAE,UAAI,WAAW,KAAK,CAAC;AAAG;AAAA,IAAU;AAChE,QAAI,MAAM,KAAK;AAAE,UAAI,aAAa,KAAK,CAAC;AAAG;AAAA,IAAU;AACrD,QAAI,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK;AAAE,UAAI,aAAa,KAAK,CAAC;AAAG;AAAA,IAAU;AAC/E,QAAI,MAAM,KAAK;AAAE,YAAM,KAAK,IAAI,MAAM,OAAO,CAAC,CAAC;AAAG,cAAQ,IAAI;AAAG;AAAK;AAAA,IAAU;AAChF;AAAA,EACF;AACA,QAAM,KAAK,IAAI,MAAM,KAAK,CAAC;AAC3B,SAAO,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAClC;;;AC5FO,SAAS,WAAW,MAAsB;AAC/C,QAAM,OAAO,KAAK,QAAQ,GAAG;AAC7B,QAAM,MAAM,aAAa,MAAM,IAAI;AACnC,SAAO,KAAK,MAAM,OAAO,GAAG,MAAM,CAAC;AACrC;;;ACIO,SAAS,gBAAgB,SAAyB;AACvD,MAAI,MAAM;AACV,MAAI,IAAI;AACR,SAAO,IAAI,QAAQ,QAAQ;AACzB,UAAM,IAAI,QAAQ,CAAC;AACnB,QAAI,MAAM,MAAM;AACd,YAAM,IAAI,QAAQ,IAAI,CAAC;AAEvB,aAAO,MAAM,OAAO,OAAO,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM;AAC/D,WAAK;AACL;AAAA,IACF;AACA,QAAI,MAAM,OAAO,QAAQ,IAAI,CAAC,MAAM,KAAK;AACvC,YAAM,MAAM,aAAa,SAAS,IAAI,CAAC;AACvC,aAAO,OAAO,QAAQ,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI;AACrD,UAAI;AACJ;AAAA,IACF;AACA,WAAO;AACP;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,mBAAmB,MAAc,KAA4B;AAC3E,QAAM,IAAI,KAAK,KAAK;AAEpB,MAAI,IAAI,YAAY,IAAI,CAAC,EAAG,QAAO,IAAI,YAAY,IAAI,CAAC;AACxD,MAAI,EAAE,WAAW,OAAO,EAAG,QAAO,aAAa,WAAW,CAAC,CAAC;AAG5D,MAAI,EAAE,WAAW,OAAO,EAAG,QAAO,aAAa,cAAc,WAAW,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;AACnF,MAAI,EAAE,WAAW,YAAY,EAAG,QAAO,aAAa,cAAc,WAAW,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;AACxF,MAAI,EAAE,CAAC,MAAM,IAAK,QAAO,gBAAgB,EAAE,MAAM,GAAG,EAAE,CAAC;AACvD,MAAI,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,IAAK,QAAO,aAAa,CAAC;AACvD,MAAI,EAAE,CAAC,MAAM,IAAK,QAAO,aAAa,CAAC;AACvC,MAAI,MAAM,OAAQ,QAAO;AACzB,MAAI,MAAM,QAAS,QAAO;AAC1B,MAAI,MAAM,OAAQ,QAAO;AACzB,MAAI,kBAAkB,KAAK,CAAC,KAAK,CAAC,OAAO,MAAM,OAAO,CAAC,CAAC,EAAG,QAAO,OAAO,CAAC;AAE1E,SAAO,KAAK,CAAC;AACf;AAGO,SAAS,mBAAmB,MAKjC;AACA,QAAM,OAAO,WAAW,IAAI;AAC5B,QAAM,QAAQ,cAAc,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AACjE,QAAM,MAA+B,CAAC;AACtC,MAAI,MAAM,CAAC,EAAG,KAAI,QAAQ,aAAa,MAAM,CAAC,CAAC;AAI/C,QAAM,WAAW,MAAM,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,CAAC;AACzE,MAAI,UAAU;AACZ,UAAM,OAAO,aAAa,QAAQ;AAClC,QAAI,KAAK,gBAAgB,OAAW,KAAI,oBAAoB,KAAK;AACjE,QAAI,KAAK,UAAU,OAAW,KAAI,QAAQ,KAAK;AAC/C,QAAI,KAAK,aAAa,OAAW,KAAI,uBAAuB,KAAK;AAAA,EAEnE;AACA,SAAO;AACT;AAGO,SAAS,iBAAiB,MAA0C;AACzE,QAAM,IAAI,KAAK,KAAK;AACpB,MAAI,MAAM,QAAS,QAAO;AAC1B,MAAI,MAAM,OAAQ,QAAO;AACzB,MAAI,EAAE,WAAW,OAAO,EAAG,QAAO,aAAa,WAAW,CAAC,CAAC;AAC5D,SAAO,KAAK,CAAC;AACf;;;ACzDO,SAAS,qBAAmC;AACjD,SAAO;AAAA,IACL,oBAAoB,oBAAI,IAAI;AAAA,IAC5B,aAAa,oBAAI,IAAI;AAAA,IACrB,WAAW,oBAAI,IAAI;AAAA,IACnB,gBAAgB,oBAAI,IAAI;AAAA,EAC1B;AACF;;;ACpBA,SAAS,aAAa,MAAc,QAAqC;AACvE,QAAM,MAAM,KAAK,QAAQ,MAAM;AAC/B,MAAI,MAAM,EAAG,QAAO;AACpB,SAAO,aAAa,MAAM,MAAM,OAAO,MAAM,EAAE;AACjD;AAEO,SAAS,iBAAiB,MAA2B;AAC1D,QAAM,MAAM,mBAAmB;AAK/B,aAAW,KAAK,KAAK,SAAS,2EAA2E,GAAG;AAC1G,QAAI,eAAe,IAAI,EAAE,CAAC,CAAC;AAAA,EAC7B;AAGA,aAAW,KAAK,KAAK,SAAS,8BAA8B,GAAG;AAC7D,UAAM,YAAY,KAAK,QAAQ,KAAK,EAAE,QAAS,EAAE,CAAC,EAAE,MAAM;AAC1D,QAAI,YAAY,EAAG;AACnB,UAAM,UAAU,aAAa,MAAM,SAAS;AAC5C,QAAI,YAAY,IAAI,EAAE,CAAC,GAAG,gBAAgB,KAAK,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC;AAAA,EACnF;AAGA,aAAW,KAAK,KAAK,SAAS,2BAA2B,GAAG;AAC1D,UAAM,YAAY,KAAK,QAAQ,KAAK,EAAE,QAAS,EAAE,CAAC,EAAE,MAAM;AAC1D,QAAI,YAAY,EAAG;AACnB,UAAM,UAAU,aAAa,MAAM,SAAS;AAC5C,QAAI,UAAU,IAAI,EAAE,CAAC,GAAG,gBAAgB,KAAK,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC;AAAA,EACjF;AAMA,aAAW,KAAK,KAAK,SAAS,kDAAkD,GAAG;AACjF,UAAM,OAAO,EAAE,QAAS,EAAE,CAAC,EAAE,SAAS;AACtC,UAAM,QAAQ,KAAK,MAAM,OAAO,GAAG,aAAa,MAAM,IAAI,IAAI,CAAC;AAC/D,UAAM,OAAO,cAAc,OAAO,GAAG,EAAE,OAAO,OAAO;AACrD,UAAM,SAAS,aAAa,KAAK,CAAC,CAAC;AACnC,UAAM,QAAQ,KAAK,CAAC,GAAG,KAAK,EAAE,WAAW,GAAG,IACvC,aAAa,KAAK,CAAC,CAAC,IACrB;AACJ,QAAI,mBAAmB,IAAI,EAAE,CAAC,GAAG,EAAE,QAAQ,MAAM,CAAC;AAAA,EACpD;AAMA,QAAM,iBAAiB,aAAa,MAAM,sBAAsB;AAChE,QAAM,gBAAiB,aAAa,MAAM,iBAAiB,KAAiC,CAAC;AAC7F,QAAM,OAAO,aAAa,MAAM,sBAAsB;AACtD,QAAM,OAA4B,KAAK,SAAS,eAAe,IAAI,cAAc;AAEjF,SAAO,EAAE,MAAM,KAAK,MAAM,gBAAgB,cAAc;AAC1D;;;AC1DA,IAAMC,MAAK,oBAAI,IAAI,CAAC,KAAK,KAAM,MAAM,IAAI,CAAC;AAC1C,IAAM,eAAe,oBAAI,IAAI,CAAC,QAAQ,SAAS,cAAc,YAAY,CAAC;AAC1E,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EAAS;AAAA,EAAa;AAAA,EAAmB;AAAA,EAAkB;AAC7D,CAAC;AAED,SAASC,QAAO,KAAa,GAAmB;AAC9C,SAAO,IAAI,IAAI,UAAUD,IAAG,IAAI,IAAI,CAAC,CAAC,EAAG;AACzC,SAAO;AACT;AAaA,SAAS,YAAY,KAAa,GAA0C;AAC1E,MAAI,IAAI;AACR,SAAO,IAAI,IAAI,UAAU,kBAAkB,KAAK,IAAI,CAAC,CAAC,EAAG;AACzD,SAAO,EAAE,MAAM,IAAI,MAAM,GAAG,CAAC,GAAG,KAAK,EAAE;AACzC;AAEA,SAAS,gBAAgB,KAAa,GAA+D;AACnG,QAAM,QAAgB,CAAC;AACvB,MAAI,IAAI;AACR,aAAS;AACP,QAAIC,QAAO,KAAK,CAAC;AACjB,QAAI,IAAI,CAAC,MAAM,OAAO,IAAI,IAAI,CAAC,MAAM,IAAK,QAAO,EAAE,OAAO,KAAK,IAAI,GAAG,WAAW,KAAK;AACtF,QAAI,IAAI,CAAC,MAAM,IAAK,QAAO,EAAE,OAAO,KAAK,IAAI,GAAG,WAAW,MAAM;AACjE,UAAM,EAAE,MAAM,IAAI,IAAI,YAAY,KAAK,CAAC;AACxC,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,+CAA+C,CAAC,MAAM,IAAI,MAAM,GAAG,IAAI,EAAE,CAAC,IAAI;AACzG,QAAI;AACJ,QAAI,IAAI,CAAC,MAAM,KAAK;AAClB;AACA,UAAI,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,MAAM,KAAK;AACpC,cAAM,IAAI,IAAI,CAAC;AACf,YAAI,IAAI,IAAI;AACZ,eAAO,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,GAAG;AAAE,cAAI,IAAI,CAAC,MAAM,KAAM;AAAK;AAAA,QAAK;AACxE,cAAM,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,MAAM,CAAC;AAC5D,YAAI,IAAI;AAAA,MACV,WAAW,IAAI,CAAC,MAAM,KAAK;AACzB,cAAM,QAAQ,aAAa,KAAK,CAAC;AACjC,cAAM,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,QAAQ,KAAK,CAAC;AACnE,YAAI;AAAA,MACN,OAAO;AACL,cAAM,IAAI,MAAM,6CAA6C,IAAI,QAAQ,CAAC,EAAE;AAAA,MAC9E;AAAA,IACF,OAAO;AACL,YAAM,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,OAAO,WAAW,KAAK,CAAC;AAAA,IAC9D;AAAA,EACF;AACF;AAEA,SAAS,UAAU,GAAS,KAA4B;AACtD,MAAI,EAAE,UAAW,QAAO;AACxB,MAAI,CAAC,EAAE,OAAQ,QAAO,EAAE;AACxB,SAAO,mBAAmB,EAAE,KAAK,GAAG;AACtC;AAYO,SAAS,aAAa,KAAa,GAAW,KAAmB,OAAO,GAAiC;AAC9G,MAAIA,QAAO,KAAK,CAAC;AACjB,MAAI,IAAI,CAAC,MAAM,IAAK,OAAM,IAAI,MAAM,iCAAiC,CAAC,EAAE;AACxE,QAAM,EAAE,MAAM,KAAK,KAAK,SAAS,IAAI,YAAY,KAAK,IAAI,CAAC;AAC3D,QAAM,EAAE,OAAO,KAAK,YAAY,UAAU,IAAI,gBAAgB,KAAK,QAAQ;AAE3E,MAAI,WAAoB,CAAC;AACzB,MAAI,MAAM;AACV,MAAI,CAAC,WAAW;AAEd,UAAM,QAAQ,WAAW,KAAK,YAAY,KAAK,KAAK,IAAI;AACxD,eAAW,MAAM;AACjB,UAAM,QAAQ,IAAI,QAAQ,KAAK,MAAM,GAAG;AACxC,UAAM,QAAQ;AAAA,EAChB;AACA,SAAO,EAAE,MAAM,cAAc,KAAK,OAAO,UAAU,GAAG,GAAG,IAAI;AAC/D;AAGA,SAAS,WAAW,KAAmB,MAAa,OAAe,KAAmB;AACpF,MAAI,IAAI,SAAS,QAAQ,OAAO,SAAS,SAAU,KAAI,MAAM,IAAI,MAAM,EAAE,OAAO,IAAI,CAAC;AACvF;AAEO,SAAS,WACd,KACA,GACA,KACA,SACA,OAAO,GAC0B;AACjC,QAAM,QAAiB,CAAC;AACxB,MAAI,IAAI;AACR,SAAO,IAAI,IAAI,QAAQ;AACrB,UAAM,IAAIA,QAAO,KAAK,CAAC;AACvB,QAAI,KAAK,IAAI,QAAQ;AAAE,UAAI;AAAG;AAAA,IAAO;AACrC,QAAI,WAAW,IAAI,CAAC,MAAM,OAAO,IAAI,IAAI,CAAC,MAAM,IAAK,QAAO,EAAE,OAAO,KAAK,EAAE;AAC5E,QAAI,IAAI,CAAC,MAAM,KAAK;AAClB,YAAM,EAAE,MAAM,IAAI,IAAI,aAAa,KAAK,GAAG,KAAK,IAAI;AACpD,iBAAW,KAAK,MAAM,OAAO,GAAG,OAAO,GAAG;AAC1C,YAAM,KAAK,IAAI;AACf,UAAI;AACJ;AAAA,IACF;AACA,QAAI,IAAI,CAAC,MAAM,KAAK;AAClB,YAAM,MAAM,aAAa,KAAK,CAAC;AAC/B,YAAM,QAAQ,mBAAmB,IAAI,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC;AAC7E,UAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AAEzD,mBAAW,KAAK,OAAO,OAAO,GAAG,OAAO,GAAG;AAC3C,cAAM,KAAK,KAAK;AAAA,MAClB;AACA,UAAI;AACJ;AAAA,IACF;AAEA,QAAI,IAAI;AACR,WAAO,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,MAAM,IAAK;AAC3D,UAAM,OAAO,IAAI,MAAM,GAAG,CAAC,EAAE,KAAK;AAClC,QAAI,KAAK,OAAQ,OAAM,KAAK,IAAI;AAChC,QAAI;AAAA,EACN;AACA,SAAO,EAAE,OAAO,KAAK,EAAE;AACzB;AAMO,SAAS,mBAAmB,OAAe,KAAmB,OAAO,GAAsB;AAChG,QAAM,IAAI,MAAM,KAAK;AACrB,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,QAAQ,OAAO,UAAU,KAAK;AAEpC,QAAM,MAAM,kBAAkB,GAAG,GAAG;AACpC,MAAI,KAAK;AACP,UAAM,SAAS,EAAE,MAAM,GAAG,IAAI,IAAI,EAAE,KAAK;AACzC,QAAI,OAAO,SAAS,IAAI,GAAG;AACzB,YAAM,OAAO,OAAO,MAAM,GAAG,EAAE,EAAE,KAAK;AACtC,YAAM,UAAU,IAAI;AACpB,YAAM,OAAO,QAAQ,KAAK;AAC1B,YAAM,WAAW,QAAQ,IAAI,OAAO,IAAI,UAAU,OAAO;AACzD,YAAM,OAAO,KAAK,WAAW,GAAG,IAC5B,aAAa,MAAM,GAAG,KAAK,QAAQ,EAAE,OACrC,mBAAmB,MAAM,KAAK,QAAQ;AAC1C,UAAI,QAAQ,OAAO,SAAS,SAAU,MAAK,KAAK,iBAAiB,IAAI;AACrE,aAAO;AAAA,IACT;AACA,QAAI,OAAO,SAAS,MAAM,GAAG;AAC3B,aAAO,aAAa,GAAG,KAAK,KAAK;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,MAAM,mBAAmB,GAAG,GAAG;AACrC,SAAO;AACT;AAGA,SAAS,UAAU,GAAmB;AACpC,SAAO,EAAE,SAAS,EAAE,UAAU,EAAE;AAClC;AAEA,SAAS,aAAa,GAAW,KAAmB,OAAO,GAAS;AAClE,QAAM,SAAS,EAAE,QAAQ,OAAO;AAChC,QAAM,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK;AACrC,QAAM,UAAU,SAAS;AACzB,QAAM,SAAS,aAAa,GAAG,OAAO;AACtC,QAAM,SAAS,EAAE,MAAM,UAAU,GAAG,SAAS,CAAC;AAC9C,QAAM,MAAM,OAAO,KAAK;AACxB,QAAM,UAAU,OAAO,UAAU,IAAI,UAAU,MAAM;AAErD,QAAM,YAAY,aAAa,KAAK,CAAC;AACrC,QAAM,SAAS,cAAc,IAAI,MAAM,GAAG,YAAY,CAAC,GAAG,GAAG,EAAE,OAAO,OAAO;AAC7E,QAAM,UAAU,OAAO,CAAC;AACxB,QAAM,cAAc,IAAI,MAAM,SAAS;AACvC,QAAM,UAAU,kBAAkB,YAAY,KAAK,GAAG,GAAG;AACzD,MAAI,WAAoB,CAAC;AACzB,MAAI,SAAS;AACX,UAAM,eAAe,UAAU,YAAY,UAAU,WAAW,IAAI,QAAQ,OAAO;AACnF,eAAW,WAAW,QAAQ,OAAO,GAAG,KAAK,QAAW,YAAY,EAAE;AAAA,EACxE;AAEA,MAAI,KAAK,WAAW,OAAO,GAAG;AAC5B,UAAM,QAAQ,WAAW,IAAI;AAC7B,UAAM,QAAQ,cAAc,OAAO,GAAG,EAAE,OAAO,OAAO;AACtD,UAAM,OAAO,MAAM,CAAC,IAAK,aAAa,MAAM,CAAC,CAAC,IAAgC,CAAC;AAC/E,UAAMC,QAAa;AAAA,MACjB,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,QAAQ,KAAK,MAAM,CAAC,CAAC;AAAA,MACrB,GAAG;AAAA,MACH;AAAA,IACF;AACA,QAAI,WAAW,YAAY,OAAQ,CAAAA,MAAK,SAAS;AACjD,WAAOA;AAAA,EACT;AAEA,QAAM,UAAU,IAAI,mBAAmB,IAAI,IAAI;AAC/C,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,OAAa;AAAA,IACjB,MAAM;AAAA,IACN,YAAY;AAAA,IACZ;AAAA,IACA,GAAI,SAAS,SAAS,CAAC;AAAA,IACvB;AAAA,EACF;AACA,MAAI,WAAW,YAAY,YAAY,MAAM,EAAG,MAAK,SAAS;AAC9D,SAAO;AACT;AAMA,SAAS,WAAW,MAAY,OAAqB;AACnD,QAAM,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAChD,MAAI,CAAC,IAAK;AACV,QAAM,SAAS,mBAAmB,IAAI,GAAG;AACzC,MAAI,OAAO,UAAU,OAAW,MAAK,QAAQ,OAAO;AACpD,MAAI,OAAO,sBAAsB,OAAW,MAAK,oBAAoB,OAAO;AAC5E,MAAI,OAAO,UAAU,OAAW,MAAK,QAAQ,OAAO;AACpD,MAAI,OAAO,yBAAyB,OAAW,MAAK,uBAAuB,OAAO;AACpF;AAEA,SAAS,WAAW,OAAe,KAAmB,MAA4C;AAChG,QAAM,MAA+B,CAAC;AACtC,aAAW,KAAK,OAAO;AACrB,QAAI,KAAK,IAAI,EAAE,IAAI,EAAG;AACtB,QAAI,EAAE,IAAI,IAAI,UAAU,GAAG,GAAG;AAAA,EAChC;AACA,SAAO;AACT;AAEA,SAAS,cAAc,KAAa,OAAe,UAAmB,KAAyB;AAE7F,MAAI,IAAI,UAAU,IAAI,GAAG,GAAG;AAC1B,UAAMA,QAAa,EAAE,MAAM,QAAQ,KAAK,IAAI,UAAU,IAAI,GAAG,EAAG;AAChE,eAAWA,OAAM,KAAK;AACtB,UAAMC,cAAa,WAAW,OAAO,KAAK,oBAAI,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5D,QAAI,OAAO,KAAKA,WAAU,EAAE,OAAQ,CAAAD,MAAK,aAAaC;AACtD,QAAI,SAAS,OAAQ,CAAAD,MAAK,WAAW;AACrC,WAAOA;AAAA,EACT;AAEA,MAAI,QAAQ,QAAQ;AAClB,UAAMA,QAAa,EAAE,MAAM,OAAO;AAClC,QAAI,SAAS,OAAQ,CAAAA,MAAK,UAAU;AACpC,WAAOA;AAAA,EACT;AAEA,MAAI,QAAQ,QAAQ;AAClB,UAAMA,QAAa,EAAE,MAAM,OAAO;AAClC,UAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAChD,QAAI,KAAM,CAAAA,MAAK,OAAO,UAAU,MAAM,GAAG;AACzC,eAAWA,OAAM,KAAK;AACtB,UAAM,OAAO,WAAW,OAAO,KAAK,oBAAI,IAAI,CAAC,QAAQ,OAAO,CAAC,CAAC;AAC9D,QAAI,OAAO,KAAK,IAAI,EAAE,OAAQ,CAAAA,MAAK,aAAa;AAChD,QAAI,SAAS,OAAQ,CAAAA,MAAK,WAAW;AACrC,WAAOA;AAAA,EACT;AAEA,MAAI,QAAQ,SAAS;AACnB,UAAMA,QAAa,EAAE,MAAM,QAAQ;AACnC,UAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAChD,QAAI,KAAM,CAAAA,MAAK,OAAO,UAAU,MAAM,GAAG;AACzC,eAAWA,OAAM,KAAK;AACtB,UAAM,OAAO,WAAW,OAAO,KAAK,oBAAI,IAAI,CAAC,QAAQ,OAAO,CAAC,CAAC;AAC9D,QAAI,OAAO,KAAK,IAAI,EAAE,OAAQ,CAAAA,MAAK,aAAa;AAChD,WAAOA;AAAA,EACT;AAEA,MAAI,QAAQ,cAAc;AACxB,UAAMA,QAAa,EAAE,MAAM,cAAc;AACzC,eAAW,KAAK,OAAO;AACrB,UAAI,mBAAmB,IAAI,EAAE,IAAI,KAAK,EAAE,UAAU,EAAE,IAAI,UAAU,EAAE,WAAW,QAAQ,GAAG;AACxF,QAAAA,MAAK,EAAE,IAAI,IAAI,aAAa,WAAW,EAAE,GAAG,CAAC;AAAA,MAC/C,WAAW,EAAE,SAAS,UAAU,EAAE,QAAQ;AACxC,cAAM,OAAO,aAAa,EAAE,GAAG;AAC/B,YAAI,KAAK,gBAAgB,OAAW,CAAAA,MAAK,oBAAoB,KAAK;AAClE,YAAI,KAAK,UAAU,OAAW,CAAAA,MAAK,QAAQ,KAAK;AAChD,YAAI,KAAK,aAAa,OAAW,CAAAA,MAAK,uBAAuB,KAAK;AAAA,MACpE,OAAO;AACL,QAAAA,MAAK,EAAE,IAAI,IAAI,UAAU,GAAG,GAAG;AAAA,MACjC;AAAA,IACF;AACA,WAAOA;AAAA,EACT;AAGA,QAAM,cAAc,SAAS,KAAK,GAAG,KAAK,CAAC,aAAa,IAAI,GAAG;AAC/D,MAAI,aAAa;AACf,UAAMA,QAAa,EAAE,MAAM,aAAa,WAAW,IAAI;AACvD,eAAWA,OAAM,KAAK;AACtB,UAAM,QAAQ,WAAW,OAAO,KAAK,oBAAI,IAAI,CAAC,OAAO,CAAC,CAAC;AACvD,QAAI,OAAO,KAAK,KAAK,EAAE,OAAQ,CAAAA,MAAK,QAAQ;AAC5C,QAAI,SAAS,OAAQ,CAAAA,MAAK,WAAW;AACrC,WAAOA;AAAA,EACT;AAGA,QAAM,OAAa,EAAE,MAAM,QAAQ,IAAI;AACvC,aAAW,MAAM,KAAK;AACtB,QAAM,aAAa,WAAW,OAAO,KAAK,oBAAI,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5D,MAAI,OAAO,KAAK,UAAU,EAAE,OAAQ,MAAK,aAAa;AACtD,MAAI,SAAS,OAAQ,MAAK,WAAW;AACrC,SAAO;AACT;;;AC7TA,SAASE,WAAU,GAAmB;AACpC,SAAO,EAAE,SAAS,EAAE,UAAU,EAAE;AAClC;AAEA,SAAS,iBAAiB,QAAmE;AAC3F,QAAM,IAAI,OAAO,MAAM,mCAAmC;AAE1D,QAAM,OAAO,IAAI,EAAE,CAAC,IAAI;AACxB,SAAO,EAAE,MAAM,IAAI,EAAE,CAAC,IAAI,IAAI,MAAM,WAAW,OAAO,SAAS,KAAK,OAAO;AAC7E;AAGA,SAAS,gBAAgB,SAAuC;AAC9D,QAAM,IAAI,QAAQ,MAAM,6BAA6B;AACrD,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,EAAE,CAAC,EACP,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AACnB;AAEA,SAAS,mBACP,MACA,KACA,WACmF;AACnF,MAAI,OAAO;AACX,MAAI;AACJ,MAAI;AACJ,MAAI;AAIJ,QAAM,UAAU,KAAK,MAAM,gDAAgD;AAC3E,MAAI,SAAS;AACX,iBAAa,QAAQ,CAAC;AACtB,iBAAa,gBAAgB,QAAQ,CAAC,CAAC;AACvC,WAAO,KAAK,MAAM,GAAG,QAAQ,KAAK;AAAA,EACpC;AACA,QAAM,SAAS,KAAK,MAAM,uCAAuC;AACjE,MAAI,QAAQ;AACV,UAAM,OAAO,CAAC;AACd,WAAO,KAAK,MAAM,GAAG,OAAO,KAAK;AAAA,EACnC;AAEA,QAAM,SAAS,KAAK,KAAK;AAEzB,QAAM,OAAO,YAAYA,WAAU,IAAI;AACvC,QAAM,YAAY,SAAS,WAAW,QAAQ,GAAG,KAAK,QAAW,IAAI,EAAE,MAAM,CAAC,IAAI;AAClF,SAAO,EAAE,WAAW,KAAK,YAAY,WAAW;AAClD;AAEA,SAAS,cAAc,MAAc,KAAmB,WAA4B;AAClF,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,CAAC,QAAQ,WAAW,GAAG,EAAG,QAAO;AACrC,QAAM,OAAO,YAAYA,WAAU,IAAI;AACvC,QAAM,UAAU,aAAa,SAAS,GAAG,KAAK,IAAI,EAAE;AACpD,QAAM,WAAW,QAAQ;AACzB,SAAO,MAAM,QAAQ,QAAQ,IAAI,SAAS,CAAC,IAAI;AACjD;AAEO,SAAS,UAAU,QAAgB,OAAyB,CAAC,GAAe;AACjF,QAAM,EAAE,MAAM,MAAM,UAAU,IAAI,iBAAiB,MAAM;AACzD,QAAM,QAAQ,iBAAiB,IAAI;AACnC,QAAM,QAAQ,KAAK,eAAe,oBAAI,IAAsB,IAAI;AAChE,MAAI,MAAO,OAAM,IAAI,QAAQ;AAE7B,MAAI,MAAM,SAAS,aAAa;AAC9B,UAAM,EAAE,WAAW,KAAK,YAAY,WAAW,IAAI,mBAAmB,MAAM,MAAM,KAAK,SAAS;AAChG,UAAM,MAA+B,CAAC;AACtC,QAAI,MAAM,kBAAkB,OAAO,KAAK,MAAM,cAAc,EAAE,QAAQ;AACpE,UAAI,YAAY,MAAM;AAAA,IACxB;AACA,QAAI,cAAc,OAAW,KAAI,YAAY;AAC7C,WAAO,OAAO,KAAK,MAAM,aAAa;AACtC,QAAI,QAAQ,OAAW,KAAI,MAAM;AACjC,QAAI,eAAe,OAAW,KAAI,aAAa;AAG/C,QAAI,eAAe,OAAW,KAAI,aAAa;AAC/C,WAAO,EAAE,OAAO,EAAE,WAAW,IAAI,GAAG,MAAM;AAAA,EAC5C;AAEA,QAAM,OAAO,cAAc,MAAM,MAAM,KAAK,SAAS;AACrD,QAAM,OAAgC,CAAC;AACvC,MAAI,MAAM,SAAS,OAAW,MAAK,OAAO,MAAM;AAChD,MAAI,SAAS,OAAW,MAAK,OAAO;AACpC,SAAO,EAAE,OAAO,MAAM,MAAM;AAC9B;;;ACjGA,SAASC,iBAAgB,OAAyB;AAChD,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,aAAW,KAAK,OAAO,OAAO,KAAgC,GAAG;AAC/D,QAAI,MAAM,UAAa,MAAM,KAAM;AACnC,QAAI,OAAO,MAAM,UAAU;AACzB,UAAI,OAAO,KAAK,CAAW,EAAE,SAAS,EAAG,QAAO;AAAA,IAClD,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,kBAAkB,UAA4B;AACrD,MAAI,OAAO,aAAa,SAAU,QAAO;AACzC,MAAI,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO;AACrC,QAAM,QAAQ,SAAS,IAAI,cAAc;AACzC,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,KAAK,OAAO,MAAM,CAAC,MAAM,SAAU,QAAO,MAAM,CAAC;AACtE,SAAO;AACT;AAEA,SAAS,eAAe,OAAyB;AAC/C,SAAO,OAAO,UAAU,WAAW,QAAQ,cAAc,KAAK;AAChE;AAGA,SAAS,cAAc,GAAqD;AAC1E,MAAI,EAAE,SAAS,YAAY;AACzB,UAAM,EAAE,MAAM,YAAY,OAAO,YAAY,UAAU,GAAG,KAAK,IAAI;AACnE,UAAM,OAAgC;AAAA,MACpC,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,GAAG;AAAA,IACL;AAIA,QAAI,KAAK,WAAW,OAAW,MAAK,SAAS;AAC7C,QAAI,aAAa,OAAW,MAAK,WAAW;AAE5C,QAAI,UAAU,UAAa,eAAe,QAAW;AACnD,YAAM,UAAmC,EAAE,MAAM,QAAQ,KAAK,MAAM;AACpE,UAAI,UAAU,OAAW,SAAQ,QAAQ;AACzC,UAAI,eAAe,OAAW,SAAQ,aAAa;AACnD,cAAQ,WAAW,CAAC,IAAI;AACxB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACA,MAAI,EAAE,SAAS,SAAS;AACtB,UAAM,EAAE,MAAM,KAAK,KAAK,OAAO,YAAY,GAAG,KAAK,IAAI;AACvD,UAAM,QAAiC,EAAE,GAAI,WAAsB;AACnE,QAAI,QAAQ,OAAW,OAAM,MAAM;AACnC,QAAI,QAAQ,OAAW,OAAM,MAAM;AACnC,UAAM,MAA+B,EAAE,MAAM,QAAQ,KAAK,OAAO,GAAG,KAAK;AACzE,QAAI,OAAO,KAAK,KAAK,EAAE,OAAQ,KAAI,aAAa;AAChD,QAAI,UAAU,OAAW,KAAI,QAAQ;AACrC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,cAAc,MAAwB;AAC7C,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,MAAM,cAAc,EAAE,GAAI,KAAiC,CAAC;AAElE,MAAI,WAAW,OAAO,CAACA,iBAAgB,IAAI,KAAK,EAAG,QAAO,IAAI;AAI9D,MAAI,IAAI,SAAS,UAAU,IAAI,SAAS,OAAO,IAAI,UAAU,UAAU;AACrE,QAAI,aAAa,EAAE,GAAI,IAAI,OAAkB,GAAK,IAAI,cAAyB,CAAC,EAAG;AACnF,WAAO,IAAI;AAAA,EACb;AAEA,MAAI,IAAI,SAAS,QAAQ;AACvB,UAAM,aAAc,IAAI,cAAyB;AAEjD,QAAI,eAAe,gBAAgB,OAAO,IAAI,WAAW,YAAY,CAAC,IAAI,OAAO,SAAS,IAAI,GAAG;AAC/F,UAAI,SAAS,KAAK,IAAI,MAAM;AAAA,IAC9B;AAEA,UAAM,cAAc,eAAe,eAAe,YAAY,OAAO,IAAI,MAAM,CAAC,IAAI;AACpF,QAAI,IAAI,WAAW,YAAa,QAAO,IAAI;AAAA,EAC7C;AAEA,MAAI,cAAc,KAAK;AACrB,UAAM,IAAI,kBAAkB,IAAI,QAAQ;AACxC,QAAI,MAAM,OAAW,QAAO,IAAI;AAAA,QAC3B,KAAI,WAAW;AAAA,EACtB;AACA,MAAI,aAAa,KAAK;AACpB,UAAM,IAAI,kBAAkB,IAAI,OAAO;AACvC,QAAI,MAAM,OAAW,QAAO,IAAI;AAAA,QAC3B,KAAI,UAAU;AAAA,EACrB;AACA,SAAO;AACT;AAeA,SAAS,oBAAoB,MAAqC;AAChE,MAAI,KAAK,eAAe,OAAW;AAGnC,MAAI,CAAC,KAAK,YAAY;AACpB,WAAO,KAAK;AACZ;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,KAAK,UAAU,GAAG;AAClC,UAAM,QAAQ,KAAK;AACnB,UAAM,MAAM,OAAO,KAAM,KAAK,aAAyC,CAAC,CAAC,EAAE;AAAA,MACzE,CAAC,MAAM,MAAM;AAAA,IACf;AACA,UAAM,UACJ,MAAM,WAAW,IAAI,UAAU,IAAI,IAAI,KAAK,EAAE,SAAS,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC;AACzG,QAAI,QAAS,MAAK,aAAa;AAAA,EACjC;AACF;AAEO,SAAS,eAAe,OAAyB;AACtD,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,IAAI;AAGV,MAAI,EAAE,aAAa,OAAO,EAAE,cAAc,UAAU;AAClD,UAAM,OAAO,EAAE,GAAI,EAAE,UAAsC;AAC3D,QAAI,eAAe,SAAS,CAAC,KAAK,aAAa,OAAO,KAAK,KAAK,SAAmB,EAAE,WAAW,IAAI;AAClG,aAAO,KAAK;AAAA,IACd;AACA,QAAI,KAAK,cAAc,OAAW,MAAK,YAAY,cAAc,KAAK,SAAS;AAC/E,wBAAoB,IAAI;AACxB,WAAO,EAAE,GAAG,GAAG,WAAW,KAAK;AAAA,EACjC;AAGA,QAAM,MAA+B,EAAE,GAAG,EAAE;AAC5C,MAAI,UAAU,QAAQ,CAAC,IAAI,QAAQ,OAAO,KAAK,IAAI,IAAc,EAAE,WAAW,GAAI,QAAO,IAAI;AAC7F,MAAI,IAAI,SAAS,OAAW,KAAI,OAAO,cAAc,IAAI,IAAI;AAC7D,SAAO;AACT;;;AC5IA,SAAS,gBAAgB,QAA0B;AACjD,QAAM,aAAa,IAAI,MAAc,OAAO,MAAM;AAClD,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,eAAW,CAAC,IAAI;AAChB,QAAI,OAAO,CAAC,MAAM,KAAM;AAAA,EAC1B;AACA,SAAO;AACT;AAGA,SAAS,SAAS,OAAkD;AAClE,QAAM,YAAY,MAAM;AACxB,QAAM,YAAY,YAAY,UAAU,YAAY,MAAM;AAC1D,SAAO,aAAa,OAAO,cAAc,WAAY,YAAqB;AAC5E;AAOO,SAAS,kBAAkB,QAAyB;AACzD,QAAM,UAAmB,oBAAI,IAAI;AACjC,MAAI;AACF,UAAM,EAAE,OAAO,MAAM,IAAI,UAAU,QAAQ,EAAE,cAAc,KAAK,CAAC;AACjE,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,OAAO,SAAS,KAAK;AAC3B,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,aAAa,gBAAgB,MAAM;AACzC,UAAM,UAAU,CAAC,UAA+B;AAAA,MAC9C,WAAW,WAAW,KAAK,KAAK,KAAK;AAAA,MACrC,SAAS,WAAW,KAAK,MAAM,CAAC,KAAK,WAAW,KAAK,KAAK,KAAK;AAAA,IACjE;AAEA,UAAM,OAAO,CAAC,MAAY,QAAsB;AAC9C,YAAM,OAAO,MAAM,IAAI,IAAI;AAC3B,UAAI,KAAM,SAAQ,IAAI,KAAK,QAAQ,IAAI,CAAC;AACxC,YAAM,WAAW,KAAK;AACtB,UAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,iBAAS,QAAQ,CAAC,OAAO,MAAM;AAC7B,cAAI,SAAS,OAAO,UAAU,UAAU;AACtC,iBAAK,OAAe,QAAQ,KAAK,OAAO,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,EAAE;AAAA,UAC5D;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,SAAK,MAAM,EAAE;AAAA,EACf,QAAQ;AAAA,EAER;AACA,SAAO;AACT;;;AClBO,SAAS,KAAK,OAAqB,MAA4B;AAGpE,QAAM,IAAI,eAAe,KAAK;AAC9B,MAAI,KAAK,OAAO,MAAM,UAAU;AAE9B,QAAI,EAAE,aAAa,OAAO,EAAE,cAAc,SAAU,QAAO,cAAc,EAAE,WAAW,IAAI;AAE1F,QACE,EAAE,cAAc,UAChB,EAAE,cAAc,UAChB,EAAE,eAAe,UACjB,EAAE,QAAQ,QACV;AACA,aAAO,cAAc,GAAoC,IAAI;AAAA,IAC/D;AAAA,EACF;AAEA,SAAO,SAAS,GAAe,IAAI;AACrC;AAGO,SAAS,MAAM,QAA6B;AACjD,QAAM,EAAE,MAAM,IAAI,UAAU,MAAM;AAGlC,SAAO,EAAE,OAAO,eAAe,KAAK,GAAmB,SAAS,CAAC,EAAE;AACrE;",
6
+ "names": ["startCol", "pad", "expr", "WS", "skipWs", "node", "attributes", "leadingWs", "hasStyleContent"]
7
+ }
@@ -3,7 +3,7 @@ import {
3
3
  emit,
4
4
  normalizeModel,
5
5
  parse
6
- } from "../../chunks/chunk-YU23XI6A.js";
6
+ } from "../../chunks/chunk-ACHLFXXY.js";
7
7
  import "../../chunks/chunk-I57UVB4P.js";
8
8
  import "../../chunks/chunk-ZYQNHI3W.js";
9
9
  export {
package/dist/lib/index.js CHANGED
@@ -45,6 +45,39 @@ function loadFontCss(projectRoot) {
45
45
  }
46
46
  }
47
47
 
48
+ // lib/runtime/refs.ts
49
+ function isMapping(value) {
50
+ return !!value && typeof value === "object" && value._mapping === true && typeof value.prop === "string";
51
+ }
52
+ function toHrefString(value) {
53
+ if (typeof value === "string") return value;
54
+ if (value && typeof value === "object" && "href" in value) {
55
+ const h = value.href;
56
+ return typeof h === "string" ? h : "#";
57
+ }
58
+ return "#";
59
+ }
60
+ function href(value, props) {
61
+ if (!isMapping(value)) return toHrefString(value);
62
+ const propValue = props?.[value.prop];
63
+ if (propValue === void 0 || propValue === null) return "#";
64
+ if (typeof propValue === "object" && propValue !== null && "href" in propValue) {
65
+ return toHrefString(propValue);
66
+ }
67
+ if (value.values) return toHrefString(value.values[String(propValue)]);
68
+ return toHrefString(propValue);
69
+ }
70
+ function embedHtml(value, props) {
71
+ if (!isMapping(value)) return typeof value === "string" ? value : "";
72
+ const propValue = props?.[value.prop];
73
+ if (propValue === void 0 || propValue === null) return "";
74
+ if (value.values && Object.keys(value.values).length > 0) {
75
+ const mapped = value.values[String(propValue)];
76
+ return typeof mapped === "string" ? mapped : "";
77
+ }
78
+ return typeof propValue === "string" ? propValue : "";
79
+ }
80
+
48
81
  // lib/runtime/collectionList.ts
49
82
  async function getCollectionList(source, query = {}, astro, getCollection) {
50
83
  if (typeof getCollection !== "function") return [];
@@ -150,10 +183,12 @@ export {
150
183
  createLocaleMiddleware,
151
184
  deriveLocale,
152
185
  dialectVersion,
186
+ embedHtml,
153
187
  extractLocaleFromPath,
154
188
  flushCollectedStyles,
155
189
  getCollectionList,
156
190
  getLocaleContext,
191
+ href,
157
192
  i18n,
158
193
  isI18nValue,
159
194
  list,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../lib/server/loadFontCss.ts", "../../lib/runtime/collectionList.ts", "../../lib/index.ts"],
4
- "sourcesContent": ["/**\n * meno-astro/server \u2014 `loadFontCss`.\n *\n * Reads a project's `project.config.json`, pulls its `fonts` array, and renders the\n * `@font-face` rules + `<link rel=\"preload\">` tags for `BaseLayout.astro` to drop into\n * `<head>`. This is the dialect twin's counterpart to what meno-core's SSR\n * (`htmlGenerator`) and JSON\u2192Astro export (`build-astro`) already emit \u2014 without it the\n * font files ship but are never *defined*, so any `font-family: 'Inter'` declared via\n * `style()` silently falls back to a system font.\n *\n * Formatting is delegated wholesale to meno-core's pure `fontCss` helpers so all three\n * renderers stay byte-identical. Any failure (missing file, bad JSON, no `fonts`)\n * degrades to empty strings \u2014 a project always renders, just without custom fonts.\n *\n * Server/build-only (touches the filesystem); BaseLayout's frontmatter runs at\n * build/SSR time, never in the browser.\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\n// Import from the `meno-core/shared` barrel (not the deep `./fontCss` path): the\n// published meno-core bundles shared modules into the barrel and does not emit\n// `dist/lib/shared/fontCss.js`, so the deep path would 404 in a consumer project.\nimport { fontFaceCss, fontPreloadLinks, type FontConfig } from 'meno-core/shared';\n\nexport interface FontHeadAssets {\n /** `@font-face` rules for a `<style>` tag (empty string when no fonts). */\n css: string;\n /** `<link rel=\"preload\">` tags (empty string when no fonts). */\n preloads: string;\n}\n\nconst EMPTY: FontHeadAssets = { css: '', preloads: '' };\n\n/**\n * Load font `<head>` assets for the project rooted at `projectRoot`.\n *\n * Resolution: read `<projectRoot>/project.config.json`, take its `.fonts` array, and\n * format it. Never throws \u2014 every failure path returns empty strings.\n */\nexport function loadFontCss(projectRoot: string): FontHeadAssets {\n try {\n const cfgPath = join(projectRoot, 'project.config.json');\n if (!existsSync(cfgPath)) return EMPTY;\n const parsed = JSON.parse(readFileSync(cfgPath, 'utf8')) as { fonts?: FontConfig[] };\n const fonts = Array.isArray(parsed.fonts) ? parsed.fonts : [];\n if (fonts.length === 0) return EMPTY;\n return { css: fontFaceCss(fonts), preloads: fontPreloadLinks(fonts) };\n } catch {\n return EMPTY;\n }\n}\n", "/**\n * Runtime helper for CMS list nodes (`sourceType: 'collection'`) in the meno-astro\n * dialect. The emitter generates:\n *\n * const blogList = await getCollectionList(\"blog\", { sort, filter, limit, \u2026 }, Astro);\n * blogList.map((blog, blogIndex) => ( \u2026 ))\n *\n * It pulls the collection's items from Astro's content layer (`astro:content`\n * `getCollection`) and applies the same query semantics as the JSON runtime's\n * `CMSService.queryItems` / `getItemsByIds` (mirrored here so both render the same\n * lists). Each returned item is the raw stored JSON (`entry.data`) \u2014 the converter\n * writes items with a permissive `z.record(z.string(), z.any())` schema, so `_id`,\n * `_createdAt`, and all fields sit at the top level, exactly as the emitted child\n * template expects (`blog.title`, `blog._createdAt`, \u2026).\n *\n * `astro:content`'s `getCollection` is passed IN by the calling page (which lives in\n * the host Astro project where the virtual module resolves natively). meno-astro never\n * imports `astro:content` itself \u2014 doing so from inside node_modules both breaks\n * non-Astro loaders (tooling/tests) and corrupts Astro's generated content module.\n */\n\ntype GetCollection = (name: string) => Promise<Array<{ data: Record<string, any> }>>;\n\ntype Item = Record<string, any>;\ntype SortConfig = { field: string; order?: 'asc' | 'desc' };\ntype FilterCondition = { field: string; operator?: string; value?: unknown };\n\nexport interface CollectionListQuery {\n filter?: FilterCondition | FilterCondition[] | Record<string, unknown>;\n sort?: SortConfig | SortConfig[];\n limit?: number;\n offset?: number;\n /** Explicit id/filename list (reference fields) \u2014 preserves the given order. */\n items?: string[] | string;\n /** Drop the current page's CMS item (for related-item lists on template routes). */\n excludeCurrentItem?: boolean;\n /** Emit-only hint; unused at runtime. */\n emitTemplate?: unknown;\n}\n\ninterface AstroLike {\n props?: { cms?: { _id?: string } | undefined } & Record<string, unknown>;\n}\n\n/**\n * Resolve a CMS collection list to its items, applying the node's query. `getCollection`\n * is the host project's `astro:content` export, passed by the emitted page.\n */\nexport async function getCollectionList(\n source: string,\n query: CollectionListQuery = {},\n astro?: AstroLike,\n getCollection?: GetCollection,\n): Promise<Item[]> {\n if (typeof getCollection !== 'function') return [];\n let entries: Array<{ data: Item }>;\n try {\n entries = await getCollection(source);\n } catch {\n // No such collection \u2192 empty list (matches the SSR fallback).\n return [];\n }\n\n let items: Item[] = entries.map((e) => e.data);\n\n if (query.items !== undefined) {\n // Reference-field path: fetch specific ids in order (match _id or _filename),\n // skipping missing \u2014 mirrors CMSService.getItemsByIds.\n const ids = (Array.isArray(query.items) ? query.items : [query.items]).filter(Boolean).map(String);\n const byId = new Map(items.map((i) => [i._id, i]));\n const byFilename = new Map(items.filter((i) => i._filename).map((i) => [i._filename, i]));\n items = ids.map((id) => byId.get(id) ?? byFilename.get(id)).filter((i): i is Item => i !== undefined);\n } else {\n if (query.filter) items = applyFilters(items, query.filter);\n if (query.sort) items = applySorting(items, query.sort);\n if (query.offset !== undefined && query.offset > 0) items = items.slice(query.offset);\n if (query.limit !== undefined && query.limit > 0) items = items.slice(0, query.limit);\n }\n\n // Exclude the current CMS item (template [slug] pages pass it on Astro.props.cms).\n if (query.excludeCurrentItem) {\n const currentId = astro?.props?.cms?._id;\n if (currentId) items = items.filter((i) => i._id !== currentId);\n }\n\n return items;\n}\n\n// --- filter/sort, ported verbatim from CMSService for identical semantics ---\n\nfunction isFilterCondition(obj: unknown): obj is FilterCondition {\n return typeof obj === 'object' && obj !== null && 'field' in obj;\n}\n\nfunction applyFilters(\n items: Item[],\n filter: FilterCondition | FilterCondition[] | Record<string, unknown>,\n): Item[] {\n // Simple object filter: { featured: true } \u2192 equality on every key.\n if (!Array.isArray(filter) && !isFilterCondition(filter)) {\n const entries = Object.entries(filter);\n return items.filter((item) => entries.every(([key, value]) => item[key] === value));\n }\n const conditions = Array.isArray(filter) ? filter : [filter as FilterCondition];\n return items.filter((item) => conditions.every((cond) => matchCondition(item, cond)));\n}\n\nfunction matchCondition(item: Item, condition: FilterCondition): boolean {\n const value = item[condition.field];\n switch (condition.operator || 'eq') {\n case 'eq': return value === condition.value;\n case 'neq': return value !== condition.value;\n case 'gt': return (value as number) > (condition.value as number);\n case 'gte': return (value as number) >= (condition.value as number);\n case 'lt': return (value as number) < (condition.value as number);\n case 'lte': return (value as number) <= (condition.value as number);\n case 'contains': return String(value).includes(String(condition.value));\n case 'in': return Array.isArray(condition.value) && condition.value.includes(value);\n default: return false;\n }\n}\n\nfunction applySorting(items: Item[], sort: SortConfig | SortConfig[]): Item[] {\n const sorts = Array.isArray(sort) ? sort : [sort];\n return [...items].sort((a, b) => {\n for (const s of sorts) {\n const aVal = a[s.field];\n const bVal = b[s.field];\n const isDesc = s.order === 'desc';\n if (typeof aVal === 'boolean' && typeof bVal === 'boolean') {\n if (aVal === bVal) continue;\n return isDesc ? (aVal ? -1 : 1) : (aVal ? 1 : -1);\n }\n let result = 0;\n if ((aVal as string | number) < (bVal as string | number)) result = -1;\n else if ((aVal as string | number) > (bVal as string | number)) result = 1;\n if (result !== 0) return isDesc ? -result : result;\n }\n return 0;\n });\n}\n", "/**\n * meno-astro \u2014 runtime entry point.\n *\n * This is the package that Meno-generated Astro projects import at runtime so the\n * `.astro` source stays thin and consistent (one shared resolver for styles, i18n,\n * and CMS queries \u2014 the same code paths the Studio React preview uses).\n *\n * Design note: `meno-astro` depends on `meno-core` (single direction). The heavy,\n * battle-tested logic (style/utility-class generation, i18n resolution, CMS query\n * parsing, the template engine) lives in `meno-core` and is composed here behind a\n * curated, stable surface. No `meno-core` files move, so the existing JSON runtime is\n * untouched by construction. Slimming the published bundle (so generated projects do\n * not transitively pull all of `meno-core`) is a later optimization.\n */\n\nimport type {\n JSONPage,\n PageData,\n ComponentNode,\n StructuredComponentDefinition,\n PropDefinition,\n StyleObject,\n ResponsiveStyleObject,\n} from 'meno-core/shared/types';\n\n// ---------------------------------------------------------------------------\n// Dialect version \u2014 written into generated projects so a project can be\n// migrated forward if the on-disk `.astro` dialect format evolves. Part of the\n// package's semver contract.\n// ---------------------------------------------------------------------------\nexport const dialectVersion = '0.1.0' as const;\n\n// ---------------------------------------------------------------------------\n// Model types re-exported for the dialect + generated projects. These are the\n// Meno in-memory model the emitter serializes and the parser reconstructs.\n// ---------------------------------------------------------------------------\nexport type {\n JSONPage,\n PageData,\n ComponentNode,\n StructuredComponentDefinition,\n PropDefinition,\n StyleObject,\n ResponsiveStyleObject,\n};\n\n/** A responsive style payload as carried verbatim in `style({...})` calls. */\nexport type MenoStyle = ResponsiveStyleObject | StyleObject;\n\n/** A component's prop definitions, as carried by the `resolveProps(Astro, {\u2026})` call. */\nexport type MenoProps = Record<string, PropDefinition>;\n\n/** A page's `export const meta` payload. */\nexport type MenoPageMeta = NonNullable<JSONPage['meta']>;\n\n/**\n * A component's non-interface metadata, carried by the `__meno` frontmatter const.\n * `defineVars` is intentionally not here: it is emitted as the script's native\n * `<script define:vars={{\u2026}}>` directive and reconstructed on parse, not via `__meno`.\n */\nexport type MenoComponentMeta = Pick<\n StructuredComponentDefinition,\n 'category' | 'acceptsStyles' | 'libraries'\n>;\n\n// ---------------------------------------------------------------------------\n// Curated runtime helpers, composed from meno-core. The dialect-specific wrappers\n// the emitter targets are landing incrementally: `i18n()` and `list()` are implemented\n// (below / `runtime/i18n.ts`); `style()`, `getCollectionList()`, `when()`, and\n// `embedHtml()` remain pending. The primitives re-exported here are the\n// unambiguous, dependency-free foundations they build on.\n// ---------------------------------------------------------------------------\n\n// i18n resolution (pure primitives; only type-imports inside meno-core).\nexport {\n isI18nValue,\n resolveI18nValue,\n extractLocaleFromPath,\n buildLocalizedPath,\n} from 'meno-core/shared';\n\n// i18n runtime \u2014 the emitter-facing `i18n()` resolver + its locale-context seam.\n// Emitted markup calls `i18n({\u2026})`; `runWithLocale` is how BaseLayout/middleware will\n// set the active locale per route. See `runtime/i18n.ts`.\nexport {\n i18n,\n runWithLocale,\n getLocaleContext,\n localeFromAstro,\n} from './runtime/i18n';\nexport type {\n LocaleContextValue,\n AstroLike,\n I18nOverride,\n} from './runtime/i18n';\n\n// Locale middleware factory \u2014 wraps each page render in `runWithLocale(...)` so `i18n()`\n// resolves per locale. `createLocaleMiddleware(config)` is the pure, testable factory;\n// `deriveLocale` is its locale-selection policy. The injected middleware module (the one\n// the integration points Astro at) lives at the `meno-astro/runtime/localeMiddleware`\n// subpath. See `runtime/middleware.ts`.\nexport {\n createLocaleMiddleware,\n deriveLocale,\n} from './runtime/middleware';\nexport type {\n LocaleMiddleware,\n LocaleMiddlewareContext,\n} from './runtime/middleware';\n\n// loadI18nConfig \u2014 read + migrate a converted project's i18n config (server/build helper).\n// Also available from `meno-astro/server`; re-exported here as the natural root surface\n// for the middleware/integration story. Touches the filesystem (server/build only).\nexport { loadI18nConfig } from './server/loadI18nConfig';\n\n// loadFontCss \u2014 read a project's `fonts` config \u2192 `@font-face` CSS + preload tags for\n// BaseLayout's <head>. Re-exported here (alongside loadI18nConfig) so the published\n// BaseLayout component can reach it; `meno-astro/server` is workspace-only and not\n// shipped. Touches the filesystem (build/SSR only \u2014 runs in BaseLayout frontmatter).\nexport { loadFontCss } from './server/loadFontCss';\nexport type { FontHeadAssets } from './server/loadFontCss';\n\n// style() runtime \u2014 the emitter-facing style resolver + its module-level CSS collector.\n// Emitted markup calls `style(styleObject[, props][, meta])`; the collector is what a\n// future BaseLayout/integration flushes into a `<style>` tag. See `runtime/style.ts`.\n// IMPLEMENTED (PoC): the prop-bound `_mapping` resolver (option A) + CSS collector,\n// proven by `style.test.ts`. The emit threading of `props` and the render-path flush\n// remain (gated on this PoC).\nexport {\n style,\n flushCollectedStyles,\n resetStyleCollector,\n} from './runtime/style';\nexport type { StyleMeta } from './runtime/style';\n\n/**\n * Prop-list helper used by generated `.astro`: `list(items, { limit, offset }).map(\u2026)`.\n * Tolerates null/undefined sources and applies offset/limit. (The scope-aware\n * `when()` / `href()` runtime + the CSS-injection integration are the remaining,\n * Astro-toolchain-verified part of Phase 0b.)\n */\nexport function list<T>(\n source: T[] | null | undefined,\n opts?: { offset?: number; limit?: number },\n): T[] {\n let out = Array.isArray(source) ? source : [];\n if (opts?.offset) out = out.slice(opts.offset);\n if (opts?.limit != null) out = out.slice(0, opts.limit);\n return out;\n}\n\n// CMS collection list helper used by generated `.astro`:\n// `const blogList = await getCollectionList(\"blog\", { sort, limit, \u2026 }, Astro)`.\n// Pulls items from astro:content and applies the JSON runtime's query semantics.\nexport { getCollectionList } from './runtime/collectionList';\nexport type { CollectionListQuery } from './runtime/collectionList';\n\n// CMS filter/sort expression parsing + serialization (pure).\nexport {\n parseFilterExpression,\n serializeFilterExpression,\n parseSortExpression,\n serializeSortExpression,\n} from 'meno-core/shared';\n\n// ---------------------------------------------------------------------------\n// resolveProps \u2014 the single authoritative prop block for `.astro` components.\n//\n// A component's frontmatter declares its props exactly once:\n//\n// const { text, isMarginTop, class: className } = resolveProps(Astro, {\n// text: { type: \"string\", default: \"Link\" },\n// isMarginTop: { type: \"boolean\", default: false },\n// });\n//\n// The `{\u2026}` literal is the authoritative prop definition the dialect parser reads\n// back into `def.interface`. At runtime this merges `Astro.props` over each def's\n// `default` (and always provides `class`, defaulting to \"\"). The destructured locals\n// are typed by inferring each prop's value type from its definition (mirroring the\n// old `interface Props` mapping), so editing the file stays fully type-checked.\n// ---------------------------------------------------------------------------\n\n/** Map a single prop definition to the runtime value type of that prop. */\ntype InferMenoProp<D> =\n D extends { type: 'number' } ? number :\n D extends { type: 'boolean' } ? boolean :\n D extends { type: 'link' } ? { href: string; target?: string } :\n D extends { type: 'list' } ? unknown[] :\n D extends { type: 'select'; options: infer O }\n ? (O extends readonly (infer U)[] ? U : string)\n : string; // string, rich-text, image, embed, file \u2192 string\n\n/** Map a whole prop-definition record to the destructured locals' value types. */\ntype InferMenoProps<T extends MenoProps> = { [K in keyof T]: InferMenoProp<T[K]> };\n\n/**\n * Resolve a component's props from `Astro.props`, merging each provided value over\n * its declared `default` and always supplying `class` (defaulting to \"\").\n *\n * `defs` is the authoritative prop definition (the same literal the dialect parser\n * reads). The `const` type parameter preserves literal `type`/`options` so the\n * returned locals are precisely typed (e.g. `select` options become a string union).\n */\nexport function resolveProps<const T extends MenoProps>(\n astro: { props: Record<string, unknown> },\n defs: T,\n): InferMenoProps<T> & { class: string } {\n const props = astro.props ?? {};\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(defs)) {\n if (key === 'children') continue;\n const provided = props[key];\n out[key] = provided !== undefined ? provided : (defs[key] as PropDefinition).default;\n }\n out.class = typeof props.class === 'string' ? props.class : '';\n return out as InferMenoProps<T> & { class: string };\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../../lib/server/loadFontCss.ts", "../../lib/runtime/refs.ts", "../../lib/runtime/collectionList.ts", "../../lib/index.ts"],
4
+ "sourcesContent": ["/**\n * meno-astro/server \u2014 `loadFontCss`.\n *\n * Reads a project's `project.config.json`, pulls its `fonts` array, and renders the\n * `@font-face` rules + `<link rel=\"preload\">` tags for `BaseLayout.astro` to drop into\n * `<head>`. This is the dialect twin's counterpart to what meno-core's SSR\n * (`htmlGenerator`) and JSON\u2192Astro export (`build-astro`) already emit \u2014 without it the\n * font files ship but are never *defined*, so any `font-family: 'Inter'` declared via\n * `style()` silently falls back to a system font.\n *\n * Formatting is delegated wholesale to meno-core's pure `fontCss` helpers so all three\n * renderers stay byte-identical. Any failure (missing file, bad JSON, no `fonts`)\n * degrades to empty strings \u2014 a project always renders, just without custom fonts.\n *\n * Server/build-only (touches the filesystem); BaseLayout's frontmatter runs at\n * build/SSR time, never in the browser.\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\n// Import from the `meno-core/shared` barrel (not the deep `./fontCss` path): the\n// published meno-core bundles shared modules into the barrel and does not emit\n// `dist/lib/shared/fontCss.js`, so the deep path would 404 in a consumer project.\nimport { fontFaceCss, fontPreloadLinks, type FontConfig } from 'meno-core/shared';\n\nexport interface FontHeadAssets {\n /** `@font-face` rules for a `<style>` tag (empty string when no fonts). */\n css: string;\n /** `<link rel=\"preload\">` tags (empty string when no fonts). */\n preloads: string;\n}\n\nconst EMPTY: FontHeadAssets = { css: '', preloads: '' };\n\n/**\n * Load font `<head>` assets for the project rooted at `projectRoot`.\n *\n * Resolution: read `<projectRoot>/project.config.json`, take its `.fonts` array, and\n * format it. Never throws \u2014 every failure path returns empty strings.\n */\nexport function loadFontCss(projectRoot: string): FontHeadAssets {\n try {\n const cfgPath = join(projectRoot, 'project.config.json');\n if (!existsSync(cfgPath)) return EMPTY;\n const parsed = JSON.parse(readFileSync(cfgPath, 'utf8')) as { fonts?: FontConfig[] };\n const fonts = Array.isArray(parsed.fonts) ? parsed.fonts : [];\n if (fonts.length === 0) return EMPTY;\n return { css: fontFaceCss(fonts), preloads: fontPreloadLinks(fonts) };\n } catch {\n return EMPTY;\n }\n}\n", "/**\n * meno-astro \u2014 `href()` / `embedHtml()` runtime resolvers.\n *\n * Emitted markup binds a Link's `href` and an Embed's `html` through these helpers when\n * the model value is a prop-`_mapping` (`{ _mapping: true, prop, values? }`) rather than a\n * literal string/template:\n *\n * <Link href={href(mapping, __props)} />\n * <Embed html={embedHtml(mapping, __props)} />\n *\n * `__props` is the host component's resolved props (threaded by the emitter, exactly like\n * `style()`); pages have no props scope, so the emitter calls the 1-arg form and the\n * mapping degrades to a safe default.\n *\n * \u2500\u2500 Parity with meno-core \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * These mirror meno-core's canonical `resolveLinkMapping` / `resolveHtmlMapping`\n * (`client/templateEngine.ts`), re-implemented locally so this Node/SSR package keeps its\n * narrow `meno-core/shared`-only import graph \u2014 the `meno-core/client` barrel re-exports\n * the whole React renderer (and browser globals), which must not enter an Astro build.\n * `style.ts` mirrors core's style-mapping resolver for the same reason.\n *\n * Both mapping modes are supported, matching core:\n * - value mapping: `mapping.values[String(props[prop])]`\n * - passthrough : `props[prop]` used directly (an object link `{ href, target? }` or a\n * bare string URL / HTML string) when `values` is omitted/empty.\n * The resolved link is flattened to its URL the same way the JSON\u2192Astro exporter does\n * (`(typeof v === 'string' ? v : v?.href) ?? '#'`) \u2014 the dialect `Link.astro` takes a\n * string `href`. Anything that can't resolve (no props, prop unset, missing key) degrades\n * to a safe default \u2014 `\"#\"` for href, `\"\"` for html \u2014 and never throws.\n */\n\n/** A prop-binding `_mapping` of either link or html flavour. */\ninterface RefMapping {\n _mapping: true;\n prop: string;\n values?: Record<string, unknown>;\n}\n\nfunction isMapping(value: unknown): value is RefMapping {\n return (\n !!value &&\n typeof value === 'object' &&\n (value as { _mapping?: unknown })._mapping === true &&\n typeof (value as { prop?: unknown }).prop === 'string'\n );\n}\n\n/** Flatten a resolved link value (object `{ href }` or bare string) to its URL, else `\"#\"`. */\nfunction toHrefString(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value && typeof value === 'object' && 'href' in value) {\n const h = (value as { href?: unknown }).href;\n return typeof h === 'string' ? h : '#';\n }\n return '#';\n}\n\n/**\n * Resolve a Link node's `href` to a URL string.\n *\n * @param value A `LinkMapping` (`{ _mapping, prop, values? }`) for a prop-bound link, or\n * an already-literal value (passed straight through).\n * @param props The host component's resolved props (`__props`); absent for pages.\n * @returns The URL the dialect `Link.astro` renders; `\"#\"` when unresolvable.\n */\nexport function href(value: unknown, props?: Record<string, unknown>): string {\n if (!isMapping(value)) return toHrefString(value);\n const propValue = props?.[value.prop];\n if (propValue === undefined || propValue === null) return '#';\n // Passthrough: the prop value is already a link object \u2014 use it directly (mirrors\n // resolveLinkMapping, which prefers passthrough even when a `values` table exists).\n if (typeof propValue === 'object' && propValue !== null && 'href' in propValue) {\n return toHrefString(propValue);\n }\n // Value-mapping mode: look the prop value up in the mapping table.\n if (value.values) return toHrefString(value.values[String(propValue)]);\n // Passthrough of a coerced string URL.\n return toHrefString(propValue);\n}\n\n/**\n * Resolve an Embed node's `html` to an HTML string.\n *\n * @param value An `HtmlMapping` (`{ _mapping, prop, values? }`) for a prop-bound embed, or\n * an already-literal string (passed straight through).\n * @param props The host component's resolved props (`__props`); absent for pages.\n * @returns The HTML string to inject; `\"\"` when unresolvable.\n */\nexport function embedHtml(value: unknown, props?: Record<string, unknown>): string {\n if (!isMapping(value)) return typeof value === 'string' ? value : '';\n const propValue = props?.[value.prop];\n if (propValue === undefined || propValue === null) return '';\n // Value-mapping mode (non-empty table); else passthrough of a string prop.\n if (value.values && Object.keys(value.values).length > 0) {\n const mapped = value.values[String(propValue)];\n return typeof mapped === 'string' ? mapped : '';\n }\n return typeof propValue === 'string' ? propValue : '';\n}\n", "/**\n * Runtime helper for CMS list nodes (`sourceType: 'collection'`) in the meno-astro\n * dialect. The emitter generates:\n *\n * const blogList = await getCollectionList(\"blog\", { sort, filter, limit, \u2026 }, Astro);\n * blogList.map((blog, blogIndex) => ( \u2026 ))\n *\n * It pulls the collection's items from Astro's content layer (`astro:content`\n * `getCollection`) and applies the same query semantics as the JSON runtime's\n * `CMSService.queryItems` / `getItemsByIds` (mirrored here so both render the same\n * lists). Each returned item is the raw stored JSON (`entry.data`) \u2014 the converter\n * writes items with a permissive `z.record(z.string(), z.any())` schema, so `_id`,\n * `_createdAt`, and all fields sit at the top level, exactly as the emitted child\n * template expects (`blog.title`, `blog._createdAt`, \u2026).\n *\n * `astro:content`'s `getCollection` is passed IN by the calling page (which lives in\n * the host Astro project where the virtual module resolves natively). meno-astro never\n * imports `astro:content` itself \u2014 doing so from inside node_modules both breaks\n * non-Astro loaders (tooling/tests) and corrupts Astro's generated content module.\n */\n\ntype GetCollection = (name: string) => Promise<Array<{ data: Record<string, any> }>>;\n\ntype Item = Record<string, any>;\ntype SortConfig = { field: string; order?: 'asc' | 'desc' };\ntype FilterCondition = { field: string; operator?: string; value?: unknown };\n\nexport interface CollectionListQuery {\n filter?: FilterCondition | FilterCondition[] | Record<string, unknown>;\n sort?: SortConfig | SortConfig[];\n limit?: number;\n offset?: number;\n /** Explicit id/filename list (reference fields) \u2014 preserves the given order. */\n items?: string[] | string;\n /** Drop the current page's CMS item (for related-item lists on template routes). */\n excludeCurrentItem?: boolean;\n /** Emit-only hint; unused at runtime. */\n emitTemplate?: unknown;\n}\n\ninterface AstroLike {\n props?: { cms?: { _id?: string } | undefined } & Record<string, unknown>;\n}\n\n/**\n * Resolve a CMS collection list to its items, applying the node's query. `getCollection`\n * is the host project's `astro:content` export, passed by the emitted page.\n */\nexport async function getCollectionList(\n source: string,\n query: CollectionListQuery = {},\n astro?: AstroLike,\n getCollection?: GetCollection,\n): Promise<Item[]> {\n if (typeof getCollection !== 'function') return [];\n let entries: Array<{ data: Item }>;\n try {\n entries = await getCollection(source);\n } catch {\n // No such collection \u2192 empty list (matches the SSR fallback).\n return [];\n }\n\n let items: Item[] = entries.map((e) => e.data);\n\n if (query.items !== undefined) {\n // Reference-field path: fetch specific ids in order (match _id or _filename),\n // skipping missing \u2014 mirrors CMSService.getItemsByIds.\n const ids = (Array.isArray(query.items) ? query.items : [query.items]).filter(Boolean).map(String);\n const byId = new Map(items.map((i) => [i._id, i]));\n const byFilename = new Map(items.filter((i) => i._filename).map((i) => [i._filename, i]));\n items = ids.map((id) => byId.get(id) ?? byFilename.get(id)).filter((i): i is Item => i !== undefined);\n } else {\n if (query.filter) items = applyFilters(items, query.filter);\n if (query.sort) items = applySorting(items, query.sort);\n if (query.offset !== undefined && query.offset > 0) items = items.slice(query.offset);\n if (query.limit !== undefined && query.limit > 0) items = items.slice(0, query.limit);\n }\n\n // Exclude the current CMS item (template [slug] pages pass it on Astro.props.cms).\n if (query.excludeCurrentItem) {\n const currentId = astro?.props?.cms?._id;\n if (currentId) items = items.filter((i) => i._id !== currentId);\n }\n\n return items;\n}\n\n// --- filter/sort, ported verbatim from CMSService for identical semantics ---\n\nfunction isFilterCondition(obj: unknown): obj is FilterCondition {\n return typeof obj === 'object' && obj !== null && 'field' in obj;\n}\n\nfunction applyFilters(\n items: Item[],\n filter: FilterCondition | FilterCondition[] | Record<string, unknown>,\n): Item[] {\n // Simple object filter: { featured: true } \u2192 equality on every key.\n if (!Array.isArray(filter) && !isFilterCondition(filter)) {\n const entries = Object.entries(filter);\n return items.filter((item) => entries.every(([key, value]) => item[key] === value));\n }\n const conditions = Array.isArray(filter) ? filter : [filter as FilterCondition];\n return items.filter((item) => conditions.every((cond) => matchCondition(item, cond)));\n}\n\nfunction matchCondition(item: Item, condition: FilterCondition): boolean {\n const value = item[condition.field];\n switch (condition.operator || 'eq') {\n case 'eq': return value === condition.value;\n case 'neq': return value !== condition.value;\n case 'gt': return (value as number) > (condition.value as number);\n case 'gte': return (value as number) >= (condition.value as number);\n case 'lt': return (value as number) < (condition.value as number);\n case 'lte': return (value as number) <= (condition.value as number);\n case 'contains': return String(value).includes(String(condition.value));\n case 'in': return Array.isArray(condition.value) && condition.value.includes(value);\n default: return false;\n }\n}\n\nfunction applySorting(items: Item[], sort: SortConfig | SortConfig[]): Item[] {\n const sorts = Array.isArray(sort) ? sort : [sort];\n return [...items].sort((a, b) => {\n for (const s of sorts) {\n const aVal = a[s.field];\n const bVal = b[s.field];\n const isDesc = s.order === 'desc';\n if (typeof aVal === 'boolean' && typeof bVal === 'boolean') {\n if (aVal === bVal) continue;\n return isDesc ? (aVal ? -1 : 1) : (aVal ? 1 : -1);\n }\n let result = 0;\n if ((aVal as string | number) < (bVal as string | number)) result = -1;\n else if ((aVal as string | number) > (bVal as string | number)) result = 1;\n if (result !== 0) return isDesc ? -result : result;\n }\n return 0;\n });\n}\n", "/**\n * meno-astro \u2014 runtime entry point.\n *\n * This is the package that Meno-generated Astro projects import at runtime so the\n * `.astro` source stays thin and consistent (one shared resolver for styles, i18n,\n * and CMS queries \u2014 the same code paths the Studio React preview uses).\n *\n * Design note: `meno-astro` depends on `meno-core` (single direction). The heavy,\n * battle-tested logic (style/utility-class generation, i18n resolution, CMS query\n * parsing, the template engine) lives in `meno-core` and is composed here behind a\n * curated, stable surface. No `meno-core` files move, so the existing JSON runtime is\n * untouched by construction. Slimming the published bundle (so generated projects do\n * not transitively pull all of `meno-core`) is a later optimization.\n */\n\nimport type {\n JSONPage,\n PageData,\n ComponentNode,\n StructuredComponentDefinition,\n PropDefinition,\n StyleObject,\n ResponsiveStyleObject,\n} from 'meno-core/shared/types';\n\n// ---------------------------------------------------------------------------\n// Dialect version \u2014 written into generated projects so a project can be\n// migrated forward if the on-disk `.astro` dialect format evolves. Part of the\n// package's semver contract.\n// ---------------------------------------------------------------------------\nexport const dialectVersion = '0.1.0' as const;\n\n// ---------------------------------------------------------------------------\n// Model types re-exported for the dialect + generated projects. These are the\n// Meno in-memory model the emitter serializes and the parser reconstructs.\n// ---------------------------------------------------------------------------\nexport type {\n JSONPage,\n PageData,\n ComponentNode,\n StructuredComponentDefinition,\n PropDefinition,\n StyleObject,\n ResponsiveStyleObject,\n};\n\n/** A responsive style payload as carried verbatim in `style({...})` calls. */\nexport type MenoStyle = ResponsiveStyleObject | StyleObject;\n\n/** A component's prop definitions, as carried by the `resolveProps(Astro, {\u2026})` call. */\nexport type MenoProps = Record<string, PropDefinition>;\n\n/** A page's `export const meta` payload. */\nexport type MenoPageMeta = NonNullable<JSONPage['meta']>;\n\n/**\n * A component's non-interface metadata, carried by the `__meno` frontmatter const.\n * `defineVars` is intentionally not here: it is emitted as the script's native\n * `<script define:vars={{\u2026}}>` directive and reconstructed on parse, not via `__meno`.\n */\nexport type MenoComponentMeta = Pick<\n StructuredComponentDefinition,\n 'category' | 'acceptsStyles' | 'libraries'\n>;\n\n// ---------------------------------------------------------------------------\n// Curated runtime helpers, composed from meno-core. The dialect-specific wrappers\n// the emitter targets: `i18n()`, `list()`, `style()`, `getCollectionList()`,\n// `href()`, and `embedHtml()` are implemented (below / `runtime/*.ts`). The primitives\n// re-exported here are the unambiguous, dependency-free foundations they build on.\n// ---------------------------------------------------------------------------\n\n// i18n resolution (pure primitives; only type-imports inside meno-core).\nexport {\n isI18nValue,\n resolveI18nValue,\n extractLocaleFromPath,\n buildLocalizedPath,\n} from 'meno-core/shared';\n\n// i18n runtime \u2014 the emitter-facing `i18n()` resolver + its locale-context seam.\n// Emitted markup calls `i18n({\u2026})`; `runWithLocale` is how BaseLayout/middleware will\n// set the active locale per route. See `runtime/i18n.ts`.\nexport {\n i18n,\n runWithLocale,\n getLocaleContext,\n localeFromAstro,\n} from './runtime/i18n';\nexport type {\n LocaleContextValue,\n AstroLike,\n I18nOverride,\n} from './runtime/i18n';\n\n// Locale middleware factory \u2014 wraps each page render in `runWithLocale(...)` so `i18n()`\n// resolves per locale. `createLocaleMiddleware(config)` is the pure, testable factory;\n// `deriveLocale` is its locale-selection policy. The injected middleware module (the one\n// the integration points Astro at) lives at the `meno-astro/runtime/localeMiddleware`\n// subpath. See `runtime/middleware.ts`.\nexport {\n createLocaleMiddleware,\n deriveLocale,\n} from './runtime/middleware';\nexport type {\n LocaleMiddleware,\n LocaleMiddlewareContext,\n} from './runtime/middleware';\n\n// loadI18nConfig \u2014 read + migrate a converted project's i18n config (server/build helper).\n// Also available from `meno-astro/server`; re-exported here as the natural root surface\n// for the middleware/integration story. Touches the filesystem (server/build only).\nexport { loadI18nConfig } from './server/loadI18nConfig';\n\n// loadFontCss \u2014 read a project's `fonts` config \u2192 `@font-face` CSS + preload tags for\n// BaseLayout's <head>. Re-exported here (alongside loadI18nConfig) so the published\n// BaseLayout component can reach it; `meno-astro/server` is workspace-only and not\n// shipped. Touches the filesystem (build/SSR only \u2014 runs in BaseLayout frontmatter).\nexport { loadFontCss } from './server/loadFontCss';\nexport type { FontHeadAssets } from './server/loadFontCss';\n\n// style() runtime \u2014 the emitter-facing style resolver + its module-level CSS collector.\n// Emitted markup calls `style(styleObject[, props][, meta])`; the collector is what a\n// future BaseLayout/integration flushes into a `<style>` tag. See `runtime/style.ts`.\n// IMPLEMENTED (PoC): the prop-bound `_mapping` resolver (option A) + CSS collector,\n// proven by `style.test.ts`. The emit threading of `props` and the render-path flush\n// remain (gated on this PoC).\nexport {\n style,\n flushCollectedStyles,\n resetStyleCollector,\n} from './runtime/style';\nexport type { StyleMeta } from './runtime/style';\n\n// href() / embedHtml() runtime \u2014 resolve a Link's href / an Embed's html when the model\n// value is a prop-`_mapping`. Emitted markup calls `href(mapping, __props)` /\n// `embedHtml(mapping, __props)`; both mirror meno-core's resolveLinkMapping /\n// resolveHtmlMapping (value-map + passthrough). See `runtime/refs.ts`.\nexport { href, embedHtml } from './runtime/refs';\n\n/**\n * Prop-list helper used by generated `.astro`: `list(items, { limit, offset }).map(\u2026)`.\n * Tolerates null/undefined sources and applies offset/limit. (The scope-aware\n * `when()` / `href()` runtime + the CSS-injection integration are the remaining,\n * Astro-toolchain-verified part of Phase 0b.)\n */\nexport function list<T>(\n source: T[] | null | undefined,\n opts?: { offset?: number; limit?: number },\n): T[] {\n let out = Array.isArray(source) ? source : [];\n if (opts?.offset) out = out.slice(opts.offset);\n if (opts?.limit != null) out = out.slice(0, opts.limit);\n return out;\n}\n\n// CMS collection list helper used by generated `.astro`:\n// `const blogList = await getCollectionList(\"blog\", { sort, limit, \u2026 }, Astro)`.\n// Pulls items from astro:content and applies the JSON runtime's query semantics.\nexport { getCollectionList } from './runtime/collectionList';\nexport type { CollectionListQuery } from './runtime/collectionList';\n\n// CMS filter/sort expression parsing + serialization (pure).\nexport {\n parseFilterExpression,\n serializeFilterExpression,\n parseSortExpression,\n serializeSortExpression,\n} from 'meno-core/shared';\n\n// ---------------------------------------------------------------------------\n// resolveProps \u2014 the single authoritative prop block for `.astro` components.\n//\n// A component's frontmatter declares its props exactly once:\n//\n// const { text, isMarginTop, class: className } = resolveProps(Astro, {\n// text: { type: \"string\", default: \"Link\" },\n// isMarginTop: { type: \"boolean\", default: false },\n// });\n//\n// The `{\u2026}` literal is the authoritative prop definition the dialect parser reads\n// back into `def.interface`. At runtime this merges `Astro.props` over each def's\n// `default` (and always provides `class`, defaulting to \"\"). The destructured locals\n// are typed by inferring each prop's value type from its definition (mirroring the\n// old `interface Props` mapping), so editing the file stays fully type-checked.\n// ---------------------------------------------------------------------------\n\n/** Map a single prop definition to the runtime value type of that prop. */\ntype InferMenoProp<D> =\n D extends { type: 'number' } ? number :\n D extends { type: 'boolean' } ? boolean :\n D extends { type: 'link' } ? { href: string; target?: string } :\n D extends { type: 'list' } ? unknown[] :\n D extends { type: 'select'; options: infer O }\n ? (O extends readonly (infer U)[] ? U : string)\n : string; // string, rich-text, image, embed, file \u2192 string\n\n/** Map a whole prop-definition record to the destructured locals' value types. */\ntype InferMenoProps<T extends MenoProps> = { [K in keyof T]: InferMenoProp<T[K]> };\n\n/**\n * Resolve a component's props from `Astro.props`, merging each provided value over\n * its declared `default` and always supplying `class` (defaulting to \"\").\n *\n * `defs` is the authoritative prop definition (the same literal the dialect parser\n * reads). The `const` type parameter preserves literal `type`/`options` so the\n * returned locals are precisely typed (e.g. `select` options become a string union).\n */\nexport function resolveProps<const T extends MenoProps>(\n astro: { props: Record<string, unknown> },\n defs: T,\n): InferMenoProps<T> & { class: string } {\n const props = astro.props ?? {};\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(defs)) {\n if (key === 'children') continue;\n const provided = props[key];\n out[key] = provided !== undefined ? provided : (defs[key] as PropDefinition).default;\n }\n out.class = typeof props.class === 'string' ? props.class : '';\n return out as InferMenoProps<T> & { class: string };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }