@json-to-office/shared 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/services.ts","../src/fonts/collect.ts","../src/fonts/document-registry.ts","../src/fonts/validator.ts","../src/fonts/synthesize.ts","../src/fonts/sources/data-loader.ts","../src/fonts/sources/google-fetcher.ts","../src/fonts/sources/url-fetcher.ts","../src/fonts/sources/ttf-validate.ts","../src/fonts/sources/ttf-structure.ts","../src/fonts/cache/memory-cache.ts","../src/fonts/registry.ts","../src/fonts/catalog/popular-google.ts","../src/fonts/catalog/upstream-overrides.ts","../src/fonts/substitute.ts","../src/theme/chart-palette.ts","../src/theme/chart-typography.ts","../src/blocks/schema.ts","../src/blocks/directives.ts","../src/blocks/evaluator.ts","../src/blocks/metadata.ts","../src/blocks/schema-types.ts","../src/blocks/authoring-schema.ts","../src/blocks/compose.ts","../src/blocks/editor.ts","../src/utils/deepMerge.ts"],"sourcesContent":["/**\n * Service configuration types for external integrations (e.g. Highcharts export server)\n */\n\n// ============================================================================\n// Visual rasterization policy — single source of truth for DPI bounds shared\n// by the visual schema, the in-process rasterizer, the flatten transform, and\n// both HTTP /rasterize surfaces. Keep these in sync in one place.\n// ============================================================================\n\n/** Default raster resolution when a `visual` does not specify one. */\nexport const DEFAULT_VISUAL_DPI = 200;\n/** Minimum accepted raster resolution. */\nexport const MIN_VISUAL_DPI = 36;\n/** Maximum accepted raster resolution (bounds bitmap size / DoS surface). */\nexport const MAX_VISUAL_DPI = 600;\n\n/** Clamp an arbitrary dpi to [MIN_VISUAL_DPI, MAX_VISUAL_DPI]; non-finite → default. */\nexport function clampVisualDpi(dpi: unknown): number {\n if (typeof dpi !== 'number' || !Number.isFinite(dpi))\n return DEFAULT_VISUAL_DPI;\n return Math.min(MAX_VISUAL_DPI, Math.max(MIN_VISUAL_DPI, Math.round(dpi)));\n}\n\nexport type HighchartsHeaders = Record<string, string>;\n\nexport type HighchartsHeadersResolver = (\n body: unknown\n) => HighchartsHeaders | Promise<HighchartsHeaders>;\n\nexport interface HighchartsServiceConfig {\n serverUrl?: string;\n headers?: HighchartsHeaders | HighchartsHeadersResolver;\n}\n\n// ============================================================================\n// PPTX rasterization service (used by the docx `visual` component)\n// ============================================================================\n\nexport type PptxServiceHeaders = Record<string, string>;\n\nexport type PptxServiceHeadersResolver = (\n body: unknown\n) => PptxServiceHeaders | Promise<PptxServiceHeaders>;\n\n/** Max font faces accepted in one rasterize request. */\nexport const MAX_RASTERIZE_FONTS = 32;\n/** Max total DECODED font bytes accepted in one rasterize request. */\nexport const MAX_RASTERIZE_FONT_BYTES = 8 * 1024 * 1024;\n\n/**\n * One font face shipped alongside a rasterize request so the rasterizer's\n * out-of-process LibreOffice can render the slide with the document's real\n * fonts instead of a system fallback.\n *\n * `data` is base64 of the raw font file — NO `data:` URI prefix — so the\n * request stays plain serializable JSON.\n *\n * `family` is the CATALOG family (`ResolvedFont.family`, e.g. \"Inter\"), not\n * the synthesized sub-family the presentation references. The receiving\n * stager applies `synthesizeFamilyName` + `rewriteFontFamilyName` itself,\n * exactly as it does for the PDF-preview path; pre-synthesizing here would\n * double-apply the suffix (\"Inter Light Light\").\n */\nexport interface RasterizeFontFace {\n family: string;\n weight: number;\n italic: boolean;\n /** Base64-encoded font file bytes (no `data:` prefix). */\n data: string;\n format?: 'ttf' | 'otf' | 'woff' | 'woff2';\n}\n\n/**\n * Request handed to a pptx rasterizer: a single-slide pptx presentation\n * component definition plus the target resolution.\n */\nexport interface PptxRasterizeRequest {\n /** A pptx presentation component definition ({ name: 'pptx', ... }) with one slide */\n presentation: unknown;\n /** Target raster resolution in dots-per-inch */\n dpi: number;\n /**\n * Directory that relative asset paths inside the presentation resolve\n * against — the originating document's own directory. Absent → the\n * rasterizer's cwd, the legacy behavior (#142).\n */\n baseDir?: string;\n /**\n * Font faces to stage for the rasterizer's LibreOffice launch. Absent →\n * system fonts only, which is what every non-font-aware caller (and every\n * pre-Area-6 client) sends.\n */\n fonts?: RasterizeFontFace[];\n}\n\n/**\n * Result returned by a pptx rasterizer.\n */\nexport interface PptxRasterizeResult {\n /** Rendered PNG as a base64 data URI (data:image/png;base64,...) */\n base64DataUri: string;\n /** Natural pixel width of the rendered image */\n width: number;\n /** Natural pixel height of the rendered image */\n height: number;\n}\n\n/**\n * In-process rasterizer callback. Implementations build the .pptx from the\n * presentation JSON and rasterize it to a PNG (e.g. via LibreOffice + poppler).\n */\nexport type PptxRasterizer = (\n request: PptxRasterizeRequest\n) => Promise<PptxRasterizeResult>;\n\n// ============================================================================\n// Batch rasterization (#153) — one request rasterizes many independent slides.\n//\n// Each slide is a complete single-slide presentation (the exact shape a\n// single {@link PptxRasterizeRequest} carries), NOT a slide fragment of one\n// merged deck. This keeps slides independent — each may use its own canvas\n// size, theme, and dpi, so callers never need to group visuals — and lets\n// implementations key per-slide caches identically to the single-slide path.\n// ============================================================================\n\n/**\n * Maximum slides accepted in one batch request. Shared by the HTTP surface\n * (request validation) and clients (chunk size) so the two cannot drift.\n * Bounds per-request work and response size the same way rate limits bound\n * request counts.\n */\nexport const MAX_RASTERIZE_BATCH_SLIDES = 32;\n\n/** One slide in a batch: a single-slide presentation plus its resolution. */\nexport interface PptxRasterizeBatchSlide {\n /** A pptx presentation component definition ({ name: 'pptx', ... }) with one slide */\n presentation: unknown;\n /** Target raster resolution in dots-per-inch (absent → service default) */\n dpi?: number;\n}\n\n/** Request handed to a batch pptx rasterizer. */\nexport interface PptxRasterizeBatchRequest {\n /** Slides to rasterize; results come back index-aligned with this array. */\n slides: PptxRasterizeBatchSlide[];\n /** Base directory for relative asset paths, shared by every slide (#142). */\n baseDir?: string;\n /**\n * Font faces staged for the batch's LibreOffice launch, shared by every\n * slide exactly like `baseDir`. Deliberately REQUEST-level and never\n * per-slide: {@link PptxRasterizeBatchSlide} stays `{presentation, dpi}` so\n * batch-internal dedupe and the per-slide disk-cache key stay uniform with\n * the single-slide path.\n */\n fonts?: RasterizeFontFace[];\n}\n\n/**\n * Pipeline stage a slide failed in. `build` failures are caused by the\n * slide's own JSON (safe to surface verbatim to callers); `convert` and\n * `rasterize` failures are environment/tooling errors whose raw messages may\n * carry host paths — HTTP surfaces sanitize those.\n */\nexport type PptxRasterizeFailureStage = 'build' | 'convert' | 'rasterize';\n\n/**\n * Per-slide outcome. A batch response is 200-with-item-errors rather than\n * all-or-nothing: one bad visual must not discard its siblings' pixels.\n */\nexport type PptxRasterizeBatchSlideResult =\n | ({ ok: true } & PptxRasterizeResult)\n | { ok: false; error: string; stage?: PptxRasterizeFailureStage };\n\n/** Result returned by a batch pptx rasterizer. */\nexport interface PptxRasterizeBatchResult {\n /** Index-aligned with the request's `slides` (same length, same order). */\n results: PptxRasterizeBatchSlideResult[];\n}\n\n/**\n * In-process batch rasterizer callback. Batch-level failures (missing\n * binaries, bad request) throw; per-slide failures land in `results`.\n */\nexport type PptxBatchRasterizer = (\n request: PptxRasterizeBatchRequest\n) => Promise<PptxRasterizeBatchResult>;\n\n/**\n * Configuration for the pptx rasterization service backing `visual` components.\n *\n * Mirrors {@link HighchartsServiceConfig}: the published packages depend on this\n * interface, never on a binary. A host injects either an in-process `render`\n * callback or an HTTP `serverUrl`.\n */\nexport interface PptxServiceConfig {\n /**\n * In-process rasterizer. Takes precedence over `serverUrl` when provided.\n * Ideal for tests (no binaries) and single-process hosts.\n */\n render?: PptxRasterizer;\n /**\n * In-process batch rasterizer. When provided, the docx renderer coalesces a\n * document's visuals into batch calls (#153) instead of one `render` call\n * per visual. Like `render`, takes precedence over `serverUrl`.\n */\n renderBatch?: PptxBatchRasterizer;\n /**\n * HTTP rasterization service URL. The service receives\n * `{ presentation, dpi }` and returns a {@link PptxRasterizeResult}.\n */\n serverUrl?: string;\n /** Optional headers (or async resolver) for the HTTP service. */\n headers?: PptxServiceHeaders | PptxServiceHeadersResolver;\n /** Default DPI applied when a `visual` does not specify one. */\n dpi?: number;\n}\n\nexport interface ServicesConfig {\n highcharts?: HighchartsServiceConfig;\n pptx?: PptxServiceConfig;\n}\n","/**\n * Walk a document tree and collect every font family name referenced.\n *\n * Matches both DOCX conventions (`family` nested under `font`, theme.fonts.*)\n * and PPTX conventions (`fontFace`, chart `titleFontFace` etc., theme.fonts.*).\n * Key-name matching is intentionally permissive so future component schemas\n * that reuse the same conventions pick up automatically.\n */\n\nexport const FONT_NAME_KEYS = new Set([\n 'family',\n 'fontFace',\n 'titleFontFace',\n 'legendFontFace',\n 'dataLabelFontFace',\n 'catAxisLabelFontFace',\n 'valAxisLabelFontFace',\n]);\n\nexport const THEME_FONT_KEYS = new Set(['heading', 'body', 'mono', 'light']);\n\n/**\n * Subtrees that declare fonts rather than reference them. `fontRegistry`\n * entries carry `family` (and `sources[].family` for kind:'safe'/'google'),\n * which the depth-agnostic `family` match would otherwise scoop up as\n * references — a registry would self-satisfy its own validation, and a\n * `kind:'google'` source family would appear as a phantom reference.\n * substitute.ts's rewriter skips the same key; the two MUST stay in sync.\n */\nexport const FONT_DECLARATION_KEYS = new Set(['fontRegistry']);\n\nfunction collect(node: unknown, out: Set<string>, parentKey?: string): void {\n if (node == null) return;\n\n if (typeof node === 'string') {\n // String values under a font-name key or under theme.fonts.{heading,body,...}\n if (\n parentKey &&\n (FONT_NAME_KEYS.has(parentKey) || THEME_FONT_KEYS.has(parentKey))\n ) {\n const trimmed = node.trim();\n if (trimmed.length > 0) out.add(trimmed);\n }\n return;\n }\n\n if (Array.isArray(node)) {\n // Forward parentKey so font-name arrays (e.g. theme.fonts.heading: [...])\n // are walked with the same context as the non-array case. Mirrors\n // substitute.ts's rewrite walker — the two must stay in sync or\n // substitution silently misses array-shaped references.\n for (const item of node) collect(item, out, parentKey);\n return;\n }\n\n if (typeof node === 'object') {\n // Special-cased: theme.fonts is an object whose values (or values.family) are font names.\n const maybeFonts = (node as Record<string, unknown>).fonts;\n if (parentKey === 'theme' && maybeFonts && typeof maybeFonts === 'object') {\n for (const [k, v] of Object.entries(\n maybeFonts as Record<string, unknown>\n )) {\n if (typeof v === 'string') {\n const trimmed = v.trim();\n if (trimmed.length > 0) out.add(trimmed);\n } else if (v && typeof v === 'object') {\n const fam = (v as Record<string, unknown>).family;\n if (typeof fam === 'string' && fam.trim().length > 0) {\n out.add(fam.trim());\n }\n }\n void k;\n }\n }\n\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n // Declarations, not references — see FONT_DECLARATION_KEYS.\n if (FONT_DECLARATION_KEYS.has(k)) continue;\n collect(v, out, k);\n }\n }\n}\n\n/** Scan an arbitrary doc tree (DOCX or PPTX) for every font family referenced. */\nexport function collectFontNames(doc: unknown): Set<string> {\n const out = new Set<string>();\n collect(doc, out);\n return out;\n}\n\n/** Scan a DOCX document tree for every font family name referenced. */\nexport const collectFontNamesFromDocx = collectFontNames;\n\n/** Scan a PPTX presentation tree for every font family name referenced. */\nexport const collectFontNamesFromPptx = collectFontNames;\n","/**\n * Read the document-scoped and theme-scoped font registries and merge them\n * with runtime `fonts.extraEntries`.\n *\n * Precedence (last wins, matching registry.ts's documented resolution rules\n * and FontRuntimeOpts.extraEntries's \"merged over the document's\n * fontRegistry\"):\n *\n * theme.fontRegistry < document.props.fontRegistry < fonts.extraEntries\n *\n * Merging happens here rather than inside FontRegistry because\n * `validateFontReferences` needs the same merged list, and two merge sites\n * would eventually disagree — which would show up as a font that validates\n * but never renders, or vice versa.\n */\n\nimport type { FontRegistryEntry } from '../schemas/font-catalog';\n\nfunction isEntry(v: unknown): v is FontRegistryEntry {\n if (!v || typeof v !== 'object') return false;\n const e = v as Record<string, unknown>;\n return (\n typeof e.id === 'string' &&\n typeof e.family === 'string' &&\n Array.isArray(e.sources)\n );\n}\n\nfunction readAt(node: unknown, key: string): FontRegistryEntry[] {\n if (!node || typeof node !== 'object') return [];\n const raw = (node as Record<string, unknown>)[key];\n return Array.isArray(raw) ? raw.filter(isEntry) : [];\n}\n\n/** `document.props.fontRegistry`, defensively (props may be absent/null). */\nexport function documentFontRegistry(document: unknown): FontRegistryEntry[] {\n if (!document || typeof document !== 'object') return [];\n return readAt((document as Record<string, unknown>).props, 'fontRegistry');\n}\n\n/** `theme.fontRegistry`, defensively. */\nexport function themeFontRegistry(theme: unknown): FontRegistryEntry[] {\n return readAt(theme, 'fontRegistry');\n}\n\n/**\n * Merge entry groups in precedence order — later groups win on a collision of\n * `family` OR `id`, case-insensitively, which are the same two keys\n * `FontRegistry.addEntry` indexes on. Returns a flat list safe to hand to both\n * `validateFontReferences` and `new FontRegistry({ opts: { extraEntries } })`.\n */\nexport function mergeFontRegistries(\n ...groups: (FontRegistryEntry[] | undefined)[]\n): FontRegistryEntry[] {\n // Order IS the contract: `FontRegistry` replays this array through\n // `addEntry`, indexing on family and id with last-write-wins, so an entry\n // only outranks another by sitting later. Concatenating the groups in\n // precedence order is therefore the whole mechanism.\n //\n // Deliberately NOT de-duped through a Map keyed by family/id: `Map.set` on\n // an existing key keeps the original insertion *position*, so a\n // higher-precedence entry colliding with an earlier one would be emitted\n // early and then lose the replay to the entry it was supposed to beat.\n const out: FontRegistryEntry[] = [];\n for (const group of groups) {\n for (const entry of group ?? []) {\n const family = entry.family.toLowerCase();\n const id = entry.id.toLowerCase();\n // Drop only a true replacement — same family AND same id. An entry that\n // shares just one of the two still owns the other key in FontRegistry's\n // index, so removing it here would make that name unresolvable.\n for (let i = out.length - 1; i >= 0; i--) {\n if (\n out[i].family.toLowerCase() === family &&\n out[i].id.toLowerCase() === id\n ) {\n out.splice(i, 1);\n }\n }\n out.push(entry);\n }\n }\n return out;\n}\n","/**\n * Validate that every font name referenced in a document is either\n * in SAFE_FONTS or present in the document's fontRegistry / runtime overrides.\n *\n * Used at generate-start; emits warnings for unresolved names so pipelines\n * can surface them via their existing warning channels.\n */\n\nimport { SAFE_FONTS, isSafeFont } from '../schemas/font-catalog';\nimport type { FontRegistryEntry } from '../schemas/font-catalog';\n\n/**\n * Warning codes for font resolution + rendering.\n *\n * - `FONT_UNRESOLVED` — family not in SAFE_FONTS and not registered.\n * - `FONT_MODE_SUBSTITUTED` — non-safe families rewritten to safe equivalents.\n * - `FONT_MODE_CUSTOM` — export mode \"custom\" — refs kept as-is.\n */\nexport type FontIssueCode =\n | 'FONT_UNRESOLVED'\n | 'FONT_MODE_SUBSTITUTED'\n | 'FONT_MODE_CUSTOM';\n\nexport interface FontResolutionIssue {\n code: FontIssueCode;\n family: string;\n message: string;\n}\n\nexport interface FontValidationResult {\n /** Names that resolved via SAFE_FONTS or the registry. */\n resolved: string[];\n /** Names with no resolution path. */\n unresolved: string[];\n /** One warning per unresolved name. */\n warnings: FontResolutionIssue[];\n}\n\nexport interface FontValidationInput {\n /** Font names referenced in the document (from collectFontNamesFromDocx / FromPptx). */\n referencedNames: Iterable<string>;\n /** Runtime-registered entries (e.g. from FontRuntimeOpts.extraEntries). */\n registeredEntries?: FontRegistryEntry[];\n}\n\nfunction buildRegistryIndex(\n registeredEntries?: FontRegistryEntry[]\n): Set<string> {\n const idx = new Set<string>();\n for (const e of registeredEntries ?? []) {\n idx.add(e.family.toLowerCase());\n idx.add(e.id.toLowerCase());\n }\n return idx;\n}\n\n/**\n * Validate referenced font names against SAFE_FONTS + runtime-registered entries.\n * Does not perform network fetches — this runs purely off schema + opts content.\n */\nexport function validateFontReferences(\n input: FontValidationInput\n): FontValidationResult {\n const registryIdx = buildRegistryIndex(input.registeredEntries);\n const resolved: string[] = [];\n const unresolved: string[] = [];\n const warnings: FontResolutionIssue[] = [];\n\n for (const name of input.referencedNames) {\n if (isSafeFont(name) || registryIdx.has(name.toLowerCase())) {\n resolved.push(name);\n continue;\n }\n unresolved.push(name);\n warnings.push({\n code: 'FONT_UNRESOLVED',\n family: name,\n message:\n `Font \"${name}\" is not a SAFE_FONTS entry and is not registered via fonts.extraEntries. ` +\n `It will render with a host fallback on machines lacking the font. ` +\n `Safe fonts: ${SAFE_FONTS.join(', ')}.`,\n });\n }\n\n return { resolved, unresolved, warnings };\n}\n","/**\n * Map a (family, weight, italic) tuple to the pair of\n * `(familyName, { bold, italic })` the renderer should actually use.\n *\n * OOXML runs can only carry a bold/italic toggle, not a numeric weight.\n * For weights outside the RIBBI quad (400/700 × roman/italic), Word\n * resolves intermediate weights via **separate sub-family faces** whose\n * internal family name is the canonical Google-Fonts-style subfamily,\n * e.g. `Inter Light`, `Inter ExtraBold Italic`. Rewriting the run's\n * `family` to that synthetic name lets Word pick the right face when the\n * recipient has the full family installed, and lets the LibreOffice\n * preview resolve the matching staged TTF by its internal name.\n *\n * No embedding involved — this is purely a name transform applied at\n * render time. Safe fonts and unrecognised weights fall back to the\n * bold-only heuristic (`weight >= 600 → bold`).\n */\n\n/** Human-readable labels for the canonical font-weight numbers. */\nexport const WEIGHT_LABELS: Record<number, string> = {\n 100: 'Thin',\n 200: 'ExtraLight',\n 300: 'Light',\n 400: 'Regular',\n 500: 'Medium',\n 600: 'SemiBold',\n 700: 'Bold',\n 800: 'ExtraBold',\n 900: 'Black',\n};\n\nexport interface SynthesizedFamily {\n /** The family name to emit in `rFonts`/`fontFace`. */\n family: string;\n /** Whether to also set the run's bold toggle. */\n bold: boolean;\n /** Whether to also set the run's italic toggle. */\n italic: boolean;\n /**\n * `true` when the input `weight` was not one of the canonical\n * 100/200/.../900 labels. The canonical family name is returned with\n * a `weight >= 600 → bold` fallback, but the run will not match a\n * dedicated sub-family face — callers should surface this so authors\n * know the weight was effectively rounded to Regular or Bold.\n */\n nonCanonicalWeight: boolean;\n}\n\n/**\n * Translate `(family, weight, italic)` into the rendering-time family name\n * plus the bold/italic toggles to emit on the run.\n *\n * - RIBBI (weights 400 + 700, roman + italic) stays on the canonical family\n * name and uses native bold/italic toggles.\n * - Other canonical weights become `\"<Family> <Weight>\"` (e.g.\n * `\"Inter Light\"`) with bold/italic toggles cleared; any italic flag is\n * folded into the name (`\"Inter Light Italic\"`).\n * - Non-canonical weights (floating or out-of-range) fall back to\n * `bold = weight >= 600` and leave the family name untouched.\n */\nexport function synthesizeFamilyName(\n family: string,\n weight: number | undefined,\n italic: boolean\n): SynthesizedFamily {\n if (weight == null) {\n return { family, bold: false, italic, nonCanonicalWeight: false };\n }\n // RIBBI — no rewrite needed, let native bold/italic do the work.\n if (weight === 400) {\n return { family, bold: false, italic, nonCanonicalWeight: false };\n }\n if (weight === 700) {\n return { family, bold: true, italic, nonCanonicalWeight: false };\n }\n const label = WEIGHT_LABELS[weight];\n if (!label) {\n // Non-canonical weight — best-effort bold fallback. Flag the result so\n // callers can warn: the run will render as Regular or Bold, not the\n // intermediate weight the author asked for.\n return {\n family,\n bold: weight >= 600,\n italic,\n nonCanonicalWeight: true,\n };\n }\n const suffix = italic ? ` ${label} Italic` : ` ${label}`;\n return {\n family: `${family}${suffix}`,\n bold: false,\n italic: false,\n nonCanonicalWeight: false,\n };\n}\n","/**\n * Decode a base64 / data-URL font payload to a Buffer.\n */\n\nimport type { ResolvedFontSource } from '../types';\nimport { detectFontFormat } from './format';\n\nexport interface DataSourceInput {\n data: string;\n weight?: number;\n italic?: boolean;\n}\n\n/**\n * Hard upper bound on the decoded font buffer. Real TTF/OTF faces are well\n * under 5 MB; even variable-axis fonts with CJK coverage rarely exceed 4 MB.\n * Rejecting oversized payloads before decoding prevents a malicious\n * `kind: 'data'` registry entry from allocating arbitrary server memory\n * when the generator runs behind an HTTP endpoint.\n */\nconst MAX_DATA_FONT_BYTES = 5 * 1024 * 1024;\n\n/**\n * Accepts either a bare base64 string or a data: URL.\n * Throws on invalid input; renderer catches and emits a warning.\n */\nexport function loadDataFontSource(input: DataSourceInput): ResolvedFontSource {\n const raw = input.data.trim();\n let b64: string;\n if (raw.startsWith('data:')) {\n const comma = raw.indexOf(',');\n if (comma < 0) throw new Error('Invalid data URL: no payload separator');\n // Only base64-encoded payloads are supported.\n const header = raw.slice(5, comma);\n if (!header.includes(';base64')) {\n throw new Error('Data URL must be base64-encoded');\n }\n b64 = raw.slice(comma + 1);\n } else {\n b64 = raw;\n }\n // Upper-bound the decoded size via base64 length before allocating. A\n // base64 string decodes to ~3/4 its character count, so a conservative\n // check on the encoded size avoids decoding a 50 MB payload just to\n // reject it afterward.\n const approxDecodedBytes = Math.floor((b64.length * 3) / 4);\n if (approxDecodedBytes > MAX_DATA_FONT_BYTES) {\n throw new Error(\n `Font data payload exceeds ${MAX_DATA_FONT_BYTES} byte limit`\n );\n }\n const data = Buffer.from(b64, 'base64');\n if (data.length === 0) throw new Error('Decoded font buffer is empty');\n if (data.length > MAX_DATA_FONT_BYTES) {\n throw new Error(\n `Font data payload exceeds ${MAX_DATA_FONT_BYTES} byte limit`\n );\n }\n // Base64 decoding silently discards invalid characters, so garbage input\n // yields a non-empty buffer that isn't a real font. Magic-byte check\n // rejects the garbage before it reaches the LibreOffice preview stager.\n const format = detectFontFormat(data);\n if (format === 'unknown') {\n throw new Error(\n 'Decoded font buffer is not a recognized font (expected TTF/OTF/WOFF/WOFF2)'\n );\n }\n // WOFF/WOFF2 flow through: Office output never embeds bytes, and the\n // LibreOffice preview stager handles them via fontconfig.\n return {\n data,\n weight: input.weight ?? 400,\n italic: input.italic ?? false,\n format,\n };\n}\n","/**\n * Google Fonts fetcher.\n *\n * Hits the CSS API v2 with an older User-Agent that returns TTF (default UA\n * gets WOFF2, which Office cannot embed as-is). Parses the `src: url(...)` line\n * and downloads the binary.\n *\n * Uses memory + optional disk cache keyed by `${family}|${weight}|${italic}`.\n */\n\nimport type { ResolvedFontSource } from '../types';\nimport { FontMemoryCache } from '../cache/memory-cache';\nimport { detectFontFormat } from './format';\n\ninterface FontDiskCacheLike {\n get(key: string): Promise<Buffer | undefined>;\n set(key: string, value: Buffer): Promise<void>;\n}\n\nexport interface GoogleFetchOptions {\n family: string;\n weights: number[];\n italics?: boolean;\n memoryCache?: FontMemoryCache;\n diskCache?: FontDiskCacheLike;\n fetchTimeoutMs?: number;\n /** Override for tests. */\n fetcher?: typeof fetch;\n}\n\nexport interface GoogleFetchResult {\n sources: ResolvedFontSource[];\n warnings: string[];\n}\n\nconst TTF_UA = 'Mozilla/4.0';\n\nasync function fetchWithTimeout(\n url: string,\n opts: {\n headers?: Record<string, string>;\n timeoutMs?: number;\n fetcher?: typeof fetch;\n }\n): Promise<Response> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 5000);\n try {\n const f = opts.fetcher ?? fetch;\n return await f(url, { headers: opts.headers, signal: ctrl.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction buildCssUrl(\n family: string,\n weights: number[],\n italics: boolean\n): string {\n // URL-encode then restore spaces as `+` (Google's CSS2 API convention).\n const famPart = encodeURIComponent(family).replace(/%20/g, '+');\n const sortedWeights = [...weights].sort((a, b) => a - b);\n if (italics) {\n const axis = sortedWeights.flatMap((w) => [`0,${w}`, `1,${w}`]).join(';');\n return `https://fonts.googleapis.com/css2?family=${famPart}:ital,wght@${axis}&display=swap`;\n }\n const wghtPart = sortedWeights.join(';');\n return `https://fonts.googleapis.com/css2?family=${famPart}:wght@${wghtPart}&display=swap`;\n}\n\n/**\n * Parse Google Fonts CSS response into { weight, italic, ttfUrl } tuples.\n * Each @font-face block contains the src + font-weight + font-style we need.\n */\nfunction parseCssFaces(\n css: string\n): { weight: number; italic: boolean; ttfUrl: string }[] {\n const out: { weight: number; italic: boolean; ttfUrl: string }[] = [];\n const faceRe = /@font-face\\s*\\{([^}]*)\\}/g;\n let m: RegExpExecArray | null;\n while ((m = faceRe.exec(css)) !== null) {\n const block = m[1];\n // Pin the CDN: only accept URLs whose hostname is fonts.gstatic.com so a\n // hijacked/mitm'd CSS response can't redirect downloads to arbitrary hosts.\n const urlM = block.match(\n /src:\\s*url\\((https:\\/\\/fonts\\.gstatic\\.com\\/[^)]+\\.ttf)\\)/\n );\n if (!urlM) continue;\n const weightM = block.match(/font-weight:\\s*(\\d+)/);\n const italicM = block.match(/font-style:\\s*italic/);\n out.push({\n weight: weightM ? parseInt(weightM[1], 10) : 400,\n italic: Boolean(italicM),\n ttfUrl: urlM[1],\n });\n }\n return out;\n}\n\nfunction cacheKey(family: string, weight: number, italic: boolean): string {\n return `google|${family}|${weight}|${italic ? 'i' : 'r'}`;\n}\n\nexport async function fetchGoogleFontSources(\n opts: GoogleFetchOptions\n): Promise<GoogleFetchResult> {\n const weights = opts.weights?.length ? opts.weights : [400, 700];\n const italics = opts.italics ?? false;\n const warnings: string[] = [];\n const sources: ResolvedFontSource[] = [];\n\n // Try every (weight, italic) combo — first against caches, then via fetch.\n const wanted: { weight: number; italic: boolean }[] = [];\n for (const w of weights) {\n wanted.push({ weight: w, italic: false });\n if (italics) wanted.push({ weight: w, italic: true });\n }\n\n // Resolve any cache hits first.\n const pending: { weight: number; italic: boolean }[] = [];\n for (const w of wanted) {\n const key = cacheKey(opts.family, w.weight, w.italic);\n const mem = opts.memoryCache?.get(key);\n if (mem) {\n sources.push({\n data: mem,\n weight: w.weight,\n italic: w.italic,\n format: detectFontFormat(mem),\n });\n continue;\n }\n const disk = await opts.diskCache?.get(key);\n if (disk) {\n opts.memoryCache?.set(key, disk);\n sources.push({\n data: disk,\n weight: w.weight,\n italic: w.italic,\n format: detectFontFormat(disk),\n });\n continue;\n }\n pending.push(w);\n }\n\n if (pending.length === 0) {\n return { sources, warnings };\n }\n\n // Single CSS request covers all pending variants.\n const needItalics = pending.some((p) => p.italic);\n const cssUrl = buildCssUrl(\n opts.family,\n Array.from(new Set(pending.map((p) => p.weight))),\n needItalics\n );\n let faces: { weight: number; italic: boolean; ttfUrl: string }[];\n try {\n const cssRes = await fetchWithTimeout(cssUrl, {\n headers: { 'User-Agent': TTF_UA },\n timeoutMs: opts.fetchTimeoutMs,\n fetcher: opts.fetcher,\n });\n if (!cssRes.ok) {\n warnings.push(\n `Google Fonts CSS fetch for \"${opts.family}\" returned ${cssRes.status}`\n );\n return { sources, warnings };\n }\n const css = await cssRes.text();\n faces = parseCssFaces(css);\n } catch (err) {\n warnings.push(\n `Google Fonts CSS fetch for \"${opts.family}\" failed: ${\n (err as Error).message\n }`\n );\n return { sources, warnings };\n }\n\n for (const need of pending) {\n const match = faces.find(\n (f) => f.weight === need.weight && f.italic === need.italic\n );\n if (!match) {\n warnings.push(\n `Google Fonts \"${opts.family}\" missing weight ${need.weight}${\n need.italic ? ' italic' : ''\n }`\n );\n continue;\n }\n try {\n const res = await fetchWithTimeout(match.ttfUrl, {\n timeoutMs: opts.fetchTimeoutMs,\n fetcher: opts.fetcher,\n });\n if (!res.ok) {\n warnings.push(\n `Google Fonts TTF fetch for \"${opts.family}\" ${need.weight} returned ${res.status}`\n );\n continue;\n }\n const ab = await res.arrayBuffer();\n // Metadata validation (weight class, name-table defects, fsType) runs\n // centrally in FontRegistry.materializeEntry so file/data/url/google\n // sources are all checked under one code path.\n const buf = Buffer.from(ab);\n const key = cacheKey(opts.family, need.weight, need.italic);\n opts.memoryCache?.set(key, buf);\n await opts.diskCache?.set(key, buf);\n sources.push({\n data: buf,\n weight: need.weight,\n italic: need.italic,\n format: detectFontFormat(buf),\n });\n } catch (err) {\n warnings.push(\n `Google Fonts TTF fetch for \"${opts.family}\" ${need.weight} failed: ${\n (err as Error).message\n }`\n );\n }\n }\n\n return { sources, warnings };\n}\n","/**\n * Direct-URL font fetcher. Downloads a single TTF/OTF from an HTTPS URL and\n * returns it as a `ResolvedFontSource`. Cache-keyed the same way as the\n * Google Fonts fetcher so fetches are deduplicated across generations.\n *\n * Used as an escape hatch for families whose Google Fonts redistribution has\n * known defects (e.g. Inter's static Thin/ExtraLight shipping with a broken\n * `OS/2.usWeightClass`). The `UPSTREAM_OVERRIDES` catalog points affected\n * families at clean upstream sources like rsms/inter via jsDelivr.\n */\n\nimport type { ResolvedFontSource } from '../types';\nimport { detectFontFormat } from './format';\nimport { isAllowedFontUrl } from './url-allowlist';\n\nexport interface UrlFetchOptions {\n url: string;\n weight: number;\n italic: boolean;\n fetchTimeoutMs?: number;\n fetcher?: typeof fetch;\n memoryCache?: {\n get(key: string): Buffer | undefined;\n set(key: string, value: Buffer): void;\n };\n diskCache?: {\n get(key: string): Promise<Buffer | undefined>;\n set(key: string, value: Buffer): Promise<void>;\n };\n}\n\nfunction cacheKey(url: string, weight: number, italic: boolean): string {\n return `url|${url}|${weight}|${italic ? 'i' : 'r'}`;\n}\n\nexport async function fetchUrlFontSource(\n opts: UrlFetchOptions\n): Promise<{ source?: ResolvedFontSource; warnings?: string[] }> {\n if (!isAllowedFontUrl(opts.url)) {\n return {\n warnings: [\n `URL font fetch rejected (host not in allowlist or non-HTTPS): ${opts.url}`,\n ],\n };\n }\n const key = cacheKey(opts.url, opts.weight, opts.italic);\n const mem = opts.memoryCache?.get(key);\n if (mem) {\n return {\n source: {\n data: mem,\n weight: opts.weight,\n italic: opts.italic,\n format: detectFontFormat(mem),\n },\n warnings: [],\n };\n }\n const disk = await opts.diskCache?.get(key);\n if (disk) {\n opts.memoryCache?.set(key, disk);\n return {\n source: {\n data: disk,\n weight: opts.weight,\n italic: opts.italic,\n format: detectFontFormat(disk),\n },\n warnings: [],\n };\n }\n\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), opts.fetchTimeoutMs ?? 10000);\n try {\n const f = opts.fetcher ?? fetch;\n // redirect: 'manual' prevents the allowlist from being bypassed via\n // a 3xx Location pointing at an off-list host. We re-validate the\n // Location header against the allowlist before following.\n let res = await f(opts.url, { signal: ctrl.signal, redirect: 'manual' });\n let hops = 0;\n while (res.status >= 300 && res.status < 400 && res.status !== 304) {\n const next = res.headers.get('location');\n if (!next) {\n return {\n warnings: [\n `URL font fetch \"${opts.url}\" ${res.status} with no Location header`,\n ],\n };\n }\n const resolved = new URL(next, opts.url).toString();\n if (!isAllowedFontUrl(resolved)) {\n return {\n warnings: [\n `URL font fetch \"${opts.url}\" redirected to disallowed host: ${resolved}`,\n ],\n };\n }\n if (++hops > 3) {\n return {\n warnings: [`URL font fetch \"${opts.url}\" too many redirects`],\n };\n }\n res = await f(resolved, { signal: ctrl.signal, redirect: 'manual' });\n }\n if (!res.ok) {\n return {\n warnings: [`URL font fetch \"${opts.url}\" returned ${res.status}`],\n };\n }\n const ab = await res.arrayBuffer();\n const raw = Buffer.from(ab);\n // Reject obvious non-font responses — e.g. jsDelivr 404 HTML, 200 OK\n // redirect pages, or aliased directory listings. Without this check the\n // bytes would sail through to the embed step and corrupt the output.\n const format = detectFontFormat(raw);\n if (format === 'unknown' || raw.length < 512) {\n return {\n warnings: [\n `URL font fetch \"${opts.url}\" returned ${raw.length} bytes of ${format} — not a TTF/OTF. Skipping.`,\n ],\n };\n }\n // WOFF/WOFF2 flow through: Office output never embeds bytes; the\n // LibreOffice preview stager handles them via fontconfig.\n // Metadata validation runs centrally in FontRegistry.materializeEntry.\n const buf = raw;\n opts.memoryCache?.set(key, buf);\n await opts.diskCache?.set(key, buf);\n return {\n source: {\n data: buf,\n weight: opts.weight,\n italic: opts.italic,\n format,\n },\n warnings: [],\n };\n } catch (err) {\n return {\n warnings: [\n `URL font fetch \"${opts.url}\" failed: ${(err as Error).message}`,\n ],\n };\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Post-fetch metadata validation for TTF/OTF bytes. Catches the three known\n * classes of defects that surface in Google Fonts' redistribution pipeline:\n *\n * 1. Wrong `OS/2.usWeightClass` (Chivo Light, Mada Regular, Petrona)\n * 2. Duplicate usWeightClass across weights (Exo Thin/ExtraLight)\n * 3. Non-unique `name` subfamily records (Inter, Manrope, Recursive)\n * 4. A family name that isn't the one we resolved the bytes as — an\n * instanced `InterVariable.ttf` still calls itself \"Inter Variable\", a\n * vendor CDN static may call itself anything at all\n *\n * We don't throw on mismatch — the pipeline has already tried to fix the\n * bytes where it can (`rewriteFontSubfamilyNames` after variable-font\n * instancing; `rewriteFontFamilyName` at preview staging). The validator\n * returns human-readable diagnostics so the caller can emit warnings tagged\n * `FONT_METADATA_DEFECT`, pointing users at the upstream override escape\n * hatch before they ship a broken document.\n */\n\nimport {\n readFontFamilyNames,\n readNameRecords,\n standardSubfamilyNames,\n} from './ttf-name';\n\nconst HEADER_SIZE = 12;\nconst TABLE_RECORD_SIZE = 16;\n\nfunction readTable(\n ttf: Buffer,\n tag: string\n): { off: number; len: number } | null {\n if (ttf.length < HEADER_SIZE) return null;\n const version = ttf.readUInt32BE(0);\n if (version !== 0x00010000 && version !== 0x4f54544f) return null;\n const numTables = ttf.readUInt16BE(4);\n for (let i = 0; i < numTables; i++) {\n const r = HEADER_SIZE + i * TABLE_RECORD_SIZE;\n if (r + TABLE_RECORD_SIZE > ttf.length) return null;\n if (ttf.toString('ascii', r, r + 4) === tag) {\n return { off: ttf.readUInt32BE(r + 8), len: ttf.readUInt32BE(r + 12) };\n }\n }\n return null;\n}\n\nfunction readUsWeightClass(ttf: Buffer): number | null {\n const os2 = readTable(ttf, 'OS/2');\n if (!os2) return null;\n if (os2.off + 6 > ttf.length) return null;\n return ttf.readUInt16BE(os2.off + 4);\n}\n\nexport interface FontMetadataDiagnostic {\n code:\n | 'WEIGHT_CLASS_MISMATCH'\n | 'SUBFAMILY_MISMATCH'\n | 'LEGACY_SUBFAMILY_MISMATCH'\n | 'FAMILY_MISMATCH';\n message: string;\n}\n\n/**\n * Inspect a font's metadata against the weight + italic we asked it to\n * represent. Returns one diagnostic per detected defect.\n */\nexport function validateFontMetadata(\n ttf: Buffer,\n weight: number,\n italic: boolean,\n familyLabel: string\n): FontMetadataDiagnostic[] {\n const diags: FontMetadataDiagnostic[] = [];\n const usWeight = readUsWeightClass(ttf);\n if (usWeight != null && usWeight !== weight) {\n diags.push({\n code: 'WEIGHT_CLASS_MISMATCH',\n message: `Font \"${familyLabel}\" weight ${weight}: OS/2.usWeightClass reports ${usWeight}. Likely a defective redistribution — consider adding an upstream override.`,\n });\n }\n\n // OS/2.fsType (embedding-permission bits) deliberately NOT checked. Office\n // output never embeds font bytes anymore — substitute mode rewrites to\n // SAFE_FONTS, custom mode ships references as-is, and the LibreOffice\n // preview stager only registers bytes transiently with the converter's\n // child process. Permission warnings would be pure noise for every\n // Google Fonts resolution.\n\n // The bytes must answer to the family they were resolved as, or nothing\n // downstream can find them: a run says `rFonts w:ascii=\"Inter\"` and the\n // host matches that against the font's own name table, never against the\n // registry entry or the filename. `FontRegistry` repairs this before\n // validating, so reaching here means the repair could not run (no name\n // table, a format-1 one, non-sfnt bytes) — i.e. the face really will be\n // unreachable under `familyLabel`.\n const declaredFamilies = readFontFamilyNames(ttf);\n if (\n declaredFamilies.length > 0 &&\n !declaredFamilies.includes(familyLabel.trim())\n ) {\n diags.push({\n code: 'FAMILY_MISMATCH',\n message: `Font \"${familyLabel}\" weight ${weight}${italic ? ' italic' : ''}: name table declares ${declaredFamilies\n .map((f) => `\"${f}\"`)\n .join(\n ' / '\n )}, not \"${familyLabel}\". Referencing runs will not resolve this face.`,\n });\n }\n\n const std = standardSubfamilyNames(weight, italic);\n if (!std) return diags;\n const expected17 = std.typographic;\n const expected2 = std.legacy;\n\n const names = readNameRecords(ttf, new Set([2, 17]));\n for (const n of names) {\n if (n.nameID === 17 && n.value !== expected17) {\n diags.push({\n code: 'SUBFAMILY_MISMATCH',\n message: `Font \"${familyLabel}\" weight ${weight}${italic ? ' italic' : ''}: name record (platform ${n.platformID}) nameID 17 = \"${n.value}\", expected \"${expected17}\".`,\n });\n }\n if (n.nameID === 2 && n.value !== expected2) {\n diags.push({\n code: 'LEGACY_SUBFAMILY_MISMATCH',\n message: `Font \"${familyLabel}\" weight ${weight}${italic ? ' italic' : ''}: name record (platform ${n.platformID}) nameID 2 = \"${n.value}\", expected \"${expected2}\".`,\n });\n }\n }\n return diags;\n}\n","/**\n * Structural sanity check for TTF/OTF bytes — can a font system load this at\n * all? Answered before `validateFontMetadata`, which asks the narrower\n * question of whether a loadable font's metadata says the right things.\n *\n * The gap this closes: `detectFontFormat` classifies by the four magic bytes\n * alone, so a download truncated anywhere after byte four is still 'ttf' and\n * flows on as if it were a font. Nothing downstream notices. The metadata\n * validator has no name records to check and usually no readable OS/2\n * either, so it stays silent by design; `FontRegistry`'s family stamp finds\n * no declared family to contradict and no-ops; and the bytes stage as a\n * `.ttf` that fontconfig and Core Text refuse, so the document renders in a\n * fallback face with nothing anywhere saying why.\n *\n * Deliberately NOT a full sfnt parser. It answers \"will this load\", not \"is\n * this well-formed\" — checksums, table-specific contents and glyph data are\n * out of scope. Every check here is one a font system performs before it can\n * index a face at all, which is what makes a failure worth a warning rather\n * than a matter of taste.\n */\n\nimport { readNameRecords } from './ttf-name';\n\nexport interface FontStructureDiagnostic {\n code: 'FONT_UNREADABLE';\n message: string;\n}\n\n/** sfnt versions a font system will attempt to load. */\nconst SFNT_VERSIONS = new Set<number>([\n 0x00010000, // TrueType outlines\n 0x4f54544f, // 'OTTO' — CFF outlines\n 0x74727565, // 'true'\n 0x74797031, // 'typ1'\n]);\n\nconst HEADER_SIZE = 12;\nconst TABLE_RECORD_SIZE = 16;\n\n/**\n * Inspect the sfnt envelope of a font we are about to hand to a font system.\n * Returns the first thing that makes it unloadable, or null.\n *\n * One diagnostic, not a list: past the first structural failure every later\n * check is reading rubble, and a caller can only act on the file as a whole\n * anyway.\n */\nexport function validateFontStructure(\n ttf: Buffer,\n weight: number,\n italic: boolean,\n familyLabel: string\n): FontStructureDiagnostic | null {\n const face = `Font \"${familyLabel}\" weight ${weight}${italic ? ' italic' : ''}`;\n const unreadable = (reason: string): FontStructureDiagnostic => ({\n code: 'FONT_UNREADABLE',\n message: `${face}: ${reason} The face will not resolve; text referencing it renders in a fallback.`,\n });\n\n if (ttf.length < HEADER_SIZE) {\n return unreadable(\n `${ttf.length} bytes is shorter than an sfnt header — the download is truncated or empty.`\n );\n }\n const version = ttf.readUInt32BE(0);\n if (!SFNT_VERSIONS.has(version)) {\n return unreadable(\n `sfnt version 0x${version.toString(16).padStart(8, '0')} is neither TrueType nor OpenType.`\n );\n }\n\n const numTables = ttf.readUInt16BE(4);\n if (numTables === 0) return unreadable('its table directory is empty.');\n const directoryEnd = HEADER_SIZE + numTables * TABLE_RECORD_SIZE;\n if (directoryEnd > ttf.length) {\n return unreadable(\n `its directory claims ${numTables} tables (${directoryEnd} bytes) but the file is ${ttf.length} bytes — truncated.`\n );\n }\n\n // Directory offsets in range. A table pointing past the end is the shape a\n // truncated download takes once it keeps enough bytes for the directory.\n const tags = new Set<string>();\n for (let i = 0; i < numTables; i += 1) {\n const ro = HEADER_SIZE + i * TABLE_RECORD_SIZE;\n const tag = ttf.toString('ascii', ro, ro + 4);\n const offset = ttf.readUInt32BE(ro + 8);\n const length = ttf.readUInt32BE(ro + 12);\n if (offset + length > ttf.length) {\n return unreadable(\n `its \"${tag}\" table runs to byte ${offset + length} but the file is ${ttf.length} bytes — truncated.`\n );\n }\n tags.add(tag);\n }\n\n // `name` carries the family every consumer looks a face up by, and `head`\n // the units-per-em every consumer scales it with. Neither is optional.\n for (const required of ['name', 'head']) {\n if (!tags.has(required)) {\n return unreadable(`it has no \"${required}\" table.`);\n }\n }\n\n // Outlines: glyf + loca (TrueType) or a CFF table (OpenType). Without them\n // there is nothing to draw, whatever else the file carries.\n const hasTrueTypeOutlines = tags.has('glyf') && tags.has('loca');\n const hasCffOutlines = tags.has('CFF ') || tags.has('CFF2');\n if (!hasTrueTypeOutlines && !hasCffOutlines) {\n return unreadable(\n 'it carries no glyph outlines (neither \"glyf\" + \"loca\" nor \"CFF \").'\n );\n }\n\n // Present is not the same as readable: the reader bounds every record by\n // the table's own extent, so a `name` table with a corrupt header or\n // out-of-range string offsets yields nothing and the face is unindexable.\n if (readNameRecords(ttf).length === 0) {\n return unreadable('its \"name\" table carries no readable records.');\n }\n\n return null;\n}\n","/**\n * In-process LRU cache for resolved font buffers.\n * Scoped to a single process — do not share across requests on a server.\n */\n\nexport interface MemoryCacheOptions {\n /** Approximate soft cap in bytes. LRU-evict when exceeded. */\n maxBytes?: number;\n}\n\nexport class FontMemoryCache {\n private readonly store = new Map<string, Buffer>();\n private bytes = 0;\n private readonly maxBytes: number;\n\n constructor(opts: MemoryCacheOptions = {}) {\n this.maxBytes = opts.maxBytes ?? 20 * 1024 * 1024; // 20 MB default\n }\n\n get(key: string): Buffer | undefined {\n const v = this.store.get(key);\n if (!v) return undefined;\n // Refresh LRU position.\n this.store.delete(key);\n this.store.set(key, v);\n return v;\n }\n\n set(key: string, value: Buffer): void {\n const existing = this.store.get(key);\n if (existing) this.bytes -= existing.byteLength;\n this.store.set(key, value);\n this.bytes += value.byteLength;\n while (this.bytes > this.maxBytes && this.store.size > 0) {\n const oldest = this.store.keys().next().value as string | undefined;\n if (!oldest) break;\n const removed = this.store.get(oldest);\n this.store.delete(oldest);\n if (removed) this.bytes -= removed.byteLength;\n }\n }\n\n size(): number {\n return this.store.size;\n }\n}\n","/**\n * FontRegistry — merges catalog + document registry + runtime entries\n * and materializes referenced fonts into ResolvedFont records.\n *\n * Resolution rules, per referenced name:\n * 1. Registry match (by family or id, case-insensitive). Runtime entries win\n * on collision with document entries. Materialize each source.\n * 2. SAFE_FONTS membership → empty sources.\n * 3. Otherwise → empty sources with FONT_UNRESOLVED warning.\n */\n\nimport { isSafeFont } from '../schemas/font-catalog';\nimport type { FontRegistryEntry, FontSource } from '../schemas/font-catalog';\nimport type {\n FontRuntimeOpts,\n ResolvedFont,\n ResolvedFontSource,\n} from './types';\nimport { loadDataFontSource } from './sources/data-loader';\nimport { fetchGoogleFontSources } from './sources/google-fetcher';\nimport { fetchUrlFontSource } from './sources/url-fetcher';\nimport { validateFontMetadata } from './sources/ttf-validate';\nimport { validateFontStructure } from './sources/ttf-structure';\nimport {\n readFontFamilyNames,\n rewriteFontFamilyName,\n standardSubfamilyNames,\n} from './sources/ttf-name';\nimport { FontMemoryCache } from './cache/memory-cache';\n\n/**\n * Minimal interface the registry needs from a disk cache. The concrete\n * implementation ships in `./cache/disk-cache` but is Node-only (uses fs/crypto).\n * Callers on Node inject an instance; browser callers pass nothing.\n */\nexport interface FontDiskCacheLike {\n get(key: string): Promise<Buffer | undefined>;\n set(key: string, value: Buffer): Promise<void>;\n}\n\n/**\n * Minimal interface for a file-loader. Same reasoning as FontDiskCacheLike:\n * concrete impl is Node-only, callers inject when on Node.\n */\nexport type FontFileLoader = (input: {\n path: string;\n weight?: number;\n italic?: boolean;\n baseDir?: string;\n}) => Promise<ResolvedFontSource>;\n\n/**\n * Minimal interface for the variable-font fetcher. `subset-font` (the\n * harfbuzz-wasm wrapper we use for axis pinning) reaches for `fs` at\n * init time, which crashes in the browser. Injection keeps that import\n * behind the Node-only subpath; browser bundles never pull it in, and\n * browser callers simply won't see `kind: 'variable'` fonts resolved\n * (the registry warns and skips instead).\n */\nexport type FontVariableLoader = (input: {\n url: string;\n weight: number;\n italic: boolean;\n axes?: Record<string, number>;\n fetchTimeoutMs?: number;\n memoryCache?: {\n get(key: string): Buffer | undefined;\n set(key: string, value: Buffer): void;\n };\n diskCache?: {\n get(key: string): Promise<Buffer | undefined>;\n set(key: string, value: Buffer): Promise<void>;\n };\n}) => Promise<{ source?: ResolvedFontSource; warnings?: string[] }>;\n\nexport interface FontRegistryInput {\n /** Runtime options — entries come from opts.extraEntries. */\n opts?: FontRuntimeOpts;\n /** Optional disk cache (Node only). Pass an instance of FontDiskCache. */\n diskCache?: FontDiskCacheLike;\n /**\n * Optional `kind: \"file\"` loader (Node only). Inject `loadFileFontSource`\n * from `@json-to-office/shared/fonts/sources/file-loader` on Node. Browser\n * callers pass nothing; `kind: \"file\"` sources then warn and skip.\n */\n fileLoader?: FontFileLoader;\n /**\n * Optional `kind: \"variable\"` loader (Node only). Inject\n * `fetchVariableFontSource` from `@json-to-office/shared/fonts/node` on\n * Node. Browser callers pass nothing; `kind: \"variable\"` sources then\n * warn and skip. Keeping this injected avoids dragging subset-font (and\n * its `fs.promises.readFile` bootstrap) into client bundles.\n */\n variableLoader?: FontVariableLoader;\n}\n\n/**\n * Make the bytes declare the family they were resolved as.\n *\n * `ResolvedFont.family` is a claim about the bytes that every consumer\n * relies on and that nothing used to enforce. A host — Core Text,\n * fontconfig, GDI — finds a face by the family in its `name` table, never\n * by the registry entry or the filename, so a source whose name table says\n * something else is unreachable from the runs that reference it. It fails\n * silently: on a machine that happens to have the real family installed the\n * reference lands there instead, and only a host without it (a container,\n * a colleague's laptop) shows the fallback.\n *\n * The case that forced this: Inter resolves through an upstream override\n * that instances `InterVariable.ttf` per weight, and harfbuzz keeps the\n * master's name table — so every instance called itself \"Inter Variable\".\n * The weighted faces were saved by the preview stager renaming them to\n * \"Inter Medium\" / \"Inter SemiBold\" on the way out; weights 400 and 700\n * kept the family name unchanged (they ride the run's bold/italic toggles\n * instead), so those alone were staged under a name no run asks for.\n *\n * Matching on ANY declared name (family or typographic family) keeps a\n * legitimately-named static untouched: LifeSans-Medium.ttf registered as\n * \"Life Sans\" already answers to it via nameID 16, even though nameID 1\n * says \"Life Sans Medium\". Only bytes that answer to nothing get rewritten.\n */\nfunction stampResolvedFamily(\n source: ResolvedFontSource,\n family: string\n): ResolvedFontSource {\n if (source.format !== 'ttf' && source.format !== 'otf') return source;\n const declared = readFontFamilyNames(source.data);\n // Nothing declared: no claim to contradict, and nothing to repair against.\n if (declared.length === 0 || declared.includes(family)) return source;\n // The style this face occupies within `family`. The family IDs become\n // `family` for all four RIBBI faces, so full/PostScript names have to\n // carry the style or roman and italic collide on both.\n const subfamily = standardSubfamilyNames(\n source.weight,\n source.italic\n )?.legacy;\n return {\n ...source,\n data: rewriteFontFamilyName(source.data, family, subfamily),\n };\n}\n\nexport class FontRegistry {\n private readonly index: Map<string, FontRegistryEntry>;\n private readonly cache: Map<string, ResolvedFont>;\n private readonly opts: FontRuntimeOpts;\n private readonly memoryCache: FontMemoryCache;\n private readonly diskCache: FontDiskCacheLike | undefined;\n private readonly fileLoader: FontFileLoader | undefined;\n private readonly variableLoader: FontVariableLoader | undefined;\n\n constructor(input: FontRegistryInput = {}) {\n this.opts = input.opts ?? {};\n this.index = new Map();\n this.cache = new Map();\n this.memoryCache = new FontMemoryCache();\n this.diskCache = input.diskCache;\n this.fileLoader = input.fileLoader;\n this.variableLoader = input.variableLoader;\n\n for (const e of this.opts.extraEntries ?? []) this.addEntry(e);\n }\n\n private addEntry(entry: FontRegistryEntry): void {\n this.index.set(entry.family.toLowerCase(), entry);\n this.index.set(entry.id.toLowerCase(), entry);\n }\n\n /** Resolve every referenced name in one pass. Order preserved. */\n async resolveMany(names: Iterable<string>): Promise<ResolvedFont[]> {\n const out: ResolvedFont[] = [];\n for (const n of names) out.push(await this.resolve(n));\n return out;\n }\n\n async resolve(name: string): Promise<ResolvedFont> {\n const key = name.toLowerCase();\n const cached = this.cache.get(key);\n if (cached) return cached;\n\n const entry = this.index.get(key);\n let result: ResolvedFont;\n\n if (entry) {\n result = await this.materializeEntry(entry);\n } else if (isSafeFont(name)) {\n result = { family: name, sources: [], warnings: [] };\n } else {\n result = {\n family: name,\n sources: [],\n warnings: [\n `Font \"${name}\" is not registered and not in SAFE_FONTS; will rely on host fallback.`,\n ],\n };\n }\n this.cache.set(key, result);\n return result;\n }\n\n private async materializeEntry(\n entry: FontRegistryEntry\n ): Promise<ResolvedFont> {\n const sources: ResolvedFontSource[] = [];\n const warnings: string[] = [];\n\n for (const source of entry.sources) {\n try {\n const materialized = await this.materializeSource(source, warnings);\n for (const raw of materialized) {\n const sfnt = raw.format === 'ttf' || raw.format === 'otf';\n // Can a font system load these bytes at all? Asked first, and on\n // failure asked instead of everything below: the stamp has no name\n // table to write into and the metadata checks no records to read,\n // so both would quietly do nothing and report nothing. The source\n // is still returned — this diagnoses the file, it doesn't decide\n // for the caller whether to ship it.\n const broken = sfnt\n ? validateFontStructure(\n raw.data,\n raw.weight,\n raw.italic,\n entry.family\n )\n : null;\n if (broken) {\n warnings.push(`[${broken.code}] ${broken.message}`);\n sources.push(raw);\n continue;\n }\n const s = stampResolvedFamily(raw, entry.family);\n if (sfnt) {\n for (const d of validateFontMetadata(\n s.data,\n s.weight,\n s.italic,\n entry.family\n )) {\n warnings.push(`[FONT_METADATA_DEFECT:${d.code}] ${d.message}`);\n }\n }\n sources.push(s);\n }\n } catch (err) {\n warnings.push(\n `Font \"${entry.family}\" source (${source.kind}) failed: ${\n (err as Error).message\n }`\n );\n }\n }\n\n return {\n family: entry.family,\n sources,\n warnings,\n };\n }\n\n private async materializeSource(\n source: FontSource,\n warnings: string[]\n ): Promise<ResolvedFontSource[]> {\n switch (source.kind) {\n case 'safe':\n // System-installed; no embedding data.\n return [];\n case 'file': {\n if (!this.fileLoader) {\n warnings.push(\n `kind:\"file\" source for \"${source.path}\" requires a fileLoader (Node-only); skipping.`\n );\n return [];\n }\n return [\n await this.fileLoader({\n path: source.path,\n weight: source.weight,\n italic: source.italic,\n baseDir: this.opts.baseDir,\n }),\n ];\n }\n case 'data':\n return [\n loadDataFontSource({\n data: source.data,\n weight: source.weight,\n italic: source.italic,\n }),\n ];\n case 'google': {\n const gf = this.opts.googleFonts;\n if (gf?.enabled === false) {\n warnings.push(\n `Google Fonts fetch disabled — skipping \"${source.family}\".`\n );\n return [];\n }\n const { sources: fetched, warnings: fetchWarnings } =\n await fetchGoogleFontSources({\n family: source.family,\n weights: source.weights ?? [400, 700],\n italics: source.italics ?? false,\n memoryCache: this.memoryCache,\n diskCache: this.diskCache,\n fetchTimeoutMs: gf?.fetchTimeoutMs,\n });\n warnings.push(...fetchWarnings);\n return fetched;\n }\n case 'url': {\n const gf = this.opts.googleFonts;\n const { source: fetched, warnings: fetchWarnings } =\n await fetchUrlFontSource({\n url: source.url,\n weight: source.weight ?? 400,\n italic: source.italic ?? false,\n memoryCache: this.memoryCache,\n diskCache: this.diskCache,\n fetchTimeoutMs: gf?.fetchTimeoutMs,\n });\n if (fetchWarnings) warnings.push(...fetchWarnings);\n return fetched ? [fetched] : [];\n }\n case 'variable': {\n // Variable-font instancing: fetch the variable TTF once (disk-\n // cached), then harfbuzz-pin the `wght` axis to produce a clean\n // static for this weight. Requires a Node-injected loader because\n // `subset-font` pulls in `fs` at init; without it, browser\n // bundles would break. Callers on Node pass `fetchVariableFontSource`\n // from `@json-to-office/shared/fonts/node`.\n if (!this.variableLoader) {\n warnings.push(\n `kind:\"variable\" source for \"${source.url}\" requires a variableLoader (Node-only); skipping.`\n );\n return [];\n }\n const gf = this.opts.googleFonts;\n const { source: fetched, warnings: fetchWarnings } =\n await this.variableLoader({\n url: source.url,\n weight: source.weight,\n italic: source.italic ?? false,\n axes: source.axes,\n memoryCache: this.memoryCache,\n diskCache: this.diskCache,\n fetchTimeoutMs: gf?.fetchTimeoutMs,\n });\n if (fetchWarnings) warnings.push(...fetchWarnings);\n return fetched ? [fetched] : [];\n }\n default:\n // Exhaustiveness guard — new kind added to schema without handler\n throw new Error(\n `Unknown font source kind: ${(source as { kind: string }).kind}`\n );\n }\n }\n}\n","/**\n * Curated list of popular Google Fonts for picker autocomplete.\n *\n * Not exhaustive — the full Google Fonts library has ~1500 families.\n * This is ~37 names known to cover most real-world use cases.\n */\n\nexport interface PopularGoogleFont {\n family: string;\n category: 'sans' | 'serif' | 'mono' | 'display' | 'handwriting';\n /** Weights available on Google Fonts for this family. */\n weights: number[];\n /** Whether italic variants exist. */\n hasItalic: boolean;\n}\n\nexport const POPULAR_GOOGLE_FONTS: readonly PopularGoogleFont[] = [\n // Sans-serif\n {\n family: 'Inter',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: false,\n },\n {\n family: 'Roboto',\n category: 'sans',\n weights: [100, 300, 400, 500, 700, 900],\n hasItalic: true,\n },\n {\n family: 'Open Sans',\n category: 'sans',\n weights: [300, 400, 500, 600, 700, 800],\n hasItalic: true,\n },\n {\n family: 'Lato',\n category: 'sans',\n weights: [100, 300, 400, 700, 900],\n hasItalic: true,\n },\n {\n family: 'Montserrat',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Poppins',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Work Sans',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Nunito',\n category: 'sans',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'DM Sans',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Rubik',\n category: 'sans',\n weights: [300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Source Sans 3',\n category: 'sans',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Manrope',\n category: 'sans',\n weights: [200, 300, 400, 500, 600, 700, 800],\n hasItalic: false,\n },\n {\n family: 'Plus Jakarta Sans',\n category: 'sans',\n weights: [200, 300, 400, 500, 600, 700, 800],\n hasItalic: true,\n },\n {\n family: 'IBM Plex Sans',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700],\n hasItalic: true,\n },\n {\n family: 'Archivo',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Geist',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Space Grotesk',\n category: 'sans',\n weights: [300, 400, 500, 600, 700],\n hasItalic: false,\n },\n\n // Serif\n {\n family: 'Playfair Display',\n category: 'serif',\n weights: [400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Merriweather',\n category: 'serif',\n weights: [300, 400, 700, 900],\n hasItalic: true,\n },\n {\n family: 'Lora',\n category: 'serif',\n weights: [400, 500, 600, 700],\n hasItalic: true,\n },\n {\n family: 'Source Serif 4',\n category: 'serif',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'DM Serif Display',\n category: 'serif',\n weights: [400],\n hasItalic: true,\n },\n {\n family: 'Crimson Pro',\n category: 'serif',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Cormorant Garamond',\n category: 'serif',\n weights: [300, 400, 500, 600, 700],\n hasItalic: true,\n },\n\n // Monospace\n {\n family: 'JetBrains Mono',\n category: 'mono',\n weights: [100, 200, 300, 400, 500, 600, 700, 800],\n hasItalic: true,\n },\n {\n family: 'Fira Code',\n category: 'mono',\n weights: [300, 400, 500, 600, 700],\n hasItalic: false,\n },\n {\n family: 'IBM Plex Mono',\n category: 'mono',\n weights: [100, 200, 300, 400, 500, 600, 700],\n hasItalic: true,\n },\n {\n family: 'Source Code Pro',\n category: 'mono',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Space Mono',\n category: 'mono',\n weights: [400, 700],\n hasItalic: true,\n },\n {\n family: 'Geist Mono',\n category: 'mono',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n\n // Display\n {\n family: 'Bebas Neue',\n category: 'display',\n weights: [400],\n hasItalic: false,\n },\n {\n family: 'Abril Fatface',\n category: 'display',\n weights: [400],\n hasItalic: false,\n },\n {\n family: 'Archivo Black',\n category: 'display',\n weights: [400],\n hasItalic: false,\n },\n {\n family: 'Oswald',\n category: 'display',\n weights: [200, 300, 400, 500, 600, 700],\n hasItalic: false,\n },\n\n // Handwriting\n {\n family: 'Caveat',\n category: 'handwriting',\n weights: [400, 500, 600, 700],\n hasItalic: false,\n },\n {\n family: 'Pacifico',\n category: 'handwriting',\n weights: [400],\n hasItalic: false,\n },\n];\n","/**\n * Per-family upstream overrides for popular Google Fonts whose\n * redistribution on fonts.google.com has known defects we can't fix via\n * metadata patching alone.\n *\n * When `autoGoogleFontEntries` hits a family present in this table, it\n * builds override sources instead of issuing `kind: \"google\"` CSS requests.\n * Each entry is either:\n *\n * - `{ kind: \"url\", url, weight, italic? }` — a direct HTTPS TTF/OTF.\n * Use when a clean per-weight static exists on a stable CDN.\n *\n * - `{ kind: \"variable\", url, weight, italic? }` — points at a variable\n * TTF with an `fvar` table. The registry downloads the variable font\n * once and harfbuzz-pins the `wght` axis to the specified weight,\n * producing a clean static TTF. Use when the upstream ships a variable\n * font but no per-weight statics on a CDN (rsms/inter is the\n * canonical example — variable font on jsDelivr, per-weight statics\n * only in GitHub release zips).\n *\n * Pick `variable` over `url` when both are available: the instancer\n * produces per-weight glyph outlines that diverge correctly at every\n * axis value. Google's static redistributions collapse adjacent weights\n * onto the same instance — Inter Thin and ExtraLight both source at\n * ~wght=250 in Google's pipeline, so their static TTFs have 98% identical\n * glyph outlines. Instancing the upstream variable font at exactly wght=100\n * vs wght=200 gives properly distinct geometry.\n *\n * Validate new entries with a HEAD request before adding — the fetchers\n * reject non-TTF responses, but a failed override silently falls back to\n * the Google path, defeating the purpose.\n */\n\n/** One upstream variant source. Type matches the FontSource schema so we\n * can pass the entry directly into `FontRegistry`'s materialize pipeline. */\nexport type UpstreamVariant =\n | {\n kind: 'url';\n url: string;\n weight: number;\n italic?: boolean;\n }\n | {\n kind: 'variable';\n url: string;\n weight: number;\n italic?: boolean;\n /** Extra axis pins merged on top of the derived `wght` pin. */\n axes?: Record<string, number>;\n };\n\nexport interface UpstreamOverride {\n /** Human-readable for logs/diagnostics only. */\n reason: string;\n variants: UpstreamVariant[];\n}\n\n/**\n * rsms/inter publishes the upright variable master as `InterVariable.ttf`\n * on jsDelivr, but the italic master ONLY as `InterVariable-Italic.woff2`\n * — no italic `.ttf` exists under `docs/font-files/` at any tag, so a\n * `.ttf` italic URL 404s and every italic Inter run silently falls back\n * to host defaults. The variable fetcher accepts woff2 sources (fontverter\n * converts to sfnt before instancing), so point at the woff2 directly.\n *\n * We instance each master at every advertised weight so Inter Thin (100),\n * ExtraLight (200), Light (300), Medium (500), SemiBold (600), ExtraBold\n * (800), and Black (900) come out with distinct glyph outlines instead of\n * the near-duplicates Google's static redistribution ships. Regular (400)\n * and Bold (700) from Google were already clean, but instancing them from\n * the same variable font keeps the full family visually consistent.\n *\n * Version pin: `@v4.1` — the last stable rsms/inter release at the time\n * of writing. jsDelivr caches the file aggressively; a version bump here\n * invalidates that cache for users on a subsequent generate.\n */\nconst INTER_VARIABLE_URL =\n 'https://cdn.jsdelivr.net/gh/rsms/inter@v4.1/docs/font-files/InterVariable.ttf';\nconst INTER_VARIABLE_ITALIC_URL =\n 'https://cdn.jsdelivr.net/gh/rsms/inter@v4.1/docs/font-files/InterVariable-Italic.woff2';\n\nfunction interVariants(): UpstreamVariant[] {\n const weights = [100, 200, 300, 400, 500, 600, 700, 800, 900];\n const upright = weights.map((weight) => ({\n kind: 'variable' as const,\n url: INTER_VARIABLE_URL,\n weight,\n italic: false,\n }));\n const italic = weights.map((weight) => ({\n kind: 'variable' as const,\n url: INTER_VARIABLE_ITALIC_URL,\n weight,\n italic: true,\n }));\n return [...upright, ...italic];\n}\n\nexport const UPSTREAM_OVERRIDES: Record<string, UpstreamOverride> = {\n inter: {\n reason:\n \"Google's static Inter Thin/ExtraLight both carry usWeightClass=250 and near-identical glyph outlines (xAvgCharWidth differs by 1.8%); instancing the upstream variable font per weight produces properly distinct statics.\",\n variants: interVariants(),\n },\n};\n\n/** Case-insensitive lookup. Returns undefined when the family has no override. */\nexport function getUpstreamOverride(\n family: string\n): UpstreamOverride | undefined {\n return UPSTREAM_OVERRIDES[family.toLowerCase()];\n}\n","/**\n * Font family substitution: rewrite every non-safe family reference in\n * the doc tree + theme to a SAFE_FONTS equivalent. Used by the\n * `'substitute'` export mode (`FontRuntimeOpts.mode`) so that non-safe\n * fonts (Playfair Display, Inter, …) ship as Georgia/Calibri and the\n * document renders identically on every recipient machine — no embed\n * bytes, no Word-for-Mac intermediate-weight surprises.\n *\n * The walker mirrors the shape used by `collectFontNamesFromDocx/Pptx`\n * so the two stay in sync: whatever `collect` scans, `rewrite` will\n * rewrite. Future component-schema additions that introduce new font\n * keys go in `FONT_NAME_KEYS` / `THEME_FONT_KEYS` once, both sides pick\n * them up.\n */\n\nimport { SAFE_FONTS, isSafeFont } from '../schemas/font-catalog';\nimport { POPULAR_GOOGLE_FONTS } from './catalog/popular-google';\nimport {\n FONT_NAME_KEYS,\n THEME_FONT_KEYS,\n FONT_DECLARATION_KEYS,\n} from './collect';\n\n/** One swap recorded during a rewrite. */\nexport interface FontSubstitution {\n from: string;\n to: string;\n}\n\nexport interface ApplyFontSubstitutionResult<T> {\n doc: T;\n substitutions: FontSubstitution[];\n}\n\n/**\n * Walk a doc tree + swap every non-safe family reference per `mapping`.\n * Returns a new tree (structural clone) plus the list of `(from, to)`\n * swaps made, deduped by source name.\n *\n * One deliberate exception to the clone: `fontRegistry` subtrees are carried\n * through by reference, since they declare fonts rather than reference them\n * and nothing downstream mutates them.\n *\n * Families already in SAFE_FONTS are never rewritten (even if a mapping\n * entry targets them as a key — safe fonts don't need substitution).\n * Families with no mapping entry are left untouched — callers should\n * feed the result of `buildDefaultSubstitutionMap` to ensure every\n * non-safe reference gets a fallback.\n */\nexport function applyFontSubstitution<T>(\n doc: T,\n mapping: Record<string, string>\n): ApplyFontSubstitutionResult<T> {\n const seen = new Map<string, string>();\n const rewritten = rewrite(doc, mapping, seen) as T;\n const substitutions: FontSubstitution[] = [];\n for (const [from, to] of seen) substitutions.push({ from, to });\n return { doc: rewritten, substitutions };\n}\n\nfunction rewrite(\n node: unknown,\n mapping: Record<string, string>,\n seen: Map<string, string>,\n parentKey?: string\n): unknown {\n if (node == null) return node;\n\n if (typeof node === 'string') {\n if (\n parentKey &&\n (FONT_NAME_KEYS.has(parentKey) || THEME_FONT_KEYS.has(parentKey))\n ) {\n return maybeSwap(node, mapping, seen);\n }\n return node;\n }\n\n if (Array.isArray(node)) {\n return node.map((item) => rewrite(item, mapping, seen, parentKey));\n }\n\n if (typeof node === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n // Mirror of collect.ts: a fontRegistry subtree declares families, it\n // does not reference them. Rewriting `entry.family` would rename the\n // registration out from under every reference and key an entry on a\n // SAFE_FONTS name. Carry it through by reference (see the clone note\n // on applyFontSubstitution).\n if (FONT_DECLARATION_KEYS.has(k)) {\n out[k] = v;\n continue;\n }\n // Parallel to collect.ts: `theme.fonts` may hold plain strings\n // keyed by heading/body/mono/light. Those strings are font names\n // and need swapping just like `font.family` does.\n if (\n parentKey === 'theme' &&\n k === 'fonts' &&\n v &&\n typeof v === 'object'\n ) {\n const nextFonts: Record<string, unknown> = {};\n for (const [fk, fv] of Object.entries(v as Record<string, unknown>)) {\n if (typeof fv === 'string') {\n nextFonts[fk] = maybeSwap(fv, mapping, seen);\n } else if (fv && typeof fv === 'object') {\n const fam = (fv as Record<string, unknown>).family;\n nextFonts[fk] =\n typeof fam === 'string'\n ? { ...(fv as object), family: maybeSwap(fam, mapping, seen) }\n : rewrite(fv, mapping, seen, fk);\n } else {\n nextFonts[fk] = fv;\n }\n }\n out[k] = nextFonts;\n continue;\n }\n out[k] = rewrite(v, mapping, seen, k);\n }\n return out;\n }\n\n return node;\n}\n\nfunction maybeSwap(\n name: string,\n mapping: Record<string, string>,\n seen: Map<string, string>\n): string {\n const trimmed = name.trim();\n if (trimmed.length === 0) return name;\n if (isSafeFont(trimmed)) return name;\n // Case-insensitive mapping lookup. Users may feed mappings with\n // slightly different casing than the doc's reference (e.g. \"inter\" vs\n // \"Inter\") — honour the target verbatim, don't force case.\n const lowered = trimmed.toLowerCase();\n for (const [from, to] of Object.entries(mapping)) {\n if (from.toLowerCase() === lowered) {\n seen.set(trimmed, to);\n return to;\n }\n }\n return name;\n}\n\n// ---------------------------------------------------------------------------\n// Default-mapping builder\n// ---------------------------------------------------------------------------\n\n/**\n * Explicit overrides for the most common non-safe fonts we see. Chosen\n * for visual similarity: sans serifs map to Calibri, serifs to Georgia\n * or Cambria depending on axis proportion, monospace to Consolas.\n * Extendable as real usage surfaces more families.\n */\nconst EXPLICIT_OVERRIDES: Record<string, string> = {\n Inter: 'Calibri',\n Roboto: 'Calibri',\n 'Open Sans': 'Calibri',\n Lato: 'Calibri',\n 'Source Sans 3': 'Calibri',\n 'Source Sans Pro': 'Calibri',\n 'IBM Plex Sans': 'Calibri',\n Archivo: 'Calibri',\n Geist: 'Calibri',\n 'Space Grotesk': 'Calibri',\n 'Work Sans': 'Calibri',\n Manrope: 'Calibri',\n Nunito: 'Calibri',\n 'Nunito Sans': 'Calibri',\n Poppins: 'Calibri',\n Montserrat: 'Calibri',\n 'Playfair Display': 'Georgia',\n Merriweather: 'Georgia',\n 'Source Serif 4': 'Cambria',\n 'Source Serif Pro': 'Cambria',\n 'IBM Plex Serif': 'Cambria',\n 'Crimson Pro': 'Cambria',\n Lora: 'Georgia',\n 'PT Serif': 'Georgia',\n 'Cormorant Garamond': 'Cambria',\n 'JetBrains Mono': 'Consolas',\n 'Fira Code': 'Consolas',\n 'IBM Plex Mono': 'Consolas',\n 'Source Code Pro': 'Consolas',\n 'Roboto Mono': 'Consolas',\n 'Geist Mono': 'Consolas',\n};\n\nconst CATEGORY_FALLBACK: Record<string, string> = {\n sans: 'Calibri',\n serif: 'Georgia',\n mono: 'Consolas',\n display: 'Georgia',\n handwriting: 'Segoe UI',\n};\n\n/**\n * Pick the safe-font fallback for a single non-safe family. Precedence:\n * 1. Explicit override in `EXPLICIT_OVERRIDES`.\n * 2. Category lookup in `POPULAR_GOOGLE_FONTS`.\n * 3. Final default (`Calibri`).\n *\n * Exposed for the playground dialog so it can pre-populate the per-family\n * picker with the same defaults the CLI would apply.\n */\nexport function defaultSubstituteFor(family: string): string {\n const trimmed = family.trim();\n // Explicit (case-insensitive).\n for (const [from, to] of Object.entries(EXPLICIT_OVERRIDES)) {\n if (from.toLowerCase() === trimmed.toLowerCase()) return to;\n }\n // Category.\n const catalog = POPULAR_GOOGLE_FONTS.find(\n (f) => f.family.toLowerCase() === trimmed.toLowerCase()\n );\n if (catalog) {\n const cat = CATEGORY_FALLBACK[catalog.category];\n if (cat) return cat;\n }\n return 'Calibri';\n}\n\n/**\n * Build a substitution map for every non-safe family in `referencedNames`.\n * Safe fonts are omitted from the result since they don't need swapping.\n * Caller can override individual entries before passing to\n * `applyFontSubstitution`.\n */\nexport function buildDefaultSubstitutionMap(\n referencedNames: Iterable<string>\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const raw of referencedNames) {\n const name = raw.trim();\n if (name.length === 0) continue;\n if (isSafeFont(name)) continue;\n if (out[name]) continue;\n out[name] = defaultSubstituteFor(name);\n }\n return out;\n}\n\n/** Re-export SAFE_FONTS for dialog/CLI consumers that need the allowlist. */\nexport { SAFE_FONTS };\n\n// ---------------------------------------------------------------------------\n// Export-mode pre-pass\n// ---------------------------------------------------------------------------\n\nimport type { FontRuntimeOpts } from './types';\nimport { collectFontNames } from './collect';\n\nexport interface ApplyExportModeInput<D, T> {\n doc: D;\n theme: T;\n fonts?: FontRuntimeOpts;\n}\n\nexport interface ApplyExportModeWarning {\n code: 'FONT_MODE_CUSTOM' | 'FONT_MODE_SUBSTITUTED';\n message: string;\n}\n\nexport interface ApplyExportModeResult<D, T> {\n doc: D;\n theme: T;\n warnings: ApplyExportModeWarning[];\n}\n\n/**\n * Inspect `fonts.mode` and apply the pre-resolution rewrite for the\n * requested mode.\n *\n * - `'custom'` (default) — no rewrite. Font references stay as authored;\n * recipients need the font installed or Word falls back. The\n * LibreOffice preview stager registers resolved bytes so preview\n * fidelity matches the recipient-side experience when the font is\n * installed.\n * - `'substitute'` — rewrite every non-safe family in doc + theme to its\n * mapped safe equivalent. Fills in defaults via\n * `buildDefaultSubstitutionMap` for any non-safe reference not present\n * in `fonts.substitution`. Emits one `FONT_MODE_SUBSTITUTED` warning\n * listing every swap.\n */\nexport function applyExportMode<D, T>(\n input: ApplyExportModeInput<D, T>\n): ApplyExportModeResult<D, T> {\n const mode = input.fonts?.mode ?? 'custom';\n if (mode === 'custom') {\n // Suppress the advisory entirely when callers never passed a `fonts`\n // option: they opted out of font-mode handling, so noisy per-run\n // warnings would flood existing callers that predate the pipeline.\n if (!input.fonts) {\n return { doc: input.doc, theme: input.theme, warnings: [] };\n }\n // Only emit the advisory when the doc/theme actually references a\n // non-safe family — a safe-only doc has nothing for recipients to be\n // missing, and the warning would be noise.\n const referenced = new Set<string>([\n ...collectFontNames(input.doc),\n ...collectFontNames(input.theme),\n ]);\n const nonSafe = [...referenced].filter((name) => !isSafeFont(name.trim()));\n const warnings: ApplyExportModeWarning[] =\n nonSafe.length > 0\n ? [\n {\n code: 'FONT_MODE_CUSTOM',\n message: `Export mode \"custom\": non-safe font references (${nonSafe.join(', ')}) kept as-is. Recipients need these fonts installed locally; Word falls back to a generic substitute otherwise.`,\n },\n ]\n : [];\n return {\n doc: input.doc,\n theme: input.theme,\n warnings,\n };\n }\n // mode === 'substitute'\n const referenced = new Set<string>([\n ...collectFontNames(input.doc),\n ...collectFontNames(input.theme),\n ]);\n const defaults = buildDefaultSubstitutionMap(referenced);\n const mapping: Record<string, string> = {\n ...defaults,\n ...(input.fonts?.substitution ?? {}),\n };\n\n const docRewrite = applyFontSubstitution(input.doc, mapping);\n const themeRewrite = applyFontSubstitution(input.theme, mapping);\n const combined = new Map<string, string>();\n for (const s of docRewrite.substitutions) combined.set(s.from, s.to);\n for (const s of themeRewrite.substitutions) combined.set(s.from, s.to);\n\n const warnings: ApplyExportModeWarning[] = [];\n if (combined.size > 0) {\n const list = [...combined]\n .map(([from, to]) => `${from} → ${to}`)\n .join(', ');\n warnings.push({\n code: 'FONT_MODE_SUBSTITUTED',\n message: `Export mode \"substitute\": rewrote non-safe families to safe equivalents — ${list}. No fonts embedded; document renders identically on every machine.`,\n });\n }\n return {\n doc: docRewrite.doc,\n theme: themeRewrite.doc,\n warnings,\n };\n}\n","/**\n * Default series-color tokens for charts. Single source of truth for every\n * format: the PPTX `chart` and `highcharts` components and the DOCX\n * `highcharts` component all resolve this list, in this order, against the\n * active theme when the author sets no explicit colors. Both theme schemas\n * declare all six tokens (accent4-6 optional in each), so a theme that fills\n * every slot produces the same palette in a deck and in a document.\n *\n * Slots the theme leaves unset are skipped in both formats: the implicit\n * palette shrinks and the chart library cycles the shorter list rather than\n * repeating `primary` for every empty slot. A theme carrying only\n * primary/secondary/accent — which is what the bundled DOCX themes carry —\n * therefore paints series 4+ identically in a deck and in a document.\n *\n * Skipping compacts holes: a theme defining accent5 but not accent4 yields\n * [primary, secondary, accent, accent5], so accent5 paints series 4. The list\n * is a preference-ordered pool of candidate colors, not fixed per-series slots,\n * so keeping a color the theme did define beats dropping or duplicating one.\n *\n * DOCX legacy slots and both formats' new `palette` roles may name another\n * token. Legacy PPTX `colors` slots accept hex only at validation, though\n * both runtime resolvers walk references to hex before\n * using it, so a chained slot lands on the same color in a deck as in a\n * document. A slot whose value reaches no hex (`\"accent4\": \"nonsense\"`, or a\n * reference cycle) is dropped from the implicit palette in both formats rather\n * than emitted verbatim: PowerPoint and Highcharts both answer an unparseable\n * color with silent black. Parity here covers the token names the two schemas\n * share; each format also has private color keys (DOCX `textSecondary`, PPTX\n * `text2`) that only resolve in their own format.\n *\n * Only the implicit palette skips. An author who names a token explicitly\n * (PPTX `chartColors: ['accent4']`) still gets the `primary` fallback and a\n * warning — naming an undefined token is an authoring error and stays loud.\n * PPTX warns THEME_COLOR_FALLBACK for an unset slot and UNKNOWN_COLOR for one\n * holding an unresolvable value; DOCX throws.\n */\nexport const DEFAULT_CHART_THEME_COLORS = [\n 'primary',\n 'secondary',\n 'accent',\n 'accent4',\n 'accent5',\n 'accent6',\n];\n","/**\n * The document's typography, expressed as Highcharts options.\n *\n * A `highcharts` component is a PNG drawn by a browser that has never seen the\n * document, so nothing about the page's type reaches the chart on its own: the\n * axis labels, title and legend come out in the export server's default face\n * at Highcharts' own sizes, visibly foreign to the prose around them. The\n * palette already carries (see `chart-palette.ts`); this carries the type.\n *\n * Format-neutral on purpose. Each core reads its own theme shape into a\n * `ChartTypography` — family, colours and sizes in document points — and this\n * module turns that into the option paths Highcharts styles text through. An\n * explicit author value keeps winning, property by property, exactly as\n * `options.colors` does.\n *\n * Sizes are converted from points to chart pixels through the scale the chart\n * is placed at: a 900px chart set into a 450pt measure shrinks by half, so a\n * label that must read as 9pt on the page is drawn at 18px.\n */\n\nimport type { RasterizeFontFace } from '../types/services';\nimport type { FontRegistryEntry } from '../schemas/font-catalog';\nimport { themeFontRegistry } from '../fonts/document-registry';\n\nexport interface ChartTypography {\n /** CSS `font-family` for everything not styled otherwise (see `cssFontFamily`). */\n bodyFamily: string;\n /** CSS `font-family` for the chart title. */\n headingFamily: string;\n /** `#RRGGBB` for the title, legend and data labels. */\n textColor: string;\n /** `#RRGGBB` for axis text, subtitle, caption and credits. */\n mutedColor: string;\n /** Axis labels, axis titles, legend, subtitle and data labels, in points. */\n labelPt: number;\n /** Weight for legend items and data labels; Highcharts' own default when unset. */\n labelWeight?: number;\n /** Chart title, in points. */\n titlePt: number;\n /** Chart title weight; Highcharts' own default when unset. */\n titleWeight?: number;\n /** Credits (the source line) and caption, in points. */\n sourcePt: number;\n}\n\n/** Points per CSS pixel at the 96 dpi both formats assume for an unplaced chart. */\nexport const POINTS_PER_PIXEL_96DPI = 0.75;\n\n/**\n * How many document points one chart pixel occupies once the image is placed.\n * Unknown or degenerate widths fall back to 96 dpi, the size an unscaled\n * chart has in both formats.\n */\nexport function chartPointsPerPixel(\n chartWidthPx: number,\n placedWidthPt: number | undefined\n): number {\n if (\n !Number.isFinite(chartWidthPx) ||\n chartWidthPx <= 0 ||\n placedWidthPt === undefined ||\n !Number.isFinite(placedWidthPt) ||\n placedWidthPt <= 0\n ) {\n return POINTS_PER_PIXEL_96DPI;\n }\n return placedWidthPt / chartWidthPx;\n}\n\nconst SERIF_FAMILIES = new Set(['georgia', 'times new roman', 'cambria']);\nconst MONO_FAMILIES = new Set(['consolas', 'courier new', 'menlo', 'monaco']);\n\ntype FontCategory = NonNullable<FontRegistryEntry['category']>;\n\n/**\n * A CSS `font-family` list: the family, quoted, then the generic it belongs\n * to — from the registry category when the font is registered, from the\n * SAFE_FONTS list otherwise — so a face the export server lacks degrades to\n * the right shape rather than to the browser's default.\n */\nexport function cssFontFamily(family: string, category?: FontCategory): string {\n const generic =\n category === 'serif'\n ? 'serif'\n : category === 'mono'\n ? 'monospace'\n : category === 'handwriting'\n ? 'cursive'\n : category === undefined && SERIF_FAMILIES.has(family.toLowerCase())\n ? 'serif'\n : category === undefined && MONO_FAMILIES.has(family.toLowerCase())\n ? 'monospace'\n : 'sans-serif';\n return `\"${family.replace(/[\"\\\\]/g, '\\\\$&')}\", ${generic}`;\n}\n\n/**\n * `cssFontFamily` bound to a theme: a registered family answers with its\n * registry category, an unregistered one with what SAFE_FONTS says of it.\n */\nexport function chartFamilyResolver(\n theme: unknown\n): (family: string) => string {\n const categories = new Map(\n themeFontRegistry(theme).map((entry) => [\n entry.family.toLowerCase(),\n entry.category,\n ])\n );\n return (family) =>\n cssFontFamily(family, categories.get(family.toLowerCase()));\n}\n\ntype Options = Record<string, unknown>;\n\nfunction isPlainObject(value: unknown): value is Options {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * `defaults` beneath `authored`: an authored key is never replaced, and an\n * authored value that is not an object — `null`, `false` — is kept as it is\n * rather than turned into a defaulted object.\n */\nfunction fill(authored: unknown, defaults: Options): unknown {\n if (authored !== undefined && !isPlainObject(authored)) return authored;\n const base: Options = isPlainObject(authored) ? { ...authored } : {};\n for (const [key, value] of Object.entries(defaults)) {\n if (value === undefined) continue;\n const current = base[key];\n if (current === undefined) {\n base[key] = isPlainObject(value) ? fill(undefined, value) : value;\n } else if (isPlainObject(current) && isPlainObject(value)) {\n base[key] = fill(current, value);\n }\n }\n return base;\n}\n\n/** Highcharts axes may be one object or an array of them. */\nfunction fillAxis(authored: unknown, defaults: Options): unknown {\n if (Array.isArray(authored)) {\n return authored.map((axis) => fill(axis, defaults));\n }\n return fill(authored, defaults);\n}\n\nfunction weight(value: number | undefined): string | undefined {\n return value === undefined ? undefined : String(value);\n}\n\n/**\n * The document's typography written into every Highcharts option path that\n * styles text, beneath whatever the author set. `ptPerPx` is the placement\n * scale from `chartPointsPerPixel`.\n */\nexport function withChartTypography<T extends Options>(\n options: T,\n typography: ChartTypography,\n ptPerPx: number\n): T {\n const px = (points: number): string =>\n `${Math.round((points / ptPerPx) * 10) / 10}px`;\n const labelPx = px(typography.labelPt);\n const sourcePx = px(typography.sourcePt);\n const mutedText = { fontSize: labelPx, color: typography.mutedColor };\n const mutedSource = { fontSize: sourcePx, color: typography.mutedColor };\n const labelText = {\n fontSize: labelPx,\n color: typography.textColor,\n fontWeight: weight(typography.labelWeight),\n };\n const axis = { labels: { style: mutedText }, title: { style: mutedText } };\n\n return {\n ...options,\n chart: fill(options.chart, {\n style: { fontFamily: typography.bodyFamily },\n }),\n title: fill(options.title, {\n style: {\n fontFamily: typography.headingFamily,\n fontSize: px(typography.titlePt),\n fontWeight: weight(typography.titleWeight),\n color: typography.textColor,\n },\n }),\n subtitle: fill(options.subtitle, { style: mutedText }),\n caption: fill(options.caption, { style: mutedSource }),\n xAxis: fillAxis(options.xAxis, axis),\n yAxis: fillAxis(options.yAxis, axis),\n legend: fill(options.legend, { itemStyle: labelText }),\n plotOptions: fill(options.plotOptions, {\n series: { dataLabels: { style: labelText } },\n }),\n credits: fill(options.credits, { style: mutedSource }),\n };\n}\n\nconst FONT_FORMATS: Record<\n NonNullable<RasterizeFontFace['format']>,\n { mime: string; format: string }\n> = {\n ttf: { mime: 'font/ttf', format: 'truetype' },\n otf: { mime: 'font/otf', format: 'opentype' },\n woff: { mime: 'font/woff', format: 'woff' },\n woff2: { mime: 'font/woff2', format: 'woff2' },\n};\n\n/**\n * `@font-face` rules for the faces of `families`, inlined as data URIs, so an\n * export server draws a registered font from the same bytes the document\n * stages rather than from whatever its host happens to have installed. The\n * bytes go only to the export server, which already receives every data\n * point of the chart. Empty when no face matches.\n */\nexport function chartFontFaceCss(\n faces: readonly RasterizeFontFace[],\n families: readonly string[]\n): string {\n const wanted = new Set(families.map((family) => family.toLowerCase()));\n return faces\n .filter((face) => wanted.has(face.family.toLowerCase()))\n .map((face) => {\n const { mime, format } = FONT_FORMATS[face.format ?? 'ttf'];\n return (\n `@font-face{font-family:\"${face.family.replace(/[\"\\\\]/g, '\\\\$&')}\";` +\n `font-weight:${face.weight};font-style:${face.italic ? 'italic' : 'normal'};` +\n `src:url(data:${mime};base64,${face.data}) format(\"${format}\")}`\n );\n })\n .join('\\n');\n}\n\n/**\n * The `@font-face` rules for `families` written into a chart's `resources.css`\n * ahead of whatever the author supplied there. Nothing changes when no face\n * matches, so a chart set in safe fonts posts the same request it always did.\n */\nexport function withChartFontFaceCss<\n T extends { resources?: { css?: string } },\n>(\n props: T,\n faces: readonly RasterizeFontFace[],\n families: readonly string[]\n): T {\n const css = chartFontFaceCss(faces, families);\n if (!css) return props;\n const authored = props.resources?.css;\n return {\n ...props,\n resources: {\n ...props.resources,\n css: authored ? `${css}\\n${authored}` : css,\n },\n };\n}\n","import { Type, type TSchema } from '@sinclair/typebox';\n\n/**\n * Content roles a definition may assign to a slot. A quality profile reads\n * them to require or measure content (an action title at most two lines, a\n * source under every chart); the theme only styles them. No role adds a\n * requirement on its own.\n */\nexport const BLOCK_SLOT_ROLES = [\n 'actionTitle',\n 'takeaway',\n 'source',\n 'tracker',\n 'footer',\n] as const;\nexport type BlockSlotRole = (typeof BLOCK_SLOT_ROLES)[number];\n\nexport interface BlockSlot {\n type:\n | 'string'\n | 'number'\n | 'integer'\n | 'boolean'\n | 'object'\n | 'array'\n | 'component';\n description?: string;\n required?: boolean;\n default?: unknown;\n enum?: (string | number | boolean)[];\n minItems?: number;\n maxItems?: number;\n minLength?: number;\n maxLength?: number;\n minimum?: number;\n maximum?: number;\n maxWords?: number;\n oneLine?: boolean;\n items?: BlockSlot;\n properties?: Record<string, BlockSlot>;\n role?: BlockSlotRole;\n}\n\n/** Definitions are authored data. No concrete block is registered by the core. */\nexport interface JsonBlockDefinition {\n description?: string;\n slots: Record<string, BlockSlot>;\n body: unknown[];\n /** DOCX section state, applied before rendering its header and footer. */\n section?: {\n tracker?: unknown;\n header?: unknown[];\n footer?: unknown[];\n pageBreak?: boolean;\n scope?: 'section' | 'following';\n };\n /** PPTX slide settings the invocation's slide inherits unless it states its own. */\n slide?: {\n background?: unknown;\n grid?: unknown;\n notes?: unknown;\n };\n}\n\nexport const BlockSlotSchema: TSchema = Type.Recursive(\n (Self) =>\n Type.Object(\n {\n type: Type.Union(\n [\n 'string',\n 'number',\n 'integer',\n 'boolean',\n 'object',\n 'array',\n 'component',\n ].map((v) => Type.Literal(v)),\n {\n description:\n 'Content type accepted by this slot. Use component for a document component or registered plugin.',\n }\n ),\n description: Type.Optional(\n Type.String({\n description: 'Explain this slot’s content and purpose to authors.',\n })\n ),\n required: Type.Optional(\n Type.Boolean({\n description:\n 'Require a value when no default is provided. Defaults to false.',\n })\n ),\n default: Type.Optional(\n Type.Unknown({\n description:\n 'Value used when the caller omits this slot. Must satisfy the slot’s type and constraints.',\n })\n ),\n enum: Type.Optional(\n Type.Array(\n Type.Union([Type.String(), Type.Number(), Type.Boolean()]),\n {\n minItems: 1,\n description: 'Allowed scalar values for this slot.',\n }\n )\n ),\n minItems: Type.Optional(\n Type.Integer({\n minimum: 0,\n description: 'Minimum number of array entries, inclusive.',\n })\n ),\n maxItems: Type.Optional(\n Type.Integer({\n minimum: 0,\n description: 'Maximum number of array entries, inclusive.',\n })\n ),\n minLength: Type.Optional(\n Type.Integer({\n minimum: 0,\n description: 'Minimum string length in characters, inclusive.',\n })\n ),\n maxLength: Type.Optional(\n Type.Integer({\n minimum: 0,\n description: 'Maximum string length in characters, inclusive.',\n })\n ),\n minimum: Type.Optional(\n Type.Number({ description: 'Minimum numeric value, inclusive.' })\n ),\n maximum: Type.Optional(\n Type.Number({ description: 'Maximum numeric value, inclusive.' })\n ),\n maxWords: Type.Optional(\n Type.Integer({\n minimum: 1,\n description:\n 'Maximum whitespace-separated word count. Exceeding it fails validation.',\n })\n ),\n oneLine: Type.Optional(\n Type.Boolean({\n description:\n 'Reject newline characters in string values. Does not prevent visual line wrapping.',\n })\n ),\n items: Type.Optional({\n ...Self,\n description: 'Slot type and constraints for each array entry.',\n }),\n properties: Type.Optional(\n Type.Record(Type.String(), Self, {\n description:\n 'Named child slots accepted by an object slot. Undeclared properties are rejected.',\n })\n ),\n role: Type.Optional(\n Type.Union(\n BLOCK_SLOT_ROLES.map((role) => Type.Literal(role)),\n {\n description:\n 'Content role for quality profiles: actionTitle, takeaway, source, tracker or footer. A profile may require or measure it; the theme only styles it.',\n }\n )\n ),\n },\n { additionalProperties: false }\n ),\n // Named so the export hoists it under a stable definition rather than a\n // TypeBox ordinal that shifts with what the process built before it.\n { $id: 'BlockSlot' }\n);\n\nexport const JsonBlockDefinitionSchema = Type.Unsafe<JsonBlockDefinition>(\n Type.Object(\n {\n description: Type.Optional(\n Type.String({\n description:\n 'Describe what this reusable block renders and when to use it.',\n })\n ),\n slots: Type.Record(Type.String(), BlockSlotSchema, {\n description:\n 'Named inputs and their types, defaults and constraints. Use an empty object for a block with no inputs.',\n }),\n body: Type.Array(Type.Unknown(), {\n description:\n 'Components and binding directives expanded in order when this block is invoked.',\n }),\n section: Type.Optional(\n Type.Object(\n {\n tracker: Type.Optional(\n Type.Unknown({\n description:\n 'Section tracker value or binding, available to headers and footers through $context at /section/tracker.',\n })\n ),\n header: Type.Optional(\n Type.Array(Type.Unknown(), {\n description:\n 'Header component templates. Explicit header settings on the section take precedence.',\n })\n ),\n footer: Type.Optional(\n Type.Array(Type.Unknown(), {\n description:\n 'Footer component templates. Explicit footer settings on the section take precedence.',\n })\n ),\n pageBreak: Type.Optional(\n Type.Boolean({\n description:\n 'Start the containing section on a new page. An explicit section pageBreak setting takes precedence.',\n })\n ),\n scope: Type.Optional(\n Type.Union([Type.Literal('section'), Type.Literal('following')], {\n description:\n 'Apply header/footer templates to this section only, or inherit them in following sections. Defaults to section.',\n })\n ),\n },\n {\n additionalProperties: false,\n description:\n 'DOCX section tracker, header/footer templates and page-break behavior. Place this block at the section boundary.',\n }\n )\n ),\n slide: Type.Optional(\n Type.Object(\n {\n background: Type.Optional(\n Type.Unknown({\n description:\n 'Slide background (color, gradient or image) or a binding. A background the slide states itself takes precedence.',\n })\n ),\n grid: Type.Optional(\n Type.Unknown({\n description:\n 'Grid configuration merged over the presentation grid when resolving grid placements in this block’s body.',\n })\n ),\n notes: Type.Optional(\n Type.Unknown({\n description:\n 'Speaker notes or a binding. Notes the slide states itself take precedence.',\n })\n ),\n },\n {\n additionalProperties: false,\n description:\n 'PPTX slide background, grid and notes supplied by this block. Invoke the block as a direct child of a slide.',\n }\n )\n ),\n },\n { additionalProperties: false }\n )\n);\n\nexport const BlockDefinitionsSchema = Type.Record(\n Type.String({ pattern: '^[a-zA-Z][a-zA-Z0-9_-]*$' }),\n JsonBlockDefinitionSchema,\n {\n description:\n 'Document-local JSON block definitions. Names are not built into the engine.',\n }\n);\n\nexport const BlockInvocationPropsSchema = Type.Object(\n {\n ref: Type.String({\n minLength: 1,\n description: 'Name in this document’s props.blocks.',\n }),\n slots: Type.Optional(\n Type.Record(Type.String(), Type.Unknown(), {\n description:\n 'Input values keyed by the slot names declared in the referenced block definition.',\n })\n ),\n },\n { additionalProperties: false }\n);\n\n/** Portable JSON Schema for a single slot, also used by catalog/inspect clients. */\nexport function blockSlotJsonSchema(slot: BlockSlot): Record<string, unknown> {\n const { oneLine, properties, items, role: _role, ...rest } = slot; // eslint-disable-line @typescript-eslint/no-unused-vars\n delete rest.required;\n delete rest.maxWords;\n if (slot.type === 'component') {\n return {\n type: 'object',\n properties: { name: { type: 'string' } },\n required: ['name'],\n description: slot.description,\n };\n }\n return {\n ...rest,\n ...(oneLine && { pattern: '^[^\\\\r\\\\n]*$' }),\n ...(items && { items: blockSlotJsonSchema(items) }),\n ...(properties && {\n properties: Object.fromEntries(\n Object.entries(properties).map(([key, value]) => [\n key,\n blockSlotJsonSchema(value),\n ])\n ),\n required: Object.entries(properties)\n .filter(([, value]) => value.required && value.default === undefined)\n .map(([key]) => key),\n additionalProperties: false,\n }),\n };\n}\n","/** Evaluator syntax and result families, shared with authoring-schema generation. */\nexport const BLOCK_DIRECTIVES = {\n $slot: { keys: ['$slot', 'default', 'props'], result: 'dynamic' },\n $item: { keys: ['$item', 'default', 'props'], result: 'dynamic' },\n $theme: { keys: ['$theme', 'default'], result: 'dynamic' },\n $context: { keys: ['$context', 'default'], result: 'dynamic' },\n $count: { keys: ['$count'], result: 'number' },\n $if: { keys: ['$if', 'then', 'else'], result: 'dynamic' },\n $each: { keys: ['$each', 'template'], result: 'array' },\n $join: { keys: ['$join', 'separator', 'keepEmpty'], result: 'string' },\n $measure: { keys: ['$measure', 'fraction', 'unit'], result: 'number' },\n} as const;\nexport type BlockDirective = keyof typeof BLOCK_DIRECTIVES;\n/** Roots a `$if`/`$each`/`$count` operand may name instead of a slot pointer. */\nexport const BLOCK_OPERAND_ROOTS = ['$item', '$slot', '$context'] as const;\nexport type BlockOperandRoot = (typeof BLOCK_OPERAND_ROOTS)[number];\n","import {\n BLOCK_DIRECTIVES,\n BLOCK_OPERAND_ROOTS,\n type BlockOperandRoot,\n} from './directives';\nimport { Value } from '@sinclair/typebox/value';\nimport {\n BlockDefinitionsSchema,\n type BlockSlot,\n type JsonBlockDefinition,\n} from './schema';\n\ntype Rec = Record<string, unknown>;\nexport interface BlockIssue {\n path: string;\n code: string;\n message: string;\n}\nexport class BlockEvaluationError extends Error {\n constructor(public readonly issues: BlockIssue[]) {\n super(issues.map((i) => `${i.path}: ${i.message}`).join('\\n'));\n this.name = 'BlockEvaluationError';\n }\n}\nexport const isBlockRecord = (v: unknown): v is Rec =>\n typeof v === 'object' && v !== null && !Array.isArray(v);\nexport const blockPointerKey = (s: string): string =>\n s.replace(/~/g, '~0').replace(/\\//g, '~1');\nconst own = (obj: object, key: string) =>\n Object.prototype.hasOwnProperty.call(obj, key);\nexport function blockValueAt(root: unknown, path: string): unknown {\n if (path === '') return root;\n if (!path.startsWith('/')) return undefined;\n let value = root;\n for (const part of path.slice(1).split('/')) {\n const key = part.replace(/~1/g, '/').replace(/~0/g, '~');\n if ((!isBlockRecord(value) && !Array.isArray(value)) || !own(value, key))\n return undefined;\n value = (value as Rec)[key];\n }\n return value;\n}\nexport function toAuthoredBlockPointer(\n map: Readonly<Record<string, string>>,\n pointer: string\n): string {\n let best: string | undefined;\n for (const path of Object.keys(map)) {\n if (\n (pointer === path || pointer.startsWith(`${path}/`)) &&\n (best === undefined || path.length > best.length)\n )\n best = path;\n }\n return best === undefined\n ? pointer\n : `${map[best]}${pointer.slice(best.length)}`;\n}\n/**\n * Props a component placed in a slot may not carry: placement and group\n * layout belong to the definition. Read by the runtime check below and by the\n * editor schema that flags them inline.\n */\nexport const BLOCK_SLOT_PLACEMENT_PROPS: readonly string[] = [\n 'x',\n 'y',\n 'w',\n 'h',\n 'position',\n 'grid',\n 'gridConfig',\n 'direction',\n 'gap',\n 'weights',\n 'alignment',\n 'spacing',\n];\n\nexport const blockWordCount = (text: string): number =>\n text.trim() === '' ? 0 : text.trim().split(/\\s+/).length;\nconst present = (value: unknown): boolean =>\n value !== undefined &&\n value !== null &&\n value !== '' &&\n value !== false &&\n (!Array.isArray(value) || value.length > 0);\nconst fail = (path: string, code: string, message: string): never => {\n throw new BlockEvaluationError([{ path, code, message }]);\n};\n\n/** Slot constraints and defaults are shared by validation and evaluation. */\nexport function resolveBlockSlot(\n slot: BlockSlot,\n input: unknown,\n path: string,\n issues: BlockIssue[]\n): unknown {\n const value =\n input === undefined && slot.default !== undefined\n ? structuredClone(slot.default)\n : input;\n if (value === undefined) {\n if (slot.required)\n issues.push({\n path,\n code: 'block_required_slot',\n message: 'Required block slot is missing.',\n });\n return undefined;\n }\n const validType =\n slot.type === 'array'\n ? Array.isArray(value)\n : slot.type === 'component'\n ? isBlockRecord(value) && typeof value.name === 'string'\n : slot.type === 'object'\n ? isBlockRecord(value)\n : slot.type === 'integer'\n ? typeof value === 'number' && Number.isInteger(value)\n : typeof value === slot.type &&\n (typeof value !== 'number' || Number.isFinite(value));\n if (!validType) {\n issues.push({\n path,\n code: 'block_slot_type',\n message: `Expected ${slot.type}.`,\n });\n return value;\n }\n const issue = (message: string) =>\n issues.push({ path, code: 'block_slot_budget', message });\n if (slot.enum && !slot.enum.includes(value as string | number | boolean))\n issue('Value is not one of the declared choices.');\n if (typeof value === 'string') {\n if (slot.oneLine && /[\\r\\n]/.test(value))\n issue('Slot must contain one line.');\n if (slot.minLength !== undefined && value.length < slot.minLength)\n issue(`Minimum length is ${slot.minLength}.`);\n if (slot.maxLength !== undefined && value.length > slot.maxLength)\n issue(`Maximum length is ${slot.maxLength}.`);\n if (slot.maxWords !== undefined && blockWordCount(value) > slot.maxWords)\n issue(`Maximum word count is ${slot.maxWords}.`);\n }\n if (typeof value === 'number') {\n if (slot.minimum !== undefined && value < slot.minimum)\n issue(`Minimum value is ${slot.minimum}.`);\n if (slot.maximum !== undefined && value > slot.maximum)\n issue(`Maximum value is ${slot.maximum}.`);\n }\n if (Array.isArray(value)) {\n if (slot.minItems !== undefined && value.length < slot.minItems)\n issue(`Minimum item count is ${slot.minItems}.`);\n if (slot.maxItems !== undefined && value.length > slot.maxItems)\n issue(`Maximum item count is ${slot.maxItems}.`);\n return slot.items\n ? value.map((v, i) =>\n resolveBlockSlot(slot.items!, v, `${path}/${i}`, issues)\n )\n : value;\n }\n if (slot.type === 'component' && isBlockRecord(value)) {\n const checkPlacement = (\n node: unknown,\n pointer: string,\n depth = 0\n ): void => {\n if (depth > 64) {\n issues.push({\n path: pointer,\n code: 'block_expansion_limit',\n message: 'Component slot exceeds 64 levels.',\n });\n return;\n }\n if (Array.isArray(node)) {\n node.forEach((item, i) =>\n checkPlacement(item, `${pointer}/${i}`, depth + 1)\n );\n return;\n }\n if (!isBlockRecord(node)) return;\n const props =\n typeof node.name === 'string' && isBlockRecord(node.props)\n ? node.props\n : {};\n for (const key of BLOCK_SLOT_PLACEMENT_PROPS) {\n if (own(props, key))\n issues.push({\n path: `${pointer}/props/${key}`,\n code: 'block_slot_placement',\n message:\n 'Block placement belongs in the definition, not in a component slot.',\n });\n }\n for (const [key, item] of Object.entries(node))\n checkPlacement(item, `${pointer}/${blockPointerKey(key)}`, depth + 1);\n };\n checkPlacement(value, path);\n }\n if (slot.type === 'object' && isBlockRecord(value) && slot.properties)\n return resolveBlockSlots(slot.properties, value, path, issues);\n return value;\n}\n\nfunction resolveBlockSlots(\n slots: Record<string, BlockSlot>,\n values: Rec,\n path: string,\n issues: BlockIssue[]\n): Rec {\n const out: Rec = {};\n for (const key of Object.keys(values)) {\n if (!own(slots, key))\n issues.push({\n path: `${path}/${blockPointerKey(key)}`,\n code: 'block_unknown_slot',\n message: `Unknown slot '${key}'. Expected: ${Object.keys(slots).join(', ')}.`,\n });\n }\n for (const [key, slot] of Object.entries(slots)) {\n const value = resolveBlockSlot(\n slot,\n own(values, key) ? values[key] : undefined,\n `${path}/${blockPointerKey(key)}`,\n issues\n );\n if (value !== undefined)\n Object.defineProperty(out, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n return out;\n}\n\nconst DIRECTIVES: Record<string, readonly string[]> = Object.fromEntries(\n Object.entries(BLOCK_DIRECTIVES).map(([key, directive]) => [\n key,\n directive.keys,\n ])\n);\nfunction slotDescriptorAt(\n slots: Record<string, BlockSlot>,\n pointer: string\n): BlockSlot | undefined {\n let descriptor: BlockSlot | undefined = { type: 'object', properties: slots };\n for (const escaped of pointer.slice(1).split('/')) {\n const key = escaped.replace(/~1/g, '/').replace(/~0/g, '~');\n if (descriptor?.type === 'object') {\n if (!descriptor.properties) return { type: 'object' }; // Deliberately open data.\n descriptor = own(descriptor.properties, key)\n ? descriptor.properties[key]\n : undefined;\n } else if (descriptor?.type === 'array' && /^(0|[1-9]\\d*)$/.test(key))\n descriptor = descriptor.items ?? { type: 'object' };\n else if (descriptor?.type === 'component') return { type: 'object' };\n else return undefined;\n }\n return descriptor;\n}\n\n/** Directives whose value is an operand rather than a plain pointer. */\nconst OPERAND_DIRECTIVES = ['$if', '$each', '$count'];\ninterface BlockOperand {\n root: BlockOperandRoot | '$theme';\n pointer: string;\n}\nconst isPointer = (value: unknown): value is string =>\n typeof value === 'string' && (value === '' || value.startsWith('/'));\n/**\n * Read a directive's operand. A plain pointer reads a slot (for `$slot`,\n * `$item`, `$theme` and `$context` it is the directive's own root); for\n * `$if`, `$each` and `$count` a one-key reference object names the root\n * instead. Anything else is malformed.\n */\nfunction blockOperand(value: unknown, key: string): BlockOperand | undefined {\n if (isPointer(value))\n return {\n root: OPERAND_DIRECTIVES.includes(key)\n ? '$slot'\n : (key as BlockOperand['root']),\n pointer: value,\n };\n if (!OPERAND_DIRECTIVES.includes(key) || !isBlockRecord(value))\n return undefined;\n const keys = Object.keys(value);\n const root = BLOCK_OPERAND_ROOTS.find((candidate) => candidate === keys[0]);\n if (keys.length !== 1 || !root || !isPointer(value[root])) return undefined;\n return { root, pointer: value[root] as string };\n}\n\nfunction checkTemplate(\n value: unknown,\n path: string,\n slots: Record<string, BlockSlot>,\n issues: BlockIssue[],\n repeated = false,\n depth = 0\n): void {\n if (depth > 64) {\n issues.push({\n path,\n code: 'block_depth',\n message: 'Definition exceeds 64 levels.',\n });\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((v, i) =>\n checkTemplate(v, `${path}/${i}`, slots, issues, repeated, depth + 1)\n );\n return;\n }\n if (!isBlockRecord(value)) return;\n const keys = Object.keys(value).filter((k) => k.startsWith('$'));\n if (keys.length) {\n const key = keys[0];\n const allowed = DIRECTIVES[key];\n if (\n !allowed ||\n keys.length !== 1 ||\n Object.keys(value).some((k) => !allowed.includes(k))\n ) {\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: 'Unknown or malformed block directive.',\n });\n return;\n }\n if (\n [\n '$slot',\n '$item',\n '$theme',\n '$context',\n '$if',\n '$each',\n '$count',\n ].includes(key)\n ) {\n // `$if`, `$each` and `$count` take an operand: a slot pointer, or a\n // reference object that reads the current `$each` item, a slot or the\n // context — so a repeat can walk the current item's own array and a\n // condition can test one of its fields.\n const operand = blockOperand(value[key], key);\n if (!operand)\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: OPERAND_DIRECTIVES.includes(key)\n ? `${key} takes a slot pointer such as /items, or one reference: ${BLOCK_OPERAND_ROOTS.map((root) => `{ \"${root}\": ... }`).join(', ')}.`\n : 'Bindings use JSON Pointers, e.g. /title.',\n });\n else if (operand.root === '$slot') {\n const descriptor = slotDescriptorAt(slots, operand.pointer);\n if (!descriptor)\n issues.push({\n path,\n code: 'block_unknown_binding',\n message: `No slot field '${operand.pointer}' is declared.`,\n });\n else if (\n ['$each', '$count'].includes(key) &&\n descriptor.type !== 'array'\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: `${key} requires an array slot.`,\n });\n }\n if (operand?.root === '$item' && !repeated)\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: '$item is only available inside $each.',\n });\n if (\n (key === '$slot' || key === '$item') &&\n own(value, 'props') &&\n !isBlockRecord(value.props)\n )\n issues.push({\n path: `${path}/props`,\n code: 'block_invalid_binding',\n message:\n 'props must be an object of component props merged beneath a component-slot value.',\n });\n }\n if (\n key === '$join' &&\n value.keepEmpty !== undefined &&\n typeof value.keepEmpty !== 'boolean'\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: 'keepEmpty must be boolean.',\n });\n if (key === '$if' && !own(value, 'then'))\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: '$if requires then.',\n });\n if (\n key === '$each' &&\n (!own(value, 'template') || Array.isArray(value.template))\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message:\n '$each requires one template value; use a group for multiple flow children.',\n });\n if (\n key === '$join' &&\n (!Array.isArray(value.$join) ||\n (value.separator !== undefined && typeof value.separator !== 'string'))\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: '$join requires an array and an optional string separator.',\n });\n if (\n key === '$measure' &&\n (!['width', 'height'].includes(String(value.$measure)) ||\n !['pt', 'twip', 'in'].includes(String(value.unit ?? 'pt')) ||\n (value.fraction !== undefined &&\n (typeof value.fraction !== 'number' ||\n value.fraction < 0 ||\n value.fraction > 1)))\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message:\n '$measure requires width/height, pt/twip/in and a fraction between 0 and 1.',\n });\n }\n for (const [key, item] of Object.entries(value)) {\n if (key.startsWith('$') && key !== '$join') continue;\n checkTemplate(\n item,\n `${path}/${blockPointerKey(key)}`,\n slots,\n issues,\n repeated || own(value, '$each'),\n depth + 1\n );\n }\n}\n\nexport function readBlockDefinitions(\n document: unknown\n): Record<string, JsonBlockDefinition> {\n const value =\n isBlockRecord(document) && isBlockRecord(document.props)\n ? document.props.blocks\n : undefined;\n return (value ?? {}) as Record<string, JsonBlockDefinition>;\n}\n\nexport function validateBlockDefinitions(\n definitions: unknown,\n format: 'docx' | 'pptx',\n reservedNames: readonly string[] = []\n): BlockIssue[] {\n if (!Value.Check(BlockDefinitionsSchema, definitions))\n return [...Value.Errors(BlockDefinitionsSchema, definitions)]\n .slice(0, 100)\n .map((e) => ({\n path: `/props/blocks${e.path}`,\n code: 'block_invalid_definition',\n message: e.message,\n }));\n const issues: BlockIssue[] = [];\n for (const [name, def] of Object.entries(definitions)) {\n const path = `/props/blocks/${blockPointerKey(name)}`;\n if (reservedNames.includes(name))\n issues.push({\n path,\n code: 'block_name_collision',\n message: `Block '${name}' conflicts with a registered component.`,\n });\n if (format !== 'docx' && def.section)\n issues.push({\n path: `${path}/section`,\n code: 'block_format',\n message: 'Section effects are DOCX-only.',\n });\n if (format !== 'pptx' && def.slide)\n issues.push({\n path: `${path}/slide`,\n code: 'block_format',\n message: 'Slide effects are PPTX-only.',\n });\n const checkSlot = (slot: BlockSlot, pointer: string): void => {\n if (slot.default !== undefined)\n resolveBlockSlot(slot, slot.default, `${pointer}/default`, issues);\n for (const [minimum, maximum] of [\n ['minItems', 'maxItems'],\n ['minLength', 'maxLength'],\n ['minimum', 'maximum'],\n ] as const) {\n if (\n slot[minimum] !== undefined &&\n slot[maximum] !== undefined &&\n slot[minimum]! > slot[maximum]!\n )\n issues.push({\n path: pointer,\n code: 'block_invalid_definition',\n message: `${minimum} exceeds ${maximum}.`,\n });\n }\n if (slot.items) checkSlot(slot.items, `${pointer}/items`);\n for (const [key, nested] of Object.entries(slot.properties ?? {}))\n checkSlot(nested, `${pointer}/properties/${blockPointerKey(key)}`);\n };\n for (const [key, slot] of Object.entries(def.slots))\n checkSlot(slot, `${path}/slots/${blockPointerKey(key)}`);\n checkTemplate(def.body, `${path}/body`, def.slots, issues);\n if (def.section)\n checkTemplate(def.section, `${path}/section`, def.slots, issues);\n if (def.slide) checkTemplate(def.slide, `${path}/slide`, def.slots, issues);\n }\n return issues;\n}\n\nexport function validateBlockInvocations(\n document: unknown,\n definitions: Record<string, JsonBlockDefinition>,\n format: 'docx' | 'pptx',\n reservedNames: readonly string[] = []\n): BlockIssue[] {\n const issues = validateBlockDefinitions(definitions, format, reservedNames);\n if (issues.length) return issues;\n const walk = (v: unknown, path: string): void => {\n if (Array.isArray(v)) {\n v.forEach((item, i) => walk(item, `${path}/${i}`));\n return;\n }\n if (!isBlockRecord(v) || v.enabled === false) return;\n if (\n v.name === 'block' &&\n isBlockRecord(v.props) &&\n typeof v.props.ref === 'string'\n ) {\n const def = own(definitions, v.props.ref)\n ? definitions[v.props.ref]\n : undefined;\n if (!def)\n issues.push({\n path: `${path}/props/ref`,\n code: 'block_unknown_reference',\n message: `Block '${v.props.ref}' is not defined in this document.`,\n });\n else {\n if (v.props.slots === undefined || isBlockRecord(v.props.slots))\n resolveBlockSlots(\n def.slots,\n (v.props.slots ?? {}) as Rec,\n `${path}/props/slots`,\n issues\n );\n if (def.section && !/^\\/children\\/\\d+\\/children\\/\\d+$/.test(path))\n issues.push({\n path,\n code: 'invalid_placement',\n message:\n 'A block with section effects must be a direct child of a top-level section.',\n });\n if (def.slide && !/^\\/children\\/\\d+\\/children\\/\\d+$/.test(path))\n issues.push({\n path,\n code: 'invalid_placement',\n message:\n 'A block with slide effects must be a direct child of a slide.',\n });\n }\n }\n for (const [key, item] of Object.entries(v)) {\n if (path === '/props' && key === 'blocks') continue;\n walk(item, `${path}/${blockPointerKey(key)}`);\n }\n };\n walk(document, '');\n return issues;\n}\n\nexport interface BlockEnvironment {\n slots: Rec;\n slotSources?: Record<string, string>;\n source: string;\n definition: string;\n context: Rec;\n contextSources?: Record<string, string>;\n item?: unknown;\n itemSource?: string;\n}\nexport interface BlockSectionEffect {\n settings: NonNullable<JsonBlockDefinition['section']>;\n environment: BlockEnvironment;\n path: string;\n}\nexport interface BlockSlideEffect {\n settings: NonNullable<JsonBlockDefinition['slide']>;\n environment: BlockEnvironment;\n path: string;\n}\nexport interface BlockEvaluatorOptions {\n format: 'docx' | 'pptx';\n theme?: unknown;\n context?: Rec;\n contextSources?: Record<string, string>;\n reservedNames?: readonly string[];\n contextAt?: (path: string) => Rec;\n measure?: (\n axis: 'width' | 'height',\n unit: 'pt' | 'twip' | 'in',\n context: Rec\n ) => number;\n onSection?: (effect: BlockSectionEffect) => void;\n onSlide?: (effect: BlockSlideEffect) => void;\n}\n\n/** Pure bounded JSON composition. Plugins are expanded by the host, never evaluated here. */\nexport class JsonBlockEvaluator {\n readonly sourceMap: Record<string, string> = {};\n readonly blocks: string[] = [];\n private nodes = 0;\n constructor(\n readonly definitions: Record<string, JsonBlockDefinition>,\n readonly options: BlockEvaluatorOptions\n ) {\n const issues = validateBlockDefinitions(\n definitions,\n options.format,\n options.reservedNames\n );\n if (issues.length) throw new BlockEvaluationError(issues);\n }\n private guard(path: string, depth: number): void {\n if (depth > 64 || ++this.nodes > 50000)\n fail(\n path,\n 'block_expansion_limit',\n 'Block expansion exceeds the depth/node limit (64/50000).'\n );\n }\n /**\n * A directive operand and the authored pointer it came from: the slot the\n * pointer form names, or the current item, slot or context a reference\n * object names. Definitions are validated before this runs, so a malformed\n * operand cannot reach it.\n */\n private operand(\n raw: unknown,\n key: string,\n env: BlockEnvironment\n ): { value: unknown; source: string; element: (index: number) => string } {\n const { root, pointer } = blockOperand(raw, key)!;\n const { value, source } = this.reference(root, pointer, env);\n return {\n value,\n source,\n // Element i of the array is authored at pointer/i, looked up the same\n // way: a slot the enclosing invocation built from its own repeat maps\n // element by element, and pointer + \"/i\" is not the same as that.\n element: (index) =>\n this.reference(root, `${pointer}/${index}`, env).source,\n };\n }\n /**\n * What a reference reads and where the author wrote it. One resolution for\n * the binding form and the operand form, so `{ \"$context\": ... }` is\n * attributed the same way whichever directive carries it.\n */\n private reference(\n root: BlockOperandRoot | '$theme',\n pointer: string,\n env: BlockEnvironment\n ): { value: unknown; source: string } {\n if (root === '$item')\n return {\n value: blockValueAt(env.item, pointer),\n source: `${env.itemSource ?? env.source}${pointer}`,\n };\n if (root === '$context') {\n const authored = toAuthoredBlockPointer(\n env.contextSources ?? {},\n pointer\n );\n return {\n value: blockValueAt(env.context, pointer),\n source: authored === pointer ? env.source : authored,\n };\n }\n if (root === '$theme')\n return {\n value: blockValueAt(this.options.theme, pointer),\n source: env.source,\n };\n return {\n value: blockValueAt(env.slots, pointer),\n source: env.slotSources\n ? toAuthoredBlockPointer(env.slotSources, pointer)\n : `${env.source}/props/slots${pointer}`,\n };\n }\n evaluate(\n value: unknown,\n env: BlockEnvironment,\n out: string,\n definitionPath: string,\n depth = 0\n ): unknown {\n this.guard(env.source, depth);\n this.sourceMap[out] = env.source;\n if (Array.isArray(value)) {\n const result: unknown[] = [];\n value.forEach((v, i) => {\n const evaluated = this.evaluate(\n v,\n env,\n `${out}/${result.length}`,\n `${definitionPath}/${i}`,\n depth + 1\n );\n if (evaluated !== undefined) {\n if (\n isBlockRecord(v) &&\n ('$if' in v || '$each' in v) &&\n Array.isArray(evaluated)\n ) {\n // Directives splice sequences; ordinary arrays remain ordinary arrays.\n const base = `${out}/${result.length}`;\n const maps = Object.entries(this.sourceMap).filter(([key]) =>\n key.startsWith(`${base}/`)\n );\n for (const [key] of maps) delete this.sourceMap[key];\n for (const [key, source] of maps) {\n const rest = key.slice(base.length + 1);\n const [index, ...suffix] = rest.split('/');\n this.sourceMap[\n `${out}/${result.length + Number(index)}${suffix.length ? '/' + suffix.join('/') : ''}`\n ] = source;\n }\n result.push(...evaluated);\n } else result.push(evaluated);\n }\n });\n return result;\n }\n if (!isBlockRecord(value)) return value;\n if (\n '$slot' in value ||\n '$item' in value ||\n '$theme' in value ||\n '$context' in value\n ) {\n const key = ['$slot', '$item', '$theme', '$context'].find(\n (k) => k in value\n )!;\n const pointer = value[key] as string;\n const { value: found, source } = this.reference(\n key as BlockOperandRoot | '$theme',\n pointer,\n env\n );\n this.sourceMap[out] = source;\n let result: unknown =\n found !== undefined ? structuredClone(found) : undefined;\n if (result === undefined && own(value, 'default'))\n result = this.evaluate(\n value.default,\n env,\n out,\n `${definitionPath}/default`,\n depth + 1\n );\n if (result === undefined && key === '$theme')\n return fail(\n definitionPath,\n 'block_unknown_theme_binding',\n `Theme value '${pointer}' is missing; declare a fallback or use an existing token.`\n );\n // A component slot takes its placement and styling defaults from the\n // definition: `props` are merged beneath the slot value's own props.\n // The slot content cannot carry placement (rejected at validation), so\n // geometry always comes from the definition; other props stay the\n // author's to override.\n if (\n (key === '$slot' || key === '$item') &&\n own(value, 'props') &&\n isBlockRecord(result) &&\n typeof result.name === 'string'\n ) {\n const origin = this.sourceMap[out];\n const defaults = this.evaluate(\n value.props,\n env,\n `${out}/props`,\n `${definitionPath}/props`,\n depth + 1\n );\n const authored = isBlockRecord(result.props) ? result.props : {};\n for (const propKey of Object.keys(authored)) {\n const pointerKey = `${out}/props/${blockPointerKey(propKey)}`;\n for (const mapped of Object.keys(this.sourceMap))\n if (mapped === pointerKey || mapped.startsWith(`${pointerKey}/`))\n delete this.sourceMap[mapped];\n this.sourceMap[pointerKey] =\n `${origin}/props/${blockPointerKey(propKey)}`;\n }\n result = {\n ...result,\n props: {\n ...(isBlockRecord(defaults) ? defaults : {}),\n ...authored,\n },\n };\n }\n return result;\n }\n if ('$if' in value) {\n const operand = this.operand(value.$if, '$if', env);\n const branch = present(operand.value) ? value.then : value.else;\n const result = this.evaluate(branch, env, out, definitionPath, depth + 1);\n // A literal branch is the tested value's consequence: a finding on it\n // lands on the field that selected it. A binding keeps its own origin.\n const literal =\n !isBlockRecord(branch) ||\n !Object.keys(branch).some((k) => k.startsWith('$'));\n if (literal && this.sourceMap[out] === env.source)\n this.sourceMap[out] = operand.source;\n return result;\n }\n if ('$count' in value) {\n const operand = this.operand(value.$count, '$count', env);\n if (!Array.isArray(operand.value))\n return fail(\n operand.source,\n 'block_slot_type',\n '$count requires an array.'\n );\n return operand.value.length;\n }\n if ('$each' in value) {\n const operand = this.operand(value.$each, '$each', env);\n const list = operand.value;\n if (!Array.isArray(list))\n return fail(\n operand.source,\n 'block_slot_type',\n '$each requires an array.'\n );\n const result: unknown[] = [];\n list.forEach((item, i) => {\n const pointer = `${out}/${result.length}`;\n const evaluated = this.evaluate(\n value.template,\n {\n ...env,\n item,\n itemSource: operand.element(i),\n },\n pointer,\n `${definitionPath}/template`,\n depth + 1\n );\n if (evaluated !== undefined) {\n // The repeated element belongs to the item that produced it: a\n // finding on a whole column lands on that column, not on the block.\n if (this.sourceMap[pointer] === env.source)\n this.sourceMap[pointer] = operand.element(i);\n result.push(evaluated);\n } else\n for (const key of Object.keys(this.sourceMap)) {\n if (key === pointer || key.startsWith(`${pointer}/`))\n delete this.sourceMap[key];\n }\n });\n return result;\n }\n if ('$join' in value) {\n const values = (value.$join as unknown[]).map((v, i) =>\n this.evaluate(\n v,\n env,\n `${out}/${i}`,\n `${definitionPath}/$join/${i}`,\n depth + 1\n )\n );\n const first = values.findIndex(present);\n if (first >= 0) this.sourceMap[out] = this.sourceMap[`${out}/${first}`];\n return (value.keepEmpty === true ? values : values.filter(present))\n .map((v) => String(v ?? ''))\n .join(String(value.separator ?? ''));\n }\n if ('$measure' in value) {\n if (!this.options.measure)\n return fail(\n definitionPath,\n 'block_unsupported_operation',\n 'This format does not support $measure.'\n );\n return (\n this.options.measure(\n value.$measure as 'width' | 'height',\n (value.unit ?? 'pt') as 'pt' | 'twip' | 'in',\n env.context\n ) * Number(value.fraction ?? 1)\n );\n }\n const result: Rec = {};\n for (const [key, item] of Object.entries(value)) {\n const evaluated = this.evaluate(\n item,\n env,\n `${out}/${blockPointerKey(key)}`,\n `${definitionPath}/${blockPointerKey(key)}`,\n depth + 1\n );\n if (evaluated !== undefined)\n Object.defineProperty(result, key, {\n value: evaluated,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n return result;\n }\n expand(value: unknown, path = '', depth = 0): unknown {\n this.guard(path, depth);\n if (Array.isArray(value))\n return value.map((v, i) => this.expand(v, `${path}/${i}`, depth + 1));\n if (!isBlockRecord(value)) return value;\n if (value.name === 'block' && value.enabled !== false) {\n if (!isBlockRecord(value.props) || typeof value.props.ref !== 'string')\n return fail(\n path,\n 'block_invalid_invocation',\n 'A block requires props.ref and optional props.slots.'\n );\n if (\n Object.keys(value.props).some(\n (key) => !['ref', 'slots'].includes(key)\n ) ||\n (value.props.slots !== undefined && !isBlockRecord(value.props.slots))\n )\n return fail(\n path,\n 'block_invalid_invocation',\n 'Block props accept only ref and an object of slots.'\n );\n const def = own(this.definitions, value.props.ref)\n ? this.definitions[value.props.ref]\n : undefined;\n if (!def)\n return fail(\n `${path}/props/ref`,\n 'block_unknown_reference',\n `Block '${value.props.ref}' is not defined in this document.`\n );\n const issues: BlockIssue[] = [];\n const source = toAuthoredBlockPointer(this.sourceMap, path);\n const slotsPath = `${path}/props/slots`;\n const slots = resolveBlockSlots(\n def.slots,\n (value.props.slots ?? {}) as Rec,\n slotsPath,\n issues\n );\n if (issues.length)\n throw new BlockEvaluationError(\n issues.map((issue) => ({\n ...issue,\n path: toAuthoredBlockPointer(this.sourceMap, issue.path),\n }))\n );\n const slotSources = Object.fromEntries([\n ['', toAuthoredBlockPointer(this.sourceMap, slotsPath)],\n ...Object.entries(this.sourceMap)\n .filter(([key]) => key.startsWith(`${slotsPath}/`))\n .map(([key, origin]) => [key.slice(slotsPath.length), origin]),\n ]);\n const env: BlockEnvironment = {\n slots,\n slotSources,\n source,\n definition: `/props/blocks/${blockPointerKey(value.props.ref)}`,\n context: this.options.contextAt?.(path) ?? this.options.context ?? {},\n contextSources: this.options.contextSources,\n };\n if (def.section)\n this.options.onSection?.({\n settings: def.section,\n environment: env,\n path,\n });\n if (def.slide)\n this.options.onSlide?.({ settings: def.slide, environment: env, path });\n this.blocks.push(source);\n const children = this.evaluate(\n def.body,\n env,\n `${path}/children`,\n `${env.definition}/body`,\n depth + 1\n );\n return {\n name: 'group',\n ...(value.id !== undefined && { id: value.id }),\n children: this.expand(children, `${path}/children`, depth + 1),\n };\n }\n if (value.enabled === false) return { ...value };\n const result: Rec = { ...value };\n // Traverse the document, never its definition library or unexpanded slot data.\n for (const [key, item] of Object.entries(value)) {\n if (path === '/props' && key === 'blocks') continue;\n Object.defineProperty(result, key, {\n value: this.expand(item, `${path}/${blockPointerKey(key)}`, depth + 1),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n return result;\n }\n}\n","import { Value } from '@sinclair/typebox/value';\nimport {\n BlockDefinitionsSchema,\n blockSlotJsonSchema,\n type BlockSlot,\n type BlockSlotRole,\n type JsonBlockDefinition,\n} from './schema';\nimport {\n blockPointerKey,\n blockValueAt,\n blockWordCount,\n isBlockRecord,\n readBlockDefinitions,\n} from './evaluator';\n\nexport function blockSlotsJsonSchema(\n definition: JsonBlockDefinition\n): Record<string, unknown> {\n return {\n type: 'object',\n additionalProperties: false,\n properties: Object.fromEntries(\n Object.entries(definition.slots).map(([key, slot]) => [\n key,\n blockSlotJsonSchema(slot),\n ])\n ),\n required: Object.entries(definition.slots)\n .filter(([, slot]) => slot.required && slot.default === undefined)\n .map(([key]) => key),\n };\n}\n\n/** Authored definitions and fill pointers for exactly this document revision. */\nexport function documentBlockMetadata(document: unknown) {\n const definitions = readBlockDefinitions(document);\n if (!Value.Check(BlockDefinitionsSchema, definitions))\n return { definitions: [], invocations: [], invalidDefinitions: true };\n const invocations: {\n ref: string;\n path: string;\n slotsPath: string;\n defined: boolean;\n }[] = [];\n const walk = (value: unknown, path: string): void => {\n if (Array.isArray(value)) {\n value.forEach((item, i) => walk(item, `${path}/${i}`));\n return;\n }\n if (!isBlockRecord(value)) return;\n if (\n value.name === 'block' &&\n isBlockRecord(value.props) &&\n typeof value.props.ref === 'string'\n )\n invocations.push({\n ref: value.props.ref,\n path,\n slotsPath: `${path}/props/slots`,\n defined: Object.prototype.hasOwnProperty.call(\n definitions,\n value.props.ref\n ),\n });\n for (const [key, item] of Object.entries(value)) {\n if (path === '/props' && key === 'blocks') continue;\n walk(item, `${path}/${blockPointerKey(key)}`);\n }\n };\n walk(document, '');\n return {\n definitions: Object.entries(definitions).map(([name, definition]) => ({\n name,\n definitionPointer: `/props/blocks/${blockPointerKey(name)}`,\n definition,\n slotsSchema: blockSlotsJsonSchema(definition),\n })),\n invocations,\n invalidDefinitions: false,\n };\n}\n\n/** Compiled pointer → authored pointer. */\nexport type BlockSourceMap = Readonly<Record<string, string>>;\n/** A document with every block lowered in place, and how to get back. */\nexport interface ExpandedBlocks<T> {\n document: T;\n sourceMap: BlockSourceMap;\n /** Authored pointers of every expanded invocation, in document order. */\n blocks: readonly string[];\n}\n\nexport interface BlockSlotBudget {\n block: string;\n slot: string;\n path: string;\n words: number;\n maxWords: number;\n}\n\nexport interface BlockSlotRoleValue {\n block: string;\n /** Authored pointer of the invocation. */\n invocation: string;\n slot: string;\n role: BlockSlotRole;\n /** Authored pointer of the slot value, whether or not one was supplied. */\n path: string;\n /** The resolved value after defaults; undefined when absent. */\n value: unknown;\n}\n\n/** Visit every declared slot of an invocation with its resolved value. */\nfunction visitInvocationSlots(\n document: unknown,\n blocks: readonly string[],\n visit: (\n ref: string,\n slot: BlockSlot,\n value: unknown,\n pointer: string,\n name: string\n ) => void\n): void {\n const definitions = readBlockDefinitions(document);\n for (const path of blocks) {\n const node = blockValueAt(document, path);\n if (\n !isBlockRecord(node) ||\n !isBlockRecord(node.props) ||\n typeof node.props.ref !== 'string'\n )\n continue;\n const ref = node.props.ref;\n const definition = definitions[ref];\n if (!definition) continue;\n const walk = (\n slot: BlockSlot,\n value: unknown,\n pointer: string,\n name: string\n ): void => {\n visit(ref, slot, value, pointer, name);\n if (isBlockRecord(value) && slot.properties) {\n for (const [key, property] of Object.entries(slot.properties)) {\n walk(\n property,\n blockValueAt(value, `/${blockPointerKey(key)}`),\n `${pointer}/${blockPointerKey(key)}`,\n `${name}.${key}`\n );\n }\n }\n if (Array.isArray(value) && slot.items)\n value.forEach((item, i) =>\n walk(slot.items!, item, `${pointer}/${i}`, name)\n );\n };\n for (const [name, slot] of Object.entries(definition.slots)) {\n const authored = blockValueAt(\n node.props.slots,\n `/${blockPointerKey(name)}`\n );\n walk(\n slot,\n authored === undefined && slot.default !== undefined\n ? slot.default\n : authored,\n `${path}/props/slots/${blockPointerKey(name)}`,\n name\n );\n }\n }\n}\n\n/** Metadata is always read from authored definitions, never from a named catalog. */\nexport function blockSlotBudgets(\n document: unknown,\n blocks: readonly string[]\n): BlockSlotBudget[] {\n const result: BlockSlotBudget[] = [];\n visitInvocationSlots(document, blocks, (ref, slot, value, pointer, name) => {\n if (typeof value === 'string' && slot.maxWords !== undefined)\n result.push({\n block: ref,\n slot: name,\n path: pointer,\n words: blockWordCount(value),\n maxWords: slot.maxWords,\n });\n });\n return result;\n}\n\n/**\n * Every role-bearing slot of every invocation, present or not, so a profile\n * can require one (a source under a chart) and measure another (an action\n * title's length) at the authored pointer the author can patch.\n */\nexport function blockSlotRoles(\n document: unknown,\n blocks: readonly string[]\n): BlockSlotRoleValue[] {\n const result: BlockSlotRoleValue[] = [];\n visitInvocationSlots(document, blocks, (ref, slot, value, pointer, name) => {\n if (!slot.role) return;\n result.push({\n block: ref,\n invocation: pointer.replace(/\\/props\\/slots\\/.*$/, ''),\n slot: name,\n role: slot.role,\n path: pointer,\n value,\n });\n });\n return result;\n}\n","/** JSON Schema type reasoning for authoring; never used as runtime validation. */\nexport type AuthoringSchema = boolean | Record<string, any>;\nexport type ValueType =\n | 'null'\n | 'boolean'\n | 'number'\n | 'string'\n | 'array'\n | 'object';\nconst allTypes: ValueType[] = [\n 'null',\n 'boolean',\n 'number',\n 'string',\n 'array',\n 'object',\n];\ntype Resolve = (ref: string) => AuthoringSchema | undefined;\nconst intersection = (a: Set<ValueType>, b: Set<ValueType>) =>\n new Set([...a].filter((value) => b.has(value)));\nconst union = (sets: Set<ValueType>[]) =>\n new Set(sets.flatMap((set) => [...set]));\nconst typeOf = (value: unknown): ValueType =>\n value === null\n ? 'null'\n : Array.isArray(value)\n ? 'array'\n : (typeof value as ValueType);\n\n/** Conservative possible types: intersect constraints, combine union branches,\n * and resolve references with a cycle guard. Unknown schemas allow every type.\n * Integer is part of the numeric family; bounds and integrality still validate\n * on evaluated output, just as they do for a reference's unknown value.\n */\nexport function possibleValueTypes(\n schema: AuthoringSchema,\n resolve: Resolve,\n seen = new Set<AuthoringSchema>()\n): Set<ValueType> {\n if (schema === false) return new Set();\n if (schema === true || seen.has(schema)) return new Set(allTypes);\n // Type.Never and plain negated type schemas exclude complete result families.\n // More specific negations (bounds/patterns/enum values) cannot safely exclude\n // an entire family and are left to ordinary literal/output validation.\n const negated = schema.not;\n if (\n negated === true ||\n (negated &&\n typeof negated === 'object' &&\n Object.keys(negated).length === 0)\n )\n return new Set();\n const next = new Set(seen).add(schema);\n let types = new Set(allTypes);\n if (schema.type) {\n const declared = Array.isArray(schema.type) ? schema.type : [schema.type];\n types = intersection(\n types,\n new Set(\n allTypes.filter(\n (type) =>\n declared.includes(type) ||\n (type === 'number' && declared.includes('integer'))\n )\n )\n );\n }\n if (Object.hasOwn(schema, 'const'))\n types = intersection(types, new Set([typeOf(schema.const)]));\n if (Array.isArray(schema.enum))\n types = intersection(types, new Set(schema.enum.map(typeOf)));\n if (typeof schema.$ref === 'string') {\n const target = resolve(schema.$ref);\n if (target !== undefined)\n types = intersection(types, possibleValueTypes(target, resolve, next));\n }\n for (const key of ['anyOf', 'oneOf']) {\n if (Array.isArray(schema[key]))\n types = intersection(\n types,\n union(\n schema[key].map((branch: AuthoringSchema) =>\n possibleValueTypes(branch, resolve, next)\n )\n )\n );\n }\n if (Array.isArray(schema.allOf))\n for (const branch of schema.allOf)\n types = intersection(types, possibleValueTypes(branch, resolve, next));\n if (\n negated &&\n typeof negated === 'object' &&\n negated.type &&\n Object.keys(negated).every((key) =>\n ['type', 'description', 'title', '$comment'].includes(key)\n )\n ) {\n // Excluding integers alone does not exclude all numbers.\n const excluded = (\n Array.isArray(negated.type) ? negated.type : [negated.type]\n ).filter((type: string) => type !== 'integer');\n types = new Set([...types].filter((type) => !excluded.includes(type)));\n }\n return types;\n}\n\n/** Item constraints for an array-valued expression. For tuples, each iteration\n * may produce any tuple item type; final length/position validation stays with\n * the evaluated array. Unions keep alternatives and intersections keep all\n * applicable item constraints. References may be recursive.\n */\nexport function arrayItemSchema(\n schema: AuthoringSchema,\n resolve: Resolve,\n seen = new Set<AuthoringSchema>()\n): AuthoringSchema {\n if (schema === false) return false;\n if (schema === true || seen.has(schema)) return {};\n const next = new Set(seen).add(schema);\n const constraints: AuthoringSchema[] = [];\n if (typeof schema.$ref === 'string') {\n const target = resolve(schema.$ref);\n if (target !== undefined)\n constraints.push(arrayItemSchema(target, resolve, next));\n }\n if (schema.items !== undefined)\n constraints.push(\n Array.isArray(schema.items)\n ? {\n anyOf: [\n ...schema.items,\n ...(schema.additionalItems === false\n ? []\n : [schema.additionalItems ?? {}]),\n ],\n }\n : schema.items\n );\n for (const key of ['anyOf', 'oneOf'])\n if (Array.isArray(schema[key])) {\n constraints.push({\n anyOf: schema[key]\n .filter((branch: AuthoringSchema) =>\n possibleValueTypes(branch, resolve).has('array')\n )\n .map((branch: AuthoringSchema) =>\n arrayItemSchema(branch, resolve, next)\n ),\n });\n }\n if (Array.isArray(schema.allOf))\n constraints.push(\n ...schema.allOf.map((branch: AuthoringSchema) =>\n arrayItemSchema(branch, resolve, next)\n )\n );\n return constraints.length === 0\n ? {}\n : constraints.length === 1\n ? constraints[0]\n : { allOf: constraints };\n}\n","import type { OfficeFormat } from '../rendering/types';\nimport {\n BLOCK_DIRECTIVES,\n BLOCK_OPERAND_ROOTS,\n type BlockDirective,\n} from './directives';\nimport {\n arrayItemSchema,\n possibleValueTypes,\n type AuthoringSchema,\n} from './schema-types';\n\ntype Schema = Record<string, any>;\nconst object = (properties: Schema, required: string[]): Schema => ({\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n});\nconst pointer = (description: string): Schema => ({\n type: 'string',\n pattern: '^(|/.*)$',\n description,\n});\nconst referenceDescriptions = (format: OfficeFormat) => ({\n $slot:\n 'Read a named input slot by JSON Pointer, e.g. /title or /client/name.',\n $item:\n 'Read the current $each entry by JSON Pointer. Use an empty string for the whole entry or /title for a property.',\n $theme:\n 'Read the active theme by JSON Pointer, e.g. /colors/primary. A missing value requires a default.',\n $context:\n format === 'pptx'\n ? 'Read deck or slide context by JSON Pointer, e.g. /document/title, /slide/width or /slide/index.'\n : 'Read document or section context by JSON Pointer, e.g. /document/title or /section/tracker.',\n});\nconst measureDescriptions = (format: OfficeFormat) =>\n format === 'pptx'\n ? {\n axis: 'Measure the slide canvas width or height, in the unit given.',\n unit: 'Measurement unit: points, twentieths of a point, or inches. Defaults to pt; use in for frame coordinates.',\n }\n : {\n axis: 'Measure the usable page width or height after margins, using the containing section’s page settings.',\n unit: 'Measurement unit: points, twentieths of a point, or inches. Defaults to pt.',\n };\nconst describe = (schema: AuthoringSchema, description: string): Schema => ({\n ...(typeof schema === 'boolean' ? { allOf: [schema] } : schema),\n description,\n});\nconst metadata = (schema: AuthoringSchema): Schema =>\n typeof schema === 'boolean'\n ? {}\n : {\n ...(schema.description && { description: schema.description }),\n ...(schema.markdownDescription && {\n markdownDescription: schema.markdownDescription,\n }),\n };\nconst hasKey = (key: string): Schema => ({ type: 'object', required: [key] });\nconst directiveNames = Object.keys(BLOCK_DIRECTIVES) as BlockDirective[];\n\n/**\n * Derive authoring from the renderer/plugin schemas without weakening ordinary\n * documents. Each value retains its literal schema and receives only directives\n * whose result family can fit. Defaults and conditional branches recurse into\n * that same value schema; repetition templates use the actual array item schema.\n *\n * Dispatch uses standard draft-07 conditionals, not overlapping anyOf branches:\n * existing literal keys keep literal completion, and a directive selects only\n * its own options. Empty/incomplete objects offer literal keys and directive\n * starters. Memoized references keep recursive schemas finite and avoid copying\n * the component graph into every default/then/else branch.\n */\nexport function createBlockAuthoringSchema(\n definitions: Record<string, Schema>,\n componentDefinition: string,\n excludedComponents: readonly string[] = [],\n format: OfficeFormat = 'docx'\n): Schema {\n const prefix = `BlockTemplate_${componentDefinition}`;\n const references = referenceDescriptions(format);\n const measure = measureDescriptions(format);\n // `$if`, `$each` and `$count` take an operand: a slot pointer, or one\n // reference that reads the current `$each` entry, a slot or the context.\n const operand = (description: string): Schema => ({\n description,\n anyOf: [\n pointer(description),\n ...BLOCK_OPERAND_ROOTS.map((root) =>\n object({ [root]: pointer(references[root]) }, [root])\n ),\n ],\n });\n const bodyName = `${prefix}_Body`;\n const ref = (name: string): Schema => ({ $ref: `#/definitions/${name}` });\n if (definitions[bodyName]) return ref(bodyName);\n\n // Only resolve canonical input definitions. Generated schemas must never be\n // transformed again. Narrow the component root without changing the original.\n const originals: Record<string, Schema> = { ...definitions };\n const source = originals[componentDefinition];\n originals[componentDefinition] = {\n ...source,\n anyOf: (source.anyOf ?? [source]).filter(\n (branch: Schema) =>\n !excludedComponents.includes(branch.properties?.name?.const)\n ),\n };\n const resolve = (pointer: string): AuthoringSchema | undefined => {\n if (!pointer.startsWith('#/definitions/')) return undefined;\n let node: any = originals;\n for (const key of pointer.slice('#/definitions/'.length).split('/')) {\n const decoded = key.replace(/~1/g, '/').replace(/~0/g, '~');\n if (!node || typeof node !== 'object' || !Object.hasOwn(node, decoded))\n return undefined;\n node = node[decoded];\n }\n return typeof node === 'boolean' || (node && typeof node === 'object')\n ? node\n : undefined;\n };\n\n const values = new Map<string, string>();\n const literals = new Map<string, string>();\n let nextId = 0;\n const componentRef = ref(componentDefinition);\n const shared = new Map<string, string>();\n const share = (schema: Schema): Schema => {\n const key = JSON.stringify(schema);\n let name = shared.get(key);\n if (!name) {\n name = `${prefix}_Shared${nextId++}`;\n shared.set(key, name);\n definitions[name] = schema;\n }\n return ref(name);\n };\n const presence = Object.fromEntries(\n directiveNames.map((key) => [key, share(hasKey(key))])\n );\n const anyDirective = share({ anyOf: Object.values(presence) });\n const starterPrefixes = [\n ...new Set([\n '',\n ...directiveNames.flatMap((key) =>\n Array.from({ length: key.length - 1 }, (_, index) =>\n key.slice(0, index + 1)\n )\n ),\n ]),\n ];\n const starterObject = share({\n type: 'object',\n // An enum here would itself become a list of bogus property suggestions.\n propertyNames: {\n pattern: `^(?:${starterPrefixes.map((key) => key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|')})$`,\n },\n });\n\n function literal(schema: AuthoringSchema): AuthoringSchema {\n if (typeof schema === 'boolean') return schema;\n const key = JSON.stringify(schema);\n const cached = literals.get(key);\n if (cached) return { ...ref(cached), ...metadata(schema) };\n const name = `${prefix}_Literal${nextId++}`;\n literals.set(key, name);\n definitions[name] = {};\n const result: Schema = { ...schema };\n if (typeof schema.$ref === 'string') {\n const target = resolve(schema.$ref);\n if (target !== undefined) {\n const transformed = literal(target);\n if (typeof transformed === 'object') result.$ref = transformed.$ref;\n else {\n delete result.$ref;\n if (!transformed) result.not = {};\n }\n }\n }\n if (schema.properties)\n result.properties = Object.fromEntries(\n Object.entries(\n schema.properties as Record<string, AuthoringSchema>\n ).map(([key, value]) => [\n key,\n // Literal discriminators retain canonical component/version dispatch\n // and their individual choice descriptions.\n ['name', 'version'].includes(key) &&\n typeof value === 'object' &&\n typeof value.const === 'string'\n ? value\n : author(value),\n ])\n );\n if (schema.patternProperties)\n result.patternProperties = Object.fromEntries(\n Object.entries(\n schema.patternProperties as Record<string, AuthoringSchema>\n ).map(([key, value]) => [key, author(value)])\n );\n if (schema.items !== undefined)\n result.items = Array.isArray(schema.items)\n ? schema.items.map((item: AuthoringSchema) => author(item, true))\n : author(schema.items, true);\n for (const key of ['additionalProperties', 'additionalItems'])\n if (typeof schema[key] === 'object')\n result[key] = author(schema[key], key === 'additionalItems');\n for (const key of ['anyOf', 'oneOf', 'allOf'])\n if (Array.isArray(schema[key]))\n // Keep branches inline so canonical name-union restructuring still sees\n // their discriminators. Their nested value schemas are shared references.\n result[key] = schema[key].map((branch: AuthoringSchema) => {\n const transformed = literal(branch);\n return typeof branch === 'object' &&\n typeof branch.properties?.name?.const === 'string' &&\n typeof transformed === 'object' &&\n transformed.$ref\n ? definitions[transformed.$ref.slice('#/definitions/'.length)]\n : transformed;\n });\n // Conditions/negations inspect literal values, not binding syntax.\n for (const key of ['then', 'else'])\n if (schema[key] !== undefined) result[key] = literal(schema[key]);\n definitions[name] = result;\n return { ...ref(name), ...metadata(schema) };\n }\n\n function author(input: AuthoringSchema, sequence = false): AuthoringSchema {\n if (input === false) return false;\n // Property help stays on the reference at the use site. It must not cause\n // duplicate binding graphs for otherwise identical value constraints.\n const annotations = metadata(input);\n const schema = typeof input === 'object' ? { ...input } : input;\n if (typeof schema === 'object') {\n delete schema.description;\n delete schema.markdownDescription;\n }\n const key = `${sequence ? 'sequence' : 'value'}:${JSON.stringify(schema)}`;\n const cached = values.get(key);\n if (cached) return { ...ref(cached), ...annotations };\n const name = `${prefix}_Value${nextId++}`;\n values.set(key, name);\n definitions[name] = {};\n const self = ref(name);\n const types = possibleValueTypes(schema, resolve);\n if (types.size === 0) {\n definitions[name] = { allOf: [literal(schema)] };\n return self;\n }\n const value = () => (sequence ? author(schema) : self);\n const branch = () =>\n sequence ? { anyOf: [self, { type: 'array', items: self }] } : self;\n const item = () =>\n sequence ? value() : author(arrayItemSchema(schema, resolve));\n const specs: Partial<Record<BlockDirective, Schema>> = {};\n for (const directive of directiveNames) {\n const result = BLOCK_DIRECTIVES[directive].result;\n if (\n result !== 'dynamic' &&\n !types.has(result) &&\n !(sequence && result === 'array')\n )\n continue;\n switch (directive) {\n case '$slot':\n case '$item':\n case '$theme':\n case '$context':\n specs[directive] = object(\n {\n [directive]: pointer(references[directive]),\n default: describe(\n value(),\n 'Fallback value or binding used only when the referenced value is missing. Null, false and empty values do not trigger it.'\n ),\n ...(directive === '$slot' || directive === '$item'\n ? {\n props: {\n type: 'object',\n description:\n 'Component props merged beneath a component-slot value. Put placement (x, y, w, h, grid) and styling defaults here; the slot content may override styling but never placement.',\n },\n }\n : {}),\n },\n [directive]\n );\n break;\n case '$if':\n specs[directive] = object(\n {\n $if: operand(\n 'Test a slot by JSON Pointer, e.g. /subtitle, or a reference such as { \"$item\": \"/numeric\" }. Missing, null, false, empty text and empty arrays select else; zero selects then.'\n ),\n then: describe(\n branch(),\n 'Value or components to emit when the slot tested by $if is present.'\n ),\n else: describe(\n branch(),\n 'Value or components to emit otherwise. Omit to produce no output.'\n ),\n },\n ['$if', 'then']\n );\n break;\n case '$each':\n specs[directive] = object(\n {\n $each: operand(\n 'Repeat template for each entry in an array slot, e.g. /items, or in an array of the current entry, { \"$item\": \"/cells\" }. Read the current entry with $item.'\n ),\n template: describe(\n item(),\n 'One template evaluated per array entry. Use $item for the current entry and a group for multiple components.'\n ),\n },\n ['$each', 'template']\n );\n break;\n case '$count':\n specs[directive] = object(\n {\n $count: operand(\n 'Return the number of entries in an array slot, e.g. /items, or in an array of the current entry, { \"$item\": \"/cells\" }.'\n ),\n },\n ['$count']\n );\n break;\n case '$join':\n specs[directive] = object(\n {\n $join: {\n type: 'array',\n items: author({}),\n description:\n 'Evaluate these values or bindings and join them as text. Empty values are skipped unless keepEmpty is true.',\n },\n separator: {\n type: 'string',\n description:\n 'Text inserted between joined values. Defaults to an empty string.',\n },\n keepEmpty: {\n type: 'boolean',\n description:\n 'Keep missing, null, false, empty text and empty arrays in the join. Defaults to false.',\n },\n },\n ['$join']\n );\n break;\n case '$measure':\n specs[directive] = object(\n {\n $measure: {\n enum: ['width', 'height'],\n description: measure.axis,\n },\n fraction: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description:\n 'Fraction of the measured dimension, from 0 to 1. Defaults to 1.',\n },\n unit: {\n enum: ['pt', 'twip', 'in'],\n description: measure.unit,\n },\n },\n ['$measure']\n );\n break;\n default: {\n const exhaustive: never = directive;\n throw new Error(\n `Missing authoring schema for directive ${exhaustive}`\n );\n }\n }\n }\n definitions[name] = {\n allOf: [\n {\n if: anyDirective,\n then: {\n allOf: directiveNames.map((directive) => ({\n if: presence[directive],\n then: specs[directive]\n ? share({\n ...specs[directive],\n properties: Object.fromEntries(\n Object.entries(specs[directive]!.properties).map(\n ([key, property]) => [key, share(property as Schema)]\n )\n ),\n })\n : false,\n })),\n },\n else: literal(schema),\n },\n {\n // Keep starters while the first key is empty or a partial directive\n // (\"$\", \"$sl\", ...). Any ordinary or completed key ends this phase.\n // Prefixes come from the evaluator's directive registry.\n if: starterObject,\n then: {\n properties: Object.fromEntries(\n Object.entries(specs).map(([key, spec]) => [\n key,\n share(spec.properties[key]),\n ])\n ),\n },\n },\n ],\n };\n return { ...self, ...annotations };\n }\n\n definitions[bodyName] = author(componentRef, true) as Schema;\n return ref(bodyName);\n}\n","import {\n BlockEvaluationError,\n isBlockRecord,\n toAuthoredBlockPointer,\n type JsonBlockEvaluator,\n} from './evaluator';\n\ntype Rec = Record<string, unknown>;\n\nexport interface BlockCompositionOptions {\n /** Registered code component names. JSON never loads or installs them. */\n plugins: ReadonlySet<string>;\n /** Expand one registered component at its authored path into standard output. */\n render: (component: Rec, path: string) => Promise<unknown[]>;\n /** Plugin names kept unexpanded in the `preserved` tree (schema export, inspection). */\n preserve?: ReadonlySet<string>;\n}\n\nexport interface BlockComposition {\n /** Every block and plugin lowered to standard components. */\n standard: unknown;\n /** The same tree with preserved plugins left as authored. */\n preserved: unknown;\n}\n\n/**\n * One bounded expansion for document-local JSON and registered code, in both\n * directions: a plugin can emit a block, a block body or component slot can\n * name a plugin, and either can nest. Provenance survives each boundary\n * through the evaluator's source map; emitted output is wrapped in a `group`\n * whose pointer maps back to the plugin's authored node.\n *\n * Format-neutral: the host supplies the evaluator (its format, theme and\n * context) and validates the finished tree.\n */\nexport async function composeBlocksWithPlugins(\n evaluator: JsonBlockEvaluator,\n document: unknown,\n options: BlockCompositionOptions\n): Promise<BlockComposition> {\n const preserve = options.preserve ?? new Set<string>();\n let visited = 0;\n const walk = async (\n value: unknown,\n path: string,\n depth: number\n ): Promise<BlockComposition> => {\n if (depth > 64 || ++visited > 100000)\n throw new BlockEvaluationError([\n {\n path: toAuthoredBlockPointer(evaluator.sourceMap, path),\n code: 'block_expansion_limit',\n message:\n 'Combined plugin/block expansion exceeds depth/node limits (64/100000).',\n },\n ]);\n if (Array.isArray(value)) {\n const children: BlockComposition[] = [];\n for (let i = 0; i < value.length; i++)\n children.push(await walk(value[i], `${path}/${i}`, depth + 1));\n return {\n standard: children.map((c) => c.standard),\n preserved: children.map((c) => c.preserved),\n };\n }\n if (!isBlockRecord(value) || value.enabled === false)\n return { standard: value, preserved: value };\n if (value.name === 'block')\n return walk(evaluator.expand(value, path, depth), path, depth + 1);\n const standard: Rec = { ...value };\n const kept: Rec = { ...value };\n for (const [key, item] of Object.entries(value)) {\n if (path === '/props' && key === 'blocks') continue;\n const processed = await walk(item, `${path}/${key}`, depth + 1);\n Object.defineProperty(standard, key, {\n value: processed.standard,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n Object.defineProperty(kept, key, {\n value: processed.preserved,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n if (typeof value.name === 'string' && options.plugins.has(value.name)) {\n const source = toAuthoredBlockPointer(evaluator.sourceMap, path);\n const emitted = await options.render(standard, source);\n evaluator.sourceMap[`${path}/children`] = source;\n const processed = await walk(emitted, `${path}/children`, depth + 1);\n return {\n standard: { name: 'group', children: processed.standard },\n preserved: preserve.has(value.name)\n ? value\n : { name: 'group', children: processed.preserved },\n };\n }\n return { standard, preserved: kept };\n };\n return walk(document, '', 0);\n}\n","/**\n * Editor assistance derived from a document's own block definitions.\n *\n * A published schema cannot know which blocks one document defines, so the\n * exported `block` component accepts any `ref` and any `slots`. Everything\n * here is computed from the definitions actually present — in the editor on\n * every change, on the server for a reference catalog — and expressed in\n * standard draft-07 so the JSON language service completes, hovers and\n * diagnoses exactly what the runtime validator will accept: the names in\n * `props.blocks`, each one's slots with their descriptions, defaults and\n * constraints, and the placement a component slot may not carry.\n */\nimport { Value } from '@sinclair/typebox/value';\nimport type { OfficeFormat } from '../rendering/types';\nimport { blockSlotsJsonSchema } from './metadata';\nimport {\n BLOCK_SLOT_PLACEMENT_PROPS,\n blockPointerKey,\n isBlockRecord,\n readBlockDefinitions,\n validateBlockDefinitions,\n} from './evaluator';\nimport {\n BlockDefinitionsSchema,\n type BlockSlot,\n type JsonBlockDefinition,\n} from './schema';\n\ntype Schema = Record<string, any>;\n\n/** A block invocation as authored: the component the editor inserts. */\nexport interface BlockInvocationExample {\n name: 'block';\n props: { ref: string; slots?: Record<string, unknown> };\n}\n\nconst clone = <T>(value: T): T => JSON.parse(JSON.stringify(value));\n\nfunction range(\n minimum: number | undefined,\n maximum: number | undefined,\n unit: string\n): string | undefined {\n if (minimum !== undefined && maximum !== undefined)\n return minimum === maximum\n ? `${minimum} ${unit}`\n : `${minimum}–${maximum} ${unit}`;\n if (minimum !== undefined) return `at least ${minimum} ${unit}`;\n if (maximum !== undefined) return `at most ${maximum} ${unit}`;\n return undefined;\n}\n\n/**\n * A slot's contract as short facts, in one order, for every place that shows\n * it: the editor hover, the AI prompt, a catalog summary. \"Required\" means\n * the caller must supply a value — a slot with a default never is.\n */\nexport function blockSlotFacts(slot: BlockSlot): string[] {\n const facts: string[] = [];\n if (slot.required && slot.default === undefined) facts.push('Required');\n if (slot.default !== undefined)\n facts.push(`Default: \\`${JSON.stringify(slot.default)}\\``);\n if (slot.type === 'component')\n facts.push('A component; placement stays in the definition');\n if (slot.enum)\n facts.push(\n `One of ${slot.enum.map((value) => `\\`${JSON.stringify(value)}\\``).join(', ')}`\n );\n const length = range(slot.minLength, slot.maxLength, 'characters');\n if (length) facts.push(length);\n if (slot.maxWords !== undefined) facts.push(`at most ${slot.maxWords} words`);\n if (slot.oneLine) facts.push('one line');\n const bounds = range(slot.minimum, slot.maximum, '');\n if (bounds) facts.push(bounds.trim());\n const entries = range(slot.minItems, slot.maxItems, 'entries');\n if (entries) facts.push(entries);\n if (slot.role) facts.push(`Role: ${slot.role}`);\n return facts;\n}\n\n/** The hover text for a slot: its description, then its contract in one line. */\nexport function blockSlotMarkdown(slot: BlockSlot): string {\n return [slot.description, blockSlotFacts(slot).join(' · ')]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * JSON Schema for one slot as the editor should see it. Unlike the portable\n * `blockSlotJsonSchema`, a component slot references the real component\n * definition — so a chart placed in it completes like any other chart — with\n * the placement props the runtime rejects flagged at the key they appear on.\n */\nexport function blockSlotEditorSchema(\n slot: BlockSlot,\n componentRef?: Schema\n): Schema {\n let schema: Schema;\n if (slot.type === 'component') {\n schema = componentRef\n ? {\n allOf: [\n componentRef,\n {\n properties: {\n props: {\n propertyNames: {\n not: { enum: [...BLOCK_SLOT_PLACEMENT_PROPS] },\n errorMessage:\n 'Block placement belongs in the definition, not in a component slot.',\n },\n },\n },\n },\n ],\n }\n : {\n type: 'object',\n properties: { name: { type: 'string' } },\n required: ['name'],\n };\n } else {\n const { oneLine, properties, items, ...rest } = slot;\n // Runtime-only facts leave the schema and go into the hover text.\n for (const key of ['role', 'required', 'maxWords', 'description'] as const)\n delete rest[key];\n schema = { ...rest };\n if (oneLine) schema.pattern = '^[^\\\\r\\\\n]*$';\n if (items) schema.items = blockSlotEditorSchema(items, componentRef);\n if (properties) {\n schema.properties = Object.fromEntries(\n Object.entries(properties).map(([key, value]) => [\n key,\n blockSlotEditorSchema(value, componentRef),\n ])\n );\n schema.required = Object.entries(properties)\n .filter(([, value]) => value.required && value.default === undefined)\n .map(([key]) => key);\n schema.additionalProperties = false;\n }\n }\n if (slot.description) schema.description = slot.description;\n const markdown = blockSlotMarkdown(slot);\n if (markdown) schema.markdownDescription = markdown;\n return schema;\n}\n\n/** The `slots` object of an invocation of this definition. */\nexport function blockSlotsEditorSchema(\n definition: JsonBlockDefinition,\n componentRef?: Schema\n): Schema {\n return {\n type: 'object',\n additionalProperties: false,\n description:\n 'Input values keyed by the slot names declared in the referenced block definition.',\n properties: Object.fromEntries(\n Object.entries(definition.slots).map(([key, slot]) => [\n key,\n blockSlotEditorSchema(slot, componentRef),\n ])\n ),\n required: Object.entries(definition.slots)\n .filter(([, slot]) => slot.required && slot.default === undefined)\n .map(([key]) => key),\n };\n}\n\n/**\n * The `props` of a `block` component given this document's definitions:\n * `ref` enumerates the names with their descriptions, and each name\n * dispatches `slots` to its own schema. With no definitions the reference\n * stays a free string — the runtime says which name is missing.\n */\nexport function blockInvocationPropsSchema(\n definitions: Record<string, JsonBlockDefinition>,\n componentRef?: Schema\n): Schema {\n const names = Object.keys(definitions);\n const schema: Schema = {\n type: 'object',\n additionalProperties: false,\n required: ['ref'],\n properties: {\n ref: {\n type: 'string',\n minLength: 1,\n description: 'Name in this document’s props.blocks.',\n ...(names.length && {\n anyOf: names.map((name) => ({\n const: name,\n type: 'string',\n description:\n definitions[name].description ??\n `Block \"${name}\", defined in this document.`,\n })),\n }),\n },\n slots: {\n type: 'object',\n description:\n 'Input values keyed by the slot names declared in the referenced block definition.',\n },\n },\n };\n if (names.length)\n schema.allOf = names.map((name) => ({\n if: { properties: { ref: { const: name } }, required: ['ref'] },\n then: {\n properties: {\n slots: blockSlotsEditorSchema(definitions[name], componentRef),\n },\n },\n }));\n return schema;\n}\n\n/** Where the document-aware invocation props go in an exported schema. */\nexport interface DocumentBlockTarget {\n /** A component definition under `definitions`, typically one per renderer. */\n name: string;\n /**\n * What a component slot accepts — the content a slide or a section holds,\n * as a reference into the same schema. Omitted, a component slot only asks\n * for a `name`.\n */\n componentRef?: Schema;\n}\n\n/**\n * Install the document-aware invocation props on every `block` branch inside\n * the targeted component definitions — the definition's own branch and the\n * copies a container inlines for its children — so an invocation completes\n * the same wherever a slide or section places it. References out of the\n * definition are not followed: block bodies live in their own derived\n * definitions and keep their binding-aware props. Mutates in place; call on\n * a copy of the shared schema.\n */\nexport function applyDocumentBlocksToSchema(\n schema: Schema,\n definitions: Record<string, JsonBlockDefinition>,\n targets: readonly DocumentBlockTarget[]\n): void {\n for (const target of targets) {\n const definition = schema.definitions?.[target.name];\n if (!definition) continue;\n const props = blockInvocationPropsSchema(definitions, target.componentRef);\n const seen = new Set<object>();\n const walk = (node: unknown): void => {\n if (!node || typeof node !== 'object' || seen.has(node)) return;\n seen.add(node);\n if (Array.isArray(node)) {\n node.forEach(walk);\n return;\n }\n const value = node as Schema;\n if (value.properties?.name?.const === 'block' && value.properties.props) {\n value.properties.props = clone(props);\n return;\n }\n for (const [key, child] of Object.entries(value))\n if (key !== '$ref') walk(child);\n };\n walk(definition);\n }\n}\n\n/** Every `block` invocation reachable from a node, in document order. */\nfunction invocations(\n node: unknown,\n visit: (ref: string, invocation: Record<string, unknown>) => void\n): void {\n if (Array.isArray(node)) {\n node.forEach((item) => invocations(item, visit));\n return;\n }\n if (!isBlockRecord(node)) return;\n if (\n node.name === 'block' &&\n isBlockRecord(node.props) &&\n typeof node.props.ref === 'string'\n )\n visit(node.props.ref, node);\n for (const value of Object.values(node)) invocations(value, visit);\n}\n\n/**\n * The definitions a block needs beside itself, dependencies first, so a\n * copied definition never leaves an unresolved reference behind. Unknown\n * references and cycles are skipped: the runtime reports those.\n */\nexport function blockDependencies(\n definitions: Record<string, JsonBlockDefinition>,\n name: string\n): string[] {\n const order: string[] = [];\n const seen = new Set<string>([name]);\n const walk = (current: string): void => {\n const definition = Object.prototype.hasOwnProperty.call(\n definitions,\n current\n )\n ? definitions[current]\n : undefined;\n if (!definition) return;\n invocations(\n [definition.body, definition.section, definition.slide],\n (ref) => {\n if (seen.has(ref)) return;\n seen.add(ref);\n if (!Object.prototype.hasOwnProperty.call(definitions, ref)) return;\n walk(ref);\n order.push(ref);\n }\n );\n };\n walk(name);\n return order;\n}\n\nfunction exampleValue(\n slot: BlockSlot,\n name: string,\n format: OfficeFormat\n): unknown {\n if (slot.default !== undefined) return clone(slot.default);\n if (slot.enum?.length) return slot.enum[0];\n switch (slot.type) {\n case 'string':\n return name;\n case 'number':\n case 'integer': {\n const minimum = slot.minimum ?? 0;\n return slot.maximum !== undefined && slot.maximum < minimum\n ? slot.maximum\n : minimum;\n }\n case 'boolean':\n return true;\n case 'array': {\n // Typical cardinality: three entries, pulled inside the declared bounds.\n const count = Math.min(\n Math.max(3, slot.minItems ?? 0),\n slot.maxItems ?? Number.POSITIVE_INFINITY\n );\n const item = slot.items ?? { type: 'string' };\n return Array.from({ length: count }, (_, index) =>\n exampleValue(item, `${name} ${index + 1}`, format)\n );\n }\n case 'object':\n return exampleSlots(slot.properties ?? {}, format);\n case 'component':\n return format === 'docx'\n ? { name: 'paragraph', props: { text: name } }\n : { name: 'text', props: { text: name } };\n default:\n return name;\n }\n}\n\n/** Required slots and role-bearing chrome; everything else stays omitted. */\nfunction exampleSlots(\n slots: Record<string, BlockSlot>,\n format: OfficeFormat\n): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(slots)\n .filter(\n ([, slot]) => (slot.required && slot.default === undefined) || slot.role\n )\n .map(([key, slot]) => [key, exampleValue(slot, key, format)])\n );\n}\n\n/**\n * A valid invocation to insert: the first one the source document makes, if\n * it makes one — real content, at the cardinality its author chose — else\n * one synthesized from the slots at typical cardinality.\n */\nexport function blockInvocationExample(\n name: string,\n definition: JsonBlockDefinition,\n options: { document?: unknown; format: OfficeFormat }\n): BlockInvocationExample {\n let found: BlockInvocationExample | undefined;\n if (isBlockRecord(options.document)) {\n // Authored slides only: the definitions themselves also invoke blocks.\n const authored = Object.fromEntries(\n Object.entries(options.document).filter(([key]) => key !== 'props')\n );\n invocations(authored, (ref, invocation) => {\n if (found || ref !== name) return;\n const props = invocation.props as Record<string, unknown>;\n found = {\n name: 'block',\n props: {\n ref,\n ...(isBlockRecord(props.slots) && { slots: clone(props.slots) }),\n },\n };\n });\n }\n return (\n found ?? {\n name: 'block',\n props: {\n ref: name,\n slots: exampleSlots(definition.slots, options.format),\n },\n }\n );\n}\n\n/** An authoring reference extracted from a complete document. */\nexport interface BlockReference {\n name: string;\n format: OfficeFormat;\n /** The document the definition comes from. */\n template: string;\n definitionPointer: string;\n description: string;\n definition: JsonBlockDefinition;\n /** Portable slot schema, as `jto://blocks` publishes it. */\n slotsSchema: Record<string, unknown>;\n /** A valid invocation at typical cardinality. */\n example: BlockInvocationExample;\n /** Other definitions of the same document this one invokes, dependencies first. */\n dependencies: string[];\n}\n\n/**\n * Every block a complete document defines, as a reference an editor or an\n * agent can copy: definition, dependencies and a working invocation. A\n * document whose definitions do not validate contributes nothing — a\n * reference must be copyable as is.\n */\nexport function blockReferencesFromDocument(\n document: unknown,\n source: { template: string; format: OfficeFormat }\n): BlockReference[] {\n const definitions = readBlockDefinitions(document);\n if (\n !Value.Check(BlockDefinitionsSchema, definitions) ||\n validateBlockDefinitions(definitions, source.format).length > 0\n )\n return [];\n return Object.entries(definitions).map(([name, definition]) => ({\n name,\n format: source.format,\n template: source.template,\n definitionPointer: `/props/blocks/${blockPointerKey(name)}`,\n description: definition.description ?? '',\n definition,\n slotsSchema: blockSlotsJsonSchema(definition),\n example: blockInvocationExample(name, definition, {\n document,\n format: source.format,\n }),\n dependencies: blockDependencies(definitions, name),\n }));\n}\n","/**\n * Deep Merge Utilities\n * Generic deep-merge helpers used by both docx and pptx\n * componentDefaults resolution systems.\n */\n\nfunction isObject(item: any): boolean {\n return item !== null && typeof item === 'object' && !Array.isArray(item);\n}\n\nfunction deepMerge<T>(target: any, source: any): T {\n const output = { ...target };\n\n if (isObject(target) && isObject(source)) {\n Object.keys(source).forEach((key) => {\n if (isObject(source[key])) {\n // Recursing into a non-object default would spread it — a scalar\n // theme default (`borderColor: '#f0f0f0'`) turned a user's per-side\n // object into `{0: '#', 1: 'f', …}`, silently erasing the user value\n // it was supposed to yield to.\n if (!(key in target) || !isObject(target[key])) {\n output[key] = source[key];\n } else {\n output[key] = deepMerge(target[key], source[key]);\n }\n } else {\n output[key] = source[key];\n }\n });\n }\n\n return output as T;\n}\n\n/**\n * Merge theme defaults with user-provided configuration.\n * User config takes precedence over theme defaults.\n * Uses deep merge to preserve nested objects.\n * Arrays are replaced wholesale, not merged per-element.\n */\nexport function mergeWithDefaults<T>(\n userConfig: T,\n themeDefaults: Partial<T>\n): T {\n return deepMerge<T>(themeDefaults, userConfig);\n}\n"],"mappings":"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","names":["weight","weight","cacheKey","weight","weight","HEADER_SIZE","TABLE_RECORD_SIZE","weight","weight","referenced","warnings","pointer","result","Value","Value","invocations","pointer","pointer","key","Value","Value"]}
1
+ {"version":3,"sources":["../src/types/services.ts","../src/fonts/collect.ts","../src/fonts/document-registry.ts","../src/fonts/validator.ts","../src/fonts/synthesize.ts","../src/fonts/sources/data-loader.ts","../src/fonts/sources/google-fetcher.ts","../src/fonts/sources/url-fetcher.ts","../src/fonts/sources/ttf-validate.ts","../src/fonts/sources/ttf-structure.ts","../src/fonts/cache/memory-cache.ts","../src/fonts/registry.ts","../src/fonts/catalog/popular-google.ts","../src/fonts/catalog/upstream-overrides.ts","../src/fonts/substitute.ts","../src/theme/chart-palette.ts","../src/theme/chart-typography.ts","../src/blocks/schema.ts","../src/blocks/directives.ts","../src/blocks/evaluator.ts","../src/blocks/metadata.ts","../src/blocks/schema-types.ts","../src/blocks/authoring-schema.ts","../src/blocks/compose.ts","../src/blocks/editor.ts","../src/utils/deepMerge.ts","../src/utils/serviceUrl.ts"],"sourcesContent":["/**\n * Service configuration types for external integrations (e.g. Highcharts export server)\n */\n\n// ============================================================================\n// Visual rasterization policy — single source of truth for DPI bounds shared\n// by the visual schema, the in-process rasterizer, the flatten transform, and\n// both HTTP /rasterize surfaces. Keep these in sync in one place.\n// ============================================================================\n\n/** Default raster resolution when a `visual` does not specify one. */\nexport const DEFAULT_VISUAL_DPI = 200;\n/** Minimum accepted raster resolution. */\nexport const MIN_VISUAL_DPI = 36;\n/** Maximum accepted raster resolution (bounds bitmap size / DoS surface). */\nexport const MAX_VISUAL_DPI = 600;\n\n/** Clamp an arbitrary dpi to [MIN_VISUAL_DPI, MAX_VISUAL_DPI]; non-finite → default. */\nexport function clampVisualDpi(dpi: unknown): number {\n if (typeof dpi !== 'number' || !Number.isFinite(dpi))\n return DEFAULT_VISUAL_DPI;\n return Math.min(MAX_VISUAL_DPI, Math.max(MIN_VISUAL_DPI, Math.round(dpi)));\n}\n\nexport type HighchartsHeaders = Record<string, string>;\n\nexport type HighchartsHeadersResolver = (\n body: unknown\n) => HighchartsHeaders | Promise<HighchartsHeaders>;\n\nexport interface HighchartsServiceConfig {\n serverUrl?: string;\n headers?: HighchartsHeaders | HighchartsHeadersResolver;\n /**\n * Allow an export server outside this machine and its private networks.\n * A chart is posted whole — every series, label and title — so a remote\n * server is a decision, not a default: without this, generation refuses a\n * public URL; with it, every generation says which URL received the data.\n */\n allowRemote?: boolean;\n}\n\n// ============================================================================\n// PPTX rasterization service (used by the docx `visual` component)\n// ============================================================================\n\nexport type PptxServiceHeaders = Record<string, string>;\n\nexport type PptxServiceHeadersResolver = (\n body: unknown\n) => PptxServiceHeaders | Promise<PptxServiceHeaders>;\n\n/** Max font faces accepted in one rasterize request. */\nexport const MAX_RASTERIZE_FONTS = 32;\n/** Max total DECODED font bytes accepted in one rasterize request. */\nexport const MAX_RASTERIZE_FONT_BYTES = 8 * 1024 * 1024;\n\n/**\n * One font face shipped alongside a rasterize request so the rasterizer's\n * out-of-process LibreOffice can render the slide with the document's real\n * fonts instead of a system fallback.\n *\n * `data` is base64 of the raw font file — NO `data:` URI prefix — so the\n * request stays plain serializable JSON.\n *\n * `family` is the CATALOG family (`ResolvedFont.family`, e.g. \"Inter\"), not\n * the synthesized sub-family the presentation references. The receiving\n * stager applies `synthesizeFamilyName` + `rewriteFontFamilyName` itself,\n * exactly as it does for the PDF-preview path; pre-synthesizing here would\n * double-apply the suffix (\"Inter Light Light\").\n */\nexport interface RasterizeFontFace {\n family: string;\n weight: number;\n italic: boolean;\n /** Base64-encoded font file bytes (no `data:` prefix). */\n data: string;\n format?: 'ttf' | 'otf' | 'woff' | 'woff2';\n}\n\n/**\n * Request handed to a pptx rasterizer: a single-slide pptx presentation\n * component definition plus the target resolution.\n */\nexport interface PptxRasterizeRequest {\n /** A pptx presentation component definition ({ name: 'pptx', ... }) with one slide */\n presentation: unknown;\n /** Target raster resolution in dots-per-inch */\n dpi: number;\n /**\n * Directory that relative asset paths inside the presentation resolve\n * against — the originating document's own directory. Absent → the\n * rasterizer's cwd, the legacy behavior (#142).\n */\n baseDir?: string;\n /**\n * Font faces to stage for the rasterizer's LibreOffice launch. Absent →\n * system fonts only, which is what every non-font-aware caller (and every\n * pre-Area-6 client) sends.\n */\n fonts?: RasterizeFontFace[];\n}\n\n/**\n * Result returned by a pptx rasterizer.\n */\nexport interface PptxRasterizeResult {\n /** Rendered PNG as a base64 data URI (data:image/png;base64,...) */\n base64DataUri: string;\n /** Natural pixel width of the rendered image */\n width: number;\n /** Natural pixel height of the rendered image */\n height: number;\n}\n\n/**\n * In-process rasterizer callback. Implementations build the .pptx from the\n * presentation JSON and rasterize it to a PNG (e.g. via LibreOffice + poppler).\n */\nexport type PptxRasterizer = (\n request: PptxRasterizeRequest\n) => Promise<PptxRasterizeResult>;\n\n// ============================================================================\n// Batch rasterization (#153) — one request rasterizes many independent slides.\n//\n// Each slide is a complete single-slide presentation (the exact shape a\n// single {@link PptxRasterizeRequest} carries), NOT a slide fragment of one\n// merged deck. This keeps slides independent — each may use its own canvas\n// size, theme, and dpi, so callers never need to group visuals — and lets\n// implementations key per-slide caches identically to the single-slide path.\n// ============================================================================\n\n/**\n * Maximum slides accepted in one batch request. Shared by the HTTP surface\n * (request validation) and clients (chunk size) so the two cannot drift.\n * Bounds per-request work and response size the same way rate limits bound\n * request counts.\n */\nexport const MAX_RASTERIZE_BATCH_SLIDES = 32;\n\n/** One slide in a batch: a single-slide presentation plus its resolution. */\nexport interface PptxRasterizeBatchSlide {\n /** A pptx presentation component definition ({ name: 'pptx', ... }) with one slide */\n presentation: unknown;\n /** Target raster resolution in dots-per-inch (absent → service default) */\n dpi?: number;\n}\n\n/** Request handed to a batch pptx rasterizer. */\nexport interface PptxRasterizeBatchRequest {\n /** Slides to rasterize; results come back index-aligned with this array. */\n slides: PptxRasterizeBatchSlide[];\n /** Base directory for relative asset paths, shared by every slide (#142). */\n baseDir?: string;\n /**\n * Font faces staged for the batch's LibreOffice launch, shared by every\n * slide exactly like `baseDir`. Deliberately REQUEST-level and never\n * per-slide: {@link PptxRasterizeBatchSlide} stays `{presentation, dpi}` so\n * batch-internal dedupe and the per-slide disk-cache key stay uniform with\n * the single-slide path.\n */\n fonts?: RasterizeFontFace[];\n}\n\n/**\n * Pipeline stage a slide failed in. `build` failures are caused by the\n * slide's own JSON (safe to surface verbatim to callers); `convert` and\n * `rasterize` failures are environment/tooling errors whose raw messages may\n * carry host paths — HTTP surfaces sanitize those.\n */\nexport type PptxRasterizeFailureStage = 'build' | 'convert' | 'rasterize';\n\n/**\n * Per-slide outcome. A batch response is 200-with-item-errors rather than\n * all-or-nothing: one bad visual must not discard its siblings' pixels.\n */\nexport type PptxRasterizeBatchSlideResult =\n | ({ ok: true } & PptxRasterizeResult)\n | { ok: false; error: string; stage?: PptxRasterizeFailureStage };\n\n/** Result returned by a batch pptx rasterizer. */\nexport interface PptxRasterizeBatchResult {\n /** Index-aligned with the request's `slides` (same length, same order). */\n results: PptxRasterizeBatchSlideResult[];\n}\n\n/**\n * In-process batch rasterizer callback. Batch-level failures (missing\n * binaries, bad request) throw; per-slide failures land in `results`.\n */\nexport type PptxBatchRasterizer = (\n request: PptxRasterizeBatchRequest\n) => Promise<PptxRasterizeBatchResult>;\n\n/**\n * Configuration for the pptx rasterization service backing `visual` components.\n *\n * Mirrors {@link HighchartsServiceConfig}: the published packages depend on this\n * interface, never on a binary. A host injects either an in-process `render`\n * callback or an HTTP `serverUrl`.\n */\nexport interface PptxServiceConfig {\n /**\n * In-process rasterizer. Takes precedence over `serverUrl` when provided.\n * Ideal for tests (no binaries) and single-process hosts.\n */\n render?: PptxRasterizer;\n /**\n * In-process batch rasterizer. When provided, the docx renderer coalesces a\n * document's visuals into batch calls (#153) instead of one `render` call\n * per visual. Like `render`, takes precedence over `serverUrl`.\n */\n renderBatch?: PptxBatchRasterizer;\n /**\n * HTTP rasterization service URL. The service receives\n * `{ presentation, dpi }` and returns a {@link PptxRasterizeResult}.\n */\n serverUrl?: string;\n /** Optional headers (or async resolver) for the HTTP service. */\n headers?: PptxServiceHeaders | PptxServiceHeadersResolver;\n /** Default DPI applied when a `visual` does not specify one. */\n dpi?: number;\n}\n\nexport interface ServicesConfig {\n highcharts?: HighchartsServiceConfig;\n pptx?: PptxServiceConfig;\n}\n","/**\n * Walk a document tree and collect every font family name referenced.\n *\n * Matches both DOCX conventions (`family` nested under `font`, theme.fonts.*)\n * and PPTX conventions (`fontFace`, chart `titleFontFace` etc., theme.fonts.*).\n * Key-name matching is intentionally permissive so future component schemas\n * that reuse the same conventions pick up automatically.\n */\n\nexport const FONT_NAME_KEYS = new Set([\n 'family',\n 'fontFace',\n 'titleFontFace',\n 'legendFontFace',\n 'dataLabelFontFace',\n 'catAxisLabelFontFace',\n 'valAxisLabelFontFace',\n]);\n\nexport const THEME_FONT_KEYS = new Set(['heading', 'body', 'mono', 'light']);\n\n/**\n * Subtrees that declare fonts rather than reference them. `fontRegistry`\n * entries carry `family` (and `sources[].family` for kind:'safe'/'google'),\n * which the depth-agnostic `family` match would otherwise scoop up as\n * references — a registry would self-satisfy its own validation, and a\n * `kind:'google'` source family would appear as a phantom reference.\n * substitute.ts's rewriter skips the same key; the two MUST stay in sync.\n */\nexport const FONT_DECLARATION_KEYS = new Set(['fontRegistry']);\n\nfunction collect(node: unknown, out: Set<string>, parentKey?: string): void {\n if (node == null) return;\n\n if (typeof node === 'string') {\n // String values under a font-name key or under theme.fonts.{heading,body,...}\n if (\n parentKey &&\n (FONT_NAME_KEYS.has(parentKey) || THEME_FONT_KEYS.has(parentKey))\n ) {\n const trimmed = node.trim();\n if (trimmed.length > 0) out.add(trimmed);\n }\n return;\n }\n\n if (Array.isArray(node)) {\n // Forward parentKey so font-name arrays (e.g. theme.fonts.heading: [...])\n // are walked with the same context as the non-array case. Mirrors\n // substitute.ts's rewrite walker — the two must stay in sync or\n // substitution silently misses array-shaped references.\n for (const item of node) collect(item, out, parentKey);\n return;\n }\n\n if (typeof node === 'object') {\n // Special-cased: theme.fonts is an object whose values (or values.family) are font names.\n const maybeFonts = (node as Record<string, unknown>).fonts;\n if (parentKey === 'theme' && maybeFonts && typeof maybeFonts === 'object') {\n for (const [k, v] of Object.entries(\n maybeFonts as Record<string, unknown>\n )) {\n if (typeof v === 'string') {\n const trimmed = v.trim();\n if (trimmed.length > 0) out.add(trimmed);\n } else if (v && typeof v === 'object') {\n const fam = (v as Record<string, unknown>).family;\n if (typeof fam === 'string' && fam.trim().length > 0) {\n out.add(fam.trim());\n }\n }\n void k;\n }\n }\n\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n // Declarations, not references — see FONT_DECLARATION_KEYS.\n if (FONT_DECLARATION_KEYS.has(k)) continue;\n collect(v, out, k);\n }\n }\n}\n\n/** Scan an arbitrary doc tree (DOCX or PPTX) for every font family referenced. */\nexport function collectFontNames(doc: unknown): Set<string> {\n const out = new Set<string>();\n collect(doc, out);\n return out;\n}\n\n/** Scan a DOCX document tree for every font family name referenced. */\nexport const collectFontNamesFromDocx = collectFontNames;\n\n/** Scan a PPTX presentation tree for every font family name referenced. */\nexport const collectFontNamesFromPptx = collectFontNames;\n","/**\n * Read the document-scoped and theme-scoped font registries and merge them\n * with runtime `fonts.extraEntries`.\n *\n * Precedence (last wins, matching registry.ts's documented resolution rules\n * and FontRuntimeOpts.extraEntries's \"merged over the document's\n * fontRegistry\"):\n *\n * theme.fontRegistry < document.props.fontRegistry < fonts.extraEntries\n *\n * Merging happens here rather than inside FontRegistry because\n * `validateFontReferences` needs the same merged list, and two merge sites\n * would eventually disagree — which would show up as a font that validates\n * but never renders, or vice versa.\n */\n\nimport type { FontRegistryEntry } from '../schemas/font-catalog';\n\nfunction isEntry(v: unknown): v is FontRegistryEntry {\n if (!v || typeof v !== 'object') return false;\n const e = v as Record<string, unknown>;\n return (\n typeof e.id === 'string' &&\n typeof e.family === 'string' &&\n Array.isArray(e.sources)\n );\n}\n\nfunction readAt(node: unknown, key: string): FontRegistryEntry[] {\n if (!node || typeof node !== 'object') return [];\n const raw = (node as Record<string, unknown>)[key];\n return Array.isArray(raw) ? raw.filter(isEntry) : [];\n}\n\n/** `document.props.fontRegistry`, defensively (props may be absent/null). */\nexport function documentFontRegistry(document: unknown): FontRegistryEntry[] {\n if (!document || typeof document !== 'object') return [];\n return readAt((document as Record<string, unknown>).props, 'fontRegistry');\n}\n\n/** `theme.fontRegistry`, defensively. */\nexport function themeFontRegistry(theme: unknown): FontRegistryEntry[] {\n return readAt(theme, 'fontRegistry');\n}\n\n/**\n * Merge entry groups in precedence order — later groups win on a collision of\n * `family` OR `id`, case-insensitively, which are the same two keys\n * `FontRegistry.addEntry` indexes on. Returns a flat list safe to hand to both\n * `validateFontReferences` and `new FontRegistry({ opts: { extraEntries } })`.\n */\nexport function mergeFontRegistries(\n ...groups: (FontRegistryEntry[] | undefined)[]\n): FontRegistryEntry[] {\n // Order IS the contract: `FontRegistry` replays this array through\n // `addEntry`, indexing on family and id with last-write-wins, so an entry\n // only outranks another by sitting later. Concatenating the groups in\n // precedence order is therefore the whole mechanism.\n //\n // Deliberately NOT de-duped through a Map keyed by family/id: `Map.set` on\n // an existing key keeps the original insertion *position*, so a\n // higher-precedence entry colliding with an earlier one would be emitted\n // early and then lose the replay to the entry it was supposed to beat.\n const out: FontRegistryEntry[] = [];\n for (const group of groups) {\n for (const entry of group ?? []) {\n const family = entry.family.toLowerCase();\n const id = entry.id.toLowerCase();\n // Drop only a true replacement — same family AND same id. An entry that\n // shares just one of the two still owns the other key in FontRegistry's\n // index, so removing it here would make that name unresolvable.\n for (let i = out.length - 1; i >= 0; i--) {\n if (\n out[i].family.toLowerCase() === family &&\n out[i].id.toLowerCase() === id\n ) {\n out.splice(i, 1);\n }\n }\n out.push(entry);\n }\n }\n return out;\n}\n","/**\n * Validate that every font name referenced in a document is either\n * in SAFE_FONTS or present in the document's fontRegistry / runtime overrides.\n *\n * Used at generate-start; emits warnings for unresolved names so pipelines\n * can surface them via their existing warning channels.\n */\n\nimport { SAFE_FONTS, isSafeFont } from '../schemas/font-catalog';\nimport type { FontRegistryEntry } from '../schemas/font-catalog';\n\n/**\n * Warning codes for font resolution + rendering.\n *\n * - `FONT_UNRESOLVED` — family not in SAFE_FONTS and not registered.\n * - `FONT_MODE_SUBSTITUTED` — non-safe families rewritten to safe equivalents.\n * - `FONT_MODE_CUSTOM` — export mode \"custom\" — refs kept as-is.\n */\nexport type FontIssueCode =\n | 'FONT_UNRESOLVED'\n | 'FONT_MODE_SUBSTITUTED'\n | 'FONT_MODE_CUSTOM';\n\nexport interface FontResolutionIssue {\n code: FontIssueCode;\n family: string;\n message: string;\n}\n\nexport interface FontValidationResult {\n /** Names that resolved via SAFE_FONTS or the registry. */\n resolved: string[];\n /** Names with no resolution path. */\n unresolved: string[];\n /** One warning per unresolved name. */\n warnings: FontResolutionIssue[];\n}\n\nexport interface FontValidationInput {\n /** Font names referenced in the document (from collectFontNamesFromDocx / FromPptx). */\n referencedNames: Iterable<string>;\n /** Runtime-registered entries (e.g. from FontRuntimeOpts.extraEntries). */\n registeredEntries?: FontRegistryEntry[];\n}\n\nfunction buildRegistryIndex(\n registeredEntries?: FontRegistryEntry[]\n): Set<string> {\n const idx = new Set<string>();\n for (const e of registeredEntries ?? []) {\n idx.add(e.family.toLowerCase());\n idx.add(e.id.toLowerCase());\n }\n return idx;\n}\n\n/**\n * Validate referenced font names against SAFE_FONTS + runtime-registered entries.\n * Does not perform network fetches — this runs purely off schema + opts content.\n */\nexport function validateFontReferences(\n input: FontValidationInput\n): FontValidationResult {\n const registryIdx = buildRegistryIndex(input.registeredEntries);\n const resolved: string[] = [];\n const unresolved: string[] = [];\n const warnings: FontResolutionIssue[] = [];\n\n for (const name of input.referencedNames) {\n if (isSafeFont(name) || registryIdx.has(name.toLowerCase())) {\n resolved.push(name);\n continue;\n }\n unresolved.push(name);\n warnings.push({\n code: 'FONT_UNRESOLVED',\n family: name,\n message:\n `Font \"${name}\" is not a SAFE_FONTS entry and is not registered via fonts.extraEntries. ` +\n `It will render with a host fallback on machines lacking the font. ` +\n `Safe fonts: ${SAFE_FONTS.join(', ')}.`,\n });\n }\n\n return { resolved, unresolved, warnings };\n}\n","/**\n * Map a (family, weight, italic) tuple to the pair of\n * `(familyName, { bold, italic })` the renderer should actually use.\n *\n * OOXML runs can only carry a bold/italic toggle, not a numeric weight.\n * For weights outside the RIBBI quad (400/700 × roman/italic), Word\n * resolves intermediate weights via **separate sub-family faces** whose\n * internal family name is the canonical Google-Fonts-style subfamily,\n * e.g. `Inter Light`, `Inter ExtraBold Italic`. Rewriting the run's\n * `family` to that synthetic name lets Word pick the right face when the\n * recipient has the full family installed, and lets the LibreOffice\n * preview resolve the matching staged TTF by its internal name.\n *\n * No embedding involved — this is purely a name transform applied at\n * render time. Safe fonts and unrecognised weights fall back to the\n * bold-only heuristic (`weight >= 600 → bold`).\n */\n\n/** Human-readable labels for the canonical font-weight numbers. */\nexport const WEIGHT_LABELS: Record<number, string> = {\n 100: 'Thin',\n 200: 'ExtraLight',\n 300: 'Light',\n 400: 'Regular',\n 500: 'Medium',\n 600: 'SemiBold',\n 700: 'Bold',\n 800: 'ExtraBold',\n 900: 'Black',\n};\n\nexport interface SynthesizedFamily {\n /** The family name to emit in `rFonts`/`fontFace`. */\n family: string;\n /** Whether to also set the run's bold toggle. */\n bold: boolean;\n /** Whether to also set the run's italic toggle. */\n italic: boolean;\n /**\n * `true` when the input `weight` was not one of the canonical\n * 100/200/.../900 labels. The canonical family name is returned with\n * a `weight >= 600 → bold` fallback, but the run will not match a\n * dedicated sub-family face — callers should surface this so authors\n * know the weight was effectively rounded to Regular or Bold.\n */\n nonCanonicalWeight: boolean;\n}\n\n/**\n * Translate `(family, weight, italic)` into the rendering-time family name\n * plus the bold/italic toggles to emit on the run.\n *\n * - RIBBI (weights 400 + 700, roman + italic) stays on the canonical family\n * name and uses native bold/italic toggles.\n * - Other canonical weights become `\"<Family> <Weight>\"` (e.g.\n * `\"Inter Light\"`) with bold/italic toggles cleared; any italic flag is\n * folded into the name (`\"Inter Light Italic\"`).\n * - Non-canonical weights (floating or out-of-range) fall back to\n * `bold = weight >= 600` and leave the family name untouched.\n */\nexport function synthesizeFamilyName(\n family: string,\n weight: number | undefined,\n italic: boolean\n): SynthesizedFamily {\n if (weight == null) {\n return { family, bold: false, italic, nonCanonicalWeight: false };\n }\n // RIBBI — no rewrite needed, let native bold/italic do the work.\n if (weight === 400) {\n return { family, bold: false, italic, nonCanonicalWeight: false };\n }\n if (weight === 700) {\n return { family, bold: true, italic, nonCanonicalWeight: false };\n }\n const label = WEIGHT_LABELS[weight];\n if (!label) {\n // Non-canonical weight — best-effort bold fallback. Flag the result so\n // callers can warn: the run will render as Regular or Bold, not the\n // intermediate weight the author asked for.\n return {\n family,\n bold: weight >= 600,\n italic,\n nonCanonicalWeight: true,\n };\n }\n const suffix = italic ? ` ${label} Italic` : ` ${label}`;\n return {\n family: `${family}${suffix}`,\n bold: false,\n italic: false,\n nonCanonicalWeight: false,\n };\n}\n","/**\n * Decode a base64 / data-URL font payload to a Buffer.\n */\n\nimport type { ResolvedFontSource } from '../types';\nimport { detectFontFormat } from './format';\n\nexport interface DataSourceInput {\n data: string;\n weight?: number;\n italic?: boolean;\n}\n\n/**\n * Hard upper bound on the decoded font buffer. Real TTF/OTF faces are well\n * under 5 MB; even variable-axis fonts with CJK coverage rarely exceed 4 MB.\n * Rejecting oversized payloads before decoding prevents a malicious\n * `kind: 'data'` registry entry from allocating arbitrary server memory\n * when the generator runs behind an HTTP endpoint.\n */\nconst MAX_DATA_FONT_BYTES = 5 * 1024 * 1024;\n\n/**\n * Accepts either a bare base64 string or a data: URL.\n * Throws on invalid input; renderer catches and emits a warning.\n */\nexport function loadDataFontSource(input: DataSourceInput): ResolvedFontSource {\n const raw = input.data.trim();\n let b64: string;\n if (raw.startsWith('data:')) {\n const comma = raw.indexOf(',');\n if (comma < 0) throw new Error('Invalid data URL: no payload separator');\n // Only base64-encoded payloads are supported.\n const header = raw.slice(5, comma);\n if (!header.includes(';base64')) {\n throw new Error('Data URL must be base64-encoded');\n }\n b64 = raw.slice(comma + 1);\n } else {\n b64 = raw;\n }\n // Upper-bound the decoded size via base64 length before allocating. A\n // base64 string decodes to ~3/4 its character count, so a conservative\n // check on the encoded size avoids decoding a 50 MB payload just to\n // reject it afterward.\n const approxDecodedBytes = Math.floor((b64.length * 3) / 4);\n if (approxDecodedBytes > MAX_DATA_FONT_BYTES) {\n throw new Error(\n `Font data payload exceeds ${MAX_DATA_FONT_BYTES} byte limit`\n );\n }\n const data = Buffer.from(b64, 'base64');\n if (data.length === 0) throw new Error('Decoded font buffer is empty');\n if (data.length > MAX_DATA_FONT_BYTES) {\n throw new Error(\n `Font data payload exceeds ${MAX_DATA_FONT_BYTES} byte limit`\n );\n }\n // Base64 decoding silently discards invalid characters, so garbage input\n // yields a non-empty buffer that isn't a real font. Magic-byte check\n // rejects the garbage before it reaches the LibreOffice preview stager.\n const format = detectFontFormat(data);\n if (format === 'unknown') {\n throw new Error(\n 'Decoded font buffer is not a recognized font (expected TTF/OTF/WOFF/WOFF2)'\n );\n }\n // WOFF/WOFF2 flow through: Office output never embeds bytes, and the\n // LibreOffice preview stager handles them via fontconfig.\n return {\n data,\n weight: input.weight ?? 400,\n italic: input.italic ?? false,\n format,\n };\n}\n","/**\n * Google Fonts fetcher.\n *\n * Hits the CSS API v2 with an older User-Agent that returns TTF (default UA\n * gets WOFF2, which Office cannot embed as-is). Parses the `src: url(...)` line\n * and downloads the binary.\n *\n * Uses memory + optional disk cache keyed by `${family}|${weight}|${italic}`.\n */\n\nimport type { ResolvedFontSource } from '../types';\nimport { FontMemoryCache } from '../cache/memory-cache';\nimport { detectFontFormat } from './format';\n\ninterface FontDiskCacheLike {\n get(key: string): Promise<Buffer | undefined>;\n set(key: string, value: Buffer): Promise<void>;\n}\n\nexport interface GoogleFetchOptions {\n family: string;\n weights: number[];\n italics?: boolean;\n memoryCache?: FontMemoryCache;\n diskCache?: FontDiskCacheLike;\n fetchTimeoutMs?: number;\n /** Override for tests. */\n fetcher?: typeof fetch;\n}\n\nexport interface GoogleFetchResult {\n sources: ResolvedFontSource[];\n warnings: string[];\n}\n\nconst TTF_UA = 'Mozilla/4.0';\n\nasync function fetchWithTimeout(\n url: string,\n opts: {\n headers?: Record<string, string>;\n timeoutMs?: number;\n fetcher?: typeof fetch;\n }\n): Promise<Response> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 5000);\n try {\n const f = opts.fetcher ?? fetch;\n return await f(url, { headers: opts.headers, signal: ctrl.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction buildCssUrl(\n family: string,\n weights: number[],\n italics: boolean\n): string {\n // URL-encode then restore spaces as `+` (Google's CSS2 API convention).\n const famPart = encodeURIComponent(family).replace(/%20/g, '+');\n const sortedWeights = [...weights].sort((a, b) => a - b);\n if (italics) {\n const axis = sortedWeights.flatMap((w) => [`0,${w}`, `1,${w}`]).join(';');\n return `https://fonts.googleapis.com/css2?family=${famPart}:ital,wght@${axis}&display=swap`;\n }\n const wghtPart = sortedWeights.join(';');\n return `https://fonts.googleapis.com/css2?family=${famPart}:wght@${wghtPart}&display=swap`;\n}\n\n/**\n * Parse Google Fonts CSS response into { weight, italic, ttfUrl } tuples.\n * Each @font-face block contains the src + font-weight + font-style we need.\n */\nfunction parseCssFaces(\n css: string\n): { weight: number; italic: boolean; ttfUrl: string }[] {\n const out: { weight: number; italic: boolean; ttfUrl: string }[] = [];\n const faceRe = /@font-face\\s*\\{([^}]*)\\}/g;\n let m: RegExpExecArray | null;\n while ((m = faceRe.exec(css)) !== null) {\n const block = m[1];\n // Pin the CDN: only accept URLs whose hostname is fonts.gstatic.com so a\n // hijacked/mitm'd CSS response can't redirect downloads to arbitrary hosts.\n const urlM = block.match(\n /src:\\s*url\\((https:\\/\\/fonts\\.gstatic\\.com\\/[^)]+\\.ttf)\\)/\n );\n if (!urlM) continue;\n const weightM = block.match(/font-weight:\\s*(\\d+)/);\n const italicM = block.match(/font-style:\\s*italic/);\n out.push({\n weight: weightM ? parseInt(weightM[1], 10) : 400,\n italic: Boolean(italicM),\n ttfUrl: urlM[1],\n });\n }\n return out;\n}\n\nfunction cacheKey(family: string, weight: number, italic: boolean): string {\n return `google|${family}|${weight}|${italic ? 'i' : 'r'}`;\n}\n\nexport async function fetchGoogleFontSources(\n opts: GoogleFetchOptions\n): Promise<GoogleFetchResult> {\n const weights = opts.weights?.length ? opts.weights : [400, 700];\n const italics = opts.italics ?? false;\n const warnings: string[] = [];\n const sources: ResolvedFontSource[] = [];\n\n // Try every (weight, italic) combo — first against caches, then via fetch.\n const wanted: { weight: number; italic: boolean }[] = [];\n for (const w of weights) {\n wanted.push({ weight: w, italic: false });\n if (italics) wanted.push({ weight: w, italic: true });\n }\n\n // Resolve any cache hits first.\n const pending: { weight: number; italic: boolean }[] = [];\n for (const w of wanted) {\n const key = cacheKey(opts.family, w.weight, w.italic);\n const mem = opts.memoryCache?.get(key);\n if (mem) {\n sources.push({\n data: mem,\n weight: w.weight,\n italic: w.italic,\n format: detectFontFormat(mem),\n });\n continue;\n }\n const disk = await opts.diskCache?.get(key);\n if (disk) {\n opts.memoryCache?.set(key, disk);\n sources.push({\n data: disk,\n weight: w.weight,\n italic: w.italic,\n format: detectFontFormat(disk),\n });\n continue;\n }\n pending.push(w);\n }\n\n if (pending.length === 0) {\n return { sources, warnings };\n }\n\n // Single CSS request covers all pending variants.\n const needItalics = pending.some((p) => p.italic);\n const cssUrl = buildCssUrl(\n opts.family,\n Array.from(new Set(pending.map((p) => p.weight))),\n needItalics\n );\n let faces: { weight: number; italic: boolean; ttfUrl: string }[];\n try {\n const cssRes = await fetchWithTimeout(cssUrl, {\n headers: { 'User-Agent': TTF_UA },\n timeoutMs: opts.fetchTimeoutMs,\n fetcher: opts.fetcher,\n });\n if (!cssRes.ok) {\n warnings.push(\n `Google Fonts CSS fetch for \"${opts.family}\" returned ${cssRes.status}`\n );\n return { sources, warnings };\n }\n const css = await cssRes.text();\n faces = parseCssFaces(css);\n } catch (err) {\n warnings.push(\n `Google Fonts CSS fetch for \"${opts.family}\" failed: ${\n (err as Error).message\n }`\n );\n return { sources, warnings };\n }\n\n for (const need of pending) {\n const match = faces.find(\n (f) => f.weight === need.weight && f.italic === need.italic\n );\n if (!match) {\n warnings.push(\n `Google Fonts \"${opts.family}\" missing weight ${need.weight}${\n need.italic ? ' italic' : ''\n }`\n );\n continue;\n }\n try {\n const res = await fetchWithTimeout(match.ttfUrl, {\n timeoutMs: opts.fetchTimeoutMs,\n fetcher: opts.fetcher,\n });\n if (!res.ok) {\n warnings.push(\n `Google Fonts TTF fetch for \"${opts.family}\" ${need.weight} returned ${res.status}`\n );\n continue;\n }\n const ab = await res.arrayBuffer();\n // Metadata validation (weight class, name-table defects, fsType) runs\n // centrally in FontRegistry.materializeEntry so file/data/url/google\n // sources are all checked under one code path.\n const buf = Buffer.from(ab);\n const key = cacheKey(opts.family, need.weight, need.italic);\n opts.memoryCache?.set(key, buf);\n await opts.diskCache?.set(key, buf);\n sources.push({\n data: buf,\n weight: need.weight,\n italic: need.italic,\n format: detectFontFormat(buf),\n });\n } catch (err) {\n warnings.push(\n `Google Fonts TTF fetch for \"${opts.family}\" ${need.weight} failed: ${\n (err as Error).message\n }`\n );\n }\n }\n\n return { sources, warnings };\n}\n","/**\n * Direct-URL font fetcher. Downloads a single TTF/OTF from an HTTPS URL and\n * returns it as a `ResolvedFontSource`. Cache-keyed the same way as the\n * Google Fonts fetcher so fetches are deduplicated across generations.\n *\n * Used as an escape hatch for families whose Google Fonts redistribution has\n * known defects (e.g. Inter's static Thin/ExtraLight shipping with a broken\n * `OS/2.usWeightClass`). The `UPSTREAM_OVERRIDES` catalog points affected\n * families at clean upstream sources like rsms/inter via jsDelivr.\n */\n\nimport type { ResolvedFontSource } from '../types';\nimport { detectFontFormat } from './format';\nimport { isAllowedFontUrl } from './url-allowlist';\n\nexport interface UrlFetchOptions {\n url: string;\n weight: number;\n italic: boolean;\n fetchTimeoutMs?: number;\n fetcher?: typeof fetch;\n memoryCache?: {\n get(key: string): Buffer | undefined;\n set(key: string, value: Buffer): void;\n };\n diskCache?: {\n get(key: string): Promise<Buffer | undefined>;\n set(key: string, value: Buffer): Promise<void>;\n };\n}\n\nfunction cacheKey(url: string, weight: number, italic: boolean): string {\n return `url|${url}|${weight}|${italic ? 'i' : 'r'}`;\n}\n\nexport async function fetchUrlFontSource(\n opts: UrlFetchOptions\n): Promise<{ source?: ResolvedFontSource; warnings?: string[] }> {\n if (!isAllowedFontUrl(opts.url)) {\n return {\n warnings: [\n `URL font fetch rejected (host not in allowlist or non-HTTPS): ${opts.url}`,\n ],\n };\n }\n const key = cacheKey(opts.url, opts.weight, opts.italic);\n const mem = opts.memoryCache?.get(key);\n if (mem) {\n return {\n source: {\n data: mem,\n weight: opts.weight,\n italic: opts.italic,\n format: detectFontFormat(mem),\n },\n warnings: [],\n };\n }\n const disk = await opts.diskCache?.get(key);\n if (disk) {\n opts.memoryCache?.set(key, disk);\n return {\n source: {\n data: disk,\n weight: opts.weight,\n italic: opts.italic,\n format: detectFontFormat(disk),\n },\n warnings: [],\n };\n }\n\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), opts.fetchTimeoutMs ?? 10000);\n try {\n const f = opts.fetcher ?? fetch;\n // redirect: 'manual' prevents the allowlist from being bypassed via\n // a 3xx Location pointing at an off-list host. We re-validate the\n // Location header against the allowlist before following.\n let res = await f(opts.url, { signal: ctrl.signal, redirect: 'manual' });\n let hops = 0;\n while (res.status >= 300 && res.status < 400 && res.status !== 304) {\n const next = res.headers.get('location');\n if (!next) {\n return {\n warnings: [\n `URL font fetch \"${opts.url}\" ${res.status} with no Location header`,\n ],\n };\n }\n const resolved = new URL(next, opts.url).toString();\n if (!isAllowedFontUrl(resolved)) {\n return {\n warnings: [\n `URL font fetch \"${opts.url}\" redirected to disallowed host: ${resolved}`,\n ],\n };\n }\n if (++hops > 3) {\n return {\n warnings: [`URL font fetch \"${opts.url}\" too many redirects`],\n };\n }\n res = await f(resolved, { signal: ctrl.signal, redirect: 'manual' });\n }\n if (!res.ok) {\n return {\n warnings: [`URL font fetch \"${opts.url}\" returned ${res.status}`],\n };\n }\n const ab = await res.arrayBuffer();\n const raw = Buffer.from(ab);\n // Reject obvious non-font responses — e.g. jsDelivr 404 HTML, 200 OK\n // redirect pages, or aliased directory listings. Without this check the\n // bytes would sail through to the embed step and corrupt the output.\n const format = detectFontFormat(raw);\n if (format === 'unknown' || raw.length < 512) {\n return {\n warnings: [\n `URL font fetch \"${opts.url}\" returned ${raw.length} bytes of ${format} — not a TTF/OTF. Skipping.`,\n ],\n };\n }\n // WOFF/WOFF2 flow through: Office output never embeds bytes; the\n // LibreOffice preview stager handles them via fontconfig.\n // Metadata validation runs centrally in FontRegistry.materializeEntry.\n const buf = raw;\n opts.memoryCache?.set(key, buf);\n await opts.diskCache?.set(key, buf);\n return {\n source: {\n data: buf,\n weight: opts.weight,\n italic: opts.italic,\n format,\n },\n warnings: [],\n };\n } catch (err) {\n return {\n warnings: [\n `URL font fetch \"${opts.url}\" failed: ${(err as Error).message}`,\n ],\n };\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Post-fetch metadata validation for TTF/OTF bytes. Catches the three known\n * classes of defects that surface in Google Fonts' redistribution pipeline:\n *\n * 1. Wrong `OS/2.usWeightClass` (Chivo Light, Mada Regular, Petrona)\n * 2. Duplicate usWeightClass across weights (Exo Thin/ExtraLight)\n * 3. Non-unique `name` subfamily records (Inter, Manrope, Recursive)\n * 4. A family name that isn't the one we resolved the bytes as — an\n * instanced `InterVariable.ttf` still calls itself \"Inter Variable\", a\n * vendor CDN static may call itself anything at all\n *\n * We don't throw on mismatch — the pipeline has already tried to fix the\n * bytes where it can (`rewriteFontSubfamilyNames` after variable-font\n * instancing; `rewriteFontFamilyName` at preview staging). The validator\n * returns human-readable diagnostics so the caller can emit warnings tagged\n * `FONT_METADATA_DEFECT`, pointing users at the upstream override escape\n * hatch before they ship a broken document.\n */\n\nimport {\n readFontFamilyNames,\n readNameRecords,\n standardSubfamilyNames,\n} from './ttf-name';\n\nconst HEADER_SIZE = 12;\nconst TABLE_RECORD_SIZE = 16;\n\nfunction readTable(\n ttf: Buffer,\n tag: string\n): { off: number; len: number } | null {\n if (ttf.length < HEADER_SIZE) return null;\n const version = ttf.readUInt32BE(0);\n if (version !== 0x00010000 && version !== 0x4f54544f) return null;\n const numTables = ttf.readUInt16BE(4);\n for (let i = 0; i < numTables; i++) {\n const r = HEADER_SIZE + i * TABLE_RECORD_SIZE;\n if (r + TABLE_RECORD_SIZE > ttf.length) return null;\n if (ttf.toString('ascii', r, r + 4) === tag) {\n return { off: ttf.readUInt32BE(r + 8), len: ttf.readUInt32BE(r + 12) };\n }\n }\n return null;\n}\n\nfunction readUsWeightClass(ttf: Buffer): number | null {\n const os2 = readTable(ttf, 'OS/2');\n if (!os2) return null;\n if (os2.off + 6 > ttf.length) return null;\n return ttf.readUInt16BE(os2.off + 4);\n}\n\nexport interface FontMetadataDiagnostic {\n code:\n | 'WEIGHT_CLASS_MISMATCH'\n | 'SUBFAMILY_MISMATCH'\n | 'LEGACY_SUBFAMILY_MISMATCH'\n | 'FAMILY_MISMATCH';\n message: string;\n}\n\n/**\n * Inspect a font's metadata against the weight + italic we asked it to\n * represent. Returns one diagnostic per detected defect.\n */\nexport function validateFontMetadata(\n ttf: Buffer,\n weight: number,\n italic: boolean,\n familyLabel: string\n): FontMetadataDiagnostic[] {\n const diags: FontMetadataDiagnostic[] = [];\n const usWeight = readUsWeightClass(ttf);\n if (usWeight != null && usWeight !== weight) {\n diags.push({\n code: 'WEIGHT_CLASS_MISMATCH',\n message: `Font \"${familyLabel}\" weight ${weight}: OS/2.usWeightClass reports ${usWeight}. Likely a defective redistribution — consider adding an upstream override.`,\n });\n }\n\n // OS/2.fsType (embedding-permission bits) deliberately NOT checked. Office\n // output never embeds font bytes anymore — substitute mode rewrites to\n // SAFE_FONTS, custom mode ships references as-is, and the LibreOffice\n // preview stager only registers bytes transiently with the converter's\n // child process. Permission warnings would be pure noise for every\n // Google Fonts resolution.\n\n // The bytes must answer to the family they were resolved as, or nothing\n // downstream can find them: a run says `rFonts w:ascii=\"Inter\"` and the\n // host matches that against the font's own name table, never against the\n // registry entry or the filename. `FontRegistry` repairs this before\n // validating, so reaching here means the repair could not run (no name\n // table, a format-1 one, non-sfnt bytes) — i.e. the face really will be\n // unreachable under `familyLabel`.\n const declaredFamilies = readFontFamilyNames(ttf);\n if (\n declaredFamilies.length > 0 &&\n !declaredFamilies.includes(familyLabel.trim())\n ) {\n diags.push({\n code: 'FAMILY_MISMATCH',\n message: `Font \"${familyLabel}\" weight ${weight}${italic ? ' italic' : ''}: name table declares ${declaredFamilies\n .map((f) => `\"${f}\"`)\n .join(\n ' / '\n )}, not \"${familyLabel}\". Referencing runs will not resolve this face.`,\n });\n }\n\n const std = standardSubfamilyNames(weight, italic);\n if (!std) return diags;\n const expected17 = std.typographic;\n const expected2 = std.legacy;\n\n const names = readNameRecords(ttf, new Set([2, 17]));\n for (const n of names) {\n if (n.nameID === 17 && n.value !== expected17) {\n diags.push({\n code: 'SUBFAMILY_MISMATCH',\n message: `Font \"${familyLabel}\" weight ${weight}${italic ? ' italic' : ''}: name record (platform ${n.platformID}) nameID 17 = \"${n.value}\", expected \"${expected17}\".`,\n });\n }\n if (n.nameID === 2 && n.value !== expected2) {\n diags.push({\n code: 'LEGACY_SUBFAMILY_MISMATCH',\n message: `Font \"${familyLabel}\" weight ${weight}${italic ? ' italic' : ''}: name record (platform ${n.platformID}) nameID 2 = \"${n.value}\", expected \"${expected2}\".`,\n });\n }\n }\n return diags;\n}\n","/**\n * Structural sanity check for TTF/OTF bytes — can a font system load this at\n * all? Answered before `validateFontMetadata`, which asks the narrower\n * question of whether a loadable font's metadata says the right things.\n *\n * The gap this closes: `detectFontFormat` classifies by the four magic bytes\n * alone, so a download truncated anywhere after byte four is still 'ttf' and\n * flows on as if it were a font. Nothing downstream notices. The metadata\n * validator has no name records to check and usually no readable OS/2\n * either, so it stays silent by design; `FontRegistry`'s family stamp finds\n * no declared family to contradict and no-ops; and the bytes stage as a\n * `.ttf` that fontconfig and Core Text refuse, so the document renders in a\n * fallback face with nothing anywhere saying why.\n *\n * Deliberately NOT a full sfnt parser. It answers \"will this load\", not \"is\n * this well-formed\" — checksums, table-specific contents and glyph data are\n * out of scope. Every check here is one a font system performs before it can\n * index a face at all, which is what makes a failure worth a warning rather\n * than a matter of taste.\n */\n\nimport { readNameRecords } from './ttf-name';\n\nexport interface FontStructureDiagnostic {\n code: 'FONT_UNREADABLE';\n message: string;\n}\n\n/** sfnt versions a font system will attempt to load. */\nconst SFNT_VERSIONS = new Set<number>([\n 0x00010000, // TrueType outlines\n 0x4f54544f, // 'OTTO' — CFF outlines\n 0x74727565, // 'true'\n 0x74797031, // 'typ1'\n]);\n\nconst HEADER_SIZE = 12;\nconst TABLE_RECORD_SIZE = 16;\n\n/**\n * Inspect the sfnt envelope of a font we are about to hand to a font system.\n * Returns the first thing that makes it unloadable, or null.\n *\n * One diagnostic, not a list: past the first structural failure every later\n * check is reading rubble, and a caller can only act on the file as a whole\n * anyway.\n */\nexport function validateFontStructure(\n ttf: Buffer,\n weight: number,\n italic: boolean,\n familyLabel: string\n): FontStructureDiagnostic | null {\n const face = `Font \"${familyLabel}\" weight ${weight}${italic ? ' italic' : ''}`;\n const unreadable = (reason: string): FontStructureDiagnostic => ({\n code: 'FONT_UNREADABLE',\n message: `${face}: ${reason} The face will not resolve; text referencing it renders in a fallback.`,\n });\n\n if (ttf.length < HEADER_SIZE) {\n return unreadable(\n `${ttf.length} bytes is shorter than an sfnt header — the download is truncated or empty.`\n );\n }\n const version = ttf.readUInt32BE(0);\n if (!SFNT_VERSIONS.has(version)) {\n return unreadable(\n `sfnt version 0x${version.toString(16).padStart(8, '0')} is neither TrueType nor OpenType.`\n );\n }\n\n const numTables = ttf.readUInt16BE(4);\n if (numTables === 0) return unreadable('its table directory is empty.');\n const directoryEnd = HEADER_SIZE + numTables * TABLE_RECORD_SIZE;\n if (directoryEnd > ttf.length) {\n return unreadable(\n `its directory claims ${numTables} tables (${directoryEnd} bytes) but the file is ${ttf.length} bytes — truncated.`\n );\n }\n\n // Directory offsets in range. A table pointing past the end is the shape a\n // truncated download takes once it keeps enough bytes for the directory.\n const tags = new Set<string>();\n for (let i = 0; i < numTables; i += 1) {\n const ro = HEADER_SIZE + i * TABLE_RECORD_SIZE;\n const tag = ttf.toString('ascii', ro, ro + 4);\n const offset = ttf.readUInt32BE(ro + 8);\n const length = ttf.readUInt32BE(ro + 12);\n if (offset + length > ttf.length) {\n return unreadable(\n `its \"${tag}\" table runs to byte ${offset + length} but the file is ${ttf.length} bytes — truncated.`\n );\n }\n tags.add(tag);\n }\n\n // `name` carries the family every consumer looks a face up by, and `head`\n // the units-per-em every consumer scales it with. Neither is optional.\n for (const required of ['name', 'head']) {\n if (!tags.has(required)) {\n return unreadable(`it has no \"${required}\" table.`);\n }\n }\n\n // Outlines: glyf + loca (TrueType) or a CFF table (OpenType). Without them\n // there is nothing to draw, whatever else the file carries.\n const hasTrueTypeOutlines = tags.has('glyf') && tags.has('loca');\n const hasCffOutlines = tags.has('CFF ') || tags.has('CFF2');\n if (!hasTrueTypeOutlines && !hasCffOutlines) {\n return unreadable(\n 'it carries no glyph outlines (neither \"glyf\" + \"loca\" nor \"CFF \").'\n );\n }\n\n // Present is not the same as readable: the reader bounds every record by\n // the table's own extent, so a `name` table with a corrupt header or\n // out-of-range string offsets yields nothing and the face is unindexable.\n if (readNameRecords(ttf).length === 0) {\n return unreadable('its \"name\" table carries no readable records.');\n }\n\n return null;\n}\n","/**\n * In-process LRU cache for resolved font buffers.\n * Scoped to a single process — do not share across requests on a server.\n */\n\nexport interface MemoryCacheOptions {\n /** Approximate soft cap in bytes. LRU-evict when exceeded. */\n maxBytes?: number;\n}\n\nexport class FontMemoryCache {\n private readonly store = new Map<string, Buffer>();\n private bytes = 0;\n private readonly maxBytes: number;\n\n constructor(opts: MemoryCacheOptions = {}) {\n this.maxBytes = opts.maxBytes ?? 20 * 1024 * 1024; // 20 MB default\n }\n\n get(key: string): Buffer | undefined {\n const v = this.store.get(key);\n if (!v) return undefined;\n // Refresh LRU position.\n this.store.delete(key);\n this.store.set(key, v);\n return v;\n }\n\n set(key: string, value: Buffer): void {\n const existing = this.store.get(key);\n if (existing) this.bytes -= existing.byteLength;\n this.store.set(key, value);\n this.bytes += value.byteLength;\n while (this.bytes > this.maxBytes && this.store.size > 0) {\n const oldest = this.store.keys().next().value as string | undefined;\n if (!oldest) break;\n const removed = this.store.get(oldest);\n this.store.delete(oldest);\n if (removed) this.bytes -= removed.byteLength;\n }\n }\n\n size(): number {\n return this.store.size;\n }\n}\n","/**\n * FontRegistry — merges catalog + document registry + runtime entries\n * and materializes referenced fonts into ResolvedFont records.\n *\n * Resolution rules, per referenced name:\n * 1. Registry match (by family or id, case-insensitive). Runtime entries win\n * on collision with document entries. Materialize each source.\n * 2. SAFE_FONTS membership → empty sources.\n * 3. Otherwise → empty sources with FONT_UNRESOLVED warning.\n */\n\nimport { isSafeFont } from '../schemas/font-catalog';\nimport type { FontRegistryEntry, FontSource } from '../schemas/font-catalog';\nimport type {\n FontRuntimeOpts,\n ResolvedFont,\n ResolvedFontSource,\n} from './types';\nimport { loadDataFontSource } from './sources/data-loader';\nimport { fetchGoogleFontSources } from './sources/google-fetcher';\nimport { fetchUrlFontSource } from './sources/url-fetcher';\nimport { validateFontMetadata } from './sources/ttf-validate';\nimport { validateFontStructure } from './sources/ttf-structure';\nimport {\n readFontFamilyNames,\n rewriteFontFamilyName,\n standardSubfamilyNames,\n} from './sources/ttf-name';\nimport { FontMemoryCache } from './cache/memory-cache';\n\n/**\n * Minimal interface the registry needs from a disk cache. The concrete\n * implementation ships in `./cache/disk-cache` but is Node-only (uses fs/crypto).\n * Callers on Node inject an instance; browser callers pass nothing.\n */\nexport interface FontDiskCacheLike {\n get(key: string): Promise<Buffer | undefined>;\n set(key: string, value: Buffer): Promise<void>;\n}\n\n/**\n * Minimal interface for a file-loader. Same reasoning as FontDiskCacheLike:\n * concrete impl is Node-only, callers inject when on Node.\n */\nexport type FontFileLoader = (input: {\n path: string;\n weight?: number;\n italic?: boolean;\n baseDir?: string;\n}) => Promise<ResolvedFontSource>;\n\n/**\n * Minimal interface for the variable-font fetcher. `subset-font` (the\n * harfbuzz-wasm wrapper we use for axis pinning) reaches for `fs` at\n * init time, which crashes in the browser. Injection keeps that import\n * behind the Node-only subpath; browser bundles never pull it in, and\n * browser callers simply won't see `kind: 'variable'` fonts resolved\n * (the registry warns and skips instead).\n */\nexport type FontVariableLoader = (input: {\n url: string;\n weight: number;\n italic: boolean;\n axes?: Record<string, number>;\n fetchTimeoutMs?: number;\n memoryCache?: {\n get(key: string): Buffer | undefined;\n set(key: string, value: Buffer): void;\n };\n diskCache?: {\n get(key: string): Promise<Buffer | undefined>;\n set(key: string, value: Buffer): Promise<void>;\n };\n}) => Promise<{ source?: ResolvedFontSource; warnings?: string[] }>;\n\nexport interface FontRegistryInput {\n /** Runtime options — entries come from opts.extraEntries. */\n opts?: FontRuntimeOpts;\n /** Optional disk cache (Node only). Pass an instance of FontDiskCache. */\n diskCache?: FontDiskCacheLike;\n /**\n * Optional `kind: \"file\"` loader (Node only). Inject `loadFileFontSource`\n * from `@json-to-office/shared/fonts/sources/file-loader` on Node. Browser\n * callers pass nothing; `kind: \"file\"` sources then warn and skip.\n */\n fileLoader?: FontFileLoader;\n /**\n * Optional `kind: \"variable\"` loader (Node only). Inject\n * `fetchVariableFontSource` from `@json-to-office/shared/fonts/node` on\n * Node. Browser callers pass nothing; `kind: \"variable\"` sources then\n * warn and skip. Keeping this injected avoids dragging subset-font (and\n * its `fs.promises.readFile` bootstrap) into client bundles.\n */\n variableLoader?: FontVariableLoader;\n}\n\n/**\n * Make the bytes declare the family they were resolved as.\n *\n * `ResolvedFont.family` is a claim about the bytes that every consumer\n * relies on and that nothing used to enforce. A host — Core Text,\n * fontconfig, GDI — finds a face by the family in its `name` table, never\n * by the registry entry or the filename, so a source whose name table says\n * something else is unreachable from the runs that reference it. It fails\n * silently: on a machine that happens to have the real family installed the\n * reference lands there instead, and only a host without it (a container,\n * a colleague's laptop) shows the fallback.\n *\n * The case that forced this: Inter resolves through an upstream override\n * that instances `InterVariable.ttf` per weight, and harfbuzz keeps the\n * master's name table — so every instance called itself \"Inter Variable\".\n * The weighted faces were saved by the preview stager renaming them to\n * \"Inter Medium\" / \"Inter SemiBold\" on the way out; weights 400 and 700\n * kept the family name unchanged (they ride the run's bold/italic toggles\n * instead), so those alone were staged under a name no run asks for.\n *\n * Matching on ANY declared name (family or typographic family) keeps a\n * legitimately-named static untouched: LifeSans-Medium.ttf registered as\n * \"Life Sans\" already answers to it via nameID 16, even though nameID 1\n * says \"Life Sans Medium\". Only bytes that answer to nothing get rewritten.\n */\nfunction stampResolvedFamily(\n source: ResolvedFontSource,\n family: string\n): ResolvedFontSource {\n if (source.format !== 'ttf' && source.format !== 'otf') return source;\n const declared = readFontFamilyNames(source.data);\n // Nothing declared: no claim to contradict, and nothing to repair against.\n if (declared.length === 0 || declared.includes(family)) return source;\n // The style this face occupies within `family`. The family IDs become\n // `family` for all four RIBBI faces, so full/PostScript names have to\n // carry the style or roman and italic collide on both.\n const subfamily = standardSubfamilyNames(\n source.weight,\n source.italic\n )?.legacy;\n return {\n ...source,\n data: rewriteFontFamilyName(source.data, family, subfamily),\n };\n}\n\nexport class FontRegistry {\n private readonly index: Map<string, FontRegistryEntry>;\n private readonly cache: Map<string, ResolvedFont>;\n private readonly opts: FontRuntimeOpts;\n private readonly memoryCache: FontMemoryCache;\n private readonly diskCache: FontDiskCacheLike | undefined;\n private readonly fileLoader: FontFileLoader | undefined;\n private readonly variableLoader: FontVariableLoader | undefined;\n\n constructor(input: FontRegistryInput = {}) {\n this.opts = input.opts ?? {};\n this.index = new Map();\n this.cache = new Map();\n this.memoryCache = new FontMemoryCache();\n this.diskCache = input.diskCache;\n this.fileLoader = input.fileLoader;\n this.variableLoader = input.variableLoader;\n\n for (const e of this.opts.extraEntries ?? []) this.addEntry(e);\n }\n\n private addEntry(entry: FontRegistryEntry): void {\n this.index.set(entry.family.toLowerCase(), entry);\n this.index.set(entry.id.toLowerCase(), entry);\n }\n\n /** Resolve every referenced name in one pass. Order preserved. */\n async resolveMany(names: Iterable<string>): Promise<ResolvedFont[]> {\n const out: ResolvedFont[] = [];\n for (const n of names) out.push(await this.resolve(n));\n return out;\n }\n\n async resolve(name: string): Promise<ResolvedFont> {\n const key = name.toLowerCase();\n const cached = this.cache.get(key);\n if (cached) return cached;\n\n const entry = this.index.get(key);\n let result: ResolvedFont;\n\n if (entry) {\n result = await this.materializeEntry(entry);\n } else if (isSafeFont(name)) {\n result = { family: name, sources: [], warnings: [] };\n } else {\n result = {\n family: name,\n sources: [],\n warnings: [\n `Font \"${name}\" is not registered and not in SAFE_FONTS; will rely on host fallback.`,\n ],\n };\n }\n this.cache.set(key, result);\n return result;\n }\n\n private async materializeEntry(\n entry: FontRegistryEntry\n ): Promise<ResolvedFont> {\n const sources: ResolvedFontSource[] = [];\n const warnings: string[] = [];\n\n for (const source of entry.sources) {\n try {\n const materialized = await this.materializeSource(source, warnings);\n for (const raw of materialized) {\n const sfnt = raw.format === 'ttf' || raw.format === 'otf';\n // Can a font system load these bytes at all? Asked first, and on\n // failure asked instead of everything below: the stamp has no name\n // table to write into and the metadata checks no records to read,\n // so both would quietly do nothing and report nothing. The source\n // is still returned — this diagnoses the file, it doesn't decide\n // for the caller whether to ship it.\n const broken = sfnt\n ? validateFontStructure(\n raw.data,\n raw.weight,\n raw.italic,\n entry.family\n )\n : null;\n if (broken) {\n warnings.push(`[${broken.code}] ${broken.message}`);\n sources.push(raw);\n continue;\n }\n const s = stampResolvedFamily(raw, entry.family);\n if (sfnt) {\n for (const d of validateFontMetadata(\n s.data,\n s.weight,\n s.italic,\n entry.family\n )) {\n warnings.push(`[FONT_METADATA_DEFECT:${d.code}] ${d.message}`);\n }\n }\n sources.push(s);\n }\n } catch (err) {\n warnings.push(\n `Font \"${entry.family}\" source (${source.kind}) failed: ${\n (err as Error).message\n }`\n );\n }\n }\n\n return {\n family: entry.family,\n sources,\n warnings,\n };\n }\n\n private async materializeSource(\n source: FontSource,\n warnings: string[]\n ): Promise<ResolvedFontSource[]> {\n switch (source.kind) {\n case 'safe':\n // System-installed; no embedding data.\n return [];\n case 'file': {\n if (!this.fileLoader) {\n warnings.push(\n `kind:\"file\" source for \"${source.path}\" requires a fileLoader (Node-only); skipping.`\n );\n return [];\n }\n return [\n await this.fileLoader({\n path: source.path,\n weight: source.weight,\n italic: source.italic,\n baseDir: this.opts.baseDir,\n }),\n ];\n }\n case 'data':\n return [\n loadDataFontSource({\n data: source.data,\n weight: source.weight,\n italic: source.italic,\n }),\n ];\n case 'google': {\n const gf = this.opts.googleFonts;\n if (gf?.enabled === false) {\n warnings.push(\n `Google Fonts fetch disabled — skipping \"${source.family}\".`\n );\n return [];\n }\n const { sources: fetched, warnings: fetchWarnings } =\n await fetchGoogleFontSources({\n family: source.family,\n weights: source.weights ?? [400, 700],\n italics: source.italics ?? false,\n memoryCache: this.memoryCache,\n diskCache: this.diskCache,\n fetchTimeoutMs: gf?.fetchTimeoutMs,\n });\n warnings.push(...fetchWarnings);\n return fetched;\n }\n case 'url': {\n const gf = this.opts.googleFonts;\n const { source: fetched, warnings: fetchWarnings } =\n await fetchUrlFontSource({\n url: source.url,\n weight: source.weight ?? 400,\n italic: source.italic ?? false,\n memoryCache: this.memoryCache,\n diskCache: this.diskCache,\n fetchTimeoutMs: gf?.fetchTimeoutMs,\n });\n if (fetchWarnings) warnings.push(...fetchWarnings);\n return fetched ? [fetched] : [];\n }\n case 'variable': {\n // Variable-font instancing: fetch the variable TTF once (disk-\n // cached), then harfbuzz-pin the `wght` axis to produce a clean\n // static for this weight. Requires a Node-injected loader because\n // `subset-font` pulls in `fs` at init; without it, browser\n // bundles would break. Callers on Node pass `fetchVariableFontSource`\n // from `@json-to-office/shared/fonts/node`.\n if (!this.variableLoader) {\n warnings.push(\n `kind:\"variable\" source for \"${source.url}\" requires a variableLoader (Node-only); skipping.`\n );\n return [];\n }\n const gf = this.opts.googleFonts;\n const { source: fetched, warnings: fetchWarnings } =\n await this.variableLoader({\n url: source.url,\n weight: source.weight,\n italic: source.italic ?? false,\n axes: source.axes,\n memoryCache: this.memoryCache,\n diskCache: this.diskCache,\n fetchTimeoutMs: gf?.fetchTimeoutMs,\n });\n if (fetchWarnings) warnings.push(...fetchWarnings);\n return fetched ? [fetched] : [];\n }\n default:\n // Exhaustiveness guard — new kind added to schema without handler\n throw new Error(\n `Unknown font source kind: ${(source as { kind: string }).kind}`\n );\n }\n }\n}\n","/**\n * Curated list of popular Google Fonts for picker autocomplete.\n *\n * Not exhaustive — the full Google Fonts library has ~1500 families.\n * This is ~37 names known to cover most real-world use cases.\n */\n\nexport interface PopularGoogleFont {\n family: string;\n category: 'sans' | 'serif' | 'mono' | 'display' | 'handwriting';\n /** Weights available on Google Fonts for this family. */\n weights: number[];\n /** Whether italic variants exist. */\n hasItalic: boolean;\n}\n\nexport const POPULAR_GOOGLE_FONTS: readonly PopularGoogleFont[] = [\n // Sans-serif\n {\n family: 'Inter',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: false,\n },\n {\n family: 'Roboto',\n category: 'sans',\n weights: [100, 300, 400, 500, 700, 900],\n hasItalic: true,\n },\n {\n family: 'Open Sans',\n category: 'sans',\n weights: [300, 400, 500, 600, 700, 800],\n hasItalic: true,\n },\n {\n family: 'Lato',\n category: 'sans',\n weights: [100, 300, 400, 700, 900],\n hasItalic: true,\n },\n {\n family: 'Montserrat',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Poppins',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Work Sans',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Nunito',\n category: 'sans',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'DM Sans',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Rubik',\n category: 'sans',\n weights: [300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Source Sans 3',\n category: 'sans',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Manrope',\n category: 'sans',\n weights: [200, 300, 400, 500, 600, 700, 800],\n hasItalic: false,\n },\n {\n family: 'Plus Jakarta Sans',\n category: 'sans',\n weights: [200, 300, 400, 500, 600, 700, 800],\n hasItalic: true,\n },\n {\n family: 'IBM Plex Sans',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700],\n hasItalic: true,\n },\n {\n family: 'Archivo',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Geist',\n category: 'sans',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Space Grotesk',\n category: 'sans',\n weights: [300, 400, 500, 600, 700],\n hasItalic: false,\n },\n\n // Serif\n {\n family: 'Playfair Display',\n category: 'serif',\n weights: [400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Merriweather',\n category: 'serif',\n weights: [300, 400, 700, 900],\n hasItalic: true,\n },\n {\n family: 'Lora',\n category: 'serif',\n weights: [400, 500, 600, 700],\n hasItalic: true,\n },\n {\n family: 'Source Serif 4',\n category: 'serif',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'DM Serif Display',\n category: 'serif',\n weights: [400],\n hasItalic: true,\n },\n {\n family: 'Crimson Pro',\n category: 'serif',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Cormorant Garamond',\n category: 'serif',\n weights: [300, 400, 500, 600, 700],\n hasItalic: true,\n },\n\n // Monospace\n {\n family: 'JetBrains Mono',\n category: 'mono',\n weights: [100, 200, 300, 400, 500, 600, 700, 800],\n hasItalic: true,\n },\n {\n family: 'Fira Code',\n category: 'mono',\n weights: [300, 400, 500, 600, 700],\n hasItalic: false,\n },\n {\n family: 'IBM Plex Mono',\n category: 'mono',\n weights: [100, 200, 300, 400, 500, 600, 700],\n hasItalic: true,\n },\n {\n family: 'Source Code Pro',\n category: 'mono',\n weights: [200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n {\n family: 'Space Mono',\n category: 'mono',\n weights: [400, 700],\n hasItalic: true,\n },\n {\n family: 'Geist Mono',\n category: 'mono',\n weights: [100, 200, 300, 400, 500, 600, 700, 800, 900],\n hasItalic: true,\n },\n\n // Display\n {\n family: 'Bebas Neue',\n category: 'display',\n weights: [400],\n hasItalic: false,\n },\n {\n family: 'Abril Fatface',\n category: 'display',\n weights: [400],\n hasItalic: false,\n },\n {\n family: 'Archivo Black',\n category: 'display',\n weights: [400],\n hasItalic: false,\n },\n {\n family: 'Oswald',\n category: 'display',\n weights: [200, 300, 400, 500, 600, 700],\n hasItalic: false,\n },\n\n // Handwriting\n {\n family: 'Caveat',\n category: 'handwriting',\n weights: [400, 500, 600, 700],\n hasItalic: false,\n },\n {\n family: 'Pacifico',\n category: 'handwriting',\n weights: [400],\n hasItalic: false,\n },\n];\n","/**\n * Per-family upstream overrides for popular Google Fonts whose\n * redistribution on fonts.google.com has known defects we can't fix via\n * metadata patching alone.\n *\n * When `autoGoogleFontEntries` hits a family present in this table, it\n * builds override sources instead of issuing `kind: \"google\"` CSS requests.\n * Each entry is either:\n *\n * - `{ kind: \"url\", url, weight, italic? }` — a direct HTTPS TTF/OTF.\n * Use when a clean per-weight static exists on a stable CDN.\n *\n * - `{ kind: \"variable\", url, weight, italic? }` — points at a variable\n * TTF with an `fvar` table. The registry downloads the variable font\n * once and harfbuzz-pins the `wght` axis to the specified weight,\n * producing a clean static TTF. Use when the upstream ships a variable\n * font but no per-weight statics on a CDN (rsms/inter is the\n * canonical example — variable font on jsDelivr, per-weight statics\n * only in GitHub release zips).\n *\n * Pick `variable` over `url` when both are available: the instancer\n * produces per-weight glyph outlines that diverge correctly at every\n * axis value. Google's static redistributions collapse adjacent weights\n * onto the same instance — Inter Thin and ExtraLight both source at\n * ~wght=250 in Google's pipeline, so their static TTFs have 98% identical\n * glyph outlines. Instancing the upstream variable font at exactly wght=100\n * vs wght=200 gives properly distinct geometry.\n *\n * Validate new entries with a HEAD request before adding — the fetchers\n * reject non-TTF responses, but a failed override silently falls back to\n * the Google path, defeating the purpose.\n */\n\n/** One upstream variant source. Type matches the FontSource schema so we\n * can pass the entry directly into `FontRegistry`'s materialize pipeline. */\nexport type UpstreamVariant =\n | {\n kind: 'url';\n url: string;\n weight: number;\n italic?: boolean;\n }\n | {\n kind: 'variable';\n url: string;\n weight: number;\n italic?: boolean;\n /** Extra axis pins merged on top of the derived `wght` pin. */\n axes?: Record<string, number>;\n };\n\nexport interface UpstreamOverride {\n /** Human-readable for logs/diagnostics only. */\n reason: string;\n variants: UpstreamVariant[];\n}\n\n/**\n * rsms/inter publishes the upright variable master as `InterVariable.ttf`\n * on jsDelivr, but the italic master ONLY as `InterVariable-Italic.woff2`\n * — no italic `.ttf` exists under `docs/font-files/` at any tag, so a\n * `.ttf` italic URL 404s and every italic Inter run silently falls back\n * to host defaults. The variable fetcher accepts woff2 sources (fontverter\n * converts to sfnt before instancing), so point at the woff2 directly.\n *\n * We instance each master at every advertised weight so Inter Thin (100),\n * ExtraLight (200), Light (300), Medium (500), SemiBold (600), ExtraBold\n * (800), and Black (900) come out with distinct glyph outlines instead of\n * the near-duplicates Google's static redistribution ships. Regular (400)\n * and Bold (700) from Google were already clean, but instancing them from\n * the same variable font keeps the full family visually consistent.\n *\n * Version pin: `@v4.1` — the last stable rsms/inter release at the time\n * of writing. jsDelivr caches the file aggressively; a version bump here\n * invalidates that cache for users on a subsequent generate.\n */\nconst INTER_VARIABLE_URL =\n 'https://cdn.jsdelivr.net/gh/rsms/inter@v4.1/docs/font-files/InterVariable.ttf';\nconst INTER_VARIABLE_ITALIC_URL =\n 'https://cdn.jsdelivr.net/gh/rsms/inter@v4.1/docs/font-files/InterVariable-Italic.woff2';\n\nfunction interVariants(): UpstreamVariant[] {\n const weights = [100, 200, 300, 400, 500, 600, 700, 800, 900];\n const upright = weights.map((weight) => ({\n kind: 'variable' as const,\n url: INTER_VARIABLE_URL,\n weight,\n italic: false,\n }));\n const italic = weights.map((weight) => ({\n kind: 'variable' as const,\n url: INTER_VARIABLE_ITALIC_URL,\n weight,\n italic: true,\n }));\n return [...upright, ...italic];\n}\n\nexport const UPSTREAM_OVERRIDES: Record<string, UpstreamOverride> = {\n inter: {\n reason:\n \"Google's static Inter Thin/ExtraLight both carry usWeightClass=250 and near-identical glyph outlines (xAvgCharWidth differs by 1.8%); instancing the upstream variable font per weight produces properly distinct statics.\",\n variants: interVariants(),\n },\n};\n\n/** Case-insensitive lookup. Returns undefined when the family has no override. */\nexport function getUpstreamOverride(\n family: string\n): UpstreamOverride | undefined {\n return UPSTREAM_OVERRIDES[family.toLowerCase()];\n}\n","/**\n * Font family substitution: rewrite every non-safe family reference in\n * the doc tree + theme to a SAFE_FONTS equivalent. Used by the\n * `'substitute'` export mode (`FontRuntimeOpts.mode`) so that non-safe\n * fonts (Playfair Display, Inter, …) ship as Georgia/Calibri and the\n * document renders identically on every recipient machine — no embed\n * bytes, no Word-for-Mac intermediate-weight surprises.\n *\n * The walker mirrors the shape used by `collectFontNamesFromDocx/Pptx`\n * so the two stay in sync: whatever `collect` scans, `rewrite` will\n * rewrite. Future component-schema additions that introduce new font\n * keys go in `FONT_NAME_KEYS` / `THEME_FONT_KEYS` once, both sides pick\n * them up.\n */\n\nimport { SAFE_FONTS, isSafeFont } from '../schemas/font-catalog';\nimport { POPULAR_GOOGLE_FONTS } from './catalog/popular-google';\nimport {\n FONT_NAME_KEYS,\n THEME_FONT_KEYS,\n FONT_DECLARATION_KEYS,\n} from './collect';\n\n/** One swap recorded during a rewrite. */\nexport interface FontSubstitution {\n from: string;\n to: string;\n}\n\nexport interface ApplyFontSubstitutionResult<T> {\n doc: T;\n substitutions: FontSubstitution[];\n}\n\n/**\n * Walk a doc tree + swap every non-safe family reference per `mapping`.\n * Returns a new tree (structural clone) plus the list of `(from, to)`\n * swaps made, deduped by source name.\n *\n * One deliberate exception to the clone: `fontRegistry` subtrees are carried\n * through by reference, since they declare fonts rather than reference them\n * and nothing downstream mutates them.\n *\n * Families already in SAFE_FONTS are never rewritten (even if a mapping\n * entry targets them as a key — safe fonts don't need substitution).\n * Families with no mapping entry are left untouched — callers should\n * feed the result of `buildDefaultSubstitutionMap` to ensure every\n * non-safe reference gets a fallback.\n */\nexport function applyFontSubstitution<T>(\n doc: T,\n mapping: Record<string, string>\n): ApplyFontSubstitutionResult<T> {\n const seen = new Map<string, string>();\n const rewritten = rewrite(doc, mapping, seen) as T;\n const substitutions: FontSubstitution[] = [];\n for (const [from, to] of seen) substitutions.push({ from, to });\n return { doc: rewritten, substitutions };\n}\n\nfunction rewrite(\n node: unknown,\n mapping: Record<string, string>,\n seen: Map<string, string>,\n parentKey?: string\n): unknown {\n if (node == null) return node;\n\n if (typeof node === 'string') {\n if (\n parentKey &&\n (FONT_NAME_KEYS.has(parentKey) || THEME_FONT_KEYS.has(parentKey))\n ) {\n return maybeSwap(node, mapping, seen);\n }\n return node;\n }\n\n if (Array.isArray(node)) {\n return node.map((item) => rewrite(item, mapping, seen, parentKey));\n }\n\n if (typeof node === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n // Mirror of collect.ts: a fontRegistry subtree declares families, it\n // does not reference them. Rewriting `entry.family` would rename the\n // registration out from under every reference and key an entry on a\n // SAFE_FONTS name. Carry it through by reference (see the clone note\n // on applyFontSubstitution).\n if (FONT_DECLARATION_KEYS.has(k)) {\n out[k] = v;\n continue;\n }\n // Parallel to collect.ts: `theme.fonts` may hold plain strings\n // keyed by heading/body/mono/light. Those strings are font names\n // and need swapping just like `font.family` does.\n if (\n parentKey === 'theme' &&\n k === 'fonts' &&\n v &&\n typeof v === 'object'\n ) {\n const nextFonts: Record<string, unknown> = {};\n for (const [fk, fv] of Object.entries(v as Record<string, unknown>)) {\n if (typeof fv === 'string') {\n nextFonts[fk] = maybeSwap(fv, mapping, seen);\n } else if (fv && typeof fv === 'object') {\n const fam = (fv as Record<string, unknown>).family;\n nextFonts[fk] =\n typeof fam === 'string'\n ? { ...(fv as object), family: maybeSwap(fam, mapping, seen) }\n : rewrite(fv, mapping, seen, fk);\n } else {\n nextFonts[fk] = fv;\n }\n }\n out[k] = nextFonts;\n continue;\n }\n out[k] = rewrite(v, mapping, seen, k);\n }\n return out;\n }\n\n return node;\n}\n\nfunction maybeSwap(\n name: string,\n mapping: Record<string, string>,\n seen: Map<string, string>\n): string {\n const trimmed = name.trim();\n if (trimmed.length === 0) return name;\n if (isSafeFont(trimmed)) return name;\n // Case-insensitive mapping lookup. Users may feed mappings with\n // slightly different casing than the doc's reference (e.g. \"inter\" vs\n // \"Inter\") — honour the target verbatim, don't force case.\n const lowered = trimmed.toLowerCase();\n for (const [from, to] of Object.entries(mapping)) {\n if (from.toLowerCase() === lowered) {\n seen.set(trimmed, to);\n return to;\n }\n }\n return name;\n}\n\n// ---------------------------------------------------------------------------\n// Default-mapping builder\n// ---------------------------------------------------------------------------\n\n/**\n * Explicit overrides for the most common non-safe fonts we see. Chosen\n * for visual similarity: sans serifs map to Calibri, serifs to Georgia\n * or Cambria depending on axis proportion, monospace to Consolas.\n * Extendable as real usage surfaces more families.\n */\nconst EXPLICIT_OVERRIDES: Record<string, string> = {\n Inter: 'Calibri',\n Roboto: 'Calibri',\n 'Open Sans': 'Calibri',\n Lato: 'Calibri',\n 'Source Sans 3': 'Calibri',\n 'Source Sans Pro': 'Calibri',\n 'IBM Plex Sans': 'Calibri',\n Archivo: 'Calibri',\n Geist: 'Calibri',\n 'Space Grotesk': 'Calibri',\n 'Work Sans': 'Calibri',\n Manrope: 'Calibri',\n Nunito: 'Calibri',\n 'Nunito Sans': 'Calibri',\n Poppins: 'Calibri',\n Montserrat: 'Calibri',\n 'Playfair Display': 'Georgia',\n Merriweather: 'Georgia',\n 'Source Serif 4': 'Cambria',\n 'Source Serif Pro': 'Cambria',\n 'IBM Plex Serif': 'Cambria',\n 'Crimson Pro': 'Cambria',\n Lora: 'Georgia',\n 'PT Serif': 'Georgia',\n 'Cormorant Garamond': 'Cambria',\n 'JetBrains Mono': 'Consolas',\n 'Fira Code': 'Consolas',\n 'IBM Plex Mono': 'Consolas',\n 'Source Code Pro': 'Consolas',\n 'Roboto Mono': 'Consolas',\n 'Geist Mono': 'Consolas',\n};\n\nconst CATEGORY_FALLBACK: Record<string, string> = {\n sans: 'Calibri',\n serif: 'Georgia',\n mono: 'Consolas',\n display: 'Georgia',\n handwriting: 'Segoe UI',\n};\n\n/**\n * Pick the safe-font fallback for a single non-safe family. Precedence:\n * 1. Explicit override in `EXPLICIT_OVERRIDES`.\n * 2. Category lookup in `POPULAR_GOOGLE_FONTS`.\n * 3. Final default (`Calibri`).\n *\n * Exposed for the playground dialog so it can pre-populate the per-family\n * picker with the same defaults the CLI would apply.\n */\nexport function defaultSubstituteFor(family: string): string {\n const trimmed = family.trim();\n // Explicit (case-insensitive).\n for (const [from, to] of Object.entries(EXPLICIT_OVERRIDES)) {\n if (from.toLowerCase() === trimmed.toLowerCase()) return to;\n }\n // Category.\n const catalog = POPULAR_GOOGLE_FONTS.find(\n (f) => f.family.toLowerCase() === trimmed.toLowerCase()\n );\n if (catalog) {\n const cat = CATEGORY_FALLBACK[catalog.category];\n if (cat) return cat;\n }\n return 'Calibri';\n}\n\n/**\n * Build a substitution map for every non-safe family in `referencedNames`.\n * Safe fonts are omitted from the result since they don't need swapping.\n * Caller can override individual entries before passing to\n * `applyFontSubstitution`.\n */\nexport function buildDefaultSubstitutionMap(\n referencedNames: Iterable<string>\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const raw of referencedNames) {\n const name = raw.trim();\n if (name.length === 0) continue;\n if (isSafeFont(name)) continue;\n if (out[name]) continue;\n out[name] = defaultSubstituteFor(name);\n }\n return out;\n}\n\n/** Re-export SAFE_FONTS for dialog/CLI consumers that need the allowlist. */\nexport { SAFE_FONTS };\n\n// ---------------------------------------------------------------------------\n// Export-mode pre-pass\n// ---------------------------------------------------------------------------\n\nimport type { FontRuntimeOpts } from './types';\nimport { collectFontNames } from './collect';\n\nexport interface ApplyExportModeInput<D, T> {\n doc: D;\n theme: T;\n fonts?: FontRuntimeOpts;\n}\n\nexport interface ApplyExportModeWarning {\n code: 'FONT_MODE_CUSTOM' | 'FONT_MODE_SUBSTITUTED';\n message: string;\n}\n\nexport interface ApplyExportModeResult<D, T> {\n doc: D;\n theme: T;\n warnings: ApplyExportModeWarning[];\n}\n\n/**\n * Inspect `fonts.mode` and apply the pre-resolution rewrite for the\n * requested mode.\n *\n * - `'custom'` (default) — no rewrite. Font references stay as authored;\n * recipients need the font installed or Word falls back. The\n * LibreOffice preview stager registers resolved bytes so preview\n * fidelity matches the recipient-side experience when the font is\n * installed.\n * - `'substitute'` — rewrite every non-safe family in doc + theme to its\n * mapped safe equivalent. Fills in defaults via\n * `buildDefaultSubstitutionMap` for any non-safe reference not present\n * in `fonts.substitution`. Emits one `FONT_MODE_SUBSTITUTED` warning\n * listing every swap.\n */\nexport function applyExportMode<D, T>(\n input: ApplyExportModeInput<D, T>\n): ApplyExportModeResult<D, T> {\n const mode = input.fonts?.mode ?? 'custom';\n if (mode === 'custom') {\n // Suppress the advisory entirely when callers never passed a `fonts`\n // option: they opted out of font-mode handling, so noisy per-run\n // warnings would flood existing callers that predate the pipeline.\n if (!input.fonts) {\n return { doc: input.doc, theme: input.theme, warnings: [] };\n }\n // Only emit the advisory when the doc/theme actually references a\n // non-safe family — a safe-only doc has nothing for recipients to be\n // missing, and the warning would be noise.\n const referenced = new Set<string>([\n ...collectFontNames(input.doc),\n ...collectFontNames(input.theme),\n ]);\n const nonSafe = [...referenced].filter((name) => !isSafeFont(name.trim()));\n const warnings: ApplyExportModeWarning[] =\n nonSafe.length > 0\n ? [\n {\n code: 'FONT_MODE_CUSTOM',\n message: `Export mode \"custom\": non-safe font references (${nonSafe.join(', ')}) kept as-is. Recipients need these fonts installed locally; Word falls back to a generic substitute otherwise.`,\n },\n ]\n : [];\n return {\n doc: input.doc,\n theme: input.theme,\n warnings,\n };\n }\n // mode === 'substitute'\n const referenced = new Set<string>([\n ...collectFontNames(input.doc),\n ...collectFontNames(input.theme),\n ]);\n const defaults = buildDefaultSubstitutionMap(referenced);\n const mapping: Record<string, string> = {\n ...defaults,\n ...(input.fonts?.substitution ?? {}),\n };\n\n const docRewrite = applyFontSubstitution(input.doc, mapping);\n const themeRewrite = applyFontSubstitution(input.theme, mapping);\n const combined = new Map<string, string>();\n for (const s of docRewrite.substitutions) combined.set(s.from, s.to);\n for (const s of themeRewrite.substitutions) combined.set(s.from, s.to);\n\n const warnings: ApplyExportModeWarning[] = [];\n if (combined.size > 0) {\n const list = [...combined]\n .map(([from, to]) => `${from} → ${to}`)\n .join(', ');\n warnings.push({\n code: 'FONT_MODE_SUBSTITUTED',\n message: `Export mode \"substitute\": rewrote non-safe families to safe equivalents — ${list}. No fonts embedded; document renders identically on every machine.`,\n });\n }\n return {\n doc: docRewrite.doc,\n theme: themeRewrite.doc,\n warnings,\n };\n}\n","/**\n * Default series-color tokens for charts. Single source of truth for every\n * format: the PPTX `chart` and `highcharts` components and the DOCX\n * `highcharts` component all resolve this list, in this order, against the\n * active theme when the author sets no explicit colors. Both theme schemas\n * declare all six tokens (accent4-6 optional in each), so a theme that fills\n * every slot produces the same palette in a deck and in a document.\n *\n * Slots the theme leaves unset are skipped in both formats: the implicit\n * palette shrinks and the chart library cycles the shorter list rather than\n * repeating `primary` for every empty slot. A theme carrying only\n * primary/secondary/accent — which is what the bundled DOCX themes carry —\n * therefore paints series 4+ identically in a deck and in a document.\n *\n * Skipping compacts holes: a theme defining accent5 but not accent4 yields\n * [primary, secondary, accent, accent5], so accent5 paints series 4. The list\n * is a preference-ordered pool of candidate colors, not fixed per-series slots,\n * so keeping a color the theme did define beats dropping or duplicating one.\n *\n * DOCX legacy slots and both formats' new `palette` roles may name another\n * token. Legacy PPTX `colors` slots accept hex only at validation, though\n * both runtime resolvers walk references to hex before\n * using it, so a chained slot lands on the same color in a deck as in a\n * document. A slot whose value reaches no hex (`\"accent4\": \"nonsense\"`, or a\n * reference cycle) is dropped from the implicit palette in both formats rather\n * than emitted verbatim: PowerPoint and Highcharts both answer an unparseable\n * color with silent black. Parity here covers the token names the two schemas\n * share; each format also has private color keys (DOCX `textSecondary`, PPTX\n * `text2`) that only resolve in their own format.\n *\n * Only the implicit palette skips. An author who names a token explicitly\n * (PPTX `chartColors: ['accent4']`) still gets the `primary` fallback and a\n * warning — naming an undefined token is an authoring error and stays loud.\n * PPTX warns THEME_COLOR_FALLBACK for an unset slot and UNKNOWN_COLOR for one\n * holding an unresolvable value; DOCX throws.\n */\nexport const DEFAULT_CHART_THEME_COLORS = [\n 'primary',\n 'secondary',\n 'accent',\n 'accent4',\n 'accent5',\n 'accent6',\n];\n","/**\n * The document's typography, expressed as Highcharts options.\n *\n * A `highcharts` component is a PNG drawn by a browser that has never seen the\n * document, so nothing about the page's type reaches the chart on its own: the\n * axis labels, title and legend come out in the export server's default face\n * at Highcharts' own sizes, visibly foreign to the prose around them. The\n * palette already carries (see `chart-palette.ts`); this carries the type.\n *\n * Format-neutral on purpose. Each core reads its own theme shape into a\n * `ChartTypography` — family, colours and sizes in document points — and this\n * module turns that into the option paths Highcharts styles text through. An\n * explicit author value keeps winning, property by property, exactly as\n * `options.colors` does.\n *\n * Sizes are converted from points to chart pixels through the scale the chart\n * is placed at: a 900px chart set into a 450pt measure shrinks by half, so a\n * label that must read as 9pt on the page is drawn at 18px.\n */\n\nimport type { RasterizeFontFace } from '../types/services';\nimport type { FontRegistryEntry } from '../schemas/font-catalog';\nimport { themeFontRegistry } from '../fonts/document-registry';\n\nexport interface ChartTypography {\n /** CSS `font-family` for everything not styled otherwise (see `cssFontFamily`). */\n bodyFamily: string;\n /** CSS `font-family` for the chart title. */\n headingFamily: string;\n /** `#RRGGBB` for the title, legend and data labels. */\n textColor: string;\n /** `#RRGGBB` for axis text, subtitle, caption and credits. */\n mutedColor: string;\n /** Axis labels, axis titles, legend, subtitle and data labels, in points. */\n labelPt: number;\n /** Weight for legend items and data labels; Highcharts' own default when unset. */\n labelWeight?: number;\n /** Chart title, in points. */\n titlePt: number;\n /** Chart title weight; Highcharts' own default when unset. */\n titleWeight?: number;\n /** Credits (the source line) and caption, in points. */\n sourcePt: number;\n}\n\n/** Points per CSS pixel at the 96 dpi both formats assume for an unplaced chart. */\nexport const POINTS_PER_PIXEL_96DPI = 0.75;\n\n/**\n * How many document points one chart pixel occupies once the image is placed.\n * Unknown or degenerate widths fall back to 96 dpi, the size an unscaled\n * chart has in both formats.\n */\nexport function chartPointsPerPixel(\n chartWidthPx: number,\n placedWidthPt: number | undefined\n): number {\n if (\n !Number.isFinite(chartWidthPx) ||\n chartWidthPx <= 0 ||\n placedWidthPt === undefined ||\n !Number.isFinite(placedWidthPt) ||\n placedWidthPt <= 0\n ) {\n return POINTS_PER_PIXEL_96DPI;\n }\n return placedWidthPt / chartWidthPx;\n}\n\nconst SERIF_FAMILIES = new Set(['georgia', 'times new roman', 'cambria']);\nconst MONO_FAMILIES = new Set(['consolas', 'courier new', 'menlo', 'monaco']);\n\ntype FontCategory = NonNullable<FontRegistryEntry['category']>;\n\n/**\n * A CSS `font-family` list: the family, quoted, then the generic it belongs\n * to — from the registry category when the font is registered, from the\n * SAFE_FONTS list otherwise — so a face the export server lacks degrades to\n * the right shape rather than to the browser's default.\n */\nexport function cssFontFamily(family: string, category?: FontCategory): string {\n const generic =\n category === 'serif'\n ? 'serif'\n : category === 'mono'\n ? 'monospace'\n : category === 'handwriting'\n ? 'cursive'\n : category === undefined && SERIF_FAMILIES.has(family.toLowerCase())\n ? 'serif'\n : category === undefined && MONO_FAMILIES.has(family.toLowerCase())\n ? 'monospace'\n : 'sans-serif';\n return `\"${family.replace(/[\"\\\\]/g, '\\\\$&')}\", ${generic}`;\n}\n\n/**\n * `cssFontFamily` bound to a theme: a registered family answers with its\n * registry category, an unregistered one with what SAFE_FONTS says of it.\n */\nexport function chartFamilyResolver(\n theme: unknown\n): (family: string) => string {\n const categories = new Map(\n themeFontRegistry(theme).map((entry) => [\n entry.family.toLowerCase(),\n entry.category,\n ])\n );\n return (family) =>\n cssFontFamily(family, categories.get(family.toLowerCase()));\n}\n\ntype Options = Record<string, unknown>;\n\nfunction isPlainObject(value: unknown): value is Options {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * `defaults` beneath `authored`: an authored key is never replaced, and an\n * authored value that is not an object — `null`, `false` — is kept as it is\n * rather than turned into a defaulted object.\n */\nfunction fill(authored: unknown, defaults: Options): unknown {\n if (authored !== undefined && !isPlainObject(authored)) return authored;\n const base: Options = isPlainObject(authored) ? { ...authored } : {};\n for (const [key, value] of Object.entries(defaults)) {\n if (value === undefined) continue;\n const current = base[key];\n if (current === undefined) {\n base[key] = isPlainObject(value) ? fill(undefined, value) : value;\n } else if (isPlainObject(current) && isPlainObject(value)) {\n base[key] = fill(current, value);\n }\n }\n return base;\n}\n\n/** Highcharts axes may be one object or an array of them. */\nfunction fillAxis(authored: unknown, defaults: Options): unknown {\n if (Array.isArray(authored)) {\n return authored.map((axis) => fill(axis, defaults));\n }\n return fill(authored, defaults);\n}\n\nfunction weight(value: number | undefined): string | undefined {\n return value === undefined ? undefined : String(value);\n}\n\n/**\n * The document's typography written into every Highcharts option path that\n * styles text, beneath whatever the author set. `ptPerPx` is the placement\n * scale from `chartPointsPerPixel`.\n */\nexport function withChartTypography<T extends Options>(\n options: T,\n typography: ChartTypography,\n ptPerPx: number\n): T {\n const px = (points: number): string =>\n `${Math.round((points / ptPerPx) * 10) / 10}px`;\n const labelPx = px(typography.labelPt);\n const sourcePx = px(typography.sourcePt);\n const mutedText = { fontSize: labelPx, color: typography.mutedColor };\n const mutedSource = { fontSize: sourcePx, color: typography.mutedColor };\n const labelText = {\n fontSize: labelPx,\n color: typography.textColor,\n fontWeight: weight(typography.labelWeight),\n };\n const axis = { labels: { style: mutedText }, title: { style: mutedText } };\n\n return {\n ...options,\n chart: fill(options.chart, {\n style: { fontFamily: typography.bodyFamily },\n }),\n title: fill(options.title, {\n style: {\n fontFamily: typography.headingFamily,\n fontSize: px(typography.titlePt),\n fontWeight: weight(typography.titleWeight),\n color: typography.textColor,\n },\n }),\n subtitle: fill(options.subtitle, { style: mutedText }),\n caption: fill(options.caption, { style: mutedSource }),\n xAxis: fillAxis(options.xAxis, axis),\n yAxis: fillAxis(options.yAxis, axis),\n legend: fill(options.legend, { itemStyle: labelText }),\n plotOptions: fill(options.plotOptions, {\n series: { dataLabels: { style: labelText } },\n }),\n credits: fill(options.credits, { style: mutedSource }),\n };\n}\n\nconst FONT_FORMATS: Record<\n NonNullable<RasterizeFontFace['format']>,\n { mime: string; format: string }\n> = {\n ttf: { mime: 'font/ttf', format: 'truetype' },\n otf: { mime: 'font/otf', format: 'opentype' },\n woff: { mime: 'font/woff', format: 'woff' },\n woff2: { mime: 'font/woff2', format: 'woff2' },\n};\n\n/**\n * `@font-face` rules for the faces of `families`, inlined as data URIs, so an\n * export server draws a registered font from the same bytes the document\n * stages rather than from whatever its host happens to have installed. The\n * bytes go only to the export server, which already receives every data\n * point of the chart. Empty when no face matches.\n */\nexport function chartFontFaceCss(\n faces: readonly RasterizeFontFace[],\n families: readonly string[]\n): string {\n const wanted = new Set(families.map((family) => family.toLowerCase()));\n return faces\n .filter((face) => wanted.has(face.family.toLowerCase()))\n .map((face) => {\n const { mime, format } = FONT_FORMATS[face.format ?? 'ttf'];\n return (\n `@font-face{font-family:\"${face.family.replace(/[\"\\\\]/g, '\\\\$&')}\";` +\n `font-weight:${face.weight};font-style:${face.italic ? 'italic' : 'normal'};` +\n `src:url(data:${mime};base64,${face.data}) format(\"${format}\")}`\n );\n })\n .join('\\n');\n}\n\n/**\n * The `@font-face` rules for `families` written into a chart's `resources.css`\n * ahead of whatever the author supplied there. Nothing changes when no face\n * matches, so a chart set in safe fonts posts the same request it always did.\n */\nexport function withChartFontFaceCss<\n T extends { resources?: { css?: string } },\n>(\n props: T,\n faces: readonly RasterizeFontFace[],\n families: readonly string[]\n): T {\n const css = chartFontFaceCss(faces, families);\n if (!css) return props;\n const authored = props.resources?.css;\n return {\n ...props,\n resources: {\n ...props.resources,\n css: authored ? `${css}\\n${authored}` : css,\n },\n };\n}\n","import { Type, type TSchema } from '@sinclair/typebox';\n\n/**\n * Content roles a definition may assign to a slot. A quality profile reads\n * them to require or measure content (an action title at most two lines, a\n * source under every chart); the theme only styles them. No role adds a\n * requirement on its own.\n */\nexport const BLOCK_SLOT_ROLES = [\n 'actionTitle',\n 'takeaway',\n 'source',\n 'tracker',\n 'footer',\n] as const;\nexport type BlockSlotRole = (typeof BLOCK_SLOT_ROLES)[number];\n\nexport interface BlockSlot {\n type:\n | 'string'\n | 'number'\n | 'integer'\n | 'boolean'\n | 'object'\n | 'array'\n | 'component';\n description?: string;\n required?: boolean;\n default?: unknown;\n enum?: (string | number | boolean)[];\n minItems?: number;\n maxItems?: number;\n minLength?: number;\n maxLength?: number;\n minimum?: number;\n maximum?: number;\n maxWords?: number;\n oneLine?: boolean;\n items?: BlockSlot;\n properties?: Record<string, BlockSlot>;\n role?: BlockSlotRole;\n}\n\n/** Definitions are authored data. No concrete block is registered by the core. */\nexport interface JsonBlockDefinition {\n description?: string;\n slots: Record<string, BlockSlot>;\n body: unknown[];\n /** DOCX section state, applied before rendering its header and footer. */\n section?: {\n tracker?: unknown;\n header?: unknown[];\n footer?: unknown[];\n pageBreak?: boolean;\n scope?: 'section' | 'following';\n };\n /** PPTX slide settings the invocation's slide inherits unless it states its own. */\n slide?: {\n background?: unknown;\n grid?: unknown;\n notes?: unknown;\n };\n}\n\nexport const BlockSlotSchema: TSchema = Type.Recursive(\n (Self) =>\n Type.Object(\n {\n type: Type.Union(\n [\n 'string',\n 'number',\n 'integer',\n 'boolean',\n 'object',\n 'array',\n 'component',\n ].map((v) => Type.Literal(v)),\n {\n description:\n 'Content type accepted by this slot. Use component for a document component or registered plugin.',\n }\n ),\n description: Type.Optional(\n Type.String({\n description: 'Explain this slot’s content and purpose to authors.',\n })\n ),\n required: Type.Optional(\n Type.Boolean({\n description:\n 'Require a value when no default is provided. Defaults to false.',\n })\n ),\n default: Type.Optional(\n Type.Unknown({\n description:\n 'Value used when the caller omits this slot. Must satisfy the slot’s type and constraints.',\n })\n ),\n enum: Type.Optional(\n Type.Array(\n Type.Union([Type.String(), Type.Number(), Type.Boolean()]),\n {\n minItems: 1,\n description: 'Allowed scalar values for this slot.',\n }\n )\n ),\n minItems: Type.Optional(\n Type.Integer({\n minimum: 0,\n description: 'Minimum number of array entries, inclusive.',\n })\n ),\n maxItems: Type.Optional(\n Type.Integer({\n minimum: 0,\n description: 'Maximum number of array entries, inclusive.',\n })\n ),\n minLength: Type.Optional(\n Type.Integer({\n minimum: 0,\n description: 'Minimum string length in characters, inclusive.',\n })\n ),\n maxLength: Type.Optional(\n Type.Integer({\n minimum: 0,\n description: 'Maximum string length in characters, inclusive.',\n })\n ),\n minimum: Type.Optional(\n Type.Number({ description: 'Minimum numeric value, inclusive.' })\n ),\n maximum: Type.Optional(\n Type.Number({ description: 'Maximum numeric value, inclusive.' })\n ),\n maxWords: Type.Optional(\n Type.Integer({\n minimum: 1,\n description:\n 'Maximum whitespace-separated word count. Exceeding it fails validation.',\n })\n ),\n oneLine: Type.Optional(\n Type.Boolean({\n description:\n 'Reject newline characters in string values. Does not prevent visual line wrapping.',\n })\n ),\n items: Type.Optional({\n ...Self,\n description: 'Slot type and constraints for each array entry.',\n }),\n properties: Type.Optional(\n Type.Record(Type.String(), Self, {\n description:\n 'Named child slots accepted by an object slot. Undeclared properties are rejected.',\n })\n ),\n role: Type.Optional(\n Type.Union(\n BLOCK_SLOT_ROLES.map((role) => Type.Literal(role)),\n {\n description:\n 'Content role for quality profiles: actionTitle, takeaway, source, tracker or footer. A profile may require or measure it; the theme only styles it.',\n }\n )\n ),\n },\n { additionalProperties: false }\n ),\n // Named so the export hoists it under a stable definition rather than a\n // TypeBox ordinal that shifts with what the process built before it.\n { $id: 'BlockSlot' }\n);\n\nexport const JsonBlockDefinitionSchema = Type.Unsafe<JsonBlockDefinition>(\n Type.Object(\n {\n description: Type.Optional(\n Type.String({\n description:\n 'Describe what this reusable block renders and when to use it.',\n })\n ),\n slots: Type.Record(Type.String(), BlockSlotSchema, {\n description:\n 'Named inputs and their types, defaults and constraints. Use an empty object for a block with no inputs.',\n }),\n body: Type.Array(Type.Unknown(), {\n description:\n 'Components and binding directives expanded in order when this block is invoked.',\n }),\n section: Type.Optional(\n Type.Object(\n {\n tracker: Type.Optional(\n Type.Unknown({\n description:\n 'Section tracker value or binding, available to headers and footers through $context at /section/tracker.',\n })\n ),\n header: Type.Optional(\n Type.Array(Type.Unknown(), {\n description:\n 'Header component templates. Explicit header settings on the section take precedence.',\n })\n ),\n footer: Type.Optional(\n Type.Array(Type.Unknown(), {\n description:\n 'Footer component templates. Explicit footer settings on the section take precedence.',\n })\n ),\n pageBreak: Type.Optional(\n Type.Boolean({\n description:\n 'Start the containing section on a new page. An explicit section pageBreak setting takes precedence.',\n })\n ),\n scope: Type.Optional(\n Type.Union([Type.Literal('section'), Type.Literal('following')], {\n description:\n 'Apply header/footer templates to this section only, or inherit them in following sections. Defaults to section.',\n })\n ),\n },\n {\n additionalProperties: false,\n description:\n 'DOCX section tracker, header/footer templates and page-break behavior. Place this block at the section boundary.',\n }\n )\n ),\n slide: Type.Optional(\n Type.Object(\n {\n background: Type.Optional(\n Type.Unknown({\n description:\n 'Slide background (color, gradient or image) or a binding. A background the slide states itself takes precedence.',\n })\n ),\n grid: Type.Optional(\n Type.Unknown({\n description:\n 'Grid configuration merged over the presentation grid when resolving grid placements in this block’s body.',\n })\n ),\n notes: Type.Optional(\n Type.Unknown({\n description:\n 'Speaker notes or a binding. Notes the slide states itself take precedence.',\n })\n ),\n },\n {\n additionalProperties: false,\n description:\n 'PPTX slide background, grid and notes supplied by this block. Invoke the block as a direct child of a slide.',\n }\n )\n ),\n },\n { additionalProperties: false }\n )\n);\n\nexport const BlockDefinitionsSchema = Type.Record(\n Type.String({ pattern: '^[a-zA-Z][a-zA-Z0-9_-]*$' }),\n JsonBlockDefinitionSchema,\n {\n description:\n 'Document-local JSON block definitions. Names are not built into the engine.',\n }\n);\n\nexport const BlockInvocationPropsSchema = Type.Object(\n {\n ref: Type.String({\n minLength: 1,\n description: 'Name in this document’s props.blocks.',\n }),\n slots: Type.Optional(\n Type.Record(Type.String(), Type.Unknown(), {\n description:\n 'Input values keyed by the slot names declared in the referenced block definition.',\n })\n ),\n },\n { additionalProperties: false }\n);\n\n/** Portable JSON Schema for a single slot, also used by catalog/inspect clients. */\nexport function blockSlotJsonSchema(slot: BlockSlot): Record<string, unknown> {\n const { oneLine, properties, items, role: _role, ...rest } = slot; // eslint-disable-line @typescript-eslint/no-unused-vars\n delete rest.required;\n delete rest.maxWords;\n if (slot.type === 'component') {\n return {\n type: 'object',\n properties: { name: { type: 'string' } },\n required: ['name'],\n description: slot.description,\n };\n }\n return {\n ...rest,\n ...(oneLine && { pattern: '^[^\\\\r\\\\n]*$' }),\n ...(items && { items: blockSlotJsonSchema(items) }),\n ...(properties && {\n properties: Object.fromEntries(\n Object.entries(properties).map(([key, value]) => [\n key,\n blockSlotJsonSchema(value),\n ])\n ),\n required: Object.entries(properties)\n .filter(([, value]) => value.required && value.default === undefined)\n .map(([key]) => key),\n additionalProperties: false,\n }),\n };\n}\n","/** Evaluator syntax and result families, shared with authoring-schema generation. */\nexport const BLOCK_DIRECTIVES = {\n $slot: { keys: ['$slot', 'default', 'props'], result: 'dynamic' },\n $item: { keys: ['$item', 'default', 'props'], result: 'dynamic' },\n $theme: { keys: ['$theme', 'default'], result: 'dynamic' },\n $context: { keys: ['$context', 'default'], result: 'dynamic' },\n $count: { keys: ['$count'], result: 'number' },\n $if: { keys: ['$if', 'then', 'else'], result: 'dynamic' },\n $each: { keys: ['$each', 'template'], result: 'array' },\n $join: { keys: ['$join', 'separator', 'keepEmpty'], result: 'string' },\n $measure: { keys: ['$measure', 'fraction', 'unit'], result: 'number' },\n} as const;\nexport type BlockDirective = keyof typeof BLOCK_DIRECTIVES;\n/** Roots a `$if`/`$each`/`$count` operand may name instead of a slot pointer. */\nexport const BLOCK_OPERAND_ROOTS = ['$item', '$slot', '$context'] as const;\nexport type BlockOperandRoot = (typeof BLOCK_OPERAND_ROOTS)[number];\n","import {\n BLOCK_DIRECTIVES,\n BLOCK_OPERAND_ROOTS,\n type BlockOperandRoot,\n} from './directives';\nimport { Value } from '@sinclair/typebox/value';\nimport {\n BlockDefinitionsSchema,\n type BlockSlot,\n type JsonBlockDefinition,\n} from './schema';\n\ntype Rec = Record<string, unknown>;\nexport interface BlockIssue {\n path: string;\n code: string;\n message: string;\n}\nexport class BlockEvaluationError extends Error {\n constructor(public readonly issues: BlockIssue[]) {\n super(issues.map((i) => `${i.path}: ${i.message}`).join('\\n'));\n this.name = 'BlockEvaluationError';\n }\n}\nexport const isBlockRecord = (v: unknown): v is Rec =>\n typeof v === 'object' && v !== null && !Array.isArray(v);\nexport const blockPointerKey = (s: string): string =>\n s.replace(/~/g, '~0').replace(/\\//g, '~1');\nconst own = (obj: object, key: string) =>\n Object.prototype.hasOwnProperty.call(obj, key);\nexport function blockValueAt(root: unknown, path: string): unknown {\n if (path === '') return root;\n if (!path.startsWith('/')) return undefined;\n let value = root;\n for (const part of path.slice(1).split('/')) {\n const key = part.replace(/~1/g, '/').replace(/~0/g, '~');\n if ((!isBlockRecord(value) && !Array.isArray(value)) || !own(value, key))\n return undefined;\n value = (value as Rec)[key];\n }\n return value;\n}\nexport function toAuthoredBlockPointer(\n map: Readonly<Record<string, string>>,\n pointer: string\n): string {\n let best: string | undefined;\n for (const path of Object.keys(map)) {\n if (\n (pointer === path || pointer.startsWith(`${path}/`)) &&\n (best === undefined || path.length > best.length)\n )\n best = path;\n }\n return best === undefined\n ? pointer\n : `${map[best]}${pointer.slice(best.length)}`;\n}\n/**\n * Props a component placed in a slot may not carry: placement and group\n * layout belong to the definition. Read by the runtime check below and by the\n * editor schema that flags them inline.\n */\nexport const BLOCK_SLOT_PLACEMENT_PROPS: readonly string[] = [\n 'x',\n 'y',\n 'w',\n 'h',\n 'position',\n 'grid',\n 'gridConfig',\n 'direction',\n 'gap',\n 'weights',\n 'alignment',\n 'spacing',\n];\n\nexport const blockWordCount = (text: string): number =>\n text.trim() === '' ? 0 : text.trim().split(/\\s+/).length;\nconst present = (value: unknown): boolean =>\n value !== undefined &&\n value !== null &&\n value !== '' &&\n value !== false &&\n (!Array.isArray(value) || value.length > 0);\nconst fail = (path: string, code: string, message: string): never => {\n throw new BlockEvaluationError([{ path, code, message }]);\n};\n\n/** Slot constraints and defaults are shared by validation and evaluation. */\nexport function resolveBlockSlot(\n slot: BlockSlot,\n input: unknown,\n path: string,\n issues: BlockIssue[]\n): unknown {\n const value =\n input === undefined && slot.default !== undefined\n ? structuredClone(slot.default)\n : input;\n if (value === undefined) {\n if (slot.required)\n issues.push({\n path,\n code: 'block_required_slot',\n message: 'Required block slot is missing.',\n });\n return undefined;\n }\n const validType =\n slot.type === 'array'\n ? Array.isArray(value)\n : slot.type === 'component'\n ? isBlockRecord(value) && typeof value.name === 'string'\n : slot.type === 'object'\n ? isBlockRecord(value)\n : slot.type === 'integer'\n ? typeof value === 'number' && Number.isInteger(value)\n : typeof value === slot.type &&\n (typeof value !== 'number' || Number.isFinite(value));\n if (!validType) {\n issues.push({\n path,\n code: 'block_slot_type',\n message: `Expected ${slot.type}.`,\n });\n return value;\n }\n const issue = (message: string) =>\n issues.push({ path, code: 'block_slot_budget', message });\n if (slot.enum && !slot.enum.includes(value as string | number | boolean))\n issue('Value is not one of the declared choices.');\n if (typeof value === 'string') {\n if (slot.oneLine && /[\\r\\n]/.test(value))\n issue('Slot must contain one line.');\n if (slot.minLength !== undefined && value.length < slot.minLength)\n issue(`Minimum length is ${slot.minLength}.`);\n if (slot.maxLength !== undefined && value.length > slot.maxLength)\n issue(`Maximum length is ${slot.maxLength}.`);\n if (slot.maxWords !== undefined && blockWordCount(value) > slot.maxWords)\n issue(`Maximum word count is ${slot.maxWords}.`);\n }\n if (typeof value === 'number') {\n if (slot.minimum !== undefined && value < slot.minimum)\n issue(`Minimum value is ${slot.minimum}.`);\n if (slot.maximum !== undefined && value > slot.maximum)\n issue(`Maximum value is ${slot.maximum}.`);\n }\n if (Array.isArray(value)) {\n if (slot.minItems !== undefined && value.length < slot.minItems)\n issue(`Minimum item count is ${slot.minItems}.`);\n if (slot.maxItems !== undefined && value.length > slot.maxItems)\n issue(`Maximum item count is ${slot.maxItems}.`);\n return slot.items\n ? value.map((v, i) =>\n resolveBlockSlot(slot.items!, v, `${path}/${i}`, issues)\n )\n : value;\n }\n if (slot.type === 'component' && isBlockRecord(value)) {\n const checkPlacement = (\n node: unknown,\n pointer: string,\n depth = 0\n ): void => {\n if (depth > 64) {\n issues.push({\n path: pointer,\n code: 'block_expansion_limit',\n message: 'Component slot exceeds 64 levels.',\n });\n return;\n }\n if (Array.isArray(node)) {\n node.forEach((item, i) =>\n checkPlacement(item, `${pointer}/${i}`, depth + 1)\n );\n return;\n }\n if (!isBlockRecord(node)) return;\n const props =\n typeof node.name === 'string' && isBlockRecord(node.props)\n ? node.props\n : {};\n for (const key of BLOCK_SLOT_PLACEMENT_PROPS) {\n if (own(props, key))\n issues.push({\n path: `${pointer}/props/${key}`,\n code: 'block_slot_placement',\n message:\n 'Block placement belongs in the definition, not in a component slot.',\n });\n }\n for (const [key, item] of Object.entries(node))\n checkPlacement(item, `${pointer}/${blockPointerKey(key)}`, depth + 1);\n };\n checkPlacement(value, path);\n }\n if (slot.type === 'object' && isBlockRecord(value) && slot.properties)\n return resolveBlockSlots(slot.properties, value, path, issues);\n return value;\n}\n\nfunction resolveBlockSlots(\n slots: Record<string, BlockSlot>,\n values: Rec,\n path: string,\n issues: BlockIssue[]\n): Rec {\n const out: Rec = {};\n for (const key of Object.keys(values)) {\n if (!own(slots, key))\n issues.push({\n path: `${path}/${blockPointerKey(key)}`,\n code: 'block_unknown_slot',\n message: `Unknown slot '${key}'. Expected: ${Object.keys(slots).join(', ')}.`,\n });\n }\n for (const [key, slot] of Object.entries(slots)) {\n const value = resolveBlockSlot(\n slot,\n own(values, key) ? values[key] : undefined,\n `${path}/${blockPointerKey(key)}`,\n issues\n );\n if (value !== undefined)\n Object.defineProperty(out, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n return out;\n}\n\nconst DIRECTIVES: Record<string, readonly string[]> = Object.fromEntries(\n Object.entries(BLOCK_DIRECTIVES).map(([key, directive]) => [\n key,\n directive.keys,\n ])\n);\nfunction slotDescriptorAt(\n slots: Record<string, BlockSlot>,\n pointer: string\n): BlockSlot | undefined {\n let descriptor: BlockSlot | undefined = { type: 'object', properties: slots };\n for (const escaped of pointer.slice(1).split('/')) {\n const key = escaped.replace(/~1/g, '/').replace(/~0/g, '~');\n if (descriptor?.type === 'object') {\n if (!descriptor.properties) return { type: 'object' }; // Deliberately open data.\n descriptor = own(descriptor.properties, key)\n ? descriptor.properties[key]\n : undefined;\n } else if (descriptor?.type === 'array' && /^(0|[1-9]\\d*)$/.test(key))\n descriptor = descriptor.items ?? { type: 'object' };\n else if (descriptor?.type === 'component') return { type: 'object' };\n else return undefined;\n }\n return descriptor;\n}\n\n/** Directives whose value is an operand rather than a plain pointer. */\nconst OPERAND_DIRECTIVES = ['$if', '$each', '$count'];\ninterface BlockOperand {\n root: BlockOperandRoot | '$theme';\n pointer: string;\n}\nconst isPointer = (value: unknown): value is string =>\n typeof value === 'string' && (value === '' || value.startsWith('/'));\n/**\n * Read a directive's operand. A plain pointer reads a slot (for `$slot`,\n * `$item`, `$theme` and `$context` it is the directive's own root); for\n * `$if`, `$each` and `$count` a one-key reference object names the root\n * instead. Anything else is malformed.\n */\nfunction blockOperand(value: unknown, key: string): BlockOperand | undefined {\n if (isPointer(value))\n return {\n root: OPERAND_DIRECTIVES.includes(key)\n ? '$slot'\n : (key as BlockOperand['root']),\n pointer: value,\n };\n if (!OPERAND_DIRECTIVES.includes(key) || !isBlockRecord(value))\n return undefined;\n const keys = Object.keys(value);\n const root = BLOCK_OPERAND_ROOTS.find((candidate) => candidate === keys[0]);\n if (keys.length !== 1 || !root || !isPointer(value[root])) return undefined;\n return { root, pointer: value[root] as string };\n}\n\nfunction checkTemplate(\n value: unknown,\n path: string,\n slots: Record<string, BlockSlot>,\n issues: BlockIssue[],\n repeated = false,\n depth = 0\n): void {\n if (depth > 64) {\n issues.push({\n path,\n code: 'block_depth',\n message: 'Definition exceeds 64 levels.',\n });\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((v, i) =>\n checkTemplate(v, `${path}/${i}`, slots, issues, repeated, depth + 1)\n );\n return;\n }\n if (!isBlockRecord(value)) return;\n const keys = Object.keys(value).filter((k) => k.startsWith('$'));\n if (keys.length) {\n const key = keys[0];\n const allowed = DIRECTIVES[key];\n if (\n !allowed ||\n keys.length !== 1 ||\n Object.keys(value).some((k) => !allowed.includes(k))\n ) {\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: 'Unknown or malformed block directive.',\n });\n return;\n }\n if (\n [\n '$slot',\n '$item',\n '$theme',\n '$context',\n '$if',\n '$each',\n '$count',\n ].includes(key)\n ) {\n // `$if`, `$each` and `$count` take an operand: a slot pointer, or a\n // reference object that reads the current `$each` item, a slot or the\n // context — so a repeat can walk the current item's own array and a\n // condition can test one of its fields.\n const operand = blockOperand(value[key], key);\n if (!operand)\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: OPERAND_DIRECTIVES.includes(key)\n ? `${key} takes a slot pointer such as /items, or one reference: ${BLOCK_OPERAND_ROOTS.map((root) => `{ \"${root}\": ... }`).join(', ')}.`\n : 'Bindings use JSON Pointers, e.g. /title.',\n });\n else if (operand.root === '$slot') {\n const descriptor = slotDescriptorAt(slots, operand.pointer);\n if (!descriptor)\n issues.push({\n path,\n code: 'block_unknown_binding',\n message: `No slot field '${operand.pointer}' is declared.`,\n });\n else if (\n ['$each', '$count'].includes(key) &&\n descriptor.type !== 'array'\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: `${key} requires an array slot.`,\n });\n }\n if (operand?.root === '$item' && !repeated)\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: '$item is only available inside $each.',\n });\n if (\n (key === '$slot' || key === '$item') &&\n own(value, 'props') &&\n !isBlockRecord(value.props)\n )\n issues.push({\n path: `${path}/props`,\n code: 'block_invalid_binding',\n message:\n 'props must be an object of component props merged beneath a component-slot value.',\n });\n }\n if (\n key === '$join' &&\n value.keepEmpty !== undefined &&\n typeof value.keepEmpty !== 'boolean'\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: 'keepEmpty must be boolean.',\n });\n if (key === '$if' && !own(value, 'then'))\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: '$if requires then.',\n });\n if (\n key === '$each' &&\n (!own(value, 'template') || Array.isArray(value.template))\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message:\n '$each requires one template value; use a group for multiple flow children.',\n });\n if (\n key === '$join' &&\n (!Array.isArray(value.$join) ||\n (value.separator !== undefined && typeof value.separator !== 'string'))\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message: '$join requires an array and an optional string separator.',\n });\n if (\n key === '$measure' &&\n (!['width', 'height'].includes(String(value.$measure)) ||\n !['pt', 'twip', 'in'].includes(String(value.unit ?? 'pt')) ||\n (value.fraction !== undefined &&\n (typeof value.fraction !== 'number' ||\n value.fraction < 0 ||\n value.fraction > 1)))\n )\n issues.push({\n path,\n code: 'block_invalid_binding',\n message:\n '$measure requires width/height, pt/twip/in and a fraction between 0 and 1.',\n });\n }\n for (const [key, item] of Object.entries(value)) {\n if (key.startsWith('$') && key !== '$join') continue;\n checkTemplate(\n item,\n `${path}/${blockPointerKey(key)}`,\n slots,\n issues,\n repeated || own(value, '$each'),\n depth + 1\n );\n }\n}\n\nexport function readBlockDefinitions(\n document: unknown\n): Record<string, JsonBlockDefinition> {\n const value =\n isBlockRecord(document) && isBlockRecord(document.props)\n ? document.props.blocks\n : undefined;\n return (value ?? {}) as Record<string, JsonBlockDefinition>;\n}\n\nexport function validateBlockDefinitions(\n definitions: unknown,\n format: 'docx' | 'pptx',\n reservedNames: readonly string[] = []\n): BlockIssue[] {\n if (!Value.Check(BlockDefinitionsSchema, definitions))\n return [...Value.Errors(BlockDefinitionsSchema, definitions)]\n .slice(0, 100)\n .map((e) => ({\n path: `/props/blocks${e.path}`,\n code: 'block_invalid_definition',\n message: e.message,\n }));\n const issues: BlockIssue[] = [];\n for (const [name, def] of Object.entries(definitions)) {\n const path = `/props/blocks/${blockPointerKey(name)}`;\n if (reservedNames.includes(name))\n issues.push({\n path,\n code: 'block_name_collision',\n message: `Block '${name}' conflicts with a registered component.`,\n });\n if (format !== 'docx' && def.section)\n issues.push({\n path: `${path}/section`,\n code: 'block_format',\n message: 'Section effects are DOCX-only.',\n });\n if (format !== 'pptx' && def.slide)\n issues.push({\n path: `${path}/slide`,\n code: 'block_format',\n message: 'Slide effects are PPTX-only.',\n });\n const checkSlot = (slot: BlockSlot, pointer: string): void => {\n if (slot.default !== undefined)\n resolveBlockSlot(slot, slot.default, `${pointer}/default`, issues);\n for (const [minimum, maximum] of [\n ['minItems', 'maxItems'],\n ['minLength', 'maxLength'],\n ['minimum', 'maximum'],\n ] as const) {\n if (\n slot[minimum] !== undefined &&\n slot[maximum] !== undefined &&\n slot[minimum]! > slot[maximum]!\n )\n issues.push({\n path: pointer,\n code: 'block_invalid_definition',\n message: `${minimum} exceeds ${maximum}.`,\n });\n }\n if (slot.items) checkSlot(slot.items, `${pointer}/items`);\n for (const [key, nested] of Object.entries(slot.properties ?? {}))\n checkSlot(nested, `${pointer}/properties/${blockPointerKey(key)}`);\n };\n for (const [key, slot] of Object.entries(def.slots))\n checkSlot(slot, `${path}/slots/${blockPointerKey(key)}`);\n checkTemplate(def.body, `${path}/body`, def.slots, issues);\n if (def.section)\n checkTemplate(def.section, `${path}/section`, def.slots, issues);\n if (def.slide) checkTemplate(def.slide, `${path}/slide`, def.slots, issues);\n }\n return issues;\n}\n\nexport function validateBlockInvocations(\n document: unknown,\n definitions: Record<string, JsonBlockDefinition>,\n format: 'docx' | 'pptx',\n reservedNames: readonly string[] = []\n): BlockIssue[] {\n const issues = validateBlockDefinitions(definitions, format, reservedNames);\n if (issues.length) return issues;\n const walk = (v: unknown, path: string): void => {\n if (Array.isArray(v)) {\n v.forEach((item, i) => walk(item, `${path}/${i}`));\n return;\n }\n if (!isBlockRecord(v) || v.enabled === false) return;\n if (\n v.name === 'block' &&\n isBlockRecord(v.props) &&\n typeof v.props.ref === 'string'\n ) {\n const def = own(definitions, v.props.ref)\n ? definitions[v.props.ref]\n : undefined;\n if (!def)\n issues.push({\n path: `${path}/props/ref`,\n code: 'block_unknown_reference',\n message: `Block '${v.props.ref}' is not defined in this document.`,\n });\n else {\n if (v.props.slots === undefined || isBlockRecord(v.props.slots))\n resolveBlockSlots(\n def.slots,\n (v.props.slots ?? {}) as Rec,\n `${path}/props/slots`,\n issues\n );\n if (def.section && !/^\\/children\\/\\d+\\/children\\/\\d+$/.test(path))\n issues.push({\n path,\n code: 'invalid_placement',\n message:\n 'A block with section effects must be a direct child of a top-level section.',\n });\n if (def.slide && !/^\\/children\\/\\d+\\/children\\/\\d+$/.test(path))\n issues.push({\n path,\n code: 'invalid_placement',\n message:\n 'A block with slide effects must be a direct child of a slide.',\n });\n }\n }\n for (const [key, item] of Object.entries(v)) {\n if (path === '/props' && key === 'blocks') continue;\n walk(item, `${path}/${blockPointerKey(key)}`);\n }\n };\n walk(document, '');\n return issues;\n}\n\nexport interface BlockEnvironment {\n slots: Rec;\n slotSources?: Record<string, string>;\n source: string;\n definition: string;\n context: Rec;\n contextSources?: Record<string, string>;\n item?: unknown;\n itemSource?: string;\n}\nexport interface BlockSectionEffect {\n settings: NonNullable<JsonBlockDefinition['section']>;\n environment: BlockEnvironment;\n path: string;\n}\nexport interface BlockSlideEffect {\n settings: NonNullable<JsonBlockDefinition['slide']>;\n environment: BlockEnvironment;\n path: string;\n}\nexport interface BlockEvaluatorOptions {\n format: 'docx' | 'pptx';\n theme?: unknown;\n context?: Rec;\n contextSources?: Record<string, string>;\n reservedNames?: readonly string[];\n contextAt?: (path: string) => Rec;\n measure?: (\n axis: 'width' | 'height',\n unit: 'pt' | 'twip' | 'in',\n context: Rec\n ) => number;\n onSection?: (effect: BlockSectionEffect) => void;\n onSlide?: (effect: BlockSlideEffect) => void;\n}\n\n/** Pure bounded JSON composition. Plugins are expanded by the host, never evaluated here. */\nexport class JsonBlockEvaluator {\n readonly sourceMap: Record<string, string> = {};\n readonly blocks: string[] = [];\n private nodes = 0;\n constructor(\n readonly definitions: Record<string, JsonBlockDefinition>,\n readonly options: BlockEvaluatorOptions\n ) {\n const issues = validateBlockDefinitions(\n definitions,\n options.format,\n options.reservedNames\n );\n if (issues.length) throw new BlockEvaluationError(issues);\n }\n private guard(path: string, depth: number): void {\n if (depth > 64 || ++this.nodes > 50000)\n fail(\n path,\n 'block_expansion_limit',\n 'Block expansion exceeds the depth/node limit (64/50000).'\n );\n }\n /**\n * A directive operand and the authored pointer it came from: the slot the\n * pointer form names, or the current item, slot or context a reference\n * object names. Definitions are validated before this runs, so a malformed\n * operand cannot reach it.\n */\n private operand(\n raw: unknown,\n key: string,\n env: BlockEnvironment\n ): { value: unknown; source: string; element: (index: number) => string } {\n const { root, pointer } = blockOperand(raw, key)!;\n const { value, source } = this.reference(root, pointer, env);\n return {\n value,\n source,\n // Element i of the array is authored at pointer/i, looked up the same\n // way: a slot the enclosing invocation built from its own repeat maps\n // element by element, and pointer + \"/i\" is not the same as that.\n element: (index) =>\n this.reference(root, `${pointer}/${index}`, env).source,\n };\n }\n /**\n * What a reference reads and where the author wrote it. One resolution for\n * the binding form and the operand form, so `{ \"$context\": ... }` is\n * attributed the same way whichever directive carries it.\n */\n private reference(\n root: BlockOperandRoot | '$theme',\n pointer: string,\n env: BlockEnvironment\n ): { value: unknown; source: string } {\n if (root === '$item')\n return {\n value: blockValueAt(env.item, pointer),\n source: `${env.itemSource ?? env.source}${pointer}`,\n };\n if (root === '$context') {\n const authored = toAuthoredBlockPointer(\n env.contextSources ?? {},\n pointer\n );\n return {\n value: blockValueAt(env.context, pointer),\n source: authored === pointer ? env.source : authored,\n };\n }\n if (root === '$theme')\n return {\n value: blockValueAt(this.options.theme, pointer),\n source: env.source,\n };\n return {\n value: blockValueAt(env.slots, pointer),\n source: env.slotSources\n ? toAuthoredBlockPointer(env.slotSources, pointer)\n : `${env.source}/props/slots${pointer}`,\n };\n }\n evaluate(\n value: unknown,\n env: BlockEnvironment,\n out: string,\n definitionPath: string,\n depth = 0\n ): unknown {\n this.guard(env.source, depth);\n this.sourceMap[out] = env.source;\n if (Array.isArray(value)) {\n const result: unknown[] = [];\n value.forEach((v, i) => {\n const evaluated = this.evaluate(\n v,\n env,\n `${out}/${result.length}`,\n `${definitionPath}/${i}`,\n depth + 1\n );\n if (evaluated !== undefined) {\n if (\n isBlockRecord(v) &&\n ('$if' in v || '$each' in v) &&\n Array.isArray(evaluated)\n ) {\n // Directives splice sequences; ordinary arrays remain ordinary arrays.\n const base = `${out}/${result.length}`;\n const maps = Object.entries(this.sourceMap).filter(([key]) =>\n key.startsWith(`${base}/`)\n );\n for (const [key] of maps) delete this.sourceMap[key];\n for (const [key, source] of maps) {\n const rest = key.slice(base.length + 1);\n const [index, ...suffix] = rest.split('/');\n this.sourceMap[\n `${out}/${result.length + Number(index)}${suffix.length ? '/' + suffix.join('/') : ''}`\n ] = source;\n }\n result.push(...evaluated);\n } else result.push(evaluated);\n }\n });\n return result;\n }\n if (!isBlockRecord(value)) return value;\n if (\n '$slot' in value ||\n '$item' in value ||\n '$theme' in value ||\n '$context' in value\n ) {\n const key = ['$slot', '$item', '$theme', '$context'].find(\n (k) => k in value\n )!;\n const pointer = value[key] as string;\n const { value: found, source } = this.reference(\n key as BlockOperandRoot | '$theme',\n pointer,\n env\n );\n this.sourceMap[out] = source;\n let result: unknown =\n found !== undefined ? structuredClone(found) : undefined;\n if (result === undefined && own(value, 'default'))\n result = this.evaluate(\n value.default,\n env,\n out,\n `${definitionPath}/default`,\n depth + 1\n );\n if (result === undefined && key === '$theme')\n return fail(\n definitionPath,\n 'block_unknown_theme_binding',\n `Theme value '${pointer}' is missing; declare a fallback or use an existing token.`\n );\n // A component slot takes its placement and styling defaults from the\n // definition: `props` are merged beneath the slot value's own props.\n // The slot content cannot carry placement (rejected at validation), so\n // geometry always comes from the definition; other props stay the\n // author's to override.\n if (\n (key === '$slot' || key === '$item') &&\n own(value, 'props') &&\n isBlockRecord(result) &&\n typeof result.name === 'string'\n ) {\n const origin = this.sourceMap[out];\n const defaults = this.evaluate(\n value.props,\n env,\n `${out}/props`,\n `${definitionPath}/props`,\n depth + 1\n );\n const authored = isBlockRecord(result.props) ? result.props : {};\n for (const propKey of Object.keys(authored)) {\n const pointerKey = `${out}/props/${blockPointerKey(propKey)}`;\n for (const mapped of Object.keys(this.sourceMap))\n if (mapped === pointerKey || mapped.startsWith(`${pointerKey}/`))\n delete this.sourceMap[mapped];\n this.sourceMap[pointerKey] =\n `${origin}/props/${blockPointerKey(propKey)}`;\n }\n result = {\n ...result,\n props: {\n ...(isBlockRecord(defaults) ? defaults : {}),\n ...authored,\n },\n };\n }\n return result;\n }\n if ('$if' in value) {\n const operand = this.operand(value.$if, '$if', env);\n const branch = present(operand.value) ? value.then : value.else;\n const result = this.evaluate(branch, env, out, definitionPath, depth + 1);\n // A literal branch is the tested value's consequence: a finding on it\n // lands on the field that selected it. A binding keeps its own origin.\n const literal =\n !isBlockRecord(branch) ||\n !Object.keys(branch).some((k) => k.startsWith('$'));\n if (literal && this.sourceMap[out] === env.source)\n this.sourceMap[out] = operand.source;\n return result;\n }\n if ('$count' in value) {\n const operand = this.operand(value.$count, '$count', env);\n if (!Array.isArray(operand.value))\n return fail(\n operand.source,\n 'block_slot_type',\n '$count requires an array.'\n );\n return operand.value.length;\n }\n if ('$each' in value) {\n const operand = this.operand(value.$each, '$each', env);\n const list = operand.value;\n if (!Array.isArray(list))\n return fail(\n operand.source,\n 'block_slot_type',\n '$each requires an array.'\n );\n const result: unknown[] = [];\n list.forEach((item, i) => {\n const pointer = `${out}/${result.length}`;\n const evaluated = this.evaluate(\n value.template,\n {\n ...env,\n item,\n itemSource: operand.element(i),\n },\n pointer,\n `${definitionPath}/template`,\n depth + 1\n );\n if (evaluated !== undefined) {\n // The repeated element belongs to the item that produced it: a\n // finding on a whole column lands on that column, not on the block.\n if (this.sourceMap[pointer] === env.source)\n this.sourceMap[pointer] = operand.element(i);\n result.push(evaluated);\n } else\n for (const key of Object.keys(this.sourceMap)) {\n if (key === pointer || key.startsWith(`${pointer}/`))\n delete this.sourceMap[key];\n }\n });\n return result;\n }\n if ('$join' in value) {\n const values = (value.$join as unknown[]).map((v, i) =>\n this.evaluate(\n v,\n env,\n `${out}/${i}`,\n `${definitionPath}/$join/${i}`,\n depth + 1\n )\n );\n const first = values.findIndex(present);\n if (first >= 0) this.sourceMap[out] = this.sourceMap[`${out}/${first}`];\n return (value.keepEmpty === true ? values : values.filter(present))\n .map((v) => String(v ?? ''))\n .join(String(value.separator ?? ''));\n }\n if ('$measure' in value) {\n if (!this.options.measure)\n return fail(\n definitionPath,\n 'block_unsupported_operation',\n 'This format does not support $measure.'\n );\n return (\n this.options.measure(\n value.$measure as 'width' | 'height',\n (value.unit ?? 'pt') as 'pt' | 'twip' | 'in',\n env.context\n ) * Number(value.fraction ?? 1)\n );\n }\n const result: Rec = {};\n for (const [key, item] of Object.entries(value)) {\n const evaluated = this.evaluate(\n item,\n env,\n `${out}/${blockPointerKey(key)}`,\n `${definitionPath}/${blockPointerKey(key)}`,\n depth + 1\n );\n if (evaluated !== undefined)\n Object.defineProperty(result, key, {\n value: evaluated,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n return result;\n }\n expand(value: unknown, path = '', depth = 0): unknown {\n this.guard(path, depth);\n if (Array.isArray(value))\n return value.map((v, i) => this.expand(v, `${path}/${i}`, depth + 1));\n if (!isBlockRecord(value)) return value;\n if (value.name === 'block' && value.enabled !== false) {\n if (!isBlockRecord(value.props) || typeof value.props.ref !== 'string')\n return fail(\n path,\n 'block_invalid_invocation',\n 'A block requires props.ref and optional props.slots.'\n );\n if (\n Object.keys(value.props).some(\n (key) => !['ref', 'slots'].includes(key)\n ) ||\n (value.props.slots !== undefined && !isBlockRecord(value.props.slots))\n )\n return fail(\n path,\n 'block_invalid_invocation',\n 'Block props accept only ref and an object of slots.'\n );\n const def = own(this.definitions, value.props.ref)\n ? this.definitions[value.props.ref]\n : undefined;\n if (!def)\n return fail(\n `${path}/props/ref`,\n 'block_unknown_reference',\n `Block '${value.props.ref}' is not defined in this document.`\n );\n const issues: BlockIssue[] = [];\n const source = toAuthoredBlockPointer(this.sourceMap, path);\n const slotsPath = `${path}/props/slots`;\n const slots = resolveBlockSlots(\n def.slots,\n (value.props.slots ?? {}) as Rec,\n slotsPath,\n issues\n );\n if (issues.length)\n throw new BlockEvaluationError(\n issues.map((issue) => ({\n ...issue,\n path: toAuthoredBlockPointer(this.sourceMap, issue.path),\n }))\n );\n const slotSources = Object.fromEntries([\n ['', toAuthoredBlockPointer(this.sourceMap, slotsPath)],\n ...Object.entries(this.sourceMap)\n .filter(([key]) => key.startsWith(`${slotsPath}/`))\n .map(([key, origin]) => [key.slice(slotsPath.length), origin]),\n ]);\n const env: BlockEnvironment = {\n slots,\n slotSources,\n source,\n definition: `/props/blocks/${blockPointerKey(value.props.ref)}`,\n context: this.options.contextAt?.(path) ?? this.options.context ?? {},\n contextSources: this.options.contextSources,\n };\n if (def.section)\n this.options.onSection?.({\n settings: def.section,\n environment: env,\n path,\n });\n if (def.slide)\n this.options.onSlide?.({ settings: def.slide, environment: env, path });\n this.blocks.push(source);\n const children = this.evaluate(\n def.body,\n env,\n `${path}/children`,\n `${env.definition}/body`,\n depth + 1\n );\n return {\n name: 'group',\n ...(value.id !== undefined && { id: value.id }),\n children: this.expand(children, `${path}/children`, depth + 1),\n };\n }\n if (value.enabled === false) return { ...value };\n const result: Rec = { ...value };\n // Traverse the document, never its definition library or unexpanded slot data.\n for (const [key, item] of Object.entries(value)) {\n if (path === '/props' && key === 'blocks') continue;\n Object.defineProperty(result, key, {\n value: this.expand(item, `${path}/${blockPointerKey(key)}`, depth + 1),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n return result;\n }\n}\n","import { Value } from '@sinclair/typebox/value';\nimport {\n BlockDefinitionsSchema,\n blockSlotJsonSchema,\n type BlockSlot,\n type BlockSlotRole,\n type JsonBlockDefinition,\n} from './schema';\nimport {\n blockPointerKey,\n blockValueAt,\n blockWordCount,\n isBlockRecord,\n readBlockDefinitions,\n} from './evaluator';\n\nexport function blockSlotsJsonSchema(\n definition: JsonBlockDefinition\n): Record<string, unknown> {\n return {\n type: 'object',\n additionalProperties: false,\n properties: Object.fromEntries(\n Object.entries(definition.slots).map(([key, slot]) => [\n key,\n blockSlotJsonSchema(slot),\n ])\n ),\n required: Object.entries(definition.slots)\n .filter(([, slot]) => slot.required && slot.default === undefined)\n .map(([key]) => key),\n };\n}\n\n/** Authored definitions and fill pointers for exactly this document revision. */\nexport function documentBlockMetadata(document: unknown) {\n const definitions = readBlockDefinitions(document);\n if (!Value.Check(BlockDefinitionsSchema, definitions))\n return { definitions: [], invocations: [], invalidDefinitions: true };\n const invocations: {\n ref: string;\n path: string;\n slotsPath: string;\n defined: boolean;\n }[] = [];\n const walk = (value: unknown, path: string): void => {\n if (Array.isArray(value)) {\n value.forEach((item, i) => walk(item, `${path}/${i}`));\n return;\n }\n if (!isBlockRecord(value)) return;\n if (\n value.name === 'block' &&\n isBlockRecord(value.props) &&\n typeof value.props.ref === 'string'\n )\n invocations.push({\n ref: value.props.ref,\n path,\n slotsPath: `${path}/props/slots`,\n defined: Object.prototype.hasOwnProperty.call(\n definitions,\n value.props.ref\n ),\n });\n for (const [key, item] of Object.entries(value)) {\n if (path === '/props' && key === 'blocks') continue;\n walk(item, `${path}/${blockPointerKey(key)}`);\n }\n };\n walk(document, '');\n return {\n definitions: Object.entries(definitions).map(([name, definition]) => ({\n name,\n definitionPointer: `/props/blocks/${blockPointerKey(name)}`,\n definition,\n slotsSchema: blockSlotsJsonSchema(definition),\n })),\n invocations,\n invalidDefinitions: false,\n };\n}\n\n/** Compiled pointer → authored pointer. */\nexport type BlockSourceMap = Readonly<Record<string, string>>;\n/** A document with every block lowered in place, and how to get back. */\nexport interface ExpandedBlocks<T> {\n document: T;\n sourceMap: BlockSourceMap;\n /** Authored pointers of every expanded invocation, in document order. */\n blocks: readonly string[];\n}\n\nexport interface BlockSlotBudget {\n block: string;\n slot: string;\n path: string;\n words: number;\n maxWords: number;\n}\n\nexport interface BlockSlotRoleValue {\n block: string;\n /** Authored pointer of the invocation. */\n invocation: string;\n slot: string;\n role: BlockSlotRole;\n /** Authored pointer of the slot value, whether or not one was supplied. */\n path: string;\n /** The resolved value after defaults; undefined when absent. */\n value: unknown;\n}\n\n/** Visit every declared slot of an invocation with its resolved value. */\nfunction visitInvocationSlots(\n document: unknown,\n blocks: readonly string[],\n visit: (\n ref: string,\n slot: BlockSlot,\n value: unknown,\n pointer: string,\n name: string\n ) => void\n): void {\n const definitions = readBlockDefinitions(document);\n for (const path of blocks) {\n const node = blockValueAt(document, path);\n if (\n !isBlockRecord(node) ||\n !isBlockRecord(node.props) ||\n typeof node.props.ref !== 'string'\n )\n continue;\n const ref = node.props.ref;\n const definition = definitions[ref];\n if (!definition) continue;\n const walk = (\n slot: BlockSlot,\n value: unknown,\n pointer: string,\n name: string\n ): void => {\n visit(ref, slot, value, pointer, name);\n if (isBlockRecord(value) && slot.properties) {\n for (const [key, property] of Object.entries(slot.properties)) {\n walk(\n property,\n blockValueAt(value, `/${blockPointerKey(key)}`),\n `${pointer}/${blockPointerKey(key)}`,\n `${name}.${key}`\n );\n }\n }\n if (Array.isArray(value) && slot.items)\n value.forEach((item, i) =>\n walk(slot.items!, item, `${pointer}/${i}`, name)\n );\n };\n for (const [name, slot] of Object.entries(definition.slots)) {\n const authored = blockValueAt(\n node.props.slots,\n `/${blockPointerKey(name)}`\n );\n walk(\n slot,\n authored === undefined && slot.default !== undefined\n ? slot.default\n : authored,\n `${path}/props/slots/${blockPointerKey(name)}`,\n name\n );\n }\n }\n}\n\n/** Metadata is always read from authored definitions, never from a named catalog. */\nexport function blockSlotBudgets(\n document: unknown,\n blocks: readonly string[]\n): BlockSlotBudget[] {\n const result: BlockSlotBudget[] = [];\n visitInvocationSlots(document, blocks, (ref, slot, value, pointer, name) => {\n if (typeof value === 'string' && slot.maxWords !== undefined)\n result.push({\n block: ref,\n slot: name,\n path: pointer,\n words: blockWordCount(value),\n maxWords: slot.maxWords,\n });\n });\n return result;\n}\n\n/**\n * Every role-bearing slot of every invocation, present or not, so a profile\n * can require one (a source under a chart) and measure another (an action\n * title's length) at the authored pointer the author can patch.\n */\nexport function blockSlotRoles(\n document: unknown,\n blocks: readonly string[]\n): BlockSlotRoleValue[] {\n const result: BlockSlotRoleValue[] = [];\n visitInvocationSlots(document, blocks, (ref, slot, value, pointer, name) => {\n if (!slot.role) return;\n result.push({\n block: ref,\n invocation: pointer.replace(/\\/props\\/slots\\/.*$/, ''),\n slot: name,\n role: slot.role,\n path: pointer,\n value,\n });\n });\n return result;\n}\n","/** JSON Schema type reasoning for authoring; never used as runtime validation. */\nexport type AuthoringSchema = boolean | Record<string, any>;\nexport type ValueType =\n | 'null'\n | 'boolean'\n | 'number'\n | 'string'\n | 'array'\n | 'object';\nconst allTypes: ValueType[] = [\n 'null',\n 'boolean',\n 'number',\n 'string',\n 'array',\n 'object',\n];\ntype Resolve = (ref: string) => AuthoringSchema | undefined;\nconst intersection = (a: Set<ValueType>, b: Set<ValueType>) =>\n new Set([...a].filter((value) => b.has(value)));\nconst union = (sets: Set<ValueType>[]) =>\n new Set(sets.flatMap((set) => [...set]));\nconst typeOf = (value: unknown): ValueType =>\n value === null\n ? 'null'\n : Array.isArray(value)\n ? 'array'\n : (typeof value as ValueType);\n\n/** Conservative possible types: intersect constraints, combine union branches,\n * and resolve references with a cycle guard. Unknown schemas allow every type.\n * Integer is part of the numeric family; bounds and integrality still validate\n * on evaluated output, just as they do for a reference's unknown value.\n */\nexport function possibleValueTypes(\n schema: AuthoringSchema,\n resolve: Resolve,\n seen = new Set<AuthoringSchema>()\n): Set<ValueType> {\n if (schema === false) return new Set();\n if (schema === true || seen.has(schema)) return new Set(allTypes);\n // Type.Never and plain negated type schemas exclude complete result families.\n // More specific negations (bounds/patterns/enum values) cannot safely exclude\n // an entire family and are left to ordinary literal/output validation.\n const negated = schema.not;\n if (\n negated === true ||\n (negated &&\n typeof negated === 'object' &&\n Object.keys(negated).length === 0)\n )\n return new Set();\n const next = new Set(seen).add(schema);\n let types = new Set(allTypes);\n if (schema.type) {\n const declared = Array.isArray(schema.type) ? schema.type : [schema.type];\n types = intersection(\n types,\n new Set(\n allTypes.filter(\n (type) =>\n declared.includes(type) ||\n (type === 'number' && declared.includes('integer'))\n )\n )\n );\n }\n if (Object.hasOwn(schema, 'const'))\n types = intersection(types, new Set([typeOf(schema.const)]));\n if (Array.isArray(schema.enum))\n types = intersection(types, new Set(schema.enum.map(typeOf)));\n if (typeof schema.$ref === 'string') {\n const target = resolve(schema.$ref);\n if (target !== undefined)\n types = intersection(types, possibleValueTypes(target, resolve, next));\n }\n for (const key of ['anyOf', 'oneOf']) {\n if (Array.isArray(schema[key]))\n types = intersection(\n types,\n union(\n schema[key].map((branch: AuthoringSchema) =>\n possibleValueTypes(branch, resolve, next)\n )\n )\n );\n }\n if (Array.isArray(schema.allOf))\n for (const branch of schema.allOf)\n types = intersection(types, possibleValueTypes(branch, resolve, next));\n if (\n negated &&\n typeof negated === 'object' &&\n negated.type &&\n Object.keys(negated).every((key) =>\n ['type', 'description', 'title', '$comment'].includes(key)\n )\n ) {\n // Excluding integers alone does not exclude all numbers.\n const excluded = (\n Array.isArray(negated.type) ? negated.type : [negated.type]\n ).filter((type: string) => type !== 'integer');\n types = new Set([...types].filter((type) => !excluded.includes(type)));\n }\n return types;\n}\n\n/** Item constraints for an array-valued expression. For tuples, each iteration\n * may produce any tuple item type; final length/position validation stays with\n * the evaluated array. Unions keep alternatives and intersections keep all\n * applicable item constraints. References may be recursive.\n */\nexport function arrayItemSchema(\n schema: AuthoringSchema,\n resolve: Resolve,\n seen = new Set<AuthoringSchema>()\n): AuthoringSchema {\n if (schema === false) return false;\n if (schema === true || seen.has(schema)) return {};\n const next = new Set(seen).add(schema);\n const constraints: AuthoringSchema[] = [];\n if (typeof schema.$ref === 'string') {\n const target = resolve(schema.$ref);\n if (target !== undefined)\n constraints.push(arrayItemSchema(target, resolve, next));\n }\n if (schema.items !== undefined)\n constraints.push(\n Array.isArray(schema.items)\n ? {\n anyOf: [\n ...schema.items,\n ...(schema.additionalItems === false\n ? []\n : [schema.additionalItems ?? {}]),\n ],\n }\n : schema.items\n );\n for (const key of ['anyOf', 'oneOf'])\n if (Array.isArray(schema[key])) {\n constraints.push({\n anyOf: schema[key]\n .filter((branch: AuthoringSchema) =>\n possibleValueTypes(branch, resolve).has('array')\n )\n .map((branch: AuthoringSchema) =>\n arrayItemSchema(branch, resolve, next)\n ),\n });\n }\n if (Array.isArray(schema.allOf))\n constraints.push(\n ...schema.allOf.map((branch: AuthoringSchema) =>\n arrayItemSchema(branch, resolve, next)\n )\n );\n return constraints.length === 0\n ? {}\n : constraints.length === 1\n ? constraints[0]\n : { allOf: constraints };\n}\n","import type { OfficeFormat } from '../rendering/types';\nimport {\n BLOCK_DIRECTIVES,\n BLOCK_OPERAND_ROOTS,\n type BlockDirective,\n} from './directives';\nimport {\n arrayItemSchema,\n possibleValueTypes,\n type AuthoringSchema,\n} from './schema-types';\n\ntype Schema = Record<string, any>;\nconst object = (properties: Schema, required: string[]): Schema => ({\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n});\nconst pointer = (description: string): Schema => ({\n type: 'string',\n pattern: '^(|/.*)$',\n description,\n});\nconst referenceDescriptions = (format: OfficeFormat) => ({\n $slot:\n 'Read a named input slot by JSON Pointer, e.g. /title or /client/name.',\n $item:\n 'Read the current $each entry by JSON Pointer. Use an empty string for the whole entry or /title for a property.',\n $theme:\n 'Read the active theme by JSON Pointer, e.g. /colors/primary. A missing value requires a default.',\n $context:\n format === 'pptx'\n ? 'Read deck or slide context by JSON Pointer, e.g. /document/title, /slide/width or /slide/index.'\n : 'Read document or section context by JSON Pointer, e.g. /document/title or /section/tracker.',\n});\nconst measureDescriptions = (format: OfficeFormat) =>\n format === 'pptx'\n ? {\n axis: 'Measure the slide canvas width or height, in the unit given.',\n unit: 'Measurement unit: points, twentieths of a point, or inches. Defaults to pt; use in for frame coordinates.',\n }\n : {\n axis: 'Measure the usable page width or height after margins, using the containing section’s page settings.',\n unit: 'Measurement unit: points, twentieths of a point, or inches. Defaults to pt.',\n };\nconst describe = (schema: AuthoringSchema, description: string): Schema => ({\n ...(typeof schema === 'boolean' ? { allOf: [schema] } : schema),\n description,\n});\nconst metadata = (schema: AuthoringSchema): Schema =>\n typeof schema === 'boolean'\n ? {}\n : {\n ...(schema.description && { description: schema.description }),\n ...(schema.markdownDescription && {\n markdownDescription: schema.markdownDescription,\n }),\n };\nconst hasKey = (key: string): Schema => ({ type: 'object', required: [key] });\nconst directiveNames = Object.keys(BLOCK_DIRECTIVES) as BlockDirective[];\n\n/**\n * Derive authoring from the renderer/plugin schemas without weakening ordinary\n * documents. Each value retains its literal schema and receives only directives\n * whose result family can fit. Defaults and conditional branches recurse into\n * that same value schema; repetition templates use the actual array item schema.\n *\n * Dispatch uses standard draft-07 conditionals, not overlapping anyOf branches:\n * existing literal keys keep literal completion, and a directive selects only\n * its own options. Empty/incomplete objects offer literal keys and directive\n * starters. Memoized references keep recursive schemas finite and avoid copying\n * the component graph into every default/then/else branch.\n */\nexport function createBlockAuthoringSchema(\n definitions: Record<string, Schema>,\n componentDefinition: string,\n excludedComponents: readonly string[] = [],\n format: OfficeFormat = 'docx'\n): Schema {\n const prefix = `BlockTemplate_${componentDefinition}`;\n const references = referenceDescriptions(format);\n const measure = measureDescriptions(format);\n // `$if`, `$each` and `$count` take an operand: a slot pointer, or one\n // reference that reads the current `$each` entry, a slot or the context.\n const operand = (description: string): Schema => ({\n description,\n anyOf: [\n pointer(description),\n ...BLOCK_OPERAND_ROOTS.map((root) =>\n object({ [root]: pointer(references[root]) }, [root])\n ),\n ],\n });\n const bodyName = `${prefix}_Body`;\n const ref = (name: string): Schema => ({ $ref: `#/definitions/${name}` });\n if (definitions[bodyName]) return ref(bodyName);\n\n // Only resolve canonical input definitions. Generated schemas must never be\n // transformed again. Narrow the component root without changing the original.\n const originals: Record<string, Schema> = { ...definitions };\n const source = originals[componentDefinition];\n originals[componentDefinition] = {\n ...source,\n anyOf: (source.anyOf ?? [source]).filter(\n (branch: Schema) =>\n !excludedComponents.includes(branch.properties?.name?.const)\n ),\n };\n const resolve = (pointer: string): AuthoringSchema | undefined => {\n if (!pointer.startsWith('#/definitions/')) return undefined;\n let node: any = originals;\n for (const key of pointer.slice('#/definitions/'.length).split('/')) {\n const decoded = key.replace(/~1/g, '/').replace(/~0/g, '~');\n if (!node || typeof node !== 'object' || !Object.hasOwn(node, decoded))\n return undefined;\n node = node[decoded];\n }\n return typeof node === 'boolean' || (node && typeof node === 'object')\n ? node\n : undefined;\n };\n\n const values = new Map<string, string>();\n const literals = new Map<string, string>();\n let nextId = 0;\n const componentRef = ref(componentDefinition);\n const shared = new Map<string, string>();\n const share = (schema: Schema): Schema => {\n const key = JSON.stringify(schema);\n let name = shared.get(key);\n if (!name) {\n name = `${prefix}_Shared${nextId++}`;\n shared.set(key, name);\n definitions[name] = schema;\n }\n return ref(name);\n };\n const presence = Object.fromEntries(\n directiveNames.map((key) => [key, share(hasKey(key))])\n );\n const anyDirective = share({ anyOf: Object.values(presence) });\n const starterPrefixes = [\n ...new Set([\n '',\n ...directiveNames.flatMap((key) =>\n Array.from({ length: key.length - 1 }, (_, index) =>\n key.slice(0, index + 1)\n )\n ),\n ]),\n ];\n const starterObject = share({\n type: 'object',\n // An enum here would itself become a list of bogus property suggestions.\n propertyNames: {\n pattern: `^(?:${starterPrefixes.map((key) => key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|')})$`,\n },\n });\n\n function literal(schema: AuthoringSchema): AuthoringSchema {\n if (typeof schema === 'boolean') return schema;\n const key = JSON.stringify(schema);\n const cached = literals.get(key);\n if (cached) return { ...ref(cached), ...metadata(schema) };\n const name = `${prefix}_Literal${nextId++}`;\n literals.set(key, name);\n definitions[name] = {};\n const result: Schema = { ...schema };\n if (typeof schema.$ref === 'string') {\n const target = resolve(schema.$ref);\n if (target !== undefined) {\n const transformed = literal(target);\n if (typeof transformed === 'object') result.$ref = transformed.$ref;\n else {\n delete result.$ref;\n if (!transformed) result.not = {};\n }\n }\n }\n if (schema.properties)\n result.properties = Object.fromEntries(\n Object.entries(\n schema.properties as Record<string, AuthoringSchema>\n ).map(([key, value]) => [\n key,\n // Literal discriminators retain canonical component/version dispatch\n // and their individual choice descriptions.\n ['name', 'version'].includes(key) &&\n typeof value === 'object' &&\n typeof value.const === 'string'\n ? value\n : author(value),\n ])\n );\n if (schema.patternProperties)\n result.patternProperties = Object.fromEntries(\n Object.entries(\n schema.patternProperties as Record<string, AuthoringSchema>\n ).map(([key, value]) => [key, author(value)])\n );\n if (schema.items !== undefined)\n result.items = Array.isArray(schema.items)\n ? schema.items.map((item: AuthoringSchema) => author(item, true))\n : author(schema.items, true);\n for (const key of ['additionalProperties', 'additionalItems'])\n if (typeof schema[key] === 'object')\n result[key] = author(schema[key], key === 'additionalItems');\n for (const key of ['anyOf', 'oneOf', 'allOf'])\n if (Array.isArray(schema[key]))\n // Keep branches inline so canonical name-union restructuring still sees\n // their discriminators. Their nested value schemas are shared references.\n result[key] = schema[key].map((branch: AuthoringSchema) => {\n const transformed = literal(branch);\n return typeof branch === 'object' &&\n typeof branch.properties?.name?.const === 'string' &&\n typeof transformed === 'object' &&\n transformed.$ref\n ? definitions[transformed.$ref.slice('#/definitions/'.length)]\n : transformed;\n });\n // Conditions/negations inspect literal values, not binding syntax.\n for (const key of ['then', 'else'])\n if (schema[key] !== undefined) result[key] = literal(schema[key]);\n definitions[name] = result;\n return { ...ref(name), ...metadata(schema) };\n }\n\n function author(input: AuthoringSchema, sequence = false): AuthoringSchema {\n if (input === false) return false;\n // Property help stays on the reference at the use site. It must not cause\n // duplicate binding graphs for otherwise identical value constraints.\n const annotations = metadata(input);\n const schema = typeof input === 'object' ? { ...input } : input;\n if (typeof schema === 'object') {\n delete schema.description;\n delete schema.markdownDescription;\n }\n const key = `${sequence ? 'sequence' : 'value'}:${JSON.stringify(schema)}`;\n const cached = values.get(key);\n if (cached) return { ...ref(cached), ...annotations };\n const name = `${prefix}_Value${nextId++}`;\n values.set(key, name);\n definitions[name] = {};\n const self = ref(name);\n const types = possibleValueTypes(schema, resolve);\n if (types.size === 0) {\n definitions[name] = { allOf: [literal(schema)] };\n return self;\n }\n const value = () => (sequence ? author(schema) : self);\n const branch = () =>\n sequence ? { anyOf: [self, { type: 'array', items: self }] } : self;\n const item = () =>\n sequence ? value() : author(arrayItemSchema(schema, resolve));\n const specs: Partial<Record<BlockDirective, Schema>> = {};\n for (const directive of directiveNames) {\n const result = BLOCK_DIRECTIVES[directive].result;\n if (\n result !== 'dynamic' &&\n !types.has(result) &&\n !(sequence && result === 'array')\n )\n continue;\n switch (directive) {\n case '$slot':\n case '$item':\n case '$theme':\n case '$context':\n specs[directive] = object(\n {\n [directive]: pointer(references[directive]),\n default: describe(\n value(),\n 'Fallback value or binding used only when the referenced value is missing. Null, false and empty values do not trigger it.'\n ),\n ...(directive === '$slot' || directive === '$item'\n ? {\n props: {\n type: 'object',\n description:\n 'Component props merged beneath a component-slot value. Put placement (x, y, w, h, grid) and styling defaults here; the slot content may override styling but never placement.',\n },\n }\n : {}),\n },\n [directive]\n );\n break;\n case '$if':\n specs[directive] = object(\n {\n $if: operand(\n 'Test a slot by JSON Pointer, e.g. /subtitle, or a reference such as { \"$item\": \"/numeric\" }. Missing, null, false, empty text and empty arrays select else; zero selects then.'\n ),\n then: describe(\n branch(),\n 'Value or components to emit when the slot tested by $if is present.'\n ),\n else: describe(\n branch(),\n 'Value or components to emit otherwise. Omit to produce no output.'\n ),\n },\n ['$if', 'then']\n );\n break;\n case '$each':\n specs[directive] = object(\n {\n $each: operand(\n 'Repeat template for each entry in an array slot, e.g. /items, or in an array of the current entry, { \"$item\": \"/cells\" }. Read the current entry with $item.'\n ),\n template: describe(\n item(),\n 'One template evaluated per array entry. Use $item for the current entry and a group for multiple components.'\n ),\n },\n ['$each', 'template']\n );\n break;\n case '$count':\n specs[directive] = object(\n {\n $count: operand(\n 'Return the number of entries in an array slot, e.g. /items, or in an array of the current entry, { \"$item\": \"/cells\" }.'\n ),\n },\n ['$count']\n );\n break;\n case '$join':\n specs[directive] = object(\n {\n $join: {\n type: 'array',\n items: author({}),\n description:\n 'Evaluate these values or bindings and join them as text. Empty values are skipped unless keepEmpty is true.',\n },\n separator: {\n type: 'string',\n description:\n 'Text inserted between joined values. Defaults to an empty string.',\n },\n keepEmpty: {\n type: 'boolean',\n description:\n 'Keep missing, null, false, empty text and empty arrays in the join. Defaults to false.',\n },\n },\n ['$join']\n );\n break;\n case '$measure':\n specs[directive] = object(\n {\n $measure: {\n enum: ['width', 'height'],\n description: measure.axis,\n },\n fraction: {\n type: 'number',\n minimum: 0,\n maximum: 1,\n description:\n 'Fraction of the measured dimension, from 0 to 1. Defaults to 1.',\n },\n unit: {\n enum: ['pt', 'twip', 'in'],\n description: measure.unit,\n },\n },\n ['$measure']\n );\n break;\n default: {\n const exhaustive: never = directive;\n throw new Error(\n `Missing authoring schema for directive ${exhaustive}`\n );\n }\n }\n }\n definitions[name] = {\n allOf: [\n {\n if: anyDirective,\n then: {\n allOf: directiveNames.map((directive) => ({\n if: presence[directive],\n then: specs[directive]\n ? share({\n ...specs[directive],\n properties: Object.fromEntries(\n Object.entries(specs[directive]!.properties).map(\n ([key, property]) => [key, share(property as Schema)]\n )\n ),\n })\n : false,\n })),\n },\n else: literal(schema),\n },\n {\n // Keep starters while the first key is empty or a partial directive\n // (\"$\", \"$sl\", ...). Any ordinary or completed key ends this phase.\n // Prefixes come from the evaluator's directive registry.\n if: starterObject,\n then: {\n properties: Object.fromEntries(\n Object.entries(specs).map(([key, spec]) => [\n key,\n share(spec.properties[key]),\n ])\n ),\n },\n },\n ],\n };\n return { ...self, ...annotations };\n }\n\n definitions[bodyName] = author(componentRef, true) as Schema;\n return ref(bodyName);\n}\n","import {\n BlockEvaluationError,\n isBlockRecord,\n toAuthoredBlockPointer,\n type JsonBlockEvaluator,\n} from './evaluator';\n\ntype Rec = Record<string, unknown>;\n\nexport interface BlockCompositionOptions {\n /** Registered code component names. JSON never loads or installs them. */\n plugins: ReadonlySet<string>;\n /** Expand one registered component at its authored path into standard output. */\n render: (component: Rec, path: string) => Promise<unknown[]>;\n /** Plugin names kept unexpanded in the `preserved` tree (schema export, inspection). */\n preserve?: ReadonlySet<string>;\n}\n\nexport interface BlockComposition {\n /** Every block and plugin lowered to standard components. */\n standard: unknown;\n /** The same tree with preserved plugins left as authored. */\n preserved: unknown;\n}\n\n/**\n * One bounded expansion for document-local JSON and registered code, in both\n * directions: a plugin can emit a block, a block body or component slot can\n * name a plugin, and either can nest. Provenance survives each boundary\n * through the evaluator's source map; emitted output is wrapped in a `group`\n * whose pointer maps back to the plugin's authored node.\n *\n * Format-neutral: the host supplies the evaluator (its format, theme and\n * context) and validates the finished tree.\n */\nexport async function composeBlocksWithPlugins(\n evaluator: JsonBlockEvaluator,\n document: unknown,\n options: BlockCompositionOptions\n): Promise<BlockComposition> {\n const preserve = options.preserve ?? new Set<string>();\n let visited = 0;\n const walk = async (\n value: unknown,\n path: string,\n depth: number\n ): Promise<BlockComposition> => {\n if (depth > 64 || ++visited > 100000)\n throw new BlockEvaluationError([\n {\n path: toAuthoredBlockPointer(evaluator.sourceMap, path),\n code: 'block_expansion_limit',\n message:\n 'Combined plugin/block expansion exceeds depth/node limits (64/100000).',\n },\n ]);\n if (Array.isArray(value)) {\n const children: BlockComposition[] = [];\n for (let i = 0; i < value.length; i++)\n children.push(await walk(value[i], `${path}/${i}`, depth + 1));\n return {\n standard: children.map((c) => c.standard),\n preserved: children.map((c) => c.preserved),\n };\n }\n if (!isBlockRecord(value) || value.enabled === false)\n return { standard: value, preserved: value };\n if (value.name === 'block')\n return walk(evaluator.expand(value, path, depth), path, depth + 1);\n const standard: Rec = { ...value };\n const kept: Rec = { ...value };\n for (const [key, item] of Object.entries(value)) {\n if (path === '/props' && key === 'blocks') continue;\n const processed = await walk(item, `${path}/${key}`, depth + 1);\n Object.defineProperty(standard, key, {\n value: processed.standard,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n Object.defineProperty(kept, key, {\n value: processed.preserved,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n if (typeof value.name === 'string' && options.plugins.has(value.name)) {\n const source = toAuthoredBlockPointer(evaluator.sourceMap, path);\n const emitted = await options.render(standard, source);\n evaluator.sourceMap[`${path}/children`] = source;\n const processed = await walk(emitted, `${path}/children`, depth + 1);\n return {\n standard: { name: 'group', children: processed.standard },\n preserved: preserve.has(value.name)\n ? value\n : { name: 'group', children: processed.preserved },\n };\n }\n return { standard, preserved: kept };\n };\n return walk(document, '', 0);\n}\n","/**\n * Editor assistance derived from a document's own block definitions.\n *\n * A published schema cannot know which blocks one document defines, so the\n * exported `block` component accepts any `ref` and any `slots`. Everything\n * here is computed from the definitions actually present — in the editor on\n * every change, on the server for a reference catalog — and expressed in\n * standard draft-07 so the JSON language service completes, hovers and\n * diagnoses exactly what the runtime validator will accept: the names in\n * `props.blocks`, each one's slots with their descriptions, defaults and\n * constraints, and the placement a component slot may not carry.\n */\nimport { Value } from '@sinclair/typebox/value';\nimport type { OfficeFormat } from '../rendering/types';\nimport { blockSlotsJsonSchema } from './metadata';\nimport {\n BLOCK_SLOT_PLACEMENT_PROPS,\n blockPointerKey,\n isBlockRecord,\n readBlockDefinitions,\n validateBlockDefinitions,\n} from './evaluator';\nimport {\n BlockDefinitionsSchema,\n type BlockSlot,\n type JsonBlockDefinition,\n} from './schema';\n\ntype Schema = Record<string, any>;\n\n/** A block invocation as authored: the component the editor inserts. */\nexport interface BlockInvocationExample {\n name: 'block';\n props: { ref: string; slots?: Record<string, unknown> };\n}\n\nconst clone = <T>(value: T): T => JSON.parse(JSON.stringify(value));\n\nfunction range(\n minimum: number | undefined,\n maximum: number | undefined,\n unit: string\n): string | undefined {\n if (minimum !== undefined && maximum !== undefined)\n return minimum === maximum\n ? `${minimum} ${unit}`\n : `${minimum}–${maximum} ${unit}`;\n if (minimum !== undefined) return `at least ${minimum} ${unit}`;\n if (maximum !== undefined) return `at most ${maximum} ${unit}`;\n return undefined;\n}\n\n/**\n * A slot's contract as short facts, in one order, for every place that shows\n * it: the editor hover, the AI prompt, a catalog summary. \"Required\" means\n * the caller must supply a value — a slot with a default never is.\n */\nexport function blockSlotFacts(slot: BlockSlot): string[] {\n const facts: string[] = [];\n if (slot.required && slot.default === undefined) facts.push('Required');\n if (slot.default !== undefined)\n facts.push(`Default: \\`${JSON.stringify(slot.default)}\\``);\n if (slot.type === 'component')\n facts.push('A component; placement stays in the definition');\n if (slot.enum)\n facts.push(\n `One of ${slot.enum.map((value) => `\\`${JSON.stringify(value)}\\``).join(', ')}`\n );\n const length = range(slot.minLength, slot.maxLength, 'characters');\n if (length) facts.push(length);\n if (slot.maxWords !== undefined) facts.push(`at most ${slot.maxWords} words`);\n if (slot.oneLine) facts.push('one line');\n const bounds = range(slot.minimum, slot.maximum, '');\n if (bounds) facts.push(bounds.trim());\n const entries = range(slot.minItems, slot.maxItems, 'entries');\n if (entries) facts.push(entries);\n if (slot.role) facts.push(`Role: ${slot.role}`);\n return facts;\n}\n\n/** The hover text for a slot: its description, then its contract in one line. */\nexport function blockSlotMarkdown(slot: BlockSlot): string {\n return [slot.description, blockSlotFacts(slot).join(' · ')]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * JSON Schema for one slot as the editor should see it. Unlike the portable\n * `blockSlotJsonSchema`, a component slot references the real component\n * definition — so a chart placed in it completes like any other chart — with\n * the placement props the runtime rejects flagged at the key they appear on.\n */\nexport function blockSlotEditorSchema(\n slot: BlockSlot,\n componentRef?: Schema\n): Schema {\n let schema: Schema;\n if (slot.type === 'component') {\n schema = componentRef\n ? {\n allOf: [\n componentRef,\n {\n properties: {\n props: {\n propertyNames: {\n not: { enum: [...BLOCK_SLOT_PLACEMENT_PROPS] },\n errorMessage:\n 'Block placement belongs in the definition, not in a component slot.',\n },\n },\n },\n },\n ],\n }\n : {\n type: 'object',\n properties: { name: { type: 'string' } },\n required: ['name'],\n };\n } else {\n const { oneLine, properties, items, ...rest } = slot;\n // Runtime-only facts leave the schema and go into the hover text.\n for (const key of ['role', 'required', 'maxWords', 'description'] as const)\n delete rest[key];\n schema = { ...rest };\n if (oneLine) schema.pattern = '^[^\\\\r\\\\n]*$';\n if (items) schema.items = blockSlotEditorSchema(items, componentRef);\n if (properties) {\n schema.properties = Object.fromEntries(\n Object.entries(properties).map(([key, value]) => [\n key,\n blockSlotEditorSchema(value, componentRef),\n ])\n );\n schema.required = Object.entries(properties)\n .filter(([, value]) => value.required && value.default === undefined)\n .map(([key]) => key);\n schema.additionalProperties = false;\n }\n }\n if (slot.description) schema.description = slot.description;\n const markdown = blockSlotMarkdown(slot);\n if (markdown) schema.markdownDescription = markdown;\n return schema;\n}\n\n/** The `slots` object of an invocation of this definition. */\nexport function blockSlotsEditorSchema(\n definition: JsonBlockDefinition,\n componentRef?: Schema\n): Schema {\n return {\n type: 'object',\n additionalProperties: false,\n description:\n 'Input values keyed by the slot names declared in the referenced block definition.',\n properties: Object.fromEntries(\n Object.entries(definition.slots).map(([key, slot]) => [\n key,\n blockSlotEditorSchema(slot, componentRef),\n ])\n ),\n required: Object.entries(definition.slots)\n .filter(([, slot]) => slot.required && slot.default === undefined)\n .map(([key]) => key),\n };\n}\n\n/**\n * The `props` of a `block` component given this document's definitions:\n * `ref` enumerates the names with their descriptions, and each name\n * dispatches `slots` to its own schema. With no definitions the reference\n * stays a free string — the runtime says which name is missing.\n */\nexport function blockInvocationPropsSchema(\n definitions: Record<string, JsonBlockDefinition>,\n componentRef?: Schema\n): Schema {\n const names = Object.keys(definitions);\n const schema: Schema = {\n type: 'object',\n additionalProperties: false,\n required: ['ref'],\n properties: {\n ref: {\n type: 'string',\n minLength: 1,\n description: 'Name in this document’s props.blocks.',\n ...(names.length && {\n anyOf: names.map((name) => ({\n const: name,\n type: 'string',\n description:\n definitions[name].description ??\n `Block \"${name}\", defined in this document.`,\n })),\n }),\n },\n slots: {\n type: 'object',\n description:\n 'Input values keyed by the slot names declared in the referenced block definition.',\n },\n },\n };\n if (names.length)\n schema.allOf = names.map((name) => ({\n if: { properties: { ref: { const: name } }, required: ['ref'] },\n then: {\n properties: {\n slots: blockSlotsEditorSchema(definitions[name], componentRef),\n },\n },\n }));\n return schema;\n}\n\n/** Where the document-aware invocation props go in an exported schema. */\nexport interface DocumentBlockTarget {\n /** A component definition under `definitions`, typically one per renderer. */\n name: string;\n /**\n * What a component slot accepts — the content a slide or a section holds,\n * as a reference into the same schema. Omitted, a component slot only asks\n * for a `name`.\n */\n componentRef?: Schema;\n}\n\n/**\n * Install the document-aware invocation props on every `block` branch inside\n * the targeted component definitions — the definition's own branch and the\n * copies a container inlines for its children — so an invocation completes\n * the same wherever a slide or section places it. References out of the\n * definition are not followed: block bodies live in their own derived\n * definitions and keep their binding-aware props. Mutates in place; call on\n * a copy of the shared schema.\n */\nexport function applyDocumentBlocksToSchema(\n schema: Schema,\n definitions: Record<string, JsonBlockDefinition>,\n targets: readonly DocumentBlockTarget[]\n): void {\n for (const target of targets) {\n const definition = schema.definitions?.[target.name];\n if (!definition) continue;\n const props = blockInvocationPropsSchema(definitions, target.componentRef);\n const seen = new Set<object>();\n const walk = (node: unknown): void => {\n if (!node || typeof node !== 'object' || seen.has(node)) return;\n seen.add(node);\n if (Array.isArray(node)) {\n node.forEach(walk);\n return;\n }\n const value = node as Schema;\n if (value.properties?.name?.const === 'block' && value.properties.props) {\n value.properties.props = clone(props);\n return;\n }\n for (const [key, child] of Object.entries(value))\n if (key !== '$ref') walk(child);\n };\n walk(definition);\n }\n}\n\n/** Every `block` invocation reachable from a node, in document order. */\nfunction invocations(\n node: unknown,\n visit: (ref: string, invocation: Record<string, unknown>) => void\n): void {\n if (Array.isArray(node)) {\n node.forEach((item) => invocations(item, visit));\n return;\n }\n if (!isBlockRecord(node)) return;\n if (\n node.name === 'block' &&\n isBlockRecord(node.props) &&\n typeof node.props.ref === 'string'\n )\n visit(node.props.ref, node);\n for (const value of Object.values(node)) invocations(value, visit);\n}\n\n/**\n * The definitions a block needs beside itself, dependencies first, so a\n * copied definition never leaves an unresolved reference behind. Unknown\n * references and cycles are skipped: the runtime reports those.\n */\nexport function blockDependencies(\n definitions: Record<string, JsonBlockDefinition>,\n name: string\n): string[] {\n const order: string[] = [];\n const seen = new Set<string>([name]);\n const walk = (current: string): void => {\n const definition = Object.prototype.hasOwnProperty.call(\n definitions,\n current\n )\n ? definitions[current]\n : undefined;\n if (!definition) return;\n invocations(\n [definition.body, definition.section, definition.slide],\n (ref) => {\n if (seen.has(ref)) return;\n seen.add(ref);\n if (!Object.prototype.hasOwnProperty.call(definitions, ref)) return;\n walk(ref);\n order.push(ref);\n }\n );\n };\n walk(name);\n return order;\n}\n\nfunction exampleValue(\n slot: BlockSlot,\n name: string,\n format: OfficeFormat\n): unknown {\n if (slot.default !== undefined) return clone(slot.default);\n if (slot.enum?.length) return slot.enum[0];\n switch (slot.type) {\n case 'string':\n return name;\n case 'number':\n case 'integer': {\n const minimum = slot.minimum ?? 0;\n return slot.maximum !== undefined && slot.maximum < minimum\n ? slot.maximum\n : minimum;\n }\n case 'boolean':\n return true;\n case 'array': {\n // Typical cardinality: three entries, pulled inside the declared bounds.\n const count = Math.min(\n Math.max(3, slot.minItems ?? 0),\n slot.maxItems ?? Number.POSITIVE_INFINITY\n );\n const item = slot.items ?? { type: 'string' };\n return Array.from({ length: count }, (_, index) =>\n exampleValue(item, `${name} ${index + 1}`, format)\n );\n }\n case 'object':\n return exampleSlots(slot.properties ?? {}, format);\n case 'component':\n return format === 'docx'\n ? { name: 'paragraph', props: { text: name } }\n : { name: 'text', props: { text: name } };\n default:\n return name;\n }\n}\n\n/** Required slots and role-bearing chrome; everything else stays omitted. */\nfunction exampleSlots(\n slots: Record<string, BlockSlot>,\n format: OfficeFormat\n): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(slots)\n .filter(\n ([, slot]) => (slot.required && slot.default === undefined) || slot.role\n )\n .map(([key, slot]) => [key, exampleValue(slot, key, format)])\n );\n}\n\n/**\n * A valid invocation to insert: the first one the source document makes, if\n * it makes one — real content, at the cardinality its author chose — else\n * one synthesized from the slots at typical cardinality.\n */\nexport function blockInvocationExample(\n name: string,\n definition: JsonBlockDefinition,\n options: { document?: unknown; format: OfficeFormat }\n): BlockInvocationExample {\n let found: BlockInvocationExample | undefined;\n if (isBlockRecord(options.document)) {\n // Authored slides only: the definitions themselves also invoke blocks.\n const authored = Object.fromEntries(\n Object.entries(options.document).filter(([key]) => key !== 'props')\n );\n invocations(authored, (ref, invocation) => {\n if (found || ref !== name) return;\n const props = invocation.props as Record<string, unknown>;\n found = {\n name: 'block',\n props: {\n ref,\n ...(isBlockRecord(props.slots) && { slots: clone(props.slots) }),\n },\n };\n });\n }\n return (\n found ?? {\n name: 'block',\n props: {\n ref: name,\n slots: exampleSlots(definition.slots, options.format),\n },\n }\n );\n}\n\n/** An authoring reference extracted from a complete document. */\nexport interface BlockReference {\n name: string;\n format: OfficeFormat;\n /** The document the definition comes from. */\n template: string;\n definitionPointer: string;\n description: string;\n definition: JsonBlockDefinition;\n /** Portable slot schema, as `jto://blocks` publishes it. */\n slotsSchema: Record<string, unknown>;\n /** A valid invocation at typical cardinality. */\n example: BlockInvocationExample;\n /** Other definitions of the same document this one invokes, dependencies first. */\n dependencies: string[];\n}\n\n/**\n * Every block a complete document defines, as a reference an editor or an\n * agent can copy: definition, dependencies and a working invocation. A\n * document whose definitions do not validate contributes nothing — a\n * reference must be copyable as is.\n */\nexport function blockReferencesFromDocument(\n document: unknown,\n source: { template: string; format: OfficeFormat }\n): BlockReference[] {\n const definitions = readBlockDefinitions(document);\n if (\n !Value.Check(BlockDefinitionsSchema, definitions) ||\n validateBlockDefinitions(definitions, source.format).length > 0\n )\n return [];\n return Object.entries(definitions).map(([name, definition]) => ({\n name,\n format: source.format,\n template: source.template,\n definitionPointer: `/props/blocks/${blockPointerKey(name)}`,\n description: definition.description ?? '',\n definition,\n slotsSchema: blockSlotsJsonSchema(definition),\n example: blockInvocationExample(name, definition, {\n document,\n format: source.format,\n }),\n dependencies: blockDependencies(definitions, name),\n }));\n}\n","/**\n * Deep Merge Utilities\n * Generic deep-merge helpers used by both docx and pptx\n * componentDefaults resolution systems.\n */\n\nfunction isObject(item: any): boolean {\n return item !== null && typeof item === 'object' && !Array.isArray(item);\n}\n\nfunction deepMerge<T>(target: any, source: any): T {\n const output = { ...target };\n\n if (isObject(target) && isObject(source)) {\n Object.keys(source).forEach((key) => {\n if (isObject(source[key])) {\n // Recursing into a non-object default would spread it — a scalar\n // theme default (`borderColor: '#f0f0f0'`) turned a user's per-side\n // object into `{0: '#', 1: 'f', …}`, silently erasing the user value\n // it was supposed to yield to.\n if (!(key in target) || !isObject(target[key])) {\n output[key] = source[key];\n } else {\n output[key] = deepMerge(target[key], source[key]);\n }\n } else {\n output[key] = source[key];\n }\n });\n }\n\n return output as T;\n}\n\n/**\n * Merge theme defaults with user-provided configuration.\n * User config takes precedence over theme defaults.\n * Uses deep merge to preserve nested objects.\n * Arrays are replaced wholesale, not merged per-element.\n */\nexport function mergeWithDefaults<T>(\n userConfig: T,\n themeDefaults: Partial<T>\n): T {\n return deepMerge<T>(themeDefaults, userConfig);\n}\n","/**\n * Whether a service URL stays on this machine or a private network.\n *\n * The question the `highcharts` component has to answer before it posts a\n * chart — every series, label and title — to an export server. Only what an\n * address itself proves counts: loopback, RFC 1918, link-local and\n * unique-local literals, `localhost`, and the special-use names reserved for\n * private resolution (`.local`, `.internal`, `.home.arpa`). A hostname that\n * DNS decides — a bare label, a `.corp` — is not guessed at: it needs\n * `services.highcharts.allowRemote`, like any other.\n */\nexport function isPrivateServiceUrl(url: string): boolean {\n let hostname: string;\n try {\n hostname = new URL(\n /^https?:\\/\\//i.test(url.trim()) ? url.trim() : `http://${url.trim()}`\n ).hostname.toLowerCase();\n } catch {\n return false;\n }\n const host = hostname.replace(/^\\[|\\]$/g, '').replace(/\\.$/, '');\n if (host === 'localhost' || host.endsWith('.localhost')) return true;\n if (host === '::1' || /^f[cd][0-9a-f]{2}:/.test(host)) return true;\n if (/^fe[89ab][0-9a-f]:/.test(host)) return true;\n const v4 = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(host);\n if (v4) {\n const [a, b] = [Number(v4[1]), Number(v4[2])];\n return (\n a === 127 ||\n a === 10 ||\n (a === 172 && b >= 16 && b <= 31) ||\n (a === 192 && b === 168) ||\n (a === 169 && b === 254)\n );\n }\n return /\\.(local|internal|home\\.arpa)$/.test(host);\n}\n\n/** Warning code for a chart posted outside the private network. */\nexport const REMOTE_EXPORT_WARNING = 'W_HIGHCHARTS_REMOTE_EXPORT';\n\n/**\n * A public export server is a decision, not a default: the request carries\n * the whole chart, data included. Throws unless the caller opted in; when it\n * did, returns the sentence each pipeline records as a warning.\n */\nexport function remoteExportNotice(\n serverUrl: string,\n allowRemote: boolean | undefined\n): string | undefined {\n if (isPrivateServiceUrl(serverUrl)) return undefined;\n if (!allowRemote) {\n throw new Error(\n `Highcharts export server ${serverUrl} is outside this machine and its private networks, ` +\n 'and a chart is posted whole — every series, label and title. ' +\n 'Run the export server locally (pnpm dlx highcharts-export-server --enableServer true), ' +\n 'or set services.highcharts.allowRemote (HIGHCHARTS_ALLOW_REMOTE=1) to send chart data there deliberately.'\n );\n }\n return `Chart data — every series, label and title — was sent to ${serverUrl}, outside this machine and its private networks (services.highcharts.allowRemote).`;\n}\n"],"mappings":"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","names":["weight","weight","cacheKey","weight","weight","HEADER_SIZE","TABLE_RECORD_SIZE","weight","weight","referenced","warnings","pointer","result","Value","Value","invocations","pointer","pointer","key","Value","Value"]}