@json-to-office/core-docx 0.26.1 → 0.28.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/themes/defaults.ts","../src/templates/themes/minimal.docx.theme.json","../src/templates/themes/corporate.docx.theme.json","../src/templates/themes/modern.docx.theme.json","../src/templates/themes/apex.docx.theme.json","../src/templates/themes/devportal.docx.theme.json","../src/templates/themes/index.ts","../src/styles/utils/colorUtils.ts","../src/styles/utils/styleHelpers.ts","../src/styles/utils/layoutUtils.ts","../src/themes/json/parser.ts","../src/themes/json/validator.ts","../src/themes/json/loader.ts","../src/themes/json/index.ts","../src/styles/index.ts","../src/utils/widthUtils.ts","../src/utils/docxImagePositioning.ts","../src/core/generator.ts","../src/types/index.ts","../src/core/generationContext.ts","../src/styles/theme-resolver.ts","../src/themes/overrides.ts","../src/utils/formatters.ts","../src/styles/utils/componentDefaults.ts","../src/styles/utils/resolveComponentTree.ts","../src/core/structure.ts","../src/core/layout.ts","../src/core/render.ts","../src/utils/imageUtils.ts","../src/styles/themeToDocxAdapter.ts","../src/cache/index.ts","../src/cache/key-generator.ts","../src/utils/revisionUtils.ts","../src/utils/unicode.ts","../src/utils/placeholderProcessor.ts","../src/utils/textParser.ts","../src/utils/generationContext.ts","../src/core/cached-render.ts","../src/core/content.ts","../src/utils/bookmarkRegistry.ts","../src/components/heading.ts","../src/utils/numberingConfig.ts","../src/components/paragraph.ts","../src/components/list.ts","../src/components/image.ts","../src/components/text-box.ts","../src/styles/utils/borderUtils.ts","../src/styles/utils/cellUtils.ts","../src/components/table.ts","../src/components/section.ts","../src/components/columns.ts","../src/components/statistic.ts","../src/components/toc/index.ts","../src/components/highcharts.ts","../src/utils/environment.ts","../src/utils/serviceClient.ts","../src/components/visual.ts","../src/components/text-space-after.ts","../src/plugin/createComponent.ts","../src/core/fontResolution.ts","../src/utils/packageDocument.ts","../src/utils/fixFloatingImageIds.ts","../src/json/parser.ts","../src/json/normalizer.ts","../src/json/filesystem.ts","../src/core/flattenVisuals.ts","../src/utils/warningsDocument.ts","../src/index.ts","../src/templates/documents/index.ts","../src/utils/exampleRunner.ts","../src/plugin/version-resolver.ts","../src/plugin/validation.ts","../src/plugin/createDocumentGenerator.ts","../src/plugin/schema.ts"],"sourcesContent":["/**\n * Default theme values and utilities for handling optional theme properties\n */\n\nimport type { ThemeConfigJson } from '@json-to-office/shared-docx';\n\n/**\n * Default colors for themes\n */\nexport const DEFAULT_COLORS = {\n primary: '#000000',\n secondary: '#666666',\n accent: '#0066CC',\n text: '#000000',\n background: '#FFFFFF',\n border: '#CCCCCC',\n // Semantic colors\n textPrimary: '#000000',\n textSecondary: '#666666',\n textMuted: '#999999',\n borderPrimary: '#CCCCCC',\n borderSecondary: '#E5E5E5',\n backgroundPrimary: '#FFFFFF',\n backgroundSecondary: '#F5F5F5',\n};\n\n/**\n * Default fonts for themes\n */\nexport const DEFAULT_FONTS = {\n heading: { family: 'Arial', size: 20 },\n body: { family: 'Arial', size: 11 },\n mono: { family: 'Courier New', size: 10 },\n light: { family: 'Arial', size: 24 },\n};\n\n/**\n * Default styles for themes\n */\nexport const DEFAULT_STYLES = {\n normal: {\n font: 'body' as const,\n size: 11,\n color: '#000000',\n alignment: 'left' as const,\n lineSpacing: {\n type: 'single' as const,\n value: 1,\n },\n spacing: {\n after: 6,\n },\n },\n heading1: {\n font: 'heading' as const,\n size: 24,\n color: '#000000',\n bold: true,\n spacing: {\n before: 12,\n after: 12,\n },\n },\n heading2: {\n font: 'heading' as const,\n size: 20,\n color: '#000000',\n bold: true,\n spacing: {\n before: 10,\n after: 10,\n },\n },\n heading3: {\n font: 'heading' as const,\n size: 16,\n color: '#000000',\n bold: true,\n spacing: {\n before: 8,\n after: 8,\n },\n },\n heading4: {\n font: 'heading' as const,\n size: 14,\n color: '#000000',\n bold: true,\n spacing: {\n before: 6,\n after: 6,\n },\n },\n heading5: {\n font: 'heading' as const,\n size: 12,\n color: '#000000',\n bold: true,\n spacing: {\n before: 6,\n after: 6,\n },\n },\n heading6: {\n font: 'heading' as const,\n size: 11,\n color: '#000000',\n bold: true,\n spacing: {\n before: 6,\n after: 6,\n },\n },\n};\n\n/**\n * Default page settings\n */\nexport const DEFAULT_PAGE = {\n size: 'LETTER' as const,\n margins: {\n top: 720,\n bottom: 720,\n left: 720,\n right: 720,\n header: 360,\n footer: 360,\n gutter: 0,\n },\n};\n\n/**\n * Ensures theme has all required properties with defaults\n */\nexport function ensureThemeDefaults(\n theme: Partial<ThemeConfigJson>\n): ThemeConfigJson {\n return {\n $schema: theme.$schema,\n name: theme.name || 'default',\n displayName: theme.displayName || 'Default Theme',\n description: theme.description || 'Default theme configuration',\n version: theme.version || '1.0.0',\n colors: {\n ...DEFAULT_COLORS,\n ...(theme.colors || {}),\n },\n fonts: {\n heading: { ...DEFAULT_FONTS.heading, ...(theme.fonts?.heading || {}) },\n body: { ...DEFAULT_FONTS.body, ...(theme.fonts?.body || {}) },\n mono: { ...DEFAULT_FONTS.mono, ...(theme.fonts?.mono || {}) },\n light: { ...DEFAULT_FONTS.light, ...(theme.fonts?.light || {}) },\n },\n page: {\n ...DEFAULT_PAGE,\n ...(theme.page || {}),\n margins: {\n ...DEFAULT_PAGE.margins,\n ...(theme.page?.margins || {}),\n },\n },\n styles: theme.styles,\n componentDefaults: theme.componentDefaults,\n };\n}\n\n/**\n * Type guard to check if a theme has all required properties\n */\nexport function isCompleteTheme(theme: unknown): theme is ThemeConfigJson {\n const t = theme as Record<string, unknown>;\n return (\n t &&\n typeof t === 'object' &&\n !!t.colors &&\n !!t.fonts &&\n !!t.page &&\n typeof t.name === 'string' &&\n typeof t.displayName === 'string' &&\n typeof t.description === 'string' &&\n typeof t.version === 'string'\n );\n}\n\n/**\n * Safe getter for theme colors with defaults\n */\nexport function getThemeColors(theme: Partial<ThemeConfigJson>) {\n return {\n ...DEFAULT_COLORS,\n ...(theme.colors || {}),\n };\n}\n\n/**\n * Safe getter for theme fonts with defaults\n */\nexport function getThemeFonts(theme: Partial<ThemeConfigJson>) {\n return {\n ...DEFAULT_FONTS,\n ...(theme.fonts || {}),\n };\n}\n\n/**\n * Safe getter for theme styles with defaults\n */\nexport function getThemeStyles(theme: Partial<ThemeConfigJson>) {\n return {\n ...DEFAULT_STYLES,\n ...(theme.styles || {}),\n };\n}\n\n/**\n * Safe getter for normal style with defaults\n */\nexport function getNormalStyle(theme: Partial<ThemeConfigJson>) {\n const styles = getThemeStyles(theme);\n return {\n ...DEFAULT_STYLES.normal,\n ...(styles.normal || {}),\n };\n}\n","{\n \"$schema\": \"../../../../shared/json-schemas/theme.schema.json\",\n \"name\": \"minimal\",\n \"displayName\": \"Minimal Clean\",\n \"description\": \"A clean, minimalist theme focused on readability and elegant simplicity\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#000000\",\n \"secondary\": \"#666666\",\n \"accent\": \"#2c3e50\",\n \"background\": \"#ffffff\",\n \"text\": \"#2c2c2c\",\n \"border\": \"#f0f0f0\",\n \"textPrimary\": \"#000000\",\n \"textSecondary\": \"#4a4a4a\",\n \"textMuted\": \"#999999\",\n \"borderPrimary\": \"#e0e0e0\",\n \"borderSecondary\": \"#f5f5f5\",\n \"backgroundPrimary\": \"#ffffff\",\n \"backgroundSecondary\": \"#fafafa\"\n },\n \"fonts\": {\n \"heading\": {\n \"family\": \"Arial\",\n \"size\": 24\n },\n \"body\": {\n \"family\": \"Arial\",\n \"size\": 11\n },\n \"mono\": {\n \"family\": \"Menlo\",\n \"size\": 10\n },\n \"light\": {\n \"family\": \"Arial\",\n \"size\": 24\n }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1080,\n \"right\": 1080,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"#000000\",\n \"lineSpacing\": {\n \"type\": \"multiple\",\n \"value\": 1.5\n },\n \"alignment\": \"justify\",\n \"spacing\": {\n \"after\": 9\n }\n },\n \"heading1\": {\n \"font\": \"light\",\n \"size\": 24,\n \"bold\": false,\n \"color\": \"#000000\",\n \"spacing\": {\n \"before\": 18,\n \"after\": 12\n },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"characterSpacing\": {\n \"type\": \"expanded\",\n \"value\": 1.2\n }\n },\n \"heading2\": {\n \"font\": \"light\",\n \"size\": 20,\n \"bold\": false,\n \"color\": \"#000000\",\n \"spacing\": {\n \"before\": 12,\n \"after\": 9\n },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"characterSpacing\": {\n \"type\": \"expanded\",\n \"value\": 0.8\n }\n },\n \"heading3\": {\n \"font\": \"heading\",\n \"size\": 16,\n \"bold\": false,\n \"color\": \"#2c2c2c\",\n \"spacing\": {\n \"before\": 9,\n \"after\": 6\n },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading4\": {\n \"font\": \"heading\",\n \"size\": 14,\n \"bold\": true,\n \"color\": \"#4a4a4a\",\n \"spacing\": {\n \"before\": 6,\n \"after\": 4\n },\n \"keepNext\": true\n },\n \"heading5\": {\n \"font\": \"heading\",\n \"size\": 12,\n \"bold\": false,\n \"italic\": true,\n \"color\": \"#666666\",\n \"spacing\": {\n \"before\": 4,\n \"after\": 3\n }\n },\n \"heading6\": {\n \"font\": \"light\",\n \"size\": 11,\n \"bold\": false,\n \"color\": \"#999999\",\n \"spacing\": {\n \"before\": 3,\n \"after\": 2\n }\n },\n \"title\": {\n \"font\": \"light\",\n \"bold\": false,\n \"color\": \"#000000\",\n \"alignment\": \"left\",\n \"spacing\": {\n \"before\": 0,\n \"after\": 24\n },\n \"characterSpacing\": {\n \"type\": \"condensed\",\n \"value\": 20\n }\n },\n \"subtitle\": {\n \"font\": \"light\",\n \"size\": 16,\n \"italic\": false,\n \"color\": \"#666666\",\n \"alignment\": \"left\",\n \"spacing\": {\n \"before\": 0,\n \"after\": 18\n }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#f0f0f0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"•\",\n \"indent\": 3\n },\n \"image\": {\n \"alignment\": \"left\"\n },\n \"statistic\": {\n \"alignment\": \"left\"\n },\n \"section\": {\n \"pageBreak\": false\n },\n \"heading\": {\n \"numbering\": false\n }\n }\n}\n","{\n \"name\": \"corporate\",\n \"displayName\": \"Corporate Professional\",\n \"description\": \"A polished corporate theme with blue accents and structured typography\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#1a365d\",\n \"secondary\": \"#2D3748\",\n \"accent\": \"#3182CE\",\n \"text\": \"#1A202C\",\n \"background\": \"#FFFFFF\",\n \"border\": \"#E2E8F0\",\n \"textPrimary\": \"#1A202C\",\n \"textSecondary\": \"#4A5568\",\n \"textMuted\": \"#A0AEC0\",\n \"borderPrimary\": \"#CBD5E0\",\n \"borderSecondary\": \"#E2E8F0\",\n \"backgroundPrimary\": \"#FFFFFF\",\n \"backgroundSecondary\": \"#F7FAFC\"\n },\n \"fonts\": {\n \"heading\": { \"family\": \"Georgia\", \"size\": 26 },\n \"body\": { \"family\": \"Calibri\", \"size\": 11 },\n \"mono\": { \"family\": \"Consolas\", \"size\": 10 },\n \"light\": { \"family\": \"Georgia\", \"size\": 26 }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1200,\n \"right\": 1200,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"#1A202C\",\n \"lineSpacing\": { \"type\": \"multiple\", \"value\": 1.4 },\n \"alignment\": \"justify\",\n \"spacing\": { \"after\": 8 }\n },\n \"heading1\": {\n \"font\": \"heading\",\n \"size\": 26,\n \"bold\": false,\n \"color\": \"primary\",\n \"spacing\": { \"before\": 24, \"after\": 12 },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"borders\": {\n \"bottom\": {\n \"style\": \"single\",\n \"size\": 2,\n \"color\": \"primary\",\n \"space\": 6\n }\n }\n },\n \"heading2\": {\n \"font\": \"heading\",\n \"size\": 18,\n \"bold\": false,\n \"color\": \"secondary\",\n \"spacing\": { \"before\": 18, \"after\": 8 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading3\": {\n \"font\": \"body\",\n \"size\": 13,\n \"bold\": true,\n \"color\": \"accent\",\n \"spacing\": { \"before\": 12, \"after\": 6 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"title\": {\n \"font\": \"light\",\n \"size\": 32,\n \"bold\": false,\n \"color\": \"primary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 18 }\n },\n \"subtitle\": {\n \"font\": \"body\",\n \"size\": 16,\n \"italic\": false,\n \"color\": \"textSecondary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 24 }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#E2E8F0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"\\u2022\",\n \"indent\": 3\n },\n \"statistic\": {\n \"alignment\": \"center\"\n },\n \"section\": {\n \"pageBreak\": false\n },\n \"heading\": {\n \"numbering\": false\n }\n }\n}\n","{\n \"name\": \"modern\",\n \"displayName\": \"Modern Clean\",\n \"description\": \"A contemporary theme with vibrant accents and generous whitespace\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#6D28D9\",\n \"secondary\": \"#1E293B\",\n \"accent\": \"#0891B2\",\n \"text\": \"#0F172A\",\n \"background\": \"#FFFFFF\",\n \"border\": \"#E2E8F0\",\n \"textPrimary\": \"#0F172A\",\n \"textSecondary\": \"#475569\",\n \"textMuted\": \"#94A3B8\",\n \"borderPrimary\": \"#CBD5E1\",\n \"borderSecondary\": \"#E2E8F0\",\n \"backgroundPrimary\": \"#FFFFFF\",\n \"backgroundSecondary\": \"#F8FAFC\"\n },\n \"fonts\": {\n \"heading\": { \"family\": \"Helvetica\", \"size\": 28 },\n \"body\": { \"family\": \"Helvetica\", \"size\": 11 },\n \"mono\": { \"family\": \"Menlo\", \"size\": 10 },\n \"light\": { \"family\": \"Helvetica\", \"size\": 28 }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1080,\n \"right\": 1080,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"#0F172A\",\n \"lineSpacing\": { \"type\": \"multiple\", \"value\": 1.5 },\n \"alignment\": \"left\",\n \"spacing\": { \"after\": 10 }\n },\n \"heading1\": {\n \"font\": \"heading\",\n \"size\": 28,\n \"bold\": true,\n \"color\": \"primary\",\n \"spacing\": { \"before\": 24, \"after\": 14 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading2\": {\n \"font\": \"heading\",\n \"size\": 20,\n \"bold\": true,\n \"color\": \"secondary\",\n \"spacing\": { \"before\": 18, \"after\": 10 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading3\": {\n \"font\": \"body\",\n \"size\": 14,\n \"bold\": true,\n \"color\": \"accent\",\n \"spacing\": { \"before\": 12, \"after\": 6 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"title\": {\n \"font\": \"heading\",\n \"size\": 36,\n \"bold\": true,\n \"color\": \"primary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 12 }\n },\n \"subtitle\": {\n \"font\": \"light\",\n \"size\": 18,\n \"italic\": false,\n \"color\": \"textSecondary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 24 }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#E2E8F0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"\\u2013\",\n \"indent\": 3\n },\n \"image\": {\n \"alignment\": \"center\"\n },\n \"statistic\": {\n \"alignment\": \"center\"\n },\n \"section\": {\n \"pageBreak\": false\n }\n }\n}\n","{\n \"name\": \"apex\",\n \"displayName\": \"Apex Consulting\",\n \"description\": \"A premium consulting theme with deep navy, warm amber accents, and authoritative typography\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#0C2340\",\n \"secondary\": \"#1B3A5C\",\n \"accent\": \"#D4A843\",\n \"text\": \"#1A1A2E\",\n \"background\": \"#FFFFFF\",\n \"border\": \"#D6DAE0\",\n \"textPrimary\": \"#1A1A2E\",\n \"textSecondary\": \"#4A5066\",\n \"textMuted\": \"#8B91A0\",\n \"borderPrimary\": \"#B8BCC6\",\n \"borderSecondary\": \"#E8EAF0\",\n \"backgroundPrimary\": \"#FFFFFF\",\n \"backgroundSecondary\": \"#F4F5F8\"\n },\n \"fonts\": {\n \"heading\": { \"family\": \"Georgia\", \"size\": 26 },\n \"body\": { \"family\": \"Calibri\", \"size\": 11 },\n \"mono\": { \"family\": \"Consolas\", \"size\": 10 },\n \"light\": { \"family\": \"Georgia\", \"size\": 26 }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1200,\n \"right\": 1200,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"textPrimary\",\n \"lineSpacing\": { \"type\": \"multiple\", \"value\": 1.4 },\n \"alignment\": \"justify\",\n \"spacing\": { \"after\": 8 }\n },\n \"heading1\": {\n \"font\": \"heading\",\n \"size\": 26,\n \"bold\": false,\n \"color\": \"primary\",\n \"spacing\": { \"before\": 24, \"after\": 12 },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"borders\": {\n \"bottom\": {\n \"style\": \"single\",\n \"size\": 2,\n \"color\": \"accent\",\n \"space\": 6\n }\n }\n },\n \"heading2\": {\n \"font\": \"heading\",\n \"size\": 18,\n \"bold\": false,\n \"color\": \"secondary\",\n \"spacing\": { \"before\": 18, \"after\": 8 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading3\": {\n \"font\": \"body\",\n \"size\": 13,\n \"bold\": true,\n \"color\": \"accent\",\n \"spacing\": { \"before\": 12, \"after\": 6 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"title\": {\n \"font\": \"light\",\n \"size\": 36,\n \"bold\": false,\n \"color\": \"primary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 18 }\n },\n \"subtitle\": {\n \"font\": \"body\",\n \"size\": 16,\n \"italic\": false,\n \"color\": \"textSecondary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 24 }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#D6DAE0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"\\u2022\",\n \"indent\": 3\n },\n \"image\": {\n \"alignment\": \"center\"\n },\n \"statistic\": {\n \"alignment\": \"center\"\n },\n \"section\": {\n \"pageBreak\": false\n },\n \"heading\": {\n \"numbering\": false\n }\n }\n}\n","{\n \"name\": \"devportal\",\n \"displayName\": \"Developer Portal\",\n \"description\": \"A modern developer-focused theme with cool grays, teal accents, and monospace code styling\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#0F172A\",\n \"secondary\": \"#334155\",\n \"accent\": \"#0D9488\",\n \"text\": \"#0F172A\",\n \"background\": \"#FFFFFF\",\n \"border\": \"#E2E8F0\",\n \"textPrimary\": \"#0F172A\",\n \"textSecondary\": \"#475569\",\n \"textMuted\": \"#94A3B8\",\n \"borderPrimary\": \"#CBD5E1\",\n \"borderSecondary\": \"#F1F5F9\",\n \"backgroundPrimary\": \"#FFFFFF\",\n \"backgroundSecondary\": \"#F8FAFC\"\n },\n \"fonts\": {\n \"heading\": { \"family\": \"Helvetica\", \"size\": 24 },\n \"body\": { \"family\": \"Calibri\", \"size\": 11 },\n \"mono\": { \"family\": \"Consolas\", \"size\": 10 },\n \"light\": { \"family\": \"Helvetica\", \"size\": 24 }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1080,\n \"right\": 1080,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"textPrimary\",\n \"lineSpacing\": { \"type\": \"multiple\", \"value\": 1.5 },\n \"alignment\": \"left\",\n \"spacing\": { \"after\": 8 }\n },\n \"heading1\": {\n \"font\": \"heading\",\n \"size\": 24,\n \"bold\": true,\n \"color\": \"primary\",\n \"spacing\": { \"before\": 24, \"after\": 12 },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"borders\": {\n \"bottom\": {\n \"style\": \"single\",\n \"size\": 1,\n \"color\": \"accent\",\n \"space\": 6\n }\n }\n },\n \"heading2\": {\n \"font\": \"heading\",\n \"size\": 18,\n \"bold\": true,\n \"color\": \"secondary\",\n \"spacing\": { \"before\": 18, \"after\": 8 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading3\": {\n \"font\": \"body\",\n \"size\": 13,\n \"bold\": true,\n \"color\": \"accent\",\n \"spacing\": { \"before\": 12, \"after\": 6 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading4\": {\n \"font\": \"body\",\n \"size\": 12,\n \"bold\": true,\n \"color\": \"textSecondary\",\n \"spacing\": { \"before\": 8, \"after\": 4 },\n \"keepNext\": true\n },\n \"title\": {\n \"font\": \"heading\",\n \"size\": 32,\n \"bold\": true,\n \"color\": \"primary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 12 }\n },\n \"subtitle\": {\n \"font\": \"light\",\n \"size\": 16,\n \"italic\": false,\n \"color\": \"textSecondary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 24 }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#E2E8F0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"\\u2013\",\n \"indent\": 3\n },\n \"image\": {\n \"alignment\": \"center\"\n },\n \"statistic\": {\n \"alignment\": \"center\"\n },\n \"section\": {\n \"pageBreak\": false\n },\n \"heading\": {\n \"numbering\": false\n }\n }\n}\n","/**\n * JSON-based themes registry\n * This file provides a unified interface to JSON themes\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport {\n isValidThemeConfig,\n type ThemeConfigJson,\n} from '@json-to-office/shared-docx';\nimport { ensureThemeDefaults } from '../../themes/defaults';\n\n// Import theme JSON files directly. Every bundled theme is imported here, so\n// which themes exist is decided by code, not by whether `dist/` happens to be\n// built and fresh — `apex` and `devportal` used to be reachable only through\n// the filesystem scan below, which meant a stale build silently served the old\n// copy and a missing one degraded to `minimal`.\nimport minimalThemeJson from './minimal.docx.theme.json';\nimport corporateThemeJson from './corporate.docx.theme.json';\nimport modernThemeJson from './modern.docx.theme.json';\nimport apexThemeJson from './apex.docx.theme.json';\nimport devportalThemeJson from './devportal.docx.theme.json';\n\n/**\n * Registry of available themes loaded from JSON files\n */\nlet _themesCache: Record<string, ThemeConfigJson> | null = null;\n\nfunction loadThemesFromJson(): Record<string, ThemeConfigJson> {\n if (_themesCache) {\n return _themesCache;\n }\n\n // Build themes from imported JSON files\n const themes: Record<string, ThemeConfigJson> = {\n minimal: ensureThemeDefaults(minimalThemeJson as ThemeConfigJson),\n corporate: ensureThemeDefaults(corporateThemeJson as ThemeConfigJson),\n modern: ensureThemeDefaults(modernThemeJson as ThemeConfigJson),\n apex: ensureThemeDefaults(apexThemeJson as ThemeConfigJson),\n devportal: ensureThemeDefaults(devportalThemeJson as ThemeConfigJson),\n };\n\n // Also try to load from file system for runtime additions (if available)\n try {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const themesDir = path.join(__dirname, '../../../dist/templates/themes');\n\n if (fs.existsSync(themesDir)) {\n const themeFiles = fs\n .readdirSync(themesDir)\n .filter((file) => file.endsWith('.docx.theme.json'))\n .map((file) => path.basename(file, '.docx.theme.json'));\n\n for (const themeName of themeFiles) {\n if (!themes[themeName]) {\n try {\n const filePath = path.join(\n themesDir,\n `${themeName}.docx.theme.json`\n );\n const content = fs.readFileSync(filePath, 'utf8');\n const parsedTheme = JSON.parse(content);\n // Check before registering. A theme that reaches the registry is\n // never validated again, so an invalid one here renders wrong\n // rather than failing — the drift that hid dead `componentDefaults`\n // props across five themes for as long as they shipped.\n if (!isValidThemeConfig(parsedTheme)) {\n console.warn(\n `Skipping theme ${themeName}: does not match the theme schema.`\n );\n continue;\n }\n themes[themeName] = ensureThemeDefaults(parsedTheme);\n } catch (error) {\n console.warn(\n `Failed to load additional theme ${themeName}:`,\n error\n );\n }\n }\n }\n }\n } catch (error) {\n // Silently ignore if file system access fails (e.g., in bundled environment)\n }\n\n _themesCache = themes;\n return themes;\n}\n\nexport const themes = loadThemesFromJson();\n\n/**\n * Type representing valid theme names\n */\nexport type ThemeName = keyof typeof themes;\n\n/**\n * Get theme configuration by name\n * @param themeName - Name of the theme to retrieve\n * @returns Theme configuration or undefined if not found\n */\nexport const getTheme = (themeName: string): ThemeConfigJson | undefined => {\n return themes[themeName];\n};\n\n/**\n * Get theme configuration with safe fallback\n * @param themeName - Name of the theme to retrieve\n * @param fallbackTheme - Fallback theme name (default: 'minimal')\n * @returns Theme configuration (guaranteed to be defined)\n * @throws Error if neither theme nor fallback can be found\n */\nexport const getThemeWithFallback = (\n themeName: string,\n fallbackTheme: string = 'minimal'\n): ThemeConfigJson => {\n const theme = getTheme(themeName) || getTheme(fallbackTheme);\n\n if (!theme) {\n throw new Error(\n `Failed to load theme: ${themeName}. Fallback theme '${fallbackTheme}' also not found.`\n );\n }\n\n return theme;\n};\n\n/**\n * Check if a theme exists\n * @param themeName - Name of the theme to check\n * @returns True if theme exists, false otherwise\n */\nexport const hasTheme = (themeName: string): boolean => {\n return themeName in themes;\n};\n\n/**\n * Type guard to ensure theme name is valid\n * @param themeName - Theme name to validate\n * @returns True if theme name exists in registry\n */\nexport const isValidThemeName = (\n themeName: string\n): themeName is keyof typeof themes => {\n return hasTheme(themeName);\n};\n\n/**\n * Get all available theme names\n * @returns Array of theme names\n */\nexport const getThemeNames = (): string[] => {\n return Object.keys(themes);\n};\n\n// Export individual theme configs for direct access\nexport const minimalTheme = themes['minimal'];\nexport const corporateTheme = themes['corporate'];\nexport const modernTheme = themes['modern'];\n","import { ThemeConfig } from '../index';\nimport { getThemeColors } from '../../themes/defaults';\n\nexport type ColorName = keyof ReturnType<typeof getThemeColors>;\n\n// Union type for all valid color names\nexport type ValidColorName =\n | 'primary'\n | 'secondary'\n | 'accent'\n | 'text'\n | 'background'\n | 'textPrimary'\n | 'textSecondary'\n | 'textMuted'\n | 'borderPrimary'\n | 'borderSecondary'\n | 'backgroundPrimary'\n | 'backgroundSecondary';\n\n// Type for color value that can be either a hex string or a color name\nexport type ColorValue = string; // Can be hex color or color name\n\n/**\n * Resolves a color value, which can be either a hex color string or a color name reference\n * @param colorValue - Either a hex color (e.g., '#000000') or a color name (e.g., 'primary')\n * @param theme - The theme configuration containing color definitions\n * @returns The resolved hex color value (6-character hex without #)\n * @throws Error if the color value is invalid\n */\nexport function resolveColor(\n colorValue: ColorValue,\n theme: ThemeConfig\n): string {\n // Check if it's a hex color with # prefix\n if (colorValue.startsWith('#')) {\n const hexValue = colorValue.slice(1);\n if (/^[0-9A-Fa-f]{6}$/.test(hexValue)) {\n return hexValue.toUpperCase(); // Normalize to uppercase\n }\n // Invalid hex format\n throw new Error(\n `Invalid hex color: \"${colorValue}\". Hex colors must be in format #RRGGBB (e.g., \"#000000\").`\n );\n }\n\n // If it's a color name, resolve it from the theme. Optional slots\n // (accent4-6) may be present-but-undefined, which counts as unset.\n const colors = getThemeColors(theme);\n const resolvedColor = colors[colorValue as ColorName];\n if (typeof resolvedColor === 'string') {\n // Recursively resolve in case the theme color is also a reference\n return resolveColor(resolvedColor, theme);\n }\n\n // Bare 6-digit hex, e.g. \"F0FDF4\". HexColorSchema admits it through the\n // theme-name branch, so rejecting it here would validate a document and then\n // throw while rendering it. Table cells and the chart palette already accept\n // this form; no theme color name is six hex characters, so there is no\n // ambiguity with a real token.\n if (/^[0-9A-Fa-f]{6}$/.test(colorValue)) {\n return colorValue.toUpperCase();\n }\n\n // Strict validation - throw error for invalid colors\n throw new Error(\n `Invalid color value: \"${colorValue}\". Must be a hex color with # prefix (e.g., \"#000000\") or a valid theme color name.`\n );\n}\n\n/**\n * Validates if a color name is set in the theme\n * @param colorName - The color name to validate\n * @param theme - The theme configuration\n * @returns True if the color name resolves to a value. A present-but-undefined\n * optional slot counts as unset, matching what `resolveColor` accepts.\n */\nexport function isValidColorName(\n colorName: string,\n theme: ThemeConfig\n): boolean {\n const colors = getThemeColors(theme);\n if (typeof colors[colorName as ColorName] !== 'string') return false;\n // Follow the reference chain: a token whose value names an unset slot is not\n // usable, so reporting it as valid would hand a caller a color that throws.\n try {\n resolveColor(colorName as ColorValue, theme);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Gets all available color names from a theme\n * @param theme - The theme configuration\n * @returns Array of valid color names, excluding present-but-undefined slots\n */\nexport function getAvailableColorNames(theme: ThemeConfig): string[] {\n const colors = getThemeColors(theme);\n return Object.keys(colors).filter((name) => isValidColorName(name, theme));\n}\n","import { getTheme } from '../../templates/themes';\nimport { ThemeConfig } from '../index';\nimport { resolveColor } from './colorUtils';\nimport { LineSpacing } from '@json-to-office/shared-docx';\nimport { ISpacingProperties } from 'docx';\nimport { getNormalStyle } from '../../themes/defaults';\n\n// Constants for line spacing calculations\nconst TWIPS_PER_POINT = 20;\nconst SINGLE_LINE_SPACING_POINTS = 12;\nconst SINGLE_LINE_SPACING_TWIPS = SINGLE_LINE_SPACING_POINTS * TWIPS_PER_POINT;\nconst DOUBLE_LINE_SPACING_TWIPS = SINGLE_LINE_SPACING_TWIPS * 2;\n\n/**\n * Convert points to twips for docx spacing\n * @param points - Value in points\n * @returns Value in twips (1/20 of a point)\n */\nexport function pointsToTwips(points: number): number {\n return Math.round(points * TWIPS_PER_POINT);\n}\n\n/**\n * Resolve theme configuration from either a theme object or theme name\n * @param theme - Theme configuration object (for custom themes)\n * @param themeName - Theme name (for built-in themes)\n * @returns Resolved theme configuration\n */\nexport function resolveTheme(\n theme?: ThemeConfig,\n themeName?: string\n): ThemeConfig | undefined {\n // First check if we have a theme object passed directly (for custom themes)\n if (theme) {\n return theme;\n }\n\n // If no theme object, check for built-in theme by name\n if (themeName) {\n return getTheme(themeName);\n }\n\n // Default to minimal theme if nothing else works\n return getTheme('minimal');\n}\n\n/**\n * Resolve font family from font reference (e.g., 'body', 'heading') to actual font family name\n * @param theme - Theme configuration object\n * @param fontRef - Font reference ('body', 'heading', 'mono', 'light') or undefined\n * @returns Actual font family name (e.g., 'Arial', 'Helvetica')\n */\nexport function resolveFontFamily(\n theme: ThemeConfig,\n fontRef?: 'heading' | 'body' | 'mono' | 'light'\n): string {\n // Handle empty/invalid themes gracefully\n if (!theme?.fonts?.body?.family) {\n return 'Arial'; // fallback to Arial\n }\n if (!fontRef) {\n return theme.fonts.body.family;\n }\n return theme.fonts[fontRef]?.family || theme.fonts.body.family;\n}\n\n/**\n * Resolve font size from font reference (e.g., 'body', 'heading') to actual font size in points\n * @param theme - Theme configuration object\n * @param fontRef - Font reference ('body', 'heading', 'mono', 'light') or undefined\n * @returns Font size in points (callers multiply by 2 for docx) or undefined if no size found\n */\nexport function resolveFontSize(\n theme: ThemeConfig,\n fontRef?: 'heading' | 'body' | 'mono' | 'light'\n): number | undefined {\n // Handle empty/invalid themes gracefully\n if (!theme?.fonts?.body?.size) {\n return undefined; // let caller handle fallback\n }\n if (!fontRef) {\n return theme.fonts.body.size;\n }\n return theme.fonts[fontRef]?.size || theme.fonts.body.size;\n}\n\n/**\n * Font properties that can be defined in font definitions\n */\nexport interface FontProperties {\n family?: string;\n size?: number;\n color?: string;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n alignment?: 'left' | 'center' | 'right' | 'justify';\n lineSpacing?: {\n type: 'single' | 'atLeast' | 'exactly' | 'double' | 'multiple';\n value?: number;\n };\n spacing?: {\n before?: number;\n after?: number;\n };\n characterSpacing?: { type: 'condensed' | 'expanded'; value: number };\n scale?: number;\n}\n\n/**\n * Resolve all font properties from font reference.\n * Returns all formatting properties defined in the font definition.\n * @param theme - Theme configuration object\n * @param fontRef - Font reference ('body', 'heading', 'mono', 'light') or undefined\n * @returns Object containing all font properties\n */\nexport function resolveFontProperties(\n theme: ThemeConfig,\n fontRef?: 'heading' | 'body' | 'mono' | 'light'\n): FontProperties {\n // Default to body font if no reference provided\n const targetFontKey = fontRef || 'body';\n\n // Handle empty/invalid themes gracefully\n if (!theme?.fonts?.[targetFontKey]) {\n return {\n family: 'Arial',\n size: 11,\n };\n }\n\n const fontDef = theme.fonts[targetFontKey] as FontProperties;\n\n return {\n family: fontDef.family,\n size: fontDef.size,\n color: fontDef.color,\n bold: fontDef.bold,\n italic: fontDef.italic,\n underline: fontDef.underline,\n alignment: fontDef.alignment,\n lineSpacing: fontDef.lineSpacing,\n spacing: fontDef.spacing,\n characterSpacing: fontDef.characterSpacing,\n scale: fontDef.scale,\n };\n}\n\n/**\n * Merge font properties with style overrides.\n * Style properties take precedence over font properties.\n * Only defined (non-undefined) style properties override font properties.\n * @param fontProps - Properties from font definition\n * @param styleOverrides - Properties from style definition\n * @returns Merged properties object\n */\nexport function mergeFontAndStyleProperties<T extends Partial<FontProperties>>(\n fontProps: FontProperties,\n styleOverrides: T\n): FontProperties & T {\n // Filter out undefined values from styleOverrides to prevent overwriting font properties\n // Use type-safe Object.entries approach\n const definedOverrides = Object.entries(styleOverrides).reduce<\n Record<string, unknown>\n >((acc, [key, value]) => {\n if (value !== undefined) {\n acc[key] = value;\n }\n return acc;\n }, {});\n\n return {\n ...fontProps,\n ...definedOverrides,\n } as FontProperties & T;\n}\n\n/**\n * Get body text style configuration\n * @param theme - Theme configuration object\n * @param themeName - Name of the theme (for fallback to built-in themes)\n * @returns Style configuration object\n */\nexport const getBodyTextStyle = (theme?: ThemeConfig, themeName?: string) => {\n const themeConfig = resolveTheme(theme, themeName);\n\n if (themeConfig) {\n const normalStyle = getNormalStyle(themeConfig);\n return {\n size: (normalStyle.size || 11) * 2,\n font: resolveFontFamily(themeConfig, normalStyle.font),\n color: normalStyle.color\n ? resolveColor(normalStyle.color, themeConfig)\n : '000000',\n };\n }\n\n // Fallback\n return {\n size: 20,\n font: 'Arial',\n color: '000000',\n };\n};\n\n/**\n * Converts line spacing from theme definition to DOCX spacing options.\n * DOCX uses twips (1/20th of a point) for line spacing.\n * @param lineSpacing The line spacing object from the theme definition.\n * @returns IParagraphSpacingOptions for docx.\n */\nexport function convertLineSpacing(\n lineSpacing?: LineSpacing | number\n): ISpacingProperties | undefined {\n if (lineSpacing === undefined) {\n return undefined;\n }\n\n // Handle number (simple multiplier) case\n if (typeof lineSpacing === 'number') {\n return {\n line: Math.round(lineSpacing * SINGLE_LINE_SPACING_TWIPS),\n lineRule: 'auto',\n };\n }\n\n const { type, value } = lineSpacing;\n let line: number | undefined;\n let lineRule: 'auto' | 'exact' | 'atLeast' | undefined;\n\n switch (type) {\n case 'single':\n line = SINGLE_LINE_SPACING_TWIPS;\n lineRule = 'auto';\n break;\n case 'double':\n line = DOUBLE_LINE_SPACING_TWIPS;\n lineRule = 'auto';\n break;\n case 'atLeast':\n line = value !== undefined ? value * TWIPS_PER_POINT : undefined;\n lineRule = 'atLeast';\n break;\n case 'exactly':\n line = value !== undefined ? value * TWIPS_PER_POINT : undefined;\n lineRule = 'exact';\n break;\n case 'multiple':\n line =\n value !== undefined ? value * SINGLE_LINE_SPACING_TWIPS : undefined;\n lineRule = 'auto';\n break;\n default:\n return undefined;\n }\n\n return { line, lineRule };\n}\n","import { BorderStyle } from 'docx';\nimport { LineSpacing } from '@json-to-office/shared-docx';\nimport { ThemeConfig } from '../index';\nimport { resolveColor } from './colorUtils';\nimport {\n resolveTheme,\n resolveFontFamily,\n convertLineSpacing,\n pointsToTwips,\n} from './styleHelpers';\n\n/**\n * Subset of a theme StyleProperties entry relevant to paragraph spacing.\n */\ninterface TableParagraphStyle {\n spacing?: { before?: number; after?: number };\n lineSpacing?: LineSpacing;\n}\n\n/**\n * Resolve the paragraph spacing for a table cell/header wrapper paragraph.\n *\n * Table cells render as a single wrapper paragraph. Historically that paragraph\n * inherited the `normal` style, dragging body-prose rhythm (8–10pt after-spacing\n * + 1.4–1.5x line) into every row and inflating row height regardless of font\n * size, padding, or the cell `height` prop. Tables should be dense by default:\n * no extra paragraph spacing, single line. Vertical breathing room is the job of\n * cell padding, not paragraph spacing.\n *\n * Themes may override per context via `styles.tableCell` / `styles.tableHeader`\n * (standard StyleProperties: `spacing.before/after` in points, `lineSpacing`).\n */\nconst resolveTableParagraphSpacing = (style?: TableParagraphStyle) => {\n const lineSpacing =\n convertLineSpacing(style?.lineSpacing) ??\n convertLineSpacing({ type: 'single' });\n return {\n before:\n style?.spacing?.before !== undefined\n ? pointsToTwips(style.spacing.before)\n : 0,\n after:\n style?.spacing?.after !== undefined\n ? pointsToTwips(style.spacing.after)\n : 0,\n ...lineSpacing,\n };\n};\n\n/**\n * Standard page sizes in twips (1/20 of a point, 1/1440 of an inch)\n */\nconst PAGE_SIZES = {\n A4: { width: 11906, height: 16838 },\n A3: { width: 16838, height: 23811 },\n LETTER: { width: 12240, height: 15840 },\n LEGAL: { width: 12240, height: 20160 },\n} as const;\n\n/**\n * Get page dimensions from size (string or object)\n */\nfunction getPageDimensions(\n size: 'A4' | 'A3' | 'LETTER' | 'LEGAL' | { width: number; height: number }\n): { width: number; height: number } {\n if (typeof size === 'string') {\n return PAGE_SIZES[size];\n }\n return size;\n}\n\n/**\n * Get table style configuration\n * @param theme - Theme configuration object\n * @param themeName - Name of the theme (for fallback to built-in themes)\n * @returns Table style configuration object\n */\nexport const getTableStyle = (theme?: ThemeConfig, themeName?: string) => {\n const themeConfig = resolveTheme(theme, themeName);\n\n if (themeConfig && themeConfig.styles?.normal) {\n // Use normal style for run-level header/cell defaults (font, size, color).\n // Paragraph spacing is resolved separately so table rows stay dense and do\n // not inherit `normal`'s body-prose after-spacing/line height.\n const normalStyle = themeConfig.styles.normal;\n const styles = themeConfig.styles as Record<string, TableParagraphStyle>;\n return {\n cellParagraph: resolveTableParagraphSpacing(styles.tableCell),\n headerParagraph: resolveTableParagraphSpacing(styles.tableHeader),\n tableHeader: {\n fill: resolveColor(\n themeConfig.colors?.primary || '#000000',\n themeConfig\n ),\n color: resolveColor(\n themeConfig.colors?.backgroundPrimary || '#FFFFFF',\n themeConfig\n ), // Use background color for header text\n bold: true, // Headers should be bold\n size: (normalStyle.size || 11) * 2, // Convert to half-points\n font: resolveFontFamily(themeConfig, normalStyle.font),\n },\n tableCell: {\n color: resolveColor(normalStyle.color || '#000000', themeConfig),\n size: (normalStyle.size || 11) * 2, // Convert to half-points\n font: resolveFontFamily(themeConfig, normalStyle.font),\n },\n alternatingRow: {\n fill: resolveColor(\n themeConfig.colors?.accent || '#F0F0F0',\n themeConfig\n ),\n },\n borders: {\n top: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: resolveColor(\n themeConfig.colors?.secondary || '#CCCCCC',\n themeConfig\n ),\n },\n bottom: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: resolveColor(\n themeConfig.colors?.secondary || '#CCCCCC',\n themeConfig\n ),\n },\n left: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: resolveColor(\n themeConfig.colors?.secondary || '#CCCCCC',\n themeConfig\n ),\n },\n right: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: resolveColor(\n themeConfig.colors?.secondary || '#CCCCCC',\n themeConfig\n ),\n },\n },\n };\n }\n\n // This shouldn't happen with minimal themes\n return {\n cellParagraph: resolveTableParagraphSpacing(),\n headerParagraph: resolveTableParagraphSpacing(),\n tableHeader: {\n fill: '000000',\n color: 'FFFFFF',\n bold: true,\n size: 22,\n font: 'Arial',\n },\n tableCell: {\n color: '000000',\n size: 20,\n font: 'Arial',\n },\n alternatingRow: {\n fill: 'F5F5F5',\n },\n borders: {\n top: { style: BorderStyle.SINGLE, size: 1, color: '000000' },\n bottom: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: '000000',\n },\n left: { style: BorderStyle.SINGLE, size: 1, color: '000000' },\n right: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: '000000',\n },\n },\n };\n};\n\n/**\n * Get document margins configuration\n * @param theme - Theme configuration object\n * @param themeName - Name of the theme (for fallback to built-in themes)\n * @returns Document margins object\n */\nexport const getDocumentMargins = (theme?: ThemeConfig, themeName?: string) => {\n const themeConfig = resolveTheme(theme, themeName);\n\n if (themeConfig?.page?.margins) {\n return themeConfig.page.margins;\n }\n\n // Default margins for all themes (standard Word document margins)\n return {\n top: 1440, // 1 inch in twips\n right: 1440, // 1 inch in twips\n bottom: 1440, // 1 inch in twips\n left: 1440, // 1 inch in twips\n header: 720, // 0.5 inch in twips\n footer: 720, // 0.5 inch in twips\n };\n};\n\n/**\n * Get page setup configuration\n * @param theme - Theme configuration object\n * @param themeName - Name of the theme (for fallback to built-in themes)\n * @returns Page setup object\n */\nexport const getPageSetup = (theme?: ThemeConfig, themeName?: string) => {\n const themeConfig = resolveTheme(theme, themeName);\n const defaultMargins = getDocumentMargins(theme, themeName);\n\n if (themeConfig?.page) {\n const margins = themeConfig.page.margins || {};\n const dimensions = getPageDimensions(themeConfig.page.size);\n return {\n size: {\n width: dimensions.width,\n height: dimensions.height,\n },\n margin: {\n top: margins.top ?? defaultMargins.top ?? 1440,\n right: margins.right ?? defaultMargins.right ?? 1440,\n bottom: margins.bottom ?? defaultMargins.bottom ?? 1440,\n left: margins.left ?? defaultMargins.left ?? 1440,\n },\n };\n }\n\n // Default page setup for all themes\n return {\n size: {\n width: 11906, // 8.5 inches in twips (Letter size)\n height: 16838, // 11.7 inches in twips (Letter size)\n },\n margin: {\n top: defaultMargins.top ?? 1440,\n right: defaultMargins.right ?? 1440,\n bottom: defaultMargins.bottom ?? 1440,\n left: defaultMargins.left ?? 1440,\n },\n };\n};\n","/**\n * Theme Parser using unified validation (TypeBox under the hood)\n */\n\nimport type { ThemeConfigJson } from '@json-to-office/shared-docx';\nimport { validateThemeJson } from '@json-to-office/shared-docx/validation/unified';\nimport type { ValidationError } from '@json-to-office/shared-docx/validation/unified';\nimport { ensureThemeDefaults } from '../../themes/defaults';\n\n// Custom error classes with enhanced error details\nexport class ThemeValidationError extends Error {\n constructor(public errors: ValidationError[]) {\n const errorCount = errors.length;\n const errorSummary = errors\n .slice(0, 3)\n .map((error) => {\n const path = error.path\n ? error.path.replace(/^\\//, '').replace(/\\//g, '.')\n : '';\n const pathStr = path ? `${path}: ` : '';\n return `${pathStr}${error.message}`;\n })\n .join('; ');\n\n super(\n `Theme validation failed with ${errorCount} error${errorCount > 1 ? 's' : ''}: ${errorSummary}${errorCount > 3 ? '...' : ''}`\n );\n this.name = 'ThemeValidationError';\n }\n\n getDetailedErrors(): string[] {\n return this.errors.map((error) => {\n const path = error.path\n ? error.path.replace(/^\\//, '').replace(/\\//g, '.')\n : '';\n const pathStr = path ? `${path}: ` : '';\n return `${pathStr}${error.message}`;\n });\n }\n}\n\nexport class ThemeParseError extends Error {\n constructor(\n message: string,\n public cause?: Error\n ) {\n super(`Failed to parse theme: ${message}`);\n this.name = 'ThemeParseError';\n }\n}\n\n// Theme parser class with comprehensive validation and error handling\nexport class ThemeParser {\n private readonly MAX_JSON_SIZE = 1024 * 1024; // 1MB limit (pre-parse guard)\n\n parse(jsonString: string): ThemeConfigJson {\n try {\n // Input validation and sanitization\n this.validateInput(jsonString);\n\n // Use unified validator (handles parsing + position calculation)\n const result = validateThemeJson(jsonString);\n if (!result.valid) {\n throw new ThemeValidationError(result.errors || []);\n }\n\n const validated = result.data as ThemeConfigJson;\n\n // Apply defaults and return ThemeConfig\n return this.applyDefaults(validated);\n } catch (error) {\n if (\n error instanceof ThemeValidationError ||\n error instanceof ThemeParseError\n ) {\n throw error;\n }\n throw new ThemeParseError(\n `Unexpected error during theme parsing: ${error instanceof Error ? error.message : String(error)}`,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private validateInput(jsonString: string): void {\n // Check for null/undefined\n if (!jsonString) {\n throw new ThemeParseError('JSON string cannot be null or empty');\n }\n\n // Check string type\n if (typeof jsonString !== 'string') {\n throw new ThemeParseError('Input must be a string');\n }\n\n // Check size limits (additional robustness guard)\n if (jsonString.length > this.MAX_JSON_SIZE) {\n throw new ThemeParseError(\n `JSON string too large (${jsonString.length} bytes, max ${this.MAX_JSON_SIZE} bytes)`\n );\n }\n }\n\n private applyDefaults(parsedTheme: ThemeConfigJson): ThemeConfigJson {\n // Apply defaults to ensure all required properties are present\n // This handles partial theme configurations by merging with defaults\n return ensureThemeDefaults(parsedTheme);\n }\n\n // Utility method for validating without parsing\n validate(jsonString: string): { valid: boolean; errors?: string[] } {\n try {\n this.validateInput(jsonString);\n const result = validateThemeJson(jsonString);\n\n if (result.valid) {\n return { valid: true };\n } else {\n const errors = (result.errors || []).map((e) => {\n const path = e.path\n ? e.path.replace(/^\\//, '').replace(/\\//g, '.')\n : '';\n const pathStr = path ? `${path}: ` : '';\n return `${pathStr}${e.message}`;\n });\n return { valid: false, errors };\n }\n } catch (error) {\n return {\n valid: false,\n errors: [\n error instanceof Error ? error.message : 'Unknown validation error',\n ],\n };\n }\n }\n}\n","/**\n * Theme Validator - thin wrapper over shared unified validator\n * Maintains backward-compatible API while removing duplicate logic\n */\n\nimport { validateThemeJson as validateThemeJsonUnified } from '@json-to-office/shared-docx/validation/unified';\n\n// Backward-compatible ValidationResult type used by core\nexport type ValidationResult = {\n success: boolean;\n error?: {\n issues: Array<{\n code: string;\n message: string;\n path: Array<string | number>;\n expected?: string;\n received?: string;\n type?: string;\n minimum?: number;\n maximum?: number;\n validation?: string;\n options?: string[];\n line?: number;\n column?: number;\n }>;\n };\n};\n\n// Validator function using unified shared validation\nexport function validateThemeJson(jsonString: string): ValidationResult {\n const result = validateThemeJsonUnified(jsonString);\n\n if (result.valid) {\n return { success: true };\n }\n\n const issues = (result.errors || []).map((e) => {\n const pathArray = (e.path || '')\n .split('/')\n .filter((p) => p)\n .map((p) => {\n const num = parseInt(p, 10);\n return isNaN(num) ? p : num;\n });\n\n return {\n code: e.code || 'validation_error',\n message: e.message,\n path: pathArray,\n line: e.line,\n column: e.column,\n };\n });\n\n return { success: false, error: { issues } };\n}\n\nexport function formatValidationErrors(error: {\n issues: Array<any>;\n}): string[] {\n return error.issues.map((issue) => {\n const path =\n issue.path && issue.path.length > 0 ? `${issue.path.join('.')}: ` : '';\n let message = issue.message;\n // Keep messages simple; unified validator already includes good messages\n return `${path}${message}`;\n });\n}\n\nexport function isValidThemeJson(jsonString: string): boolean {\n const result = validateThemeJson(jsonString);\n return result.success;\n}\n\nexport function getValidationSummary(jsonString: string): {\n valid: boolean;\n errorCount: number;\n errors: string[];\n summary: string;\n} {\n const result = validateThemeJson(jsonString);\n\n if (result.success) {\n return {\n valid: true,\n errorCount: 0,\n errors: [],\n summary: 'Theme JSON is valid',\n };\n }\n\n const errors = formatValidationErrors(result.error!);\n const errorCount = errors.length;\n\n return {\n valid: false,\n errorCount,\n errors,\n summary: `Theme validation failed with ${errorCount} error${errorCount > 1 ? 's' : ''}`,\n };\n}\n","import { promises as fs } from 'fs';\nimport { normalize } from 'path';\nimport type { ThemeConfigJson } from '@json-to-office/shared-docx';\nimport { ThemeParser } from './parser';\n\n// File system error class with enhanced error details\nexport class ThemeFileError extends Error {\n constructor(\n message: string,\n public path?: string,\n public _cause?: Error\n ) {\n const pathInfo = path ? ` (path: ${path})` : '';\n super(`Failed to load theme file: ${message}${pathInfo}`);\n this.name = 'ThemeFileError';\n }\n}\n\n// Theme loader class with comprehensive security and error handling\nexport class ThemeLoader {\n private parser = new ThemeParser();\n private readonly MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB limit\n private readonly ALLOWED_EXTENSIONS = ['.json'];\n\n async loadFromFile(filePath: string): Promise<ThemeConfigJson> {\n try {\n // Validate file path for security\n this.validateFilePath(filePath);\n\n // Read file with size limits\n const content = await this.readFileWithLimits(filePath);\n\n // Parse the theme content\n return this.parser.parse(content);\n } catch (error) {\n if (error instanceof ThemeFileError) {\n throw error;\n }\n\n // Handle file system errors\n if (error && typeof error === 'object' && 'code' in error) {\n const fsError = error as { code?: string; message: string };\n let message: string;\n\n switch (fsError.code) {\n case 'ENOENT':\n message = 'File not found';\n break;\n case 'EACCES':\n message = 'Permission denied';\n break;\n case 'EISDIR':\n message = 'Path is a directory, not a file';\n break;\n case 'EMFILE':\n case 'ENFILE':\n message = 'Too many open files';\n break;\n case 'ENOTDIR':\n message = 'Directory in path does not exist';\n break;\n default:\n message = `File system error: ${fsError.message}`;\n }\n\n throw new ThemeFileError(\n message,\n filePath,\n error instanceof Error ? error : undefined\n );\n }\n\n // Handle other errors\n throw new ThemeFileError(\n `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,\n filePath,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n async loadFromUrl(_url: string): Promise<ThemeConfigJson> {\n // Future enhancement for loading themes from URLs\n // Would need additional dependencies (fetch) and security considerations\n throw new ThemeFileError(\n 'URL loading not yet implemented - use loadFromFile() instead'\n );\n }\n\n private validateFilePath(filePath: string): void {\n // Basic input validation\n if (!filePath || typeof filePath !== 'string') {\n throw new ThemeFileError('File path must be a non-empty string');\n }\n\n // Normalize the path to handle different separators and relative paths\n const normalizedPath = normalize(filePath);\n\n // Check for directory traversal attempts\n if (normalizedPath.includes('..')) {\n throw new ThemeFileError('Directory traversal is not allowed', filePath);\n }\n\n // Check for null bytes (path injection)\n if (normalizedPath.includes('\\0')) {\n throw new ThemeFileError(\n 'Null bytes in file path are not allowed',\n filePath\n );\n }\n\n // Validate file extension\n const hasValidExtension = this.ALLOWED_EXTENSIONS.some((ext) =>\n normalizedPath.toLowerCase().endsWith(ext)\n );\n\n if (!hasValidExtension) {\n throw new ThemeFileError(\n `Invalid file extension. Allowed: ${this.ALLOWED_EXTENSIONS.join(', ')}`,\n filePath\n );\n }\n\n // Additional security: ensure path is reasonable length\n if (normalizedPath.length > 1000) {\n throw new ThemeFileError('File path is too long', filePath);\n }\n }\n\n private async readFileWithLimits(filePath: string): Promise<string> {\n try {\n // Get file stats to check size before reading\n const stats = await fs.stat(filePath);\n\n // Check if it's actually a file\n if (!stats.isFile()) {\n throw new ThemeFileError('Path is not a regular file', filePath);\n }\n\n // Check file size limits\n if (stats.size > this.MAX_FILE_SIZE) {\n throw new ThemeFileError(\n `File too large (${stats.size} bytes, max ${this.MAX_FILE_SIZE} bytes)`,\n filePath\n );\n }\n\n // Check for empty file\n if (stats.size === 0) {\n throw new ThemeFileError('File is empty', filePath);\n }\n\n // Read file with proper encoding\n const content = await fs.readFile(filePath, 'utf8');\n\n // Verify content was read properly\n if (typeof content !== 'string') {\n throw new ThemeFileError('Failed to read file as text', filePath);\n }\n\n return content;\n } catch (error) {\n if (error instanceof ThemeFileError) {\n throw error;\n }\n\n // Re-throw as ThemeFileError for consistent error handling\n throw new ThemeFileError(\n `Failed to read file: ${error instanceof Error ? error.message : String(error)}`,\n filePath,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n // Utility method to validate a file path without reading\n validateFile(filePath: string): { valid: boolean; error?: string } {\n try {\n this.validateFilePath(filePath);\n return { valid: true };\n } catch (error) {\n return {\n valid: false,\n error:\n error instanceof Error ? error.message : 'Unknown validation error',\n };\n }\n }\n\n // Utility method to get file info\n async getFileInfo(filePath: string): Promise<{\n exists: boolean;\n size?: number;\n isFile?: boolean;\n error?: string;\n }> {\n try {\n const stats = await fs.stat(filePath);\n return {\n exists: true,\n size: stats.size,\n isFile: stats.isFile(),\n };\n } catch (error) {\n return {\n exists: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n}\n","// Public API exports for JSON theme system\nexport {\n ThemeConfigSchema,\n type ThemeConfigJson,\n isValidThemeConfig,\n /**\n * Create a minimal theme template for users to start with.\n * Defined in shared-docx next to `ThemeConfigSchema` so every consumer\n * (CLI, playground) scaffolds from one schema-checked source.\n */\n createMinimalTheme,\n} from '@json-to-office/shared-docx';\nexport { ThemeParser, ThemeValidationError, ThemeParseError } from './parser';\nexport {\n validateThemeJson,\n formatValidationErrors,\n type ValidationResult,\n} from './validator';\nexport { ThemeLoader, ThemeFileError } from './loader';\n\n// Main API functions - Core public interface for JSON theme system\nimport type { ThemeConfigJson } from '@json-to-office/shared-docx';\nimport { ThemeParser } from './parser';\nimport { ThemeLoader } from './loader';\n\n// Global instances for consistent behavior\nconst themeParser = new ThemeParser();\nconst themeLoader = new ThemeLoader();\n\n/**\n * Load and parse a theme from a JSON string\n * @param jsonString - JSON string containing theme definition\n * @returns Promise<ThemeConfig> - Parsed and validated theme configuration\n * @throws ThemeParseError - If JSON is malformed or invalid\n * @throws ThemeValidationError - If theme fails schema validation\n */\nexport async function loadThemeFromJson(\n jsonString: string\n): Promise<ThemeConfigJson> {\n return themeParser.parse(jsonString);\n}\n\n/**\n * Load and parse a theme from a JSON file\n * @param filePath - Path to JSON file containing theme definition\n * @returns Promise<ThemeConfig> - Parsed and validated theme configuration\n * @throws ThemeFileError - If file cannot be read or path is invalid\n * @throws ThemeParseError - If JSON is malformed or invalid\n * @throws ThemeValidationError - If theme fails schema validation\n */\nexport async function loadThemeFromFile(\n filePath: string\n): Promise<ThemeConfigJson> {\n return themeLoader.loadFromFile(filePath);\n}\n\n/**\n * Export a theme configuration to JSON string\n * @param theme - Theme configuration to export\n * @param pretty - Whether to format JSON with indentation (default: true)\n * @returns string - Formatted JSON string\n */\nexport function exportThemeToJson(\n theme: ThemeConfigJson,\n pretty: boolean = true\n): string {\n try {\n // Since ThemeConfig is inferred from TypeBox schema, it can be directly serialized\n // The schema ensures all properties are JSON-serializable\n\n if (pretty) {\n return JSON.stringify(theme, null, 2);\n } else {\n return JSON.stringify(theme);\n }\n } catch (error) {\n throw new Error(\n `Failed to export theme to JSON: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Validate a JSON string against the theme schema without parsing\n * @param jsonString - JSON string to validate\n * @returns Validation result with success status and detailed errors\n */\nexport function validateThemeJsonString(jsonString: string) {\n return themeParser.validate(jsonString);\n}\n","/**\n * Main styles module export\n * This file provides a unified interface to the styles system\n */\n\n// Base configurations - imported from TypeBox schemas\nexport type {\n ThemeConfigJson as ThemeConfig,\n StyleDefinitions,\n DocumentMargins,\n PageDimensions,\n Page,\n FontDefinition,\n Fonts,\n ComponentDefaults,\n HeadingComponentDefaults,\n ParagraphComponentDefaults,\n ImageComponentDefaults,\n StatisticComponentDefaults,\n TableComponentDefaults,\n SectionComponentDefaults,\n ColumnsComponentDefaults,\n ListComponentDefaults,\n} from '@json-to-office/shared-docx';\nexport {\n themes,\n getTheme,\n getThemeNames,\n getThemeWithFallback,\n hasTheme,\n isValidThemeName,\n} from '../templates/themes';\n\n// Export ThemeName type separately\nexport type { ThemeName } from '../templates/themes';\n\n// Style utilities\nexport { getBodyTextStyle } from './utils/styleHelpers';\nexport {\n getTableStyle,\n getDocumentMargins,\n getPageSetup,\n} from './utils/layoutUtils';\n\n// Theme configurations\nexport {\n minimalTheme,\n corporateTheme,\n modernTheme,\n} from '../templates/themes';\n\n// JSON Theme System (Phase 1 - Foundation complete)\nexport {\n ThemeConfigSchema,\n isValidThemeConfig,\n loadThemeFromJson,\n loadThemeFromFile,\n exportThemeToJson,\n validateThemeJsonString,\n ThemeValidationError,\n ThemeParseError,\n ThemeFileError,\n} from '../themes/json';\n\n// Export type separately\nexport type { ThemeConfigJson } from '../themes/json';\n\n// All themes now use the same structure\n// No need for backward compatibility exports\n","import { ThemeConfig } from '../styles';\nimport { getPageSetup } from '../styles';\nimport { pointsToTwips } from '../styles/utils/styleHelpers';\n\n/**\n * Compute available page width in twips (page width minus left/right margins)\n */\nexport function getAvailableWidthTwips(\n theme?: ThemeConfig,\n themeName?: string\n): number {\n const page = getPageSetup(theme, themeName);\n const width = page?.size?.width || 0;\n const left = page?.margin?.left || 0;\n const right = page?.margin?.right || 0;\n return Math.max(0, width - left - right);\n}\n\n/**\n * Compute full page width in twips (ignores margins)\n */\nexport function getPageWidthTwips(\n theme?: ThemeConfig,\n themeName?: string\n): number {\n const page = getPageSetup(theme, themeName);\n return page?.size?.width || 0;\n}\n\n/**\n * Compute available page height in twips (page height minus top/bottom margins)\n */\nexport function getAvailableHeightTwips(\n theme?: ThemeConfig,\n themeName?: string\n): number {\n const page = getPageSetup(theme, themeName);\n const height = page?.size?.height || 0;\n const top = page?.margin?.top || 0;\n const bottom = page?.margin?.bottom || 0;\n return Math.max(0, height - top - bottom);\n}\n\n/**\n * Compute full page height in twips (ignores margins)\n */\nexport function getPageHeightTwips(\n theme?: ThemeConfig,\n themeName?: string\n): number {\n const page = getPageSetup(theme, themeName);\n return page?.size?.height || 0;\n}\n\n/**\n * Parse a percentage string like \"75%\" into a fraction 0..1\n */\nexport function parsePercentageStringToFraction(\n value: string\n): number | undefined {\n const match = /^([0-9]+(?:\\.[0-9]+)?)%$/.exec(value);\n if (!match) return undefined;\n const pct = parseFloat(match[1]);\n if (pct < 0 || pct > 100) return undefined;\n return pct / 100;\n}\n\n/**\n * Resolve an offset value (twips or percentage string) to twips.\n * Numbers pass through unchanged; percentage strings are resolved against referenceTwips.\n */\nexport function resolveOffsetTwips(\n value: number | string,\n referenceTwips: number\n): number {\n if (typeof value === 'number') return value;\n const match = /^([0-9]+(?:\\.[0-9]+)?)%$/.exec(value);\n if (!match) {\n console.warn(\n `resolveOffsetTwips: invalid percentage string \"${value}\", defaulting to 0`\n );\n return 0;\n }\n return Math.round((referenceTwips * parseFloat(match[1])) / 100);\n}\n\n/**\n * Convert a numeric (points) or percentage string to twips using available width\n */\nexport function relativeLengthToTwips(\n value: number | string,\n availableWidthTwips: number\n): number {\n if (typeof value === 'number') {\n return pointsToTwips(value);\n }\n const fraction = parsePercentageStringToFraction(value);\n if (fraction === undefined) return 0;\n return Math.round(availableWidthTwips * fraction);\n}\n","import {\n TextWrappingType,\n TextWrappingSide,\n HorizontalPositionRelativeFrom,\n VerticalPositionRelativeFrom,\n HorizontalPositionAlign,\n VerticalPositionAlign,\n} from 'docx';\n\nimport type { ImageProps } from '../types';\nimport type { ThemeConfig } from '../styles';\nimport {\n resolveOffsetTwips,\n getPageWidthTwips,\n getPageHeightTwips,\n getAvailableWidthTwips,\n getAvailableHeightTwips,\n} from './widthUtils';\n\nexport type FloatingConfig = NonNullable<ImageProps['floating']>;\n\n/**\n * Conversion factor from twips to EMUs (English Metric Units).\n * - 1 inch = 914,400 EMUs\n * - 1 inch = 1,440 twips\n * - Therefore: 1 twip = 914,400 / 1,440 = 635 EMUs\n *\n * docx.js expects offset and margin values in EMUs, but our schema\n * documents these values in twips for consistency with other Word measurements.\n */\nconst TWIPS_TO_EMU = 635;\n\nexport function mapHorizontalRelative(\n rel?: FloatingConfig['horizontalPosition'] extends infer T\n ? T extends { relative?: infer R }\n ? R\n : never\n : never\n) {\n switch (rel) {\n case 'character':\n return HorizontalPositionRelativeFrom.CHARACTER;\n case 'column':\n return HorizontalPositionRelativeFrom.COLUMN;\n case 'margin':\n return HorizontalPositionRelativeFrom.MARGIN;\n case 'page':\n return HorizontalPositionRelativeFrom.PAGE;\n default:\n return undefined;\n }\n}\n\nexport function mapVerticalRelative(\n rel?: FloatingConfig['verticalPosition'] extends infer T\n ? T extends { relative?: infer R }\n ? R\n : never\n : never\n) {\n switch (rel) {\n case 'margin':\n return VerticalPositionRelativeFrom.MARGIN;\n case 'page':\n return VerticalPositionRelativeFrom.PAGE;\n case 'paragraph':\n return VerticalPositionRelativeFrom.PARAGRAPH;\n case 'line':\n return VerticalPositionRelativeFrom.LINE;\n default:\n return undefined;\n }\n}\n\nexport function mapHorizontalAlign(\n align?: 'left' | 'center' | 'right' | 'inside' | 'outside'\n) {\n switch (align) {\n case 'left':\n return HorizontalPositionAlign.LEFT;\n case 'center':\n return HorizontalPositionAlign.CENTER;\n case 'right':\n return HorizontalPositionAlign.RIGHT;\n case 'inside':\n return HorizontalPositionAlign.INSIDE;\n case 'outside':\n return HorizontalPositionAlign.OUTSIDE;\n default:\n return undefined;\n }\n}\n\nexport function mapVerticalAlign(\n align?: 'top' | 'center' | 'bottom' | 'inside' | 'outside'\n) {\n switch (align) {\n case 'top':\n return VerticalPositionAlign.TOP;\n case 'center':\n return VerticalPositionAlign.CENTER;\n case 'bottom':\n return VerticalPositionAlign.BOTTOM;\n case 'inside':\n return VerticalPositionAlign.INSIDE;\n case 'outside':\n return VerticalPositionAlign.OUTSIDE;\n default:\n return undefined;\n }\n}\n\nexport function mapWrapType(\n type?: 'none' | 'square' | 'topAndBottom' | 'around' | 'through'\n) {\n switch (type) {\n case 'none':\n return TextWrappingType.NONE;\n case 'square':\n return TextWrappingType.SQUARE;\n case 'topAndBottom':\n return TextWrappingType.TOP_AND_BOTTOM;\n case 'around':\n case 'through':\n // Map VML-style 'around' and 'through' to TIGHT (closest OOXML equivalent)\n return TextWrappingType.TIGHT;\n default:\n return undefined;\n }\n}\n\nexport function mapWrapSide(side?: 'bothSides' | 'left' | 'right' | 'largest') {\n switch (side) {\n case 'bothSides':\n return TextWrappingSide.BOTH_SIDES;\n case 'left':\n return TextWrappingSide.LEFT;\n case 'right':\n return TextWrappingSide.RIGHT;\n case 'largest':\n return TextWrappingSide.LARGEST;\n default:\n return undefined;\n }\n}\n\n/**\n * Map shared floating config to docx ImageRun floating options.\n * Also lifts wrap.margins (if present) to floating.margins as expected by docx.\n */\nexport function mapFloatingOptions(\n floating?: FloatingConfig,\n theme?: ThemeConfig,\n themeName?: string\n): any | undefined {\n if (!floating) return undefined;\n\n // Disallow 'tight' wrapping: docx emits invalid OOXML for wrapTight without polygon geometry\n // Note: TypeScript correctly prevents this at compile-time, but keep for runtime safety\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - Intentional defensive check for runtime input validation\n if (floating.wrap?.type === 'tight') {\n throw new Error(\n \"Image floating wrap.type 'tight' is not supported due to invalid OOXML emitted by docx. Use 'square', 'topAndBottom', or 'none'.\"\n );\n }\n\n // Determine reference dimensions for percentage resolution\n const hRelative = floating.horizontalPosition?.relative;\n const vRelative = floating.verticalPosition?.relative;\n const hRef =\n hRelative && hRelative !== 'page'\n ? getAvailableWidthTwips(theme, themeName)\n : getPageWidthTwips(theme, themeName);\n const vRef =\n vRelative && vRelative !== 'page'\n ? getAvailableHeightTwips(theme, themeName)\n : getPageHeightTwips(theme, themeName);\n\n // docx.js requires BOTH horizontal and vertical positions for floating images.\n // If only one is specified, provide sensible defaults for the other.\n const hasHorizontal = Boolean(floating.horizontalPosition);\n const hasVertical = Boolean(floating.verticalPosition);\n\n const horizontalPosition = floating.horizontalPosition\n ? {\n ...(floating.horizontalPosition.relative && {\n relative: mapHorizontalRelative(floating.horizontalPosition.relative),\n }),\n ...(floating.horizontalPosition.align !== undefined && {\n align: mapHorizontalAlign(floating.horizontalPosition.align),\n }),\n ...(floating.horizontalPosition.offset !== undefined && {\n offset:\n resolveOffsetTwips(floating.horizontalPosition.offset, hRef) *\n TWIPS_TO_EMU,\n }),\n }\n : hasVertical\n ? {\n // Default horizontal: align left relative to margin\n relative: HorizontalPositionRelativeFrom.MARGIN,\n align: HorizontalPositionAlign.LEFT,\n }\n : undefined;\n\n const verticalPosition = floating.verticalPosition\n ? {\n ...(floating.verticalPosition.relative && {\n relative: mapVerticalRelative(floating.verticalPosition.relative),\n }),\n ...(floating.verticalPosition.align !== undefined && {\n align: mapVerticalAlign(floating.verticalPosition.align),\n }),\n ...(floating.verticalPosition.offset !== undefined && {\n offset:\n resolveOffsetTwips(floating.verticalPosition.offset, vRef) *\n TWIPS_TO_EMU,\n }),\n }\n : hasHorizontal\n ? {\n // Default vertical: align top relative to paragraph\n relative: VerticalPositionRelativeFrom.PARAGRAPH,\n align: VerticalPositionAlign.TOP,\n }\n : undefined;\n\n const wrap = floating.wrap\n ? {\n ...(floating.wrap.type && { type: mapWrapType(floating.wrap.type) }),\n ...(floating.wrap.side && { side: mapWrapSide(floating.wrap.side) }),\n }\n : undefined;\n\n // Convert margins from twips (or percentage) to EMUs\n const pageW = getPageWidthTwips(theme, themeName);\n const pageH = getPageHeightTwips(theme, themeName);\n const rawMargins = floating.wrap?.margins || (floating as any).margins;\n const margins = rawMargins\n ? {\n ...(rawMargins.top !== undefined && {\n top: resolveOffsetTwips(rawMargins.top, pageH) * TWIPS_TO_EMU,\n }),\n ...(rawMargins.bottom !== undefined && {\n bottom: resolveOffsetTwips(rawMargins.bottom, pageH) * TWIPS_TO_EMU,\n }),\n ...(rawMargins.left !== undefined && {\n left: resolveOffsetTwips(rawMargins.left, pageW) * TWIPS_TO_EMU,\n }),\n ...(rawMargins.right !== undefined && {\n right: resolveOffsetTwips(rawMargins.right, pageW) * TWIPS_TO_EMU,\n }),\n }\n : undefined;\n\n // Determine and validate zIndex:\n // - OOXML requires positive integer for relativeHeight\n // - Negative values cause Word to reject the document\n // - CRITICAL: docx.js uses image HEIGHT as relativeHeight when zIndex is undefined,\n // causing inconsistent values that can corrupt documents\n // - Solution: ALWAYS provide a zIndex value, defaulting to 0\n let zIndex = floating.zIndex !== undefined ? floating.zIndex : 0; // Default to 0 for ALL floating images (behindDocument or normal)\n\n // Validate: zIndex must be >= 0 (OOXML requirement)\n if (zIndex < 0) {\n console.warn(\n `Invalid zIndex value ${zIndex} for floating image. Using 0 instead. zIndex must be >= 0.`\n );\n zIndex = 0;\n }\n\n const mapped: any = {\n ...(horizontalPosition && { horizontalPosition }),\n ...(verticalPosition && { verticalPosition }),\n ...(wrap && { wrap }),\n ...(margins && { margins }),\n ...(floating.allowOverlap !== undefined && {\n allowOverlap: floating.allowOverlap,\n }),\n ...(floating.behindDocument !== undefined && {\n behindDocument: floating.behindDocument,\n }),\n ...(floating.lockAnchor !== undefined && {\n lockAnchor: floating.lockAnchor,\n }),\n ...(floating.layoutInCell !== undefined && {\n layoutInCell: floating.layoutInCell,\n }),\n zIndex, // Always include zIndex (now always defined, defaults to 0)\n };\n\n return Object.keys(mapped).length ? mapped : undefined;\n}\n","/**\n * Document Generator\n * Main orchestration functions that compose the document generation pipeline\n */\n\nimport { Document } from 'docx';\nimport { writeFileSync } from 'fs';\nimport {\n ComponentDefinition,\n ReportProps,\n ReportComponentDefinition,\n isReportComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { resolveThemeContext } from './generationContext';\nimport type { ServicesConfig, FontRuntimeOpts } from '@json-to-office/shared';\nimport { processDocument } from './structure';\nimport { applyLayout } from './layout';\nimport { renderDocument } from './render';\nimport { resolveDocumentFonts } from './fontResolution';\nimport {\n packageDocument,\n resolveGenerationDate,\n} from '../utils/packageDocument';\n\n// JSON support imports\nimport { DocumentValidationResult } from '@json-to-office/shared-docx';\nimport type { GenerationWarning } from '@json-to-office/shared';\nimport {\n validateJsonComponent,\n JsonParsingError,\n JsonValidationError,\n} from '../json/parser';\nimport { normalizeDocument } from '../json/normalizer';\nimport { loadJsonDefinition } from '../json/filesystem';\n\n// Local generation options type\nexport interface JsonGenerationOptions {\n outputPath?: string;\n validation?: {\n /**\n * Validate the document against the schema before building, throwing on\n * errors. Defaults to `true` — invalid props are surfaced rather than\n * silently dropped into a corrupt/incomplete document.\n */\n enabled?: boolean;\n /**\n * When true, unknown/extra properties are stripped instead of rejected by\n * strict (additionalProperties:false) schemas. Escape hatch for migration.\n */\n allowUnknownFields?: boolean;\n /** @deprecated No longer consulted; retained for back-compat. */\n strict?: boolean;\n };\n customThemes?: { [key: string]: ThemeConfig };\n services?: ServicesConfig;\n fonts?: FontRuntimeOpts;\n /**\n * Optional collector for structured warnings (font resolution, etc.).\n * When provided, mirrors the plugin path's warning semantics; when absent,\n * warnings fall back to `console.warn` as before.\n */\n warnings?: GenerationWarning[];\n /** Normalize volatile OOXML values for byte-identical output. Defaults true. */\n deterministic?: boolean;\n /** Build timestamp for metadata; defaults to a stable epoch. */\n generatedAt?: string | Date;\n}\n\n// Font resolution shared with the plugin path — see ./fontResolution.ts\n\n/**\n * Type guard to check if input is a report component definition\n */\nexport function isReportComponentDefinition(\n definition: unknown\n): definition is ReportComponentDefinition {\n if (typeof definition !== 'object' || definition === null) {\n return false;\n }\n\n const def = definition as Record<string, unknown>;\n\n // Must be a report component (optionally with $schema for JSON validation).\n // `props` is optional: a propless root generates like one with `props: {}`.\n return def.name === 'docx';\n}\n\n/**\n * Generate a Word document from a report component definition\n * This is the main entry point for document generation\n */\nexport async function generateDocument(\n document: ReportComponentDefinition,\n options?: JsonGenerationOptions\n): Promise<Document> {\n // Validate that the document is a report component\n if (!document || document.name !== 'docx') {\n throw new Error('Top-level component must be a docx component');\n }\n\n // Handle JSON definitions (report components with $schema)\n if ('$schema' in document) {\n return await generateDocumentFromJson(document, options);\n }\n\n // Route through the font-aware pipeline so `options.fonts` (mode,\n // substitution, onResolved, strict) is honoured identically to the JSON\n // entry point. Previously this branch bypassed export-mode + font\n // resolution, silently ignoring `fonts.mode: 'substitute'`.\n return await generateDocumentWithCustomThemes(\n document,\n options?.customThemes,\n options?.services,\n options?.fonts,\n options?.warnings,\n resolveGenerationDate(options)\n );\n}\n\n/**\n * Generate document from report props and components\n * Convenience function that constructs the report component\n */\nexport async function generateFromConfig(\n props: ReportProps,\n components: ComponentDefinition[],\n options?: JsonGenerationOptions\n): Promise<Document> {\n const reportComponent: ReportComponentDefinition = {\n name: 'docx',\n props,\n children: components,\n };\n\n return await generateDocument(reportComponent, options);\n}\n\n/**\n * Generate a Word document with custom themes support\n * Extends the standard pipeline to support custom theme resolution\n */\nasync function generateDocumentWithCustomThemes(\n documentIn: ReportComponentDefinition,\n customThemes?: { [key: string]: ThemeConfig },\n services?: ServicesConfig,\n fonts?: FontRuntimeOpts,\n warnings?: GenerationWarning[],\n generationDate?: Date\n): Promise<Document> {\n // Props defaulting, theme resolution, in-document overrides, export-mode\n // pre-pass and cache-key scoping — shared with the plugin pipeline so the\n // two cannot drift (see core/generationContext.ts).\n const { document, theme, themeName } = resolveThemeContext(documentIn, {\n customThemes,\n fonts,\n warnings,\n });\n\n // Resolve fonts for the LibreOffice preview stager (side-channel).\n // resolveDocumentFonts fires `fonts.onResolved` internally when a\n // listener is registered. The final DOCX never embeds bytes.\n await resolveDocumentFonts(document, theme, fonts, warnings);\n\n // Pipeline: Structure -> Layout -> Render (with caching)\n const structure = await processDocument(\n document,\n theme,\n themeName,\n generationDate\n );\n const layout = applyLayout(structure.sections, theme, themeName);\n const renderedDocument = await renderDocument(structure, layout, {\n bypassCache: false,\n services,\n });\n\n return renderedDocument;\n}\n\n/**\n * Generate a Word document from JSON report definition\n * Handles parsing, validation, and conversion to internal components\n */\nexport async function generateDocumentFromJson(\n jsonConfig: string | ComponentDefinition | ReportComponentDefinition,\n options?: JsonGenerationOptions\n): Promise<Document> {\n // Validate before building unless the caller opted out. This runs the same\n // plugin-unaware validator the public playground uses, so the object/buffer\n // entry point is as strict as the playground — malformed props throw instead\n // of being silently dropped into the document.\n const validation = options?.validation;\n if (validation?.enabled !== false) {\n const result = validateJsonComponent(jsonConfig, {\n allowUnknownFields: validation?.allowUnknownFields,\n });\n if (!result.valid) {\n throw new JsonValidationError(\n 'Document validation failed',\n result.errors\n );\n }\n }\n\n // Resolve to an object for the build pipeline.\n let componentToConvert: ComponentDefinition | ReportComponentDefinition;\n if (typeof jsonConfig === 'string') {\n let parsed: ComponentDefinition;\n try {\n parsed = JSON.parse(jsonConfig) as ComponentDefinition;\n } catch (error) {\n throw new JsonParsingError('Invalid JSON syntax', [\n {\n path: '',\n message: error instanceof Error ? error.message : 'Invalid JSON',\n code: 'JSON_PARSE_ERROR',\n },\n ]);\n }\n if (!isReportComponent(parsed)) {\n throw new Error('Parsed JSON must be a docx component');\n }\n componentToConvert = parsed as ReportComponentDefinition;\n } else {\n // Could be either ComponentDefinition (from JSON) or ReportComponentDefinition (internal)\n componentToConvert = jsonConfig;\n }\n\n // Normalize JSON components (handle shorthand notations and nested structures)\n // The normalizer preserves all validated properties from TypeBox\n const [reportComponent] = normalizeDocument(componentToConvert);\n\n // Generate document using custom theme-aware pipeline.\n // Font registry lives on the theme, so resolution happens inside the\n // pipeline (after theme selection).\n return await generateDocumentWithCustomThemes(\n reportComponent,\n options?.customThemes,\n options?.services,\n options?.fonts,\n options?.warnings,\n resolveGenerationDate(options)\n );\n}\n\n/**\n * Validate JSON schema without generating document\n */\nexport function validateJsonSchema(\n jsonConfig: string | object\n): DocumentValidationResult {\n return validateJsonComponent(jsonConfig);\n}\n\n/**\n * Generate document buffer from JSON (commonly used for API responses)\n */\nexport async function generateBufferFromJson(\n jsonConfig: string | ReportComponentDefinition,\n options?: JsonGenerationOptions\n): Promise<Buffer> {\n const document = await generateDocumentFromJson(jsonConfig, options);\n return packageDocument(document, options);\n}\n\n/**\n * Generate and save document from JSON in one operation\n */\nexport async function generateAndSaveFromJson(\n jsonConfig: string | ReportComponentDefinition,\n filename: string,\n options?: JsonGenerationOptions\n): Promise<void> {\n const document = await generateDocumentFromJson(jsonConfig, options);\n await saveDocument(document, filename, options);\n}\n\n/**\n * Generate document from JSON file\n */\nexport async function generateDocumentFromFile(\n filePath: string,\n options?: JsonGenerationOptions\n): Promise<Document> {\n const jsonDefinition = await loadJsonDefinition(filePath);\n // loadJsonDefinition returns ComponentDefinition from shared (JSON schema type)\n // generateDocumentFromJson now accepts the JSON schema type directly\n return await generateDocumentFromJson(jsonDefinition, options);\n}\n\n/**\n * Generate document buffer from JSON file\n */\nexport async function generateBufferFromFile(\n filePath: string,\n options?: JsonGenerationOptions\n): Promise<Buffer> {\n const document = await generateDocumentFromFile(filePath, options);\n return packageDocument(document, options);\n}\n\n/**\n * Generate and save document from JSON file in one operation\n */\nexport async function generateAndSaveFromFile(\n inputFilePath: string,\n outputFilePath: string,\n options?: JsonGenerationOptions\n): Promise<void> {\n const document = await generateDocumentFromFile(inputFilePath, options);\n await saveDocument(document, outputFilePath, options);\n}\n\n/**\n * Save a document to file\n */\nexport async function saveDocument(\n document: Document,\n filename: string,\n options?: JsonGenerationOptions\n): Promise<void> {\n const buffer = await packageDocument(document, options);\n writeFileSync(filename, buffer);\n}\n\n/**\n * Generate and save document in one operation\n */\nexport async function generateAndSave(\n document: ReportComponentDefinition,\n filename: string,\n options?: JsonGenerationOptions\n): Promise<void> {\n const generatedDocument = await generateDocument(document, options);\n await saveDocument(generatedDocument, filename, options);\n}\n\n/**\n * Compose multiple transform functions\n * Utility for creating custom pipelines\n */\nexport function pipe<T>(...fns: Array<(_arg: T) => T>): (_arg: T) => T {\n return (_arg: T) => fns.reduce((acc, fn) => fn(acc), _arg);\n}\n\n/**\n * Export the main API\n */\nexport const DocumentGenerator = {\n generate: generateDocument,\n generateFromConfig,\n generateFromJson: generateDocumentFromJson,\n generateFromFile: generateDocumentFromFile,\n generateBufferFromJson,\n generateBufferFromFile,\n generateAndSaveFromJson,\n generateAndSaveFromFile,\n validateJsonSchema,\n save: saveDocument,\n generateAndSave,\n isReportComponentDefinition,\n};\n","import { ISectionOptions } from 'docx';\nimport type { ThemeName } from '../styles';\nimport type { ServicesConfig } from '@json-to-office/shared';\n\n// Import types from shared-docx that core needs for its internal use\nimport type {\n ComponentDefinition as SharedComponentDefinition,\n ReportComponent,\n SectionComponent,\n ColumnsComponent,\n HeadingComponent,\n ParagraphComponent,\n ImageComponent,\n HighchartsComponent,\n VisualComponent,\n StatisticComponent,\n TableComponent,\n ListComponent,\n TocComponent,\n TextBoxComponent,\n\n // Import props types needed internally\n ReportProps as SharedReportProps,\n SectionProps as SharedSectionProps,\n HeadingProps as SharedHeadingProps,\n ParagraphProps as SharedParagraphProps,\n ColumnsProps as SharedColumnsProps,\n ImageProps as SharedImageProps,\n VisualProps as SharedVisualProps,\n StatisticProps as SharedStatisticProps,\n TableProps as SharedTableProps,\n ListProps as SharedListProps,\n TocProps as SharedTocProps,\n TextBoxProps as SharedTextBoxProps,\n} from '@json-to-office/shared-docx';\n\n// Import type guards from shared-docx (these are runtime functions core needs)\nexport {\n isReportComponent,\n isSectionComponent,\n isHeadingComponent,\n isParagraphComponent,\n isColumnsComponent,\n isImageComponent,\n isTextBoxComponent,\n isStatisticComponent,\n isTableComponent,\n isListComponent,\n isTocComponent,\n isHighchartsComponent,\n isVisualComponent,\n} from '@json-to-office/shared-docx';\n\n// Re-export component definitions for internal use (type aliases for clarity)\nexport type ComponentDefinition = SharedComponentDefinition;\nexport type ReportComponentDefinition = ReportComponent & {\n /** Optional schema field for JSON validation */\n $schema?: string;\n};\nexport type SectionComponentDefinition = SectionComponent;\nexport type HeadingComponentDefinition = HeadingComponent;\nexport type ParagraphComponentDefinition = ParagraphComponent;\nexport type ColumnsComponentDefinition = ColumnsComponent;\nexport type ImageComponentDefinition = ImageComponent;\nexport type VisualComponentDefinition = VisualComponent;\nexport type TextBoxComponentDefinition = TextBoxComponent;\nexport type StatisticComponentDefinition = StatisticComponent;\nexport type TableComponentDefinition = TableComponent;\nexport type ListComponentDefinition = ListComponent;\nexport type TocComponentDefinition = TocComponent;\n\n// Export StandardComponentDefinition as union of all standard component types\nexport type StandardComponentDefinition =\n | ReportComponent\n | SectionComponent\n | ColumnsComponent\n | HeadingComponent\n | ParagraphComponent\n | TextBoxComponent\n | ImageComponent\n | HighchartsComponent\n | VisualComponent\n | StatisticComponent\n | TableComponent\n | ListComponent\n | TocComponent;\n\n// Re-export props types for internal use\nexport type ReportProps = SharedReportProps;\nexport type SectionProps = SharedSectionProps;\nexport type HeadingProps = SharedHeadingProps;\nexport type ParagraphProps = SharedParagraphProps;\nexport type ColumnsProps = SharedColumnsProps;\nexport type ImageProps = SharedImageProps;\nexport type VisualProps = SharedVisualProps;\nexport type TextBoxProps = SharedTextBoxProps;\nexport type StatisticProps = SharedStatisticProps;\nexport type TableProps = SharedTableProps;\nexport type ListProps = SharedListProps;\nexport type TocProps = SharedTocProps;\n\n// Re-export ThemeName for easier access\nexport type { ThemeName };\n\n// ============================================================================\n// CORE-SPECIFIC INTERFACES\n// ============================================================================\n\nexport interface ColumnSettings {\n count: number;\n equalWidth?: boolean;\n space?: number;\n /** Optional explicit column children with widths/spaces in twips */\n children?: { width?: number; space?: number }[];\n}\n\nexport interface PageSizeOptions {\n width: number;\n height: number;\n}\n\nexport interface PageMarginOptions {\n top: number;\n right: number;\n bottom: number;\n left: number;\n header?: number;\n footer?: number;\n}\n\nexport interface PageNumberOptions {\n start?: number;\n formatType?:\n | 'decimal'\n | 'upperRoman'\n | 'lowerRoman'\n | 'upperLetter'\n | 'lowerLetter';\n}\n\nexport interface PageBorderOptions {\n top?: { style: string; size: number; color: string };\n right?: { style: string; size: number; color: string };\n bottom?: { style: string; size: number; color: string };\n left?: { style: string; size: number; color: string };\n}\n\nexport interface SectionProperties {\n page?: {\n size?: PageSizeOptions;\n margin?: PageMarginOptions;\n pageNumbers?: PageNumberOptions;\n borders?: PageBorderOptions;\n textDirection?: 'ltr' | 'rtl';\n };\n column?: ColumnSettings;\n type?: 'continuous' | 'nextColumn' | 'nextPage' | 'evenPage' | 'oddPage';\n headers?: ISectionOptions['headers'];\n footers?: ISectionOptions['footers'];\n}\n\n// Internal interfaces used by DocumentGenerator helper methods\nexport interface ImageContent {\n path: string;\n caption?: string;\n width?: number;\n height?: number;\n alignment?: 'left' | 'center' | 'right';\n}\n\nexport interface StatisticContent {\n number: string;\n description: string;\n alignment?: 'left' | 'center' | 'right';\n}\n\nexport interface TableData {\n headers: string[];\n rows: (string | SharedComponentDefinition)[][];\n style?: 'minimal' | 'classic' | 'minimal';\n}\n\n/**\n * Rendering context for components\n */\nexport interface RenderContext {\n theme: {\n name: string;\n colors: Record<string, string>;\n fonts: Record<string, string>;\n spacing: Record<string, number>;\n };\n /** Full theme configuration for custom components */\n fullTheme: import('../styles').ThemeConfig;\n document: {\n title?: string;\n subtitle?: string;\n author?: string;\n company?: string;\n date: Date;\n };\n section: {\n currentLayout: 'single' | 'multi-column';\n columnCount: number;\n pageNumber: number;\n level?: number;\n /** Bookmark ID for section-scoped TOCs (when TOC is inside a section) */\n sectionBookmarkId?: string;\n /** Heading level of the parent section title (used to exclude it from section-scoped TOCs) */\n sectionTitleLevel?: number;\n };\n utils: {\n formatDate: (_date: Date) => string;\n parseText: (_text: string) => { text: string }[];\n getStyle: (_name: string) => { name: string };\n [key: string]: unknown;\n };\n parent?: SharedComponentDefinition;\n depth: number;\n custom?: Record<string, unknown>;\n services?: ServicesConfig;\n}\n","/**\n * Shared generation prologue.\n *\n * Both entry points — `generateBufferFromJson` (core) and\n * `createDocumentGenerator` (plugin) — must resolve the same theme, apply the\n * same in-document overrides, and derive the same cache key before the\n * structure → layout → render engine runs. Keeping two copies of that meant\n * `props.themeOverrides` reached only one of them (#133); this module is the\n * single definition so the next root-level prop cannot diverge (#132).\n *\n * The prologue deliberately stops before font resolution: the core path\n * resolves fonts straight after this, while the plugin path must first expand\n * custom components (which can introduce new families).\n */\n\nimport type { ReportComponentDefinition } from '../types';\nimport type { ThemeConfig } from '../styles';\nimport type {\n FontRuntimeOpts,\n GenerationWarning,\n} from '@json-to-office/shared';\nimport { applyExportMode, scopedThemeName } from '@json-to-office/shared';\nimport { resolveBuiltInTheme } from '../styles/theme-resolver';\nimport { applyThemeOverrides, themeOverridesDigest } from '../themes/overrides';\n\nexport interface ThemeContextOptions {\n customThemes?: { [key: string]: ThemeConfig };\n fonts?: FontRuntimeOpts;\n warnings?: GenerationWarning[];\n /**\n * Theme lookup for the base `props.theme` name. The plugin builder passes\n * its own (customThemes → constructor-supplied theme → built-in); omit it to\n * use customThemes → built-in.\n */\n resolveNamedTheme?: (\n name: string,\n warnings?: GenerationWarning[]\n ) => ThemeConfig;\n}\n\nexport interface GenerationThemeContext {\n /** The document after the export-mode pre-pass rewrote font references. */\n document: ReportComponentDefinition;\n theme: ThemeConfig;\n /** Cache key: base theme name + override digest + export-mode scope. */\n themeName: string;\n}\n\n/** customThemes lookup with the case-insensitive fallback, then built-ins. */\nfunction defaultNamedThemeLookup(\n themeName: string,\n customThemes: { [key: string]: ThemeConfig } | undefined,\n warnings?: GenerationWarning[]\n): ThemeConfig {\n if (customThemes) {\n if (customThemes[themeName]) return customThemes[themeName];\n const themeNameLower = themeName.toLowerCase();\n const matchingThemeKey = Object.keys(customThemes).find(\n (key) => key.toLowerCase() === themeNameLower\n );\n if (matchingThemeKey) return customThemes[matchingThemeKey];\n return resolveBuiltInTheme(themeName, { customThemes, warnings });\n }\n return resolveBuiltInTheme(themeName, { warnings });\n}\n\nexport function resolveThemeContext(\n documentIn: ReportComponentDefinition,\n options: ThemeContextOptions = {}\n): GenerationThemeContext {\n const { customThemes, fonts, warnings, resolveNamedTheme } = options;\n\n // A root written without a `props` key validates clean, so default it here —\n // otherwise every downstream `document.props.*` read (theme, componentDefaults,\n // noProofWords, trackRevisions, language, metadata) throws. Only `undefined`\n // is defaulted: `props: null` is malformed and must be rejected rather than\n // quietly rewritten into a valid shape.\n //\n // Both JSON entry points validate before reaching here, so null is already\n // a validation error there. `generateDocument` on a document without\n // `$schema` runs no validator at all, and used to surface this as\n // `Cannot read properties of null` from the theme read below.\n if (documentIn.props === null) {\n throw new Error(\n 'Document `props` is null. Omit it, or provide an object — ' +\n 'a null props cannot carry a theme.'\n );\n }\n const document =\n documentIn.props === undefined ? { ...documentIn, props: {} } : documentIn;\n\n const baseThemeName = document.props.theme || 'minimal';\n let theme = resolveNamedTheme\n ? resolveNamedTheme(baseThemeName, warnings)\n : defaultNamedThemeLookup(baseThemeName, customThemes, warnings);\n\n // In-document partial theme, merged before the export-mode pre-pass so a\n // font-family override is visible to it. The digest joins the cache key so\n // two documents sharing a theme name but not overrides never share slots.\n const themeOverrides = document.props.themeOverrides;\n let themeName = baseThemeName;\n if (themeOverrides) {\n theme = applyThemeOverrides(theme, themeOverrides);\n themeName = `${themeName}+ov:${themeOverridesDigest(themeOverrides)}`;\n }\n\n // Export-mode pre-pass: substitute (default) rewrites non-safe families to\n // safe equivalents; custom keeps refs as-is.\n const mode = applyExportMode({ doc: document, theme, fonts });\n for (const w of mode.warnings) {\n if (warnings) {\n warnings.push({\n component: 'fontRegistry',\n message: w.message,\n severity: 'warning',\n context: { code: w.code },\n });\n } else {\n // eslint-disable-next-line no-console\n console.warn(`[json-to-docx] [${w.code}] ${w.message}`);\n }\n }\n\n return {\n document: mode.doc,\n theme: mode.theme,\n // Scope by mode too: substitute rewrites the theme in place, so caches\n // must not share slots with custom-mode runs keyed on the same name.\n themeName: scopedThemeName(themeName, fonts?.mode),\n };\n}\n","import type { GenerationWarning } from '@json-to-office/shared';\nimport type { ThemeConfig } from './index';\nimport {\n getThemeNames,\n getThemeWithFallback,\n hasTheme,\n} from '../templates/themes';\n\n/**\n * Resolve a built-in theme by name, reporting a miss instead of swallowing it.\n *\n * `getThemeWithFallback` renders an unknown name as `minimal`, which used to be\n * invisible: a typo, or a `--theme-path` file whose internal `name` differs\n * from its filename, produced a plausible-looking document styled by the wrong\n * theme. The fallback is kept — a bad name should not fail a render — but it\n * now surfaces as a warning naming what was asked for and what is available.\n */\nexport function resolveBuiltInTheme(\n themeName: string,\n options: {\n customThemes?: { [key: string]: ThemeConfig };\n warnings?: GenerationWarning[];\n } = {}\n): ThemeConfig {\n if (!hasTheme(themeName)) {\n const available = [\n ...getThemeNames(),\n ...Object.keys(options.customThemes ?? {}),\n ].sort();\n options.warnings?.push({\n component: 'theme',\n message: `Theme \"${themeName}\" not found; falling back to \"minimal\". Available themes: ${available.join(', ')}.`,\n severity: 'warning',\n context: { code: 'theme_not_found', requested: themeName, available },\n });\n }\n\n return getThemeWithFallback(themeName);\n}\n","/**\n * In-document theme overrides: a partial theme from the document root's\n * `themeOverrides` prop, deep-merged over the resolved named theme.\n */\n\nimport { createHash } from 'crypto';\nimport type { ThemeConfig } from '../styles';\n\nexport interface ThemeOverrides {\n colors?: Partial<ThemeConfig['colors']>;\n fonts?: Partial<ThemeConfig['fonts']>;\n styles?: ThemeConfig['styles'];\n}\n\n/**\n * Merge a partial override object over a resolved theme.\n *\n * - `colors`: per-token replacement.\n * - `fonts`: per-role merge (an override role only replaces the fields it\n * sets, so `{ heading: { family: \"Geist\" } }` keeps the theme's size).\n * - `styles`: per-style merge, one level deep — nested objects inside a style\n * (spacing, lineSpacing, borders, indent) are replaced wholesale.\n */\nexport function applyThemeOverrides(\n theme: ThemeConfig,\n overrides: ThemeOverrides | undefined\n): ThemeConfig {\n if (!overrides) return theme;\n\n const fonts = { ...theme.fonts };\n for (const [role, def] of Object.entries(overrides.fonts ?? {})) {\n const key = role as keyof ThemeConfig['fonts'];\n fonts[key] = { ...theme.fonts[key], ...def };\n }\n\n const styles: Record<string, object> = { ...(theme.styles ?? {}) };\n for (const [name, def] of Object.entries(overrides.styles ?? {})) {\n styles[name] = { ...styles[name], ...(def as object) };\n }\n\n return {\n ...theme,\n colors: { ...theme.colors, ...(overrides.colors ?? {}) },\n fonts,\n ...(Object.keys(styles).length > 0 && { styles }),\n };\n}\n\n/** Short stable digest used to scope theme-keyed caches per override set. */\nexport function themeOverridesDigest(overrides: ThemeOverrides): string {\n return createHash('sha256')\n .update(JSON.stringify(overrides))\n .digest('hex')\n .slice(0, 8);\n}\n","import { format } from 'date-fns';\n\nexport const formatDate = (\n date: Date,\n formatString: string = 'MMMM d, yyyy'\n): string => {\n return format(date, formatString);\n};\n","/**\n * Component Default Resolution System\n * Provides theme-based default configurations for components\n */\n\nimport {\n ThemeConfig,\n ComponentDefaults,\n HeadingComponentDefaults,\n ParagraphComponentDefaults,\n ImageComponentDefaults,\n StatisticComponentDefaults,\n TableComponentDefaults,\n SectionComponentDefaults,\n ColumnsComponentDefaults,\n ListComponentDefaults,\n} from '../index';\nimport {\n HeadingProps,\n ParagraphProps,\n ImageProps,\n StatisticProps,\n TableProps,\n SectionProps,\n ColumnsProps,\n ListProps,\n} from '../../types';\nimport { mergeWithDefaults } from '@json-to-office/shared';\n\n/**\n * Get component defaults from theme configuration\n */\nexport function getComponentDefaults(theme: ThemeConfig): ComponentDefaults {\n return theme.componentDefaults || {};\n}\n\n/**\n * Get default configuration for heading components\n */\nexport function getHeadingDefaults(\n theme: ThemeConfig\n): HeadingComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.heading || {};\n}\n\n/**\n * Get level-specific heading defaults from theme styles\n */\nexport function getHeadingDefaultsForLevel(\n theme: ThemeConfig,\n level: number\n): Partial<HeadingComponentDefaults> {\n const defaults: Partial<HeadingComponentDefaults> = {};\n\n // Check styles for level-specific alignment\n if (theme.styles) {\n const styleKey = `heading${level}` as\n | 'heading1'\n | 'heading2'\n | 'heading3'\n | 'heading4'\n | 'heading5'\n | 'heading6';\n const headingStyle = theme.styles[styleKey];\n\n if (headingStyle?.alignment) {\n defaults.alignment = headingStyle.alignment;\n }\n }\n\n return defaults;\n}\n\n/**\n * Get default configuration for text components\n */\nexport function getTextDefaults(\n theme: ThemeConfig\n): ParagraphComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.paragraph || {};\n}\n\n/**\n * Get default configuration for image components\n */\nexport function getImageDefaults(theme: ThemeConfig): ImageComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.image || {};\n}\n\n/**\n * Get default configuration for statistic components\n */\nexport function getStatisticDefaults(\n theme: ThemeConfig\n): StatisticComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.statistic || {};\n}\n\n/**\n * Get default configuration for table components\n */\nexport function getTableDefaults(theme: ThemeConfig): TableComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.table || {};\n}\n\n/**\n * Get default configuration for section components\n */\nexport function getSectionDefaults(\n theme: ThemeConfig\n): SectionComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.section || {};\n}\n\n/**\n * Get default configuration for columns components\n */\nexport function getColumnsDefaults(\n theme: ThemeConfig\n): ColumnsComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.columns || {};\n}\n\n/**\n * Get default configuration for list components\n */\nexport function getListDefaults(theme: ThemeConfig): ListComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.list || {};\n}\n\n// mergeWithDefaults is re-exported from @json-to-office/shared\nexport { mergeWithDefaults } from '@json-to-office/shared';\n\n/**\n * Resolve heading component props with theme defaults\n */\nexport function resolveHeadingProps(\n props: HeadingProps,\n theme: ThemeConfig\n): HeadingProps {\n const defaults = getHeadingDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve paragraph component props with theme defaults\n */\nexport function resolveParagraphProps(\n props: ParagraphProps,\n theme: ThemeConfig\n): ParagraphProps {\n const defaults = getTextDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve image component props with theme defaults\n */\nexport function resolveImageProps(\n props: ImageProps,\n theme: ThemeConfig\n): ImageProps {\n const defaults = getImageDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve statistic component props with theme defaults\n */\nexport function resolveStatisticProps(\n props: StatisticProps,\n theme: ThemeConfig\n): StatisticProps {\n const defaults = getStatisticDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve table component props with theme defaults\n */\nexport function resolveTableProps(\n props: TableProps,\n theme: ThemeConfig\n): TableProps {\n const defaults = getTableDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve section component props with theme defaults\n */\nexport function resolveSectionProps(\n props: SectionProps,\n theme: ThemeConfig\n): SectionProps {\n const defaults = getSectionDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve columns component props with theme defaults\n */\nexport function resolveColumnsProps(\n props: ColumnsProps,\n theme: ThemeConfig\n): ColumnsProps {\n const defaults = getColumnsDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve list component props with theme defaults\n */\nexport function resolveListProps(\n props: ListProps,\n theme: ThemeConfig\n): ListProps {\n const defaults = getListDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve highcharts component props with theme defaults\n */\nexport function resolveHighchartsProps(\n props: import('@json-to-office/shared-docx').HighchartsProps,\n _theme: ThemeConfig\n): import('@json-to-office/shared-docx').HighchartsProps {\n // Highcharts component doesn't have theme defaults, just return the props as-is\n return props;\n}\n\n/**\n * Resolve visual component props with theme defaults.\n * The visual is rasterized by the pptx engine, so there are no docx-side theme\n * defaults to apply — return props as-is (mirrors highcharts).\n */\nexport function resolveVisualProps(\n props: import('@json-to-office/shared-docx').VisualProps,\n _theme: ThemeConfig\n): import('@json-to-office/shared-docx').VisualProps {\n return props;\n}\n\n/**\n * Get default configuration for custom components\n */\nexport function getCustomComponentDefaults(\n theme: ThemeConfig,\n componentName: string\n): Record<string, unknown> {\n const defaults = getComponentDefaults(theme);\n // Use type assertion since we're dealing with dynamic property access\n return ((defaults as any)?.[componentName] as Record<string, unknown>) || {};\n}\n\n/**\n * Resolve custom component props with theme defaults\n */\nexport function resolveCustomComponentProps<T extends Record<string, unknown>>(\n props: T,\n theme: ThemeConfig,\n componentName: string\n): T {\n const defaults = getCustomComponentDefaults(theme, componentName);\n return mergeWithDefaults(props, defaults as Partial<T>);\n}\n","/**\n * Centralized Component Defaults Resolution\n * Walks the component tree and resolves theme componentDefaults\n * on every component before any rendering or structure processing.\n */\n\nimport { ComponentDefinition, HeadingProps } from '../../types';\nimport { ThemeConfig } from '../index';\nimport {\n resolveHeadingProps,\n resolveParagraphProps,\n resolveImageProps,\n resolveStatisticProps,\n resolveTableProps,\n resolveSectionProps,\n resolveColumnsProps,\n resolveListProps,\n resolveHighchartsProps,\n resolveVisualProps,\n resolveCustomComponentProps,\n getHeadingDefaultsForLevel,\n} from './componentDefaults';\n\n/**\n * Heading resolver that also applies level-specific style defaults\n * (alignment from theme.styles.heading{N}).\n * Moved here from heading.ts to centralize all resolution.\n */\nfunction resolveHeadingWithLevelDefaults(\n props: HeadingProps,\n theme: ThemeConfig\n): HeadingProps {\n const resolved = resolveHeadingProps(props, theme);\n const level = resolved.level || 1;\n const levelDefaults = getHeadingDefaultsForLevel(theme, level);\n return {\n ...resolved,\n // Only apply level-specific defaults if no explicit alignment in original props\n ...(props.alignment ? {} : levelDefaults),\n };\n}\n\ntype Resolver = (props: any, theme: ThemeConfig) => any;\n\nconst RESOLVER_MAP: Record<string, Resolver> = {\n heading: resolveHeadingWithLevelDefaults,\n paragraph: resolveParagraphProps,\n image: resolveImageProps,\n statistic: resolveStatisticProps,\n table: resolveTableProps,\n section: resolveSectionProps,\n columns: resolveColumnsProps,\n list: resolveListProps,\n highcharts: resolveHighchartsProps,\n visual: resolveVisualProps,\n};\n\n/**\n * Resolve componentDefaults for a single component.\n * Known components use their typed resolver; unknown names\n * fall back to resolveCustomComponentProps.\n *\n * A missing `props` key is treated as `{}` — a propless node must still pick up\n * the theme's defaults (e.g. `componentDefaults.section.pageBreak: false`).\n */\nexport function resolveComponentDefaults(\n component: ComponentDefinition,\n theme: ThemeConfig\n): ComponentDefinition {\n const props = component.props ?? {};\n\n const resolver = RESOLVER_MAP[component.name];\n const resolvedProps = resolver\n ? resolver(props, theme)\n : resolveCustomComponentProps(\n props as Record<string, unknown>,\n theme,\n component.name\n );\n\n return { ...component, props: resolvedProps };\n}\n\n/**\n * Recursively walk the component tree and resolve componentDefaults\n * on every component. Returns a new tree (no mutation).\n */\nexport function resolveComponentTree(\n components: ComponentDefinition[],\n theme: ThemeConfig\n): ComponentDefinition[] {\n return components.map((component) => {\n const resolved = resolveComponentDefaults(component, theme);\n\n const children = (resolved as any).children as\n | ComponentDefinition[]\n | undefined;\n if (children && children.length > 0) {\n return {\n ...resolved,\n children: resolveComponentTree(children, theme),\n };\n }\n\n return resolved;\n });\n}\n","/**\n * Document Structure Functions\n * Handle document hierarchy and organization without layout concerns\n */\n\nimport {\n ComponentDefinition,\n ReportProps,\n ReportComponentDefinition,\n RenderContext,\n isSectionComponent,\n isColumnsComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { formatDate } from '../utils/formatters';\nimport {\n resolveComponentTree,\n resolveComponentDefaults,\n} from '../styles/utils/resolveComponentTree';\nimport { mergeWithDefaults } from '../styles/utils/componentDefaults';\n\nexport interface ProcessedDocument {\n metadata: DocumentMetadata;\n sections: ProcessedSection[];\n theme: ThemeConfig;\n themeName: string;\n /** Open the generated document in track-changes mode */\n trackRevisions?: boolean;\n /** Default document language (BCP-47) applied to docDefaults proofing */\n language?: string;\n}\n\nexport interface DocumentMetadata {\n title?: string;\n subtitle?: string;\n description?: string;\n author?: string;\n company?: string;\n version?: string;\n tags?: string[];\n date: Date;\n}\n\nexport interface ProcessedSection {\n title?: string;\n level?: number;\n components: ComponentDefinition[];\n header?: ComponentDefinition[] | 'linkToPrevious';\n footer?: ComponentDefinition[] | 'linkToPrevious';\n /** True if this section originates from an explicit Section component */\n isExplicitSection?: boolean;\n /** Whether this section should start on a new page */\n pageBreak?: boolean;\n /** Page configuration override for this section */\n page?: {\n size?: 'A4' | 'A3' | 'LETTER' | 'LEGAL' | { width: number; height: number };\n margins?: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n header?: number;\n footer?: number;\n gutter?: number;\n };\n };\n}\n\n/**\n * Process document definition into structured format\n */\nexport async function processDocument(\n document: ReportComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n generationDate?: Date\n): Promise<ProcessedDocument> {\n const metadata = createDocumentMetadata(document.props, generationDate);\n\n // Merge document-level componentDefaults on top of theme-level ones\n // (document overrides theme)\n const docDefaults = document.props.componentDefaults;\n const mergedComponentDefaults = docDefaults\n ? mergeWithDefaults(docDefaults, theme.componentDefaults || {})\n : undefined;\n\n // Fold the document's known-words allowlist into the theme object so it\n // reaches every text primitive (createText/createHeading) without threading\n // a new parameter through the whole render tree. Document words are added to\n // any house-style words the theme already defines.\n const docNoProofWords = document.props.noProofWords;\n const mergedNoProofWords =\n docNoProofWords || theme.noProofWords\n ? Array.from(\n new Set([...(theme.noProofWords || []), ...(docNoProofWords || [])])\n )\n : undefined;\n\n const effectiveTheme =\n mergedComponentDefaults || mergedNoProofWords\n ? {\n ...theme,\n ...(mergedComponentDefaults && {\n componentDefaults: mergedComponentDefaults,\n }),\n ...(mergedNoProofWords && { noProofWords: mergedNoProofWords }),\n }\n : theme;\n\n // Create context with effective theme so section-title headings\n // created in extractSections also see document-level defaults\n const context = createRenderContext(\n {\n metadata,\n sections: [],\n theme: effectiveTheme,\n themeName,\n },\n effectiveTheme,\n themeName\n );\n\n // Resolve componentDefaults on every component before\n // extractSections reads any props (fixes section pageBreak, table defaults, etc.)\n const resolvedChildren = resolveComponentTree(\n document.children || [],\n effectiveTheme\n );\n\n // Extract sections from components\n const sections = await extractSections(resolvedChildren, context);\n\n return {\n metadata,\n sections,\n theme: effectiveTheme,\n themeName,\n trackRevisions: document.props.trackRevisions,\n language: document.props.language,\n };\n}\n\n/**\n * Extract document metadata from report props\n */\nexport function createDocumentMetadata(\n props: ReportProps,\n generationDate = new Date()\n): DocumentMetadata {\n return {\n title: props.metadata?.title,\n subtitle: props.metadata?.subtitle,\n description: props.metadata?.description,\n author: props.metadata?.author,\n company: props.metadata?.company,\n version: props.metadata?.version,\n tags: props.metadata?.tags,\n date: props.metadata?.date ? new Date(props.metadata.date) : generationDate,\n };\n}\n\n/**\n * Extract and flatten sections from component hierarchy\n */\nexport async function extractSections(\n components: ComponentDefinition[],\n context: RenderContext\n): Promise<ProcessedSection[]> {\n const sections: ProcessedSection[] = [];\n\n // Filter out components with enabled: false (defaults to true when not specified)\n const activeComponents = components.filter(\n (m) => !('enabled' in m && m.enabled === false)\n );\n\n for (const component of activeComponents) {\n if (isSectionComponent(component)) {\n const sectionComponents = await flattenComponents(\n component.children || [],\n context\n );\n\n // Determine if page break should be applied (default to true)\n const shouldPageBreak = component.props?.pageBreak !== false;\n\n // Add section title as heading component if present\n if (component.props?.title) {\n // Ensure level is within valid range (1-6) for heading component\n const headingLevel = Math.min(\n Math.max(component.props.level || 1, 1),\n 6\n ) as 1 | 2 | 3 | 4 | 5 | 6;\n\n sectionComponents.unshift(\n resolveComponentDefaults(\n {\n name: 'heading',\n props: {\n text: component.props.title,\n level: headingLevel,\n pageBreak: shouldPageBreak,\n // Apply zero-spacing to prevent unwanted initial line\n spacing: {\n before: 0,\n after: 0,\n },\n },\n },\n context.fullTheme\n )\n );\n }\n\n sections.push({\n title: component.props?.title,\n level: component.props?.level,\n components: sectionComponents,\n header: component.props?.header,\n footer: component.props?.footer,\n isExplicitSection: true,\n // Store pageBreak for titleless sections to be handled at layout level\n pageBreak: !component.props?.title ? shouldPageBreak : undefined,\n // Preserve page configuration override if present\n page: component.props?.page,\n });\n } else {\n // Non-section components at root level become their own section\n sections.push({\n components: [component],\n isExplicitSection: false,\n });\n }\n }\n\n return sections;\n}\n\n/**\n * Flatten nested container components while preserving content components\n */\nexport async function flattenComponents(\n components: ComponentDefinition[],\n context: RenderContext\n): Promise<ComponentDefinition[]> {\n const flattened: ComponentDefinition[] = [];\n\n // Filter out components with enabled: false (defaults to true when not specified)\n const activeComponents = components.filter(\n (m) => !('enabled' in m && m.enabled === false)\n );\n\n for (const component of activeComponents) {\n if (isColumnsComponent(component) && component.children) {\n // Preserve columns structure but flatten its contents\n flattened.push({\n ...component,\n children: await flattenComponents(component.children, context),\n });\n } else if (isSectionComponent(component) && component.children) {\n // Flatten nested sections\n if (component.props?.title) {\n // Ensure level is within valid range (1-6) for heading component\n const headingLevel = Math.min(\n Math.max(component.props.level || 1, 1),\n 6\n ) as 1 | 2 | 3 | 4 | 5 | 6;\n\n // Convert section title to heading\n flattened.push(\n resolveComponentDefaults(\n {\n name: 'heading',\n props: {\n text: component.props.title,\n level: headingLevel,\n // Apply zero-spacing to prevent unwanted initial line\n spacing: {\n before: 0,\n after: 0,\n },\n },\n },\n context.fullTheme\n )\n );\n }\n flattened.push(...(await flattenComponents(component.children, context)));\n } else {\n // Keep content components as-is\n flattened.push(component);\n }\n }\n\n return flattened;\n}\n\n/**\n * Create render context from processed document\n */\nexport function createRenderContext(\n document: ProcessedDocument,\n theme: ThemeConfig,\n themeName: string\n): RenderContext {\n return {\n theme: {\n name: themeName,\n colors: theme.colors || {},\n fonts: theme.fonts\n ? Object.fromEntries(\n Object.entries(theme.fonts).map(([key, font]) => [key, font.family])\n )\n : {},\n spacing: { small: 120, medium: 240, large: 360, section: 480 },\n },\n fullTheme: theme,\n document: document.metadata,\n section: {\n currentLayout: 'single',\n columnCount: 1,\n pageNumber: 1,\n },\n utils: {\n formatDate: (date: Date) => formatDate(date),\n parseText: (text: string) => [{ text }],\n getStyle: (name: string) => ({ name }),\n },\n depth: 0,\n };\n}\n","/**\n * Layout Functions\n * Handle all layout concerns including columns, breaks, and section properties\n */\n\nimport { SectionType, Column as DocxColumn } from 'docx';\nimport {\n ComponentDefinition,\n ColumnSettings,\n isColumnsComponent,\n isSectionComponent,\n isHeadingComponent,\n isParagraphComponent,\n isTocComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { getPageSetup } from '../styles';\n// import { pointsToTwips } from '../styles/utils/styleHelpers';\nimport { ProcessedSection } from './structure';\nimport {\n getAvailableWidthTwips,\n relativeLengthToTwips,\n} from '../utils/widthUtils';\n\nexport interface LayoutPlan {\n sections: SectionLayout[];\n}\n\nexport interface WordSectionProperties {\n page: {\n size: {\n width: number;\n height: number;\n };\n margin: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n };\n column: ColumnSettings & { children?: DocxColumn[] };\n type?: (typeof SectionType)[keyof typeof SectionType];\n}\n\nexport interface SectionLayout {\n properties: WordSectionProperties;\n components: ComponentDefinition[];\n layoutType: 'single' | 'multi-column';\n breakBefore: boolean;\n header?: ComponentDefinition[] | 'linkToPrevious';\n footer?: ComponentDefinition[] | 'linkToPrevious';\n /** True if this layout section comes from a user-defined Section component */\n isUserSection: boolean;\n /** True if this layout chunk belongs to a user-defined Section (all chunks of that section) */\n belongsToUserSection: boolean;\n /** The heading level of the section title (e.g., 1 for Heading1) - used by TOCs to exclude section title from section-scoped TOCs */\n sectionTitleLevel?: number;\n /** Page configuration override for this section */\n pageOverride?: {\n size?: 'A4' | 'A3' | 'LETTER' | 'LEGAL' | { width: number; height: number };\n margins?: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n header?: number;\n footer?: number;\n gutter?: number;\n };\n };\n}\n\nexport interface LayoutGroup {\n layout: 'single' | 'multi-column';\n components: ComponentDefinition[];\n breakBefore: boolean;\n}\n\n/**\n * Apply layout to processed sections\n */\nexport function applyLayout(\n sections: ProcessedSection[],\n theme: ThemeConfig,\n themeName: string\n): LayoutPlan {\n const layoutSections: SectionLayout[] = [];\n\n for (let i = 0; i < sections.length; i++) {\n const section = sections[i];\n const layoutGroups = analyzeLayoutGroups(section.components);\n\n // Determine if this comes from an explicit Section component\n const isSourceUserSection = Boolean(section.isExplicitSection);\n\n // Handle sections with no components but with headers/footers\n // This ensures headers/footers are rendered even for empty sections\n if (layoutGroups.length === 0 && (section.header || section.footer)) {\n const isFirstSection = i === 0;\n const breakBefore = isFirstSection || Boolean(section.pageBreak);\n const sectionType = breakBefore ? 'nextPage' : 'continuous';\n\n layoutSections.push({\n properties: createSectionProperties(\n getColumnSettings('single'),\n theme,\n themeName,\n sectionType,\n section.page\n ),\n components: [],\n layoutType: 'single',\n breakBefore,\n header: section.header,\n footer: section.footer,\n isUserSection: isSourceUserSection,\n belongsToUserSection: isSourceUserSection,\n sectionTitleLevel: section.level,\n pageOverride: section.page,\n });\n continue;\n }\n\n for (let j = 0; j < layoutGroups.length; j++) {\n const group = layoutGroups[j];\n\n // Special handling: a single Columns component becomes its own section with explicit column children\n const isSingleColumnsGroup =\n group.components.length === 1 && isColumnsComponent(group.components[0]);\n\n const columnSettings = isSingleColumnsGroup\n ? createColumnSettingsFromConfig(group.components[0], theme, themeName)\n : getColumnSettings(group.layout);\n\n // Only break page if explicitly requested or this is the first section\n const isFirstSection = i === 0 && j === 0;\n // For titleless sections with pageBreak, apply break to first layout group\n const titlelessSectionBreak = Boolean(section.pageBreak && j === 0);\n const breakBefore =\n group.breakBefore || isFirstSection || titlelessSectionBreak;\n const sectionType = breakBefore ? 'nextPage' : 'continuous';\n\n // Build content components depending on whether this is an explicit columns group\n const contentComponents = isSingleColumnsGroup\n ? processLayoutComponents(\n (group.components[0] as unknown as { children?: ComponentDefinition[] })\n .children || []\n )\n : processLayoutComponents(group.components);\n\n layoutSections.push({\n properties: createSectionProperties(\n columnSettings,\n theme,\n themeName,\n sectionType,\n section.page\n ),\n components: contentComponents,\n layoutType: group.layout,\n breakBefore,\n header: section.header,\n footer: section.footer,\n // Only mark the FIRST layout section as user-defined to avoid\n // creating bookmark paragraphs in subsequent sections (e.g., when\n // transitioning to columns layout). This prevents unwanted newlines\n // at the start of column content.\n isUserSection: isSourceUserSection && j === 0,\n belongsToUserSection: isSourceUserSection,\n // Pass section title level for TOC scoping\n sectionTitleLevel: section.level,\n // Pass page override for this section\n pageOverride: section.page,\n });\n }\n }\n\n return { sections: layoutSections };\n}\n\n/**\n * Analyze components to determine layout groups\n */\nexport function analyzeLayoutGroups(\n components: ComponentDefinition[]\n): LayoutGroup[] {\n const groups: LayoutGroup[] = [];\n let currentLayout: 'single' | 'multi-column' = 'single';\n let currentComponents: ComponentDefinition[] = [];\n let breakNext = false;\n\n for (const component of components) {\n // Always isolate explicit Columns components into their own group\n if (isColumnsComponent(component)) {\n if (currentComponents.length > 0) {\n groups.push({\n layout: currentLayout,\n components: currentComponents,\n breakBefore: breakNext,\n });\n currentComponents = [];\n breakNext = false;\n }\n // Determine the actual layout based on the columns component configuration\n const columnsLayout = determineComponentLayout(component);\n groups.push({\n layout: columnsLayout,\n components: [component],\n breakBefore: breakNext,\n });\n breakNext = false;\n continue;\n }\n\n const componentLayout = determineComponentLayout(component);\n\n // Check for explicit break indicators\n if (hasPageBreak(component)) {\n if (currentComponents.length > 0) {\n // Finish previous group without break\n groups.push({\n layout: currentLayout,\n components: currentComponents,\n breakBefore: breakNext,\n });\n currentComponents = [];\n breakNext = false;\n }\n // Start new group with break for this component\n currentComponents = [component];\n breakNext = true;\n continue;\n }\n\n // Layout change requires new group\n if (componentLayout !== currentLayout && currentComponents.length > 0) {\n groups.push({\n layout: currentLayout,\n components: currentComponents,\n breakBefore: breakNext,\n });\n currentLayout = componentLayout;\n currentComponents = [component];\n breakNext = false;\n } else {\n currentComponents.push(component);\n }\n }\n\n // Add remaining components\n if (currentComponents.length > 0) {\n groups.push({\n layout: currentLayout,\n components: currentComponents,\n breakBefore: breakNext,\n });\n }\n\n return groups;\n}\n\n/**\n * Determine layout type for a component\n */\nexport function determineComponentLayout(\n component: ComponentDefinition\n): 'single' | 'multi-column' {\n if (isColumnsComponent(component)) {\n const columns = (component as any).props?.columns;\n\n // If columns is an array with specific configurations\n if (Array.isArray(columns)) {\n // Any columns array with 2+ items is multi-column\n return columns.length >= 2 ? 'multi-column' : 'single';\n }\n\n // No valid array provided; treat as single-column\n return 'single';\n }\n\n // Check if component contains children\n if ('children' in component && (component as any).children) {\n const hasColumns = (component as any).children.some((child: ComponentDefinition) =>\n isColumnsComponent(child)\n );\n return hasColumns ? 'multi-column' : 'single';\n }\n\n return 'single';\n}\n\n/**\n * Process components for layout (insert breaks where needed)\n */\nexport function processLayoutComponents(\n components: ComponentDefinition[]\n): ComponentDefinition[] {\n const processed: ComponentDefinition[] = [];\n\n for (let i = 0; i < components.length; i++) {\n const component = components[i];\n\n // Check if this component should have a column break\n if (shouldInsertColumnBreak()) {\n // Create a new component with columnBreak flag\n if (isHeadingComponent(component)) {\n processed.push({\n ...component,\n props: {\n ...((component as any).props || {}),\n columnBreak: true,\n },\n } as ComponentDefinition);\n } else {\n processed.push(component);\n }\n } else {\n processed.push(component);\n }\n }\n\n return processed;\n}\n\n/**\n * Determine if a column break should be inserted\n */\nfunction shouldInsertColumnBreak(): boolean {\n // Logic to determine column breaks based on content distribution\n // This is simplified - could be enhanced with more sophisticated logic\n return false;\n}\n\n/**\n * Check if component indicates a page break\n */\nfunction hasPageBreak(component: ComponentDefinition): boolean {\n if (isSectionComponent(component)) {\n // Default to true for section components when pageBreak is undefined\n return component.props?.pageBreak !== false;\n }\n if (isHeadingComponent(component)) {\n return component.props.pageBreak === true;\n }\n if (isParagraphComponent(component)) {\n return component.props.pageBreak === true;\n }\n // Allow TOC components to request a page break as well\n if (isTocComponent(component)) {\n return component.props?.pageBreak === true;\n }\n return false;\n}\n\n/**\n * Get column settings for layout type\n */\nexport function getColumnSettings(\n layout: 'single' | 'multi-column'\n): ColumnSettings {\n switch (layout) {\n case 'multi-column':\n // Default multi-column layout: 2 equal-width columns\n // Note: Specific column components will override this with their own settings via createColumnSettingsFromConfig\n return {\n count: 2,\n equalWidth: true,\n space: 720, // 0.5 inch in twips\n };\n case 'single':\n default:\n return { count: 1 };\n }\n}\n\n/**\n * Create Word section properties\n */\nexport function createSectionProperties(\n columnSettings: ColumnSettings,\n theme: ThemeConfig,\n themeName: string,\n sectionType?: 'continuous' | 'nextPage',\n pageOverride?: {\n size?: 'A4' | 'A3' | 'LETTER' | 'LEGAL' | { width: number; height: number };\n margins?: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n header?: number;\n footer?: number;\n gutter?: number;\n };\n }\n): WordSectionProperties {\n // Get base page setup from theme\n const basePageSetup = getPageSetup(theme, themeName);\n\n // Apply section-level page overrides if present\n const pageSetup = pageOverride\n ? {\n size: {\n ...basePageSetup.size,\n ...(pageOverride.size && typeof pageOverride.size === 'object'\n ? pageOverride.size\n : pageOverride.size\n ? (() => {\n // Convert string size to dimensions\n const sizes = {\n A4: { width: 11906, height: 16838 },\n A3: { width: 16838, height: 23811 },\n LETTER: { width: 12240, height: 15840 },\n LEGAL: { width: 12240, height: 20160 },\n };\n return sizes[pageOverride.size as keyof typeof sizes];\n })()\n : {}),\n },\n margin: {\n ...basePageSetup.margin,\n ...(pageOverride.margins || {}),\n },\n }\n : basePageSetup;\n\n const properties: WordSectionProperties = {\n page: pageSetup,\n column: {\n count: columnSettings.count,\n equalWidth: columnSettings.equalWidth,\n space: columnSettings.space,\n },\n };\n\n // If explicit children were provided, convert to docx Column instances\n if (\n (columnSettings as any).children &&\n Array.isArray((columnSettings as any).children)\n ) {\n const children = (columnSettings as any).children as {\n width?: number;\n space?: number;\n }[];\n // When we have explicit column children, ensure equalWidth is explicitly false\n // so Word doesn't override widths with equal distribution.\n properties.column.equalWidth = false;\n // Also remove top-level space to avoid conflicting with per-column spaces\n delete properties.column.space;\n\n properties.column.children = children.map(\n (c) =>\n new DocxColumn({\n width: c.width as number,\n ...(c.space !== undefined ? { space: c.space } : {}),\n })\n );\n }\n\n if (sectionType) {\n properties.type =\n sectionType === 'continuous'\n ? SectionType.CONTINUOUS\n : SectionType.NEXT_PAGE;\n }\n\n return properties;\n}\n\n/**\n * Create explicit column settings from a Columns component props\n * - width/gap accept number (points) or percentage string relative to available width\n */\nfunction createColumnSettingsFromConfig(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): ColumnSettings {\n const cfg = ((component as any).props || {}) as {\n columns?: Array<{ width?: number | string; gap?: number | string }>;\n };\n\n // Fallback to single column if no valid array is provided\n const columns = (cfg.columns || []) as Array<{\n width?: number | string;\n gap?: number | string;\n }>;\n\n if (!Array.isArray(columns) || columns.length === 0) {\n return { count: 1 };\n }\n\n const availableWidthTwips = getAvailableWidthTwips(theme, themeName);\n\n // First pass: compute defined widths/spaces; collect indexes without width\n const childSettings: { width?: number; space?: number }[] = [];\n let totalDefinedWidth = 0;\n let totalSpace = 0;\n const unspecifiedWidthIndexes: number[] = [];\n\n for (let i = 0; i < columns.length; i++) {\n const c = columns[i];\n const child: { width?: number; space?: number } = {};\n\n if (c.width !== undefined) {\n const widthTwips = relativeLengthToTwips(c.width, availableWidthTwips);\n if (widthTwips > 0) {\n child.width = widthTwips;\n totalDefinedWidth += widthTwips;\n }\n } else {\n unspecifiedWidthIndexes.push(i);\n }\n\n if (c.gap !== undefined) {\n const spaceTwips = relativeLengthToTwips(c.gap, availableWidthTwips);\n if (spaceTwips > 0) {\n child.space = spaceTwips;\n totalSpace += spaceTwips;\n }\n }\n\n childSettings.push(child);\n }\n\n // Validate that defined widths + gaps do not exceed available width (with tolerance)\n const totalUsedTwips = totalDefinedWidth + totalSpace;\n const tolerance = 0.005; // 0.5%\n const allowed = availableWidthTwips * (1 + tolerance);\n if (totalUsedTwips > allowed) {\n const usedPercent = (totalUsedTwips / availableWidthTwips) * 100;\n // Build diagnostics per column\n const details = childSettings\n .map((c, idx) => {\n const wPct = c.width\n ? ((c.width / availableWidthTwips) * 100).toFixed(1) + '%'\n : 'auto/unspecified';\n const gPct = c.space\n ? ((c.space / availableWidthTwips) * 100).toFixed(1) + '%'\n : '0%';\n return ` - Column ${idx + 1}: width=${wPct}, gap=${gPct}`;\n })\n .join('\\n');\n const suggestion =\n 'Reduce one or more widths/gaps so total <= 100%, remove the last gap, or set some widths to \"auto\" to consume remaining space.';\n throw new Error(\n `Columns configuration exceeds available width: widths + gaps = ${usedPercent.toFixed(1)}% (> 100% + ${(\n tolerance * 100\n ).toFixed(\n 1\n )}% tolerance)\\nDetails:\\n${details}\\nSuggestion: ${suggestion}`\n );\n }\n\n // Distribute remaining width equally among unspecified widths\n const remaining = Math.max(\n 0,\n availableWidthTwips - totalSpace - totalDefinedWidth\n );\n if (unspecifiedWidthIndexes.length > 0) {\n const each = Math.floor(remaining / unspecifiedWidthIndexes.length);\n for (const idx of unspecifiedWidthIndexes) {\n childSettings[idx].width = each;\n }\n }\n\n return {\n count: columns.length,\n equalWidth: false,\n children: childSettings,\n };\n}\n\n/**\n * Calculate optimal column distribution for content\n */\nexport function calculateColumnDistribution(\n components: ComponentDefinition[],\n columnCount: number\n): ComponentDefinition[][] {\n if (columnCount === 1) {\n return [components];\n }\n\n // Simple distribution - could be enhanced with content-aware logic\n const columns: ComponentDefinition[][] = Array(columnCount)\n .fill(null)\n .map(() => []);\n let currentColumn = 0;\n\n for (const component of components) {\n columns[currentColumn].push(component);\n currentColumn = (currentColumn + 1) % columnCount;\n }\n\n return columns;\n}\n","/**\n * Render Functions\n * Transform components and layout into Word document elements\n */\n\nimport {\n Document,\n Paragraph,\n Table,\n TableOfContents,\n IPropertiesOptions,\n ISectionOptions,\n TextRun,\n AlignmentType,\n BookmarkStart,\n BookmarkEnd,\n Textbox,\n} from 'docx';\nimport {\n calculateImageDimensions,\n getImageBuffer,\n parseWidthValue,\n detectImageType,\n createTypedImageRun,\n resolveImageSource,\n} from '../utils/imageUtils';\nimport {\n getThemeColors,\n getThemeFonts,\n getNormalStyle,\n} from '../themes/defaults';\nimport {\n ComponentDefinition,\n RenderContext,\n isHeadingComponent,\n isParagraphComponent,\n isColumnsComponent,\n isImageComponent,\n isVisualComponent,\n isTextBoxComponent,\n isStatisticComponent,\n isTableComponent,\n isSectionComponent,\n isListComponent,\n isTocComponent,\n isHighchartsComponent,\n ParagraphComponentDefinition,\n ImageComponentDefinition,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createWordStyles } from '../styles/themeToDocxAdapter';\nimport { resolveFontFamily } from '../styles/utils/styleHelpers';\nimport { getPageSetup } from '../styles/utils/layoutUtils';\nimport {\n DocumentMetadata,\n ProcessedDocument,\n createRenderContext,\n} from './structure';\nimport { LayoutPlan, SectionLayout } from './layout';\nimport {\n renderComponentWithCache,\n initializeComponentCache,\n} from './cached-render';\nimport { MemoryCache } from '../cache';\nimport type { ServicesConfig } from '@json-to-office/shared';\nimport {\n renderHeadingComponent,\n renderParagraphComponent,\n renderListComponent,\n renderImageComponent,\n renderTableComponent,\n renderSectionComponent,\n renderColumnsComponent,\n renderStatisticComponent,\n renderTocComponent,\n renderHighchartsComponent,\n renderVisualComponent,\n renderTextBoxComponent,\n} from '../components';\nimport {\n createText,\n createHeaderElement,\n createFooterElement,\n} from './content';\nimport { mapFloatingOptions } from '../utils/docxImagePositioning';\nimport { globalBookmarkRegistry } from '../utils/bookmarkRegistry';\nimport { globalNumberingRegistry } from '../utils/numberingConfig';\nimport { globalRevisionIdRegistry } from '../utils/revisionUtils';\nimport { runWithGenerationDate } from '../utils/generationContext';\n\ninterface RenderDocumentOptions {\n cache?: MemoryCache;\n bypassCache?: boolean;\n services?: ServicesConfig;\n}\n\n/**\n * Convert alignment string to docx AlignmentType\n */\nfunction getAlignment(\n alignment: string\n): (typeof AlignmentType)[keyof typeof AlignmentType] {\n switch (alignment) {\n case 'center':\n return AlignmentType.CENTER;\n case 'right':\n return AlignmentType.RIGHT;\n case 'justify':\n return AlignmentType.JUSTIFIED;\n default:\n return AlignmentType.LEFT;\n }\n}\n\ntype CorePropertyOptions = Pick<\n IPropertiesOptions,\n | 'title'\n | 'subject'\n | 'creator'\n | 'description'\n | 'keywords'\n | 'lastModifiedBy'\n | 'customProperties'\n>;\n\n/**\n * Map root `props.metadata` onto Word's document properties.\n *\n * `date` is deliberately absent: it drives placeholder resolution, not the\n * package timestamps. dcterms:created/modified come from the `generatedAt`\n * generation option (docx always stamps them with the wall clock and offers no\n * override, so packageDocument rewrites them), which is why `metadata` exposes\n * no created/modified of its own.\n * `company` and `version` have no core-property slot, so they land in\n * docProps/custom.xml.\n */\nfunction coreProperties(metadata: DocumentMetadata): CorePropertyOptions {\n const { title, subtitle, description, author, company, version, tags } =\n metadata;\n\n const customProperties = [\n ...(company ? [{ name: 'Company', value: company }] : []),\n ...(version ? [{ name: 'Version', value: version }] : []),\n ];\n\n return {\n ...(title && { title }),\n ...(subtitle && { subject: subtitle }),\n ...(description && { description }),\n // Word surfaces both names; author is the only person the document knows.\n ...(author && { creator: author, lastModifiedBy: author }),\n ...(tags && tags.length > 0 && { keywords: tags.join(', ') }),\n ...(customProperties.length > 0 && { customProperties }),\n };\n}\n\n/**\n * Render a complete document from structure and layout\n */\nexport async function renderDocument(\n structure: ProcessedDocument,\n layout: LayoutPlan,\n options?: RenderDocumentOptions\n): Promise<Document> {\n return runWithGenerationDate(structure.metadata.date, () =>\n globalBookmarkRegistry.runScoped(() =>\n globalRevisionIdRegistry.runScoped(() =>\n globalNumberingRegistry.runScoped(() =>\n renderDocumentScoped(structure, layout, options)\n )\n )\n )\n );\n}\n\nasync function renderDocumentScoped(\n structure: ProcessedDocument,\n layout: LayoutPlan,\n options?: RenderDocumentOptions\n): Promise<Document> {\n // Initialize component cache if provided\n if (options?.cache) {\n initializeComponentCache(options.cache);\n } else if (!options?.bypassCache) {\n // Initialize with default cache unless bypassed\n initializeComponentCache();\n }\n\n const sections: ISectionOptions[] = [];\n\n // Render all layout sections\n const context = createRenderContext(\n structure,\n structure.theme,\n structure.themeName\n );\n context.services = options?.services;\n\n // Initialize bookmark counter for this document (scoped to renderDocument call)\n let sectionBookmarkCounter = 0;\n\n // Track previous section's headers/footers for 'linkToPrevious' functionality\n let previousHeader: ComponentDefinition[] | undefined = undefined;\n let previousFooter: ComponentDefinition[] | undefined = undefined;\n\n // Render all layout sections\n for (let idx = 0; idx < layout.sections.length; idx++) {\n const layoutSection = layout.sections[idx];\n\n /**\n * Compute stable section ordinal for user-defined sections.\n *\n * When a user-defined Section component spans multiple layout chunks (e.g., due to\n * column transitions), all chunks must share the same bookmark ID for TOC scoping\n * to work correctly. This ensures:\n * 1. Bookmark start appears only in the first chunk\n * 2. All chunks use the same stable bookmark ID (no timestamp)\n * 3. Bookmark end appears only in the last chunk\n *\n * Previously used Date.now() in bookmark IDs, which caused different IDs per chunk.\n * Now we use a stable ordinal that's consistent across all chunks of the same section.\n */\n let sectionOrdinal: number | undefined = undefined;\n if (layoutSection.belongsToUserSection) {\n if (layoutSection.isUserSection) {\n // First chunk of this user-defined section: assign ordinal as next index\n sectionOrdinal = sectionBookmarkCounter + 1;\n } else {\n // Subsequent chunk: reuse last assigned ordinal\n sectionOrdinal = sectionBookmarkCounter; // previous value already incremented after first chunk\n }\n }\n // Handle 'linkToPrevious' value for headers\n let headerToUse: ComponentDefinition[] | undefined;\n if (layoutSection.header === 'linkToPrevious') {\n // Use the previous section's header\n headerToUse = previousHeader;\n } else if (layoutSection.header) {\n // Section has its own header\n headerToUse = layoutSection.header as ComponentDefinition[];\n previousHeader = headerToUse; // Update previous for next section\n } else {\n // No header explicitly set for this section.\n // Important: Word links headers/footers to previous by default.\n // To prevent unintended inheritance, emit an explicit empty header\n // when a previous header exists and caller didn't request linking.\n headerToUse = previousHeader ? [] : undefined;\n // Keep previousHeader cached for potential future explicit linkToPrevious\n }\n\n // Handle 'linkToPrevious' value for footers\n let footerToUse: ComponentDefinition[] | undefined;\n if (layoutSection.footer === 'linkToPrevious') {\n // Use the previous section's footer\n footerToUse = previousFooter;\n } else if (layoutSection.footer) {\n // Section has its own footer\n footerToUse = layoutSection.footer as ComponentDefinition[];\n previousFooter = footerToUse; // Update previous for next section\n } else {\n // No footer explicitly set for this section.\n // Prevent unintended inheritance by emitting an explicit empty footer\n // when a previous footer exists and caller didn't request linking.\n footerToUse = previousFooter ? [] : undefined;\n // Keep previousFooter cached for potential future explicit linkToPrevious\n }\n\n const sectionToRender = {\n ...layoutSection,\n header: headerToUse,\n footer: footerToUse,\n };\n\n // Determine if we should close the bookmark in this chunk.\n // Close when this is the last chunk belonging to the same user-defined section.\n let closeBookmark = false;\n if (layoutSection.belongsToUserSection && sectionOrdinal !== undefined) {\n const next = layout.sections[idx + 1];\n if (!next || !next.belongsToUserSection || next.isUserSection) {\n closeBookmark = true;\n }\n }\n\n const rendered = await renderSection(\n sectionToRender,\n structure.theme,\n structure.themeName,\n context,\n sectionOrdinal,\n closeBookmark,\n options?.bypassCache === true\n );\n\n // Increment counter if this section created a bookmark\n if (layoutSection.isUserSection) {\n sectionBookmarkCounter++;\n }\n\n if (rendered.children.length > 0) {\n sections.push(rendered);\n }\n }\n\n // Get all numbering configurations from the registry (already imported above)\n const numberingConfigs = globalNumberingRegistry.getAll();\n\n return new Document({\n styles: createWordStyles(structure.theme, structure.language),\n sections,\n ...coreProperties(structure.metadata),\n features: {\n updateFields: true, // Required for TOC fields to update correctly\n // Word opens the document in review mode (further edits are tracked)\n ...(structure.trackRevisions && { trackRevisions: true }),\n },\n // Add numbering configurations if any lists were rendered\n ...(numberingConfigs.length > 0 && {\n numbering: {\n config: numberingConfigs as readonly {\n readonly levels: readonly import('docx').ILevelsOptions[];\n readonly reference: string;\n }[],\n },\n }),\n });\n}\n\n/**\n * Render header/footer components into paragraphs\n */\nasync function renderHeaderFooterComponents(\n components: ComponentDefinition[] | undefined,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!components || components.length === 0) {\n return [];\n }\n\n // Filter out components with enabled: false (defaults to true when not specified)\n const activeComponents = components.filter(\n (m) => !('enabled' in m && m.enabled === false)\n );\n\n const elements: (Paragraph | Table)[] = [];\n\n for (const component of activeComponents) {\n if (isParagraphComponent(component)) {\n const textComp = component as ParagraphComponentDefinition;\n const font = textComp.props.font;\n\n // Header/footer text has no dedicated style, so unspecified font\n // properties resolve against the theme's Normal style.\n const normalStyle = getNormalStyle(theme);\n\n // Render through the shared paragraph primitive (same as body\n // paragraphs) so headers/footers honor lineSpacing, spacing\n // (before/after) and the full font set instead of silently dropping\n // them. When the component omits lineSpacing/spacing, createText leaves\n // them unset and the Normal style supplies the baseline.\n elements.push(\n createText(textComp.props.text, theme, themeName, {\n style: 'Normal',\n alignment: textComp.props.alignment,\n // Resolve explicit run styling against the Normal style, preserving\n // prior header/footer rendering for these properties.\n fontFamily:\n font?.family ||\n resolveFontFamily(theme, normalStyle.font) ||\n getThemeFonts(theme).body.family,\n fontSize: (font?.size ?? normalStyle.size ?? 11) as number,\n // Pass the raw color/token; createText resolves it. Fall back to the\n // Normal style color, then the theme's primary text color.\n fontColor: font?.color || normalStyle.color || 'textPrimary',\n bold: font?.bold ?? false,\n italic: font?.italic ?? false,\n underline: font?.underline,\n fontWeight: (font as { fontWeight?: number } | undefined)?.fontWeight,\n boldColor: textComp.props.boldColor,\n spacing: textComp.props.spacing,\n lineSpacing: font?.lineSpacing,\n })\n );\n } else if (isImageComponent(component)) {\n const imageComp = component as ImageComponentDefinition;\n // Get image source (svg, base64, or path)\n let imageSource = resolveImageSource(imageComp.props);\n if (!imageSource) {\n elements.push(\n new Paragraph({\n children: [\n new TextRun({\n text: '[IMAGE: Missing path, base64, or svg property]',\n font: getThemeFonts(theme).body.family,\n size: 20,\n bold: true,\n color: '#FF0000',\n }),\n ],\n alignment: imageComp.props.alignment\n ? getAlignment(imageComp.props.alignment)\n : undefined,\n style: 'Normal',\n })\n );\n continue;\n }\n\n let imageBuffer: Buffer;\n let responseContentType: string | undefined;\n\n try {\n // Try to use the provided source first\n const imageResult = await getImageBuffer(imageSource);\n imageBuffer = imageResult.buffer;\n responseContentType = imageResult.contentType;\n } catch (error) {\n throw new Error(\n `Failed to load image from ${imageSource.substring(0, 50)}`\n );\n }\n\n try {\n // Get page setup from theme for proper width calculations\n const pageSetup = getPageSetup(theme);\n\n // Convert twips to pixels: 1 twip = 1/1440 inch, 1 inch = 96 pixels at 96 DPI\n const TWIPS_TO_PIXELS = 96 / 1440;\n\n // Calculate page width and content width (page - left margin - right margin) in pixels\n const pageWidthPx = Math.round(pageSetup.size.width * TWIPS_TO_PIXELS);\n const contentWidthPx = Math.round(\n (pageSetup.size.width -\n pageSetup.margin.left -\n pageSetup.margin.right) *\n TWIPS_TO_PIXELS\n );\n\n // Determine reference dimensions based on widthRelativeTo/heightRelativeTo properties\n const widthRelativeTo = imageComp.props.widthRelativeTo || 'content';\n const heightRelativeTo = imageComp.props.heightRelativeTo || 'content';\n const referenceWidthPx =\n widthRelativeTo === 'page' ? pageWidthPx : contentWidthPx;\n\n // Calculate page height and content height in pixels\n const pageHeightPx = Math.round(\n pageSetup.size.height * TWIPS_TO_PIXELS\n );\n const contentHeightPx = Math.round(\n (pageSetup.size.height -\n pageSetup.margin.top -\n pageSetup.margin.bottom) *\n TWIPS_TO_PIXELS\n );\n const referenceHeightPx =\n heightRelativeTo === 'page' ? pageHeightPx : contentHeightPx;\n\n const fallbackHeight = Math.round(referenceWidthPx * 0.6);\n\n // Parse width value if it's a string percentage (like \"90%\")\n const parsedWidth =\n typeof imageComp.props.width === 'string'\n ? parseWidthValue(imageComp.props.width, referenceWidthPx) // Use appropriate reference width\n : imageComp.props.width;\n\n // Parse height value if it's a string percentage (like \"90%\")\n const parsedHeight =\n typeof imageComp.props.height === 'string'\n ? parseWidthValue(imageComp.props.height, referenceHeightPx) // Use reference height based on heightRelativeTo\n : imageComp.props.height;\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imageSource,\n parsedWidth,\n parsedHeight,\n referenceWidthPx,\n fallbackHeight\n );\n\n // Map floating options if present\n const floatingOptions = mapFloatingOptions(\n imageComp.props.floating,\n theme,\n themeName\n );\n\n const imageType = detectImageType(imageSource, responseContentType);\n\n const imageRun = createTypedImageRun({\n type: imageType,\n data: imageBuffer,\n transformation: {\n width: dimensions.width,\n height: dimensions.height,\n },\n ...(floatingOptions && { floating: floatingOptions }),\n });\n\n elements.push(\n new Paragraph({\n children: [imageRun],\n alignment: imageComp.props.alignment\n ? getAlignment(imageComp.props.alignment)\n : undefined,\n style: 'Normal',\n })\n );\n } catch (error) {\n // Fallback for missing images - log error for debugging.\n // Use the resolved source (svg/base64/path), truncated so an inline\n // data URI doesn't dump into the log or the placeholder text.\n const sourcePreview = imageSource.substring(0, 50);\n console.error(\n `[Header/Footer Image Error] Failed to render image: ${sourcePreview}...`,\n error instanceof Error ? error.message : error\n );\n elements.push(\n new Paragraph({\n children: [\n new TextRun({\n text: `[IMAGE: ${sourcePreview}]`,\n font: getThemeFonts(theme).body.family,\n size: 20,\n color: getThemeColors(theme).secondary,\n bold: true,\n }),\n ],\n style: 'Normal',\n })\n );\n }\n } else if (isTableComponent(component)) {\n // Use renderTableComponent for consistent table rendering in headers/footers\n // This ensures cellDefaults, padding, borders, and all table features work correctly\n const tables = await renderTableComponent(component, theme, themeName);\n elements.push(...tables);\n } else if (isVisualComponent(component)) {\n // A visual desugars to an image; needs the rasterization service from context.\n const visualEls = await renderVisualComponent(\n component,\n theme,\n themeName,\n context\n );\n elements.push(...visualEls);\n }\n // Other component types can be added here as needed\n }\n\n return elements;\n}\n\n/**\n * Render a section with layout\n */\nexport async function renderSection(\n section: SectionLayout,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext,\n sectionOrdinal?: number,\n closeBookmark?: boolean,\n bypassCache = false\n): Promise<ISectionOptions> {\n const elements: (Paragraph | Table | TableOfContents)[] = [];\n\n // Update context for this section\n // Generate a unique bookmark for this section so TOCs can scope to it\n const isFirstLayoutOfUserSection = section.isUserSection;\n // Use a stable bookmark ID across all layout sections of the same user-defined section\n const sharedLinkId =\n section.belongsToUserSection && sectionOrdinal ? sectionOrdinal : undefined;\n const sectionBookmarkId =\n sharedLinkId !== undefined ? `_Section_${sharedLinkId}` : undefined;\n\n const sectionContext: RenderContext = {\n ...context,\n section: {\n ...context.section,\n currentLayout: section.layoutType,\n columnCount: section.properties.column?.count || 1,\n // Always pass the same bookmark ID for all layout chunks of the same section\n sectionBookmarkId: sectionBookmarkId,\n // Pass section title level for TOC scoping (excludes section title from its own TOC)\n sectionTitleLevel: section.sectionTitleLevel,\n },\n };\n\n // Add bookmark start before all section content so TOCs can scope to it\n if (\n sectionBookmarkId &&\n isFirstLayoutOfUserSection &&\n sharedLinkId !== undefined\n ) {\n elements.push(\n new Paragraph({\n children: [new BookmarkStart(sectionBookmarkId, sharedLinkId)],\n spacing: {\n before: 0,\n after: 0,\n line: 0,\n },\n })\n );\n }\n\n // Filter out components with enabled: false and render remaining components (with caching)\n const activeComponents = section.components.filter(\n (m) => !('enabled' in m && m.enabled === false)\n );\n for (const component of activeComponents) {\n const rendered = await renderComponentWithCache(\n component,\n theme,\n themeName,\n sectionContext,\n bypassCache\n );\n elements.push(...rendered);\n }\n\n // Close bookmark after section content\n if (closeBookmark && sharedLinkId !== undefined) {\n elements.push(\n new Paragraph({\n children: [new BookmarkEnd(sharedLinkId)],\n })\n );\n }\n\n // Build section options with headers/footers if defined\n let headers: ISectionOptions['headers'] | undefined;\n let footers: ISectionOptions['footers'] | undefined;\n\n if (section.header || section.footer) {\n if (section.header && section.header !== 'linkToPrevious') {\n const headerComponents = section.header as ComponentDefinition[];\n const headerParagraphs = await renderHeaderFooterComponents(\n headerComponents,\n theme,\n themeName,\n sectionContext\n );\n // If components were provided but produced no paragraphs, still create\n // an empty Header to break Word's default link-to-previous behavior.\n if (headerComponents.length === 0 || headerParagraphs.length > 0) {\n headers = {\n default: createHeaderElement(headerParagraphs),\n };\n }\n }\n\n if (section.footer && section.footer !== 'linkToPrevious') {\n const footerComponents = section.footer as ComponentDefinition[];\n const footerParagraphs = await renderHeaderFooterComponents(\n footerComponents,\n theme,\n themeName,\n sectionContext\n );\n if (footerComponents.length === 0 || footerParagraphs.length > 0) {\n footers = {\n default: createFooterElement(footerParagraphs),\n };\n }\n }\n }\n\n const sectionOptions: ISectionOptions = {\n properties: section.properties,\n children: elements,\n headers,\n footers,\n };\n\n return sectionOptions;\n}\n\n/**\n * Render a single component to Word elements\n */\nexport async function renderComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<(Paragraph | Table | TableOfContents | Textbox)[]> {\n if (isHeadingComponent(component)) {\n return renderHeadingComponent(component, theme, themeName);\n } else if (isParagraphComponent(component)) {\n return renderParagraphComponent(component, theme, themeName);\n } else if (isColumnsComponent(component)) {\n return await renderColumnsComponent(component, theme, themeName, context);\n } else if (isImageComponent(component)) {\n return await renderImageComponent(component, theme, themeName);\n } else if (isTextBoxComponent(component)) {\n return await renderTextBoxComponent(component, theme, themeName, context);\n } else if (isStatisticComponent(component)) {\n return renderStatisticComponent(component, theme);\n } else if (isTableComponent(component)) {\n return await renderTableComponent(component, theme, themeName);\n } else if (isListComponent(component)) {\n return renderListComponent(component, theme, themeName);\n } else if (isTocComponent(component)) {\n return renderTocComponent(component, theme, context);\n } else if (isHighchartsComponent(component)) {\n return await renderHighchartsComponent(\n component,\n theme,\n themeName,\n context\n );\n } else if (isVisualComponent(component)) {\n return await renderVisualComponent(component, theme, themeName, context);\n } else if (isSectionComponent(component)) {\n return await renderSectionComponent(component, theme, themeName, context);\n }\n\n throw new Error(\n `Unknown component type: ${(component as ComponentDefinition).name}`\n );\n}\n","import { readFileSync } from 'fs';\nimport probe from 'probe-image-size';\nimport { ImageRun, IFloating } from 'docx';\nimport { parsePercentageStringToFraction } from './widthUtils';\n\nexport interface ImageDimensions {\n width: number;\n height: number;\n}\n\nexport interface CalculatedDimensions {\n width: number;\n height: number;\n}\n\nexport interface ImageBufferResult {\n buffer: Buffer;\n contentType?: string;\n}\n\n/**\n * Parse width value - accepts either number (pixels) or percentage string\n * @param width - Width value as number or percentage string (e.g., \"90%\")\n * @param availableWidthPx - Available document width in pixels\n * @returns Width in pixels\n */\nexport function parseWidthValue(\n width: number | string,\n availableWidthPx: number\n): number {\n if (typeof width === 'number') {\n return width;\n }\n\n // Parse percentage string using shared util while preserving error semantics\n const percentageMatch = (width as string).match(/^(\\d+(?:\\.\\d+)?)%$/);\n if (percentageMatch) {\n const pct = parseFloat(percentageMatch[1]);\n if (pct < 0 || pct > 100) {\n throw new Error(\n `Invalid percentage value: ${width}. Must be between 0% and 100%`\n );\n }\n const fraction = parsePercentageStringToFraction(width as string);\n if (fraction !== undefined) {\n return Math.round(availableWidthPx * fraction);\n }\n }\n\n throw new Error(\n `Invalid width value: ${width}. Expected number (pixels) or percentage string (e.g., \"90%\")`\n );\n}\n\n/**\n * Parse a generic dimension value (number in px or percentage string)\n * @param value - numeric pixels or percentage string (e.g., \"100%\")\n * @param availablePx - available pixels for percentage reference\n */\nexport function parseDimensionValue(\n value: number | string,\n availablePx: number\n): number {\n if (typeof value === 'number') return value;\n const percentageMatch = (value as string).match(/^(\\d+(?:\\.\\d+)?)%$/);\n if (percentageMatch) {\n const pct = parseFloat(percentageMatch[1]);\n if (pct < 0 || pct > 100) {\n throw new Error(\n `Invalid percentage value: ${value}. Must be between 0% and 100%`\n );\n }\n const fraction = parsePercentageStringToFraction(value as string);\n if (fraction !== undefined) return Math.round(availablePx * fraction);\n }\n throw new Error(\n `Invalid dimension value: ${value}. Expected number (pixels) or percentage string (e.g., \"90%\")`\n );\n}\n\n/**\n * Check if a string is a valid URL\n */\nexport function isValidUrl(string: string): boolean {\n try {\n const url = new URL(string);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a string is a base64 data URI\n * Supports format: data:image/[type];base64,[data]\n */\nexport function isBase64Image(string: string): boolean {\n return /^data:image\\/[a-zA-Z+]+;base64,/.test(string);\n}\n\n/**\n * Decode base64 data URI to Buffer\n * @param dataUri - Base64 data URI (e.g., \"data:image/png;base64,iVBORw0KGgo...\")\n * @returns Decoded image buffer\n */\nexport function decodeBase64Image(dataUri: string): Buffer {\n try {\n // Extract the base64 data after the comma\n const base64Data = dataUri.split(',')[1];\n if (!base64Data) {\n throw new Error('Invalid base64 data URI format');\n }\n return Buffer.from(base64Data, 'base64');\n } catch (error) {\n throw new Error(\n `Failed to decode base64 image: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Extract MIME type from base64 data URI\n * @param dataUri - Base64 data URI (e.g., \"data:image/svg+xml;base64,...\")\n * @returns MIME type (e.g., \"image/svg+xml\") or undefined if not found\n */\nexport function extractMimeTypeFromDataUri(\n dataUri: string\n): string | undefined {\n const match = dataUri.match(/^data:(image\\/[a-zA-Z0-9+.-]+);base64,/);\n return match ? match[1] : undefined;\n}\n\n/**\n * Detect image type from file extension\n * @param path - File path or URL\n * @returns Image type (jpg, png, gif, bmp, svg) or undefined\n */\nexport function detectImageTypeFromExtension(\n path: string\n): 'jpg' | 'png' | 'gif' | 'bmp' | 'svg' | undefined {\n const extension = path.toLowerCase().split('.').pop()?.split('?')[0]; // Handle query params in URLs\n switch (extension) {\n case 'jpg':\n case 'jpeg':\n return 'jpg';\n case 'png':\n return 'png';\n case 'gif':\n return 'gif';\n case 'bmp':\n return 'bmp';\n case 'svg':\n return 'svg';\n default:\n return undefined;\n }\n}\n\n/**\n * Detect image type from MIME type\n * @param mimeType - MIME type string (e.g., \"image/svg+xml\", \"image/png\")\n * @returns Image type (jpg, png, gif, bmp, svg) or undefined\n */\nexport function detectImageTypeFromMimeType(\n mimeType: string\n): 'jpg' | 'png' | 'gif' | 'bmp' | 'svg' | undefined {\n const normalized = mimeType.toLowerCase();\n if (normalized.includes('svg')) return 'svg';\n if (normalized.includes('jpeg') || normalized.includes('jpg')) return 'jpg';\n if (normalized.includes('png')) return 'png';\n if (normalized.includes('gif')) return 'gif';\n if (normalized.includes('bmp')) return 'bmp';\n return undefined;\n}\n\n/**\n * Detect image type from path or base64 data URI\n * Prioritizes: response Content-Type > MIME type from base64 > file extension > default to 'png'\n * @param imagePath - File path, URL, or base64 data URI\n * @param responseContentType - Optional Content-Type header from HTTP response\n * @returns Image type (jpg, png, gif, bmp, svg)\n */\nexport function detectImageType(\n imagePath: string,\n responseContentType?: string\n): 'jpg' | 'png' | 'gif' | 'bmp' | 'svg' {\n // Highest priority: Content-Type from HTTP response\n if (responseContentType) {\n const typeFromResponse = detectImageTypeFromMimeType(responseContentType);\n if (typeFromResponse) return typeFromResponse;\n }\n\n // Check if it's a base64 data URI and extract MIME type\n if (isBase64Image(imagePath)) {\n const mimeType = extractMimeTypeFromDataUri(imagePath);\n if (mimeType) {\n const typeFromMime = detectImageTypeFromMimeType(mimeType);\n if (typeFromMime) return typeFromMime;\n }\n }\n\n // Try to detect from file extension\n const typeFromExtension = detectImageTypeFromExtension(imagePath);\n if (typeFromExtension) return typeFromExtension;\n\n // Default to PNG for backward compatibility\n return 'png';\n}\n\n/**\n * Create an ImageRun with correct type handling, including SVG fallback.\n * TODO: SVG fallback uses raw SVG as PNG — works in Word 2016+ which renders\n * SVG natively; fallback won't render correctly in older versions.\n */\nexport function createTypedImageRun(opts: {\n type: 'jpg' | 'png' | 'gif' | 'bmp' | 'svg';\n data: Buffer;\n transformation: { width: number; height: number };\n floating?: IFloating;\n}): ImageRun {\n const base = {\n data: opts.data,\n transformation: opts.transformation,\n ...(opts.floating && { floating: opts.floating }),\n };\n if (opts.type === 'svg') {\n return new ImageRun({\n type: 'svg',\n ...base,\n fallback: { type: 'png', data: opts.data },\n });\n }\n return new ImageRun({ type: opts.type, ...base });\n}\n\n/**\n * Download image from URL and return buffer\n * Uses native fetch with automatic redirect following and proper headers\n */\nexport async function downloadImageFromUrl(\n url: string\n): Promise<ImageBufferResult> {\n try {\n // Create an AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout\n\n const response = await fetch(url, {\n signal: controller.signal,\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; json-to-docx/1.0)',\n },\n redirect: 'follow', // Automatically follow redirects (default behavior)\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(\n `Failed to download image: HTTP ${response.status} ${response.statusText}`\n );\n }\n\n const contentType = response.headers.get('content-type') || undefined;\n\n // Get the response as an ArrayBuffer\n const arrayBuffer = await response.arrayBuffer();\n\n // Convert ArrayBuffer to Buffer\n return { buffer: Buffer.from(arrayBuffer), contentType };\n } catch (error) {\n if (error instanceof Error) {\n // Handle timeout errors\n if (error.name === 'AbortError') {\n throw new Error(\n 'Failed to download image: Request timeout after 10 seconds'\n );\n }\n throw new Error(`Failed to download image from ${url}: ${error.message}`);\n }\n throw new Error(`Failed to download image from ${url}: Unknown error`);\n }\n}\n\n/**\n * Resolve the effective image source string from image component props.\n * Precedence: raw inline `svg` markup (wrapped into an svg data URI) > `base64`\n * data URI > `path` (file/URL). Returns undefined when no source is provided.\n *\n * Raw SVG is encoded as a base64 svg+xml data URI so it flows through the same\n * pipeline as any other source (getImageBuffer / detectImageType / dimensions).\n */\nexport function resolveImageSource(props: {\n svg?: string;\n base64?: string;\n path?: string;\n}): string | undefined {\n const hasValue = (v?: string): v is string =>\n typeof v === 'string' && v.trim().length > 0;\n if (hasValue(props.svg)) {\n const encoded = Buffer.from(props.svg, 'utf-8').toString('base64');\n return `data:image/svg+xml;base64,${encoded}`;\n }\n // Blank base64/path count as absent (matching the source-conflict validator),\n // so a whitespace-only value can't shadow a real later source.\n if (hasValue(props.base64)) return props.base64;\n if (hasValue(props.path)) return props.path;\n return undefined;\n}\n\n/**\n * Get image buffer from base64 data URI, URL, or local file\n */\nexport async function getImageBuffer(\n imagePath: string\n): Promise<ImageBufferResult> {\n // Check for base64 data URI first\n if (isBase64Image(imagePath)) {\n return { buffer: decodeBase64Image(imagePath) };\n }\n // Check for URL\n if (isValidUrl(imagePath)) {\n return await downloadImageFromUrl(imagePath);\n }\n // Otherwise treat as local file path\n return { buffer: readFileSync(imagePath) };\n}\n\n/**\n * Get the dimensions of an image file or URL\n */\nexport async function getImageDimensions(\n imagePath: string\n): Promise<ImageDimensions> {\n try {\n const { buffer: imageBuffer } = await getImageBuffer(imagePath);\n const result = probe.sync(imageBuffer);\n\n if (!result) {\n throw new Error(`Unable to determine dimensions for image: ${imagePath}`);\n }\n\n return {\n width: result.width,\n height: result.height,\n };\n } catch (error) {\n throw new Error(\n `Error reading image dimensions from ${imagePath}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Calculate missing dimension while preserving aspect ratio\n */\nexport function calculateMissingDimension(\n originalWidth: number,\n originalHeight: number,\n targetWidth?: number,\n targetHeight?: number\n): CalculatedDimensions {\n if (targetWidth && targetHeight) {\n // Both dimensions provided, use as-is\n return { width: targetWidth, height: targetHeight };\n }\n\n const aspectRatio = originalWidth / originalHeight;\n\n if (targetWidth && !targetHeight) {\n // Width provided, calculate height\n return {\n width: targetWidth,\n height: Math.round(targetWidth / aspectRatio),\n };\n }\n\n if (!targetWidth && targetHeight) {\n // Height provided, calculate width\n return {\n width: Math.round(targetHeight * aspectRatio),\n height: targetHeight,\n };\n }\n\n // Neither provided, return original dimensions\n return { width: originalWidth, height: originalHeight };\n}\n\n/**\n * Calculate image dimensions with aspect ratio preservation and fallback constraints\n */\nexport async function calculateImageDimensions(\n imagePath: string,\n targetWidth?: number,\n targetHeight?: number,\n fallbackWidth: number = 300,\n fallbackHeight: number = 180\n): Promise<CalculatedDimensions> {\n try {\n const originalDimensions = await getImageDimensions(imagePath);\n return calculateMissingDimension(\n originalDimensions.width,\n originalDimensions.height,\n targetWidth,\n targetHeight\n );\n } catch (error) {\n // If we can't read the image, use fallback logic\n if (targetWidth && targetHeight) {\n return { width: targetWidth, height: targetHeight };\n }\n\n if (targetWidth && !targetHeight) {\n // Use a default aspect ratio (16:9) for fallback\n return { width: targetWidth, height: Math.round((targetWidth * 9) / 16) };\n }\n\n if (!targetWidth && targetHeight) {\n // Use a default aspect ratio (16:9) for fallback\n return {\n width: Math.round((targetHeight * 16) / 9),\n height: targetHeight,\n };\n }\n\n // No dimensions provided and can't read image, use fallback\n return { width: fallbackWidth, height: fallbackHeight };\n }\n}\n","import {\n IStylesOptions,\n IRunStylePropertiesOptions,\n IParagraphStylePropertiesOptions,\n AlignmentType,\n TabStopPosition,\n} from 'docx';\nimport { getTheme } from '../templates/themes';\nimport type { ThemeConfig } from './index';\nimport { resolveColor } from './utils/colorUtils';\nimport {\n convertLineSpacing,\n pointsToTwips,\n resolveFontProperties,\n mergeFontAndStyleProperties,\n} from './utils/styleHelpers';\n\n// Border types for paragraph borders in theme styles\ninterface ThemeBorderDefinition {\n style: string; // e.g., 'single', 'double', 'dotted', etc.\n size: number; // width in eighths of a point (docx sz)\n color: string; // hex or theme color key\n space?: number; // space in points\n}\n\ninterface ThemeBorders {\n top?: ThemeBorderDefinition;\n bottom?: ThemeBorderDefinition;\n left?: ThemeBorderDefinition;\n right?: ThemeBorderDefinition;\n}\n\n// Style properties for various text elements\ninterface StyleProperties {\n font?: 'heading' | 'body' | 'mono' | 'light';\n size?: number;\n color?: string;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n alignment?: 'left' | 'center' | 'right' | 'justify';\n lineSpacing?: {\n type: 'single' | 'atLeast' | 'exactly' | 'double' | 'multiple';\n value?: number;\n };\n spacing?: {\n before?: number;\n after?: number;\n };\n characterSpacing?: { type: 'condensed' | 'expanded'; value: number };\n scale?: number;\n priority?: number;\n baseStyle?: string;\n followingStyle?: string;\n widowControl?: boolean;\n keepNext?: boolean;\n keepLinesTogether?: boolean;\n outlineLevel?: number;\n borders?: ThemeBorders;\n indent?: {\n left?: number;\n hanging?: number;\n };\n}\n\n/**\n * Type-safe style name union\n */\ntype StyleName =\n | 'normal'\n | 'heading1'\n | 'heading2'\n | 'heading3'\n | 'heading4'\n | 'heading5'\n | 'heading6'\n | 'title'\n | 'subtitle';\n\n/**\n * Type guard to check if a style name is valid\n */\nfunction isValidStyleName(name: string): name is StyleName {\n return [\n 'normal',\n 'heading1',\n 'heading2',\n 'heading3',\n 'heading4',\n 'heading5',\n 'heading6',\n 'title',\n 'subtitle',\n ].includes(name);\n}\n\n/**\n * Type-safe style getter with proper error handling\n */\nfunction getStyleSafe(\n theme: ThemeConfig,\n styleName: string\n): StyleProperties | undefined {\n if (!isValidStyleName(styleName)) {\n console.warn(`Invalid style name: ${styleName}`);\n return undefined;\n }\n return theme.styles?.[styleName] as StyleProperties | undefined;\n}\n\n/**\n * Resolves a style with baseStyle inheritance.\n * If a style has a baseStyle property, recursively resolves the base style first\n * and merges its properties with the current style (current overrides base).\n *\n * @param theme - Theme configuration\n * @param styleName - Name of the style to resolve\n * @param visited - Set of visited style names to prevent circular references\n * @returns Resolved style with all inherited properties, or undefined if not found\n */\nfunction resolveStyleWithBaseStyle(\n theme: ThemeConfig,\n styleName: string,\n visited: Set<string> = new Set()\n): StyleProperties | undefined {\n // Prevent circular references\n if (visited.has(styleName)) {\n console.warn(\n `Circular baseStyle reference detected: ${Array.from(visited).join(\n ' → '\n )} → ${styleName}`\n );\n return undefined;\n }\n\n visited.add(styleName);\n\n // Use type-safe getter instead of type assertion\n const style = getStyleSafe(theme, styleName);\n if (!style) {\n return undefined;\n }\n\n // If no baseStyle, return style as-is\n if (!style.baseStyle) {\n return style;\n }\n\n // Recursively resolve base style\n const baseStyle = resolveStyleWithBaseStyle(\n theme,\n style.baseStyle,\n new Set(visited) // Pass copy to allow different branches\n );\n\n if (!baseStyle) {\n // If baseStyle doesn't exist, just return current style\n return style;\n }\n\n // Merge: base properties first, then override with current style properties\n // Filter out undefined values from current style to preserve base style values\n const mergedStyle = mergeFontAndStyleProperties(\n baseStyle,\n style\n ) as StyleProperties;\n\n // Manually merge properties not covered by mergeFontAndStyleProperties\n // Borders: inherit from baseStyle unless explicitly provided in current style\n if (style.borders === undefined && baseStyle.borders !== undefined) {\n mergedStyle.borders = baseStyle.borders;\n } else if (style.borders !== undefined) {\n mergedStyle.borders = style.borders;\n }\n\n return mergedStyle;\n}\n\nfunction convertAlignment(\n alignment: string\n): (typeof AlignmentType)[keyof typeof AlignmentType] {\n switch (alignment) {\n case 'center':\n return AlignmentType.CENTER;\n case 'right':\n return AlignmentType.RIGHT;\n case 'justify':\n return AlignmentType.JUSTIFIED;\n default:\n return AlignmentType.LEFT;\n }\n}\n\n/**\n * Resolve spacing from new nested format\n */\nfunction resolveSpacing(spacing?: { before?: number; after?: number }): {\n before?: number;\n after?: number;\n} {\n return {\n before: spacing?.before ? pointsToTwips(spacing.before) : undefined,\n after: spacing?.after ? pointsToTwips(spacing.after) : undefined,\n };\n}\n\n/**\n * Convert merged style properties to docx run properties\n */\nfunction convertRunProperties(\n merged: any,\n theme: ThemeConfig,\n defaultColor?: string,\n defaultSize?: number\n): IRunStylePropertiesOptions {\n return {\n font: merged.family || 'Arial',\n size: (merged.size || defaultSize || 11) * 2,\n color: resolveColor(\n merged.color || defaultColor || theme.colors.text,\n theme\n ),\n ...(merged.bold !== undefined && { bold: merged.bold }),\n ...(merged.italic !== undefined && { italic: merged.italic }),\n ...(merged.underline !== undefined &&\n merged.underline && { underline: { type: 'single' } }),\n ...(merged.characterSpacing && {\n characterSpacing:\n merged.characterSpacing.type === 'condensed'\n ? -merged.characterSpacing.value\n : merged.characterSpacing.value,\n }),\n ...(merged.scale && { scale: merged.scale }),\n };\n}\n\n/**\n * Convert merged style properties to docx paragraph properties\n */\nfunction convertParagraphProperties(\n merged: any,\n styleProps?: StyleProperties,\n theme?: ThemeConfig\n): IParagraphStylePropertiesOptions {\n return {\n spacing: {\n ...resolveSpacing(merged.spacing),\n ...convertLineSpacing(merged.lineSpacing),\n },\n alignment: convertAlignment(merged.alignment || 'left'),\n ...(styleProps?.keepNext !== undefined && {\n keepNext: styleProps.keepNext,\n }),\n ...(styleProps?.keepLinesTogether !== undefined && {\n keepLines: styleProps.keepLinesTogether,\n }),\n ...(styleProps?.widowControl !== undefined && {\n widowControl: styleProps.widowControl,\n }),\n ...(styleProps?.outlineLevel !== undefined && {\n outlineLevel: styleProps.outlineLevel,\n }),\n ...(styleProps?.borders &&\n theme && {\n border: convertBorders(styleProps.borders, theme),\n }),\n ...(styleProps?.indent && {\n indent: {\n ...(styleProps.indent.left !== undefined && {\n left: styleProps.indent.left,\n }),\n ...(styleProps.indent.hanging !== undefined && {\n hanging: styleProps.indent.hanging,\n }),\n },\n }),\n } as IParagraphStylePropertiesOptions;\n}\n\n/**\n * Convert theme border definitions to docx paragraph border options\n */\nfunction convertBorders(\n borders: ThemeBorders | undefined,\n theme: ThemeConfig\n):\n | {\n top?: { style: string; size: number; color: string; space?: number };\n bottom?: { style: string; size: number; color: string; space?: number };\n left?: { style: string; size: number; color: string; space?: number };\n right?: { style: string; size: number; color: string; space?: number };\n }\n | undefined {\n if (!borders) return undefined;\n\n const mapSide = (side?: ThemeBorderDefinition) =>\n side\n ? {\n style: side.style,\n size: side.size,\n color: resolveColor(side.color, theme),\n ...(side.space !== undefined ? { space: side.space } : {}),\n }\n : undefined;\n\n const top = mapSide(borders.top);\n const bottom = mapSide(borders.bottom);\n const left = mapSide(borders.left);\n const right = mapSide(borders.right);\n\n const anyDefined = top || bottom || left || right;\n return anyDefined\n ? {\n ...(top && { top }),\n ...(bottom && { bottom }),\n ...(left && { left }),\n ...(right && { right }),\n }\n : undefined;\n}\n\nexport interface WordStyleDefinition {\n id: string;\n name: string;\n basedOn?: string;\n next?: string;\n quickFormat?: boolean;\n run?: IRunStylePropertiesOptions;\n paragraph?: IParagraphStylePropertiesOptions;\n}\n\n/**\n * Creates Word document styles from theme configuration\n * @param themeNameOrObject The theme to use for styling (name string or theme object)\n * @returns IStylesOptions for docx Document\n */\nexport function createWordStyles(\n themeNameOrObject: string | ThemeConfig = 'minimal',\n language?: string\n): IStylesOptions {\n const theme: ThemeConfig =\n typeof themeNameOrObject === 'string'\n ? getTheme(themeNameOrObject) || getTheme('minimal')!\n : themeNameOrObject;\n\n const paragraphStyles: WordStyleDefinition[] = [\n // Normal body text style\n {\n id: 'Normal',\n name: 'Normal',\n quickFormat: true,\n run: (() => {\n const normalStyle =\n resolveStyleWithBaseStyle(theme, 'normal') || theme.styles?.normal;\n const fontProps = resolveFontProperties(theme, normalStyle?.font);\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: normalStyle?.size,\n color: normalStyle?.color,\n bold: normalStyle?.bold,\n italic: normalStyle?.italic,\n underline: normalStyle?.underline,\n characterSpacing: normalStyle?.characterSpacing,\n scale: normalStyle?.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.text);\n })(),\n paragraph: (() => {\n const normalStyle =\n resolveStyleWithBaseStyle(theme, 'normal') || theme.styles?.normal;\n const fontProps = resolveFontProperties(theme, normalStyle?.font);\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: normalStyle?.alignment,\n lineSpacing: normalStyle?.lineSpacing,\n spacing: normalStyle?.spacing,\n });\n\n return convertParagraphProperties(merged, normalStyle, theme);\n })(),\n },\n ];\n\n // Generate heading styles from theme configuration\n for (let i = 1; i <= 6; i++) {\n const headingKey = `heading${i}` as keyof typeof theme.styles;\n const rawHeadingStyle = theme.styles?.[headingKey] as\n | StyleProperties\n | undefined;\n\n if (rawHeadingStyle) {\n const headingStyle =\n resolveStyleWithBaseStyle(theme, headingKey) || rawHeadingStyle;\n paragraphStyles.push({\n id: `Heading${i}`,\n name: `Heading ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n headingStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: headingStyle.size,\n color: headingStyle.color,\n bold: headingStyle.bold,\n italic: headingStyle.italic,\n underline: headingStyle.underline,\n characterSpacing: headingStyle.characterSpacing,\n scale: headingStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.primary, 20);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n headingStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: headingStyle.alignment,\n lineSpacing: headingStyle.lineSpacing,\n spacing: headingStyle.spacing,\n });\n\n return convertParagraphProperties(merged, headingStyle, theme);\n })(),\n });\n } else {\n // Fallback heading style if not defined in theme\n const fontProps = resolveFontProperties(theme, 'heading');\n paragraphStyles.push({\n id: `Heading${i}`,\n name: `Heading ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: {\n font: fontProps.family || 'Arial',\n size: (fontProps.size || 20) * 2,\n color: resolveColor(fontProps.color || theme.colors.primary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n ...(fontProps.underline !== undefined &&\n fontProps.underline && { underline: { type: 'single' } }),\n },\n paragraph: {\n spacing: {\n before: 240 - (i - 1) * 40,\n after: 120 - (i - 1) * 20,\n ...convertLineSpacing(fontProps.lineSpacing),\n },\n alignment: convertAlignment(fontProps.alignment || 'left'),\n },\n });\n }\n }\n\n // Generate display-only heading styles for text components (non-TOC, non-outline)\n for (let i = 1; i <= 6; i++) {\n const headingKey = `heading${i}` as keyof typeof theme.styles;\n const rawHeadingStyle = theme.styles?.[headingKey] as\n | StyleProperties\n | undefined;\n\n if (rawHeadingStyle) {\n const headingStyle =\n resolveStyleWithBaseStyle(theme, `heading${i}`) || rawHeadingStyle;\n\n paragraphStyles.push({\n id: `JTD_HeadingText${i}`,\n name: `Heading Text ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: false,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n headingStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: headingStyle.size,\n color: headingStyle.color,\n bold: headingStyle.bold,\n italic: headingStyle.italic,\n underline: headingStyle.underline,\n characterSpacing: headingStyle.characterSpacing,\n scale: headingStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.primary, 20);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n headingStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: headingStyle.alignment,\n lineSpacing: headingStyle.lineSpacing,\n spacing: headingStyle.spacing,\n });\n\n // Explicitly drop outlineLevel to avoid TOC participation\n return convertParagraphProperties(\n merged,\n { ...(headingStyle as any), outlineLevel: undefined },\n theme\n );\n })(),\n });\n } else {\n // Fallback display heading style mirrors fallback heading visuals\n const fontProps = resolveFontProperties(theme, 'heading');\n paragraphStyles.push({\n id: `JTD_HeadingText${i}`,\n name: `Heading Text ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: false,\n run: {\n font: fontProps.family || 'Arial',\n size: (fontProps.size || 20) * 2,\n color: resolveColor(fontProps.color || theme.colors.primary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n ...(fontProps.underline !== undefined &&\n fontProps.underline && { underline: { type: 'single' } }),\n },\n paragraph: {\n spacing: {\n before: 240 - (i - 1) * 40,\n after: 120 - (i - 1) * 20,\n ...convertLineSpacing(fontProps.lineSpacing),\n },\n alignment: convertAlignment(fontProps.alignment || 'left'),\n },\n });\n }\n }\n\n // Add Title style from theme configuration\n if (theme.styles?.title) {\n const titleStyle =\n resolveStyleWithBaseStyle(theme, 'title') || theme.styles.title;\n paragraphStyles.push({\n id: 'Title',\n name: 'Title',\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n titleStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: titleStyle.size,\n color: titleStyle.color,\n bold: titleStyle.bold,\n italic: titleStyle.italic,\n underline: titleStyle.underline,\n characterSpacing: titleStyle.characterSpacing,\n scale: titleStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.primary, 20);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n titleStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: titleStyle.alignment,\n lineSpacing: titleStyle.lineSpacing,\n spacing: titleStyle.spacing,\n });\n\n return convertParagraphProperties(merged, titleStyle, theme);\n })(),\n });\n } else {\n // Fallback title style if no theme configuration\n const fontProps = resolveFontProperties(theme, 'heading');\n paragraphStyles.push({\n id: 'Title',\n name: 'Title',\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: {\n font: fontProps.family || 'Arial',\n size: (fontProps.size || 20) * 2,\n color: resolveColor(fontProps.color || theme.colors.primary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n ...(fontProps.underline !== undefined &&\n fontProps.underline && { underline: { type: 'single' } }),\n },\n paragraph: {\n spacing: {\n after: 400,\n ...convertLineSpacing(fontProps.lineSpacing),\n },\n alignment: convertAlignment(fontProps.alignment || 'left'),\n },\n });\n }\n\n // Add Subtitle style from theme configuration\n if (theme.styles?.subtitle) {\n const subtitleStyle =\n resolveStyleWithBaseStyle(theme, 'subtitle') || theme.styles.subtitle;\n paragraphStyles.push({\n id: 'Subtitle',\n name: 'Subtitle',\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n subtitleStyle.font || 'body'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: subtitleStyle.size,\n color: subtitleStyle.color,\n bold: subtitleStyle.bold,\n italic: subtitleStyle.italic,\n underline: subtitleStyle.underline,\n characterSpacing: subtitleStyle.characterSpacing,\n scale: subtitleStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.secondary);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n subtitleStyle.font || 'body'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: subtitleStyle.alignment,\n lineSpacing: subtitleStyle.lineSpacing,\n spacing: subtitleStyle.spacing,\n });\n\n return convertParagraphProperties(merged, subtitleStyle, theme);\n })(),\n });\n } else {\n // Fallback subtitle style if no theme configuration\n const fontProps = resolveFontProperties(theme, 'body');\n paragraphStyles.push({\n id: 'Subtitle',\n name: 'Subtitle',\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: {\n font: fontProps.family || 'Arial',\n size: (fontProps.size || 11) * 2,\n color: resolveColor(fontProps.color || theme.colors.secondary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n ...(fontProps.underline !== undefined &&\n fontProps.underline && { underline: { type: 'single' } }),\n },\n paragraph: {\n spacing: {\n after: 600,\n ...convertLineSpacing(fontProps.lineSpacing),\n },\n alignment: convertAlignment(fontProps.alignment || 'left'),\n },\n });\n }\n\n paragraphStyles.push(\n // Header style\n (() => {\n const fontProps = resolveFontProperties(theme, 'body');\n return {\n id: 'Header',\n name: 'Header',\n basedOn: 'Normal',\n next: 'Header',\n quickFormat: false,\n run: {\n font: fontProps.family || 'Arial',\n size: 20, // 10pt (override default)\n color: resolveColor(fontProps.color || theme.colors.secondary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n },\n paragraph: {\n alignment: 'right',\n },\n };\n })(),\n\n // Footer style\n (() => {\n const fontProps = resolveFontProperties(theme, 'body');\n return {\n id: 'Footer',\n name: 'Footer',\n basedOn: 'Normal',\n next: 'Footer',\n quickFormat: false,\n run: {\n font: fontProps.family || 'Arial',\n size: 18, // 9pt (override default)\n color: resolveColor(fontProps.color || theme.colors.secondary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n },\n paragraph: {\n spacing: {\n before: 120,\n },\n alignment: 'center',\n // Note: Borders are applied at the paragraph instance level, not in style definitions\n },\n };\n })()\n );\n\n // Process custom styles (any additional keys in theme.styles beyond predefined ones)\n const predefinedStyleKeys = new Set([\n 'normal',\n 'heading1',\n 'heading2',\n 'heading3',\n 'heading4',\n 'heading5',\n 'heading6',\n 'title',\n 'subtitle',\n ]);\n\n if (theme.styles) {\n for (const [styleKey, styleValue] of Object.entries(theme.styles)) {\n // Skip predefined styles (already processed above)\n if (predefinedStyleKeys.has(styleKey)) {\n continue;\n }\n\n // Skip if styleValue is not defined\n if (!styleValue) {\n continue;\n }\n\n // Generate Word-compatible style ID and name\n // Special-case TOC styles to the canonical Word display name (e.g., 'TOC 1')\n const tocMatch = /^TOC([1-9])$/.exec(styleKey);\n\n // For TOC styles, DO NOT resolve baseStyle inheritance to prevent coupling with Heading styles\n // TOC styles should only use their explicitly defined properties\n const customStyle = tocMatch\n ? styleValue\n : resolveStyleWithBaseStyle(theme, styleKey) || styleValue;\n // Use a namespaced ID for TOC styles to avoid any accidental ID collisions\n const styleId = tocMatch ? `JTD_TOC${tocMatch[1]}` : styleKey;\n const styleName = tocMatch\n ? `TOC ${tocMatch[1]}`\n : styleKey.replace(/([A-Z])/g, ' $1').trim(); // Convert camelCase/PascalCase to Title Case\n\n // Helper: map baseStyle (theme key) to Word style ID\n const mapBaseStyleId = (base?: string) => {\n if (!base) return 'Normal';\n const lower = base.toLowerCase();\n if (lower === 'normal') return 'Normal';\n if (lower === 'title') return 'Title';\n if (lower === 'subtitle') return 'Subtitle';\n const m = lower.match(/^heading([1-6])$/);\n if (m) return `Heading${m[1]}`;\n // Assume custom style ID (already registered with same id)\n return base;\n };\n\n paragraphStyles.push({\n id: styleId,\n name: styleName,\n basedOn: tocMatch\n ? 'Normal'\n : mapBaseStyleId((customStyle as StyleProperties).baseStyle),\n next: customStyle.followingStyle || 'Normal',\n quickFormat: tocMatch\n ? false\n : customStyle.priority !== undefined\n ? true\n : false,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n customStyle.font || 'body'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: customStyle.size,\n color: customStyle.color,\n bold: customStyle.bold,\n italic: customStyle.italic,\n underline: customStyle.underline,\n characterSpacing: customStyle.characterSpacing,\n scale: customStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.text);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n customStyle.font || 'body'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: customStyle.alignment,\n lineSpacing: customStyle.lineSpacing,\n spacing: customStyle.spacing,\n });\n\n // Build base properties using converter\n const baseProps = convertParagraphProperties(\n merged,\n // Don't pass outlineLevel for TOC styles\n tocMatch\n ? { ...customStyle, outlineLevel: undefined }\n : customStyle,\n theme\n );\n\n // Add TOC-specific tab stops if needed\n const tabStops = (customStyle as any).tabStops;\n const defaultTocTabStops = tocMatch\n ? [{ type: 'right', position: 'max', leader: 'none' }]\n : undefined;\n const effectiveTabStops =\n tabStops && tabStops.length > 0 ? tabStops : defaultTocTabStops;\n\n return {\n ...baseProps,\n ...(effectiveTabStops && {\n tabStops: effectiveTabStops.map((ts: any) => ({\n type: ts.type,\n position:\n ts.position === 'max' ? TabStopPosition.MAX * 2 : ts.position,\n ...(ts.leader && { leader: ts.leader }),\n })),\n }),\n } as IParagraphStylePropertiesOptions;\n })(),\n });\n }\n }\n\n // Generate TOC level styles (TOC 1..6) using fixed, sober defaults.\n // These defaults do not depend on theme heading styles.\n for (let i = 1; i <= 6; i++) {\n // Skip if user already provided a custom TOC style via theme.styles (id must be 'TOC1'..'TOC6')\n if (\n theme.styles &&\n Object.prototype.hasOwnProperty.call(theme.styles, `TOC${i}`)\n ) {\n continue;\n }\n\n paragraphStyles.push({\n // Use a namespaced ID but canonical display name\n id: `JTD_TOC${i}`,\n name: `TOC ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: false,\n run: {\n font: 'Arial',\n size: 22, // 11pt\n color: resolveColor(theme.colors.text, theme),\n },\n paragraph: {\n spacing: {\n ...resolveSpacing({ before: 0, after: 6 }), // 0pt before, 6pt after\n },\n alignment: convertAlignment('left'),\n // Increase left indent per level for visual hierarchy\n indent: { left: (i - 1) * 360 }, // 0.25\" per level (360 twips)\n },\n });\n }\n\n return {\n paragraphStyles: paragraphStyles as WordStyleDefinition[], // Cast needed due to docx typing\n // Document-default proofing language (w:docDefaults/w:rPrDefault). Runs that\n // don't set their own w:lang inherit this, so Word spell-checks the whole\n // document in the requested language unless a component overrides it.\n ...(language && {\n default: {\n document: {\n run: {\n language: { value: language },\n },\n },\n },\n }),\n };\n}\n\n/**\n * Maps section levels to Word style IDs\n */\nexport function getStyleIdForLevel(level: number): string {\n const styleMap: { [key: number]: string } = {\n 1: 'Heading1',\n 2: 'Heading2',\n 3: 'Heading3',\n 4: 'Heading4',\n 5: 'Heading5',\n 6: 'Heading6',\n };\n return styleMap[level] || 'Heading1';\n}\n","/**\n * Cache Module Exports\n * Re-exports format-agnostic cache from shared + local key-generator\n */\n\nexport * from '@json-to-office/shared/cache';\nexport { CacheKeyGenerator } from './key-generator';\n","/**\n * Cache Key Generator\n * Generates deterministic cache keys for components\n */\n\nimport { createHash } from 'crypto';\nimport { ComponentDefinition, RenderContext } from '../types';\nimport { CacheKeyOptions } from '@json-to-office/shared/cache';\n\n/**\n * Cache key generator with deterministic hashing\n */\nexport class CacheKeyGenerator {\n private readonly version: string;\n\n constructor(version: string = '1.0') {\n this.version = version;\n }\n\n /**\n * Generate cache key for a component\n */\n generateKey(\n component: ComponentDefinition,\n context: RenderContext,\n options: CacheKeyOptions = {}\n ): string {\n const parts: string[] = [\n this.version,\n component.name,\n this.hashProps(component.props),\n ];\n\n if (options.includeTheme !== false) {\n parts.push(context.theme.name);\n }\n\n if (options.includeContext) {\n parts.push(this.hashContext(context));\n }\n\n if (options.additionalKeys) {\n parts.push(...options.additionalKeys);\n }\n\n if (options.version) {\n parts.push(options.version);\n }\n\n return parts.join(':');\n }\n\n /**\n * Hash component props\n */\n hashProps(props: any): string {\n if (!props) return 'null';\n\n // Sort keys for consistent hashing\n const normalized = this.normalizeObject(props);\n const json = JSON.stringify(normalized);\n\n return this.hash(json);\n }\n\n /**\n * Hash render context\n */\n private hashContext(context: RenderContext): string {\n // Only hash relevant context properties\n const relevant = {\n theme: context.theme.name,\n document: context.document,\n // Exclude runtime properties like sectionIndex, componentIndex\n };\n\n return this.hash(JSON.stringify(relevant));\n }\n\n /**\n * Normalize object for consistent hashing\n */\n private normalizeObject(obj: any): any {\n if (obj === null || obj === undefined) return obj;\n\n if (Array.isArray(obj)) {\n return obj.map((item) => this.normalizeObject(item));\n }\n\n if (obj instanceof Date) {\n return obj.toISOString();\n }\n\n if (typeof obj === 'object') {\n const sorted: any = {};\n const keys = Object.keys(obj).sort();\n\n for (const key of keys) {\n sorted[key] = this.normalizeObject(obj[key]);\n }\n\n return sorted;\n }\n\n return obj;\n }\n\n /**\n * Create hash\n */\n private hash(input: string): string {\n return createHash('sha256').update(input).digest('hex').substring(0, 16); // Use first 16 chars for shorter keys\n }\n}\n","/**\n * Revision (tracked-change) rendering utilities\n *\n * Turns `revision.segments` from the JSON definition into native Word\n * revision runs (w:ins / w:del) via docx.js InsertedTextRun / DeletedTextRun.\n */\n\nimport { TextRun, InsertedTextRun, DeletedTextRun } from 'docx';\nimport type { IRunOptions, ParagraphChild } from 'docx';\nimport type { Revision } from '@json-to-office/shared-docx';\nimport { normalizeUnicodeText } from './unicode';\nimport { processTextWithPlaceholders } from './placeholderProcessor';\nimport type { TextStyle } from './textParser';\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nexport const DEFAULT_REVISION_AUTHOR = 'json-to-office';\n// Deterministic fallback so identical inputs produce byte-identical XML\nexport const DEFAULT_REVISION_DATE = '1970-01-01T00:00:00Z';\n\n/**\n * OOXML requires a numeric id on every w:ins / w:del element, unique within\n * one document. Async-local state gives each render its own deterministic\n * counter without collisions when documents render concurrently.\n */\nclass RevisionIdRegistry {\n private fallbackCounter = 0;\n private readonly scopes = new AsyncLocalStorage<{ counter: number }>();\n\n runScoped<T>(callback: () => T): T {\n return this.scopes.run({ counter: 0 }, callback);\n }\n\n next(): number {\n const state = this.scopes.getStore();\n if (state) {\n state.counter += 1;\n return state.counter;\n }\n this.fallbackCounter += 1;\n return this.fallbackCounter;\n }\n\n /** Test-only: deterministic ids for snapshot assertions. */\n clear(): void {\n const state = this.scopes.getStore();\n if (state) {\n state.counter = 0;\n } else {\n this.fallbackCounter = 0;\n }\n }\n}\n\nexport const globalRevisionIdRegistry = new RevisionIdRegistry();\n\nexport type RevisionRun = TextRun | InsertedTextRun | DeletedTextRun;\n\nconst PLACEHOLDER_PATTERN = /\\{[^}]+\\}/;\n\ntype RevisionBaseStyle = Omit<IRunOptions, 'text' | 'children'>;\n\n/**\n * Build the runs for one segment, splitting on '\\n' so line breaks render\n * as <w:br/> (mirroring createTextRunsWithNewlines on the normal path).\n */\nfunction segmentRuns(\n text: string,\n makeRun: (options: IRunOptions) => RevisionRun\n): RevisionRun[] {\n const lines = text.split('\\n');\n return lines.map((line, index) =>\n makeRun(index === 0 ? { text: line } : { text: line, break: 1 })\n );\n}\n\n/**\n * Build paragraph children from revision segments.\n *\n * Segment text is rendered literally (no markdown parsing): a `**` opened in\n * one segment could close in another, so decorator parsing cannot work\n * per-segment. The diff engine strips markdown before diffing for this\n * reason. Placeholders ({DATE}, {PAGE}, ...) are resolved for unchanged\n * segments; inside inserted/deleted text they render literally (the diff\n * summary reports those).\n */\nexport function createRevisionRuns(\n revision: Revision,\n baseStyle: RevisionBaseStyle\n): ParagraphChild[] {\n const author = revision.author || DEFAULT_REVISION_AUTHOR;\n const date = revision.date || DEFAULT_REVISION_DATE;\n\n const runs: ParagraphChild[] = [];\n for (const segment of revision.segments) {\n if (!segment.text) continue;\n const text = normalizeUnicodeText(segment.text);\n\n if (segment.type === 'insert') {\n runs.push(\n ...segmentRuns(\n text,\n (options) =>\n new InsertedTextRun({\n ...options,\n ...baseStyle,\n id: globalRevisionIdRegistry.next(),\n author,\n date,\n })\n )\n );\n } else if (segment.type === 'delete') {\n runs.push(\n ...segmentRuns(\n text,\n (options) =>\n new DeletedTextRun({\n ...options,\n ...baseStyle,\n id: globalRevisionIdRegistry.next(),\n author,\n date,\n })\n )\n );\n } else if (PLACEHOLDER_PATTERN.test(text)) {\n // Unchanged text keeps full placeholder fidelity ({DATE}, {PAGE}, ...)\n runs.push(\n ...processTextWithPlaceholders(text, baseStyle as TextStyle, {})\n );\n } else {\n runs.push(\n ...segmentRuns(\n text,\n (options) => new TextRun({ ...options, ...baseStyle })\n )\n );\n }\n }\n return runs;\n}\n\n/**\n * True when a component carries revision data anywhere in its subtree\n * (own props, list items, or any descendant), meaning its render output\n * embeds document-scoped revision ids and must not be served from the\n * cross-document component cache.\n */\nexport function componentHasRevision(component: {\n props?: unknown;\n children?: unknown[];\n}): boolean {\n const props = component.props as Record<string, unknown> | undefined;\n if (props) {\n if (props.revision) return true;\n const items = props.items;\n if (Array.isArray(items)) {\n if (\n items.some(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n 'revision' in item &&\n (item as { revision?: unknown }).revision\n )\n ) {\n return true;\n }\n }\n }\n const children = component.children;\n if (Array.isArray(children)) {\n return children.some(\n (child) =>\n typeof child === 'object' &&\n child !== null &&\n componentHasRevision(child as { props?: unknown; children?: unknown[] })\n );\n }\n return false;\n}\n","/**\n * Normalize text to NFC so composed accented characters are preserved\n * consistently across DOCX renderers (including LibreOffice).\n */\nexport function normalizeUnicodeText(text: string | null | undefined): string {\n return (text ?? '').normalize('NFC');\n}\n","/**\n * Placeholder Processing System\n * Handles dynamic content replacement in text with support for rich text formatting\n */\n\nimport {\n TextRun,\n PageNumber,\n ExternalHyperlink,\n InternalHyperlink,\n} from 'docx';\nimport {\n parseTextWithDecorators,\n buildRunCommonProps,\n buildTextRuns,\n TextStyle,\n} from './textParser';\nimport { normalizeUnicodeText } from './unicode';\nimport { getGenerationDate } from './generationContext';\n\n// Type alias for elements that can appear in a paragraph\nexport type PlaceholderChild = TextRun | ExternalHyperlink | InternalHyperlink;\n\n/**\n * Placeholder handler function type\n */\nexport type PlaceholderHandler = (\n _context?: PlaceholderContext\n) => PlaceholderChild | PlaceholderChild[] | string;\n\n/**\n * Context passed to placeholder handlers\n */\nexport interface PlaceholderContext {\n style?: TextStyle;\n date?: Date;\n [key: string]: unknown;\n}\n\nfunction styledPlaceholderText(\n text: string,\n context?: PlaceholderContext\n): TextRun {\n return new TextRun({\n text,\n font: context?.style?.font,\n size: context?.style?.size,\n color: context?.style?.color,\n bold: context?.style?.bold,\n italics: context?.style?.italics,\n underline: context?.style?.underline,\n language: context?.style?.language,\n noProof: context?.style?.noProof,\n });\n}\n\nfunction placeholderDate(context?: PlaceholderContext): Date {\n return context?.date ?? getGenerationDate();\n}\n\nfunction isoDate(date: Date): string {\n return date.toISOString().slice(0, 10);\n}\n\nfunction isoDateTime(date: Date): string {\n return date\n .toISOString()\n .replace('T', ' ')\n .replace(/\\.\\d{3}Z$/, 'Z');\n}\n\n/**\n * Placeholder registry for managing dynamic content\n */\nexport class PlaceholderRegistry {\n private static handlers = new Map<string, PlaceholderHandler>();\n\n /**\n * Register a placeholder handler\n */\n static register(name: string, handler: PlaceholderHandler): void {\n this.handlers.set(name.toUpperCase(), handler);\n }\n\n /**\n * Get a placeholder handler\n */\n static get(name: string): PlaceholderHandler | undefined {\n return this.handlers.get(name.toUpperCase());\n }\n\n /**\n * Check if a placeholder is registered\n */\n static has(name: string): boolean {\n return this.handlers.has(name.toUpperCase());\n }\n\n /**\n * Get all registered placeholder names\n */\n static getRegisteredNames(): string[] {\n return Array.from(this.handlers.keys());\n }\n\n /**\n * Clear all registered placeholders\n */\n static clear(): void {\n this.handlers.clear();\n }\n}\n\n/**\n * Process text containing placeholders and return array of paragraph children\n */\nexport function processPlaceholders(\n text: string,\n baseStyle: TextStyle = {},\n context: PlaceholderContext = {}\n): PlaceholderChild[] {\n const normalizedText = normalizeUnicodeText(text);\n const placeholderRegex = /\\{([^}]+)\\}/g;\n const result: PlaceholderChild[] = [];\n let lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = placeholderRegex.exec(normalizedText)) !== null) {\n const beforeText = normalizedText.substring(lastIndex, match.index);\n const placeholderName = match[1];\n\n // Add text before placeholder\n if (beforeText) {\n result.push(...parseTextWithDecorators(beforeText, baseStyle));\n }\n\n // Process placeholder\n const handler = PlaceholderRegistry.get(placeholderName);\n if (handler) {\n const placeholderResult = handler({ ...context, style: baseStyle });\n\n if (Array.isArray(placeholderResult)) {\n result.push(...placeholderResult);\n } else if (typeof placeholderResult === 'string') {\n result.push(...parseTextWithDecorators(placeholderResult, baseStyle));\n } else {\n result.push(placeholderResult);\n }\n } else {\n // Unknown placeholder - keep as text\n result.push(...parseTextWithDecorators(match[0], baseStyle));\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text\n if (lastIndex < normalizedText.length) {\n const remainingText = normalizedText.substring(lastIndex);\n result.push(...parseTextWithDecorators(remainingText, baseStyle));\n }\n\n // If no placeholders found, process as normal text\n if (result.length === 0) {\n result.push(...parseTextWithDecorators(normalizedText, baseStyle));\n }\n\n return result;\n}\n\n/**\n * Process text with both decorators and placeholders\n */\nexport function processTextWithPlaceholders(\n text: string,\n baseStyle: TextStyle = {},\n context: PlaceholderContext = {},\n noProofWords?: string[]\n): PlaceholderChild[] {\n const normalizedText = normalizeUnicodeText(text);\n // Use a more sophisticated approach to handle both decorators and placeholders\n // This regex captures both markdown decorators and placeholders\n const combinedRegex =\n /(\\*\\*\\*|___)([\\s\\S]*?)\\1|(\\*\\*|__)([\\s\\S]*?)\\3|(\\*|_)([\\s\\S]*?)\\5|\\{([^}]+)\\}/g;\n const result: PlaceholderChild[] = [];\n let lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = combinedRegex.exec(normalizedText)) !== null) {\n // Add any text before the match as plain text\n if (match.index > lastIndex) {\n const beforeText = normalizedText.substring(lastIndex, match.index);\n if (beforeText) {\n result.push(\n ...createTextRunsWithNewlines(beforeText, baseStyle, noProofWords)\n );\n }\n }\n\n // Check if this is a placeholder (group 7)\n if (match[7]) {\n const placeholderName = match[7];\n const handler = PlaceholderRegistry.get(placeholderName);\n if (handler) {\n const placeholderResult = handler({ ...context, style: baseStyle });\n\n if (Array.isArray(placeholderResult)) {\n result.push(...placeholderResult);\n } else if (typeof placeholderResult === 'string') {\n result.push(\n ...createTextRunsWithNewlines(\n placeholderResult,\n baseStyle,\n noProofWords\n )\n );\n } else {\n result.push(placeholderResult);\n }\n } else {\n // Unknown placeholder - keep as text\n result.push(\n ...createTextRunsWithNewlines(match[0], baseStyle, noProofWords)\n );\n }\n } else {\n // This is a decorator match - determine the style\n let decoratedText: string;\n let bold = baseStyle.bold || false;\n let italics = baseStyle.italics || false;\n\n if (match[1] === '***' || match[1] === '___') {\n // Bold + Italic\n decoratedText = match[2];\n bold = true;\n italics = true;\n } else if (match[3] === '**' || match[3] === '__') {\n // Bold\n decoratedText = match[4];\n bold = true;\n } else if (match[5] === '*' || match[5] === '_') {\n // Italic\n decoratedText = match[6];\n italics = true;\n } else {\n // This shouldn't happen with our regex, but just in case\n decoratedText = match[0];\n }\n\n // Recursively process the decorated text (it might contain placeholders)\n const decoratedTextRuns = processTextWithPlaceholders(\n decoratedText,\n {\n ...baseStyle,\n bold,\n italics,\n },\n context\n );\n result.push(...decoratedTextRuns);\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add any remaining text after the last match\n if (lastIndex < normalizedText.length) {\n const remainingText = normalizedText.substring(lastIndex);\n if (remainingText) {\n result.push(\n ...createTextRunsWithNewlines(remainingText, baseStyle, noProofWords)\n );\n }\n }\n\n // If no matches were found, return text runs with newlines\n if (result.length === 0 && normalizedText) {\n result.push(\n ...createTextRunsWithNewlines(normalizedText, baseStyle, noProofWords)\n );\n }\n\n return result;\n}\n\n/**\n * Helper function to create TextRuns with newlines from text\n */\nfunction createTextRunsWithNewlines(\n text: string,\n baseStyle: TextStyle,\n noProofWords?: string[]\n): TextRun[] {\n return buildTextRuns(text, buildRunCommonProps(baseStyle), {\n noProof: baseStyle.noProof,\n noProofWords,\n });\n}\n\n/**\n * Initialize built-in placeholders\n */\nexport function initializeBuiltinPlaceholders(): void {\n // PAGE placeholder\n PlaceholderRegistry.register('PAGE', (context) => {\n return new TextRun({\n children: [PageNumber.CURRENT],\n font: context?.style?.font,\n size: context?.style?.size,\n color: context?.style?.color,\n bold: context?.style?.bold,\n italics: context?.style?.italics,\n underline: context?.style?.underline,\n });\n });\n\n // TOTAL_PAGES placeholder\n PlaceholderRegistry.register('TOTAL_PAGES', (context) => {\n return new TextRun({\n children: [PageNumber.TOTAL_PAGES],\n font: context?.style?.font,\n size: context?.style?.size,\n color: context?.style?.color,\n bold: context?.style?.bold,\n italics: context?.style?.italics,\n underline: context?.style?.underline,\n });\n });\n\n // DATE placeholder\n PlaceholderRegistry.register('DATE', (context) =>\n styledPlaceholderText(isoDate(placeholderDate(context)), context)\n );\n\n // DATETIME placeholder\n PlaceholderRegistry.register('DATETIME', (context) =>\n styledPlaceholderText(isoDateTime(placeholderDate(context)), context)\n );\n\n // YEAR placeholder\n PlaceholderRegistry.register('YEAR', (context) =>\n styledPlaceholderText(\n String(placeholderDate(context).getUTCFullYear()),\n context\n )\n );\n}\n\n// Initialize built-in placeholders\ninitializeBuiltinPlaceholders();\n","import { TextRun, ExternalHyperlink, InternalHyperlink, Tab } from 'docx';\nimport {\n processTextWithPlaceholders,\n type PlaceholderChild,\n type PlaceholderContext,\n} from './placeholderProcessor';\nimport { normalizeUnicodeText } from './unicode';\n\nexport interface TextStyle {\n font?: string;\n size?: number;\n color?: string;\n bold?: boolean;\n italics?: boolean;\n underline?: {\n type?:\n | 'single'\n | 'double'\n | 'thick'\n | 'dotted'\n | 'dash'\n | 'dotDash'\n | 'dotDotDash'\n | 'wave'\n | 'none'\n | 'words'\n | 'dottedHeavy'\n | 'dashedHeavy'\n | 'dashLong'\n | 'dashLongHeavy'\n | 'dashDotHeavy'\n | 'dashDotDotHeavy'\n | 'wavyHeavy'\n | 'wavyDouble';\n color?: string;\n }; // docx library expects an object or undefined, not boolean\n // Character width scaling in percent (w:w). 100 is normal.\n scale?: number;\n // Letter tracking (w:spacing) in twentieths of a point (signed).\n characterSpacing?: number;\n // Proofing language (BCP-47) for the run, e.g. { value: 'fr-FR' }\n language?: {\n value?: string;\n eastAsia?: string;\n bidirectional?: string;\n };\n // Disable spell/grammar checking for the run\n noProof?: boolean;\n}\n\nexport interface TextDecoratorOptions {\n boldColor?: string;\n placeholderContext?: PlaceholderContext;\n enableHyperlinks?: boolean;\n /**\n * \"Known words\" allowlist: each whole-word, case-insensitive occurrence is\n * emitted as its own no-proof run so Word never flags it, while surrounding\n * text stays spell-checked.\n */\n noProofWords?: string[];\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Build a matcher for the known-words allowlist, or null when there's nothing\n * to match. Matches each word as a whole token (no letter/number directly\n * adjacent on either side) so \"Wiseair\" doesn't match inside \"Wiseairy\", while\n * internal punctuation like \"json-to-office\" is matched literally.\n */\nexport function buildNoProofWordsRegex(noProofWords?: string[]): RegExp | null {\n const words = (noProofWords || []).filter((w) => w && w.trim().length > 0);\n if (words.length === 0) return null;\n // Longest first so alternation prefers the most specific match.\n const escaped = words\n .slice()\n .sort((a, b) => b.length - a.length)\n .map(escapeRegExp);\n return new RegExp(\n `(?<![\\\\p{L}\\\\p{N}])(?:${escaped.join('|')})(?![\\\\p{L}\\\\p{N}])`,\n 'giu'\n );\n}\n\n/**\n * Split a plain string into TextRuns, marking every known-word occurrence as a\n * no-proof run via `makeRun`. When there are no known words, returns a single\n * run for the whole text.\n */\nexport function splitByNoProofWords(\n text: string,\n makeRun: (segment: string, noProof: boolean) => TextRun,\n noProofWords?: string[]\n): TextRun[] {\n const regex = buildNoProofWordsRegex(noProofWords);\n if (!regex || !text) return [makeRun(text, false)];\n\n const runs: TextRun[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n runs.push(makeRun(text.slice(lastIndex, match.index), false));\n }\n runs.push(makeRun(match[0], true));\n lastIndex = match.index + match[0].length;\n // Guard against zero-length matches (shouldn't happen, but be safe).\n if (regex.lastIndex === match.index) regex.lastIndex++;\n }\n if (lastIndex < text.length) {\n runs.push(makeRun(text.slice(lastIndex), false));\n }\n return runs.length > 0 ? runs : [makeRun(text, false)];\n}\n\n/**\n * Parses text with inline markdown-style decorators, placeholders, and newlines, returning an array of TextRun objects\n * Supports:\n * - **bold** or __bold__\n * - *italic* or _italic_\n * - ***bold italic*** or ___bold italic___\n * - \\n for line breaks\n * - {PLACEHOLDER} for dynamic content\n * - [link text](url) for hyperlinks (when enableHyperlinks is true)\n *\n * @param text The text to parse\n * @param baseStyle The base style to apply to all text runs\n * @param options Additional options for text decoration\n * @returns Array of TextRun and hyperlink objects with appropriate styling\n */\nexport function parseTextWithDecorators(\n text: string,\n baseStyle: TextStyle = {},\n options: TextDecoratorOptions = {}\n): PlaceholderChild[] {\n // Guard against undefined or null text\n if (!text) {\n return [new TextRun({ text: '', ...baseStyle })];\n }\n const normalizedText = normalizeUnicodeText(text);\n\n // Check if text contains placeholders\n const hasPlaceholders = /\\{[^}]+\\}/.test(normalizedText);\n\n if (hasPlaceholders) {\n // Use new placeholder processor that handles both decorators and placeholders\n return processTextWithPlaceholders(\n normalizedText,\n baseStyle,\n options.placeholderContext || {},\n options.noProofWords\n );\n }\n\n // Process hyperlinks first if enabled\n if (options.enableHyperlinks) {\n return parseTextWithHyperlinks(normalizedText, baseStyle, options);\n }\n\n // Original decorator-only processing\n const runs: PlaceholderChild[] = [];\n\n // Process decorators on the entire text first (including newlines)\n const decoratorRegex =\n /(\\*\\*\\*|___)([\\s\\S]*?)\\1|(\\*\\*|__)([\\s\\S]*?)\\3|(\\*|_)([\\s\\S]*?)\\5/g;\n\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = decoratorRegex.exec(normalizedText)) !== null) {\n // Add any text before the match as plain text (handle newlines)\n if (match.index > lastIndex) {\n const plainText = normalizedText.substring(lastIndex, match.index);\n if (plainText) {\n runs.push(...createTextRunsWithNewlines(plainText, baseStyle, options));\n }\n }\n\n // Determine the style based on the decorator\n let decoratedText: string;\n let bold = baseStyle.bold || false;\n let italics = baseStyle.italics || false;\n\n if (match[1] === '***' || match[1] === '___') {\n // Bold + Italic\n decoratedText = match[2];\n bold = true;\n italics = true;\n } else if (match[3] === '**' || match[3] === '__') {\n // Bold\n decoratedText = match[4];\n bold = true;\n } else if (match[5] === '*' || match[5] === '_') {\n // Italic\n decoratedText = match[6];\n italics = true;\n } else {\n // This shouldn't happen with our regex, but just in case\n decoratedText = match[0];\n }\n\n // Create decorated text runs with newlines\n const decoratedRuns = createTextRunsWithNewlines(\n decoratedText,\n baseStyle,\n options,\n {\n bold,\n italics,\n }\n );\n runs.push(...decoratedRuns);\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add any remaining text after the last match\n if (lastIndex < normalizedText.length) {\n const remainingText = normalizedText.substring(lastIndex);\n if (remainingText) {\n runs.push(\n ...createTextRunsWithNewlines(remainingText, baseStyle, options)\n );\n }\n }\n\n // If no decorators were found, return text runs with newlines\n if (runs.length === 0 && normalizedText) {\n runs.push(\n ...createTextRunsWithNewlines(normalizedText, baseStyle, options)\n );\n }\n\n return runs;\n}\n\n/**\n * Run-level properties shared by every run produced for a piece of text.\n * Single assembly point for both the plain-text and placeholder paths — a\n * prop forwarded here reaches both, so the two cannot drift (issue #137).\n */\nexport function buildRunCommonProps(\n baseStyle: TextStyle,\n overrides?: { bold?: boolean; italics?: boolean; boldColor?: string }\n) {\n const bold = overrides?.bold ?? baseStyle.bold;\n const italics = overrides?.italics ?? baseStyle.italics;\n return {\n ...(baseStyle.font && { font: baseStyle.font }),\n ...(baseStyle.size && { size: baseStyle.size }),\n ...(baseStyle.color && {\n color:\n bold && overrides?.boldColor ? overrides.boldColor : baseStyle.color,\n }),\n ...(bold !== undefined && { bold }),\n ...(italics !== undefined && { italics }),\n ...(baseStyle.underline && { underline: baseStyle.underline }),\n ...(baseStyle.scale && { scale: baseStyle.scale }),\n ...(baseStyle.characterSpacing && {\n characterSpacing: baseStyle.characterSpacing,\n }),\n ...(baseStyle.language && { language: baseStyle.language }),\n };\n}\n\n/**\n * Build the runs for a single line of text: split on `\\t` into real\n * `<w:tab/>` runs (a tab char inside <w:t> would be silently dropped by\n * Word, and paragraph tabStops only apply to real tab runs), emit no-proof\n * word runs, and attach the line break to the first emitted run only.\n */\nfunction buildLineRuns(\n line: string,\n commonProps: ReturnType<typeof buildRunCommonProps>,\n opts: { needsLineBreak: boolean; noProof?: boolean; noProofWords?: string[] }\n): TextRun[] {\n const { needsLineBreak, noProof } = opts;\n // When the whole run is already no-proof, there's nothing to single out,\n // so skip word splitting and emit one run for the line.\n const wholeRunNoProof = noProof === true;\n const wordsForLine = wholeRunNoProof ? undefined : opts.noProofWords;\n\n // The line break belongs only on the first run of the line.\n let firstSegment = true;\n const lineRuns: TextRun[] = [];\n const tabSegments = line.split('\\t');\n tabSegments.forEach((tabSegment, tabIndex) => {\n if (tabIndex > 0) {\n lineRuns.push(\n new TextRun({\n children: [new Tab()],\n ...commonProps,\n ...(needsLineBreak && firstSegment && { break: 1 }),\n })\n );\n firstSegment = false;\n }\n if (!tabSegment && tabSegments.length > 1) return;\n lineRuns.push(\n ...splitByNoProofWords(\n tabSegment,\n (segment, matched) => {\n const run = new TextRun({\n text: segment,\n ...commonProps,\n ...((matched || noProof !== undefined) && {\n noProof: matched || wholeRunNoProof,\n }),\n ...(needsLineBreak && firstSegment && { break: 1 }),\n });\n firstSegment = false;\n return run;\n },\n wordsForLine\n )\n );\n });\n return lineRuns;\n}\n\n/**\n * Turn multi-line text into TextRuns: `\\n` becomes a run break, `\\t` a real\n * tab run, no-proof words their own runs. Shared by the plain-text path\n * (textParser) and the placeholder path (placeholderProcessor) so run-level\n * properties cannot diverge between them.\n */\nexport function buildTextRuns(\n text: string,\n commonProps: ReturnType<typeof buildRunCommonProps>,\n opts: { noProof?: boolean; noProofWords?: string[] } = {}\n): TextRun[] {\n const runs: TextRun[] = [];\n const lines = text.split('\\n');\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n const needsLineBreak = lineIndex > 0;\n\n // Create runs even for empty lines if they need a break\n if (line || needsLineBreak) {\n runs.push(\n ...buildLineRuns(line, commonProps, { needsLineBreak, ...opts })\n );\n }\n }\n\n return runs;\n}\n\n/**\n * Helper function to create TextRuns with newlines from text\n */\nfunction createTextRunsWithNewlines(\n text: string,\n baseStyle: TextStyle,\n options: TextDecoratorOptions,\n overrideStyle?: { bold?: boolean; italics?: boolean }\n): TextRun[] {\n return buildTextRuns(\n text,\n buildRunCommonProps(baseStyle, {\n bold: overrideStyle?.bold,\n italics: overrideStyle?.italics,\n boldColor: options.boldColor,\n }),\n { noProof: baseStyle.noProof, noProofWords: options.noProofWords }\n );\n}\n\n/**\n * Parse text with hyperlinks and decorators\n * Supports markdown-style links: [link text](url)\n */\nfunction parseTextWithHyperlinks(\n text: string,\n baseStyle: TextStyle = {},\n options: TextDecoratorOptions = {}\n): PlaceholderChild[] {\n const normalizedText = normalizeUnicodeText(text);\n const runs: PlaceholderChild[] = [];\n\n // Regex to match markdown-style links: [text](url)\n // This regex handles nested brackets in the link text\n const hyperlinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = hyperlinkRegex.exec(normalizedText)) !== null) {\n // Add any text before the hyperlink\n if (match.index > lastIndex) {\n const plainText = normalizedText.substring(lastIndex, match.index);\n if (plainText) {\n // Recursively parse the plain text for decorators\n const plainRuns = parseTextWithDecorators(plainText, baseStyle, {\n ...options,\n enableHyperlinks: false, // Disable hyperlinks in recursive call\n });\n runs.push(...plainRuns);\n }\n }\n\n const linkText = match[1];\n const linkUrl = match[2];\n\n // Determine if this is an internal or external link\n const isInternal = linkUrl.startsWith('#');\n\n // Parse the link text for decorators (bold, italic, etc.)\n const linkTextRuns = parseTextWithDecorators(linkText, baseStyle, {\n ...options,\n enableHyperlinks: false, // Disable hyperlinks in recursive call\n });\n\n // Create the appropriate hyperlink type\n if (isInternal) {\n // Internal link (bookmark)\n const bookmarkId = linkUrl.substring(1); // Remove the # prefix\n runs.push(\n new InternalHyperlink({\n children: linkTextRuns as TextRun[], // Cast needed for docx types\n anchor: bookmarkId,\n })\n );\n } else {\n // External link\n runs.push(\n new ExternalHyperlink({\n children: linkTextRuns as TextRun[], // Cast needed for docx types\n link: linkUrl,\n })\n );\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add any remaining text after the last hyperlink\n if (lastIndex < normalizedText.length) {\n const remainingText = normalizedText.substring(lastIndex);\n if (remainingText) {\n const remainingRuns = parseTextWithDecorators(remainingText, baseStyle, {\n ...options,\n enableHyperlinks: false, // Disable hyperlinks in recursive call\n });\n runs.push(...remainingRuns);\n }\n }\n\n // If no hyperlinks were found, fall back to regular decorator parsing\n if (runs.length === 0 && normalizedText) {\n return parseTextWithDecorators(normalizedText, baseStyle, {\n ...options,\n enableHyperlinks: false,\n });\n }\n\n return runs;\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\nconst generationDateStorage = new AsyncLocalStorage<Date>();\n\n/** Scope render-time values without leaking them across concurrent documents. */\nexport function runWithGenerationDate<T>(date: Date, callback: () => T): T {\n return generationDateStorage.run(date, callback);\n}\n\n/** Current document date, falling back to the wall clock outside generation. */\nexport function getGenerationDate(): Date {\n return generationDateStorage.getStore() ?? new Date();\n}\n","/**\n * Cached component rendering system\n * Provides caching layer for component rendering operations\n */\n\nimport { Paragraph, Table, TableOfContents, Textbox } from 'docx';\nimport { ComponentDefinition, RenderContext } from '../types';\nimport { ThemeConfig } from '../styles';\nimport {\n MemoryCache,\n CacheKeyGenerator,\n CacheConfiguration,\n CachedComponent,\n} from '../cache';\nimport { renderComponent } from './render';\nimport { componentHasRevision } from '../utils/revisionUtils';\nimport { getGenerationDate } from '../utils/generationContext';\nimport { createHash } from 'crypto';\n\n// Global component cache instance\nlet componentCache: MemoryCache | null = null;\nlet cacheKeyGen: CacheKeyGenerator | null = null;\n\n/**\n * Create a hash of the theme configuration for cache key generation\n * This ensures cache invalidation when theme changes\n */\nfunction createThemeHash(theme: ThemeConfig): string {\n // Serialize the theme object to JSON and create a hash\n const themeString = JSON.stringify(theme);\n return createHash('sha256').update(themeString).digest('hex').substring(0, 8);\n}\n\n/**\n * Initialize the component cache\n */\nexport function initializeComponentCache(cache?: MemoryCache): void {\n if (cache) {\n componentCache = cache;\n } else if (!componentCache) {\n // Create a default cache if none provided\n const config: CacheConfiguration = {\n enabled: true,\n evictionPolicy: 'lru',\n memory: {\n enabled: true,\n maxSize: 100, // 100MB for components\n maxEntries: 1000,\n defaultTTL: 3600, // 1 hour\n cleanupInterval: 300, // 5 minutes\n },\n performance: {\n trackMetrics: true,\n metricsSampleRate: 1.0,\n enableWarming: false,\n parallelProcessing: true,\n },\n };\n componentCache = new MemoryCache(config);\n }\n\n if (!cacheKeyGen) {\n cacheKeyGen = new CacheKeyGenerator();\n }\n}\n\n/**\n * Get the component cache instance\n */\nexport function getComponentCache(): MemoryCache | null {\n return componentCache;\n}\n\n/**\n * Clear the component cache\n */\nexport async function clearComponentCache(): Promise<void> {\n if (componentCache) {\n await componentCache.clear();\n }\n}\n\n/**\n * Render a component with caching\n */\nexport async function renderComponentWithCache(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext,\n bypassCache = false\n): Promise<(Paragraph | Table | TableOfContents | Textbox)[]> {\n // Certain components depend on dynamic runtime context and must not be cached.\n // - 'toc' depends on section bookmark IDs generated at render time; caching\n // can produce stale references to non-existent bookmarks on re-render.\n // - 'section' generates document-scoped bookmarks internally; caching would\n // duplicate bookmark IDs across sections.\n // - revision-bearing components embed document-scoped w:ins/w:del ids from\n // a per-render counter; caching would leak ids across documents.\n // - 'visual' rasterizes via the injected services.pptx (an in-process render\n // fn or an HTTP serverUrl) which is NOT part of the cache key; caching by\n // props alone could serve a stale image when the rasterizer differs across\n // renders. The rasterizer keeps its own content-addressed disk cache, so an\n // identical visual is still cheap to re-resolve.\n const forceBypassForType =\n component.name === 'toc' ||\n component.name === 'section' ||\n component.name === 'visual' ||\n component.name === 'heading' ||\n // Both explicit lists and markdown-list paragraphs register numbering in\n // the current document scope. Cached paragraphs can otherwise reference\n // definitions that only existed in a previous render.\n component.name === 'list' ||\n component.name === 'paragraph' ||\n 'id' in component ||\n componentHasRevision(component);\n\n // Initialize cache if needed\n if (!componentCache) {\n initializeComponentCache();\n }\n\n // If cache is disabled or bypassed, render directly\n if (\n !componentCache ||\n bypassCache ||\n forceBypassForType ||\n !componentCache.getConfig().enabled\n ) {\n return renderComponent(component, theme, themeName, context);\n }\n\n // Generate cache key for this component\n // Use theme hash instead of name to ensure cache invalidation on theme changes\n const componentProps = JSON.stringify(component.props || {});\n const themeHash = createThemeHash(theme);\n // Include minimal context for other components that might vary with context\n // For now we add section layout type and column count without exposing\n // bookmark IDs (TOC/section are bypassed above).\n const contextKey = context?.section\n ? `${context.section.currentLayout}:${context.section.columnCount}`\n : 'no-section';\n // Placeholder resolution is scoped to the document metadata/generatedAt\n // date. Include it for every cacheable component because dynamic text can\n // appear inside nested container props (for example a table cell), not only\n // in top-level paragraph components.\n const generationDateKey = getGenerationDate().toISOString();\n\n // For container components (columns, section, etc.), include children in cache key\n // This ensures cache invalidation when child component content changes\n const childrenKey =\n 'children' in component && component.children\n ? `:children:${JSON.stringify(component.children)}`\n : '';\n\n const cacheKey = `component:${component.name}:${themeHash}:${contextKey}:${generationDateKey}:${componentProps}${childrenKey}`;\n\n // Try to get from cache\n const cached = await componentCache.get(cacheKey);\n\n if (cached) {\n // Cache hit - the cache internally tracks this as a hit\n // Return the rendered result from cache\n return cached.result as (Paragraph | Table | TableOfContents | Textbox)[];\n }\n\n // Cache miss - render the component\n const renderStartTime = Date.now();\n const rendered = await renderComponent(component, theme, themeName, context);\n // Track render time for analytics\n Date.now() - renderStartTime;\n\n // Calculate approximate size (rough estimate)\n const componentSize = JSON.stringify(rendered).length;\n\n // Create a proper CachedComponent structure\n const cachedEntry: CachedComponent = {\n result: rendered as unknown, // Store the rendered Paragraph/Table array as result\n componentName: component.name,\n propsHash: cacheKey,\n timestamp: Date.now(),\n hits: 0,\n size: componentSize,\n dependencies: [],\n signature: cacheKey,\n lastAccessed: Date.now(),\n };\n\n // Store in cache - the cache internally tracks this as a miss\n await componentCache.set(cacheKey, cachedEntry);\n\n return rendered;\n}\n\n// Note: Component statistics are automatically tracked by the cache itself\n// The cache's updateHitStats and updateMissStats methods handle this internally\n\n/**\n * Warm the cache with frequently used components\n */\nexport async function warmComponentCache(\n components: Array<{\n component: ComponentDefinition;\n theme: ThemeConfig;\n themeName: string;\n context: RenderContext;\n }>\n): Promise<void> {\n if (\n !componentCache ||\n !componentCache.getConfig().performance.enableWarming\n ) {\n return;\n }\n\n const warmingPromises = components.map(\n async ({ component, theme, themeName, context }) => {\n await renderComponentWithCache(\n component,\n theme,\n themeName,\n context,\n false\n );\n }\n );\n\n await Promise.all(warmingPromises);\n}\n\n/**\n * Get component cache statistics\n */\nexport function getComponentCacheStats() {\n if (!componentCache) {\n return null;\n }\n\n return componentCache.getStats();\n}\n\n/**\n * Export component cache for persistence\n */\nexport async function exportComponentCache(): Promise<Map<\n string,\n unknown\n> | null> {\n if (!componentCache) {\n return null;\n }\n\n const keys = await componentCache.getKeys();\n const exported = new Map<string, unknown>();\n\n for (const key of keys) {\n const value = await componentCache.get(key);\n if (value) {\n exported.set(key, value);\n }\n }\n\n return exported;\n}\n\n/**\n * Import component cache from persistence\n */\nexport async function importComponentCache(\n data: Map<string, unknown>\n): Promise<void> {\n if (!componentCache) {\n initializeComponentCache();\n }\n\n for (const [key, value] of data.entries()) {\n await componentCache!.set(key, value as CachedComponent);\n }\n}\n","/**\n * Content Creation Functions\n * Pure functions for creating Word document elements without layout concerns\n */\n\nimport {\n Paragraph,\n TextRun,\n Table,\n TableRow,\n TableCell,\n AlignmentType,\n ImageRun,\n PageBreak,\n WidthType,\n BorderStyle,\n Header,\n Footer,\n PageNumber,\n ColumnBreak,\n TableLayoutType,\n VerticalAlign,\n Bookmark,\n} from 'docx';\nimport {\n calculateImageDimensions,\n getImageBuffer,\n parseWidthValue,\n parseDimensionValue,\n detectImageType,\n createTypedImageRun,\n resolveImageSource,\n} from '../utils/imageUtils';\nimport { ThemeConfig } from '../styles';\nimport { getTableStyle } from '../styles';\nimport { getThemeColors, getThemeFonts } from '../themes/defaults';\nimport {\n parseTextWithDecorators,\n splitByNoProofWords,\n} from '../utils/textParser';\nimport {\n processTextWithPlaceholders,\n type PlaceholderChild,\n} from '../utils/placeholderProcessor';\nimport { normalizeUnicodeText } from '../utils/unicode';\nimport { getStyleIdForLevel } from '../styles/themeToDocxAdapter';\nimport { globalBookmarkRegistry } from '../utils/bookmarkRegistry';\nimport { createRevisionRuns } from '../utils/revisionUtils';\nimport type { Revision } from '@json-to-office/shared-docx';\nimport { resolveFontFamily } from '../styles/utils/styleHelpers';\nimport { synthesizeFamilyName } from '@json-to-office/shared';\nimport {\n ComponentDefinition,\n isParagraphComponent,\n ParagraphComponentDefinition,\n isImageComponent,\n ImageComponentDefinition,\n} from '../types';\nimport { resolveColor } from '../styles/utils/colorUtils';\nimport {\n pointsToTwips,\n convertLineSpacing as convertLineSpacingToDocx,\n} from '../styles/utils/styleHelpers';\nimport {\n resolveOffsetTwips,\n getPageWidthTwips,\n getPageHeightTwips,\n getAvailableWidthTwips,\n getAvailableHeightTwips,\n} from '../utils/widthUtils';\n\n/**\n * Resolve (family, bold, italic, fontWeight) into the values the docx lib\n * should receive. For non-RIBBI weights (anything other than 400/700),\n * rewrite the family to the canonical sub-family name (e.g. \"Inter Light\")\n * so Word / LibreOffice can resolve the matching installed face.\n * `bold: true` without fontWeight is shorthand for weight 700.\n */\nfunction applyFontWeightAlias(opts: {\n fontFamily?: string;\n bold?: boolean;\n italic?: boolean;\n fontWeight?: number;\n}): { font?: string; bold?: boolean; italics?: boolean } {\n if (!opts.fontFamily) {\n return { font: undefined, bold: opts.bold, italics: opts.italic };\n }\n const weight = opts.fontWeight ?? (opts.bold === true ? 700 : undefined);\n const synth = synthesizeFamilyName(\n opts.fontFamily,\n weight,\n opts.italic === true\n );\n return { font: synth.family, bold: synth.bold, italics: synth.italic };\n}\n\n/**\n * Combine the document-level known-words allowlist (carried on the theme) with\n * any component-level list, de-duplicated. Returns undefined when empty.\n */\nfunction resolveNoProofWords(\n theme: ThemeConfig,\n optionWords?: string[]\n): string[] | undefined {\n const themeWords = theme.noProofWords;\n const merged = [...(themeWords || []), ...(optionWords || [])];\n return merged.length > 0 ? Array.from(new Set(merged)) : undefined;\n}\n\nexport interface TextOptions {\n style?: string;\n alignment?: 'left' | 'center' | 'right' | 'justify';\n spacing?: {\n before?: number; // in points\n after?: number; // in points\n };\n lineSpacing?:\n | number\n | {\n type: 'single' | 'atLeast' | 'exactly' | 'double' | 'multiple';\n value?: number;\n };\n boldColor?: string;\n columnBreak?: boolean;\n // Font properties\n fontFamily?: string;\n fontSize?: number;\n fontColor?: string;\n bold?: boolean;\n /**\n * Per-run weight (100–900). Renderer picks the closest embedded variant\n * via the font-alias registry and emits the run under a synthetic family\n * (e.g. \"Inter Light\" for 300). Overrides `bold` when set.\n */\n fontWeight?: number;\n italic?: boolean;\n underline?: boolean;\n // Character width scaling in percent (w:w). 100 is normal.\n scale?: number;\n // Letter tracking (w:spacing) — value in twentieths of a point.\n characterSpacing?: { type: 'condensed' | 'expanded'; value: number };\n // Per-run language (BCP-47) for spell/grammar checking. Overrides the\n // document default for these runs.\n language?: string;\n // Disable spell/grammar checking for these runs\n noProof?: boolean;\n // Known-words allowlist: whole-word occurrences are emitted as no-proof runs.\n // Merged with any document-level list carried on the theme.\n noProofWords?: string[];\n // Additional children to prepend (e.g., bookmarks)\n prependChildren?: any[];\n // Outline level for TOC\n outlineLevel?: number;\n // Bookmark ID for internal linking\n bookmarkId?: string;\n // Floating frame properties\n floating?: {\n horizontalPosition?: {\n relative?: 'margin' | 'page' | 'text';\n align?: 'left' | 'center' | 'right' | 'inside' | 'outside';\n offset?: number | string;\n };\n verticalPosition?: {\n relative?: 'margin' | 'page' | 'text';\n align?: 'top' | 'center' | 'bottom' | 'inside' | 'outside' | 'inline';\n offset?: number | string;\n };\n wrap?: {\n type: 'around' | 'none' | 'notBeside' | 'through' | 'tight' | 'auto';\n };\n lockAnchor?: boolean;\n width?: number;\n height?: number;\n };\n // Keep paragraph with next paragraph\n keepNext?: boolean;\n // Keep all lines of paragraph together\n keepLines?: boolean;\n // Paragraph indentation (w:ind) in twips. hanging and firstLine are\n // mutually exclusive (validated upstream).\n indent?: {\n left?: number;\n right?: number;\n hanging?: number;\n firstLine?: number;\n };\n // Tab stops (w:tabs). Tab characters (\\t) in text jump to these positions.\n tabStops?: {\n type: 'left' | 'right' | 'center' | 'decimal' | 'bar';\n position: number;\n leader?: 'dot' | 'hyphen' | 'underscore' | 'middleDot' | 'none';\n }[];\n // Tracked-change segments: when present, text is rendered from these\n // (as native Word revisions) instead of the plain content string\n revision?: Revision;\n}\n\nexport interface ImageOptions {\n caption?: string;\n width?: number | string;\n height?: number | string;\n widthRelativeTo?: 'content' | 'page';\n heightRelativeTo?: 'content' | 'page';\n alignment?: 'left' | 'center' | 'right';\n spacing?: {\n before?: number; // in points\n after?: number; // in points\n };\n floating?: {\n horizontalPosition?: {\n relative?: 'character' | 'column' | 'margin' | 'page' | 'text';\n align?: 'left' | 'center' | 'right' | 'inside' | 'outside';\n offset?: number | string;\n };\n verticalPosition?: {\n relative?: 'margin' | 'page' | 'paragraph' | 'line' | 'text';\n align?: 'top' | 'center' | 'bottom' | 'inside' | 'outside';\n offset?: number | string;\n };\n wrap?: {\n // 'tight', 'around', 'through' are VML-style; only 'none', 'square', 'topAndBottom' are supported for images\n type: 'none' | 'square' | 'topAndBottom' | 'around' | 'tight' | 'through';\n side?: 'bothSides' | 'left' | 'right' | 'largest';\n margins?: {\n top?: number | string;\n bottom?: number | string;\n left?: number | string;\n right?: number | string;\n };\n };\n allowOverlap?: boolean;\n behindDocument?: boolean;\n lockAnchor?: boolean;\n layoutInCell?: boolean;\n zIndex?: number;\n rotation?: number;\n visibility?: 'hidden' | 'inherit';\n };\n // Keep paragraph with next paragraph\n keepNext?: boolean;\n // Keep all lines of paragraph together\n keepLines?: boolean;\n}\n\nexport interface TableOptions {\n style?: 'minimal' | 'classic' | 'minimal';\n}\n\nexport interface StatisticData {\n number: string;\n description: string;\n alignment?: 'left' | 'center' | 'right';\n}\n\nexport interface StatisticOptions {\n spacing?: {\n before?: number; // in points\n after?: number; // in points\n };\n}\n\nexport interface ListOptions {\n // Reference to the numbering configuration in the Document\n numberingReference?: string;\n spacing?: {\n before?: number; // in points\n after?: number; // in points\n item?: number; // in points\n };\n alignment?: 'left' | 'center' | 'right' | 'justify';\n}\n\n/**\n * Create a text paragraph\n */\nexport function createText(\n content: string,\n theme: ThemeConfig,\n themeName: string,\n options: TextOptions = {}\n): Paragraph {\n const normalizedContent = normalizeUnicodeText(content);\n // Always use Normal style for consistent formatting\n const style = options.style || 'Normal';\n\n // Convert points to twips for spacing\n const spacing: any = {};\n if (options.spacing?.before !== undefined) {\n spacing.before = pointsToTwips(options.spacing.before);\n }\n if (options.spacing?.after !== undefined) {\n spacing.after = pointsToTwips(options.spacing.after);\n }\n // Add line spacing if provided\n const lineSpacingConfig = convertLineSpacingToDocx(options.lineSpacing);\n if (lineSpacingConfig) {\n spacing.line = lineSpacingConfig.line;\n spacing.lineRule = lineSpacingConfig.lineRule;\n }\n\n // Build children array\n const children: (\n | PlaceholderChild\n | ColumnBreak\n | Bookmark\n | import('../utils/revisionUtils').RevisionRun\n )[] = [];\n\n // Add column break if requested\n if (options.columnBreak) {\n children.push(new ColumnBreak());\n }\n\n // Resolve the effective family so fontWeight can be aliased even when the\n // run relies on the theme's body font (no inline `family` override). Without\n // this, `{ font: { fontWeight: 300 } }` would fall through with no family\n // for the alias registry to look up.\n const hasWeightRequest = options.fontWeight != null || options.bold === true;\n const effectiveFamily =\n options.fontFamily ??\n (hasWeightRequest ? resolveFontFamily(theme, 'body') : undefined);\n const weighted = applyFontWeightAlias({\n fontFamily: effectiveFamily,\n bold: options.bold,\n italic: options.italic,\n fontWeight: options.fontWeight,\n });\n const baseTextStyle = {\n // Only emit `font` when it came from the caller or from an alias —\n // emitting the theme body family on every run would be a behavior change.\n ...((options.fontFamily ||\n (weighted.font && weighted.font !== effectiveFamily)) && {\n font: weighted.font,\n }),\n ...(options.fontSize && { size: options.fontSize * 2 }), // Convert points to half-points\n ...(options.fontColor && {\n color: resolveColor(options.fontColor, theme),\n }),\n ...(weighted.bold !== undefined && { bold: weighted.bold }),\n ...(weighted.italics !== undefined && { italics: weighted.italics }),\n ...(options.underline !== undefined && {\n underline: options.underline ? { type: 'single' as const } : undefined,\n }),\n // Character width scaling in percent (w:w)\n ...(options.scale && { scale: options.scale }),\n // Letter tracking (w:spacing, twentieths of a point; negative = condensed)\n ...(options.characterSpacing && {\n characterSpacing:\n options.characterSpacing.type === 'condensed'\n ? -options.characterSpacing.value\n : options.characterSpacing.value,\n }),\n // Proofing: per-run language and/or no-proof. Omitting language lets the\n // run inherit the document default set on docDefaults.\n ...(options.language && { language: { value: options.language } }),\n ...(options.noProof !== undefined && { noProof: options.noProof }),\n };\n\n if (options.revision) {\n // Tracked changes: render revision segments as native w:ins/w:del runs\n // (literal text, no markdown parsing). Bookmarks are preserved so\n // internal hyperlinks targeting this paragraph keep working.\n const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);\n if (options.bookmarkId) {\n globalBookmarkRegistry.register(\n options.bookmarkId,\n normalizedContent,\n 'paragraph'\n );\n children.push(\n new Bookmark({\n id: options.bookmarkId,\n children: revisionRuns as TextRun[],\n })\n );\n } else {\n children.push(...revisionRuns);\n }\n } else {\n // Add text content - parseTextWithDecorators handles both decorators and newlines\n const textRuns = parseTextWithDecorators(normalizedContent, baseTextStyle, {\n boldColor: options.boldColor\n ? resolveColor(options.boldColor, theme)\n : undefined,\n enableHyperlinks: true,\n noProofWords: resolveNoProofWords(theme, options.noProofWords),\n });\n\n // If bookmarkId is provided, wrap text runs in a bookmark\n if (options.bookmarkId) {\n // Register bookmark\n globalBookmarkRegistry.register(\n options.bookmarkId,\n normalizedContent,\n 'paragraph'\n );\n\n // Wrap text runs in bookmark\n children.push(\n new Bookmark({\n id: options.bookmarkId,\n children: textRuns as TextRun[],\n })\n );\n } else {\n // No bookmark, add text runs directly\n children.push(...textRuns);\n }\n }\n\n // Build frame options for floating text\n const isFloating = !!options.floating;\n const frameOptions =\n isFloating && options.floating\n ? mapFrameOptions(options.floating, theme, themeName)\n : undefined;\n\n return new Paragraph({\n children,\n style,\n alignment: options.alignment ? getAlignment(options.alignment) : undefined,\n spacing,\n ...(options.outlineLevel !== undefined && {\n outlineLevel: options.outlineLevel,\n }),\n ...(frameOptions && { frame: frameOptions }),\n ...(options.keepNext !== undefined && { keepNext: options.keepNext }),\n ...(options.keepLines !== undefined && { keepLines: options.keepLines }),\n ...(options.indent && { indent: options.indent }),\n ...(options.tabStops &&\n options.tabStops.length > 0 && { tabStops: options.tabStops }),\n });\n}\n\n/**\n * Map floating frame configuration to docx.js IFrameOptions\n * IFrameOptions can be either IXYFrameOptions (absolute positioning) or IAlignmentFrameOptions (aligned positioning)\n *\n * Supports mixed positioning: alignment on one axis, offset on the other.\n * When mixing, calculates the position for the aligned axis.\n */\nfunction mapFrameOptions(\n floating: NonNullable<TextOptions['floating']>,\n theme?: ThemeConfig,\n themeName?: string\n): any {\n const hasHorizontalOffset = floating.horizontalPosition?.offset !== undefined;\n const hasVerticalOffset = floating.verticalPosition?.offset !== undefined;\n const hasHorizontalAlign = floating.horizontalPosition?.align !== undefined;\n const hasVerticalAlign = floating.verticalPosition?.align !== undefined;\n\n // Choose exactly one mode: absolute if any offset is present; otherwise alignment\n const useAbsolute = hasHorizontalOffset || hasVerticalOffset;\n\n // Base frame options\n const frameWidth = floating.width || 2880; // 2in default\n const frameHeight = floating.height || 1440; // 1in default\n\n const baseOptions: any = {\n width: frameWidth,\n height: frameHeight,\n anchor: {\n horizontal: floating.horizontalPosition?.relative || 'page',\n vertical: floating.verticalPosition?.relative || 'page',\n },\n };\n\n if (floating.wrap?.type) {\n baseOptions.wrap = floating.wrap.type;\n }\n\n // Config lockAnchor maps to docx anchorLock\n if (floating.lockAnchor !== undefined) {\n baseOptions.anchorLock = floating.lockAnchor;\n } else if ((floating as any).anchorLock !== undefined) {\n baseOptions.anchorLock = (floating as any).anchorLock;\n }\n\n if (useAbsolute) {\n const rawX = floating.horizontalPosition?.offset ?? 0;\n const rawY = floating.verticalPosition?.offset ?? 0;\n let x: number;\n let y: number;\n if (typeof rawX === 'string' || typeof rawY === 'string') {\n const hRelative = floating.horizontalPosition?.relative;\n const vRelative = floating.verticalPosition?.relative;\n const hRef =\n hRelative && hRelative !== 'page'\n ? getAvailableWidthTwips(theme, themeName)\n : getPageWidthTwips(theme, themeName);\n const vRef =\n vRelative && vRelative !== 'page'\n ? getAvailableHeightTwips(theme, themeName)\n : getPageHeightTwips(theme, themeName);\n x = resolveOffsetTwips(rawX, hRef);\n y = resolveOffsetTwips(rawY, vRef);\n } else {\n x = rawX;\n y = rawY;\n }\n return {\n type: 'absolute',\n position: { x, y },\n ...baseOptions,\n };\n }\n\n // Alignment positioning: use provided aligns; default missing axis\n const xAlign = hasHorizontalAlign\n ? floating.horizontalPosition!.align!\n : 'left';\n const yAlign = hasVerticalAlign ? floating.verticalPosition!.align! : 'top';\n return {\n type: 'alignment',\n alignment: { x: xAlign, y: yAlign },\n ...baseOptions,\n };\n}\n\n/**\n * Create a header paragraph\n */\nexport function createHeading(\n text: string,\n level: number,\n theme: ThemeConfig,\n _themeName: string,\n options: TextOptions = {}\n): Paragraph {\n const normalizedText = normalizeUnicodeText(text);\n const styleId = getStyleIdForLevel(level);\n\n // Only apply spacing if explicitly provided in options\n // This allows theme style spacing to be used by default\n const spacing: any = {};\n let hasExplicitSpacing = false;\n\n if (options.spacing?.before !== undefined) {\n spacing.before = pointsToTwips(options.spacing.before);\n hasExplicitSpacing = true;\n }\n if (options.spacing?.after !== undefined) {\n spacing.after = pointsToTwips(options.spacing.after);\n hasExplicitSpacing = true;\n }\n // Add line spacing if provided\n const lineSpacingConfig = convertLineSpacingToDocx(options.lineSpacing);\n if (lineSpacingConfig) {\n spacing.line = lineSpacingConfig.line;\n spacing.lineRule = lineSpacingConfig.lineRule;\n hasExplicitSpacing = true;\n }\n\n // Build children array\n const children: any[] = [];\n\n // Add prepended children first (e.g., bookmarks)\n if (options.prependChildren) {\n children.push(...options.prependChildren);\n }\n\n // Add column break if requested\n if (options.columnBreak) {\n children.push(new ColumnBreak());\n }\n\n // Check if text has decorators (bold/italic markers)\n const hasDecorators = /(\\*\\*\\*|___|(\\*\\*|__)|(\\*|_))/.test(normalizedText);\n\n // Headings default to theme.fonts.heading when no explicit family is given.\n // Resolve it so fontWeight can be aliased through the same path as body runs.\n const headingHasWeightRequest =\n options.fontWeight != null || options.bold === true;\n const headingEffectiveFamily =\n options.fontFamily ??\n (headingHasWeightRequest ? resolveFontFamily(theme, 'heading') : undefined);\n const headingWeighted = applyFontWeightAlias({\n fontFamily: headingEffectiveFamily,\n bold: options.bold,\n italic: options.italic,\n fontWeight: options.fontWeight,\n });\n // Build base text style from options (overrides theme style at run level)\n const baseTextStyle = {\n ...((options.fontFamily ||\n (headingWeighted.font &&\n headingWeighted.font !== headingEffectiveFamily)) && {\n font: headingWeighted.font,\n }),\n ...(options.fontSize && { size: options.fontSize * 2 }), // points to half-points\n ...(options.fontColor && { color: resolveColor(options.fontColor, theme) }),\n ...(headingWeighted.bold !== undefined && { bold: headingWeighted.bold }),\n ...(headingWeighted.italics !== undefined && {\n italics: headingWeighted.italics,\n }),\n ...(options.underline !== undefined && {\n underline: options.underline ? { type: 'single' as const } : undefined,\n }),\n // Character width scaling in percent (w:w)\n ...(options.scale && { scale: options.scale }),\n // Letter tracking (w:spacing, twentieths of a point; negative = condensed)\n ...(options.characterSpacing && {\n characterSpacing:\n options.characterSpacing.type === 'condensed'\n ? -options.characterSpacing.value\n : options.characterSpacing.value,\n }),\n // Proofing: per-run language and/or no-proof (see createText).\n ...(options.language && { language: { value: options.language } }),\n ...(options.noProof !== undefined && { noProof: options.noProof }),\n };\n\n // Known-words allowlist (document + component) and a run builder that marks\n // matched words as no-proof. Used by the simple (no-decorator) heading paths;\n // the decorator paths route through parseTextWithDecorators instead.\n const headingNoProofWords = resolveNoProofWords(theme, options.noProofWords);\n const makeHeadingRuns = (value: string): TextRun[] =>\n splitByNoProofWords(\n value,\n (segment, matched) =>\n new TextRun({\n text: segment,\n ...baseTextStyle,\n ...(matched && { noProof: true }),\n }),\n headingNoProofWords\n );\n\n if (options.revision) {\n // Tracked changes: revision segments replace text rendering. The TOC\n // bookmark is preserved so TOC links and cross-references keep working.\n const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);\n if (options.bookmarkId) {\n globalBookmarkRegistry.register(\n options.bookmarkId,\n normalizedText,\n 'heading'\n );\n children.push(\n new Bookmark({\n id: options.bookmarkId,\n children: revisionRuns as TextRun[],\n })\n );\n } else {\n children.push(...revisionRuns);\n }\n } else if (options.bookmarkId) {\n // Register bookmark\n globalBookmarkRegistry.register(\n options.bookmarkId,\n normalizedText,\n 'heading'\n );\n\n // Wrap heading text in bookmark\n const headingTextChildren: (TextRun | any)[] = [];\n\n if (hasDecorators) {\n // For headings with decorators, parse text runs first\n const textRuns = parseTextWithDecorators(normalizedText, baseTextStyle, {\n boldColor: options.boldColor\n ? resolveColor(options.boldColor, theme)\n : undefined,\n enableHyperlinks: true,\n noProofWords: headingNoProofWords,\n });\n headingTextChildren.push(...textRuns);\n } else {\n // For simple headings, add single text run (split on known words)\n headingTextChildren.push(...makeHeadingRuns(normalizedText));\n }\n\n // Wrap in bookmark\n children.push(\n new Bookmark({\n id: options.bookmarkId,\n children: headingTextChildren,\n })\n );\n } else {\n // No bookmark, add text directly\n if (hasDecorators) {\n // For headings with decorators, parse and add text runs\n const textRuns = parseTextWithDecorators(normalizedText, baseTextStyle, {\n boldColor: options.boldColor\n ? resolveColor(options.boldColor, theme)\n : undefined,\n enableHyperlinks: true,\n noProofWords: headingNoProofWords,\n });\n children.push(...textRuns);\n } else {\n // For simple headings, add single text run (split on known words)\n children.push(...makeHeadingRuns(normalizedText));\n }\n }\n\n return new Paragraph({\n children,\n style: styleId,\n alignment: getAlignment(options.alignment || 'left'),\n // Only override spacing if explicitly provided\n spacing: hasExplicitSpacing ? spacing : undefined,\n ...(options.keepNext !== undefined && { keepNext: options.keepNext }),\n ...(options.keepLines !== undefined && { keepLines: options.keepLines }),\n ...(options.indent && { indent: options.indent }),\n });\n}\n\n/**\n * Create title page content\n */\nexport function createTitleContent(\n title?: string,\n subtitle?: string\n): Paragraph[] {\n // If no title, return empty array (skip title section entirely)\n if (!title) {\n return [];\n }\n\n const normalizedTitle = normalizeUnicodeText(title);\n const elements: Paragraph[] = [];\n\n elements.push(\n new Paragraph({\n text: normalizedTitle,\n style: 'Title',\n })\n );\n\n if (subtitle) {\n const normalizedSubtitle = normalizeUnicodeText(subtitle);\n elements.push(\n new Paragraph({\n text: normalizedSubtitle,\n style: 'Subtitle',\n })\n );\n }\n\n elements.push(new Paragraph({ children: [new PageBreak()] }));\n\n return elements;\n}\n\n/**\n * Create an image with optional caption\n */\nexport async function createImage(\n path: string,\n theme: ThemeConfig,\n themeName?: string,\n options: ImageOptions = {}\n): Promise<Paragraph[]> {\n const elements: Paragraph[] = [];\n const isFloating = !!options.floating;\n const alignment = isFloating\n ? undefined\n : getAlignment(options.alignment || 'center');\n\n let imagePath = path;\n let imageBuffer: Buffer;\n let responseContentType: string | undefined;\n\n try {\n // Try to use the provided path first\n const imageResult = await getImageBuffer(imagePath);\n imageBuffer = imageResult.buffer;\n responseContentType = imageResult.contentType;\n\n // Calculate available document width/height for percentage calculations\n const {\n getAvailableWidthTwips,\n getPageWidthTwips,\n getAvailableHeightTwips,\n getPageHeightTwips,\n } = await import('../utils/widthUtils');\n const widthRef = options.widthRelativeTo || 'content';\n const heightRef = options.heightRelativeTo || 'content';\n const availableWidthTwips =\n widthRef === 'page'\n ? getPageWidthTwips(theme)\n : getAvailableWidthTwips(theme);\n const availableHeightTwips =\n heightRef === 'page'\n ? getPageHeightTwips(theme)\n : getAvailableHeightTwips(theme);\n // Convert twips to pixels: 1 twip = 1/1440 inch, 1 inch = 96 pixels (screen DPI)\n const availableWidthPx = Math.round((availableWidthTwips / 1440) * 96);\n const availableHeightPx = Math.round((availableHeightTwips / 1440) * 96);\n\n // Default size calculations (fallback)\n const columnWidthCm = 7.36;\n const pixelsPerCm = 37.795275591;\n const columnWidthPx = Math.round(columnWidthCm * pixelsPerCm);\n const fallbackHeight = Math.round(columnWidthPx * 0.6);\n\n // Parse width value (handles both number and percentage string)\n // Default to 100% if no width is specified\n const parsedWidth = parseWidthValue(\n options.width ?? '100%',\n availableWidthPx\n );\n\n // Parse height value if provided\n const parsedHeight =\n options.height !== undefined\n ? parseDimensionValue(options.height, availableHeightPx)\n : undefined;\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imagePath,\n parsedWidth,\n parsedHeight,\n columnWidthPx,\n fallbackHeight\n );\n\n // Build ImageRun configuration with optional floating\n const { mapFloatingOptions } = await import(\n '../utils/docxImagePositioning'\n );\n const floating = isFloating\n ? mapFloatingOptions(options.floating, theme, themeName)\n : undefined;\n\n // Detect image type from response Content-Type, path, or base64 data URI\n const imageType = detectImageType(imagePath, responseContentType);\n\n // Create ImageRun based on image type\n const imageRun = createTypedImageRun({\n type: imageType,\n data: imageBuffer,\n transformation: { width: dimensions.width, height: dimensions.height },\n ...(floating && { floating }),\n });\n\n // Convert spacing from points to twips\n const spacing: any = {};\n if (options.spacing?.before !== undefined) {\n spacing.before = pointsToTwips(options.spacing.before);\n }\n if (options.spacing?.after !== undefined) {\n spacing.after = pointsToTwips(options.spacing.after);\n }\n\n elements.push(\n new Paragraph({\n children: [imageRun],\n alignment,\n ...(Object.keys(spacing).length > 0 && { spacing }),\n ...(options.keepNext !== undefined && { keepNext: options.keepNext }),\n ...(options.keepLines !== undefined && {\n keepLines: options.keepLines,\n }),\n })\n );\n } catch (error) {\n // If the image cannot be loaded, try the placeholder\n throw new Error(`Failed to load image from ${imagePath}`);\n }\n\n if (options.caption) {\n // Check if caption has decorators (bold/italic markers)\n const hasDecorators = /(\\*\\*\\*|___|(\\*\\*|__)|(\\*|_))/.test(options.caption);\n\n if (!hasDecorators) {\n // No decorators - use Normal style for font inheritance\n elements.push(\n new Paragraph({\n text: normalizeUnicodeText(options.caption),\n style: 'Normal',\n alignment: AlignmentType.LEFT, // Captions default to left alignment\n })\n );\n } else {\n // Has decorators - use parseTextWithDecorators (same as text component)\n const textRuns = parseTextWithDecorators(\n options.caption,\n {},\n {\n enableHyperlinks: true,\n }\n );\n\n elements.push(\n new Paragraph({\n children: textRuns,\n style: 'Normal', // Use Normal style for consistent font inheritance\n alignment: AlignmentType.LEFT, // Captions default to left alignment\n })\n );\n }\n }\n\n return elements;\n}\n\n/**\n * Create a statistic display\n */\nexport function createStatistic(\n data: StatisticData,\n options: StatisticOptions = {}\n): Paragraph[] {\n const alignment = getAlignment(data.alignment || 'center');\n const normalizedNumber = normalizeUnicodeText(data.number);\n const normalizedDescription = normalizeUnicodeText(data.description);\n\n return [\n new Paragraph({\n text: normalizedNumber,\n style: 'StatisticNumber',\n alignment,\n spacing: options.spacing,\n }),\n new Paragraph({\n text: normalizedDescription,\n style: 'StatisticDescription',\n alignment,\n }),\n ];\n}\n\n/**\n * Create a list of items using proper docx numbering\n */\nexport function createList(\n items: (string | { text: string; level?: number; revision?: Revision })[],\n _theme: ThemeConfig,\n _themeName: string,\n options: ListOptions = {}\n): Paragraph[] {\n if (!items || items.length === 0) {\n return [];\n }\n\n const paragraphs: Paragraph[] = [];\n\n items.forEach((item, index) => {\n // Handle both string and object items\n const itemText = typeof item === 'string' ? item : item.text;\n const itemLevel = typeof item === 'object' ? item.level || 0 : 0;\n const itemRevision = typeof item === 'object' ? item.revision : undefined;\n\n // Skip empty items — unless they carry revision data (a fully deleted\n // item has empty new text but must still render its w:del runs)\n if (!itemText.trim() && !itemRevision) {\n return;\n }\n\n // Parse rich text decorators for each item\n // Don't pass font/size/color - let list items inherit from Normal paragraph style\n const textRuns = itemRevision\n ? createRevisionRuns(itemRevision, {})\n : parseTextWithDecorators(\n itemText,\n {},\n {\n enableHyperlinks: true,\n }\n );\n\n // Calculate spacing for this item (convert points to twips)\n const spacing: { before?: number; after?: number } = {};\n if (index === 0 && options.spacing?.before) {\n spacing.before = pointsToTwips(options.spacing.before);\n }\n if (index === items.length - 1 && options.spacing?.after) {\n spacing.after = pointsToTwips(options.spacing.after);\n } else if (options.spacing?.item) {\n spacing.after = pointsToTwips(options.spacing.item);\n }\n\n // Create the paragraph with proper numbering reference\n const paragraph = new Paragraph({\n style: 'Normal', // Apply Normal style for font inheritance\n children: textRuns,\n alignment: options.alignment\n ? getAlignment(options.alignment)\n : AlignmentType.LEFT,\n spacing,\n // Use proper docx numbering instead of prepending text\n ...(options.numberingReference && {\n numbering: {\n reference: options.numberingReference,\n level: itemLevel,\n },\n }),\n });\n\n paragraphs.push(paragraph);\n });\n\n return paragraphs;\n}\n\n/**\n * Create a table\n */\ntype TableFontConfig = {\n family?: string;\n size?: number;\n bold?: boolean;\n fontWeight?: number;\n italic?: boolean;\n underline?: boolean;\n};\n\ntype BorderColor =\n | string\n | {\n bottom?: string;\n top?: string;\n right?: string;\n left?: string;\n };\n\ntype BorderSize =\n | number\n | {\n bottom?: number;\n top?: number;\n right?: number;\n left?: number;\n };\n\ntype Padding =\n | number\n | {\n bottom?: number;\n top?: number;\n right?: number;\n left?: number;\n };\n\ntype CellDefaults = {\n color?: string;\n backgroundColor?: string;\n horizontalAlignment?: 'left' | 'center' | 'right' | 'justify';\n verticalAlignment?: 'top' | 'middle' | 'bottom';\n font?: TableFontConfig;\n borderColor?: BorderColor;\n borderSize?: BorderSize;\n padding?: Padding;\n height?: number;\n};\n\n// After merging, borders and padding are always normalized to per-side format\ntype NormalizedCellDefaults = {\n color?: string;\n backgroundColor?: string;\n horizontalAlignment?: 'left' | 'center' | 'right' | 'justify';\n verticalAlignment?: 'top' | 'middle' | 'bottom';\n font?: TableFontConfig;\n borderColor: { top: string; right: string; bottom: string; left: string };\n borderSize: { top: number; right: number; bottom: number; left: number };\n padding?: { top: number; right: number; bottom: number; left: number };\n height?: number;\n};\n\n// Hide borders configuration - can be boolean or per-side object\ntype HideBorders =\n | boolean\n | {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n insideHorizontal?: boolean;\n insideVertical?: boolean;\n };\n\ntype TableConfig = {\n borderColor?: BorderColor;\n borderSize?: BorderSize;\n hideBorders?: HideBorders;\n cellDefaults?: CellDefaults;\n headerCellDefaults?: CellDefaults;\n width?: number;\n columns: {\n /** Width in points (number) or as percentage string e.g. \"40%\" */\n width?: number | string;\n cellDefaults?: CellDefaults;\n header?: CellDefaults & {\n content?: string | ComponentDefinition;\n };\n cells?: (CellDefaults & {\n content?: string | ComponentDefinition;\n })[];\n }[];\n keepInOnePage?: boolean;\n keepNext?: boolean;\n repeatHeaderOnPageBreak?: boolean;\n};\n\nexport async function createTable(\n columns: TableConfig['columns'],\n tableConfig: TableConfig,\n theme: ThemeConfig,\n themeName: string,\n _options: TableOptions = {}\n): Promise<Table> {\n // Note: _options parameter is available for future table customization\n const tableStyle = getTableStyle(theme, themeName);\n\n // Determine number of rows from the first column\n const numRows = columns[0]?.cells?.length || 0;\n\n // Default values for missing cell defaults\n const getDefaultCellDefaults = (): CellDefaults => ({\n color: '000000',\n backgroundColor: 'transparent',\n horizontalAlignment: 'left',\n verticalAlignment: 'top',\n font: {\n family: 'Arial',\n size: 11,\n bold: false,\n italic: false,\n underline: false,\n },\n borderColor: '000000',\n borderSize: 1,\n });\n\n // No warning collector reaches createTable (the render path passes only\n // theme/themeName), so use the prefixed console.warn fallback the generator\n // uses when no collector is present. Deduped so a column of cells sharing the\n // same bad value warns once per table.\n const warnedCellColors = new Set<string>();\n const warnCellColor = (code: string, message: string): void => {\n if (warnedCellColors.has(message)) return;\n warnedCellColors.add(message);\n // eslint-disable-next-line no-console\n console.warn(`[json-to-docx] ${code}: ${message}`);\n };\n\n // Resolve a cell color the same way paragraph/heading font colors are\n // resolved: theme name (\"primary\") or \"#RRGGBB\". Bare 6-digit hex and \"auto\"\n // are passed through — those are the only raw values OOXML itself accepts, so\n // documents relying on them predate theme resolution and must keep working.\n // \"transparent\" is a backgroundColor-only sentinel consumed at the shading\n // site; on the text path nothing consumes it and it is not a legal w:color\n // value, so it is dropped with a warning rather than emitted.\n const resolveCellColor = (\n value: string | undefined,\n prop: 'color' | 'backgroundColor'\n ): string | undefined => {\n if (value === undefined || value === 'auto') return value;\n if (value === 'transparent') {\n if (prop === 'backgroundColor') return value;\n warnCellColor(\n 'TABLE_CELL_COLOR_INVALID',\n `\"transparent\" is not a valid table cell \"color\"; ignoring it and using the table style color. It only applies to \"backgroundColor\".`\n );\n return undefined;\n }\n if (/^[0-9A-Fa-f]{6}$/.test(value)) return value.toUpperCase();\n try {\n return resolveColor(value, theme);\n } catch {\n // Passing the value through instead would not save the document: docx\n // rejects any non-hex, non-\"auto\" fill/color, so it would still fail —\n // deeper in the stack with an opaque message.\n const allowed =\n prop === 'backgroundColor'\n ? '\"auto\", or \"transparent\" for no shading'\n : 'or \"auto\"';\n throw new Error(\n `Invalid table cell ${prop}: \"${value}\". Must be a hex color with # prefix (e.g. \"#000000\"), a theme color name, ${allowed}.`\n );\n }\n };\n\n // Helper function to normalize border color to per-side format\n const normalizeBorderColor = (\n border: BorderColor | undefined\n ):\n | { top: string; right: string; bottom: string; left: string }\n | undefined => {\n if (border === undefined) return undefined;\n if (typeof border === 'string') {\n return { top: border, right: border, bottom: border, left: border };\n }\n return {\n top: border.top ?? '',\n right: border.right ?? '',\n bottom: border.bottom ?? '',\n left: border.left ?? '',\n };\n };\n\n // Helper function to normalize border size to per-side format\n const normalizeBorderSize = (\n border: BorderSize | undefined\n ):\n | { top: number; right: number; bottom: number; left: number }\n | undefined => {\n if (border === undefined) return undefined;\n if (typeof border === 'number') {\n return { top: border, right: border, bottom: border, left: border };\n }\n return {\n top: border.top ?? -1,\n right: border.right ?? -1,\n bottom: border.bottom ?? -1,\n left: border.left ?? -1,\n };\n };\n\n // Helper function to normalize padding to per-side format\n const normalizePadding = (\n padding: Padding | undefined\n ):\n | { top: number; right: number; bottom: number; left: number }\n | undefined => {\n if (padding === undefined) return undefined;\n if (typeof padding === 'number') {\n return { top: padding, right: padding, bottom: padding, left: padding };\n }\n return {\n top: padding.top ?? -1,\n right: padding.right ?? -1,\n bottom: padding.bottom ?? -1,\n left: padding.left ?? -1,\n };\n };\n\n // Helper function to merge border colors at the side level\n const mergeBorderColorPerSide = (\n ...borders: (BorderColor | undefined)[]\n ): { top: string; right: string; bottom: string; left: string } => {\n const normalized = borders.map(normalizeBorderColor);\n const defaults = getDefaultCellDefaults();\n const defaultColor =\n typeof defaults.borderColor === 'string'\n ? defaults.borderColor\n : '000000';\n\n return {\n top: normalized.find((b) => b && b.top !== '')?.top ?? defaultColor,\n right: normalized.find((b) => b && b.right !== '')?.right ?? defaultColor,\n bottom:\n normalized.find((b) => b && b.bottom !== '')?.bottom ?? defaultColor,\n left: normalized.find((b) => b && b.left !== '')?.left ?? defaultColor,\n };\n };\n\n // Helper function to merge border sizes at the side level\n const mergeBorderSizePerSide = (\n ...borders: (BorderSize | undefined)[]\n ): { top: number; right: number; bottom: number; left: number } => {\n const normalized = borders.map(normalizeBorderSize);\n const defaults = getDefaultCellDefaults();\n const defaultSize =\n typeof defaults.borderSize === 'number' ? defaults.borderSize : 1;\n\n return {\n top: normalized.find((b) => b && b.top !== -1)?.top ?? defaultSize,\n right: normalized.find((b) => b && b.right !== -1)?.right ?? defaultSize,\n bottom:\n normalized.find((b) => b && b.bottom !== -1)?.bottom ?? defaultSize,\n left: normalized.find((b) => b && b.left !== -1)?.left ?? defaultSize,\n };\n };\n\n // Helper to create border override for table outer borders based on position\n const getTableOuterBorder = (\n position: {\n isHeader?: boolean;\n isFirstCol?: boolean;\n isLastCol?: boolean;\n isLastRow?: boolean;\n },\n tableBorderColor?: BorderColor,\n tableBorderSize?: BorderSize\n ): {\n borderColor?: Partial<{\n top: string;\n right: string;\n bottom: string;\n left: string;\n }>;\n borderSize?: Partial<{\n top: number;\n right: number;\n bottom: number;\n left: number;\n }>;\n } => {\n const result: {\n borderColor?: Partial<{\n top: string;\n right: string;\n bottom: string;\n left: string;\n }>;\n borderSize?: Partial<{\n top: number;\n right: number;\n bottom: number;\n left: number;\n }>;\n } = {};\n\n if (tableBorderColor) {\n const normalizedColor = normalizeBorderColor(tableBorderColor);\n if (normalizedColor) {\n result.borderColor = {};\n if (position.isHeader && normalizedColor.top !== '')\n result.borderColor.top = normalizedColor.top;\n if (position.isFirstCol && normalizedColor.left !== '')\n result.borderColor.left = normalizedColor.left;\n if (position.isLastCol && normalizedColor.right !== '')\n result.borderColor.right = normalizedColor.right;\n if (position.isLastRow && normalizedColor.bottom !== '')\n result.borderColor.bottom = normalizedColor.bottom;\n }\n }\n\n if (tableBorderSize) {\n const normalizedSize = normalizeBorderSize(tableBorderSize);\n if (normalizedSize) {\n result.borderSize = {};\n if (position.isHeader && normalizedSize.top !== -1)\n result.borderSize.top = normalizedSize.top;\n if (position.isFirstCol && normalizedSize.left !== -1)\n result.borderSize.left = normalizedSize.left;\n if (position.isLastCol && normalizedSize.right !== -1)\n result.borderSize.right = normalizedSize.right;\n if (position.isLastRow && normalizedSize.bottom !== -1)\n result.borderSize.bottom = normalizedSize.bottom;\n }\n }\n\n return result;\n };\n\n // Helper function to merge padding at the side level\n const mergePaddingPerSide = (\n ...paddings: (Padding | undefined)[]\n ):\n | { top: number; right: number; bottom: number; left: number }\n | undefined => {\n const normalized = paddings.map(normalizePadding);\n const hasAny = normalized.some((p) => p !== undefined);\n if (!hasAny) return undefined;\n\n return {\n top: normalized.find((p) => p && p.top !== -1)?.top ?? 0,\n right: normalized.find((p) => p && p.right !== -1)?.right ?? 0,\n bottom: normalized.find((p) => p && p.bottom !== -1)?.bottom ?? 0,\n left: normalized.find((p) => p && p.left !== -1)?.left ?? 0,\n };\n };\n\n // Helper function to merge cell defaults with priority: cell > column > table outer border (for specific sides) > table cellDefaults > default\n const mergeCellDefaults = (\n tableDef?: CellDefaults,\n columnDef?: CellDefaults,\n cellDef?: Partial<CellDefaults>,\n position?: {\n isFirstCol?: boolean;\n isLastCol?: boolean;\n isLastRow?: boolean;\n },\n tableOuterBorder?: { borderColor?: BorderColor; borderSize?: BorderSize }\n ): NormalizedCellDefaults => {\n const defaults = getDefaultCellDefaults();\n\n // Merge font configs\n const mergedFont: TableFontConfig = {\n ...defaults.font,\n ...tableDef?.font,\n ...columnDef?.font,\n ...cellDef?.font,\n };\n\n // Get table outer border overrides based on position\n const outerBorder =\n position && tableOuterBorder\n ? getTableOuterBorder(\n position,\n tableOuterBorder.borderColor,\n tableOuterBorder.borderSize\n )\n : {};\n\n // Merge border colors per side (priority: cell > column > table outer border > table cellDefaults > table borderColor > default)\n // tableOuterBorder.borderColor is used twice: via outerBorder for edge-specific application,\n // and directly as fallback for ALL borders when not overridden by cellDefaults\n const mergedBorderColor = mergeBorderColorPerSide(\n cellDef?.borderColor,\n columnDef?.borderColor,\n outerBorder.borderColor as BorderColor,\n tableDef?.borderColor,\n tableOuterBorder?.borderColor // Apply table-level borderColor to all cells as fallback\n );\n\n // Merge border sizes per side (priority: cell > column > table outer border > table cellDefaults > table borderSize > default)\n const mergedBorderSize = mergeBorderSizePerSide(\n cellDef?.borderSize,\n columnDef?.borderSize,\n outerBorder.borderSize as BorderSize,\n tableDef?.borderSize,\n tableOuterBorder?.borderSize // Apply table-level borderSize to all cells as fallback\n );\n\n // Merge padding per side (priority: cell > column > table)\n const mergedPadding = mergePaddingPerSide(\n cellDef?.padding,\n columnDef?.padding,\n tableDef?.padding\n );\n\n return {\n color: resolveCellColor(\n cellDef?.color ?? columnDef?.color ?? tableDef?.color ?? defaults.color,\n 'color'\n ),\n backgroundColor: resolveCellColor(\n cellDef?.backgroundColor ??\n columnDef?.backgroundColor ??\n tableDef?.backgroundColor ??\n defaults.backgroundColor,\n 'backgroundColor'\n ),\n horizontalAlignment:\n cellDef?.horizontalAlignment ??\n columnDef?.horizontalAlignment ??\n tableDef?.horizontalAlignment ??\n defaults.horizontalAlignment,\n verticalAlignment:\n cellDef?.verticalAlignment ??\n columnDef?.verticalAlignment ??\n tableDef?.verticalAlignment ??\n defaults.verticalAlignment,\n font: mergedFont,\n borderColor: mergedBorderColor,\n borderSize: mergedBorderSize,\n padding: mergedPadding,\n height: cellDef?.height ?? columnDef?.height ?? tableDef?.height,\n };\n };\n\n // Helper function to merge header cell defaults with priority: header > columnCellDefaults > table outer border (for specific sides) > headerCellDefaults > cellDefaults > default\n const mergeHeaderCellDefaults = (\n tableDef?: CellDefaults,\n headerTableDef?: CellDefaults,\n columnDef?: CellDefaults,\n headerDef?: Partial<CellDefaults>,\n position?: { isFirstCol?: boolean; isLastCol?: boolean },\n tableOuterBorder?: { borderColor?: BorderColor; borderSize?: BorderSize }\n ): NormalizedCellDefaults => {\n const defaults = getDefaultCellDefaults();\n\n // Merge font configs with new priority\n const mergedFont: TableFontConfig = {\n ...defaults.font,\n ...tableDef?.font,\n ...headerTableDef?.font,\n ...columnDef?.font,\n ...headerDef?.font,\n };\n\n // Get table outer border overrides based on position (headers always affect top border)\n const outerBorder =\n position && tableOuterBorder\n ? getTableOuterBorder(\n {\n isHeader: true,\n isFirstCol: position.isFirstCol,\n isLastCol: position.isLastCol,\n },\n tableOuterBorder.borderColor,\n tableOuterBorder.borderSize\n )\n : {};\n\n // Merge border colors per side (priority: header > columnCellDefaults > table outer border > headerCellDefaults > cellDefaults > table borderColor > default)\n // tableOuterBorder.borderColor is used twice: via outerBorder for edge-specific application,\n // and directly as fallback for ALL borders when not overridden by cellDefaults\n const mergedBorderColor = mergeBorderColorPerSide(\n headerDef?.borderColor,\n columnDef?.borderColor,\n outerBorder.borderColor as BorderColor,\n headerTableDef?.borderColor,\n tableDef?.borderColor,\n tableOuterBorder?.borderColor // Apply table-level borderColor to all cells as fallback\n );\n\n // Merge border sizes per side (priority: header > columnCellDefaults > table outer border > headerCellDefaults > cellDefaults > table borderSize > default)\n const mergedBorderSize = mergeBorderSizePerSide(\n headerDef?.borderSize,\n columnDef?.borderSize,\n outerBorder.borderSize as BorderSize,\n headerTableDef?.borderSize,\n tableDef?.borderSize,\n tableOuterBorder?.borderSize // Apply table-level borderSize to all cells as fallback\n );\n\n // Merge padding per side (priority: header > headerCellDefaults > columnCellDefaults > cellDefaults)\n const mergedPadding = mergePaddingPerSide(\n headerDef?.padding,\n headerTableDef?.padding,\n columnDef?.padding,\n tableDef?.padding\n );\n\n return {\n color: resolveCellColor(\n headerDef?.color ??\n headerTableDef?.color ??\n columnDef?.color ??\n tableDef?.color ??\n defaults.color,\n 'color'\n ),\n backgroundColor: resolveCellColor(\n headerDef?.backgroundColor ??\n headerTableDef?.backgroundColor ??\n columnDef?.backgroundColor ??\n tableDef?.backgroundColor ??\n defaults.backgroundColor,\n 'backgroundColor'\n ),\n horizontalAlignment:\n headerDef?.horizontalAlignment ??\n headerTableDef?.horizontalAlignment ??\n columnDef?.horizontalAlignment ??\n tableDef?.horizontalAlignment ??\n defaults.horizontalAlignment,\n verticalAlignment:\n headerDef?.verticalAlignment ??\n headerTableDef?.verticalAlignment ??\n columnDef?.verticalAlignment ??\n tableDef?.verticalAlignment ??\n defaults.verticalAlignment,\n font: mergedFont,\n borderColor: mergedBorderColor,\n borderSize: mergedBorderSize,\n padding: mergedPadding,\n height:\n headerDef?.height ??\n headerTableDef?.height ??\n columnDef?.height ??\n tableDef?.height,\n };\n };\n\n // Helper function to get border value for a specific side\n // After normalization, borders are always objects with side properties\n const getBorderValue = (\n border: {\n top: string | number;\n right: string | number;\n bottom: string | number;\n left: string | number;\n },\n side: 'top' | 'bottom' | 'left' | 'right'\n ) => {\n return border[side];\n };\n\n // Helper function to get padding value for a specific side\n // After normalization, padding is always an object with side properties or undefined\n const getPaddingValue = (\n padding:\n | { top: number; right: number; bottom: number; left: number }\n | undefined,\n side: 'top' | 'bottom' | 'left' | 'right'\n ): number | undefined => {\n if (padding === undefined) return undefined;\n return padding[side] * 20; // Convert points to twips\n };\n\n // Helper function to create margins object from padding\n // After normalization, padding is always an object with side properties or undefined\n // Returns ITableCellMarginOptions with marginUnitType set to DXA (twips)\n const createMarginsFromPadding = (\n padding:\n | { top: number; right: number; bottom: number; left: number }\n | undefined\n ) => {\n if (padding === undefined) return undefined;\n\n return {\n marginUnitType: WidthType.DXA, // Specify that values are in twips\n top: getPaddingValue(padding, 'top') ?? 0,\n bottom: getPaddingValue(padding, 'bottom') ?? 0,\n left: getPaddingValue(padding, 'left') ?? 0,\n right: getPaddingValue(padding, 'right') ?? 0,\n };\n };\n\n // Normalize hideBorders config to per-side format\n const normalizeHideBorders = (\n hideBorders: HideBorders | undefined\n ): {\n top: boolean;\n right: boolean;\n bottom: boolean;\n left: boolean;\n insideHorizontal: boolean;\n insideVertical: boolean;\n } => {\n if (hideBorders === undefined) {\n return {\n top: false,\n right: false,\n bottom: false,\n left: false,\n insideHorizontal: false,\n insideVertical: false,\n };\n }\n if (typeof hideBorders === 'boolean') {\n return {\n top: hideBorders,\n right: hideBorders,\n bottom: hideBorders,\n left: hideBorders,\n insideHorizontal: hideBorders,\n insideVertical: hideBorders,\n };\n }\n return {\n top: hideBorders.top ?? false,\n right: hideBorders.right ?? false,\n bottom: hideBorders.bottom ?? false,\n left: hideBorders.left ?? false,\n insideHorizontal: hideBorders.insideHorizontal ?? false,\n insideVertical: hideBorders.insideVertical ?? false,\n };\n };\n\n // Normalized hidden borders config\n const hiddenBorders = normalizeHideBorders(tableConfig.hideBorders);\n\n // Helper function to create border config\n const createBorder = (size: number, color: string, isHidden?: boolean) => {\n if (size === 0 || isHidden) {\n return { style: BorderStyle.NONE, size: 0, color: '000000' };\n }\n return {\n style: BorderStyle.SINGLE,\n size: size * 8, // Convert points to eighths of a point\n color: color || '000000',\n };\n };\n\n // Helper to determine if a specific border should be hidden based on cell position\n const shouldHideBorder = (\n side: 'top' | 'right' | 'bottom' | 'left',\n position: {\n isFirstRow?: boolean;\n isLastRow?: boolean;\n isFirstCol?: boolean;\n isLastCol?: boolean;\n }\n ): boolean => {\n // Map cell position to which hideBorders config applies\n // Outer borders use top/right/bottom/left, inner borders use insideHorizontal/insideVertical\n switch (side) {\n case 'top':\n return position.isFirstRow\n ? hiddenBorders.top\n : hiddenBorders.insideHorizontal;\n case 'bottom':\n return position.isLastRow\n ? hiddenBorders.bottom\n : hiddenBorders.insideHorizontal;\n case 'left':\n return position.isFirstCol\n ? hiddenBorders.left\n : hiddenBorders.insideVertical;\n case 'right':\n return position.isLastCol\n ? hiddenBorders.right\n : hiddenBorders.insideVertical;\n default:\n return false;\n }\n };\n\n // Helper function to process cell content\n const processCellContent = async (\n cell: string | ComponentDefinition | undefined,\n cellDefaults: NormalizedCellDefaults,\n baseCellStyle: typeof tableStyle.tableCell\n ): Promise<(PlaceholderChild | ImageRun)[]> => {\n let cellChildren: (PlaceholderChild | ImageRun)[] = [];\n\n // Handle undefined or empty content\n if (!cell) {\n return cellChildren;\n }\n\n // Create merged style with config overrides\n const cellWeighted = applyFontWeightAlias({\n fontFamily: cellDefaults.font?.family || baseCellStyle.font,\n bold: cellDefaults.font?.bold ?? false,\n italic: cellDefaults.font?.italic ?? false,\n fontWeight: cellDefaults.font?.fontWeight,\n });\n const mergedStyle = {\n font: cellWeighted.font,\n size: cellDefaults.font?.size\n ? cellDefaults.font.size * 2\n : baseCellStyle.size, // Convert to half-points\n bold: cellWeighted.bold ?? false,\n italics: cellWeighted.italics ?? false,\n underline: cellDefaults.font?.underline\n ? { type: 'single' as const }\n : undefined,\n color: cellDefaults.color || baseCellStyle.color,\n };\n\n if (typeof cell === 'object' && 'name' in cell && 'props' in cell) {\n // Handle ComponentDefinition\n if (isParagraphComponent(cell)) {\n const textComp = cell as ParagraphComponentDefinition;\n const paragraphFont = textComp.props.font;\n const paraWeighted = applyFontWeightAlias({\n fontFamily: paragraphFont?.family ?? mergedStyle.font,\n bold: paragraphFont?.bold,\n italic: paragraphFont?.italic,\n fontWeight: paragraphFont?.fontWeight,\n });\n const paragraphStyle = {\n ...mergedStyle,\n ...(paraWeighted.font && { font: paraWeighted.font }),\n ...(paragraphFont?.size && { size: paragraphFont.size * 2 }),\n ...(paraWeighted.bold !== undefined && {\n bold: paraWeighted.bold,\n }),\n ...(paraWeighted.italics !== undefined && {\n italics: paraWeighted.italics,\n }),\n ...(paragraphFont?.underline !== undefined && {\n underline: paragraphFont.underline\n ? { type: 'single' as const }\n : undefined,\n }),\n ...(paragraphFont?.color && {\n color: resolveColor(paragraphFont.color, theme),\n }),\n };\n cellChildren = parseTextWithDecorators(\n textComp.props.text,\n paragraphStyle,\n { enableHyperlinks: true }\n );\n } else if (isImageComponent(cell)) {\n const imageComp = cell as ImageComponentDefinition;\n try {\n // Get image source (svg, base64, or path)\n const imageSource = resolveImageSource(imageComp.props);\n if (!imageSource) {\n throw new Error(\n 'Image component requires one of \"path\", \"base64\", or \"svg\" property'\n );\n }\n\n // Read from local file, URL, or base64\n const imageResult = await getImageBuffer(imageSource);\n\n // Parse width value if it's a string percentage (like \"90%\")\n const parsedWidth =\n typeof imageComp.props.width === 'string'\n ? parseWidthValue(imageComp.props.width, 300) // Use a reasonable default for table context\n : imageComp.props.width;\n\n // Parse height value if it's a string percentage (like \"90%\")\n const parsedHeight =\n typeof imageComp.props.height === 'string'\n ? parseWidthValue(imageComp.props.height, 200) // Use a reasonable default for table context\n : imageComp.props.height;\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imageSource,\n parsedWidth,\n parsedHeight,\n 60, // fallback width\n 20 // fallback height\n );\n\n const imgType = detectImageType(imageSource, imageResult.contentType);\n const imageRun = createTypedImageRun({\n type: imgType,\n data: imageResult.buffer,\n transformation: {\n width: dimensions.width,\n height: dimensions.height,\n },\n });\n cellChildren = [imageRun];\n } catch (error) {\n // Fallback for missing images\n const imageSource = imageComp.props.svg?.trim()\n ? 'inline-svg'\n : imageComp.props.base64 || imageComp.props.path || 'unknown';\n cellChildren = [\n new TextRun({\n text: `[IMAGE: ${imageSource.substring(0, 50)}${imageSource.length > 50 ? '...' : ''}]`,\n font: mergedStyle.font,\n size: mergedStyle.size,\n color: '#999999',\n }),\n ];\n }\n } else {\n // Unsupported component type in table cell\n cellChildren = [\n new TextRun({\n text: `[Unsupported component type: ${cell.name}]`,\n font: mergedStyle.font,\n size: mergedStyle.size,\n color: '#999999',\n }),\n ];\n }\n } else {\n // Handle plain string\n cellChildren = parseTextWithDecorators(cell as string, mergedStyle, {\n enableHyperlinks: true,\n });\n }\n\n return cellChildren;\n };\n\n // Create header row by iterating through columns\n // Calculate row height from any header cell that defines it\n const numColumns = columns.length;\n const headerHeight = columns.reduce<number | undefined>(\n (maxHeight, column, colIndex) => {\n const headerCell = column.header;\n const position = {\n isFirstCol: colIndex === 0,\n isLastCol: colIndex === numColumns - 1,\n };\n const mergedDefaults = mergeHeaderCellDefaults(\n tableConfig.cellDefaults,\n tableConfig.headerCellDefaults,\n column.cellDefaults,\n headerCell,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n if (mergedDefaults.height !== undefined) {\n return maxHeight !== undefined\n ? Math.max(maxHeight, mergedDefaults.height)\n : mergedDefaults.height;\n }\n return maxHeight;\n },\n undefined\n );\n\n const headerRow = new TableRow({\n // Headers repeat across page breaks unless explicitly disabled\n tableHeader: tableConfig.repeatHeaderOnPageBreak ?? true,\n height:\n headerHeight !== undefined\n ? { value: headerHeight * 20, rule: 'atLeast' as const }\n : undefined,\n children: await Promise.all(\n columns.map(async (column, colIndex) => {\n const headerCell = column.header;\n\n // Determine position for outer border application and hideBorders\n const position = {\n isFirstRow: true, // Header is always the first row\n isLastRow: numRows === 0, // Header is last row only if no data rows\n isFirstCol: colIndex === 0,\n isLastCol: colIndex === numColumns - 1,\n };\n\n // Merge cell defaults with priority: header > columnCellDefaults > table outer border > headerCellDefaults > cellDefaults\n const mergedDefaults = mergeHeaderCellDefaults(\n tableConfig.cellDefaults,\n tableConfig.headerCellDefaults,\n column.cellDefaults,\n headerCell,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n\n const cellChildren = await processCellContent(\n headerCell?.content,\n mergedDefaults,\n tableStyle.tableHeader\n );\n\n const horizontalAlignment = mergedDefaults.horizontalAlignment!;\n const verticalAlignment = getVerticalAlignment(\n mergedDefaults.verticalAlignment\n );\n\n return new TableCell({\n children: [\n new Paragraph({\n ...(tableConfig.keepInOnePage && { keepNext: true }),\n spacing: tableStyle.headerParagraph,\n alignment: getAlignment(horizontalAlignment),\n children: cellChildren,\n }),\n ],\n\n verticalAlign: verticalAlignment,\n ...(mergedDefaults.backgroundColor !== 'transparent' && {\n shading: {\n fill: mergedDefaults.backgroundColor,\n },\n }),\n margins: createMarginsFromPadding(mergedDefaults.padding),\n borders: {\n top: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'top') as number,\n getBorderValue(mergedDefaults.borderColor, 'top') as string,\n shouldHideBorder('top', position)\n ),\n bottom: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'bottom') as number,\n getBorderValue(mergedDefaults.borderColor, 'bottom') as string,\n shouldHideBorder('bottom', position)\n ),\n left: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'left') as number,\n getBorderValue(mergedDefaults.borderColor, 'left') as string,\n shouldHideBorder('left', position)\n ),\n right: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'right') as number,\n getBorderValue(mergedDefaults.borderColor, 'right') as string,\n shouldHideBorder('right', position)\n ),\n },\n });\n })\n ),\n });\n\n // Create data rows\n const dataRows = await Promise.all(\n Array.from({ length: numRows }, async (_, rowIndex) => {\n const isLastRow = rowIndex === numRows - 1;\n\n // Calculate row height from any cell in this row that defines it\n const rowHeight = columns.reduce<number | undefined>(\n (maxHeight, column, colIndex) => {\n const cell = column.cells?.[rowIndex];\n if (cell) {\n const position = {\n isFirstCol: colIndex === 0,\n isLastCol: colIndex === numColumns - 1,\n isLastRow,\n };\n const mergedDefaults = mergeCellDefaults(\n tableConfig.cellDefaults,\n column.cellDefaults,\n cell,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n if (mergedDefaults.height !== undefined) {\n return maxHeight !== undefined\n ? Math.max(maxHeight, mergedDefaults.height)\n : mergedDefaults.height;\n }\n }\n return maxHeight;\n },\n undefined\n );\n\n return new TableRow({\n height:\n rowHeight !== undefined\n ? { value: rowHeight * 20, rule: 'atLeast' as const }\n : undefined,\n children: await Promise.all(\n columns.map(async (column, colIndex) => {\n const cell = column.cells?.[rowIndex];\n\n // Determine position for outer border application and hideBorders\n const position = {\n isFirstRow: false, // Data rows are never the first row (header is)\n isFirstCol: colIndex === 0,\n isLastCol: colIndex === numColumns - 1,\n isLastRow,\n };\n\n if (!cell) {\n // Handle missing cell data - merge defaults properly\n const mergedDefaultsForMissing = mergeCellDefaults(\n tableConfig.cellDefaults,\n column.cellDefaults,\n undefined,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n return new TableCell({\n children: [\n new Paragraph({\n ...((tableConfig.keepInOnePage && !isLastRow) ||\n (isLastRow && tableConfig.keepNext)\n ? { keepNext: true }\n : {}),\n spacing: tableStyle.cellParagraph,\n alignment: AlignmentType.LEFT,\n children: [],\n }),\n ],\n borders: {\n top: createBorder(\n getBorderValue(\n mergedDefaultsForMissing.borderSize,\n 'top'\n ) as number,\n getBorderValue(\n mergedDefaultsForMissing.borderColor,\n 'top'\n ) as string,\n shouldHideBorder('top', position)\n ),\n bottom: createBorder(\n getBorderValue(\n mergedDefaultsForMissing.borderSize,\n 'bottom'\n ) as number,\n getBorderValue(\n mergedDefaultsForMissing.borderColor,\n 'bottom'\n ) as string,\n shouldHideBorder('bottom', position)\n ),\n left: createBorder(\n getBorderValue(\n mergedDefaultsForMissing.borderSize,\n 'left'\n ) as number,\n getBorderValue(\n mergedDefaultsForMissing.borderColor,\n 'left'\n ) as string,\n shouldHideBorder('left', position)\n ),\n right: createBorder(\n getBorderValue(\n mergedDefaultsForMissing.borderSize,\n 'right'\n ) as number,\n getBorderValue(\n mergedDefaultsForMissing.borderColor,\n 'right'\n ) as string,\n shouldHideBorder('right', position)\n ),\n },\n });\n }\n\n // Merge cell defaults with priority: cell > column > table outer border > table cellDefaults\n const mergedDefaults = mergeCellDefaults(\n tableConfig.cellDefaults,\n column.cellDefaults,\n cell,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n\n const cellChildren = await processCellContent(\n cell.content,\n mergedDefaults,\n tableStyle.tableCell\n );\n\n const horizontalAlignment = mergedDefaults.horizontalAlignment!;\n const verticalAlignment = getVerticalAlignment(\n mergedDefaults.verticalAlignment\n );\n\n return new TableCell({\n children: [\n new Paragraph({\n ...((tableConfig.keepInOnePage && !isLastRow) ||\n (isLastRow && tableConfig.keepNext)\n ? { keepNext: true }\n : {}),\n spacing: tableStyle.cellParagraph,\n alignment: getAlignment(horizontalAlignment),\n children: cellChildren,\n }),\n ],\n verticalAlign: verticalAlignment,\n ...(mergedDefaults.backgroundColor !== 'transparent' && {\n shading: {\n fill: mergedDefaults.backgroundColor,\n },\n }),\n margins: createMarginsFromPadding(mergedDefaults.padding),\n borders: {\n top: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'top') as number,\n getBorderValue(mergedDefaults.borderColor, 'top') as string,\n shouldHideBorder('top', position)\n ),\n bottom: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'bottom') as number,\n getBorderValue(\n mergedDefaults.borderColor,\n 'bottom'\n ) as string,\n shouldHideBorder('bottom', position)\n ),\n left: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'left') as number,\n getBorderValue(mergedDefaults.borderColor, 'left') as string,\n shouldHideBorder('left', position)\n ),\n right: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'right') as number,\n getBorderValue(mergedDefaults.borderColor, 'right') as string,\n shouldHideBorder('right', position)\n ),\n },\n });\n })\n ),\n });\n })\n );\n\n // Calculate column widths - if any column has explicit width, use DXA for all\n const hasExplicitWidths = columns.some((col) => col.width !== undefined);\n\n let columnWidths: number[];\n let tableWidth: {\n size: number;\n type: (typeof WidthType)[keyof typeof WidthType];\n };\n\n if (hasExplicitWidths) {\n // Use explicit widths in DXA (twips) - convert from points\n const widthUtils = await import('../utils/widthUtils');\n const { getAvailableWidthTwips, relativeLengthToTwips } = widthUtils;\n\n // Get available table width in twips (page width minus margins)\n const availableTableWidth = getAvailableWidthTwips(theme, themeName);\n\n // Convert explicit column widths (points or percentage strings) to twips\n const columnsWithExplicitWidthTwips = columns.map((col) =>\n col.width !== undefined\n ? relativeLengthToTwips(col.width, availableTableWidth)\n : undefined\n );\n\n // Calculate total width used by columns with explicit widths\n const totalExplicitWidth = columnsWithExplicitWidthTwips.reduce(\n (sum: number, w) => sum + (w || 0),\n 0\n );\n\n if (totalExplicitWidth > availableTableWidth) {\n console.warn(\n `[json-to-office] Column widths total (${totalExplicitWidth} twips) exceeds available table width (${availableTableWidth} twips). Table may overflow.`\n );\n }\n\n // Count columns without explicit width\n const columnsWithoutWidth = columns.filter(\n (col) => col.width === undefined\n ).length;\n\n // Calculate remaining space and distribute among columns without explicit width\n const remainingWidth = Math.max(\n 0,\n availableTableWidth - totalExplicitWidth\n );\n const defaultColumnWidth =\n columnsWithoutWidth > 0\n ? remainingWidth / columnsWithoutWidth\n : pointsToTwips(72); // Fallback to 1 inch if all columns have explicit widths\n\n // Assign widths: use explicit width (in twips) or calculated default\n columnWidths = columnsWithExplicitWidthTwips.map(\n (w) => w || defaultColumnWidth\n );\n const totalWidth = columnWidths.reduce((sum, w) => sum + w, 0);\n tableWidth = { size: totalWidth, type: WidthType.DXA };\n } else {\n // Use percentage-based equal distribution\n const percentPerColumn = 100 / columns.length;\n columnWidths = columns.map(() => percentPerColumn);\n tableWidth = { size: tableConfig.width ?? 100, type: WidthType.PERCENTAGE };\n }\n\n return new Table({\n width: tableWidth,\n layout: TableLayoutType.FIXED,\n columnWidths: columnWidths,\n rows: [headerRow, ...dataRows],\n });\n}\n\n/**\n * Convert alignment string to docx AlignmentType\n */\nfunction getAlignment(\n alignment: string\n): (typeof AlignmentType)[keyof typeof AlignmentType] {\n switch (alignment) {\n case 'center':\n return AlignmentType.CENTER;\n case 'right':\n return AlignmentType.RIGHT;\n case 'justify':\n return AlignmentType.JUSTIFIED;\n default:\n return AlignmentType.LEFT;\n }\n}\n\n/**\n * Convert vertical alignment string to docx VerticalAlign\n */\nfunction getVerticalAlignment(\n alignment: string | undefined\n):\n | typeof VerticalAlign.TOP\n | typeof VerticalAlign.CENTER\n | typeof VerticalAlign.BOTTOM\n | undefined {\n if (!alignment) return undefined;\n\n switch (alignment) {\n case 'top':\n return VerticalAlign.TOP;\n case 'middle':\n return VerticalAlign.CENTER;\n case 'bottom':\n return VerticalAlign.BOTTOM;\n default:\n return undefined;\n }\n}\n\n/**\n * Create header element from content\n */\nexport function createHeaderElement(\n children: (Paragraph | Table)[],\n _options?: {\n position?: 'left' | 'center' | 'right';\n }\n): Header {\n return new Header({\n children: children,\n });\n}\n\n/**\n * Create footer element from content\n */\nexport function createFooterElement(\n children: (Paragraph | Table)[],\n _options?: {\n position?: 'left' | 'center' | 'right';\n }\n): Footer {\n return new Footer({\n children: children,\n });\n}\n\n/**\n * Create page number element\n */\nexport function createPageNumberElement(\n format?: string,\n alignment?: 'left' | 'center' | 'right'\n): Paragraph {\n const children: PlaceholderChild[] = [];\n\n if (format) {\n // Use placeholder processor to handle {PAGE} and other placeholders\n children.push(...processTextWithPlaceholders(format, {}));\n } else {\n // Default: just page number\n children.push(\n new TextRun({\n children: [PageNumber.CURRENT],\n })\n );\n }\n\n return new Paragraph({\n alignment: getAlignment(alignment || 'center'),\n children,\n });\n}\n\n/**\n * Create mixed content paragraph with text and image elements\n */\nexport async function createMixedContentParagraph(\n textContent: string,\n textOptions: {\n fontSize?: number;\n color?: string;\n bold?: boolean;\n italic?: boolean;\n },\n imagePath?: string,\n imageOptions?: {\n width?: number;\n height?: number;\n },\n alignment?: 'left' | 'center' | 'right',\n theme?: import('../styles').ThemeConfig\n): Promise<Paragraph> {\n const children: (TextRun | ImageRun)[] = [];\n const normalizedTextContent = normalizeUnicodeText(textContent);\n\n // Add text content\n if (normalizedTextContent) {\n children.push(\n new TextRun({\n text: normalizedTextContent,\n font: theme ? getThemeFonts(theme).body.family : undefined,\n size: textOptions.fontSize ? textOptions.fontSize * 2 : 20, // Convert to half-points\n color:\n textOptions.color ||\n (theme ? getThemeColors(theme).textPrimary : undefined),\n bold: textOptions.bold || false,\n italics: textOptions.italic || false,\n })\n );\n }\n\n // Add image if provided\n if (imagePath) {\n try {\n const imageResult = await getImageBuffer(imagePath);\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imagePath,\n imageOptions?.width,\n imageOptions?.height,\n 60, // fallback width\n 20 // fallback height\n );\n\n const imgType = detectImageType(imagePath, imageResult.contentType);\n const imageRun = createTypedImageRun({\n type: imgType,\n data: imageResult.buffer,\n transformation: { width: dimensions.width, height: dimensions.height },\n });\n\n // Add some spacing before the image\n children.push(new TextRun({ text: ' ' }));\n children.push(imageRun);\n } catch (error) {\n // Fallback for missing images\n children.push(\n new TextRun({\n text: ` [IMAGE: ${imagePath}]`,\n font: theme ? getThemeFonts(theme).body.family : undefined,\n size: (textOptions.fontSize || 10) * 2,\n color: theme ? getThemeColors(theme).secondary : undefined,\n bold: true,\n })\n );\n }\n }\n\n return new Paragraph({\n alignment: getAlignment(alignment || 'left'),\n children,\n });\n}\n\n/**\n * Create a table specifically for headers/footers with custom styling\n */\n\nexport async function createHeaderFooterTable(\n rows: (string | ComponentDefinition)[][],\n options: {\n cellAlignments?: ('left' | 'center' | 'right')[];\n fontSize?: number;\n bold?: boolean;\n color?: string;\n noBorders?: boolean;\n cellStyling?: {\n [rowIndex: number]: {\n [cellIndex: number]: {\n bold?: boolean;\n color?: string;\n fontSize?: number;\n };\n };\n };\n theme?: ThemeConfig;\n themeName?: string;\n } = {}\n): Promise<Table> {\n const {\n cellAlignments = ['left', 'right'],\n fontSize = 10,\n bold = false,\n color = '#000000',\n noBorders = true,\n cellStyling = {},\n theme,\n } = options;\n\n // Use theme's normal style for header/footer text since header/footer styles are removed\n const normalStyle = theme?.styles?.normal;\n\n const defaultFont = theme\n ? resolveFontFamily(theme, normalStyle?.font)\n : 'Arial';\n const defaultSize = normalStyle?.size || fontSize;\n const defaultColor =\n normalStyle?.color && theme\n ? resolveColor(normalStyle.color, theme)\n : color;\n\n const tableRows = await Promise.all(\n rows.map(\n async (row, rowIndex) =>\n new TableRow({\n children: await Promise.all(\n row.map(async (cell, cellIndex) => {\n const alignment = cellAlignments[cellIndex] || 'left';\n const cellStyle = cellStyling[rowIndex]?.[cellIndex] || {};\n\n let paragraphChildren: (PlaceholderChild | ImageRun)[] = [];\n\n // Handle ComponentDefinition first\n if (\n typeof cell === 'object' &&\n 'name' in cell &&\n 'props' in cell\n ) {\n // This is a ComponentDefinition\n if (isParagraphComponent(cell)) {\n const textComp = cell as ParagraphComponentDefinition;\n // Use parseTextWithDecorators to support rich text formatting\n const textStyle = {\n font:\n textComp.props.font?.family || (defaultFont as string),\n size:\n ((textComp.props.font?.size || defaultSize) as number) *\n 2, // Convert to half-points\n bold: textComp.props.font?.bold ?? false,\n color:\n (textComp.props.font?.color && theme\n ? resolveColor(textComp.props.font.color, theme)\n : undefined) || defaultColor,\n } as const;\n paragraphChildren = parseTextWithDecorators(\n textComp.props.text,\n textStyle,\n { enableHyperlinks: true }\n );\n } else if (isImageComponent(cell)) {\n const imageComp = cell as ImageComponentDefinition;\n try {\n // Get image source (svg, base64, or path)\n const imageSource = resolveImageSource(imageComp.props);\n if (!imageSource) {\n throw new Error(\n 'Image component requires one of \"path\", \"base64\", or \"svg\" property'\n );\n }\n\n // Read from local file, URL, or base64\n const imageResult = await getImageBuffer(imageSource);\n\n // Parse width value if it's a string percentage (like \"90%\")\n const parsedWidth =\n typeof imageComp.props.width === 'string'\n ? parseWidthValue(imageComp.props.width, 300) // Use a reasonable default for table context\n : imageComp.props.width;\n\n // Parse height value if it's a string percentage (like \"90%\")\n const parsedHeight =\n typeof imageComp.props.height === 'string'\n ? parseWidthValue(imageComp.props.height, 200) // Use a reasonable default for table context\n : imageComp.props.height;\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imageSource,\n parsedWidth,\n parsedHeight,\n 60, // fallback width\n 20 // fallback height\n );\n\n const imgType = detectImageType(\n imageSource,\n imageResult.contentType\n );\n const imageRun = createTypedImageRun({\n type: imgType,\n data: imageResult.buffer,\n transformation: {\n width: dimensions.width,\n height: dimensions.height,\n },\n });\n paragraphChildren = [imageRun];\n } catch (error) {\n // Fallback for missing images\n const imageSource = imageComp.props.svg?.trim()\n ? 'inline-svg'\n : imageComp.props.base64 ||\n imageComp.props.path ||\n 'unknown';\n paragraphChildren = [\n new TextRun({\n text: `[IMAGE: ${imageSource.substring(0, 50)}${imageSource.length > 50 ? '...' : ''}]`,\n size: fontSize * 2,\n bold: true,\n color: '#999999',\n }),\n ];\n }\n } else {\n // Unsupported component type in table cell\n paragraphChildren = [\n new TextRun({\n text: `[Unsupported component type: ${cell.name}]`,\n size: fontSize * 2,\n color: '#999999',\n }),\n ];\n }\n } else if (typeof cell === 'string') {\n // Handle plain string text (including placeholders)\n const textStyle = {\n font: defaultFont,\n size: (cellStyle.fontSize || defaultSize) * 2,\n bold: cellStyle.bold !== undefined ? cellStyle.bold : bold,\n color: cellStyle.color || defaultColor,\n };\n\n // Use parseTextWithDecorators which now handles both decorators and placeholders\n paragraphChildren = parseTextWithDecorators(cell, textStyle, {\n enableHyperlinks: true,\n });\n }\n\n return new TableCell({\n children: [\n new Paragraph({\n alignment: getAlignment(alignment),\n children: paragraphChildren,\n }),\n ],\n margins: {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n borders: noBorders\n ? {\n top: { style: BorderStyle.NONE, size: 0 },\n bottom: { style: BorderStyle.NONE, size: 0 },\n left: { style: BorderStyle.NONE, size: 0 },\n right: { style: BorderStyle.NONE, size: 0 },\n }\n : undefined,\n });\n })\n ),\n })\n )\n );\n\n return new Table({\n width: { size: 100, type: WidthType.PERCENTAGE },\n layout: TableLayoutType.FIXED, // Lock column widths to prevent horizontal resizing\n rows: tableRows,\n borders: noBorders\n ? {\n top: { style: BorderStyle.NONE, size: 0 },\n bottom: { style: BorderStyle.NONE, size: 0 },\n left: { style: BorderStyle.NONE, size: 0 },\n right: { style: BorderStyle.NONE, size: 0 },\n insideHorizontal: { style: BorderStyle.NONE, size: 0 },\n insideVertical: { style: BorderStyle.NONE, size: 0 },\n }\n : undefined,\n });\n}\n","/**\n * Bookmark Registry\n * Utilities for managing document bookmarks for internal hyperlinks\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface BookmarkInfo {\n id: string;\n title: string;\n type: string; // e.g., 'heading', 'paragraph', 'table', etc.\n}\n\ninterface BookmarkState {\n bookmarks: Map<string, BookmarkInfo>;\n}\n\n/**\n * Registry for managing document bookmarks\n * Used to track bookmark IDs and validate internal hyperlink targets\n */\nexport class BookmarkRegistry {\n private readonly fallback: BookmarkState = { bookmarks: new Map() };\n private readonly scopes = new AsyncLocalStorage<BookmarkState>();\n\n private get state(): BookmarkState {\n return this.scopes.getStore() ?? this.fallback;\n }\n\n /** Run work with an isolated registry that follows its async call chain. */\n runScoped<T>(callback: () => T): T {\n return this.scopes.run({ bookmarks: new Map() }, callback);\n }\n\n /**\n * Register a bookmark\n */\n register(id: string, title: string, type: string): void {\n if (this.state.bookmarks.has(id)) {\n console.warn(\n `Duplicate bookmark ID: ${id}. Using the latest registration.`\n );\n }\n this.state.bookmarks.set(id, { id, title, type });\n }\n\n /**\n * Generate a unique bookmark ID from text\n * Converts text to a URL-friendly format\n */\n generateId(text: string, _type: string = 'bookmark'): string {\n // Convert to lowercase, replace spaces with hyphens, remove special characters\n const baseId = text\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .substring(0, 40); // Limit length\n\n // Ensure uniqueness by appending counter if needed\n let id = baseId;\n let attempt = 0;\n while (this.state.bookmarks.has(id) && attempt < 100) {\n id = `${baseId}-${++attempt}`;\n }\n\n return id;\n }\n\n /**\n * Check if a bookmark exists\n */\n exists(id: string): boolean {\n return this.state.bookmarks.has(id);\n }\n\n /**\n * Get bookmark info by ID\n */\n get(id: string): BookmarkInfo | undefined {\n return this.state.bookmarks.get(id);\n }\n\n /**\n * Get all registered bookmarks\n */\n getAll(): BookmarkInfo[] {\n return Array.from(this.state.bookmarks.values());\n }\n\n /**\n * Clear all bookmarks\n */\n clear(): void {\n this.state.bookmarks.clear();\n }\n\n /**\n * Validate that all internal hyperlink references exist\n * Returns array of missing bookmark IDs\n */\n validateReferences(referencedIds: string[]): string[] {\n const missing: string[] = [];\n for (const id of referencedIds) {\n if (!this.exists(id)) {\n missing.push(id);\n }\n }\n return missing;\n }\n}\n\n// Global registry instance\nexport const globalBookmarkRegistry = new BookmarkRegistry();\n","/**\n * Heading Component\n * Standard component for rendering heading elements in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isHeadingComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createHeading } from '../core/content';\nimport { globalBookmarkRegistry } from '../utils/bookmarkRegistry';\n\n/**\n * Render heading component\n */\nexport function renderHeadingComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): Paragraph[] {\n if (!isHeadingComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree (componentDefaults + level-specific defaults)\n const config = component.props;\n\n // Generate or use bookmark ID for internal linking\n // If component has id, use it; otherwise generate from heading text\n const bookmarkId =\n (component as any).id ||\n globalBookmarkRegistry.generateId(config.text, 'heading');\n\n // Create heading with optional column break and bookmark\n const header = createHeading(\n config.text,\n config.level || 1,\n theme,\n themeName,\n {\n alignment: config.alignment,\n spacing: config.spacing,\n lineSpacing: config.lineSpacing,\n columnBreak: config.columnBreak,\n // Local font overrides\n fontFamily: config.font?.family,\n fontSize: config.font?.size,\n fontColor: config.font?.color,\n bold: config.font?.bold,\n fontWeight: (config.font as { fontWeight?: number } | undefined)\n ?.fontWeight,\n italic: config.font?.italic,\n underline: config.font?.underline,\n scale: config.font?.scale,\n characterSpacing: config.font?.characterSpacing,\n // Proofing: local language override + no-proof toggle + known-words list\n language: config.language,\n noProof: config.noProof,\n noProofWords: config.noProofWords,\n // Pagination control\n keepNext: config.keepNext,\n keepLines: config.keepLines,\n // Paragraph indentation (w:ind) in twips\n indent: config.indent,\n // Bookmark ID for internal linking\n bookmarkId: bookmarkId,\n // Tracked-change segments (rendered as native Word revisions)\n revision: config.revision,\n }\n );\n\n return [header];\n}\n","/**\n * Numbering Configuration Utilities\n * Utilities for creating and managing docx numbering configurations\n */\n\nimport { AlignmentType, convertInchesToTwip, LevelFormat } from 'docx';\nimport type { ILevelsOptions } from 'docx';\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\n// Type mapping from schema strings to docx LevelFormat values\nconst LEVEL_FORMAT_MAP: Record<\n string,\n (typeof LevelFormat)[keyof typeof LevelFormat]\n> = {\n decimal: LevelFormat.DECIMAL,\n upperRoman: LevelFormat.UPPER_ROMAN,\n lowerRoman: LevelFormat.LOWER_ROMAN,\n upperLetter: LevelFormat.UPPER_LETTER,\n lowerLetter: LevelFormat.LOWER_LETTER,\n bullet: LevelFormat.BULLET,\n ordinal: LevelFormat.ORDINAL,\n cardinalText: LevelFormat.CARDINAL_TEXT,\n ordinalText: LevelFormat.ORDINAL_TEXT,\n hex: LevelFormat.HEX,\n chicago: LevelFormat.CHICAGO,\n ideographDigital: LevelFormat.IDEOGRAPH__DIGITAL,\n japaneseCounting: LevelFormat.JAPANESE_COUNTING,\n aiueo: LevelFormat.AIUEO,\n iroha: LevelFormat.IROHA,\n decimalFullWidth: LevelFormat.DECIMAL_FULL_WIDTH,\n decimalHalfWidth: LevelFormat.DECIMAL_HALF_WIDTH,\n japaneseLegal: LevelFormat.JAPANESE_LEGAL,\n japaneseDigitalTenThousand: LevelFormat.JAPANESE_DIGITAL_TEN_THOUSAND,\n decimalEnclosedCircle: LevelFormat.DECIMAL_ENCLOSED_CIRCLE,\n decimalFullWidth2: LevelFormat.DECIMAL_FULL_WIDTH2,\n aiueoFullWidth: LevelFormat.AIUEO_FULL_WIDTH,\n irohaFullWidth: LevelFormat.IROHA_FULL_WIDTH,\n decimalZero: LevelFormat.DECIMAL_ZERO,\n ganada: LevelFormat.GANADA,\n chosung: LevelFormat.CHOSUNG,\n decimalEnclosedFullstop: LevelFormat.DECIMAL_ENCLOSED_FULLSTOP,\n decimalEnclosedParen: LevelFormat.DECIMAL_ENCLOSED_PARENTHESES,\n decimalEnclosedCircleChinese: LevelFormat.DECIMAL_ENCLOSED_CIRCLE_CHINESE,\n ideographEnclosedCircle: LevelFormat.IDEOGRAPH_ENCLOSED_CIRCLE,\n ideographTraditional: LevelFormat.IDEOGRAPH_TRADITIONAL,\n ideographZodiac: LevelFormat.IDEOGRAPH_ZODIAC,\n ideographZodiacTraditional: LevelFormat.IDEOGRAPH_ZODIAC_TRADITIONAL,\n taiwaneseCounting: LevelFormat.TAIWANESE_COUNTING,\n ideographLegalTraditional: LevelFormat.IDEOGRAPH_LEGAL_TRADITIONAL,\n taiwaneseCountingThousand: LevelFormat.TAIWANESE_COUNTING_THOUSAND,\n taiwaneseDigital: LevelFormat.TAIWANESE_DIGITAL,\n chineseCounting: LevelFormat.CHINESE_COUNTING,\n chineseLegalSimplified: LevelFormat.CHINESE_LEGAL_SIMPLIFIED,\n chineseCountingThousand: LevelFormat.CHINESE_COUNTING_THOUSAND,\n koreanDigital: LevelFormat.KOREAN_DIGITAL,\n koreanCounting: LevelFormat.KOREAN_COUNTING,\n koreanLegal: LevelFormat.KOREAN_LEGAL,\n koreanDigital2: LevelFormat.KOREAN_DIGITAL2,\n vietnameseCounting: LevelFormat.VIETNAMESE_COUNTING,\n russianLower: LevelFormat.RUSSIAN_LOWER,\n russianUpper: LevelFormat.RUSSIAN_UPPER,\n none: LevelFormat.NONE,\n numberInDash: LevelFormat.NUMBER_IN_DASH,\n hebrew1: LevelFormat.HEBREW1,\n hebrew2: LevelFormat.HEBREW2,\n arabicAlpha: LevelFormat.ARABIC_ALPHA,\n arabicAbjad: LevelFormat.ARABIC_ABJAD,\n hindiVowels: LevelFormat.HINDI_VOWELS,\n hindiConsonants: LevelFormat.HINDI_CONSONANTS,\n hindiNumbers: LevelFormat.HINDI_NUMBERS,\n hindiCounting: LevelFormat.HINDI_COUNTING,\n thaiLetters: LevelFormat.THAI_LETTERS,\n thaiNumbers: LevelFormat.THAI_NUMBERS,\n thaiCounting: LevelFormat.THAI_COUNTING,\n};\n\nconst ALIGNMENT_MAP: Record<\n string,\n (typeof AlignmentType)[keyof typeof AlignmentType]\n> = {\n start: AlignmentType.START,\n end: AlignmentType.END,\n left: AlignmentType.LEFT,\n right: AlignmentType.RIGHT,\n center: AlignmentType.CENTER,\n};\n\nexport interface ListLevelConfig {\n level: number;\n format?: string;\n text?: string;\n alignment?: string;\n indent?: {\n left?: number;\n hanging?: number;\n };\n start?: number;\n}\n\nexport interface NumberingConfig {\n reference: string;\n levels: ListLevelConfig[];\n}\n\ntype RegisteredNumberingConfig = {\n levels: ILevelsOptions[];\n reference: string;\n};\n\ninterface NumberingState {\n configs: Map<string, RegisteredNumberingConfig>;\n counter: number;\n}\n\n/**\n * Convert schema format string to docx LevelFormat\n */\nfunction getLevelFormat(\n format?: string\n): (typeof LevelFormat)[keyof typeof LevelFormat] {\n if (!format) return LevelFormat.BULLET;\n return LEVEL_FORMAT_MAP[format] || LevelFormat.BULLET;\n}\n\n/**\n * Convert schema alignment string to docx AlignmentType\n */\nfunction getAlignment(\n alignment?: string\n): (typeof AlignmentType)[keyof typeof AlignmentType] {\n if (!alignment) return AlignmentType.LEFT;\n return ALIGNMENT_MAP[alignment] || AlignmentType.LEFT;\n}\n\n/**\n * Create a default level configuration for a given level number\n */\nfunction createDefaultLevel(\n level: number,\n format: (typeof LevelFormat)[keyof typeof LevelFormat] = LevelFormat.BULLET,\n text?: string\n): ILevelsOptions {\n const baseIndent = 0.5 * (level + 1); // Increase indent for each level\n const hangingIndent = 0.25;\n\n return {\n level,\n format,\n text: text || (format === LevelFormat.BULLET ? '•' : '%1.'),\n alignment: AlignmentType.LEFT,\n style: {\n paragraph: {\n indent: {\n left: convertInchesToTwip(baseIndent),\n hanging: convertInchesToTwip(hangingIndent),\n },\n },\n },\n };\n}\n\n/**\n * Create numbering configuration from list config\n * Returns a single config item that can be added to INumberingOptions.config array\n */\nexport function createNumberingConfig(config: NumberingConfig): {\n levels: ILevelsOptions[];\n reference: string;\n} {\n const levels: ILevelsOptions[] = [];\n\n // Process each level\n for (const levelConfig of config.levels) {\n const format = getLevelFormat(levelConfig.format);\n const alignment = getAlignment(levelConfig.alignment);\n const text =\n levelConfig.text ||\n (format === LevelFormat.BULLET ? '•' : `%${levelConfig.level + 1}.`);\n\n // Calculate indentation\n const baseIndent =\n levelConfig.indent?.left !== undefined\n ? levelConfig.indent.left / 72 // Convert points to inches\n : 0.5 * (levelConfig.level + 1);\n\n const hangingIndent =\n levelConfig.indent?.hanging !== undefined\n ? levelConfig.indent.hanging / 72 // Convert points to inches\n : 0.25;\n\n const level: ILevelsOptions = {\n level: levelConfig.level,\n format,\n text,\n alignment,\n style: {\n paragraph: {\n indent: {\n left: convertInchesToTwip(baseIndent),\n hanging: convertInchesToTwip(hangingIndent),\n },\n },\n },\n // Add start number if specified\n ...(levelConfig.start !== undefined && { start: levelConfig.start }),\n };\n\n levels.push(level);\n }\n\n return {\n reference: config.reference,\n levels,\n };\n}\n\n/**\n * Create a simple bullet list configuration\n */\nexport function createBulletListConfig(\n reference: string,\n bullet: string = '•'\n): { levels: ILevelsOptions[]; reference: string } {\n return {\n reference,\n levels: [\n createDefaultLevel(0, LevelFormat.BULLET, bullet),\n createDefaultLevel(1, LevelFormat.BULLET, '◦'),\n createDefaultLevel(2, LevelFormat.BULLET, '▪'),\n ],\n };\n}\n\n/**\n * Create a simple numbered list configuration\n */\nexport function createNumberedListConfig(\n reference: string,\n start: number = 1\n): { levels: ILevelsOptions[]; reference: string } {\n return {\n reference,\n levels: [\n { ...createDefaultLevel(0, LevelFormat.DECIMAL, '%1.'), start },\n createDefaultLevel(1, LevelFormat.LOWER_LETTER, '%2.'),\n createDefaultLevel(2, LevelFormat.LOWER_ROMAN, '%3.'),\n ],\n };\n}\n\n/**\n * Registry for managing numbering configurations\n */\nexport class NumberingRegistry {\n private readonly fallback: NumberingState = {\n configs: new Map(),\n counter: 0,\n };\n private readonly scopes = new AsyncLocalStorage<NumberingState>();\n\n private get state(): NumberingState {\n return this.scopes.getStore() ?? this.fallback;\n }\n\n /** Run work with an isolated registry that follows its async call chain. */\n runScoped<T>(callback: () => T): T {\n return this.scopes.run({ configs: new Map(), counter: 0 }, callback);\n }\n\n /**\n * Register a numbering configuration\n */\n register(config: { levels: ILevelsOptions[]; reference: string }): string {\n const reference = config.reference;\n this.state.configs.set(reference, config);\n return reference;\n }\n\n /**\n * Generate a unique reference ID\n */\n generateReference(prefix: string = 'list'): string {\n return `${prefix}-${++this.state.counter}`;\n }\n\n /**\n * Get all registered configurations as an array suitable for INumberingOptions\n */\n getAll(): { levels: ILevelsOptions[]; reference: string }[] {\n return Array.from(this.state.configs.values());\n }\n\n /**\n * Clear all configurations\n */\n clear(): void {\n this.state.configs.clear();\n this.state.counter = 0;\n }\n\n /**\n * Check if a reference exists\n */\n has(reference: string): boolean {\n return this.state.configs.has(reference);\n }\n\n /**\n * Get a configuration by reference\n */\n get(\n reference: string\n ): { levels: ILevelsOptions[]; reference: string } | undefined {\n return this.state.configs.get(reference);\n }\n}\n\n// Global registry instance\nexport const globalNumberingRegistry = new NumberingRegistry();\n","/**\n * Paragraph Component\n * Standard component for rendering paragraph content in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isParagraphComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createText, createList } from '../core/content';\nimport {\n globalNumberingRegistry,\n createNumberingConfig,\n type NumberingConfig,\n type ListLevelConfig,\n} from '../utils/numberingConfig';\n\n/**\n * Parse markdown list syntax from paragraph text\n * Returns null if no list detected, or { type, items } if list found\n */\nfunction parseMarkdownList(text: string): {\n type: 'unordered' | 'ordered';\n items: { text: string; level: number }[];\n} | null {\n const lines = text.split('\\n');\n const items: { text: string; level: number }[] = [];\n let isUnordered: boolean | null = null;\n let isOrdered: boolean | null = null;\n\n for (const line of lines) {\n // Skip empty lines\n if (!line.trim()) continue;\n\n // Match unordered list: optional spaces + (- or *) + space + text\n const unorderedMatch = line.match(/^(\\s*)([-*])\\s+(.+)$/);\n if (unorderedMatch) {\n const indentLevel = Math.floor(unorderedMatch[1].length / 2); // 2 spaces = 1 level\n const text = unorderedMatch[3];\n items.push({ text, level: indentLevel });\n if (isUnordered === null) isUnordered = true;\n continue;\n }\n\n // Match ordered list: optional spaces + number + . + space + text\n const orderedMatch = line.match(/^(\\s*)(\\d+)\\.\\s+(.+)$/);\n if (orderedMatch) {\n const indentLevel = Math.floor(orderedMatch[1].length / 2); // 2 spaces = 1 level\n const text = orderedMatch[3];\n items.push({ text, level: indentLevel });\n if (isOrdered === null) isOrdered = true;\n continue;\n }\n\n // If we find a line that doesn't match list syntax, this isn't a list\n return null;\n }\n\n // If no items found, or mixed list types, not a valid list\n if (items.length === 0 || (isUnordered && isOrdered)) {\n return null;\n }\n\n return {\n type: isUnordered ? 'unordered' : 'ordered',\n items,\n };\n}\n\n/**\n * Render paragraph component\n */\nexport function renderParagraphComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): Paragraph[] {\n if (!isParagraphComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree\n const resolvedConfig = component.props;\n\n // Check if text contains markdown list syntax.\n // Revision paragraphs always render as plain text: their segments carry\n // literal text and cannot be re-split into list items.\n const listData = resolvedConfig.revision\n ? null\n : parseMarkdownList(resolvedConfig.text);\n\n if (listData) {\n // Text is a markdown list - render as proper docx list\n const reference =\n globalNumberingRegistry.generateReference('markdown-list');\n\n // Create appropriate numbering configuration\n const levels: ListLevelConfig[] = [];\n\n if (listData.type === 'unordered') {\n // Bullet list with different bullets for each level\n levels.push(\n { level: 0, format: 'bullet', text: '•', alignment: 'left' },\n { level: 1, format: 'bullet', text: '◦', alignment: 'left' },\n { level: 2, format: 'bullet', text: '▪', alignment: 'left' }\n );\n } else {\n // Ordered list with decimal, lowercase letter, lowercase roman\n levels.push(\n { level: 0, format: 'decimal', text: '%1.', alignment: 'left' },\n { level: 1, format: 'lowerLetter', text: '%2.', alignment: 'left' },\n { level: 2, format: 'lowerRoman', text: '%3.', alignment: 'left' }\n );\n }\n\n const numberingConfig: NumberingConfig = {\n reference,\n levels,\n };\n\n globalNumberingRegistry.register(createNumberingConfig(numberingConfig));\n\n // Create list paragraphs\n return createList(listData.items, theme, themeName, {\n numberingReference: reference,\n spacing: resolvedConfig.spacing as\n | { before?: number; after?: number; item?: number }\n | undefined,\n alignment: resolvedConfig.alignment,\n });\n }\n\n // Not a list - render as regular text paragraph\n // Map themeStyle (theme logical name) to DOCX style id\n // Supports both predefined styles and custom styles from theme.styles\n const styleFromTheme = (() => {\n const key = resolvedConfig.themeStyle;\n if (!key) return undefined;\n\n const lowerKey = key.toLowerCase();\n\n // Map predefined style names to Word style IDs\n if (lowerKey === 'normal') return 'Normal';\n if (lowerKey === 'title') return 'Title';\n if (lowerKey === 'subtitle') return 'Subtitle';\n const headingMatch = lowerKey.match(/^heading([1-6])$/);\n if (headingMatch) {\n // For paragraph components, use display-only heading styles that are visually\n // identical but do NOT participate in TOC/outline levels\n return `JTD_HeadingText${headingMatch[1]}`;\n }\n\n // For custom styles, use the exact key as the style ID\n // Custom styles are registered in themeToDocxAdapter with their exact key as ID\n return key;\n })();\n\n // Extract outline level from style if present (for TOC support)\n const outlineLevel = (() => {\n const key = resolvedConfig.themeStyle;\n if (!key) return undefined;\n\n // Never contribute paragraph component paragraphs to TOC when using heading styles\n // Even if the theme sets outlineLevel for heading styles, ignore it here\n const lowerKey = key.toLowerCase();\n const headingMatch = lowerKey.match(/^heading([1-6])$/);\n if (headingMatch) return undefined;\n\n // Check if this is a custom style with outline level\n const customStyle = theme.styles?.[key as keyof typeof theme.styles];\n if (\n customStyle &&\n typeof customStyle === 'object' &&\n 'outlineLevel' in customStyle\n ) {\n return (customStyle as any).outlineLevel;\n }\n\n return undefined;\n })();\n\n // Create text paragraph with optional column break and floating positioning\n const text = createText(resolvedConfig.text, theme, themeName, {\n style: styleFromTheme,\n spacing: resolvedConfig.spacing as\n | { before?: number; after?: number }\n | undefined,\n lineSpacing: resolvedConfig.font?.lineSpacing,\n alignment: resolvedConfig.alignment,\n boldColor: resolvedConfig.boldColor,\n columnBreak: resolvedConfig.columnBreak,\n // Pass font properties\n fontFamily: resolvedConfig.font?.family,\n fontSize: resolvedConfig.font?.size,\n fontColor: resolvedConfig.font?.color,\n bold: resolvedConfig.font?.bold,\n fontWeight: (resolvedConfig.font as { fontWeight?: number } | undefined)\n ?.fontWeight,\n italic: resolvedConfig.font?.italic,\n underline: resolvedConfig.font?.underline,\n scale: resolvedConfig.font?.scale,\n characterSpacing: resolvedConfig.font?.characterSpacing,\n // Proofing: local language override + no-proof toggle + known-words list\n language: resolvedConfig.language,\n noProof: resolvedConfig.noProof,\n noProofWords: resolvedConfig.noProofWords,\n // Pass outline level for TOC support\n outlineLevel: outlineLevel,\n // Pass floating positioning properties\n floating: resolvedConfig.floating,\n // Pass keepNext property\n keepNext: resolvedConfig.keepNext,\n // Pass keepLines property\n keepLines: resolvedConfig.keepLines,\n // Paragraph indentation (w:ind) in twips\n indent: resolvedConfig.indent,\n // Tab stops (w:tabs); \\t characters in text jump to these positions\n tabStops: resolvedConfig.tabStops,\n // Pass bookmark ID for internal linking\n bookmarkId: resolvedConfig.id,\n // Tracked-change segments (rendered as native Word revisions)\n revision: resolvedConfig.revision,\n });\n\n return [text];\n}\n","/**\n * List Component\n * Standard component for rendering list elements in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isListComponent, ListProps } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createList } from '../core/content';\nimport {\n globalNumberingRegistry,\n createNumberingConfig,\n type NumberingConfig,\n type ListLevelConfig,\n} from '../utils/numberingConfig';\n\n/**\n * Convert simplified format to proper level configurations\n */\nfunction createLevelsFromSimplifiedProps(props: ListProps): ListLevelConfig[] {\n const levels: ListLevelConfig[] = [];\n\n // Determine format from simplified options\n let format: string;\n let text: string | undefined;\n\n if (props.format) {\n if (props.format === 'numbered') {\n format = 'decimal';\n text = '%1.';\n } else if (props.format === 'none') {\n format = 'none';\n text = '';\n } else {\n format = props.format;\n }\n } else {\n // Default to bullet\n format = 'bullet';\n text = props.bullet || '•';\n }\n\n // Create level 0 configuration\n const level0: ListLevelConfig = {\n level: 0,\n format,\n text,\n alignment: 'left',\n start: props.start,\n };\n\n // Add indent if specified\n if (props.indent) {\n if (typeof props.indent === 'number') {\n level0.indent = { left: props.indent };\n } else {\n level0.indent = props.indent;\n }\n }\n\n levels.push(level0);\n\n // Add default sublevels for nested lists\n if (format === 'bullet') {\n levels.push(\n { level: 1, format: 'bullet', text: '◦', alignment: 'left' },\n { level: 2, format: 'bullet', text: '▪', alignment: 'left' }\n );\n } else if (format === 'decimal') {\n levels.push(\n { level: 1, format: 'lowerLetter', text: '%2.', alignment: 'left' },\n { level: 2, format: 'lowerRoman', text: '%3.', alignment: 'left' }\n );\n }\n\n return levels;\n}\n\n/**\n * Get the maximum level used in list items\n */\nfunction getMaxLevelFromItems(\n items: (string | { text: string; level?: number })[] | undefined\n): number {\n if (!items || !Array.isArray(items)) {\n return 0;\n }\n\n let maxLevel = 0;\n for (const item of items) {\n if (typeof item === 'object' && item.level !== undefined) {\n maxLevel = Math.max(maxLevel, item.level);\n }\n }\n return maxLevel;\n}\n\n/**\n * Fill in missing levels with default configurations\n */\nfunction fillMissingLevels(\n levels: ListLevelConfig[],\n maxLevel: number\n): ListLevelConfig[] {\n // Create a map of existing levels\n const levelMap = new Map<number, ListLevelConfig>();\n for (const level of levels) {\n levelMap.set(level.level, level);\n }\n\n // Get level 0 to determine the base format\n const level0 = levelMap.get(0);\n const baseFormat = level0?.format || 'bullet';\n\n // Create default levels for any missing ones\n const result: ListLevelConfig[] = [];\n for (let i = 0; i <= maxLevel; i++) {\n if (levelMap.has(i)) {\n result.push(levelMap.get(i)!);\n } else {\n // Create default sublevel based on parent format\n if (baseFormat === 'bullet') {\n const bullets = ['•', '◦', '▪', '▫', '‣'];\n result.push({\n level: i,\n format: 'bullet',\n text: bullets[i % bullets.length],\n alignment: 'left',\n });\n } else if (baseFormat === 'decimal' || baseFormat === 'numbered') {\n const formats = ['decimal', 'lowerLetter', 'lowerRoman'];\n const format = formats[i % formats.length];\n result.push({\n level: i,\n format,\n text: `%${i + 1}.`,\n alignment: 'left',\n });\n } else {\n // For other formats, continue with the same format\n result.push({\n level: i,\n format: baseFormat,\n text: `%${i + 1}.`,\n alignment: 'left',\n });\n }\n }\n }\n\n return result;\n}\n\n/**\n * Render list component\n */\nexport function renderListComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): Paragraph[] {\n if (!isListComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree\n const resolvedConfig = component.props;\n\n // Determine the maximum level needed from items\n const maxLevel = getMaxLevelFromItems(resolvedConfig.items);\n\n // Generate or use provided reference ID\n const reference =\n resolvedConfig.reference ||\n globalNumberingRegistry.generateReference('list');\n\n // Build numbering configuration if not already registered\n if (!globalNumberingRegistry.has(reference)) {\n let levels: ListLevelConfig[];\n\n if (resolvedConfig.levels && resolvedConfig.levels.length > 0) {\n // Use explicit level configurations, filling in missing levels\n levels = fillMissingLevels(\n resolvedConfig.levels as ListLevelConfig[],\n maxLevel\n );\n } else {\n // Build from simplified options\n const baseLevels = createLevelsFromSimplifiedProps(resolvedConfig);\n levels = fillMissingLevels(baseLevels, maxLevel);\n }\n\n const config: NumberingConfig = {\n reference,\n levels,\n };\n const numberingConfig = createNumberingConfig(config);\n globalNumberingRegistry.register(numberingConfig);\n }\n\n // Create the list paragraphs with numbering reference\n return createList(resolvedConfig.items, theme, themeName, {\n numberingReference: reference,\n spacing: resolvedConfig.spacing,\n alignment: resolvedConfig.alignment,\n });\n}\n","/**\n * Image Component\n * Standard component for rendering images in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isImageComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createImage } from '../core/content';\nimport { resolveImageSource } from '../utils/imageUtils';\n\n/**\n * Render image component\n */\nexport async function renderImageComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName?: string\n): Promise<Paragraph[]> {\n if (!isImageComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree\n const resolvedConfig = component.props;\n\n // Resolve source: inline svg > base64 > path\n const imageSource = resolveImageSource(resolvedConfig);\n\n if (!imageSource) {\n throw new Error(\n 'Image component requires one of \"path\", \"base64\", or \"svg\" property'\n );\n }\n\n return await createImage(imageSource, theme, themeName, {\n caption: resolvedConfig.caption,\n width: resolvedConfig.width,\n height: resolvedConfig.height,\n widthRelativeTo: (resolvedConfig as any).widthRelativeTo,\n heightRelativeTo: (resolvedConfig as any).heightRelativeTo,\n alignment: resolvedConfig.alignment,\n spacing: resolvedConfig.spacing,\n floating: resolvedConfig.floating,\n keepNext: resolvedConfig.keepNext,\n keepLines: resolvedConfig.keepLines,\n });\n}\n","/**\n * Text Box Component\n * Floating container that groups child paragraphs (from text/image components)\n */\n\nimport {\n Paragraph,\n Table,\n TableRow,\n TableCell,\n WidthType,\n TableAnchorType,\n RelativeHorizontalPosition,\n RelativeVerticalPosition,\n OverlapType,\n TableLayoutType,\n} from 'docx';\nimport {\n ComponentDefinition,\n TextBoxComponentDefinition,\n isTextBoxComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\n// No direct image or text parsing here; children components render themselves\nimport { renderComponent } from '../core/render';\nimport { NONE_BORDERS } from '../styles/utils/borderUtils';\nimport { buildCellOptions, CellStyleConfig } from '../styles/utils/cellUtils';\nimport {\n resolveOffsetTwips,\n getPageWidthTwips,\n getPageHeightTwips,\n getAvailableWidthTwips,\n getAvailableHeightTwips,\n} from '../utils/widthUtils';\n\n// VML style helpers removed in favor of floating table approach\n\n// Map floating config to docx paragraph frame options to enforce wrapping at paragraph level\n\n// Map floating config to table float options for a one-cell table container\nfunction mapTableFloatOptions(\n floating?: NonNullable<TextBoxComponentDefinition['props']['floating']>,\n theme?: ThemeConfig,\n themeName?: string\n): any | undefined {\n if (!floating) return undefined;\n\n const opt: any = {};\n\n // Determine reference dimensions for percentage resolution\n const hRelative = floating.horizontalPosition?.relative;\n const vRelative = floating.verticalPosition?.relative;\n const hRef =\n hRelative && hRelative !== 'page'\n ? getAvailableWidthTwips(theme, themeName)\n : getPageWidthTwips(theme, themeName);\n const vRef =\n vRelative && vRelative !== 'page'\n ? getAvailableHeightTwips(theme, themeName)\n : getPageHeightTwips(theme, themeName);\n\n const hp = floating.horizontalPosition;\n if (hp?.relative) {\n opt.horizontalAnchor =\n hp.relative === 'margin'\n ? TableAnchorType.MARGIN\n : hp.relative === 'page'\n ? TableAnchorType.PAGE\n : TableAnchorType.TEXT;\n }\n if (hp?.offset !== undefined) {\n opt.absoluteHorizontalPosition = resolveOffsetTwips(hp.offset, hRef);\n } else if (hp?.align) {\n const map: Record<\n string,\n (typeof RelativeHorizontalPosition)[keyof typeof RelativeHorizontalPosition]\n > = {\n left: RelativeHorizontalPosition.LEFT,\n center: RelativeHorizontalPosition.CENTER,\n right: RelativeHorizontalPosition.RIGHT,\n inside: RelativeHorizontalPosition.INSIDE,\n outside: RelativeHorizontalPosition.OUTSIDE,\n };\n opt.relativeHorizontalPosition = map[hp.align];\n }\n\n const vp = floating.verticalPosition;\n if (vp?.relative) {\n opt.verticalAnchor =\n vp.relative === 'margin'\n ? TableAnchorType.MARGIN\n : vp.relative === 'page'\n ? TableAnchorType.PAGE\n : TableAnchorType.TEXT;\n }\n if (vp?.offset !== undefined) {\n opt.absoluteVerticalPosition = resolveOffsetTwips(vp.offset, vRef);\n } else if (vp?.align) {\n const mapV: Record<\n string,\n (typeof RelativeVerticalPosition)[keyof typeof RelativeVerticalPosition]\n > = {\n top: RelativeVerticalPosition.TOP,\n center: RelativeVerticalPosition.CENTER,\n bottom: RelativeVerticalPosition.BOTTOM,\n inside: RelativeVerticalPosition.INSIDE,\n outside: RelativeVerticalPosition.OUTSIDE,\n } as any;\n opt.relativeVerticalPosition = mapV[vp.align];\n }\n\n // Map wrap margins to clearance distances (resolve percentages against page dimensions)\n const pageW = getPageWidthTwips(theme, themeName);\n const pageH = getPageHeightTwips(theme, themeName);\n const m = floating.wrap?.margins;\n if (m) {\n if (m.top !== undefined) opt.topFromText = resolveOffsetTwips(m.top, pageH);\n if (m.right !== undefined)\n opt.rightFromText = resolveOffsetTwips(m.right, pageW);\n if (m.bottom !== undefined)\n opt.bottomFromText = resolveOffsetTwips(m.bottom, pageH);\n if (m.left !== undefined)\n opt.leftFromText = resolveOffsetTwips(m.left, pageW);\n }\n\n opt.overlap = OverlapType.OVERLAP;\n\n return opt;\n}\n\nexport async function renderTextBoxComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n _context: import('../types').RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isTextBoxComponent(component)) return [];\n const tb = component as TextBoxComponentDefinition;\n\n const isInline = !tb.props.floating;\n const childComponents = tb.children || [];\n\n if (isInline) {\n // Inline: use a one-cell table container for multi-paragraph support\n const cellChildren: (Paragraph | Table)[] = [];\n // Create context with current text-box as parent\n const childContext: import('../types').RenderContext = {\n ..._context,\n parent: tb,\n };\n for (const child of childComponents) {\n const rendered = await renderComponent(\n child,\n theme,\n themeName,\n childContext\n );\n cellChildren.push(...rendered);\n }\n\n const styleCfg = (tb.props as any).style as CellStyleConfig | undefined;\n const cellOpts = buildCellOptions(cellChildren, styleCfg, theme);\n\n const row = new TableRow({ children: [new TableCell(cellOpts)] });\n const table = new Table({\n layout: TableLayoutType.FIXED, // Lock column widths\n rows: [row],\n width: { size: 100, type: WidthType.PERCENTAGE },\n borders: NONE_BORDERS,\n });\n return [table];\n }\n\n // Always use a floating one-cell table container for multi-paragraph support\n\n // If there is at least one table or image child, use a floating one-cell table container\n const cellChildren: (Paragraph | Table)[] = [];\n // Create context with current text-box as parent\n const childContext: import('../types').RenderContext = {\n ..._context,\n parent: tb,\n };\n for (const child of childComponents) {\n const rendered = await renderComponent(\n child,\n theme,\n themeName,\n childContext\n );\n cellChildren.push(...rendered);\n }\n\n const styleCfg = (tb.props as any).style as CellStyleConfig | undefined;\n const cellOpts = buildCellOptions(cellChildren, styleCfg, theme);\n\n const row = new TableRow({\n children: [new TableCell(cellOpts)],\n });\n\n const float = mapTableFloatOptions(tb.props.floating, theme, themeName);\n\n // Conversion factor: 1 pixel = 15 twips (at 96 DPI: 1440 twips/inch / 96 pixels/inch)\n const PIXELS_TO_TWIPS = 15;\n const DEFAULT_WIDTH_TWIPS = 5000; // ~333 pixels\n\n // Support width as number (pixels) or percentage string\n // Read from props.width (new location) with fallback to props.floating.width (legacy, in twips)\n const rawWidth = tb.props.width ?? (tb.props.floating as any)?.width;\n let widthSize: number;\n let widthType: (typeof WidthType)[keyof typeof WidthType];\n\n if (rawWidth === undefined) {\n // No width specified, use default\n widthSize = DEFAULT_WIDTH_TWIPS;\n widthType = WidthType.DXA;\n } else if (typeof rawWidth === 'string' && rawWidth.endsWith('%')) {\n // Percentage width\n widthSize = parseFloat(rawWidth);\n widthType = WidthType.PERCENTAGE;\n } else {\n // Number in pixels - convert to twips (DXA)\n widthSize =\n typeof rawWidth === 'number'\n ? rawWidth * PIXELS_TO_TWIPS\n : DEFAULT_WIDTH_TWIPS;\n widthType = WidthType.DXA;\n }\n\n const table = new Table({\n layout: TableLayoutType.FIXED, // Lock column widths\n rows: [row],\n width: { size: widthSize, type: widthType },\n float,\n borders: NONE_BORDERS,\n });\n return [table];\n}\n","/**\n * Border utilities for consistent border styling across modules\n */\n\nimport { BorderStyle } from 'docx';\nimport { resolveColor } from './colorUtils';\nimport { ThemeConfig } from '../index';\n\n/**\n * Standard \"no borders\" configuration for tables\n * Used when borders should be invisible/disabled\n */\nexport const NONE_BORDERS = {\n top: { style: BorderStyle.NONE, size: 0, color: '000000' },\n right: { style: BorderStyle.NONE, size: 0, color: '000000' },\n bottom: { style: BorderStyle.NONE, size: 0, color: '000000' },\n left: { style: BorderStyle.NONE, size: 0, color: '000000' },\n insideHorizontal: { style: BorderStyle.NONE, size: 0, color: '000000' },\n insideVertical: { style: BorderStyle.NONE, size: 0, color: '000000' },\n} as const;\n\n/**\n * Maps border style string to docx BorderStyle enum\n * @param s - Border style string ('dashed', 'dotted', 'double', 'none', 'single')\n * @returns Corresponding BorderStyle enum value\n */\nexport function mapBorderStyle(\n s?: string\n): (typeof BorderStyle)[keyof typeof BorderStyle] {\n switch (s) {\n case 'dashed':\n return BorderStyle.DASHED;\n case 'dotted':\n return BorderStyle.DOTTED;\n case 'double':\n return BorderStyle.DOUBLE;\n case 'none':\n return BorderStyle.NONE;\n default:\n return BorderStyle.SINGLE;\n }\n}\n\n/**\n * Border configuration object\n */\nexport interface BorderConfig {\n style?: string;\n width?: number;\n color?: string;\n}\n\n/**\n * Converts border configuration to docx border format\n * @param b - Border configuration object\n * @param theme - Theme configuration for color resolution\n * @returns Docx border object or undefined if no border\n */\nexport function convertBorder(\n b: BorderConfig | undefined,\n theme: ThemeConfig\n):\n | {\n style: (typeof BorderStyle)[keyof typeof BorderStyle];\n size: number;\n color: string;\n }\n | undefined {\n if (!b) return undefined;\n\n return {\n style: mapBorderStyle(b.style),\n size: b.width !== undefined ? Math.max(1, Math.round(b.width * 8)) : 1,\n color: b.color ? resolveColor(b.color, theme) : '000000',\n };\n}\n\n/**\n * Borders configuration for all four sides\n */\nexport interface BordersConfig {\n top?: BorderConfig;\n right?: BorderConfig;\n bottom?: BorderConfig;\n left?: BorderConfig;\n}\n\n/**\n * Converts borders configuration object to docx borders format\n * Returns undefined if no borders are defined\n * @param bordersConfig - Configuration for all four borders\n * @param theme - Theme configuration for color resolution\n * @returns Docx borders object or undefined\n */\nexport function convertBorders(\n bordersConfig: BordersConfig | undefined,\n theme: ThemeConfig\n):\n | Record<\n string,\n {\n style: (typeof BorderStyle)[keyof typeof BorderStyle];\n size: number;\n color: string;\n }\n >\n | undefined {\n if (!bordersConfig) return undefined;\n\n const borders: Record<\n string,\n {\n style: (typeof BorderStyle)[keyof typeof BorderStyle];\n size: number;\n color: string;\n }\n > = {};\n\n const top = convertBorder(bordersConfig.top, theme);\n const right = convertBorder(bordersConfig.right, theme);\n const bottom = convertBorder(bordersConfig.bottom, theme);\n const left = convertBorder(bordersConfig.left, theme);\n\n if (top) borders.top = top;\n if (right) borders.right = right;\n if (bottom) borders.bottom = bottom;\n if (left) borders.left = left;\n\n return Object.keys(borders).length > 0 ? borders : undefined;\n}\n","/**\n * Cell utilities for building table cell configurations\n */\n\nimport { Paragraph, Table } from 'docx';\nimport { pointsToTwips } from './styleHelpers';\nimport { resolveColor } from './colorUtils';\nimport { ThemeConfig } from '../index';\nimport { convertBorders, BordersConfig } from './borderUtils';\n\n/**\n * Padding configuration for all four sides\n */\nexport interface PaddingConfig {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\n/**\n * Shading configuration\n */\nexport interface ShadingConfig {\n fill?: string;\n}\n\n/**\n * Complete cell style configuration\n */\nexport interface CellStyleConfig {\n padding?: PaddingConfig;\n border?: BordersConfig;\n shading?: ShadingConfig;\n}\n\n/**\n * Builds cell options object for TableCell constructor\n * Handles margins (padding), shading, and borders consistently\n * @param children - Child elements to include in the cell\n * @param styleCfg - Style configuration for the cell\n * @param theme - Theme configuration for color resolution\n * @returns Cell options object ready for TableCell constructor\n */\nexport function buildCellOptions(\n children: (Paragraph | Table)[],\n styleCfg: CellStyleConfig | undefined,\n theme: ThemeConfig\n): {\n children: (Paragraph | Table)[];\n margins: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n shading?: { fill: string };\n borders?: Record<string, { style: any; size: number; color: string }>;\n} {\n const cellOpts: any = {\n children: children.length ? children : [new Paragraph({})],\n margins: {\n top: styleCfg?.padding?.top ? pointsToTwips(styleCfg.padding.top) : 0,\n right: styleCfg?.padding?.right\n ? pointsToTwips(styleCfg.padding.right)\n : 0,\n bottom: styleCfg?.padding?.bottom\n ? pointsToTwips(styleCfg.padding.bottom)\n : 0,\n left: styleCfg?.padding?.left ? pointsToTwips(styleCfg.padding.left) : 0,\n },\n };\n\n // Apply shading if configured\n if (styleCfg?.shading?.fill) {\n cellOpts.shading = { fill: resolveColor(styleCfg.shading.fill, theme) };\n }\n\n // Apply borders if configured\n if (styleCfg?.border) {\n const borders = convertBorders(styleCfg.border, theme);\n if (borders && Object.keys(borders).length > 0) {\n cellOpts.borders = borders;\n }\n }\n\n return cellOpts;\n}\n","/**\n * Table Component\n * Standard component for rendering tables in documents\n */\n\nimport { Table } from 'docx';\nimport { ComponentDefinition, isTableComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createTable } from '../core/content';\n\ntype CellContent = string | ComponentDefinition;\n\ntype HorizontalAlignment = 'left' | 'center' | 'right' | 'justify';\n\ntype VerticalAlignment = 'top' | 'middle' | 'bottom';\n\ntype FontConfig = {\n family?: string;\n size?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n};\n\ntype BorderColor =\n | string\n | {\n bottom?: string;\n top?: string;\n right?: string;\n left?: string;\n };\n\ntype BorderSize =\n | number\n | {\n bottom?: number;\n top?: number;\n right?: number;\n left?: number;\n };\n\ntype Padding =\n | number\n | {\n bottom?: number;\n top?: number;\n right?: number;\n left?: number;\n };\n\ntype CellDefaults = {\n color?: string;\n backgroundColor?: string;\n horizontalAlignment?: HorizontalAlignment;\n verticalAlignment?: VerticalAlignment;\n font?: FontConfig;\n borderColor?: BorderColor;\n borderSize?: BorderSize;\n padding?: Padding;\n height?: number;\n};\n\ntype TableConfig = {\n borderColor?: BorderColor;\n borderSize?: BorderSize;\n cellDefaults?: CellDefaults;\n headerCellDefaults?: CellDefaults;\n width?: number;\n columns: {\n /** Width in points (number) or as percentage string e.g. \"40%\" */\n width?: number | string;\n cellDefaults?: CellDefaults;\n header?: CellDefaults & {\n content?: CellContent;\n };\n cells?: (CellDefaults & {\n content?: CellContent;\n })[];\n }[];\n keepInOnePage?: boolean;\n keepNext?: boolean;\n repeatHeaderOnPageBreak?: boolean;\n};\n\n/**\n * Render table component\n * Supports new column-based format with cell defaults and legacy headers/rows format\n */\nexport async function renderTableComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): Promise<Table[]> {\n if (!isTableComponent(component)) return [];\n\n const rawConfig = component.props as any;\n const result: Table[] = [];\n\n // Check if this is the old format (has headers and rows properties)\n if (rawConfig.headers && rawConfig.rows) {\n // Convert old format to new format\n const headers = rawConfig.headers as string[];\n const rows = rawConfig.rows as string[][];\n\n const defaultCellDefaults: CellDefaults = {\n color: '000000',\n backgroundColor: 'transparent',\n horizontalAlignment: 'left',\n verticalAlignment: 'top',\n font: {\n family: 'Arial',\n size: 11,\n bold: false,\n italic: false,\n underline: false,\n },\n borderColor: '000000',\n borderSize: 1,\n };\n\n const config: TableConfig = {\n borderColor: '000000',\n borderSize: 1,\n cellDefaults: defaultCellDefaults,\n width: 100,\n columns: headers.map((header, colIndex) => ({\n cellDefaults: { ...defaultCellDefaults },\n header: {\n ...defaultCellDefaults,\n content: header,\n },\n cells: rows.map((row) => ({\n ...defaultCellDefaults,\n content: row[colIndex] || '',\n })),\n })),\n };\n\n result.push(await createTable(config.columns, config, theme, themeName));\n\n return result;\n }\n\n // New column-based format\n const config = rawConfig as TableConfig;\n\n result.push(await createTable(config.columns, config, theme, themeName));\n\n return result;\n}\n","/**\n * Section Component\n * Standard component for rendering document sections with child components\n */\n\nimport { Paragraph, Table, BookmarkStart, BookmarkEnd } from 'docx';\nimport {\n ComponentDefinition,\n RenderContext,\n isSectionComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { renderComponent } from '../core/render';\n\ninterface SectionBookmarkState {\n next: number;\n}\n\n/** Generate a document-scoped, reproducible bookmark ID. */\nfunction generateSectionBookmarkId(context: RenderContext): {\n id: string;\n linkId: number;\n} {\n const custom = (context.custom ??= {});\n const state = (custom.sectionBookmarks ??= {\n next: 1,\n }) as SectionBookmarkState;\n const ordinal = state.next++;\n // Keep nested component IDs away from the low ordinals used by layout\n // section bookmarks in core/render.ts.\n const linkId = 1_000_000 + ordinal;\n return {\n id: `_NestedSection_${ordinal}`,\n linkId,\n };\n}\n\n/**\n * Render section component with bookmark support for scoped TOCs\n */\nexport async function renderSectionComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isSectionComponent(component)) return [];\n\n const elements: (Paragraph | Table)[] = [];\n\n // Generate unique bookmark ID for this section\n const { id: sectionBookmarkId, linkId: bookmarkLinkId } =\n generateSectionBookmarkId(context);\n\n // Add bookmark in a zero-spacing paragraph at section start\n // This prevents visual gaps while maintaining bookmark functionality\n elements.push(\n new Paragraph({\n children: [new BookmarkStart(sectionBookmarkId, bookmarkLinkId)],\n spacing: {\n before: 0,\n after: 0,\n line: 0,\n },\n })\n );\n\n // Update context with section bookmark ID for child components (especially TOCs)\n const sectionContext: RenderContext = {\n ...context,\n section: {\n ...context.section,\n sectionBookmarkId,\n },\n };\n\n // Render child components with updated context\n if (component.children) {\n for (const child of component.children) {\n const childElements = await renderComponent(\n child,\n theme,\n themeName,\n sectionContext\n );\n elements.push(...childElements);\n }\n }\n\n // Add bookmark end after section content\n // Use zero spacing to prevent visual gap\n elements.push(\n new Paragraph({\n children: [new BookmarkEnd(bookmarkLinkId)],\n spacing: {\n before: 0,\n after: 0,\n line: 0,\n },\n })\n );\n\n return elements;\n}\n","/**\n * Columns Component\n * Standard component for rendering content in columns layout\n */\n\nimport {\n Paragraph,\n Table,\n TableRow,\n TableCell,\n WidthType,\n BorderStyle,\n VerticalAlign,\n TableLayoutType,\n} from 'docx';\nimport {\n ComponentDefinition,\n RenderContext,\n isColumnsComponent,\n isTextBoxComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { renderComponent } from '../core/render';\nimport {\n getAvailableWidthTwips,\n relativeLengthToTwips,\n} from '../utils/widthUtils';\nimport { NONE_BORDERS } from '../styles/utils/borderUtils';\n\n/**\n * Render columns component\n */\nexport async function renderColumnsComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isColumnsComponent(component)) return [];\n\n // Check if parent is a text-box component\n if (context.parent && isTextBoxComponent(context.parent)) {\n // Render as table-based columns when inside a text-box\n return await renderColumnsAsTable(component, theme, themeName, context);\n }\n\n // Standard section-based rendering (existing behavior)\n // Props are pre-resolved by resolveComponentTree\n const elements: (Paragraph | Table)[] = [];\n\n if (component.children) {\n for (const child of component.children) {\n const childElements = await renderComponent(\n child,\n theme,\n themeName,\n context\n );\n elements.push(...childElements);\n }\n }\n\n return elements;\n}\n\n/**\n * Render columns as a multi-column table (for use inside text-boxes)\n */\nasync function renderColumnsAsTable(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<Table[]> {\n const cfg = (component as any).props || {};\n const columns = cfg.columns || [];\n\n // Normalize columns configuration\n let columnConfigs: Array<{ width?: number | string; gap?: number | string }> =\n [];\n if (typeof columns === 'number') {\n // Equal-width columns\n columnConfigs = Array(columns).fill({ width: 'auto' });\n } else if (Array.isArray(columns)) {\n columnConfigs = columns;\n } else {\n // Invalid config, return empty\n return [];\n }\n\n const columnCount = columnConfigs.length;\n if (columnCount === 0) return [];\n\n // Calculate column widths\n const availableWidthTwips = getAvailableWidthTwips(theme, themeName);\n const columnWidths: number[] = [];\n const columnGaps: number[] = [];\n let totalDefinedWidth = 0;\n let totalGaps = 0;\n const autoWidthIndexes: number[] = [];\n\n for (let i = 0; i < columnCount; i++) {\n const col = columnConfigs[i];\n\n // Calculate width\n if (col.width === undefined || col.width === 'auto') {\n autoWidthIndexes.push(i);\n columnWidths.push(0); // Placeholder\n } else {\n const widthTwips = relativeLengthToTwips(col.width, availableWidthTwips);\n columnWidths.push(widthTwips);\n totalDefinedWidth += widthTwips;\n }\n\n // Calculate gap (space after this column)\n if (i < columnCount - 1) {\n const gapTwips =\n col.gap !== undefined\n ? relativeLengthToTwips(col.gap, availableWidthTwips)\n : cfg.gap !== undefined\n ? relativeLengthToTwips(cfg.gap, availableWidthTwips)\n : 720; // Default: 0.5 inch\n columnGaps.push(gapTwips);\n totalGaps += gapTwips;\n } else {\n columnGaps.push(0); // No gap after last column\n }\n }\n\n // Distribute remaining width among auto-width columns\n const remainingWidth = Math.max(\n 0,\n availableWidthTwips - totalDefinedWidth - totalGaps\n );\n if (autoWidthIndexes.length > 0) {\n const autoColumnWidth = Math.floor(\n remainingWidth / autoWidthIndexes.length\n );\n for (const idx of autoWidthIndexes) {\n columnWidths[idx] = autoColumnWidth;\n }\n }\n\n // Distribute child components across columns\n const childComponents = (component as any).children || [];\n const columnContents: ComponentDefinition[][] = Array(columnCount)\n .fill(null)\n .map(() => []);\n\n // Simple distribution: round-robin\n for (let i = 0; i < childComponents.length; i++) {\n const colIndex = i % columnCount;\n columnContents[colIndex].push(childComponents[i]);\n }\n\n // Render each column's content\n const cells: TableCell[] = [];\n for (let i = 0; i < columnCount; i++) {\n const columnElements: (Paragraph | Table)[] = [];\n\n for (const child of columnContents[i]) {\n const rendered = await renderComponent(child, theme, themeName, context);\n columnElements.push(...rendered);\n }\n\n // If column is empty, add empty paragraph\n if (columnElements.length === 0) {\n columnElements.push(new Paragraph({}));\n }\n\n cells.push(\n new TableCell({\n children: columnElements,\n width: { size: columnWidths[i], type: WidthType.DXA },\n margins: {\n top: 0,\n right: columnGaps[i] / 2,\n bottom: 0,\n left: i > 0 ? columnGaps[i - 1] / 2 : 0,\n },\n verticalAlign: VerticalAlign.TOP,\n borders: {\n top: { style: BorderStyle.NONE, size: 0, color: '000000' },\n right: { style: BorderStyle.NONE, size: 0, color: '000000' },\n bottom: { style: BorderStyle.NONE, size: 0, color: '000000' },\n left: { style: BorderStyle.NONE, size: 0, color: '000000' },\n },\n })\n );\n }\n\n const row = new TableRow({ children: cells });\n const table = new Table({\n rows: [row],\n width: { size: 100, type: WidthType.PERCENTAGE },\n layout: TableLayoutType.FIXED, // Lock column widths\n borders: NONE_BORDERS,\n });\n\n return [table];\n}\n","/**\n * Statistic Component\n * Standard component for rendering statistic displays in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isStatisticComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createStatistic } from '../core/content';\n\n/**\n * Render statistic component\n */\nexport function renderStatisticComponent(\n component: ComponentDefinition,\n _theme: ThemeConfig\n): Paragraph[] {\n if (!isStatisticComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree\n const resolvedConfig = component.props;\n\n return createStatistic(\n {\n number: resolvedConfig.number,\n description: resolvedConfig.description,\n alignment: resolvedConfig.alignment,\n },\n {\n spacing: resolvedConfig.spacing as\n | { before?: number; after?: number }\n | undefined,\n }\n );\n}\n","/**\n * Table of Contents Component\n * Renders TOC using Word's native TableOfContents field with bookmark scoping support\n */\n\nimport {\n Paragraph,\n TableOfContents,\n AlignmentType,\n TextRun,\n StyleLevel,\n} from 'docx';\nimport type { ITableOfContentsOptions } from 'docx';\nimport type { TocProps } from '@json-to-office/shared-docx';\nimport type { ThemeConfig } from '../../styles';\nimport type { RenderContext } from '../../types';\n\nexport interface TocComponentDefinition {\n name: 'toc';\n id?: string;\n props: TocProps;\n}\n\n/**\n * Parse and validate a depth range configuration\n * @param rawDepth - Raw depth configuration from user input\n * @param fieldName - Name of the field (for error messages)\n * @param defaultFrom - Default 'from' value if not specified\n * @param defaultTo - Default 'to' value if not specified\n * @returns Validated depth range with from and to values\n */\nfunction parseDepthRange(\n rawDepth: any,\n fieldName: string,\n defaultFrom = 1,\n defaultTo = 3\n): { from: number; to: number } {\n if (typeof rawDepth !== 'object' || rawDepth === null) {\n throw new Error(\n `${fieldName} must be a range object with optional \"from\" and/or \"to\" fields, received: ${JSON.stringify(rawDepth)}`\n );\n }\n\n // Apply defaults for missing values\n const from = rawDepth.from ?? defaultFrom;\n const to = rawDepth.to ?? defaultTo;\n\n // Validate range\n if (from < 1 || from > 6 || to < 1 || to > 6) {\n throw new Error(\n `${fieldName} range values must be between 1 and 6, received: from=${from}, to=${to}`\n );\n }\n if (from > to) {\n throw new Error(\n `${fieldName} \"from\" must be less than or equal to \"to\", received: from=${from}, to=${to}`\n );\n }\n\n return { from, to };\n}\n\n/**\n * Render TOC component using Word's native TableOfContents field with bookmark scoping\n *\n * This creates a dynamic TOC that:\n * - Auto-populates with headings from configured scope\n * - Updates automatically when document structure changes\n * - Includes clickable hyperlinks to content\n * - Shows page numbers (if enabled)\n * - Respects configured depth limits\n *\n * Scope behavior:\n * - scope: 'document' → Scans entire document (default when TOC is at report level)\n * - scope: 'section' → Scans only parent section content (uses bookmark)\n * - scope: 'auto' → Automatically detects: section if inside section, otherwise document\n */\nexport function renderTocComponent(\n component: TocComponentDefinition,\n theme: ThemeConfig,\n context?: RenderContext\n): (Paragraph | TableOfContents)[] {\n const componentProps = component.props;\n\n // Parse depth parameter - supports range with optional from/to\n const rawDepth = componentProps.depth ?? { to: 3 };\n const depthRange = parseDepthRange(rawDepth, 'TOC depth', 1, 3);\n const depthStart = depthRange.from;\n const depthEnd = depthRange.to;\n\n // Parse pageNumbersDepth parameter - controls which levels show page numbers\n let pageNumbersStart: number | undefined;\n let pageNumbersEnd: number | undefined;\n\n if (componentProps.pageNumbersDepth !== undefined) {\n const pageNumbersRange = parseDepthRange(\n componentProps.pageNumbersDepth,\n 'TOC pageNumbersDepth',\n 1,\n 3\n );\n pageNumbersStart = pageNumbersRange.from;\n pageNumbersEnd = pageNumbersRange.to;\n }\n\n // numberingStyle has no representation in Word's TOC field: the field carries\n // no numbering switch, so entries always inherit the numbering of the heading\n // styles they point at. The prop stays in the schema (documents already set it\n // and props are additionalProperties:false), but the no-op is announced rather\n // than swallowed.\n if (componentProps.numberingStyle !== undefined) {\n console.warn(\n `TOC numberingStyle \"${componentProps.numberingStyle}\" is ignored: Word's ` +\n 'table-of-contents field has no numbering switch. TOC entries inherit ' +\n 'numbering from the heading styles they reference.'\n );\n }\n\n const includePageNumbers = componentProps.includePageNumbers !== false; // default true\n const scope = componentProps.scope ?? 'auto';\n\n // Determine effective scope based on configuration and context\n const effectiveScope =\n scope === 'auto'\n ? context?.section?.sectionBookmarkId\n ? 'section'\n : 'document'\n : scope;\n\n // Get section bookmark ID if scoped to section\n const sectionBookmarkId =\n effectiveScope === 'section'\n ? context?.section?.sectionBookmarkId\n : undefined;\n\n // Validate bookmark if section-scoped\n if (effectiveScope === 'section' && !sectionBookmarkId) {\n // Log warning but gracefully fall back to document scope\n console.warn(\n 'TOC configured for section scope but no section bookmark found. Falling back to document scope.'\n );\n }\n\n const paragraphs: (Paragraph | TableOfContents)[] = [];\n\n // Add TOC title only if explicitly provided\n if (componentProps.title) {\n paragraphs.push(\n new Paragraph({\n children: [\n new TextRun({\n text: componentProps.title,\n bold: true,\n size: 28, // 14pt (size is in half-points)\n }),\n ],\n spacing: {\n before: theme.componentDefaults?.heading?.spacing?.before ?? 240,\n // Increase spacing between the title and the TOC list\n // 180 ~= 9pt, provides clearer separation by default\n after: 180,\n },\n alignment: AlignmentType.LEFT,\n })\n );\n }\n\n // Build style mappings for TOC levels based on depth\n // StyleLevel requires styleName (string) and level (number)\n const stylesWithLevels: StyleLevel[] = [];\n\n // For section-scoped TOCs, exclude heading levels equal to or above the section title level\n // This prevents the section title from appearing in its own TOC\n const sectionTitleLevel = context?.section?.sectionTitleLevel;\n const startLevel =\n effectiveScope === 'section' && sectionTitleLevel\n ? sectionTitleLevel // Start from the level after the section title\n : 0; // Document scope starts from level 1 (index 0)\n\n // Do NOT map built-in heading styles via \\t switch.\n // Use headingStyleRange (\\o) exclusively for Heading 1..6 to avoid any interference\n // between TOC styles and document heading styles.\n\n // Add custom style mappings if provided\n // These allow arbitrary theme styles to appear in the TOC at specified levels\n if (componentProps.styles && componentProps.styles.length > 0) {\n for (const styleMapping of componentProps.styles) {\n // The TOC \\t (stylesWithLevels) switch expects Word style DISPLAY NAMES, not IDs.\n // Our theme registers custom styles with:\n // - id: original key (e.g., \"MySpectacularStyle\")\n // - name: Title Case with spaces (e.g., \"My Spectacular Style\")\n // Convert known custom style IDs to their display names to ensure Word matches them.\n const styleId = styleMapping.styleId;\n const isCustomStyle =\n !!theme.styles &&\n Object.prototype.hasOwnProperty.call(theme.styles, styleId);\n const styleDisplayName = isCustomStyle\n ? styleId\n .replace(/([A-Z])/g, ' $1')\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n : styleId; // If it's not a custom style key, assume it's already a display name\n\n stylesWithLevels.push(\n new StyleLevel(styleDisplayName, styleMapping.level)\n );\n }\n }\n\n // Create Word TOC field with optional bookmark scoping\n // The TableOfContents class generates a field code that Word will populate\n // Format (document scope): { TOC \\o \"1-N\" \\h \\z \\u }\n // Format (section scope): { TOC \\b BookmarkName \\o \"1-N\" \\h \\z \\u }\n // - \\b BookmarkName: Limit TOC to entries within specified bookmark\n // - \\o \"1-N\": Include outline levels 1 through N\n // - \\h: Make TOC entries hyperlinks\n // - \\z: Hide page numbers in web layout\n // - \\u: Use outline levels instead of TC fields\n\n // Calculate heading range for \\o switch\n // For section-scoped TOCs: start AFTER section title level (e.g., level 2 if section is level 1)\n // For document-scoped TOCs: use depthStart and depthEnd from parsed depth config\n const effectiveDepthStart =\n effectiveScope === 'section' && sectionTitleLevel\n ? Math.max(depthStart, startLevel + 1) // Skip section title level, but respect user's depthStart\n : depthStart;\n const effectiveDepthEnd = depthEnd;\n\n // Build TOC options\n const tocOptions: ITableOfContentsOptions = {\n hyperlink: true, // Enable clickable hyperlinks (\\h switch)\n headingStyleRange: `${effectiveDepthStart}-${effectiveDepthEnd}`, // Outline level range (\\o switch)\n stylesWithLevels, // Style-to-TOC-level mappings (\\t switch)\n // Add bookmark scope if within a section (\\b switch)\n entriesFromBookmark: sectionBookmarkId,\n // Handle page number visibility\n // If pageNumbersDepth is specified, use it to control which levels show page numbers\n // Otherwise, respect includePageNumbers boolean (default true)\n ...(() => {\n if (pageNumbersStart !== undefined && pageNumbersEnd !== undefined) {\n // pageNumbersDepth specified: hide page numbers outside the specified range\n // Word's \\n switch omits page numbers for specified levels\n // We need to invert the logic: specify levels to OMIT, not levels to SHOW\n const levelsToOmit: string[] = [];\n\n // Omit levels before pageNumbersStart\n if (pageNumbersStart > effectiveDepthStart) {\n levelsToOmit.push(`${effectiveDepthStart}-${pageNumbersStart - 1}`);\n }\n\n // Omit levels after pageNumbersEnd\n if (pageNumbersEnd < effectiveDepthEnd) {\n levelsToOmit.push(`${pageNumbersEnd + 1}-${effectiveDepthEnd}`);\n }\n\n // Only add the option if there are levels to omit\n return levelsToOmit.length > 0\n ? { pageNumbersEntryLevelsRange: levelsToOmit.join(',') }\n : {};\n } else if (!includePageNumbers) {\n // includePageNumbers is false: omit page numbers for all levels\n return {\n pageNumbersEntryLevelsRange: `${effectiveDepthStart}-${effectiveDepthEnd}`,\n };\n } else {\n // includePageNumbers is true and no pageNumbersDepth: show page numbers for all levels\n return {};\n }\n })(),\n // Add separator between entry text and page number\n // Boolean: true = \"\\t\" (tab, default), false = \" \" (space)\n ...(componentProps.numberSeparator !== undefined\n ? {\n entryAndPageNumberSeparator: componentProps.numberSeparator\n ? '\\t'\n : ' ',\n }\n : { entryAndPageNumberSeparator: '\\t' }), // default to tab\n };\n\n // Insert TOC as a top-level block (not wrapped in a Paragraph).\n // Wrapping TableOfContents inside a Paragraph produces an empty SDT above\n // the actual entries in Word. Adding directly avoids that artifact.\n paragraphs.push(\n new TableOfContents(componentProps.title ?? 'Table of Contents', tocOptions)\n );\n\n // Do not append an extra empty paragraph after TOC to avoid\n // unwanted blank lines/newlines at the end of the TOC block.\n\n // Note: Word will automatically handle:\n // - Page number display (based on document view mode)\n // - Numbering style (inherited from heading styles)\n // - Indentation (based on heading levels)\n // - Updates (right-click TOC → Update Field in Word)\n\n return paragraphs;\n}\n","/**\n * Highcharts Component\n * Standard component for generating charts using Highcharts Export Server\n */\n\nimport { Paragraph, Table } from 'docx';\nimport {\n ComponentDefinition,\n RenderContext,\n isHighchartsComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createImage } from '../core/content';\nimport { resolveColor } from '../styles/utils/colorUtils';\nimport { isNodeEnvironment } from '../utils/environment';\nimport { resolveServiceUrl, postJsonToService } from '../utils/serviceClient';\n\n// Import only the types we actually use from shared package\nimport type { HighchartsProps } from '@json-to-office/shared-docx';\nimport type { HighchartsServiceConfig } from '@json-to-office/shared';\nimport { DEFAULT_CHART_THEME_COLORS } from '@json-to-office/shared';\n\n// Re-export HighchartsProps for backward compatibility\nexport type { HighchartsProps } from '@json-to-office/shared-docx';\n\n/**\n * Chart generation result\n */\nexport interface ChartGenerationResult {\n base64DataUri: string;\n width: number;\n height: number;\n}\n\nconst DEFAULT_EXPORT_SERVER_URL = 'http://localhost:7801';\n\n/**\n * Generate chart using Highcharts Export Server\n */\nasync function generateChart(\n config: HighchartsProps,\n servicesConfig?: HighchartsServiceConfig\n): Promise<ChartGenerationResult> {\n // Only run in Node.js environments\n if (!isNodeEnvironment()) {\n throw new Error(\n 'Highcharts export server requires a Node.js environment. ' +\n 'Chart generation is not available in browser environments.'\n );\n }\n\n const serverUrl = resolveServiceUrl(\n config.serverUrl,\n servicesConfig?.serverUrl,\n DEFAULT_EXPORT_SERVER_URL\n );\n\n const requestBody: Record<string, unknown> = {\n infile: config.options,\n type: 'png',\n b64: true,\n scale: config.scale,\n // Forward resources verbatim only when present so the payload stays\n // byte-identical to before for callers that omit it.\n ...(config.resources ? { resources: config.resources } : {}),\n };\n\n const response = await postJsonToService({\n url: serverUrl,\n path: '/export',\n body: requestBody,\n headers: servicesConfig?.headers,\n serviceLabel: 'Highcharts export server',\n onUnreachable: (url, cause) =>\n `Highcharts Export Server is not running at ${url}. ` +\n 'Start it with: npx highcharts-export-server --enableServer true\\n' +\n `Cause: ${cause}`,\n });\n\n const base64Data = await response.text();\n const base64DataUri = `data:image/png;base64,${base64Data}`;\n const width = config.options.chart.width;\n const height = config.options.chart.height;\n\n return {\n base64DataUri,\n width,\n height,\n };\n}\n\n/**\n * Turn one theme color value into a `#RRGGBB` string, or undefined when it\n * cannot be resolved. The theme schema lets a color be another token's name\n * (`\"accent4\": \"primary\"`), so a bare `#` prefix would post \"#primary\" to the\n * export server; `resolveColor` walks the reference chain and throws on\n * anything unresolvable, which we treat as an unset slot.\n */\nfunction toChartColor(value: string, theme: ThemeConfig): string | undefined {\n // Literal hex passes through untouched — resolveColor would upper-case it,\n // and it rejects the bare (no '#') form the schema still accepts.\n if (/^#?[0-9A-Fa-f]{6}$/.test(value)) {\n return value.startsWith('#') ? value : `#${value}`;\n }\n try {\n return `#${resolveColor(value, theme)}`;\n } catch {\n return undefined;\n }\n}\n\n/**\n * When the Highcharts config sets no top-level `colors`, series render in the\n * Highcharts default palette (blue-first) and ignore the document theme. Inject\n * the theme's chart palette — the same token list PPTX charts resolve — as\n * series colors so charts follow the theme by default. accent4-6 are optional\n * in the theme schema; slots the theme leaves unset are skipped, in both\n * formats, so the palette never carries gaps or repeats and Highcharts wraps\n * the shorter list (see DEFAULT_CHART_THEME_COLORS). Explicit `colors` always\n * wins.\n */\nfunction withThemeColors(\n config: HighchartsProps,\n theme: ThemeConfig\n): HighchartsProps {\n const options = config.options as Record<string, unknown> | undefined;\n if (!options || options.colors || !theme?.colors) return config;\n const themeColors = theme.colors as Record<string, string | undefined>;\n const palette = DEFAULT_CHART_THEME_COLORS.map((token) => {\n const value = themeColors[token];\n return typeof value === 'string' && value.length > 0\n ? toChartColor(value, theme)\n : undefined;\n }).filter((c): c is string => c !== undefined);\n if (palette.length === 0) return config;\n return {\n ...config,\n options: { ...config.options, colors: palette },\n };\n}\n\n/**\n * Render highcharts component\n */\nexport async function renderHighchartsComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context?: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isHighchartsComponent(component)) return [];\n\n const config = withThemeColors(component.props as HighchartsProps, theme);\n\n // Generate the chart\n const chartResult = await generateChart(\n config,\n context?.services?.highcharts\n );\n\n // If either config.width or config.height is provided, use config dimensions only\n // Otherwise fall back to chart dimensions\n const hasConfigDimensions =\n config.width !== undefined || config.height !== undefined;\n const renderWidth = hasConfigDimensions ? config.width : chartResult.width;\n const renderHeight = hasConfigDimensions ? config.height : chartResult.height;\n\n // Add chart image using the image component with base64 data URI\n const imageParagraphs = await createImage(\n chartResult.base64DataUri,\n theme,\n themeName,\n {\n width: renderWidth,\n height: renderHeight,\n alignment: 'center',\n }\n );\n\n return imageParagraphs;\n}\n","/**\n * Environment detection utilities\n */\n\n/**\n * Check if the current environment is Node.js\n * This is used to conditionally load Node.js-only modules\n */\nexport function isNodeEnvironment(): boolean {\n // Check for Node.js-specific globals\n return (\n typeof process !== 'undefined' &&\n process.versions != null &&\n process.versions.node != null &&\n typeof process.versions.node === 'string'\n );\n}\n\n/**\n * Check if Node.js built-in modules are available\n * More specific check for modules that require Node.js built-ins\n */\nexport function hasNodeBuiltins(): boolean {\n try {\n // Check if we can access Node.js built-in modules\n // This will fail in browser environments\n return (\n typeof require !== 'undefined' ||\n (typeof process !== 'undefined' &&\n typeof process.versions === 'object' &&\n typeof process.versions.node === 'string')\n );\n } catch {\n return false;\n }\n}\n","/**\n * Shared client for \"service-rendered image\" components (highcharts, visual).\n *\n * Both offload rendering to an injected HTTP service: resolve a base URL, POST a\n * JSON body with optional dynamic headers, and normalize transport errors — now\n * with a request timeout so a wedged service can't hang the render forever.\n * Callers decode the response body themselves (highcharts returns base64 text,\n * visual returns JSON), so this returns the raw Response on success.\n */\n\nexport type ServiceHeaders =\n | Record<string, string>\n | ((\n body: unknown\n ) => Record<string, string> | Promise<Record<string, string>>);\n\nconst DEFAULT_TIMEOUT_MS = 30000;\n\n/**\n * Resolve a service base URL: per-call override → services config → default.\n * Adds an `http://` scheme to a bare host and strips trailing slashes so callers\n * can append `${url}/path` without producing a `//path` that breaks routers.\n */\nexport function resolveServiceUrl(\n propsUrl: string | undefined,\n servicesUrl: string | undefined,\n defaultUrl: string\n): string {\n const raw = (propsUrl || servicesUrl || defaultUrl).trim();\n const withScheme = /^https?:\\/\\//i.test(raw) ? raw : `http://${raw}`;\n return withScheme.replace(/\\/+$/, '');\n}\n\nexport interface PostJsonOptions {\n /** Resolved base URL (use resolveServiceUrl). */\n url: string;\n /** Path appended to the base URL, e.g. '/export' or '/rasterize'. */\n path: string;\n /** Request body (JSON-serialized). */\n body: unknown;\n /** Static headers or an async resolver receiving the body. */\n headers?: ServiceHeaders;\n /** Abort timeout in ms (default 30s). */\n timeoutMs?: number;\n /** Label used in the timeout message and the non-2xx error. */\n serviceLabel: string;\n /** Message builder for a connection failure (distinct from a timeout). */\n onUnreachable: (url: string, cause: string) => string;\n}\n\n/**\n * POST a JSON body to `${url}${path}` with a timeout. Returns the Response on a\n * 2xx; throws a normalized Error on timeout, connection failure, or non-2xx.\n */\nexport async function postJsonToService(\n opts: PostJsonOptions\n): Promise<Response> {\n const resolvedHeaders =\n typeof opts.headers === 'function'\n ? await opts.headers(opts.body)\n : opts.headers;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...resolvedHeaders,\n };\n\n const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let response: Response;\n try {\n response = await fetch(`${opts.url}${opts.path}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts.body),\n signal: controller.signal,\n });\n } catch (error) {\n if ((error as Error)?.name === 'AbortError') {\n throw new Error(\n `${opts.serviceLabel} timed out after ${timeoutMs}ms at ${opts.url}.`\n );\n }\n const cause = error instanceof Error ? error.message : String(error);\n throw new Error(opts.onUnreachable(opts.url, cause));\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n throw new Error(\n `${opts.serviceLabel} returned ${response.status}: ${response.statusText}`\n );\n }\n return response;\n}\n","/**\n * Visual Component\n *\n * Renders a free-canvas graphic authored as a single pptx slide and embeds it\n * as a rasterized PNG. The slide is rendered to an image by an injected\n * rasterization service (`services.pptx`) — exactly the way the `highcharts`\n * component offloads chart rendering to an export server — then desugars to a\n * plain `image`.\n */\n\nimport { Paragraph, Table } from 'docx';\nimport {\n ComponentDefinition,\n RenderContext,\n isVisualComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createImage, type ImageOptions } from '../core/content';\nimport { isNodeEnvironment } from '../utils/environment';\nimport { resolveServiceUrl, postJsonToService } from '../utils/serviceClient';\n\nimport type { VisualProps } from '@json-to-office/shared-docx';\nimport {\n clampVisualDpi,\n DEFAULT_VISUAL_DPI,\n type PptxServiceConfig,\n type PptxRasterizeResult,\n} from '@json-to-office/shared';\n\nconst DEFAULT_RASTERIZE_SERVER_URL = 'http://localhost:7802';\n/** 1 inch = 96 CSS pixels — used to size the embedded image at its physical canvas size. */\nconst PIXELS_PER_INCH = 96;\n\n/**\n * Build a single-slide pptx presentation component definition from visual props.\n * The shape mirrors a normal `.pptx.json` document so the pptx engine renders\n * it unchanged. Exported for reuse by the `flattenVisuals` transform.\n */\nexport function buildVisualPresentation(\n props: VisualProps\n): Record<string, unknown> {\n const { canvas, elements } = props;\n\n const presentationProps: Record<string, unknown> = {\n slideWidth: canvas.width,\n slideHeight: canvas.height,\n };\n if (canvas.theme) presentationProps.theme = canvas.theme;\n\n const slideProps: Record<string, unknown> = {};\n if (canvas.background) slideProps.background = canvas.background;\n\n return {\n name: 'pptx',\n props: presentationProps,\n children: [\n {\n name: 'slide',\n props: slideProps,\n children: elements ?? [],\n },\n ],\n };\n}\n\n/**\n * Default rendered width (px) for a visual: its physical canvas inches, so a\n * 6×4 canvas prints 6×4 unless `width` overrides.\n */\nexport function defaultVisualWidthPx(props: VisualProps): number {\n return Math.round(props.canvas.width * PIXELS_PER_INCH);\n}\n\n/**\n * Shared image-placement options derived from a visual's props. Used by BOTH\n * the render-time createImage call and the flatten transform so the two\n * desugaring paths can't drift (width default, alignment default, caption,\n * spacing, floating, keepNext/keepLines all live here once).\n */\nexport function visualToImageOptions(props: VisualProps): ImageOptions {\n return {\n width: props.width ?? defaultVisualWidthPx(props),\n ...(props.height !== undefined && { height: props.height }),\n alignment: props.alignment ?? 'center',\n ...(props.caption !== undefined && { caption: props.caption }),\n ...(props.spacing !== undefined && { spacing: props.spacing }),\n ...(props.floating !== undefined && { floating: props.floating }),\n ...(props.keepNext !== undefined && { keepNext: props.keepNext }),\n ...(props.keepLines !== undefined && { keepLines: props.keepLines }),\n };\n}\n\n/**\n * Map visual props to the `image` props they desugar to (used by the\n * `flattenVisuals` transform to produce a portable, service-free document).\n */\nexport function visualToImageProps(\n props: VisualProps,\n base64DataUri: string\n): Record<string, unknown> {\n return {\n base64: base64DataUri,\n ...visualToImageOptions(props),\n ...(props.alt !== undefined && { alt: props.alt }),\n };\n}\n\n/**\n * Rasterize a single-slide presentation to a PNG via the configured service.\n * An in-process `render` callback takes precedence over an HTTP `serverUrl`.\n */\nasync function rasterize(\n presentation: Record<string, unknown>,\n dpi: number,\n propsServerUrl: string | undefined,\n serviceConfig: PptxServiceConfig | undefined\n): Promise<PptxRasterizeResult> {\n if (!isNodeEnvironment()) {\n throw new Error(\n 'Visual rasterization requires a Node.js environment. ' +\n 'It is not available in browser environments.'\n );\n }\n\n // In-process renderer wins (ideal for tests and single-process hosts).\n if (serviceConfig?.render) {\n return serviceConfig.render({ presentation, dpi });\n }\n\n const serverUrl = resolveServiceUrl(\n propsServerUrl,\n serviceConfig?.serverUrl,\n DEFAULT_RASTERIZE_SERVER_URL\n );\n\n const response = await postJsonToService({\n url: serverUrl,\n path: '/rasterize',\n body: { presentation, dpi },\n headers: serviceConfig?.headers,\n serviceLabel: 'PPTX rasterization service',\n onUnreachable: (url, cause) =>\n `PPTX rasterization service is not reachable at ${url}. ` +\n 'Configure services.pptx with a `render` callback or a running `serverUrl`.\\n' +\n `Cause: ${cause}`,\n });\n\n let result: PptxRasterizeResult;\n try {\n result = (await response.json()) as PptxRasterizeResult;\n } catch {\n throw new Error(\n 'PPTX rasterization service returned a non-JSON response (expected { base64DataUri, width, height }).'\n );\n }\n if (!result?.base64DataUri) {\n throw new Error(\n 'PPTX rasterization service returned a malformed response (missing base64DataUri).'\n );\n }\n return result;\n}\n\n/**\n * Render visual component\n */\nexport async function renderVisualComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName?: string,\n context?: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isVisualComponent(component)) return [];\n\n const props = component.props as VisualProps;\n const serviceConfig = context?.services?.pptx;\n\n const presentation = buildVisualPresentation(props);\n const dpi = clampVisualDpi(\n props.dpi ?? serviceConfig?.dpi ?? DEFAULT_VISUAL_DPI\n );\n\n const result = await rasterize(\n presentation,\n dpi,\n props.serverUrl,\n serviceConfig\n );\n\n // Size and placement options are derived once in visualToImageOptions (shared\n // with the flatten transform): default width = canvas physical inches; height\n // left unset so aspect ratio is preserved from the PNG.\n return await createImage(\n result.base64DataUri,\n theme,\n themeName,\n visualToImageOptions(props)\n );\n}\n","/**\n * Text Space After Custom Component\n * A text component with hardcoded spacing after the paragraph\n *\n * This component is provided as an example of the legacy custom component system.\n * For new custom components, use the plugin system instead:\n * @see packages/core/src/plugin/example/ for modern examples\n */\n\nimport { Type, Static } from '@sinclair/typebox';\nimport { createComponent, createVersion } from '../plugin/createComponent';\nimport type { ComponentDefinition } from '@json-to-office/shared-docx';\n\n/**\n * Props schema for text-space-after component\n */\nconst TextSpaceAfterPropsSchema = Type.Object({\n text: Type.String({\n description: 'Text content to display',\n }),\n // Retained for backwards compatibility of props shape, but not applied\n spacing: Type.Optional(\n Type.Object({\n before: Type.Optional(Type.Number()),\n after: Type.Optional(Type.Number()),\n })\n ),\n});\n\nexport type TextSpaceAfterProps = Static<typeof TextSpaceAfterPropsSchema>;\n\n/**\n * Text space after component - adds hardcoded spacing after paragraphs\n */\nexport const textSpaceAfterComponent = createComponent({\n name: 'text-space-after',\n versions: {\n '1.0.0': createVersion({\n propsSchema: TextSpaceAfterPropsSchema,\n description: 'Text component with hardcoded spacing after the paragraph',\n render: async ({ props }) => {\n // Create paragraph component with hardcoded spacing after\n const result: ComponentDefinition = {\n name: 'paragraph',\n props: {\n text: props.text,\n spacing: {\n ...props.spacing,\n after: props.spacing?.after || 12,\n },\n },\n };\n\n return [result];\n },\n }),\n },\n});\n","import type { TSchema } from '@sinclair/typebox';\nimport type { ComponentDefinition } from '@json-to-office/shared-docx';\nimport type { ThemeConfig } from '../styles';\nimport {\n createVersion as sharedCreateVersion,\n createComponent as sharedCreateComponent,\n} from '@json-to-office/shared/plugin';\nimport type {\n RenderContext as SharedRenderContext,\n RenderFunction as SharedRenderFunction,\n ComponentVersion as SharedComponentVersion,\n ComponentVersionMap as SharedComponentVersionMap,\n CustomComponent as SharedCustomComponent,\n} from '@json-to-office/shared/plugin';\n\n// ---- DOCX-specific type aliases (backward compat) ----\n\n/**\n * DOCX render context with ThemeConfig baked in\n */\nexport type RenderContext<T> = SharedRenderContext<T, ThemeConfig>;\n\nexport type RenderFunction<\n TProps,\n TComponentDefinition = ComponentDefinition,\n> = SharedRenderFunction<TProps, TComponentDefinition, ThemeConfig>;\n\nexport type ComponentVersion<\n TComponentDefinition = ComponentDefinition,\n TPropsSchema extends TSchema = TSchema,\n> = SharedComponentVersion<TComponentDefinition, TPropsSchema, ThemeConfig>;\n\nexport type ComponentVersionMap<TComponentDefinition = ComponentDefinition> =\n SharedComponentVersionMap<TComponentDefinition, ThemeConfig>;\n\nexport type CustomComponent<\n TComponentDefinition = ComponentDefinition,\n TVersions extends\n ComponentVersionMap<TComponentDefinition> = ComponentVersionMap<TComponentDefinition>,\n TName extends string = string,\n> = SharedCustomComponent<TComponentDefinition, TVersions, TName>;\n\n// ---- Re-export factory functions (thin wrappers for DOCX defaults) ----\n\nexport function createVersion<\n TPropsSchema extends TSchema,\n TComponentDefinition = ComponentDefinition,\n>(\n version: ComponentVersion<TComponentDefinition, TPropsSchema>\n): ComponentVersion<TComponentDefinition, TPropsSchema> {\n return sharedCreateVersion(version);\n}\n\nexport function createComponent<\n TComponentDefinition = ComponentDefinition,\n TVersions extends\n ComponentVersionMap<TComponentDefinition> = ComponentVersionMap<TComponentDefinition>,\n TName extends string = string,\n>(\n component: CustomComponent<TComponentDefinition, TVersions, TName>\n): CustomComponent<TComponentDefinition, TVersions, TName> {\n return sharedCreateComponent(component);\n}\n","/**\n * Shared font-resolution helper used by BOTH entry paths into renderDocument:\n *\n * - generator.ts → generateDocumentWithCustomThemes (non-plugin)\n * - plugin/createDocumentGenerator.ts → generate (plugin-aware)\n *\n * Keeping it in one place ensures the two paths behave identically around\n * validation, SAFE_FONTS awareness, Google Fonts materialization, and the\n * `onResolved` side-channel consumed by the LibreOffice preview font stager.\n */\n\nimport type {\n FontRuntimeOpts,\n ResolvedFont,\n GenerationWarning,\n} from '@json-to-office/shared';\nimport {\n collectFontNamesFromDocx,\n validateFontReferences,\n FontRegistry,\n} from '@json-to-office/shared';\nimport {\n loadFileFontSource,\n FontDiskCache,\n fetchVariableFontSource,\n} from '@json-to-office/shared/fonts/node';\nimport type { ThemeConfig } from '../styles';\nimport type { ReportComponentDefinition } from '../types';\n\nexport async function resolveDocumentFonts(\n document: ReportComponentDefinition,\n theme: ThemeConfig,\n fonts?: FontRuntimeOpts,\n warnings?: GenerationWarning[]\n): Promise<ResolvedFont[]> {\n const emit = (code: string, message: string) => {\n if (warnings) {\n warnings.push({\n component: 'fontRegistry',\n message,\n severity: 'warning',\n context: { code },\n });\n } else {\n // eslint-disable-next-line no-console\n console.warn(`[json-to-docx] ${code}: ${message}`);\n }\n };\n\n // Walk document + theme. The document typically names fonts only indirectly\n // via `theme: \"my-theme\"`, so fonts declared in the theme JSON would be\n // invisible without this second pass.\n const names = new Set<string>();\n for (const n of collectFontNamesFromDocx(document)) names.add(n);\n for (const n of collectFontNamesFromDocx(theme as unknown)) names.add(n);\n if (names.size === 0) return [];\n\n // Validate unconditionally — strict mode must fire even when no consumer\n // is listening via onResolved (CLI / library callers that just want\n // build-time validation of font references).\n const validation = validateFontReferences({\n referencedNames: names,\n registeredEntries: fonts?.extraEntries,\n });\n if (validation.warnings.length > 0) {\n if (fonts?.strict) {\n throw new Error(\n `Unresolved font references (strict mode):\\n` +\n validation.warnings.map((w) => ` - ${w.message}`).join('\\n')\n );\n }\n for (const w of validation.warnings) {\n emit(w.code, w.message);\n }\n }\n\n // Registry resolution (Google/URL/file fetches) only runs when a consumer\n // is listening via onResolved — typically the LibreOffice preview stager.\n // Office output never embeds bytes, so skipping fetches when nobody cares\n // keeps library callers from paying network cost.\n if (!fonts?.onResolved) return [];\n\n const registry = new FontRegistry({\n opts: fonts,\n fileLoader: loadFileFontSource,\n variableLoader: fetchVariableFontSource,\n diskCache: fonts?.googleFonts?.cacheDir\n ? new FontDiskCache(fonts.googleFonts.cacheDir)\n : undefined,\n });\n const resolved = await registry.resolveMany(names);\n for (const r of resolved) {\n for (const msg of r.warnings) {\n emit('FONT_UNRESOLVED', msg);\n }\n }\n // Fire the side-channel here so callers never have to remember. The\n // short-circuit above guarantees we only reach this point when a\n // listener is registered.\n fonts.onResolved(resolved);\n return resolved;\n}\n","import AdmZip from 'adm-zip';\nimport { type Document, Packer } from 'docx';\nimport { fixFloatingImageIdsInBuffer } from './fixFloatingImageIds';\n\nexport interface DocumentPackageOptions {\n /** Normalize volatile OOXML metadata and ZIP timestamps. Defaults to true. */\n deterministic?: boolean;\n /** Timestamp used for generated metadata. Defaults to a stable epoch. */\n generatedAt?: string | Date;\n}\n\n/** Stable, valid OOXML/ZIP timestamp used when no build timestamp is supplied. */\nexport const DEFAULT_GENERATION_DATE = new Date('2000-01-01T00:00:00.000Z');\n\nexport function resolveGenerationDate(options?: DocumentPackageOptions): Date {\n if (options?.generatedAt !== undefined) {\n const date = new Date(options.generatedAt);\n if (Number.isNaN(date.getTime())) {\n throw new RangeError('generatedAt must be a valid date');\n }\n if (date.getUTCFullYear() < 1980) {\n throw new RangeError(\n 'generatedAt must be on or after 1980-01-01 for ZIP compatibility'\n );\n }\n return date;\n }\n\n return options?.deterministic === false\n ? new Date()\n : new Date(DEFAULT_GENERATION_DATE);\n}\n\n/** Encode a UTC instant into the packed MS-DOS date/time field ZIP headers use. */\nfunction toDosTime(date: Date): number {\n const dosDate =\n (((date.getUTCFullYear() - 1980) & 0x7f) << 9) |\n ((date.getUTCMonth() + 1) << 5) |\n date.getUTCDate();\n const dosTime =\n (date.getUTCHours() << 11) |\n (date.getUTCMinutes() << 5) |\n (date.getUTCSeconds() >> 1);\n return ((dosDate << 16) | dosTime) >>> 0;\n}\n\n/**\n * Normalize package-level values that otherwise change on every render.\n * ZIP headers are written from UTC components because DOS timestamps carry no\n * timezone; this produces identical header bits in every locale.\n */\nexport function canonicalizeDocxBuffer(\n buffer: Buffer,\n generatedAt: Date = DEFAULT_GENERATION_DATE\n): Buffer {\n const zip = new AdmZip(buffer);\n const isoTimestamp = generatedAt.toISOString();\n const coreProperties = zip.getEntry('docProps/core.xml');\n\n if (coreProperties) {\n const normalized = coreProperties\n .getData()\n .toString('utf8')\n .replace(\n /(<dcterms:(?:created|modified)\\b[^>]*>)[^<]*(<\\/dcterms:(?:created|modified)>)/g,\n `$1${isoTimestamp}$2`\n );\n zip.updateFile(coreProperties, Buffer.from(normalized, 'utf8'));\n }\n\n // AdmZip's `header.time` setter encodes the timezone-less DOS field from\n // local getters, so the emitted bits would vary by host. Write the raw field\n // from UTC components instead. Going through a reconstructed local Date is\n // not enough: a value inside a DST spring-forward gap has no local\n // representation and the runtime silently shifts it an hour.\n // `timeval` is the raw DOS field; @types/adm-zip@0.5.7 only declares the\n // `time` Date accessor that wraps it, hence the cast.\n const zipTimestamp = toDosTime(generatedAt);\n for (const entry of zip.getEntries()) {\n (entry.header as unknown as { timeval: number }).timeval = zipTimestamp;\n }\n\n return zip.toBuffer();\n}\n\n/** Package a DOCX and apply all required OOXML post-processing once. */\nexport async function packageDocument(\n document: Document,\n options?: DocumentPackageOptions\n): Promise<Buffer> {\n const packed = (await Packer.toBuffer(document)) as Buffer;\n const fixed = fixFloatingImageIdsInBuffer(packed);\n\n if (options?.deterministic === false) {\n return fixed;\n }\n\n return canonicalizeDocxBuffer(fixed, resolveGenerationDate(options));\n}\n","/**\n * Post-processing utility to fix docx.js floating image bugs\n *\n * The docx library (as of v9.5.1) has a known issue with floating images:\n * 1. Duplicate wp:docPr IDs (GitHub issue #2719)\n *\n * Historical note: We previously also post-processed relativeHeight and\n * wrapTight elements. Those steps were removed because we always provide a\n * valid zIndex upstream and we do not support 'tight' wrapping.\n *\n * This utility extracts the DOCX, fixes duplicate IDs, and re-packages it.\n */\n\nimport AdmZip from 'adm-zip';\nimport { readFile, writeFile } from 'fs/promises';\n\n/** Fix duplicate floating-image IDs without touching the filesystem. */\nexport function fixFloatingImageIdsInBuffer(buffer: Buffer): Buffer {\n const zip = new AdmZip(buffer);\n const documentEntry = zip.getEntry('word/document.xml');\n\n if (!documentEntry) {\n throw new Error('document.xml not found in DOCX');\n }\n\n let idCounter = 1;\n const documentXml = documentEntry\n .getData()\n .toString('utf8')\n .replace(/<wp:docPr\\s+id=\"(\\d+)\"/g, () => {\n const newId = idCounter++;\n return `<wp:docPr id=\"${newId}\"`;\n });\n\n zip.updateFile(documentEntry, Buffer.from(documentXml, 'utf8'));\n return zip.toBuffer();\n}\n\n/**\n * Fix floating image issues in a generated DOCX file\n * @param docxPath - Path to the DOCX file to fix\n */\nexport async function fixFloatingImageIds(docxPath: string): Promise<void> {\n const buffer = await readFile(docxPath);\n await writeFile(docxPath, fixFloatingImageIdsInBuffer(buffer));\n}\n","/**\n * JSON Document Parser - Re-exports from shared package\n *\n * This module re-exports the JSON parsing functionality from the shared package\n * and provide a clean interface for the core package.\n */\n\n// Re-export everything from shared package's JSON parser\nexport {\n JsonDocumentParser,\n JsonParsingError,\n JsonValidationError,\n parseJsonComponent,\n validateJsonComponent,\n parseJsonWithLineNumbers,\n} from '@json-to-office/shared-docx';\n\n// Re-export types needed by other modules\nexport type {\n DocumentValidationResult,\n DocumentValidationError,\n} from '@json-to-office/shared-docx';\n","/**\n * Component Normalizer - Transforms JSON components where business logic requires it\n *\n * This module ONLY handles transformations that are actually necessary:\n * 1. Columns shorthand notation (columns: 3 → array format)\n * 2. Recursive processing of nested components\n * 3. Gap application for columns\n *\n * All other properties are preserved as-is from TypeBox validation.\n * This prevents information loss and maintains single source of truth.\n */\n\nimport {\n ComponentDefinition,\n ReportComponentDefinition,\n SectionComponentDefinition,\n ColumnsComponentDefinition,\n ColumnsProps,\n} from '../types';\n\n/**\n * Normalize a component definition and its nested children\n * Preserves all validated properties - only transforms where business logic requires\n */\nexport function normalizeComponent(\n component: ComponentDefinition\n): ComponentDefinition {\n // Handle columns component with shorthand notation\n if (component.name === 'columns') {\n return normalizeColumnsComponent(component as ColumnsComponentDefinition);\n }\n\n // Handle components with children - recursively normalize\n if ('children' in component && component.children) {\n return {\n ...component, // Preserve ALL properties from validated component\n children: component.children.map(normalizeComponent),\n } as ComponentDefinition;\n }\n\n // Handle section component with header/footer arrays\n if (component.name === 'section') {\n return normalizeSectionComponent(component as SectionComponentDefinition);\n }\n\n // All other components: return as-is (already validated by TypeBox)\n return component;\n}\n\n/**\n * Normalize columns component\n * Converts shorthand notation and applies gap logic\n */\nfunction normalizeColumnsComponent(\n component: ColumnsComponentDefinition\n): ColumnsComponentDefinition {\n const cfg = component.props || ({} as any);\n\n // Helper: apply top-level gap to all columns except last where not overridden\n const applyTopLevelGap = (\n cols: Array<{ width?: unknown; gap?: unknown }>,\n topGap: unknown\n ) =>\n cols.map((c, i) => {\n const isLast = i === cols.length - 1;\n if (!isLast && c.gap === undefined && topGap !== undefined) {\n return { ...c, gap: topGap };\n }\n return c;\n });\n\n // Helper: normalize 'auto' to unspecified width (internal layout splits remainder)\n const normalizeAutoWidth = (\n cols: Array<{ width?: unknown; gap?: unknown }>\n ) =>\n cols.map((c) => ({\n ...c,\n width: c.width === 'auto' ? undefined : c.width,\n }));\n\n let columnsArray: Array<{ width?: unknown; gap?: unknown }>;\n\n if (typeof cfg.columns === 'number' && cfg.columns > 0) {\n // Shorthand: N equal-width columns; apply gap after each except last\n const n = cfg.columns as number;\n const base = Array.from(\n { length: n },\n () => ({}) as { width?: unknown; gap?: unknown }\n );\n const topLevelGap = cfg.gap !== undefined ? cfg.gap : '5%';\n columnsArray = applyTopLevelGap(base, topLevelGap);\n } else if (Array.isArray(cfg.columns)) {\n // Array form; honor per-column config\n columnsArray = cfg.columns as Array<{ width?: unknown; gap?: unknown }>;\n // Apply top-level gap unless column overrides; skip last column\n const topLevelGap = cfg.gap !== undefined ? cfg.gap : '5%';\n columnsArray = applyTopLevelGap(columnsArray, topLevelGap);\n // Normalize 'auto' widths to unspecified so layout can allocate remainder\n columnsArray = normalizeAutoWidth(columnsArray);\n } else {\n // Minimal valid shape\n columnsArray = [{}];\n }\n\n const normalizedProps: ColumnsProps = {\n columns: columnsArray,\n } as ColumnsProps;\n\n return {\n ...component, // Preserve any additional properties\n name: 'columns',\n props: normalizedProps,\n children: component.children\n ? component.children.map(normalizeComponent)\n : undefined,\n };\n}\n\n/**\n * Normalize section component\n * Handles recursive processing of header/footer component arrays\n */\nfunction normalizeSectionComponent(\n component: SectionComponentDefinition\n): SectionComponentDefinition {\n const props = component.props || ({} as any);\n\n return {\n ...component, // Preserve ALL properties\n props: {\n ...props, // Preserve ALL props properties\n header: props.header\n ? props.header === 'linkToPrevious'\n ? 'linkToPrevious'\n : props.header.map((m: ComponentDefinition) => normalizeComponent(m))\n : undefined,\n footer: props.footer\n ? props.footer === 'linkToPrevious'\n ? 'linkToPrevious'\n : props.footer.map((m: ComponentDefinition) => normalizeComponent(m))\n : undefined,\n },\n children: component.children\n ? component.children.map(normalizeComponent)\n : undefined,\n };\n}\n\n/**\n * Normalize entire document (top-level report component)\n * Returns as single-element tuple for backward compatibility\n */\nexport function normalizeDocument(\n document: ComponentDefinition | ReportComponentDefinition\n): [ReportComponentDefinition] {\n // Validate it's a report component\n if (document.name !== 'docx') {\n throw new Error(\n 'Top-level document must be a docx component with name=\"docx\"'\n );\n }\n\n const normalized = normalizeComponent(document) as ReportComponentDefinition;\n return [normalized];\n}\n\n/**\n * Validate component structure (container vs content components)\n */\nexport function validateComponentStructure(component: any): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n\n // Components that can have children\n const containerComponents = ['docx', 'section', 'columns', 'text-box'];\n\n // Check if content components have children (they shouldn't)\n if (\n !containerComponents.includes(component.name) &&\n component.children &&\n component.children.length > 0\n ) {\n errors.push(\n `Component name \"${component.name}\" cannot have child components`\n );\n }\n\n // Recursively validate child components\n if (component.children) {\n component.children.forEach(\n (childComponent: ComponentDefinition, index: number) => {\n const childResult = validateComponentStructure(childComponent);\n if (!childResult.valid) {\n errors.push(\n ...childResult.errors.map(\n (error) => `Component[${index}]: ${error}`\n )\n );\n }\n }\n );\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","import { promises as fs } from 'fs';\nimport { join, resolve, isAbsolute } from 'path';\nimport { watch, FSWatcher } from 'fs';\nimport { ComponentDefinition } from '@json-to-office/shared-docx';\nimport { parseJsonWithLineNumbers } from './parser';\n\n/**\n * File System utilities for JSON report definitions\n */\n\n/**\n * Load JSON report definition from file\n * Supports both relative and absolute file paths\n */\nexport async function loadJsonDefinition(\n filePath: string\n): Promise<ComponentDefinition> {\n try {\n // Resolve path (handles both relative and absolute paths)\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(filePath);\n\n // Check if file exists\n await fs.access(absolutePath);\n\n // Read file content\n const fileContent = await fs.readFile(absolutePath, 'utf-8');\n\n // Parse JSON with line number tracking for better errors\n return parseJsonWithLineNumbers(fileContent) as ComponentDefinition;\n } catch (error) {\n if (error instanceof Error && 'code' in error) {\n const fsError = error as Error & { code?: string };\n\n switch (fsError.code) {\n case 'ENOENT':\n throw new JsonFileError(\n `File not found: ${filePath}`,\n 'FILE_NOT_FOUND'\n );\n case 'EACCES':\n throw new JsonFileError(\n `Permission denied: ${filePath}`,\n 'PERMISSION_DENIED'\n );\n case 'EISDIR':\n throw new JsonFileError(\n `Path is a directory: ${filePath}`,\n 'IS_DIRECTORY'\n );\n default:\n throw new JsonFileError(\n `File system error: ${fsError.message}`,\n 'FS_ERROR'\n );\n }\n }\n\n // Re-throw parsing errors with file context\n if (error instanceof Error) {\n throw new JsonFileError(\n `Error loading ${filePath}: ${error.message}`,\n 'PARSE_ERROR',\n error\n );\n }\n\n throw new JsonFileError(\n `Unknown error loading ${filePath}`,\n 'UNKNOWN_ERROR'\n );\n }\n}\n\n/**\n * Load JSON definition with validation but without throwing on validation errors\n */\nexport async function loadJsonDefinitionSafe(filePath: string): Promise<{\n success: boolean;\n definition?: ComponentDefinition;\n error?: JsonFileError;\n}> {\n try {\n const definition = await loadJsonDefinition(filePath);\n return { success: true, definition };\n } catch (error) {\n return {\n success: false,\n error:\n error instanceof JsonFileError\n ? error\n : new JsonFileError(\n error instanceof Error ? error.message : String(error),\n 'UNKNOWN_ERROR'\n ),\n };\n }\n}\n\n/**\n * Watch JSON file for changes and call callback on modifications\n * Useful for development workflows\n */\nexport function watchJsonFile(\n filePath: string,\n callback: (\n _definition: ComponentDefinition | null,\n _error?: JsonFileError\n ) => void\n): JsonFileWatcher {\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(filePath);\n\n // Initial load\n loadJsonDefinitionSafe(absolutePath).then((result) => {\n if (result.success) {\n callback(result.definition!);\n } else {\n callback(null, result.error);\n }\n });\n\n // Set up file watcher\n const watcher = watch(absolutePath, { persistent: true }, (eventType) => {\n if (eventType === 'change') {\n // Debounce rapid file changes\n setTimeout(async () => {\n const result = await loadJsonDefinitionSafe(absolutePath);\n if (result.success) {\n callback(result.definition!);\n } else {\n callback(null, result.error);\n }\n }, 100);\n }\n });\n\n return new JsonFileWatcher(watcher, absolutePath);\n}\n\n/**\n * Watch multiple JSON files and call callback when any changes\n */\nexport function watchJsonFiles(\n filePaths: string[],\n callback: (\n _filePath: string,\n _definition: ComponentDefinition | null,\n _error?: JsonFileError\n ) => void\n): JsonFileWatcher[] {\n return filePaths.map((filePath) => {\n return watchJsonFile(filePath, (definition, error) => {\n callback(filePath, definition, error);\n });\n });\n}\n\n/**\n * Check if file exists and is accessible\n */\nexport async function checkJsonFile(filePath: string): Promise<{\n exists: boolean;\n readable: boolean;\n isDirectory: boolean;\n error?: string;\n}> {\n try {\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(filePath);\n const stats = await fs.stat(absolutePath);\n\n return {\n exists: true,\n readable: true,\n isDirectory: stats.isDirectory(),\n };\n } catch (error) {\n if (error instanceof Error && 'code' in error) {\n const fsError = error as Error & { code?: string };\n\n switch (fsError.code) {\n case 'ENOENT':\n return {\n exists: false,\n readable: false,\n isDirectory: false,\n error: 'File not found',\n };\n case 'EACCES':\n return {\n exists: true,\n readable: false,\n isDirectory: false,\n error: 'Permission denied',\n };\n default:\n return {\n exists: false,\n readable: false,\n isDirectory: false,\n error: fsError.message,\n };\n }\n }\n\n return {\n exists: false,\n readable: false,\n isDirectory: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Find JSON files in a directory (non-recursive)\n */\nexport async function findJsonFiles(directoryPath: string): Promise<string[]> {\n try {\n const absolutePath = isAbsolute(directoryPath)\n ? directoryPath\n : resolve(directoryPath);\n const entries = await fs.readdir(absolutePath, { withFileTypes: true });\n\n return entries\n .filter((entry) => entry.isFile() && entry.name.endsWith('.json'))\n .map((entry) => join(absolutePath, entry.name));\n } catch (error) {\n if (error instanceof Error && 'code' in error) {\n const fsError = error as Error & { code?: string };\n\n switch (fsError.code) {\n case 'ENOENT':\n throw new JsonFileError(\n `Directory not found: ${directoryPath}`,\n 'DIRECTORY_NOT_FOUND'\n );\n case 'ENOTDIR':\n throw new JsonFileError(\n `Path is not a directory: ${directoryPath}`,\n 'NOT_DIRECTORY'\n );\n case 'EACCES':\n throw new JsonFileError(\n `Permission denied: ${directoryPath}`,\n 'PERMISSION_DENIED'\n );\n default:\n throw new JsonFileError(\n `Directory error: ${fsError.message}`,\n 'DIRECTORY_ERROR'\n );\n }\n }\n\n throw new JsonFileError(\n `Unknown error reading directory ${directoryPath}`,\n 'UNKNOWN_ERROR'\n );\n }\n}\n\n/**\n * Save JSON report definition to file\n */\nexport async function saveJsonDefinition(\n definition: ComponentDefinition,\n filePath: string,\n options: { pretty?: boolean; backup?: boolean } = {}\n): Promise<void> {\n const { pretty = true, backup = false } = options;\n\n try {\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(filePath);\n\n // Create backup if requested\n if (backup) {\n try {\n const backupPath = `${absolutePath}.backup`;\n await fs.copyFile(absolutePath, backupPath);\n } catch (error) {\n // Ignore backup errors if original file doesn't exist\n if (\n error instanceof Error &&\n 'code' in error &&\n (error as Error & { code?: string }).code !== 'ENOENT'\n ) {\n console.warn(`Failed to create backup: ${error.message}`);\n }\n }\n }\n\n // Serialize JSON\n const jsonContent = pretty\n ? JSON.stringify(definition, null, 2)\n : JSON.stringify(definition);\n\n // Write file\n await fs.writeFile(absolutePath, jsonContent, 'utf-8');\n } catch (error) {\n if (error instanceof Error && 'code' in error) {\n const fsError = error as Error & { code?: string };\n\n switch (fsError.code) {\n case 'EACCES':\n throw new JsonFileError(\n `Permission denied: ${filePath}`,\n 'PERMISSION_DENIED'\n );\n case 'ENOSPC':\n throw new JsonFileError(\n `No space left on device: ${filePath}`,\n 'NO_SPACE'\n );\n default:\n throw new JsonFileError(\n `Write error: ${fsError.message}`,\n 'WRITE_ERROR'\n );\n }\n }\n\n throw new JsonFileError(\n `Unknown error saving ${filePath}`,\n 'UNKNOWN_ERROR'\n );\n }\n}\n\n/**\n * File watcher wrapper class\n */\nexport class JsonFileWatcher {\n private watcher: FSWatcher;\n private filePath: string;\n\n constructor(watcher: FSWatcher, filePath: string) {\n this.watcher = watcher;\n this.filePath = filePath;\n }\n\n /**\n * Stop watching the file\n */\n public close(): void {\n this.watcher.close();\n }\n\n /**\n * Get the watched file path\n */\n public getFilePath(): string {\n return this.filePath;\n }\n}\n\n/**\n * Custom error class for file system operations\n */\nexport class JsonFileError extends Error {\n public readonly code: string;\n public readonly originalError?: Error;\n\n constructor(message: string, code: string, originalError?: Error) {\n super(message);\n this.name = 'JsonFileError';\n this.code = code;\n this.originalError = originalError;\n }\n}\n\n/**\n * Utility function to validate JSON file extension\n */\nexport function hasJsonExtension(filePath: string): boolean {\n return filePath.toLowerCase().endsWith('.json');\n}\n\n/**\n * Utility to ensure a path has .json extension\n */\nexport function ensureJsonExtension(filePath: string): string {\n return hasJsonExtension(filePath) ? filePath : `${filePath}.json`;\n}\n","/**\n * flattenVisuals — desugar `visual` components to plain `image` components ahead\n * of time, producing a portable, service-free `.docx.json`.\n *\n * The normal pipeline rasterizes `visual` nodes at render time via\n * `services.pptx`. This transform does the same desugaring offline: walk the\n * document tree, rasterize each `visual` with the supplied rasterizer, and\n * replace it with `{ name: 'image', props: { base64, ... } }`. The result builds\n * with no rasterization service configured — handy for shipping documents that\n * generate on hosts without LibreOffice/poppler.\n *\n * The walk covers every place the docx model can hold a child component, not\n * just `children`: section `props.header`/`props.footer`, and table\n * `props.columns[].cells[].content` / `props.columns[].header.content`.\n */\n\nimport {\n clampVisualDpi,\n DEFAULT_VISUAL_DPI,\n type PptxRasterizer,\n} from '@json-to-office/shared';\nimport type { VisualProps } from '@json-to-office/shared-docx';\nimport {\n buildVisualPresentation,\n visualToImageProps,\n} from '../components/visual';\n\nconst DEFAULT_CONCURRENCY = 4;\n\nexport interface FlattenVisualsOptions {\n /** Rasterizer that turns a single-slide pptx presentation into a PNG. */\n rasterize: PptxRasterizer;\n /** Default DPI applied when a `visual` does not specify one (default 200). */\n dpi?: number;\n /** Max concurrent rasterizations (default 4). */\n concurrency?: number;\n}\n\ninterface FlattenCtx {\n rasterize: PptxRasterizer;\n dpi?: number;\n limit: <T>(fn: () => Promise<T>) => Promise<T>;\n}\n\n/** Minimal promise pool bounding concurrent rasterizations. */\nfunction createLimiter(max: number): <T>(fn: () => Promise<T>) => Promise<T> {\n let active = 0;\n const queue: Array<() => void> = [];\n const release = () => {\n active--;\n queue.shift()?.();\n };\n return async function limit<T>(fn: () => Promise<T>): Promise<T> {\n if (active >= max)\n await new Promise<void>((resolve) => queue.push(resolve));\n active++;\n try {\n return await fn();\n } finally {\n release();\n }\n };\n}\n\n/**\n * Return a deep copy of `doc` with every `visual` node replaced by the `image`\n * node it rasterizes to. Visuals rasterize with bounded concurrency. A\n * `visual` with `enabled: false` is left untouched (it's filtered out at render\n * anyway, so rasterizing it would be wasted work). Non-visual nodes are copied\n * structurally and otherwise unchanged.\n */\nexport async function flattenVisuals<T = unknown>(\n doc: T,\n options: FlattenVisualsOptions\n): Promise<T> {\n const ctx: FlattenCtx = {\n rasterize: options.rasterize,\n dpi: options.dpi,\n limit: createLimiter(\n Math.max(1, options.concurrency ?? DEFAULT_CONCURRENCY)\n ),\n };\n return (await flattenNode(doc, ctx)) as T;\n}\n\nasync function rasterizeVisual(\n obj: Record<string, unknown>,\n ctx: FlattenCtx\n): Promise<Record<string, unknown>> {\n const props = obj.props as VisualProps;\n const dpi = clampVisualDpi(props.dpi ?? ctx.dpi ?? DEFAULT_VISUAL_DPI);\n const result = await ctx.limit(() =>\n ctx.rasterize({ presentation: buildVisualPresentation(props), dpi })\n );\n const image: Record<string, unknown> = {\n name: 'image',\n props: visualToImageProps(props, result.base64DataUri),\n };\n // Preserve identity/visibility metadata from the original node.\n if (obj.id !== undefined) image.id = obj.id;\n if (obj.enabled !== undefined) image.enabled = obj.enabled;\n return image;\n}\n\nasync function flattenNode(node: unknown, ctx: FlattenCtx): Promise<unknown> {\n if (Array.isArray(node)) {\n return Promise.all(node.map((n) => flattenNode(n, ctx)));\n }\n if (!node || typeof node !== 'object') return node;\n\n const obj = node as Record<string, unknown>;\n\n // Replace an enabled visual with its rasterized image. A disabled visual is\n // left as-is (filtered at render; rasterizing it would be wasted work).\n if (obj.name === 'visual' && obj.props && obj.enabled !== false) {\n return rasterizeVisual(obj, ctx);\n }\n\n const next: Record<string, unknown> = { ...obj };\n\n if (Array.isArray(obj.children)) {\n next.children = await flattenNode(obj.children, ctx);\n }\n\n if (obj.props && typeof obj.props === 'object') {\n const props = obj.props as Record<string, unknown>;\n let propsChanged = false;\n const nextProps: Record<string, unknown> = { ...props };\n\n // Section header/footer: arrays of component definitions (or a literal\n // 'linkToPrevious' string, which flattenNode returns unchanged).\n for (const key of ['header', 'footer'] as const) {\n if (Array.isArray(props[key])) {\n nextProps[key] = await flattenNode(props[key], ctx);\n propsChanged = true;\n }\n }\n\n // Table columns: each cell's `content` and the column header's `content`\n // hold a component definition (or a string).\n if (Array.isArray(props.columns)) {\n nextProps.columns = await Promise.all(\n (props.columns as unknown[]).map((col) => flattenColumn(col, ctx))\n );\n propsChanged = true;\n }\n\n if (propsChanged) next.props = nextProps;\n }\n\n return next;\n}\n\nasync function flattenColumn(col: unknown, ctx: FlattenCtx): Promise<unknown> {\n if (!col || typeof col !== 'object') return col;\n const column = col as Record<string, unknown>;\n const nextCol: Record<string, unknown> = { ...column };\n\n const header = column.header as Record<string, unknown> | undefined;\n if (header && typeof header === 'object' && 'content' in header) {\n nextCol.header = {\n ...header,\n content: await flattenNode(header.content, ctx),\n };\n }\n\n if (Array.isArray(column.cells)) {\n nextCol.cells = await Promise.all(\n (column.cells as unknown[]).map(async (cell) => {\n if (cell && typeof cell === 'object' && 'content' in cell) {\n const c = cell as Record<string, unknown>;\n return { ...c, content: await flattenNode(c.content, ctx) };\n }\n return cell;\n })\n );\n }\n\n return nextCol;\n}\n","/**\n * Warnings Document Generator\n * Utility to generate a document from generation warnings\n */\n\nimport type { GenerationWarning } from '@json-to-office/shared-docx';\nimport type { ComponentDefinition, ReportComponentDefinition } from '../types';\n\n/**\n * Generate a report document from warnings\n * Returns null if there are no warnings\n */\nexport function generateWarningsDocument(\n warnings: GenerationWarning[] | null\n): ReportComponentDefinition | null {\n if (!warnings || warnings.length === 0) {\n return null;\n }\n\n const children: ComponentDefinition[] = [\n {\n name: 'heading',\n props: {\n level: 1,\n text: 'Document Generation Warnings',\n },\n },\n {\n name: 'paragraph',\n props: {\n text: `${warnings.length} warning(s) were generated during document processing.`,\n spacing: {\n after: 24,\n },\n },\n },\n ];\n\n // Group warnings by component\n const warningsByComponent = new Map<string, GenerationWarning[]>();\n for (const warning of warnings) {\n const existing = warningsByComponent.get(warning.component) || [];\n existing.push(warning);\n warningsByComponent.set(warning.component, existing);\n }\n\n // Create sections for each component with warnings\n for (const [componentName, componentWarnings] of warningsByComponent.entries()) {\n children.push({\n name: 'heading',\n props: {\n level: 3,\n text: `Component: ${componentName}`,\n },\n });\n\n // Add each warning as a list item with details\n const warningItems: string[] = [];\n for (const warning of componentWarnings) {\n let warningText = warning.message;\n\n // Add context if present\n if (warning.context && Object.keys(warning.context).length > 0) {\n const contextStr = Object.entries(warning.context)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ');\n warningText += ` (${contextStr})`;\n }\n\n warningItems.push(warningText);\n }\n\n children.push({\n name: 'list',\n props: {\n items: warningItems,\n spacing: {\n after: 12,\n },\n },\n });\n }\n\n return {\n name: 'docx',\n props: {\n metadata: {\n title: 'Generation Warnings',\n },\n theme: 'minimal',\n },\n children,\n };\n}\n\n/**\n * Format warnings as plain text\n * Useful for logging or text output\n */\nexport function formatWarningsText(\n warnings: GenerationWarning[] | null\n): string {\n if (!warnings || warnings.length === 0) {\n return 'No warnings generated.';\n }\n\n const lines: string[] = [\n `Document Generation Warnings (${warnings.length} total)`,\n '='.repeat(50),\n '',\n ];\n\n // Group by component\n const warningsByComponent = new Map<string, GenerationWarning[]>();\n for (const warning of warnings) {\n const existing = warningsByComponent.get(warning.component) || [];\n existing.push(warning);\n warningsByComponent.set(warning.component, existing);\n }\n\n for (const [componentName, componentWarnings] of warningsByComponent.entries()) {\n lines.push(`Component: ${componentName}`);\n lines.push('-'.repeat(30));\n\n for (let i = 0; i < componentWarnings.length; i++) {\n const warning = componentWarnings[i];\n lines.push(` ${i + 1}. ${warning.message}`);\n\n if (warning.context && Object.keys(warning.context).length > 0) {\n lines.push(` Context: ${JSON.stringify(warning.context, null, 2)}`);\n }\n }\n\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","// Version information\nexport function getCoreVersion(): string {\n return 'Core v1.0.0';\n}\n\n// Core functional API\nexport {\n generateDocument,\n generateFromConfig,\n generateDocumentFromJson,\n generateDocumentFromFile,\n generateBufferFromJson,\n generateBufferFromFile,\n generateAndSaveFromJson,\n generateAndSaveFromFile,\n validateJsonSchema,\n isReportComponentDefinition,\n saveDocument,\n generateAndSave,\n DocumentGenerator as CoreDocumentGenerator,\n} from './core/generator';\n\n// Visual flattening (desugar `visual` → `image` for portable, service-free docs)\nexport {\n flattenVisuals,\n type FlattenVisualsOptions,\n} from './core/flattenVisuals';\n\n// Cache API (general purpose caching, not specific to custom components)\nexport {\n MemoryCache,\n CacheKeyGenerator,\n DEFAULT_CACHE_CONFIG,\n getCacheConfigFromEnv,\n mergeConfigs,\n ComponentCacheAnalytics,\n // Types\n type CacheConfiguration,\n type CachedComponent,\n type CacheStatistics,\n type CacheKeyOptions,\n type CacheEvents,\n type CacheAnalyticsReport,\n type ComponentPerformanceMetrics,\n type ComponentCacheTrends,\n type CacheOptimizationRecommendation,\n type TimeSeriesPoint,\n} from './cache/index';\n\n// Component cache functions from core\nexport {\n initializeComponentCache,\n getComponentCache,\n clearComponentCache,\n getComponentCacheStats,\n warmComponentCache,\n} from './core/cached-render';\n\n// Legacy class-based API is now removed - use functional API above\n\n// Runtime exports (only type guards and functions)\nexport {\n // Type guards\n isReportComponent,\n isSectionComponent,\n isHeadingComponent,\n isParagraphComponent,\n isColumnsComponent,\n isImageComponent,\n isStatisticComponent,\n isTableComponent,\n isListComponent,\n isHighchartsComponent,\n isVisualComponent,\n} from './types/index';\n\n// Export core-specific types only\nexport type {\n // Core-specific types\n ImageContent,\n StatisticContent,\n TableData,\n SectionProperties,\n ColumnSettings,\n PageSizeOptions,\n PageMarginOptions,\n PageNumberOptions,\n PageBorderOptions,\n RenderContext,\n} from './types/index';\n\n// Utilities\nexport * from './utils/formatters';\nexport { parseTextWithDecorators } from './utils/textParser';\nexport { isNodeEnvironment, hasNodeBuiltins } from './utils/environment';\nexport {\n generateWarningsDocument,\n formatWarningsText,\n} from './utils/warningsDocument';\n\n// Styles and themes\nexport {\n themes,\n minimalTheme,\n corporateTheme,\n modernTheme,\n} from './styles/index';\nexport type { ThemeName } from './styles/index';\n\n// JSON Theme System\nexport {\n loadThemeFromJson,\n loadThemeFromFile,\n exportThemeToJson,\n validateThemeJsonString,\n ThemeValidationError,\n ThemeParseError,\n ThemeFileError,\n createMinimalTheme,\n} from './themes/json/index';\n\n// Examples and utilities\nexport {\n examples,\n getExample,\n getExampleNames,\n loadJsonExample,\n} from './templates/documents/index';\nexport { runExample } from './utils/exampleRunner';\n\n// Export component implementations\nimport './components/index';\n\n// Re-export types from components (excluding those that come from shared)\nexport type {\n // ChartGenerationResult is specific to the component implementation\n ChartGenerationResult,\n} from './components/highcharts';\n\n// Note: TextSpaceAfterProps and HighchartsProps types are now in shared package\n// and should be imported from there to maintain single source of truth\n\n// Plugin System API\nexport {\n // Core plugin functions\n createComponent,\n createVersion,\n createDocumentGenerator,\n\n // Validation utilities\n validateComponentProps,\n validateDocument,\n cleanComponentProps,\n ComponentValidationError,\n UnknownPreservedComponentError,\n\n // Schema utilities\n generatePluginDocumentSchema,\n exportPluginSchema,\n generateComponentSchemas,\n mergeSchemas,\n\n // Types\n type CustomComponent,\n type ComponentVersion,\n type ComponentVersionMap,\n type RenderFunction,\n type RenderContext as ComponentRenderContext,\n type DocumentGenerator,\n type DocumentGeneratorOptions,\n type GenerateOptions,\n type GenerateFileOptions,\n type GenerationResult,\n type BufferGenerationResult,\n type FileGenerationResult,\n type ValidationResult,\n type ValidationError,\n\n // Type utilities for custom components\n type ExtractCustomComponentType,\n type CustomComponentUnion,\n type ExtendedComponentDefinition,\n type ExtendedReportComponent,\n type InferCustomComponents,\n} from './plugin/index';\n\n// Plugin types\nexport type {\n PluginComponent,\n PluginRenderFunction,\n PluginValidationError,\n PluginValidationResult,\n} from './types/plugin';\n","/**\n * Examples registry - JSON-based examples\n * This file provides a unified interface to the JSON examples system\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { ComponentDefinition } from '@json-to-office/shared-docx';\n\nlet _dirname: string | null = null;\n\nfunction getDirname(): string {\n if (_dirname === null) {\n try {\n _dirname = path.dirname(fileURLToPath(import.meta.url));\n } catch {\n throw new Error(\n 'Cannot resolve file paths in a bundled environment. Example loading from disk is not available.'\n );\n }\n }\n return _dirname;\n}\n\n/**\n * Load a JSON example by name\n */\nexport function loadJsonExample(name: string): ComponentDefinition {\n // Since this file is bundled into dist/index.js, getDirname() will be the dist directory\n // The JSON files are copied to dist/templates/documents/ by the tsup config\n const filePath = path.join(\n getDirname(),\n 'templates',\n 'documents',\n `${name}.docx.json`\n );\n\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n return JSON.parse(content) as ComponentDefinition;\n } catch (error) {\n throw new Error(\n `Failed to load JSON example \"${name}\": ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Get list of available JSON examples\n */\nexport function getAvailableJsonExamples(): string[] {\n // Since this file is bundled into dist/index.js, getDirname() will be the dist directory\n // The JSON files are copied to dist/templates/documents/ by the tsup config\n const examplesDir = path.join(getDirname(), 'templates', 'documents');\n\n try {\n const files = fs.readdirSync(examplesDir);\n return files\n .filter((file) => file.endsWith('.docx.json'))\n .map((file) => path.basename(file, '.docx.json'))\n .sort();\n } catch (error) {\n console.warn('Could not read JSON examples directory:', error);\n return [];\n }\n}\n\n/**\n * Example descriptions for documentation\n */\nexport const EXAMPLE_DESCRIPTIONS: Record<string, string> = {\n 'technical-guide':\n 'Arcline Platform integration guide with TOC, headers/footers, OAuth code samples, API reference tables, webhook docs, and troubleshooting',\n proposal:\n 'Apex Consulting cloud migration proposal with TOC, headers/footers, images, statistics, compliance tables, cost comparisons, and risk matrix',\n};\n\n/**\n * Registry of available JSON examples (lazy-loaded)\n * For backward compatibility, this returns ComponentDefinition objects\n */\nconst _exampleCache: Record<string, ComponentDefinition> = {};\n\nexport const examples = new Proxy({} as Record<string, ComponentDefinition>, {\n get(_target, prop: string) {\n if (!_exampleCache[prop]) {\n try {\n _exampleCache[prop] = loadJsonExample(prop);\n } catch {\n return undefined;\n }\n }\n return _exampleCache[prop];\n },\n\n ownKeys(_target) {\n return getAvailableJsonExamples();\n },\n\n has(_target, prop: string) {\n return getAvailableJsonExamples().includes(prop);\n },\n});\n\n/**\n * Get example definition by name\n */\nexport const getExample = (\n exampleName: string\n): ComponentDefinition | undefined => {\n return examples[exampleName];\n};\n\n/**\n * Get all available example names\n */\nexport const getExampleNames = (): string[] => {\n return getAvailableJsonExamples();\n};\n\n// Use loadJsonExample() directly or access via the examples proxy\nexport const technicalGuideExample = () => loadJsonExample('technical-guide');\nexport const proposalExample = () => loadJsonExample('proposal');\n\n/**\n * Print usage information\n */\nexport function printExampleUsage(): void {\n const available = getAvailableJsonExamples();\n\n console.log('📋 Available JSON Examples:');\n console.log('===========================');\n\n available.forEach((name) => {\n const description =\n EXAMPLE_DESCRIPTIONS[name] || 'No description available';\n console.log(`\\n📄 ${name}:`);\n console.log(` ${description}`);\n console.log(` Usage: loadJsonExample('${name}')`);\n });\n\n console.log('\\n🔧 Example code:');\n console.log('```typescript');\n console.log(\n 'import { loadJsonExample, generateDocumentFromJson } from \"cool-report-generator\";'\n );\n console.log('');\n console.log('const jsonConfig = loadJsonExample(\"comprehensive\");');\n console.log('const document = await generateDocumentFromJson(jsonConfig);');\n console.log('```');\n}\n","/**\n * Universal example runner utility\n * Provides common functionality for running examples\n */\n\nimport { generateDocument, saveDocument } from '../core/generator';\nimport { ReportComponentDefinition } from '../types';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nexport interface ExampleRunnerOptions {\n outputFilename?: string;\n outputDir?: string;\n verbose?: boolean;\n}\n\n/**\n * Run an example and generate a document\n * @param example - The example definition to run\n * @param options - Options for running the example\n */\nexport async function runExample(\n example: ReportComponentDefinition,\n options: ExampleRunnerOptions = {}\n): Promise<void> {\n const { outputFilename, outputDir, verbose = true } = options;\n\n if (!example.props) {\n throw new Error('Example must have props');\n }\n\n const reportTitle = String(example.props.metadata?.title) || 'Document';\n const baseFilename =\n outputFilename || `${reportTitle.toLowerCase().replace(/\\s+/g, '-')}.docx`;\n\n // Use output directory if provided, otherwise use default output/examples path\n const defaultOutputDir = path.join(process.cwd(), 'output', 'examples');\n const finalOutputDir = outputDir || defaultOutputDir;\n const filename = path.join(finalOutputDir, baseFilename);\n\n if (verbose) {\n console.log(`=== ${reportTitle} Generation ===\\n`);\n console.log(`Generating ${reportTitle} with modular system...`);\n }\n\n try {\n // Ensure output directory exists\n await fs.promises.mkdir(finalOutputDir, { recursive: true });\n\n const document = await generateDocument(example);\n await saveDocument(document, filename);\n\n if (verbose) {\n console.log(`✓ ${reportTitle} saved: ${filename}`);\n console.log(`\\n✅ ${reportTitle} generated successfully!`);\n }\n } catch (error) {\n if (verbose) {\n console.error(`${reportTitle} generation failed:`, error);\n }\n throw error;\n }\n}\n","export { resolveComponentVersion } from '@json-to-office/shared/plugin';\n","import type { TSchema, Static } from '@sinclair/typebox';\nimport type { CustomComponent } from './createComponent';\nimport type { ReportComponentDefinition } from '../types';\nimport { resolveComponentVersion } from './version-resolver';\nimport {\n validateCustomComponentProps,\n ComponentValidationError,\n type ComponentValidationResult,\n} from '@json-to-office/shared/plugin';\nimport {\n validateDocument as validateDocumentUnified,\n type ValidationError,\n} from '@json-to-office/shared-docx/validation/unified';\nimport type { ValidationResult } from '@json-to-office/shared';\n\n// Re-export errors from shared\nexport {\n DuplicateComponentError,\n ComponentValidationError,\n UnknownPreservedComponentError,\n} from '@json-to-office/shared/plugin';\n\n/**\n * Validate a component props against a schema.\n * Accepts a narrower interface — only needs { propsSchema }.\n */\nexport function validateComponentProps<TPropsSchema extends TSchema>(\n schema: { propsSchema: TPropsSchema },\n props: unknown,\n componentName?: string,\n opts?: { clean?: boolean; applyDefaults?: boolean }\n): ComponentValidationResult<TPropsSchema> {\n // `clean` defaults to true so the render path (getValidatedProps) keeps\n // normalizing props (strip unknown + apply defaults). The validation path\n // passes `clean: false` to reject unknown keys instead of silently dropping\n // them — strict unless the caller opts into allowUnknownFields.\n return validateCustomComponentProps<TPropsSchema>(schema.propsSchema, props, {\n clean: opts?.clean ?? true,\n applyDefaults: opts?.applyDefaults ?? true,\n componentName,\n });\n}\n\n/**\n * Validate document and all custom components (version-aware).\n *\n * Standard components (paragraph, section, …) are validated against their\n * schemas via the unified validator, which is told the registered custom names\n * so it neither rejects them as unknown nor checks them against a standard\n * schema. Custom component props are then validated version-aware below. Errors\n * from both passes are merged so a single call reports the whole document.\n */\nexport function validateDocument(\n document: ReportComponentDefinition,\n customComponents: CustomComponent<any, any, any>[],\n options?: { allowUnknownFields?: boolean }\n): ValidationResult & { success: boolean } {\n const knownCustomNames = new Set(customComponents.map((c) => c.name));\n\n // Validate the standard-component structure (custom components deferred).\n const documentResult = validateDocumentUnified(document, {\n knownCustomNames,\n allowUnknownFields: options?.allowUnknownFields,\n });\n\n // Collect standard-structure errors, then append custom-component errors.\n const errors: ValidationError[] = [...(documentResult.errors || [])];\n\n function validateComponents(components: any[], pathPrefix = 'children') {\n components.forEach((componentData, index) => {\n const customComponent = customComponents.find(\n (cc) => cc.name === componentData.name\n );\n if (!customComponent) {\n return;\n }\n\n const versionEntry = resolveComponentVersion(\n customComponent.name,\n customComponent.versions,\n componentData.version\n );\n\n const validation = validateComponentProps(\n versionEntry,\n componentData.props,\n customComponent.name,\n // Reject unknown custom props unless the caller allows them.\n { clean: options?.allowUnknownFields === true }\n );\n\n if (!validation.valid && validation.errors) {\n const indexedErrors = validation.errors.map(\n (error: ValidationError) => ({\n ...error,\n path: `${pathPrefix}[${index}].${error.path}`,\n })\n );\n errors.push(...indexedErrors);\n }\n\n if (componentData.children && Array.isArray(componentData.children)) {\n validateComponents(\n componentData.children,\n `${pathPrefix}[${index}].children`\n );\n }\n });\n }\n\n if (document.children) {\n validateComponents(document.children);\n }\n\n return errors.length > 0\n ? { success: false, errors, valid: false }\n : { success: true, errors: [], valid: true };\n}\n\n/**\n * Validates component props and returns the typed props or throws.\n */\nexport function getValidatedProps<TPropsSchema extends TSchema>(\n schema: { propsSchema: TPropsSchema },\n props: unknown\n): Static<TPropsSchema> {\n const validation = validateComponentProps(schema, props);\n\n if (!validation.valid) {\n throw new ComponentValidationError(validation.errors || [], props);\n }\n\n return validation.data!;\n}\n\n// Re-export types\nexport type { ValidationError } from '@json-to-office/shared-docx/validation/unified';\nexport type { ComponentValidationResult } from '@json-to-office/shared/plugin';\n\nexport const cleanComponentProps = getValidatedProps;\n","import type { TSchema } from '@sinclair/typebox';\nimport type { CustomComponent } from './createComponent';\nimport type { ComponentDefinition, ReportComponentDefinition } from '../types';\nimport { type ThemeConfig } from '../styles';\nimport { resolveBuiltInTheme } from '../styles/theme-resolver';\nimport { resolveThemeContext } from '../core/generationContext';\nimport type { GenerationWarning } from '@json-to-office/shared-docx';\nimport type { ServicesConfig, FontRuntimeOpts } from '@json-to-office/shared';\nimport { resolveDocumentFonts } from '../core/fontResolution';\nimport type {\n ExtendedReportComponent,\n DocumentGeneratorBuilder,\n GenerateOptions,\n GenerateFileOptions,\n GenerationResult,\n BufferGenerationResult,\n FileGenerationResult,\n ValidationResult,\n GenerationValidationOptions,\n} from './types';\nimport {\n validateDocument,\n cleanComponentProps,\n ComponentValidationError,\n DuplicateComponentError,\n} from './validation';\nimport { UnknownPreservedComponentError } from '@json-to-office/shared/plugin';\nimport { resolveComponentVersion } from './version-resolver';\nimport { generatePluginDocumentSchema, exportPluginSchema } from './schema';\nimport { processDocument } from '../core/structure';\nimport { applyLayout } from '../core/layout';\nimport { renderDocument } from '../core/render';\nimport { normalizeDocument } from '../json/normalizer';\nimport {\n packageDocument,\n resolveGenerationDate,\n} from '../utils/packageDocument';\n\n/**\n * Options for creating a document generator\n */\nexport interface DocumentGeneratorOptions {\n /** Default theme used when no custom or built-in theme matches */\n theme?: ThemeConfig;\n /** Custom themes keyed by name, resolved per-document via document.props.theme */\n customThemes?: Record<string, ThemeConfig>;\n /** Enable caching for better performance */\n enableCache?: boolean;\n /** Enable debug logging */\n debug?: boolean;\n /** External service configuration (e.g. Highcharts export server) */\n services?: ServicesConfig;\n /** Font resolution options — extraEntries, Google Fonts config, onResolved hook. */\n fonts?: FontRuntimeOpts;\n /**\n * Default validation behavior for every generate/generateBuffer/generateFile\n * call. Per-call `options.validation` overrides these. Validation is on by\n * default; pass `{ enabled: false }` to opt out.\n */\n validation?: GenerationValidationOptions;\n /** Normalize volatile OOXML values for byte-identical output. Defaults true. */\n deterministic?: boolean;\n /** Default build timestamp for generated metadata. */\n generatedAt?: string | Date;\n}\n\n/**\n * Internal state held by each builder instance\n */\ninterface BuilderState {\n components: readonly CustomComponent<any, any, any>[];\n componentNames: Set<string>;\n theme?: ThemeConfig;\n customThemes?: Record<string, ThemeConfig>;\n debug: boolean;\n enableCache: boolean;\n services?: ServicesConfig;\n fonts?: FontRuntimeOpts;\n validation?: GenerationValidationOptions;\n deterministic: boolean;\n generatedAt?: string | Date;\n}\n\n/**\n * Create the builder implementation with the given state\n */\nfunction createBuilderImpl<\n TComponents extends readonly CustomComponent<any, any, any>[],\n>(state: BuilderState): DocumentGeneratorBuilder<TComponents> {\n // Create component map for quick lookup\n const componentMap = new Map(state.components.map((c) => [c.name, c]));\n\n /**\n * Resolve theme for a document: customThemes → built-in → constructor fallback\n */\n function resolveDocumentTheme(\n themeName: string,\n warnings?: GenerationWarning[]\n ): ThemeConfig {\n if (state.customThemes) {\n if (state.customThemes[themeName]) {\n return state.customThemes[themeName];\n }\n const key = Object.keys(state.customThemes).find(\n (k) => k.toLowerCase() === themeName.toLowerCase()\n );\n if (key) {\n return state.customThemes[key];\n }\n }\n if (state.theme) {\n return state.theme;\n }\n return resolveBuiltInTheme(themeName, {\n customThemes: state.customThemes,\n warnings,\n });\n }\n\n /**\n * Process custom components in the document.\n *\n * Returns two parallel trees built in a single pass:\n * - `standard`: fully expanded — every custom component resolved to standard primitives.\n * - `preserved`: partially expanded — nodes whose name is in `preserveSet` are kept\n * verbatim (children NOT recursed); everything else is expanded the same as `standard`.\n *\n * `render()` always runs, even for preserved components, because the docx pipeline\n * builds from `standard` and we still need their warnings/font registrations.\n */\n async function processDocumentComponents(\n components: ComponentDefinition[],\n preserveSet: ReadonlySet<string> | undefined,\n warningsCollector: GenerationWarning[],\n resolvedTheme: ThemeConfig,\n validateEmitted:\n | ((emitted: ComponentDefinition[], componentLabel: string) => void)\n | undefined,\n depth = 0\n ): Promise<{\n standard: ComponentDefinition[];\n preserved: ComponentDefinition[];\n }> {\n if (depth > 20) {\n throw new Error(\n 'Maximum component nesting depth exceeded (20). Check for circular component references.'\n );\n }\n const standardOut: ComponentDefinition[] = [];\n const preservedOut: ComponentDefinition[] = [];\n\n for (const componentData of components) {\n // Safe type narrowing for custom component detection\n const componentName = (componentData as { name?: string })?.name;\n\n if (!componentName) {\n standardOut.push(componentData);\n preservedOut.push(componentData);\n continue;\n }\n\n const customComponent = componentMap.get(componentName);\n\n if (customComponent) {\n // This is a custom component - validate and process it\n try {\n const componentWithName = componentData as {\n name: string;\n version?: string;\n props?: unknown;\n children?: unknown;\n };\n\n if (!componentWithName.props) {\n throw new Error(\n `Custom component '${componentName}' must have a 'props' property. Use format: { name: '${componentName}', props: {...} }`\n );\n }\n\n // Resolve the correct version entry\n const versionEntry = resolveComponentVersion(\n customComponent.name,\n customComponent.versions,\n componentWithName.version\n );\n\n // Validate and clean the props against the resolved version's schema\n const cleanedProps = cleanComponentProps(\n versionEntry,\n componentWithName.props\n );\n\n // Process nested children if this is a container.\n // For the standard tree we need the fully-expanded children to feed render().\n let nestedChildren: unknown[] | undefined;\n if (\n componentWithName.children &&\n Array.isArray(componentWithName.children)\n ) {\n const nested = await processDocumentComponents(\n componentWithName.children as ComponentDefinition[],\n preserveSet,\n warningsCollector,\n resolvedTheme,\n validateEmitted,\n depth + 1\n );\n nestedChildren = nested.standard;\n }\n\n // Create addWarning callback for this component\n const versionLabel = componentWithName.version\n ? `${customComponent.name}@${componentWithName.version}`\n : customComponent.name;\n\n const addWarning = (\n message: string,\n context?: Record<string, unknown>\n ) => {\n warningsCollector.push({\n component: versionLabel,\n message,\n severity: 'warning',\n context,\n });\n };\n\n // Call the render function with context object\n const result = await versionEntry.render({\n props: cleanedProps,\n theme: resolvedTheme,\n addWarning,\n children: nestedChildren,\n });\n\n // Ensure result is an array\n const resultComponents = (\n Array.isArray(result) ? result : [result]\n ) as ComponentDefinition[];\n\n // Validate the standard tree this render() emitted, applying the same\n // schema gate authored standard components pass through up front. The\n // pre-expansion pass never saw these nodes, so without this an invalid\n // prop produced by a plugin would ride through into standardDefinition\n // and only surface when that output is validated separately.\n if (validateEmitted) {\n validateEmitted(resultComponents, versionLabel);\n }\n\n // Recursively process the result in case it contains more custom components\n const processedResult = await processDocumentComponents(\n resultComponents,\n preserveSet,\n warningsCollector,\n resolvedTheme,\n validateEmitted,\n depth + 1\n );\n standardOut.push(...processedResult.standard);\n\n if (preserveSet && preserveSet.has(componentName)) {\n // Keep this custom node verbatim in the preserved tree.\n // Per spec: do NOT recurse into authored children — leave the\n // entire subtree as the user wrote it.\n preservedOut.push(componentData);\n } else {\n // Non-preserved custom: emit the recursed expansion (which itself\n // honors preserveSet for any nested customs).\n preservedOut.push(...processedResult.preserved);\n }\n\n if (state.debug) {\n console.log(\n `Processed custom component '${versionLabel}':`,\n processedResult.standard\n );\n }\n } catch (error) {\n if (error instanceof ComponentValidationError) {\n throw error;\n }\n throw new Error(\n `Error processing custom component '${customComponent.name}': ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n } else {\n // This is a standard component or nested container - process recursively\n if (\n 'children' in componentData &&\n Array.isArray(componentData.children)\n ) {\n const processedNested = await processDocumentComponents(\n componentData.children,\n preserveSet,\n warningsCollector,\n resolvedTheme,\n validateEmitted,\n depth + 1\n );\n standardOut.push({\n ...componentData,\n children: processedNested.standard,\n });\n preservedOut.push({\n ...componentData,\n children: processedNested.preserved,\n });\n } else {\n standardOut.push(componentData);\n preservedOut.push(componentData);\n }\n }\n }\n\n return { standard: standardOut, preserved: preservedOut };\n }\n\n /**\n * Add a custom component to the generator\n */\n function addComponent<TNewComponent extends CustomComponent<any, any, any>>(\n component: TNewComponent\n ): DocumentGeneratorBuilder<readonly [...TComponents, TNewComponent]> {\n if (!component.name) {\n throw new Error('Component name is required');\n }\n\n if (state.componentNames.has(component.name)) {\n throw new DuplicateComponentError(component.name);\n }\n\n // Create NEW immutable state\n const newComponentNames = new Set(state.componentNames);\n newComponentNames.add(component.name);\n\n const newState: BuilderState = {\n components: [...state.components, component],\n componentNames: newComponentNames,\n theme: state.theme,\n customThemes: state.customThemes,\n debug: state.debug,\n enableCache: state.enableCache,\n services: state.services,\n fonts: state.fonts,\n validation: state.validation,\n deterministic: state.deterministic,\n generatedAt: state.generatedAt,\n };\n\n // Return NEW builder with expanded type\n return createBuilderImpl<readonly [...TComponents, TNewComponent]>(\n newState\n );\n }\n\n /**\n * Resolve and validate the preserve set for a per-call options object.\n * Returns `undefined` when the caller did not opt in.\n * Throws `UnknownPreservedComponentError` when any listed name is not registered.\n */\n function resolvePreserveSet(\n options?: GenerateOptions\n ): ReadonlySet<string> | undefined {\n const list = options?.preserveCustomComponents;\n if (!list || list.length === 0) {\n return undefined;\n }\n const registered = new Set(state.componentNames);\n const unknown = list.filter((n) => !registered.has(n));\n if (unknown.length > 0) {\n throw new UnknownPreservedComponentError(\n unknown,\n Array.from(state.componentNames)\n );\n }\n return new Set(list);\n }\n\n /**\n * Generate a document\n */\n async function generate(\n document: ExtendedReportComponent<TComponents>,\n options?: GenerateOptions\n ): Promise<GenerationResult<TComponents>> {\n try {\n const preserveSet = resolvePreserveSet(options);\n\n // Cast to ReportComponentDefinition for internal processing. A root\n // written without a `props` key validates clean, so default it to `{}`\n // — otherwise every downstream `props.*` read throws. Only `undefined`\n // is defaulted, so a malformed `props: null` still reaches the\n // validator. Matches core/generator.ts.\n const rootIn = document as unknown as ReportComponentDefinition;\n const internalDocument: ReportComponentDefinition =\n rootIn.props === undefined ? { ...rootIn, props: {} } : rootIn;\n\n // Validate the document first (plugin-aware), unless disabled. Throwing\n // here stops a malformed document from silently building into a corrupt\n // or incomplete DOCX.\n const vOpts: GenerationValidationOptions = {\n ...state.validation,\n ...options?.validation,\n };\n if (vOpts.enabled !== false) {\n const result = validateDocument(\n internalDocument,\n state.components as unknown as CustomComponent<TSchema>[],\n { allowUnknownFields: vOpts.allowUnknownFields }\n );\n if (!result.valid) {\n throw new ComponentValidationError(\n (result.errors ?? []).map((e) => ({\n path: e.path ?? '',\n message: e.message,\n })),\n internalDocument\n );\n }\n }\n\n // Re-apply the same gate to the tree each custom component's render()\n // emits. The pre-expansion pass above only saw authored nodes, so a\n // standard component produced by a plugin would otherwise reach\n // standardDefinition unchecked. We validate the emitted nodes in their\n // pre-normalization form — exactly how authored nodes are validated —\n // by reusing the already-validated document props as a wrapper, so the\n // only new errors come from the emitted children. Undefined when\n // validation is disabled, which short-circuits the boundary check.\n const validateEmitted =\n vOpts.enabled === false\n ? undefined\n : (emitted: ComponentDefinition[], componentLabel: string) => {\n const result = validateDocument(\n { ...internalDocument, children: emitted },\n state.components as unknown as CustomComponent<TSchema>[],\n { allowUnknownFields: vOpts.allowUnknownFields }\n );\n if (!result.valid) {\n throw new ComponentValidationError(\n (result.errors ?? []).map((e) => ({\n path: e.path ?? '',\n message: `custom component '${componentLabel}' emitted invalid output — ${e.message}`,\n })),\n emitted\n );\n }\n };\n\n // Initialize warnings collector\n const warnings: GenerationWarning[] = [];\n\n // Props defaulting, theme resolution (customThemes → constructor theme →\n // built-in), in-document overrides, export-mode pre-pass and cache-key\n // scoping — shared with the core pipeline so the two cannot drift (see\n // core/generationContext.ts). The pre-pass runs BEFORE custom-component\n // expansion so components reading `theme.fonts.*` during render see the\n // substituted names, not the original non-safe ones.\n const {\n document: modedRoot,\n theme: modedTheme,\n themeName,\n } = resolveThemeContext(internalDocument, {\n customThemes: state.customThemes,\n fonts: state.fonts,\n warnings,\n resolveNamedTheme: resolveDocumentTheme,\n });\n\n // Process custom components to convert them to standard components.\n // Builds standard (fully expanded) and preserved (partial) trees in one pass.\n const processed = await processDocumentComponents(\n modedRoot.children || [],\n preserveSet,\n warnings,\n modedTheme,\n validateEmitted\n );\n\n // Create a new document definition with processed components\n const processedDocument: ReportComponentDefinition = {\n ...modedRoot,\n children: processed.standard,\n };\n\n // Normalize components (handle shorthand notations and nested structures)\n // We bypass JSON validation since we've already validated with custom schemas\n const [modedDoc] = normalizeDocument(processedDocument);\n\n // Resolve fonts (reads document + resolved theme). The helper fires\n // `fonts.onResolved` internally when a listener is registered\n // (LibreOffice preview stager). DOCX output itself never embeds\n // bytes; recipients rely on system-installed fonts.\n await resolveDocumentFonts(modedDoc, modedTheme, state.fonts, warnings);\n\n // Use the document generation pipeline directly\n const packageOptions = {\n deterministic: options?.deterministic ?? state.deterministic,\n generatedAt: options?.generatedAt ?? state.generatedAt,\n };\n const structure = await processDocument(\n modedDoc,\n modedTheme,\n themeName,\n resolveGenerationDate(packageOptions)\n );\n const layout = applyLayout(structure.sections, modedTheme, themeName);\n const generatedDocument = await renderDocument(structure, layout, {\n services: state.services,\n bypassCache: !state.enableCache,\n });\n\n // Build preservedDefinition iff the caller opted in. Reuses the same\n // doc shell as standardDefinition but with partially-expanded children.\n // Not normalized — preserved subtrees are meant to be \"as authored\".\n const preservedDefinition = preserveSet\n ? ({\n ...modedRoot,\n children: processed.preserved,\n } as unknown as ExtendedReportComponent<TComponents>)\n : undefined;\n\n return {\n document: generatedDocument,\n warnings: warnings.length > 0 ? warnings : null,\n standardDefinition: modedDoc,\n preservedDefinition,\n };\n } catch (error) {\n if (state.debug) {\n console.error('Document generation error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Generate a document and return as buffer\n */\n async function generateBuffer(\n document: ExtendedReportComponent<TComponents>,\n options?: GenerateOptions\n ): Promise<BufferGenerationResult<TComponents>> {\n const {\n document: doc,\n warnings,\n standardDefinition,\n preservedDefinition,\n } = await generate(document, options);\n const buffer = await packageDocument(doc, {\n deterministic: options?.deterministic ?? state.deterministic,\n generatedAt: options?.generatedAt ?? state.generatedAt,\n });\n return { buffer, warnings, standardDefinition, preservedDefinition };\n }\n\n /**\n * Generate a document and save to file\n */\n async function generateFile(\n document: ExtendedReportComponent<TComponents>,\n outputPath: string,\n options?: GenerateFileOptions\n ): Promise<FileGenerationResult<TComponents>> {\n const { buffer, warnings, standardDefinition, preservedDefinition } =\n await generateBuffer(document, options);\n const fs = await import('fs/promises');\n await fs.writeFile(outputPath, new Uint8Array(buffer));\n\n let preservedOutputPath: string | undefined;\n if (preservedDefinition !== undefined) {\n const path = await import('path');\n preservedOutputPath =\n options?.preservedOutputPath ??\n (() => {\n const ext = path.extname(outputPath);\n const base = ext ? outputPath.slice(0, -ext.length) : outputPath;\n return `${base}-preserved.json`;\n })();\n await fs.writeFile(\n preservedOutputPath,\n JSON.stringify(preservedDefinition, null, 2),\n 'utf8'\n );\n }\n\n return {\n warnings,\n standardDefinition,\n preservedDefinition,\n preservedOutputPath,\n };\n }\n\n /**\n * Get registered component names\n */\n function getComponentNames(): string[] {\n return Array.from(state.componentNames);\n }\n\n /**\n * Validate a document without generating it\n */\n function validate(\n document: ExtendedReportComponent<TComponents>\n ): ValidationResult {\n try {\n // Cast to ReportComponentDefinition for internal validation\n const internalDocument = document as unknown as ReportComponentDefinition;\n const result = validateDocument(\n internalDocument,\n state.components as unknown as CustomComponent<TSchema>[]\n );\n if (result.valid) {\n return { valid: true };\n }\n return {\n valid: false,\n errors: (result.errors ?? []).map((e) => ({\n path: e.path ?? '',\n message: e.message,\n })),\n };\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: 'document',\n message: error instanceof Error ? error.message : String(error),\n },\n ],\n };\n }\n }\n\n /**\n * @deprecated Read `standardDefinition` off `generate(...)` instead. This wrapper\n * runs the full generation pipeline (including `render()` for every custom)\n * just to surface the JSON tree, so calling it alongside `generate*` doubles\n * the work. Kept for backwards compatibility; will be removed in a future major.\n */\n async function getStandardComponentsDefinition(\n document: ExtendedReportComponent<TComponents>\n ): Promise<ReportComponentDefinition> {\n const { standardDefinition } = await generate(document);\n return standardDefinition;\n }\n\n /**\n * Generate the extended JSON schema for document validation\n */\n function generateSchema(includeStandardComponents = true): TSchema {\n return generatePluginDocumentSchema(\n state.components as unknown as CustomComponent<TSchema>[],\n includeStandardComponents\n );\n }\n\n /**\n * Export the extended JSON schema to a file\n */\n async function exportSchemaToFile(\n outputPath: string,\n options?: {\n includeStandardComponents?: boolean;\n prettyPrint?: boolean;\n }\n ): Promise<void> {\n await exportPluginSchema(\n state.components as unknown as CustomComponent<TSchema>[],\n outputPath,\n options\n );\n }\n\n // Return frozen builder object\n return Object.freeze({\n addComponent,\n generate,\n generateBuffer,\n generateFile,\n getComponentNames,\n validate,\n generateSchema,\n exportSchema: exportSchemaToFile,\n getStandardComponentsDefinition,\n });\n}\n\n/**\n * Create a document generator with chainable component registration.\n */\nexport function createDocumentGenerator(\n options: DocumentGeneratorOptions\n): DocumentGeneratorBuilder<readonly []> {\n const initialState: BuilderState = {\n components: [],\n componentNames: new Set(),\n theme: options.theme,\n customThemes: options.customThemes,\n debug: options.debug ?? false,\n enableCache: options.enableCache ?? false,\n services: options.services,\n fonts: options.fonts,\n validation: options.validation,\n deterministic: options.deterministic ?? true,\n generatedAt: options.generatedAt,\n };\n\n return createBuilderImpl<readonly []>(initialState);\n}\n","import { Type, TSchema, TObject } from '@sinclair/typebox';\nimport { latestVersion } from '@json-to-office/shared-docx';\nimport type { CustomComponent } from './createComponent';\nimport {\n ReportPropsSchema,\n SectionPropsSchema,\n HeadingPropsSchema,\n ParagraphPropsSchema,\n ListPropsSchema,\n ImagePropsSchema,\n TablePropsSchema,\n} from '@json-to-office/shared-docx';\nimport { generateUnifiedDocumentSchema } from '@json-to-office/shared-docx/schemas/generator';\n\n// Schema cache to avoid regenerating identical schemas\nconst schemaCache = new Map<string, TSchema>();\n\n/**\n * Generate a JSON schema for plugin-enhanced documents at RUNTIME.\n *\n * Iterates each component's versions map to produce per-version\n * CustomComponentInfo entries for the unified schema generator.\n */\nexport function generatePluginDocumentSchema(\n customComponents: CustomComponent<any, any, any>[],\n includeStandardComponents = true\n): TSchema {\n // Produce per-version CustomComponentInfo entries for version-discriminated validation\n const customComponentInfos = customComponents.map((component) => {\n const versionKeys = Object.keys(component.versions);\n\n // Build per-version props entries\n const versionedProps = versionKeys.map((v) => ({\n version: v,\n propsSchema: component.versions[v].propsSchema,\n hasChildren: component.versions[v].hasChildren === true,\n description: component.versions[v].description,\n }));\n\n // propsSchema is used as fallback label — use latest version's props\n const latestKey = versionKeys.reduce((a, b) => (a > b ? a : b));\n\n return {\n name: component.name,\n propsSchema: component.versions[latestKey].propsSchema,\n hasChildren: versionKeys.some(\n (v) => component.versions[v].hasChildren === true\n ),\n versionedProps,\n };\n });\n\n return generateUnifiedDocumentSchema({\n includeStandardComponents: includeStandardComponents,\n includeTheme: true,\n customComponents: customComponentInfos,\n title: 'Plugin Document Definition',\n description: 'Document definition with custom plugin components',\n });\n}\n\n/**\n * Create a union type from an array of schemas\n */\nexport function createUnionSchema(schemas: TSchema[]): TSchema {\n if (schemas.length === 0) {\n return Type.Any();\n }\n if (schemas.length === 1) {\n return schemas[0];\n }\n return Type.Union(schemas as [TSchema, TSchema, ...TSchema[]]);\n}\n\n/**\n * Export a plugin-enhanced JSON schema to a file at RUNTIME\n */\nexport async function exportPluginSchema(\n customComponents: CustomComponent<any, any, any>[],\n outputPath: string,\n options: {\n includeStandardComponents?: boolean;\n prettyPrint?: boolean;\n } = {}\n): Promise<void> {\n const { includeStandardComponents = true, prettyPrint = true } = options;\n\n const { convertToJsonSchema, exportSchemaToFile } = await import(\n '@json-to-office/shared-docx/schemas/export'\n );\n\n const schema = generatePluginDocumentSchema(\n customComponents,\n includeStandardComponents\n );\n\n const jsonSchema = convertToJsonSchema(schema, {\n $schema: 'http://json-schema.org/draft-07/schema#',\n });\n\n await exportSchemaToFile(jsonSchema, outputPath, { prettyPrint });\n}\n\n/**\n * Generate schemas for individual custom components (version-aware).\n * Produces per-version schemas keyed as `name` or `name@version`.\n */\nexport function generateComponentSchemas(\n customComponents: CustomComponent<any, any, any>[]\n): Record<string, TSchema> {\n const schemas: Record<string, TSchema> = {};\n\n for (const component of customComponents) {\n const versionKeys = Object.keys(component.versions);\n const latest = latestVersion(versionKeys);\n\n for (const v of versionKeys) {\n const entry = component.versions[v];\n const cacheKey = `component_${component.name}@${v}`;\n\n if (schemaCache.has(cacheKey)) {\n schemas[`${component.name}@${v}`] = schemaCache.get(cacheKey)!;\n } else {\n const schemaObj = entry.propsSchema as TObject;\n const properties = schemaObj.properties || {};\n\n const componentSchemaProps: Record<string, TSchema> = {\n name: Type.Literal(component.name),\n version: Type.Optional(Type.Literal(v)),\n id: Type.Optional(Type.String()),\n ...properties,\n };\n\n if (entry.hasChildren) {\n componentSchemaProps.children = Type.Optional(Type.Array(Type.Any()));\n }\n\n const componentSchema = Type.Object(componentSchemaProps);\n schemaCache.set(cacheKey, componentSchema);\n schemas[`${component.name}@${v}`] = componentSchema;\n }\n }\n\n // Also add a \"default\" entry keyed by name (uses latest)\n const latestEntry = component.versions[latest];\n const defaultCacheKey = `component_${component.name}_default`;\n\n if (schemaCache.has(defaultCacheKey)) {\n schemas[component.name] = schemaCache.get(defaultCacheKey)!;\n } else {\n const schemaObj = latestEntry.propsSchema as TObject;\n const properties = schemaObj.properties || {};\n\n const componentSchemaProps: Record<string, TSchema> = {\n name: Type.Literal(component.name),\n id: Type.Optional(Type.String()),\n ...properties,\n };\n\n if (latestEntry.hasChildren) {\n componentSchemaProps.children = Type.Optional(Type.Array(Type.Any()));\n }\n\n const componentSchema = Type.Object(componentSchemaProps);\n schemaCache.set(defaultCacheKey, componentSchema);\n schemas[component.name] = componentSchema;\n }\n }\n\n return schemas;\n}\n\n/**\n * Merge custom component schemas with standard schemas\n */\nexport function mergeSchemas(\n customComponents: CustomComponent<any, any, any>[],\n standardSchemas?: Record<string, TSchema>\n): Record<string, TSchema> {\n const customSchemas = generateComponentSchemas(customComponents);\n\n if (standardSchemas) {\n return {\n ...standardSchemas,\n ...customSchemas,\n };\n }\n\n const defaultStandardSchemas: Record<string, TSchema> = {\n docx: Type.Object({\n name: Type.Literal('docx'),\n id: Type.Optional(Type.String()),\n props: ReportPropsSchema,\n children: Type.Optional(Type.Array(Type.Any())),\n }),\n section: Type.Object({\n name: Type.Literal('section'),\n id: Type.Optional(Type.String()),\n props: SectionPropsSchema,\n children: Type.Optional(Type.Array(Type.Any())),\n }),\n heading: Type.Object({\n name: Type.Literal('heading'),\n id: Type.Optional(Type.String()),\n props: HeadingPropsSchema,\n }),\n text: Type.Object({\n name: Type.Literal('text'),\n id: Type.Optional(Type.String()),\n props: ParagraphPropsSchema,\n }),\n list: Type.Object({\n name: Type.Literal('list'),\n id: Type.Optional(Type.String()),\n props: ListPropsSchema,\n }),\n image: Type.Object({\n name: Type.Literal('image'),\n id: Type.Optional(Type.String()),\n props: ImagePropsSchema,\n }),\n table: Type.Object({\n name: Type.Literal('table'),\n id: Type.Optional(Type.String()),\n props: TablePropsSchema,\n }),\n };\n\n return {\n ...defaultStandardSchemas,\n ...customSchemas,\n };\n}\n"],"mappings":"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","names":["themes","path","fs","path","isValidThemeConfig","mergeWithDefaults","mergeWithDefaults","Paragraph","TextRun","AlignmentType","BookmarkStart","BookmarkEnd","path","createHash","TextRun","TextRun","TextRun","createTextRunsWithNewlines","TextRun","AsyncLocalStorage","TextRun","createHash","TextRun","AlignmentType","BorderStyle","PageNumber","AsyncLocalStorage","TextRun","path","getAvailableWidthTwips","getPageWidthTwips","getAvailableHeightTwips","getPageHeightTwips","mapFloatingOptions","AlignmentType","BorderStyle","TextRun","relativeLengthToTwips","AlignmentType","AsyncLocalStorage","format","getAlignment","format","getAlignment","AsyncLocalStorage","text","format","Table","TableRow","TableCell","WidthType","TableLayoutType","BorderStyle","convertBorders","Paragraph","Paragraph","convertBorders","cellChildren","childContext","styleCfg","cellOpts","row","TableRow","TableCell","table","Table","TableLayoutType","WidthType","config","Paragraph","Paragraph","Paragraph","Table","TableRow","TableCell","WidthType","BorderStyle","VerticalAlign","TableLayoutType","Paragraph","TableCell","WidthType","VerticalAlign","BorderStyle","TableRow","Table","TableLayoutType","Paragraph","AlignmentType","TextRun","getAlignment","AlignmentType","Paragraph","TextRun","BookmarkStart","BookmarkEnd","AdmZip","AdmZip","coreProperties","fs","fs","clampVisualDpi","DEFAULT_VISUAL_DPI","resolve","clampVisualDpi","DEFAULT_VISUAL_DPI","fs","path","fileURLToPath","path","fs","ComponentValidationError","UnknownPreservedComponentError","Type","Type","ComponentValidationError","UnknownPreservedComponentError","fs","path"]}
1
+ {"version":3,"sources":["../src/themes/defaults.ts","../src/templates/themes/minimal.docx.theme.json","../src/templates/themes/corporate.docx.theme.json","../src/templates/themes/modern.docx.theme.json","../src/templates/themes/apex.docx.theme.json","../src/templates/themes/devportal.docx.theme.json","../src/templates/themes/index.ts","../src/styles/utils/colorUtils.ts","../src/styles/utils/styleHelpers.ts","../src/styles/utils/layoutUtils.ts","../src/themes/json/parser.ts","../src/themes/json/validator.ts","../src/themes/json/loader.ts","../src/themes/json/index.ts","../src/styles/index.ts","../src/utils/widthUtils.ts","../src/utils/docxImagePositioning.ts","../src/core/generator.ts","../src/types/index.ts","../src/core/generationContext.ts","../src/styles/theme-resolver.ts","../src/themes/overrides.ts","../src/utils/formatters.ts","../src/styles/utils/componentDefaults.ts","../src/styles/utils/resolveComponentTree.ts","../src/core/structure.ts","../src/core/layout.ts","../src/core/render.ts","../src/utils/imageUtils.ts","../src/utils/generationContext.ts","../src/styles/themeToDocxAdapter.ts","../src/cache/index.ts","../src/cache/key-generator.ts","../src/utils/revisionUtils.ts","../src/utils/unicode.ts","../src/utils/placeholderProcessor.ts","../src/utils/textParser.ts","../src/core/cached-render.ts","../src/core/content.ts","../src/utils/bookmarkRegistry.ts","../src/components/heading.ts","../src/utils/numberingConfig.ts","../src/components/paragraph.ts","../src/components/list.ts","../src/components/image.ts","../src/components/text-box.ts","../src/styles/utils/borderUtils.ts","../src/styles/utils/cellUtils.ts","../src/components/table.ts","../src/components/section.ts","../src/components/columns.ts","../src/components/statistic.ts","../src/components/toc/index.ts","../src/components/highcharts.ts","../src/utils/environment.ts","../src/utils/serviceClient.ts","../src/components/visual.ts","../src/components/text-space-after.ts","../src/plugin/createComponent.ts","../src/core/fontResolution.ts","../src/utils/packageDocument.ts","../src/utils/fixFloatingImageIds.ts","../src/json/parser.ts","../src/json/normalizer.ts","../src/json/filesystem.ts","../src/core/flattenVisuals.ts","../src/utils/warningsDocument.ts","../src/index.ts","../src/templates/documents/index.ts","../src/utils/exampleRunner.ts","../src/plugin/createDocumentGenerator.ts","../src/plugin/version-resolver.ts","../src/plugin/validation.ts","../src/plugin/schema.ts"],"sourcesContent":["/**\n * Default theme values and utilities for handling optional theme properties\n */\n\nimport type { ThemeConfigJson } from '@json-to-office/shared-docx';\n\n/**\n * Default colors for themes\n */\nexport const DEFAULT_COLORS = {\n primary: '#000000',\n secondary: '#666666',\n accent: '#0066CC',\n text: '#000000',\n background: '#FFFFFF',\n border: '#CCCCCC',\n // Semantic colors\n textPrimary: '#000000',\n textSecondary: '#666666',\n textMuted: '#999999',\n borderPrimary: '#CCCCCC',\n borderSecondary: '#E5E5E5',\n backgroundPrimary: '#FFFFFF',\n backgroundSecondary: '#F5F5F5',\n};\n\n/**\n * Default fonts for themes\n */\nexport const DEFAULT_FONTS = {\n heading: { family: 'Arial', size: 20 },\n body: { family: 'Arial', size: 11 },\n mono: { family: 'Courier New', size: 10 },\n light: { family: 'Arial', size: 24 },\n};\n\n/**\n * Default styles for themes\n */\nexport const DEFAULT_STYLES = {\n normal: {\n font: 'body' as const,\n size: 11,\n color: '#000000',\n alignment: 'left' as const,\n lineSpacing: {\n type: 'single' as const,\n value: 1,\n },\n spacing: {\n after: 6,\n },\n },\n heading1: {\n font: 'heading' as const,\n size: 24,\n color: '#000000',\n bold: true,\n spacing: {\n before: 12,\n after: 12,\n },\n },\n heading2: {\n font: 'heading' as const,\n size: 20,\n color: '#000000',\n bold: true,\n spacing: {\n before: 10,\n after: 10,\n },\n },\n heading3: {\n font: 'heading' as const,\n size: 16,\n color: '#000000',\n bold: true,\n spacing: {\n before: 8,\n after: 8,\n },\n },\n heading4: {\n font: 'heading' as const,\n size: 14,\n color: '#000000',\n bold: true,\n spacing: {\n before: 6,\n after: 6,\n },\n },\n heading5: {\n font: 'heading' as const,\n size: 12,\n color: '#000000',\n bold: true,\n spacing: {\n before: 6,\n after: 6,\n },\n },\n heading6: {\n font: 'heading' as const,\n size: 11,\n color: '#000000',\n bold: true,\n spacing: {\n before: 6,\n after: 6,\n },\n },\n};\n\n/**\n * Default page settings\n */\nexport const DEFAULT_PAGE = {\n size: 'LETTER' as const,\n margins: {\n top: 720,\n bottom: 720,\n left: 720,\n right: 720,\n header: 360,\n footer: 360,\n gutter: 0,\n },\n};\n\n/**\n * Ensures theme has all required properties with defaults\n */\nexport function ensureThemeDefaults(\n theme: Partial<ThemeConfigJson>\n): ThemeConfigJson {\n return {\n $schema: theme.$schema,\n name: theme.name || 'default',\n displayName: theme.displayName || 'Default Theme',\n description: theme.description || 'Default theme configuration',\n version: theme.version || '1.0.0',\n colors: {\n ...DEFAULT_COLORS,\n ...(theme.colors || {}),\n },\n fonts: {\n heading: { ...DEFAULT_FONTS.heading, ...(theme.fonts?.heading || {}) },\n body: { ...DEFAULT_FONTS.body, ...(theme.fonts?.body || {}) },\n mono: { ...DEFAULT_FONTS.mono, ...(theme.fonts?.mono || {}) },\n light: { ...DEFAULT_FONTS.light, ...(theme.fonts?.light || {}) },\n },\n page: {\n ...DEFAULT_PAGE,\n ...(theme.page || {}),\n margins: {\n ...DEFAULT_PAGE.margins,\n ...(theme.page?.margins || {}),\n },\n },\n styles: theme.styles,\n componentDefaults: theme.componentDefaults,\n };\n}\n\n/**\n * Type guard to check if a theme has all required properties\n */\nexport function isCompleteTheme(theme: unknown): theme is ThemeConfigJson {\n const t = theme as Record<string, unknown>;\n return (\n t &&\n typeof t === 'object' &&\n !!t.colors &&\n !!t.fonts &&\n !!t.page &&\n typeof t.name === 'string' &&\n typeof t.displayName === 'string' &&\n typeof t.description === 'string' &&\n typeof t.version === 'string'\n );\n}\n\n/**\n * Safe getter for theme colors with defaults\n */\nexport function getThemeColors(theme: Partial<ThemeConfigJson>) {\n return {\n ...DEFAULT_COLORS,\n ...(theme.colors || {}),\n };\n}\n\n/**\n * Safe getter for theme fonts with defaults\n */\nexport function getThemeFonts(theme: Partial<ThemeConfigJson>) {\n return {\n ...DEFAULT_FONTS,\n ...(theme.fonts || {}),\n };\n}\n\n/**\n * Safe getter for theme styles with defaults\n */\nexport function getThemeStyles(theme: Partial<ThemeConfigJson>) {\n return {\n ...DEFAULT_STYLES,\n ...(theme.styles || {}),\n };\n}\n\n/**\n * Safe getter for normal style with defaults\n */\nexport function getNormalStyle(theme: Partial<ThemeConfigJson>) {\n const styles = getThemeStyles(theme);\n return {\n ...DEFAULT_STYLES.normal,\n ...(styles.normal || {}),\n };\n}\n","{\n \"$schema\": \"../../../../shared/json-schemas/theme.schema.json\",\n \"name\": \"minimal\",\n \"displayName\": \"Minimal Clean\",\n \"description\": \"A clean, minimalist theme focused on readability and elegant simplicity\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#000000\",\n \"secondary\": \"#666666\",\n \"accent\": \"#2c3e50\",\n \"background\": \"#ffffff\",\n \"text\": \"#2c2c2c\",\n \"border\": \"#f0f0f0\",\n \"textPrimary\": \"#000000\",\n \"textSecondary\": \"#4a4a4a\",\n \"textMuted\": \"#999999\",\n \"borderPrimary\": \"#e0e0e0\",\n \"borderSecondary\": \"#f5f5f5\",\n \"backgroundPrimary\": \"#ffffff\",\n \"backgroundSecondary\": \"#fafafa\"\n },\n \"fonts\": {\n \"heading\": {\n \"family\": \"Arial\",\n \"size\": 24\n },\n \"body\": {\n \"family\": \"Arial\",\n \"size\": 11\n },\n \"mono\": {\n \"family\": \"Menlo\",\n \"size\": 10\n },\n \"light\": {\n \"family\": \"Arial\",\n \"size\": 24\n }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1080,\n \"right\": 1080,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"#000000\",\n \"lineSpacing\": {\n \"type\": \"multiple\",\n \"value\": 1.5\n },\n \"alignment\": \"justify\",\n \"spacing\": {\n \"after\": 9\n }\n },\n \"heading1\": {\n \"font\": \"light\",\n \"size\": 24,\n \"bold\": false,\n \"color\": \"#000000\",\n \"spacing\": {\n \"before\": 18,\n \"after\": 12\n },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"characterSpacing\": {\n \"type\": \"expanded\",\n \"value\": 1.2\n }\n },\n \"heading2\": {\n \"font\": \"light\",\n \"size\": 20,\n \"bold\": false,\n \"color\": \"#000000\",\n \"spacing\": {\n \"before\": 12,\n \"after\": 9\n },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"characterSpacing\": {\n \"type\": \"expanded\",\n \"value\": 0.8\n }\n },\n \"heading3\": {\n \"font\": \"heading\",\n \"size\": 16,\n \"bold\": false,\n \"color\": \"#2c2c2c\",\n \"spacing\": {\n \"before\": 9,\n \"after\": 6\n },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading4\": {\n \"font\": \"heading\",\n \"size\": 14,\n \"bold\": true,\n \"color\": \"#4a4a4a\",\n \"spacing\": {\n \"before\": 6,\n \"after\": 4\n },\n \"keepNext\": true\n },\n \"heading5\": {\n \"font\": \"heading\",\n \"size\": 12,\n \"bold\": false,\n \"italic\": true,\n \"color\": \"#666666\",\n \"spacing\": {\n \"before\": 4,\n \"after\": 3\n }\n },\n \"heading6\": {\n \"font\": \"light\",\n \"size\": 11,\n \"bold\": false,\n \"color\": \"#999999\",\n \"spacing\": {\n \"before\": 3,\n \"after\": 2\n }\n },\n \"title\": {\n \"font\": \"light\",\n \"bold\": false,\n \"color\": \"#000000\",\n \"alignment\": \"left\",\n \"spacing\": {\n \"before\": 0,\n \"after\": 24\n },\n \"characterSpacing\": {\n \"type\": \"condensed\",\n \"value\": 20\n }\n },\n \"subtitle\": {\n \"font\": \"light\",\n \"size\": 16,\n \"italic\": false,\n \"color\": \"#666666\",\n \"alignment\": \"left\",\n \"spacing\": {\n \"before\": 0,\n \"after\": 18\n }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#f0f0f0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"•\",\n \"indent\": 3\n },\n \"image\": {\n \"alignment\": \"left\"\n },\n \"statistic\": {\n \"alignment\": \"left\"\n },\n \"section\": {\n \"pageBreak\": false\n },\n \"heading\": {\n \"numbering\": false\n }\n }\n}\n","{\n \"name\": \"corporate\",\n \"displayName\": \"Corporate Professional\",\n \"description\": \"A polished corporate theme with blue accents and structured typography\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#1a365d\",\n \"secondary\": \"#2D3748\",\n \"accent\": \"#3182CE\",\n \"text\": \"#1A202C\",\n \"background\": \"#FFFFFF\",\n \"border\": \"#E2E8F0\",\n \"textPrimary\": \"#1A202C\",\n \"textSecondary\": \"#4A5568\",\n \"textMuted\": \"#A0AEC0\",\n \"borderPrimary\": \"#CBD5E0\",\n \"borderSecondary\": \"#E2E8F0\",\n \"backgroundPrimary\": \"#FFFFFF\",\n \"backgroundSecondary\": \"#F7FAFC\"\n },\n \"fonts\": {\n \"heading\": { \"family\": \"Georgia\", \"size\": 26 },\n \"body\": { \"family\": \"Calibri\", \"size\": 11 },\n \"mono\": { \"family\": \"Consolas\", \"size\": 10 },\n \"light\": { \"family\": \"Georgia\", \"size\": 26 }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1200,\n \"right\": 1200,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"#1A202C\",\n \"lineSpacing\": { \"type\": \"multiple\", \"value\": 1.4 },\n \"alignment\": \"justify\",\n \"spacing\": { \"after\": 8 }\n },\n \"heading1\": {\n \"font\": \"heading\",\n \"size\": 26,\n \"bold\": false,\n \"color\": \"primary\",\n \"spacing\": { \"before\": 24, \"after\": 12 },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"borders\": {\n \"bottom\": {\n \"style\": \"single\",\n \"size\": 2,\n \"color\": \"primary\",\n \"space\": 6\n }\n }\n },\n \"heading2\": {\n \"font\": \"heading\",\n \"size\": 18,\n \"bold\": false,\n \"color\": \"secondary\",\n \"spacing\": { \"before\": 18, \"after\": 8 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading3\": {\n \"font\": \"body\",\n \"size\": 13,\n \"bold\": true,\n \"color\": \"accent\",\n \"spacing\": { \"before\": 12, \"after\": 6 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"title\": {\n \"font\": \"light\",\n \"size\": 32,\n \"bold\": false,\n \"color\": \"primary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 18 }\n },\n \"subtitle\": {\n \"font\": \"body\",\n \"size\": 16,\n \"italic\": false,\n \"color\": \"textSecondary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 24 }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#E2E8F0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"\\u2022\",\n \"indent\": 3\n },\n \"statistic\": {\n \"alignment\": \"center\"\n },\n \"section\": {\n \"pageBreak\": false\n },\n \"heading\": {\n \"numbering\": false\n }\n }\n}\n","{\n \"name\": \"modern\",\n \"displayName\": \"Modern Clean\",\n \"description\": \"A contemporary theme with vibrant accents and generous whitespace\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#6D28D9\",\n \"secondary\": \"#1E293B\",\n \"accent\": \"#0891B2\",\n \"text\": \"#0F172A\",\n \"background\": \"#FFFFFF\",\n \"border\": \"#E2E8F0\",\n \"textPrimary\": \"#0F172A\",\n \"textSecondary\": \"#475569\",\n \"textMuted\": \"#94A3B8\",\n \"borderPrimary\": \"#CBD5E1\",\n \"borderSecondary\": \"#E2E8F0\",\n \"backgroundPrimary\": \"#FFFFFF\",\n \"backgroundSecondary\": \"#F8FAFC\"\n },\n \"fonts\": {\n \"heading\": { \"family\": \"Helvetica\", \"size\": 28 },\n \"body\": { \"family\": \"Helvetica\", \"size\": 11 },\n \"mono\": { \"family\": \"Menlo\", \"size\": 10 },\n \"light\": { \"family\": \"Helvetica\", \"size\": 28 }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1080,\n \"right\": 1080,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"#0F172A\",\n \"lineSpacing\": { \"type\": \"multiple\", \"value\": 1.5 },\n \"alignment\": \"left\",\n \"spacing\": { \"after\": 10 }\n },\n \"heading1\": {\n \"font\": \"heading\",\n \"size\": 28,\n \"bold\": true,\n \"color\": \"primary\",\n \"spacing\": { \"before\": 24, \"after\": 14 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading2\": {\n \"font\": \"heading\",\n \"size\": 20,\n \"bold\": true,\n \"color\": \"secondary\",\n \"spacing\": { \"before\": 18, \"after\": 10 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading3\": {\n \"font\": \"body\",\n \"size\": 14,\n \"bold\": true,\n \"color\": \"accent\",\n \"spacing\": { \"before\": 12, \"after\": 6 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"title\": {\n \"font\": \"heading\",\n \"size\": 36,\n \"bold\": true,\n \"color\": \"primary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 12 }\n },\n \"subtitle\": {\n \"font\": \"light\",\n \"size\": 18,\n \"italic\": false,\n \"color\": \"textSecondary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 24 }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#E2E8F0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"\\u2013\",\n \"indent\": 3\n },\n \"image\": {\n \"alignment\": \"center\"\n },\n \"statistic\": {\n \"alignment\": \"center\"\n },\n \"section\": {\n \"pageBreak\": false\n }\n }\n}\n","{\n \"name\": \"apex\",\n \"displayName\": \"Apex Consulting\",\n \"description\": \"A premium consulting theme with deep navy, warm amber accents, and authoritative typography\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#0C2340\",\n \"secondary\": \"#1B3A5C\",\n \"accent\": \"#D4A843\",\n \"text\": \"#1A1A2E\",\n \"background\": \"#FFFFFF\",\n \"border\": \"#D6DAE0\",\n \"textPrimary\": \"#1A1A2E\",\n \"textSecondary\": \"#4A5066\",\n \"textMuted\": \"#8B91A0\",\n \"borderPrimary\": \"#B8BCC6\",\n \"borderSecondary\": \"#E8EAF0\",\n \"backgroundPrimary\": \"#FFFFFF\",\n \"backgroundSecondary\": \"#F4F5F8\"\n },\n \"fonts\": {\n \"heading\": { \"family\": \"Georgia\", \"size\": 26 },\n \"body\": { \"family\": \"Calibri\", \"size\": 11 },\n \"mono\": { \"family\": \"Consolas\", \"size\": 10 },\n \"light\": { \"family\": \"Georgia\", \"size\": 26 }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1200,\n \"right\": 1200,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"textPrimary\",\n \"lineSpacing\": { \"type\": \"multiple\", \"value\": 1.4 },\n \"alignment\": \"justify\",\n \"spacing\": { \"after\": 8 }\n },\n \"heading1\": {\n \"font\": \"heading\",\n \"size\": 26,\n \"bold\": false,\n \"color\": \"primary\",\n \"spacing\": { \"before\": 24, \"after\": 12 },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"borders\": {\n \"bottom\": {\n \"style\": \"single\",\n \"size\": 2,\n \"color\": \"accent\",\n \"space\": 6\n }\n }\n },\n \"heading2\": {\n \"font\": \"heading\",\n \"size\": 18,\n \"bold\": false,\n \"color\": \"secondary\",\n \"spacing\": { \"before\": 18, \"after\": 8 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading3\": {\n \"font\": \"body\",\n \"size\": 13,\n \"bold\": true,\n \"color\": \"accent\",\n \"spacing\": { \"before\": 12, \"after\": 6 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"title\": {\n \"font\": \"light\",\n \"size\": 36,\n \"bold\": false,\n \"color\": \"primary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 18 }\n },\n \"subtitle\": {\n \"font\": \"body\",\n \"size\": 16,\n \"italic\": false,\n \"color\": \"textSecondary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 24 }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#D6DAE0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"\\u2022\",\n \"indent\": 3\n },\n \"image\": {\n \"alignment\": \"center\"\n },\n \"statistic\": {\n \"alignment\": \"center\"\n },\n \"section\": {\n \"pageBreak\": false\n },\n \"heading\": {\n \"numbering\": false\n }\n }\n}\n","{\n \"name\": \"devportal\",\n \"displayName\": \"Developer Portal\",\n \"description\": \"A modern developer-focused theme with cool grays, teal accents, and monospace code styling\",\n \"version\": \"2.0.0\",\n \"colors\": {\n \"primary\": \"#0F172A\",\n \"secondary\": \"#334155\",\n \"accent\": \"#0D9488\",\n \"text\": \"#0F172A\",\n \"background\": \"#FFFFFF\",\n \"border\": \"#E2E8F0\",\n \"textPrimary\": \"#0F172A\",\n \"textSecondary\": \"#475569\",\n \"textMuted\": \"#94A3B8\",\n \"borderPrimary\": \"#CBD5E1\",\n \"borderSecondary\": \"#F1F5F9\",\n \"backgroundPrimary\": \"#FFFFFF\",\n \"backgroundSecondary\": \"#F8FAFC\"\n },\n \"fonts\": {\n \"heading\": { \"family\": \"Helvetica\", \"size\": 24 },\n \"body\": { \"family\": \"Calibri\", \"size\": 11 },\n \"mono\": { \"family\": \"Consolas\", \"size\": 10 },\n \"light\": { \"family\": \"Helvetica\", \"size\": 24 }\n },\n \"page\": {\n \"size\": \"A4\",\n \"margins\": {\n \"top\": 1440,\n \"bottom\": 1440,\n \"left\": 1080,\n \"right\": 1080,\n \"header\": 720,\n \"footer\": 720,\n \"gutter\": 0\n }\n },\n \"styles\": {\n \"normal\": {\n \"font\": \"body\",\n \"color\": \"textPrimary\",\n \"lineSpacing\": { \"type\": \"multiple\", \"value\": 1.5 },\n \"alignment\": \"left\",\n \"spacing\": { \"after\": 8 }\n },\n \"heading1\": {\n \"font\": \"heading\",\n \"size\": 24,\n \"bold\": true,\n \"color\": \"primary\",\n \"spacing\": { \"before\": 24, \"after\": 12 },\n \"keepNext\": true,\n \"alignment\": \"left\",\n \"borders\": {\n \"bottom\": {\n \"style\": \"single\",\n \"size\": 1,\n \"color\": \"accent\",\n \"space\": 6\n }\n }\n },\n \"heading2\": {\n \"font\": \"heading\",\n \"size\": 18,\n \"bold\": true,\n \"color\": \"secondary\",\n \"spacing\": { \"before\": 18, \"after\": 8 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading3\": {\n \"font\": \"body\",\n \"size\": 13,\n \"bold\": true,\n \"color\": \"accent\",\n \"spacing\": { \"before\": 12, \"after\": 6 },\n \"keepNext\": true,\n \"alignment\": \"left\"\n },\n \"heading4\": {\n \"font\": \"body\",\n \"size\": 12,\n \"bold\": true,\n \"color\": \"textSecondary\",\n \"spacing\": { \"before\": 8, \"after\": 4 },\n \"keepNext\": true\n },\n \"title\": {\n \"font\": \"heading\",\n \"size\": 32,\n \"bold\": true,\n \"color\": \"primary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 12 }\n },\n \"subtitle\": {\n \"font\": \"light\",\n \"size\": 16,\n \"italic\": false,\n \"color\": \"textSecondary\",\n \"alignment\": \"left\",\n \"spacing\": { \"before\": 0, \"after\": 24 }\n }\n },\n \"componentDefaults\": {\n \"table\": {\n \"borderColor\": \"#E2E8F0\"\n },\n \"list\": {\n \"format\": \"bullet\",\n \"bullet\": \"\\u2013\",\n \"indent\": 3\n },\n \"image\": {\n \"alignment\": \"center\"\n },\n \"statistic\": {\n \"alignment\": \"center\"\n },\n \"section\": {\n \"pageBreak\": false\n },\n \"heading\": {\n \"numbering\": false\n }\n }\n}\n","/**\n * JSON-based themes registry\n * This file provides a unified interface to JSON themes\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport {\n isValidThemeConfig,\n type ThemeConfigJson,\n} from '@json-to-office/shared-docx';\nimport { ensureThemeDefaults } from '../../themes/defaults';\n\n// Import theme JSON files directly. Every bundled theme is imported here, so\n// which themes exist is decided by code, not by whether `dist/` happens to be\n// built and fresh — `apex` and `devportal` used to be reachable only through\n// the filesystem scan below, which meant a stale build silently served the old\n// copy and a missing one degraded to `minimal`.\nimport minimalThemeJson from './minimal.docx.theme.json';\nimport corporateThemeJson from './corporate.docx.theme.json';\nimport modernThemeJson from './modern.docx.theme.json';\nimport apexThemeJson from './apex.docx.theme.json';\nimport devportalThemeJson from './devportal.docx.theme.json';\n\n/**\n * Registry of available themes loaded from JSON files\n */\nlet _themesCache: Record<string, ThemeConfigJson> | null = null;\n\nfunction loadThemesFromJson(): Record<string, ThemeConfigJson> {\n if (_themesCache) {\n return _themesCache;\n }\n\n // Build themes from imported JSON files\n const themes: Record<string, ThemeConfigJson> = {\n minimal: ensureThemeDefaults(minimalThemeJson as ThemeConfigJson),\n corporate: ensureThemeDefaults(corporateThemeJson as ThemeConfigJson),\n modern: ensureThemeDefaults(modernThemeJson as ThemeConfigJson),\n apex: ensureThemeDefaults(apexThemeJson as ThemeConfigJson),\n devportal: ensureThemeDefaults(devportalThemeJson as ThemeConfigJson),\n };\n\n // Also try to load from file system for runtime additions (if available)\n try {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const themesDir = path.join(__dirname, '../../../dist/templates/themes');\n\n if (fs.existsSync(themesDir)) {\n const themeFiles = fs\n .readdirSync(themesDir)\n .filter((file) => file.endsWith('.docx.theme.json'))\n .map((file) => path.basename(file, '.docx.theme.json'));\n\n for (const themeName of themeFiles) {\n if (!themes[themeName]) {\n try {\n const filePath = path.join(\n themesDir,\n `${themeName}.docx.theme.json`\n );\n const content = fs.readFileSync(filePath, 'utf8');\n const parsedTheme = JSON.parse(content);\n // Check before registering. A theme that reaches the registry is\n // never validated again, so an invalid one here renders wrong\n // rather than failing — the drift that hid dead `componentDefaults`\n // props across five themes for as long as they shipped.\n if (!isValidThemeConfig(parsedTheme)) {\n console.warn(\n `Skipping theme ${themeName}: does not match the theme schema.`\n );\n continue;\n }\n themes[themeName] = ensureThemeDefaults(parsedTheme);\n } catch (error) {\n console.warn(\n `Failed to load additional theme ${themeName}:`,\n error\n );\n }\n }\n }\n }\n } catch (error) {\n // Silently ignore if file system access fails (e.g., in bundled environment)\n }\n\n _themesCache = themes;\n return themes;\n}\n\nexport const themes = loadThemesFromJson();\n\n/**\n * Type representing valid theme names\n */\nexport type ThemeName = keyof typeof themes;\n\n/**\n * Get theme configuration by name\n * @param themeName - Name of the theme to retrieve\n * @returns Theme configuration or undefined if not found\n */\nexport const getTheme = (themeName: string): ThemeConfigJson | undefined => {\n return themes[themeName];\n};\n\n/**\n * Get theme configuration with safe fallback\n * @param themeName - Name of the theme to retrieve\n * @param fallbackTheme - Fallback theme name (default: 'minimal')\n * @returns Theme configuration (guaranteed to be defined)\n * @throws Error if neither theme nor fallback can be found\n */\nexport const getThemeWithFallback = (\n themeName: string,\n fallbackTheme: string = 'minimal'\n): ThemeConfigJson => {\n const theme = getTheme(themeName) || getTheme(fallbackTheme);\n\n if (!theme) {\n throw new Error(\n `Failed to load theme: ${themeName}. Fallback theme '${fallbackTheme}' also not found.`\n );\n }\n\n return theme;\n};\n\n/**\n * Check if a theme exists\n * @param themeName - Name of the theme to check\n * @returns True if theme exists, false otherwise\n */\nexport const hasTheme = (themeName: string): boolean => {\n return themeName in themes;\n};\n\n/**\n * Type guard to ensure theme name is valid\n * @param themeName - Theme name to validate\n * @returns True if theme name exists in registry\n */\nexport const isValidThemeName = (\n themeName: string\n): themeName is keyof typeof themes => {\n return hasTheme(themeName);\n};\n\n/**\n * Get all available theme names\n * @returns Array of theme names\n */\nexport const getThemeNames = (): string[] => {\n return Object.keys(themes);\n};\n\n// Export individual theme configs for direct access\nexport const minimalTheme = themes['minimal'];\nexport const corporateTheme = themes['corporate'];\nexport const modernTheme = themes['modern'];\n","import { ThemeConfig } from '../index';\nimport { getThemeColors } from '../../themes/defaults';\n\nexport type ColorName = keyof ReturnType<typeof getThemeColors>;\n\n// Union type for all valid color names\nexport type ValidColorName =\n | 'primary'\n | 'secondary'\n | 'accent'\n | 'text'\n | 'background'\n | 'textPrimary'\n | 'textSecondary'\n | 'textMuted'\n | 'borderPrimary'\n | 'borderSecondary'\n | 'backgroundPrimary'\n | 'backgroundSecondary';\n\n// Type for color value that can be either a hex string or a color name\nexport type ColorValue = string; // Can be hex color or color name\n\n/**\n * Resolves a color value, which can be either a hex color string or a color name reference\n * @param colorValue - Either a hex color (e.g., '#000000') or a color name (e.g., 'primary')\n * @param theme - The theme configuration containing color definitions\n * @returns The resolved hex color value (6-character hex without #)\n * @throws Error if the color value is invalid\n */\nexport function resolveColor(\n colorValue: ColorValue,\n theme: ThemeConfig\n): string {\n // Check if it's a hex color with # prefix\n if (colorValue.startsWith('#')) {\n const hexValue = colorValue.slice(1);\n if (/^[0-9A-Fa-f]{6}$/.test(hexValue)) {\n return hexValue.toUpperCase(); // Normalize to uppercase\n }\n // Invalid hex format\n throw new Error(\n `Invalid hex color: \"${colorValue}\". Hex colors must be in format #RRGGBB (e.g., \"#000000\").`\n );\n }\n\n // If it's a color name, resolve it from the theme. Optional slots\n // (accent4-6) may be present-but-undefined, which counts as unset.\n const colors = getThemeColors(theme);\n const resolvedColor = colors[colorValue as ColorName];\n if (typeof resolvedColor === 'string') {\n // Recursively resolve in case the theme color is also a reference\n return resolveColor(resolvedColor, theme);\n }\n\n // Bare 6-digit hex, e.g. \"F0FDF4\". HexColorSchema admits it through the\n // theme-name branch, so rejecting it here would validate a document and then\n // throw while rendering it. Table cells and the chart palette already accept\n // this form; no theme color name is six hex characters, so there is no\n // ambiguity with a real token.\n if (/^[0-9A-Fa-f]{6}$/.test(colorValue)) {\n return colorValue.toUpperCase();\n }\n\n // Strict validation - throw error for invalid colors\n throw new Error(\n `Invalid color value: \"${colorValue}\". Must be a hex color with # prefix (e.g., \"#000000\") or a valid theme color name.`\n );\n}\n\n/**\n * Validates if a color name is set in the theme\n * @param colorName - The color name to validate\n * @param theme - The theme configuration\n * @returns True if the color name resolves to a value. A present-but-undefined\n * optional slot counts as unset, matching what `resolveColor` accepts.\n */\nexport function isValidColorName(\n colorName: string,\n theme: ThemeConfig\n): boolean {\n const colors = getThemeColors(theme);\n if (typeof colors[colorName as ColorName] !== 'string') return false;\n // Follow the reference chain: a token whose value names an unset slot is not\n // usable, so reporting it as valid would hand a caller a color that throws.\n try {\n resolveColor(colorName as ColorValue, theme);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Gets all available color names from a theme\n * @param theme - The theme configuration\n * @returns Array of valid color names, excluding present-but-undefined slots\n */\nexport function getAvailableColorNames(theme: ThemeConfig): string[] {\n const colors = getThemeColors(theme);\n return Object.keys(colors).filter((name) => isValidColorName(name, theme));\n}\n","import { getTheme } from '../../templates/themes';\nimport { ThemeConfig } from '../index';\nimport { resolveColor } from './colorUtils';\nimport { LineSpacing } from '@json-to-office/shared-docx';\nimport { ISpacingProperties } from 'docx';\nimport { getNormalStyle } from '../../themes/defaults';\n\n// Constants for line spacing calculations\nconst TWIPS_PER_POINT = 20;\nconst SINGLE_LINE_SPACING_POINTS = 12;\nconst SINGLE_LINE_SPACING_TWIPS = SINGLE_LINE_SPACING_POINTS * TWIPS_PER_POINT;\nconst DOUBLE_LINE_SPACING_TWIPS = SINGLE_LINE_SPACING_TWIPS * 2;\n\n/**\n * Convert points to twips for docx spacing\n * @param points - Value in points\n * @returns Value in twips (1/20 of a point)\n */\nexport function pointsToTwips(points: number): number {\n return Math.round(points * TWIPS_PER_POINT);\n}\n\n/**\n * Resolve theme configuration from either a theme object or theme name\n * @param theme - Theme configuration object (for custom themes)\n * @param themeName - Theme name (for built-in themes)\n * @returns Resolved theme configuration\n */\nexport function resolveTheme(\n theme?: ThemeConfig,\n themeName?: string\n): ThemeConfig | undefined {\n // First check if we have a theme object passed directly (for custom themes)\n if (theme) {\n return theme;\n }\n\n // If no theme object, check for built-in theme by name\n if (themeName) {\n return getTheme(themeName);\n }\n\n // Default to minimal theme if nothing else works\n return getTheme('minimal');\n}\n\n/**\n * Resolve font family from font reference (e.g., 'body', 'heading') to actual font family name\n * @param theme - Theme configuration object\n * @param fontRef - Font reference ('body', 'heading', 'mono', 'light') or undefined\n * @returns Actual font family name (e.g., 'Arial', 'Helvetica')\n */\nexport function resolveFontFamily(\n theme: ThemeConfig,\n fontRef?: 'heading' | 'body' | 'mono' | 'light'\n): string {\n // Handle empty/invalid themes gracefully\n if (!theme?.fonts?.body?.family) {\n return 'Arial'; // fallback to Arial\n }\n if (!fontRef) {\n return theme.fonts.body.family;\n }\n return theme.fonts[fontRef]?.family || theme.fonts.body.family;\n}\n\n/**\n * Resolve font size from font reference (e.g., 'body', 'heading') to actual font size in points\n * @param theme - Theme configuration object\n * @param fontRef - Font reference ('body', 'heading', 'mono', 'light') or undefined\n * @returns Font size in points (callers multiply by 2 for docx) or undefined if no size found\n */\nexport function resolveFontSize(\n theme: ThemeConfig,\n fontRef?: 'heading' | 'body' | 'mono' | 'light'\n): number | undefined {\n // Handle empty/invalid themes gracefully\n if (!theme?.fonts?.body?.size) {\n return undefined; // let caller handle fallback\n }\n if (!fontRef) {\n return theme.fonts.body.size;\n }\n return theme.fonts[fontRef]?.size || theme.fonts.body.size;\n}\n\n/**\n * Font properties that can be defined in font definitions\n */\nexport interface FontProperties {\n family?: string;\n size?: number;\n color?: string;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n alignment?: 'left' | 'center' | 'right' | 'justify';\n lineSpacing?: {\n type: 'single' | 'atLeast' | 'exactly' | 'double' | 'multiple';\n value?: number;\n };\n spacing?: {\n before?: number;\n after?: number;\n };\n characterSpacing?: { type: 'condensed' | 'expanded'; value: number };\n scale?: number;\n}\n\n/**\n * Resolve all font properties from font reference.\n * Returns all formatting properties defined in the font definition.\n * @param theme - Theme configuration object\n * @param fontRef - Font reference ('body', 'heading', 'mono', 'light') or undefined\n * @returns Object containing all font properties\n */\nexport function resolveFontProperties(\n theme: ThemeConfig,\n fontRef?: 'heading' | 'body' | 'mono' | 'light'\n): FontProperties {\n // Default to body font if no reference provided\n const targetFontKey = fontRef || 'body';\n\n // Handle empty/invalid themes gracefully\n if (!theme?.fonts?.[targetFontKey]) {\n return {\n family: 'Arial',\n size: 11,\n };\n }\n\n const fontDef = theme.fonts[targetFontKey] as FontProperties;\n\n return {\n family: fontDef.family,\n size: fontDef.size,\n color: fontDef.color,\n bold: fontDef.bold,\n italic: fontDef.italic,\n underline: fontDef.underline,\n alignment: fontDef.alignment,\n lineSpacing: fontDef.lineSpacing,\n spacing: fontDef.spacing,\n characterSpacing: fontDef.characterSpacing,\n scale: fontDef.scale,\n };\n}\n\n/**\n * Merge font properties with style overrides.\n * Style properties take precedence over font properties.\n * Only defined (non-undefined) style properties override font properties.\n * @param fontProps - Properties from font definition\n * @param styleOverrides - Properties from style definition\n * @returns Merged properties object\n */\nexport function mergeFontAndStyleProperties<T extends Partial<FontProperties>>(\n fontProps: FontProperties,\n styleOverrides: T\n): FontProperties & T {\n // Filter out undefined values from styleOverrides to prevent overwriting font properties\n // Use type-safe Object.entries approach\n const definedOverrides = Object.entries(styleOverrides).reduce<\n Record<string, unknown>\n >((acc, [key, value]) => {\n if (value !== undefined) {\n acc[key] = value;\n }\n return acc;\n }, {});\n\n return {\n ...fontProps,\n ...definedOverrides,\n } as FontProperties & T;\n}\n\n/**\n * Get body text style configuration\n * @param theme - Theme configuration object\n * @param themeName - Name of the theme (for fallback to built-in themes)\n * @returns Style configuration object\n */\nexport const getBodyTextStyle = (theme?: ThemeConfig, themeName?: string) => {\n const themeConfig = resolveTheme(theme, themeName);\n\n if (themeConfig) {\n const normalStyle = getNormalStyle(themeConfig);\n return {\n size: (normalStyle.size || 11) * 2,\n font: resolveFontFamily(themeConfig, normalStyle.font),\n color: normalStyle.color\n ? resolveColor(normalStyle.color, themeConfig)\n : '000000',\n };\n }\n\n // Fallback\n return {\n size: 20,\n font: 'Arial',\n color: '000000',\n };\n};\n\n/**\n * Converts line spacing from theme definition to DOCX spacing options.\n * DOCX uses twips (1/20th of a point) for line spacing.\n * @param lineSpacing The line spacing object from the theme definition.\n * @returns IParagraphSpacingOptions for docx.\n */\nexport function convertLineSpacing(\n lineSpacing?: LineSpacing | number\n): ISpacingProperties | undefined {\n if (lineSpacing === undefined) {\n return undefined;\n }\n\n // Handle number (simple multiplier) case\n if (typeof lineSpacing === 'number') {\n return {\n line: Math.round(lineSpacing * SINGLE_LINE_SPACING_TWIPS),\n lineRule: 'auto',\n };\n }\n\n const { type, value } = lineSpacing;\n let line: number | undefined;\n let lineRule: 'auto' | 'exact' | 'atLeast' | undefined;\n\n switch (type) {\n case 'single':\n line = SINGLE_LINE_SPACING_TWIPS;\n lineRule = 'auto';\n break;\n case 'double':\n line = DOUBLE_LINE_SPACING_TWIPS;\n lineRule = 'auto';\n break;\n case 'atLeast':\n line = value !== undefined ? value * TWIPS_PER_POINT : undefined;\n lineRule = 'atLeast';\n break;\n case 'exactly':\n line = value !== undefined ? value * TWIPS_PER_POINT : undefined;\n lineRule = 'exact';\n break;\n case 'multiple':\n line =\n value !== undefined ? value * SINGLE_LINE_SPACING_TWIPS : undefined;\n lineRule = 'auto';\n break;\n default:\n return undefined;\n }\n\n return { line, lineRule };\n}\n","import { BorderStyle } from 'docx';\nimport { LineSpacing } from '@json-to-office/shared-docx';\nimport { ThemeConfig } from '../index';\nimport { resolveColor } from './colorUtils';\nimport {\n resolveTheme,\n resolveFontFamily,\n convertLineSpacing,\n pointsToTwips,\n} from './styleHelpers';\n\n/**\n * Subset of a theme StyleProperties entry relevant to paragraph spacing.\n */\ninterface TableParagraphStyle {\n spacing?: { before?: number; after?: number };\n lineSpacing?: LineSpacing;\n}\n\n/**\n * Resolve the paragraph spacing for a table cell/header wrapper paragraph.\n *\n * Table cells render as a single wrapper paragraph. Historically that paragraph\n * inherited the `normal` style, dragging body-prose rhythm (8–10pt after-spacing\n * + 1.4–1.5x line) into every row and inflating row height regardless of font\n * size, padding, or the cell `height` prop. Tables should be dense by default:\n * no extra paragraph spacing, single line. Vertical breathing room is the job of\n * cell padding, not paragraph spacing.\n *\n * Themes may override per context via `styles.tableCell` / `styles.tableHeader`\n * (standard StyleProperties: `spacing.before/after` in points, `lineSpacing`).\n */\nconst resolveTableParagraphSpacing = (style?: TableParagraphStyle) => {\n const lineSpacing =\n convertLineSpacing(style?.lineSpacing) ??\n convertLineSpacing({ type: 'single' });\n return {\n before:\n style?.spacing?.before !== undefined\n ? pointsToTwips(style.spacing.before)\n : 0,\n after:\n style?.spacing?.after !== undefined\n ? pointsToTwips(style.spacing.after)\n : 0,\n ...lineSpacing,\n };\n};\n\n/**\n * Standard page sizes in twips (1/20 of a point, 1/1440 of an inch)\n */\nconst PAGE_SIZES = {\n A4: { width: 11906, height: 16838 },\n A3: { width: 16838, height: 23811 },\n LETTER: { width: 12240, height: 15840 },\n LEGAL: { width: 12240, height: 20160 },\n} as const;\n\n/**\n * Get page dimensions from size (string or object)\n */\nfunction getPageDimensions(\n size: 'A4' | 'A3' | 'LETTER' | 'LEGAL' | { width: number; height: number }\n): { width: number; height: number } {\n if (typeof size === 'string') {\n return PAGE_SIZES[size];\n }\n return size;\n}\n\n/**\n * Get table style configuration\n * @param theme - Theme configuration object\n * @param themeName - Name of the theme (for fallback to built-in themes)\n * @returns Table style configuration object\n */\nexport const getTableStyle = (theme?: ThemeConfig, themeName?: string) => {\n const themeConfig = resolveTheme(theme, themeName);\n\n if (themeConfig && themeConfig.styles?.normal) {\n // Use normal style for run-level header/cell defaults (font, size, color).\n // Paragraph spacing is resolved separately so table rows stay dense and do\n // not inherit `normal`'s body-prose after-spacing/line height.\n const normalStyle = themeConfig.styles.normal;\n const styles = themeConfig.styles as Record<string, TableParagraphStyle>;\n return {\n cellParagraph: resolveTableParagraphSpacing(styles.tableCell),\n headerParagraph: resolveTableParagraphSpacing(styles.tableHeader),\n tableHeader: {\n fill: resolveColor(\n themeConfig.colors?.primary || '#000000',\n themeConfig\n ),\n color: resolveColor(\n themeConfig.colors?.backgroundPrimary || '#FFFFFF',\n themeConfig\n ), // Use background color for header text\n bold: true, // Headers should be bold\n size: (normalStyle.size || 11) * 2, // Convert to half-points\n font: resolveFontFamily(themeConfig, normalStyle.font),\n },\n tableCell: {\n color: resolveColor(normalStyle.color || '#000000', themeConfig),\n size: (normalStyle.size || 11) * 2, // Convert to half-points\n font: resolveFontFamily(themeConfig, normalStyle.font),\n },\n alternatingRow: {\n fill: resolveColor(\n themeConfig.colors?.accent || '#F0F0F0',\n themeConfig\n ),\n },\n borders: {\n top: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: resolveColor(\n themeConfig.colors?.secondary || '#CCCCCC',\n themeConfig\n ),\n },\n bottom: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: resolveColor(\n themeConfig.colors?.secondary || '#CCCCCC',\n themeConfig\n ),\n },\n left: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: resolveColor(\n themeConfig.colors?.secondary || '#CCCCCC',\n themeConfig\n ),\n },\n right: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: resolveColor(\n themeConfig.colors?.secondary || '#CCCCCC',\n themeConfig\n ),\n },\n },\n };\n }\n\n // This shouldn't happen with minimal themes\n return {\n cellParagraph: resolveTableParagraphSpacing(),\n headerParagraph: resolveTableParagraphSpacing(),\n tableHeader: {\n fill: '000000',\n color: 'FFFFFF',\n bold: true,\n size: 22,\n font: 'Arial',\n },\n tableCell: {\n color: '000000',\n size: 20,\n font: 'Arial',\n },\n alternatingRow: {\n fill: 'F5F5F5',\n },\n borders: {\n top: { style: BorderStyle.SINGLE, size: 1, color: '000000' },\n bottom: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: '000000',\n },\n left: { style: BorderStyle.SINGLE, size: 1, color: '000000' },\n right: {\n style: BorderStyle.SINGLE,\n size: 1,\n color: '000000',\n },\n },\n };\n};\n\n/**\n * Get document margins configuration\n * @param theme - Theme configuration object\n * @param themeName - Name of the theme (for fallback to built-in themes)\n * @returns Document margins object\n */\nexport const getDocumentMargins = (theme?: ThemeConfig, themeName?: string) => {\n const themeConfig = resolveTheme(theme, themeName);\n\n if (themeConfig?.page?.margins) {\n return themeConfig.page.margins;\n }\n\n // Default margins for all themes (standard Word document margins)\n return {\n top: 1440, // 1 inch in twips\n right: 1440, // 1 inch in twips\n bottom: 1440, // 1 inch in twips\n left: 1440, // 1 inch in twips\n header: 720, // 0.5 inch in twips\n footer: 720, // 0.5 inch in twips\n };\n};\n\n/**\n * Get page setup configuration\n * @param theme - Theme configuration object\n * @param themeName - Name of the theme (for fallback to built-in themes)\n * @returns Page setup object\n */\nexport const getPageSetup = (theme?: ThemeConfig, themeName?: string) => {\n const themeConfig = resolveTheme(theme, themeName);\n const defaultMargins = getDocumentMargins(theme, themeName);\n\n if (themeConfig?.page) {\n const margins = themeConfig.page.margins || {};\n const dimensions = getPageDimensions(themeConfig.page.size);\n return {\n size: {\n width: dimensions.width,\n height: dimensions.height,\n },\n margin: {\n top: margins.top ?? defaultMargins.top ?? 1440,\n right: margins.right ?? defaultMargins.right ?? 1440,\n bottom: margins.bottom ?? defaultMargins.bottom ?? 1440,\n left: margins.left ?? defaultMargins.left ?? 1440,\n },\n };\n }\n\n // Default page setup for all themes\n return {\n size: {\n width: 11906, // 8.5 inches in twips (Letter size)\n height: 16838, // 11.7 inches in twips (Letter size)\n },\n margin: {\n top: defaultMargins.top ?? 1440,\n right: defaultMargins.right ?? 1440,\n bottom: defaultMargins.bottom ?? 1440,\n left: defaultMargins.left ?? 1440,\n },\n };\n};\n","/**\n * Theme Parser using unified validation (TypeBox under the hood)\n */\n\nimport type { ThemeConfigJson } from '@json-to-office/shared-docx';\nimport { validateThemeJson } from '@json-to-office/shared-docx/validation/unified';\nimport type { ValidationError } from '@json-to-office/shared-docx/validation/unified';\nimport { ensureThemeDefaults } from '../../themes/defaults';\n\n// Custom error classes with enhanced error details\nexport class ThemeValidationError extends Error {\n constructor(public errors: ValidationError[]) {\n const errorCount = errors.length;\n const errorSummary = errors\n .slice(0, 3)\n .map((error) => {\n const path = error.path\n ? error.path.replace(/^\\//, '').replace(/\\//g, '.')\n : '';\n const pathStr = path ? `${path}: ` : '';\n return `${pathStr}${error.message}`;\n })\n .join('; ');\n\n super(\n `Theme validation failed with ${errorCount} error${errorCount > 1 ? 's' : ''}: ${errorSummary}${errorCount > 3 ? '...' : ''}`\n );\n this.name = 'ThemeValidationError';\n }\n\n getDetailedErrors(): string[] {\n return this.errors.map((error) => {\n const path = error.path\n ? error.path.replace(/^\\//, '').replace(/\\//g, '.')\n : '';\n const pathStr = path ? `${path}: ` : '';\n return `${pathStr}${error.message}`;\n });\n }\n}\n\nexport class ThemeParseError extends Error {\n constructor(\n message: string,\n public cause?: Error\n ) {\n super(`Failed to parse theme: ${message}`);\n this.name = 'ThemeParseError';\n }\n}\n\n// Theme parser class with comprehensive validation and error handling\nexport class ThemeParser {\n private readonly MAX_JSON_SIZE = 1024 * 1024; // 1MB limit (pre-parse guard)\n\n parse(jsonString: string): ThemeConfigJson {\n try {\n // Input validation and sanitization\n this.validateInput(jsonString);\n\n // Use unified validator (handles parsing + position calculation)\n const result = validateThemeJson(jsonString);\n if (!result.valid) {\n throw new ThemeValidationError(result.errors || []);\n }\n\n const validated = result.data as ThemeConfigJson;\n\n // Apply defaults and return ThemeConfig\n return this.applyDefaults(validated);\n } catch (error) {\n if (\n error instanceof ThemeValidationError ||\n error instanceof ThemeParseError\n ) {\n throw error;\n }\n throw new ThemeParseError(\n `Unexpected error during theme parsing: ${error instanceof Error ? error.message : String(error)}`,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private validateInput(jsonString: string): void {\n // Check for null/undefined\n if (!jsonString) {\n throw new ThemeParseError('JSON string cannot be null or empty');\n }\n\n // Check string type\n if (typeof jsonString !== 'string') {\n throw new ThemeParseError('Input must be a string');\n }\n\n // Check size limits (additional robustness guard)\n if (jsonString.length > this.MAX_JSON_SIZE) {\n throw new ThemeParseError(\n `JSON string too large (${jsonString.length} bytes, max ${this.MAX_JSON_SIZE} bytes)`\n );\n }\n }\n\n private applyDefaults(parsedTheme: ThemeConfigJson): ThemeConfigJson {\n // Apply defaults to ensure all required properties are present\n // This handles partial theme configurations by merging with defaults\n return ensureThemeDefaults(parsedTheme);\n }\n\n // Utility method for validating without parsing\n validate(jsonString: string): { valid: boolean; errors?: string[] } {\n try {\n this.validateInput(jsonString);\n const result = validateThemeJson(jsonString);\n\n if (result.valid) {\n return { valid: true };\n } else {\n const errors = (result.errors || []).map((e) => {\n const path = e.path\n ? e.path.replace(/^\\//, '').replace(/\\//g, '.')\n : '';\n const pathStr = path ? `${path}: ` : '';\n return `${pathStr}${e.message}`;\n });\n return { valid: false, errors };\n }\n } catch (error) {\n return {\n valid: false,\n errors: [\n error instanceof Error ? error.message : 'Unknown validation error',\n ],\n };\n }\n }\n}\n","/**\n * Theme Validator - thin wrapper over shared unified validator\n * Maintains backward-compatible API while removing duplicate logic\n */\n\nimport { validateThemeJson as validateThemeJsonUnified } from '@json-to-office/shared-docx/validation/unified';\n\n// Backward-compatible ValidationResult type used by core\nexport type ValidationResult = {\n success: boolean;\n error?: {\n issues: Array<{\n code: string;\n message: string;\n path: Array<string | number>;\n expected?: string;\n received?: string;\n type?: string;\n minimum?: number;\n maximum?: number;\n validation?: string;\n options?: string[];\n line?: number;\n column?: number;\n }>;\n };\n};\n\n// Validator function using unified shared validation\nexport function validateThemeJson(jsonString: string): ValidationResult {\n const result = validateThemeJsonUnified(jsonString);\n\n if (result.valid) {\n return { success: true };\n }\n\n const issues = (result.errors || []).map((e) => {\n const pathArray = (e.path || '')\n .split('/')\n .filter((p) => p)\n .map((p) => {\n const num = parseInt(p, 10);\n return isNaN(num) ? p : num;\n });\n\n return {\n code: e.code || 'validation_error',\n message: e.message,\n path: pathArray,\n line: e.line,\n column: e.column,\n };\n });\n\n return { success: false, error: { issues } };\n}\n\nexport function formatValidationErrors(error: {\n issues: Array<any>;\n}): string[] {\n return error.issues.map((issue) => {\n const path =\n issue.path && issue.path.length > 0 ? `${issue.path.join('.')}: ` : '';\n let message = issue.message;\n // Keep messages simple; unified validator already includes good messages\n return `${path}${message}`;\n });\n}\n\nexport function isValidThemeJson(jsonString: string): boolean {\n const result = validateThemeJson(jsonString);\n return result.success;\n}\n\nexport function getValidationSummary(jsonString: string): {\n valid: boolean;\n errorCount: number;\n errors: string[];\n summary: string;\n} {\n const result = validateThemeJson(jsonString);\n\n if (result.success) {\n return {\n valid: true,\n errorCount: 0,\n errors: [],\n summary: 'Theme JSON is valid',\n };\n }\n\n const errors = formatValidationErrors(result.error!);\n const errorCount = errors.length;\n\n return {\n valid: false,\n errorCount,\n errors,\n summary: `Theme validation failed with ${errorCount} error${errorCount > 1 ? 's' : ''}`,\n };\n}\n","import { promises as fs } from 'fs';\nimport { normalize } from 'path';\nimport type { ThemeConfigJson } from '@json-to-office/shared-docx';\nimport { ThemeParser } from './parser';\n\n// File system error class with enhanced error details\nexport class ThemeFileError extends Error {\n constructor(\n message: string,\n public path?: string,\n public _cause?: Error\n ) {\n const pathInfo = path ? ` (path: ${path})` : '';\n super(`Failed to load theme file: ${message}${pathInfo}`);\n this.name = 'ThemeFileError';\n }\n}\n\n// Theme loader class with comprehensive security and error handling\nexport class ThemeLoader {\n private parser = new ThemeParser();\n private readonly MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB limit\n private readonly ALLOWED_EXTENSIONS = ['.json'];\n\n async loadFromFile(filePath: string): Promise<ThemeConfigJson> {\n try {\n // Validate file path for security\n this.validateFilePath(filePath);\n\n // Read file with size limits\n const content = await this.readFileWithLimits(filePath);\n\n // Parse the theme content\n return this.parser.parse(content);\n } catch (error) {\n if (error instanceof ThemeFileError) {\n throw error;\n }\n\n // Handle file system errors\n if (error && typeof error === 'object' && 'code' in error) {\n const fsError = error as { code?: string; message: string };\n let message: string;\n\n switch (fsError.code) {\n case 'ENOENT':\n message = 'File not found';\n break;\n case 'EACCES':\n message = 'Permission denied';\n break;\n case 'EISDIR':\n message = 'Path is a directory, not a file';\n break;\n case 'EMFILE':\n case 'ENFILE':\n message = 'Too many open files';\n break;\n case 'ENOTDIR':\n message = 'Directory in path does not exist';\n break;\n default:\n message = `File system error: ${fsError.message}`;\n }\n\n throw new ThemeFileError(\n message,\n filePath,\n error instanceof Error ? error : undefined\n );\n }\n\n // Handle other errors\n throw new ThemeFileError(\n `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,\n filePath,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n async loadFromUrl(_url: string): Promise<ThemeConfigJson> {\n // Future enhancement for loading themes from URLs\n // Would need additional dependencies (fetch) and security considerations\n throw new ThemeFileError(\n 'URL loading not yet implemented - use loadFromFile() instead'\n );\n }\n\n private validateFilePath(filePath: string): void {\n // Basic input validation\n if (!filePath || typeof filePath !== 'string') {\n throw new ThemeFileError('File path must be a non-empty string');\n }\n\n // Normalize the path to handle different separators and relative paths\n const normalizedPath = normalize(filePath);\n\n // Check for directory traversal attempts\n if (normalizedPath.includes('..')) {\n throw new ThemeFileError('Directory traversal is not allowed', filePath);\n }\n\n // Check for null bytes (path injection)\n if (normalizedPath.includes('\\0')) {\n throw new ThemeFileError(\n 'Null bytes in file path are not allowed',\n filePath\n );\n }\n\n // Validate file extension\n const hasValidExtension = this.ALLOWED_EXTENSIONS.some((ext) =>\n normalizedPath.toLowerCase().endsWith(ext)\n );\n\n if (!hasValidExtension) {\n throw new ThemeFileError(\n `Invalid file extension. Allowed: ${this.ALLOWED_EXTENSIONS.join(', ')}`,\n filePath\n );\n }\n\n // Additional security: ensure path is reasonable length\n if (normalizedPath.length > 1000) {\n throw new ThemeFileError('File path is too long', filePath);\n }\n }\n\n private async readFileWithLimits(filePath: string): Promise<string> {\n try {\n // Get file stats to check size before reading\n const stats = await fs.stat(filePath);\n\n // Check if it's actually a file\n if (!stats.isFile()) {\n throw new ThemeFileError('Path is not a regular file', filePath);\n }\n\n // Check file size limits\n if (stats.size > this.MAX_FILE_SIZE) {\n throw new ThemeFileError(\n `File too large (${stats.size} bytes, max ${this.MAX_FILE_SIZE} bytes)`,\n filePath\n );\n }\n\n // Check for empty file\n if (stats.size === 0) {\n throw new ThemeFileError('File is empty', filePath);\n }\n\n // Read file with proper encoding\n const content = await fs.readFile(filePath, 'utf8');\n\n // Verify content was read properly\n if (typeof content !== 'string') {\n throw new ThemeFileError('Failed to read file as text', filePath);\n }\n\n return content;\n } catch (error) {\n if (error instanceof ThemeFileError) {\n throw error;\n }\n\n // Re-throw as ThemeFileError for consistent error handling\n throw new ThemeFileError(\n `Failed to read file: ${error instanceof Error ? error.message : String(error)}`,\n filePath,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n // Utility method to validate a file path without reading\n validateFile(filePath: string): { valid: boolean; error?: string } {\n try {\n this.validateFilePath(filePath);\n return { valid: true };\n } catch (error) {\n return {\n valid: false,\n error:\n error instanceof Error ? error.message : 'Unknown validation error',\n };\n }\n }\n\n // Utility method to get file info\n async getFileInfo(filePath: string): Promise<{\n exists: boolean;\n size?: number;\n isFile?: boolean;\n error?: string;\n }> {\n try {\n const stats = await fs.stat(filePath);\n return {\n exists: true,\n size: stats.size,\n isFile: stats.isFile(),\n };\n } catch (error) {\n return {\n exists: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n}\n","// Public API exports for JSON theme system\nexport {\n ThemeConfigSchema,\n type ThemeConfigJson,\n isValidThemeConfig,\n /**\n * Create a minimal theme template for users to start with.\n * Defined in shared-docx next to `ThemeConfigSchema` so every consumer\n * (CLI, playground) scaffolds from one schema-checked source.\n */\n createMinimalTheme,\n} from '@json-to-office/shared-docx';\nexport { ThemeParser, ThemeValidationError, ThemeParseError } from './parser';\nexport {\n validateThemeJson,\n formatValidationErrors,\n type ValidationResult,\n} from './validator';\nexport { ThemeLoader, ThemeFileError } from './loader';\n\n// Main API functions - Core public interface for JSON theme system\nimport type { ThemeConfigJson } from '@json-to-office/shared-docx';\nimport { ThemeParser } from './parser';\nimport { ThemeLoader } from './loader';\n\n// Global instances for consistent behavior\nconst themeParser = new ThemeParser();\nconst themeLoader = new ThemeLoader();\n\n/**\n * Load and parse a theme from a JSON string\n * @param jsonString - JSON string containing theme definition\n * @returns Promise<ThemeConfig> - Parsed and validated theme configuration\n * @throws ThemeParseError - If JSON is malformed or invalid\n * @throws ThemeValidationError - If theme fails schema validation\n */\nexport async function loadThemeFromJson(\n jsonString: string\n): Promise<ThemeConfigJson> {\n return themeParser.parse(jsonString);\n}\n\n/**\n * Load and parse a theme from a JSON file\n * @param filePath - Path to JSON file containing theme definition\n * @returns Promise<ThemeConfig> - Parsed and validated theme configuration\n * @throws ThemeFileError - If file cannot be read or path is invalid\n * @throws ThemeParseError - If JSON is malformed or invalid\n * @throws ThemeValidationError - If theme fails schema validation\n */\nexport async function loadThemeFromFile(\n filePath: string\n): Promise<ThemeConfigJson> {\n return themeLoader.loadFromFile(filePath);\n}\n\n/**\n * Export a theme configuration to JSON string\n * @param theme - Theme configuration to export\n * @param pretty - Whether to format JSON with indentation (default: true)\n * @returns string - Formatted JSON string\n */\nexport function exportThemeToJson(\n theme: ThemeConfigJson,\n pretty: boolean = true\n): string {\n try {\n // Since ThemeConfig is inferred from TypeBox schema, it can be directly serialized\n // The schema ensures all properties are JSON-serializable\n\n if (pretty) {\n return JSON.stringify(theme, null, 2);\n } else {\n return JSON.stringify(theme);\n }\n } catch (error) {\n throw new Error(\n `Failed to export theme to JSON: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Validate a JSON string against the theme schema without parsing\n * @param jsonString - JSON string to validate\n * @returns Validation result with success status and detailed errors\n */\nexport function validateThemeJsonString(jsonString: string) {\n return themeParser.validate(jsonString);\n}\n","/**\n * Main styles module export\n * This file provides a unified interface to the styles system\n */\n\n// Base configurations - imported from TypeBox schemas\nexport type {\n ThemeConfigJson as ThemeConfig,\n StyleDefinitions,\n DocumentMargins,\n PageDimensions,\n Page,\n FontDefinition,\n Fonts,\n ComponentDefaults,\n HeadingComponentDefaults,\n ParagraphComponentDefaults,\n ImageComponentDefaults,\n StatisticComponentDefaults,\n TableComponentDefaults,\n SectionComponentDefaults,\n ColumnsComponentDefaults,\n ListComponentDefaults,\n} from '@json-to-office/shared-docx';\nexport {\n themes,\n getTheme,\n getThemeNames,\n getThemeWithFallback,\n hasTheme,\n isValidThemeName,\n} from '../templates/themes';\n\n// Export ThemeName type separately\nexport type { ThemeName } from '../templates/themes';\n\n// Style utilities\nexport { getBodyTextStyle } from './utils/styleHelpers';\nexport {\n getTableStyle,\n getDocumentMargins,\n getPageSetup,\n} from './utils/layoutUtils';\n\n// Theme configurations\nexport {\n minimalTheme,\n corporateTheme,\n modernTheme,\n} from '../templates/themes';\n\n// JSON Theme System (Phase 1 - Foundation complete)\nexport {\n ThemeConfigSchema,\n isValidThemeConfig,\n loadThemeFromJson,\n loadThemeFromFile,\n exportThemeToJson,\n validateThemeJsonString,\n ThemeValidationError,\n ThemeParseError,\n ThemeFileError,\n} from '../themes/json';\n\n// Export type separately\nexport type { ThemeConfigJson } from '../themes/json';\n\n// All themes now use the same structure\n// No need for backward compatibility exports\n","import { ThemeConfig } from '../styles';\nimport { getPageSetup } from '../styles';\nimport { pointsToTwips } from '../styles/utils/styleHelpers';\n\n/**\n * Compute available page width in twips (page width minus left/right margins)\n */\nexport function getAvailableWidthTwips(\n theme?: ThemeConfig,\n themeName?: string\n): number {\n const page = getPageSetup(theme, themeName);\n const width = page?.size?.width || 0;\n const left = page?.margin?.left || 0;\n const right = page?.margin?.right || 0;\n return Math.max(0, width - left - right);\n}\n\n/**\n * Compute full page width in twips (ignores margins)\n */\nexport function getPageWidthTwips(\n theme?: ThemeConfig,\n themeName?: string\n): number {\n const page = getPageSetup(theme, themeName);\n return page?.size?.width || 0;\n}\n\n/**\n * Compute available page height in twips (page height minus top/bottom margins)\n */\nexport function getAvailableHeightTwips(\n theme?: ThemeConfig,\n themeName?: string\n): number {\n const page = getPageSetup(theme, themeName);\n const height = page?.size?.height || 0;\n const top = page?.margin?.top || 0;\n const bottom = page?.margin?.bottom || 0;\n return Math.max(0, height - top - bottom);\n}\n\n/**\n * Compute full page height in twips (ignores margins)\n */\nexport function getPageHeightTwips(\n theme?: ThemeConfig,\n themeName?: string\n): number {\n const page = getPageSetup(theme, themeName);\n return page?.size?.height || 0;\n}\n\n/**\n * Parse a percentage string like \"75%\" into a fraction 0..1\n */\nexport function parsePercentageStringToFraction(\n value: string\n): number | undefined {\n const match = /^([0-9]+(?:\\.[0-9]+)?)%$/.exec(value);\n if (!match) return undefined;\n const pct = parseFloat(match[1]);\n if (pct < 0 || pct > 100) return undefined;\n return pct / 100;\n}\n\n/**\n * Resolve an offset value (twips or percentage string) to twips.\n * Numbers pass through unchanged; percentage strings are resolved against referenceTwips.\n */\nexport function resolveOffsetTwips(\n value: number | string,\n referenceTwips: number\n): number {\n if (typeof value === 'number') return value;\n const match = /^([0-9]+(?:\\.[0-9]+)?)%$/.exec(value);\n if (!match) {\n console.warn(\n `resolveOffsetTwips: invalid percentage string \"${value}\", defaulting to 0`\n );\n return 0;\n }\n return Math.round((referenceTwips * parseFloat(match[1])) / 100);\n}\n\n/**\n * Convert a numeric (points) or percentage string to twips using available width\n */\nexport function relativeLengthToTwips(\n value: number | string,\n availableWidthTwips: number\n): number {\n if (typeof value === 'number') {\n return pointsToTwips(value);\n }\n const fraction = parsePercentageStringToFraction(value);\n if (fraction === undefined) return 0;\n return Math.round(availableWidthTwips * fraction);\n}\n","import {\n TextWrappingType,\n TextWrappingSide,\n HorizontalPositionRelativeFrom,\n VerticalPositionRelativeFrom,\n HorizontalPositionAlign,\n VerticalPositionAlign,\n} from 'docx';\n\nimport type { ImageProps } from '../types';\nimport type { ThemeConfig } from '../styles';\nimport {\n resolveOffsetTwips,\n getPageWidthTwips,\n getPageHeightTwips,\n getAvailableWidthTwips,\n getAvailableHeightTwips,\n} from './widthUtils';\n\nexport type FloatingConfig = NonNullable<ImageProps['floating']>;\n\n/**\n * Conversion factor from twips to EMUs (English Metric Units).\n * - 1 inch = 914,400 EMUs\n * - 1 inch = 1,440 twips\n * - Therefore: 1 twip = 914,400 / 1,440 = 635 EMUs\n *\n * docx.js expects offset and margin values in EMUs, but our schema\n * documents these values in twips for consistency with other Word measurements.\n */\nconst TWIPS_TO_EMU = 635;\n\nexport function mapHorizontalRelative(\n rel?: FloatingConfig['horizontalPosition'] extends infer T\n ? T extends { relative?: infer R }\n ? R\n : never\n : never\n) {\n switch (rel) {\n case 'character':\n return HorizontalPositionRelativeFrom.CHARACTER;\n case 'column':\n return HorizontalPositionRelativeFrom.COLUMN;\n case 'margin':\n return HorizontalPositionRelativeFrom.MARGIN;\n case 'page':\n return HorizontalPositionRelativeFrom.PAGE;\n default:\n return undefined;\n }\n}\n\nexport function mapVerticalRelative(\n rel?: FloatingConfig['verticalPosition'] extends infer T\n ? T extends { relative?: infer R }\n ? R\n : never\n : never\n) {\n switch (rel) {\n case 'margin':\n return VerticalPositionRelativeFrom.MARGIN;\n case 'page':\n return VerticalPositionRelativeFrom.PAGE;\n case 'paragraph':\n return VerticalPositionRelativeFrom.PARAGRAPH;\n case 'line':\n return VerticalPositionRelativeFrom.LINE;\n default:\n return undefined;\n }\n}\n\nexport function mapHorizontalAlign(\n align?: 'left' | 'center' | 'right' | 'inside' | 'outside'\n) {\n switch (align) {\n case 'left':\n return HorizontalPositionAlign.LEFT;\n case 'center':\n return HorizontalPositionAlign.CENTER;\n case 'right':\n return HorizontalPositionAlign.RIGHT;\n case 'inside':\n return HorizontalPositionAlign.INSIDE;\n case 'outside':\n return HorizontalPositionAlign.OUTSIDE;\n default:\n return undefined;\n }\n}\n\nexport function mapVerticalAlign(\n align?: 'top' | 'center' | 'bottom' | 'inside' | 'outside'\n) {\n switch (align) {\n case 'top':\n return VerticalPositionAlign.TOP;\n case 'center':\n return VerticalPositionAlign.CENTER;\n case 'bottom':\n return VerticalPositionAlign.BOTTOM;\n case 'inside':\n return VerticalPositionAlign.INSIDE;\n case 'outside':\n return VerticalPositionAlign.OUTSIDE;\n default:\n return undefined;\n }\n}\n\nexport function mapWrapType(\n type?: 'none' | 'square' | 'topAndBottom' | 'around' | 'through'\n) {\n switch (type) {\n case 'none':\n return TextWrappingType.NONE;\n case 'square':\n return TextWrappingType.SQUARE;\n case 'topAndBottom':\n return TextWrappingType.TOP_AND_BOTTOM;\n case 'around':\n case 'through':\n // Map VML-style 'around' and 'through' to TIGHT (closest OOXML equivalent)\n return TextWrappingType.TIGHT;\n default:\n return undefined;\n }\n}\n\nexport function mapWrapSide(side?: 'bothSides' | 'left' | 'right' | 'largest') {\n switch (side) {\n case 'bothSides':\n return TextWrappingSide.BOTH_SIDES;\n case 'left':\n return TextWrappingSide.LEFT;\n case 'right':\n return TextWrappingSide.RIGHT;\n case 'largest':\n return TextWrappingSide.LARGEST;\n default:\n return undefined;\n }\n}\n\n/**\n * Map shared floating config to docx ImageRun floating options.\n * Also lifts wrap.margins (if present) to floating.margins as expected by docx.\n */\nexport function mapFloatingOptions(\n floating?: FloatingConfig,\n theme?: ThemeConfig,\n themeName?: string\n): any | undefined {\n if (!floating) return undefined;\n\n // Disallow 'tight' wrapping: docx emits invalid OOXML for wrapTight without polygon geometry\n // Note: TypeScript correctly prevents this at compile-time, but keep for runtime safety\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - Intentional defensive check for runtime input validation\n if (floating.wrap?.type === 'tight') {\n throw new Error(\n \"Image floating wrap.type 'tight' is not supported due to invalid OOXML emitted by docx. Use 'square', 'topAndBottom', or 'none'.\"\n );\n }\n\n // Determine reference dimensions for percentage resolution\n const hRelative = floating.horizontalPosition?.relative;\n const vRelative = floating.verticalPosition?.relative;\n const hRef =\n hRelative && hRelative !== 'page'\n ? getAvailableWidthTwips(theme, themeName)\n : getPageWidthTwips(theme, themeName);\n const vRef =\n vRelative && vRelative !== 'page'\n ? getAvailableHeightTwips(theme, themeName)\n : getPageHeightTwips(theme, themeName);\n\n // docx.js requires BOTH horizontal and vertical positions for floating images.\n // If only one is specified, provide sensible defaults for the other.\n const hasHorizontal = Boolean(floating.horizontalPosition);\n const hasVertical = Boolean(floating.verticalPosition);\n\n const horizontalPosition = floating.horizontalPosition\n ? {\n ...(floating.horizontalPosition.relative && {\n relative: mapHorizontalRelative(floating.horizontalPosition.relative),\n }),\n ...(floating.horizontalPosition.align !== undefined && {\n align: mapHorizontalAlign(floating.horizontalPosition.align),\n }),\n ...(floating.horizontalPosition.offset !== undefined && {\n offset:\n resolveOffsetTwips(floating.horizontalPosition.offset, hRef) *\n TWIPS_TO_EMU,\n }),\n }\n : hasVertical\n ? {\n // Default horizontal: align left relative to margin\n relative: HorizontalPositionRelativeFrom.MARGIN,\n align: HorizontalPositionAlign.LEFT,\n }\n : undefined;\n\n const verticalPosition = floating.verticalPosition\n ? {\n ...(floating.verticalPosition.relative && {\n relative: mapVerticalRelative(floating.verticalPosition.relative),\n }),\n ...(floating.verticalPosition.align !== undefined && {\n align: mapVerticalAlign(floating.verticalPosition.align),\n }),\n ...(floating.verticalPosition.offset !== undefined && {\n offset:\n resolveOffsetTwips(floating.verticalPosition.offset, vRef) *\n TWIPS_TO_EMU,\n }),\n }\n : hasHorizontal\n ? {\n // Default vertical: align top relative to paragraph\n relative: VerticalPositionRelativeFrom.PARAGRAPH,\n align: VerticalPositionAlign.TOP,\n }\n : undefined;\n\n const wrap = floating.wrap\n ? {\n ...(floating.wrap.type && { type: mapWrapType(floating.wrap.type) }),\n ...(floating.wrap.side && { side: mapWrapSide(floating.wrap.side) }),\n }\n : undefined;\n\n // Convert margins from twips (or percentage) to EMUs\n const pageW = getPageWidthTwips(theme, themeName);\n const pageH = getPageHeightTwips(theme, themeName);\n const rawMargins = floating.wrap?.margins || (floating as any).margins;\n const margins = rawMargins\n ? {\n ...(rawMargins.top !== undefined && {\n top: resolveOffsetTwips(rawMargins.top, pageH) * TWIPS_TO_EMU,\n }),\n ...(rawMargins.bottom !== undefined && {\n bottom: resolveOffsetTwips(rawMargins.bottom, pageH) * TWIPS_TO_EMU,\n }),\n ...(rawMargins.left !== undefined && {\n left: resolveOffsetTwips(rawMargins.left, pageW) * TWIPS_TO_EMU,\n }),\n ...(rawMargins.right !== undefined && {\n right: resolveOffsetTwips(rawMargins.right, pageW) * TWIPS_TO_EMU,\n }),\n }\n : undefined;\n\n // Determine and validate zIndex:\n // - OOXML requires positive integer for relativeHeight\n // - Negative values cause Word to reject the document\n // - CRITICAL: docx.js uses image HEIGHT as relativeHeight when zIndex is undefined,\n // causing inconsistent values that can corrupt documents\n // - Solution: ALWAYS provide a zIndex value, defaulting to 0\n let zIndex = floating.zIndex !== undefined ? floating.zIndex : 0; // Default to 0 for ALL floating images (behindDocument or normal)\n\n // Validate: zIndex must be >= 0 (OOXML requirement)\n if (zIndex < 0) {\n console.warn(\n `Invalid zIndex value ${zIndex} for floating image. Using 0 instead. zIndex must be >= 0.`\n );\n zIndex = 0;\n }\n\n const mapped: any = {\n ...(horizontalPosition && { horizontalPosition }),\n ...(verticalPosition && { verticalPosition }),\n ...(wrap && { wrap }),\n ...(margins && { margins }),\n ...(floating.allowOverlap !== undefined && {\n allowOverlap: floating.allowOverlap,\n }),\n ...(floating.behindDocument !== undefined && {\n behindDocument: floating.behindDocument,\n }),\n ...(floating.lockAnchor !== undefined && {\n lockAnchor: floating.lockAnchor,\n }),\n ...(floating.layoutInCell !== undefined && {\n layoutInCell: floating.layoutInCell,\n }),\n zIndex, // Always include zIndex (now always defined, defaults to 0)\n };\n\n return Object.keys(mapped).length ? mapped : undefined;\n}\n","/**\n * Document Generator\n * Main orchestration functions that compose the document generation pipeline\n */\n\nimport { Document } from 'docx';\nimport { writeFileSync } from 'fs';\nimport { dirname, resolve } from 'path';\nimport {\n ComponentDefinition,\n ReportProps,\n ReportComponentDefinition,\n isReportComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { resolveThemeContext } from './generationContext';\nimport type { ServicesConfig, FontRuntimeOpts } from '@json-to-office/shared';\nimport { processDocument } from './structure';\nimport { applyLayout } from './layout';\nimport { renderDocument } from './render';\nimport { resolveDocumentFonts } from './fontResolution';\nimport {\n packageDocument,\n resolveGenerationDate,\n} from '../utils/packageDocument';\n\n// JSON support imports\nimport { DocumentValidationResult } from '@json-to-office/shared-docx';\nimport type { GenerationWarning } from '@json-to-office/shared';\nimport {\n validateJsonComponent,\n JsonParsingError,\n JsonValidationError,\n} from '../json/parser';\nimport { normalizeDocument } from '../json/normalizer';\nimport { loadJsonDefinition } from '../json/filesystem';\n\n// Local generation options type\nexport interface JsonGenerationOptions {\n outputPath?: string;\n validation?: {\n /**\n * Validate the document against the schema before building, throwing on\n * errors. Defaults to `true` — invalid props are surfaced rather than\n * silently dropped into a corrupt/incomplete document.\n */\n enabled?: boolean;\n /**\n * When true, unknown/extra properties are stripped instead of rejected by\n * strict (additionalProperties:false) schemas. Escape hatch for migration.\n */\n allowUnknownFields?: boolean;\n /** @deprecated No longer consulted; retained for back-compat. */\n strict?: boolean;\n };\n customThemes?: { [key: string]: ThemeConfig };\n services?: ServicesConfig;\n fonts?: FontRuntimeOpts;\n /**\n * Optional collector for structured warnings (font resolution, etc.).\n * When provided, mirrors the plugin path's warning semantics; when absent,\n * warnings fall back to `console.warn` as before.\n */\n warnings?: GenerationWarning[];\n /** Normalize volatile OOXML values for byte-identical output. Defaults true. */\n deterministic?: boolean;\n /** Build timestamp for metadata; defaults to a stable epoch. */\n generatedAt?: string | Date;\n /**\n * Directory that relative asset paths (image `path` props) resolve against.\n * File entry points default it to the document's own directory; elsewhere\n * it falls back to `process.cwd()` (#142).\n */\n baseDir?: string;\n}\n\n// Font resolution shared with the plugin path — see ./fontResolution.ts\n\n/**\n * Type guard to check if input is a report component definition\n */\nexport function isReportComponentDefinition(\n definition: unknown\n): definition is ReportComponentDefinition {\n if (typeof definition !== 'object' || definition === null) {\n return false;\n }\n\n const def = definition as Record<string, unknown>;\n\n // Must be a report component (optionally with $schema for JSON validation).\n // `props` is optional: a propless root generates like one with `props: {}`.\n return def.name === 'docx';\n}\n\n/**\n * Generate a Word document from a report component definition\n * This is the main entry point for document generation\n */\nexport async function generateDocument(\n document: ReportComponentDefinition,\n options?: JsonGenerationOptions\n): Promise<Document> {\n // Validate that the document is a report component\n if (!document || document.name !== 'docx') {\n throw new Error('Top-level component must be a docx component');\n }\n\n // Handle JSON definitions (report components with $schema)\n if ('$schema' in document) {\n return await generateDocumentFromJson(document, options);\n }\n\n // Route through the font-aware pipeline so `options.fonts` (mode,\n // substitution, onResolved, strict) is honoured identically to the JSON\n // entry point. Previously this branch bypassed export-mode + font\n // resolution, silently ignoring `fonts.mode: 'substitute'`.\n return await generateDocumentWithCustomThemes(\n document,\n options?.customThemes,\n options?.services,\n options?.fonts,\n options?.warnings,\n resolveGenerationDate(options),\n options?.baseDir\n );\n}\n\n/**\n * Generate document from report props and components\n * Convenience function that constructs the report component\n */\nexport async function generateFromConfig(\n props: ReportProps,\n components: ComponentDefinition[],\n options?: JsonGenerationOptions\n): Promise<Document> {\n const reportComponent: ReportComponentDefinition = {\n name: 'docx',\n props,\n children: components,\n };\n\n return await generateDocument(reportComponent, options);\n}\n\n/**\n * Generate a Word document with custom themes support\n * Extends the standard pipeline to support custom theme resolution\n */\nasync function generateDocumentWithCustomThemes(\n documentIn: ReportComponentDefinition,\n customThemes?: { [key: string]: ThemeConfig },\n services?: ServicesConfig,\n fonts?: FontRuntimeOpts,\n warnings?: GenerationWarning[],\n generationDate?: Date,\n baseDir?: string\n): Promise<Document> {\n // Props defaulting, theme resolution, in-document overrides, export-mode\n // pre-pass and cache-key scoping — shared with the plugin pipeline so the\n // two cannot drift (see core/generationContext.ts).\n const { document, theme, themeName } = resolveThemeContext(documentIn, {\n customThemes,\n fonts,\n warnings,\n });\n\n // Resolve fonts for the LibreOffice preview stager (side-channel).\n // resolveDocumentFonts fires `fonts.onResolved` internally when a\n // listener is registered. The final DOCX never embeds bytes.\n await resolveDocumentFonts(document, theme, fonts, warnings);\n\n // Pipeline: Structure -> Layout -> Render (with caching)\n const structure = await processDocument(\n document,\n theme,\n themeName,\n generationDate\n );\n const layout = applyLayout(structure.sections, theme, themeName);\n const renderedDocument = await renderDocument(structure, layout, {\n bypassCache: false,\n services,\n baseDir,\n });\n\n return renderedDocument;\n}\n\n/**\n * Generate a Word document from JSON report definition\n * Handles parsing, validation, and conversion to internal components\n */\nexport async function generateDocumentFromJson(\n jsonConfig: string | ComponentDefinition | ReportComponentDefinition,\n options?: JsonGenerationOptions\n): Promise<Document> {\n // Validate before building unless the caller opted out. This runs the same\n // plugin-unaware validator the public playground uses, so the object/buffer\n // entry point is as strict as the playground — malformed props throw instead\n // of being silently dropped into the document.\n const validation = options?.validation;\n if (validation?.enabled !== false) {\n const result = validateJsonComponent(jsonConfig, {\n allowUnknownFields: validation?.allowUnknownFields,\n });\n if (!result.valid) {\n throw new JsonValidationError(\n 'Document validation failed',\n result.errors\n );\n }\n }\n\n // Resolve to an object for the build pipeline.\n let componentToConvert: ComponentDefinition | ReportComponentDefinition;\n if (typeof jsonConfig === 'string') {\n let parsed: ComponentDefinition;\n try {\n parsed = JSON.parse(jsonConfig) as ComponentDefinition;\n } catch (error) {\n throw new JsonParsingError('Invalid JSON syntax', [\n {\n path: '',\n message: error instanceof Error ? error.message : 'Invalid JSON',\n code: 'JSON_PARSE_ERROR',\n },\n ]);\n }\n if (!isReportComponent(parsed)) {\n throw new Error('Parsed JSON must be a docx component');\n }\n componentToConvert = parsed as ReportComponentDefinition;\n } else {\n // Could be either ComponentDefinition (from JSON) or ReportComponentDefinition (internal)\n componentToConvert = jsonConfig;\n }\n\n // Normalize JSON components (handle shorthand notations and nested structures)\n // The normalizer preserves all validated properties from TypeBox\n const [reportComponent] = normalizeDocument(componentToConvert);\n\n // Generate document using custom theme-aware pipeline.\n // Font registry lives on the theme, so resolution happens inside the\n // pipeline (after theme selection).\n return await generateDocumentWithCustomThemes(\n reportComponent,\n options?.customThemes,\n options?.services,\n options?.fonts,\n options?.warnings,\n resolveGenerationDate(options),\n options?.baseDir\n );\n}\n\n/**\n * Validate JSON schema without generating document\n */\nexport function validateJsonSchema(\n jsonConfig: string | object\n): DocumentValidationResult {\n return validateJsonComponent(jsonConfig);\n}\n\n/**\n * Generate document buffer from JSON (commonly used for API responses)\n */\nexport async function generateBufferFromJson(\n jsonConfig: string | ReportComponentDefinition,\n options?: JsonGenerationOptions\n): Promise<Buffer> {\n const document = await generateDocumentFromJson(jsonConfig, options);\n return packageDocument(document, options);\n}\n\n/**\n * Generate and save document from JSON in one operation\n */\nexport async function generateAndSaveFromJson(\n jsonConfig: string | ReportComponentDefinition,\n filename: string,\n options?: JsonGenerationOptions\n): Promise<void> {\n const document = await generateDocumentFromJson(jsonConfig, options);\n await saveDocument(document, filename, options);\n}\n\n/**\n * Generate document from JSON file\n */\nexport async function generateDocumentFromFile(\n filePath: string,\n options?: JsonGenerationOptions\n): Promise<Document> {\n const jsonDefinition = await loadJsonDefinition(filePath);\n // loadJsonDefinition returns ComponentDefinition from shared (JSON schema type)\n // generateDocumentFromJson now accepts the JSON schema type directly\n // The document's own directory is the natural base for its relative assets.\n return await generateDocumentFromJson(jsonDefinition, {\n baseDir: dirname(resolve(filePath)),\n ...options,\n });\n}\n\n/**\n * Generate document buffer from JSON file\n */\nexport async function generateBufferFromFile(\n filePath: string,\n options?: JsonGenerationOptions\n): Promise<Buffer> {\n const document = await generateDocumentFromFile(filePath, options);\n return packageDocument(document, options);\n}\n\n/**\n * Generate and save document from JSON file in one operation\n */\nexport async function generateAndSaveFromFile(\n inputFilePath: string,\n outputFilePath: string,\n options?: JsonGenerationOptions\n): Promise<void> {\n const document = await generateDocumentFromFile(inputFilePath, options);\n await saveDocument(document, outputFilePath, options);\n}\n\n/**\n * Save a document to file\n */\nexport async function saveDocument(\n document: Document,\n filename: string,\n options?: JsonGenerationOptions\n): Promise<void> {\n const buffer = await packageDocument(document, options);\n writeFileSync(filename, buffer);\n}\n\n/**\n * Generate and save document in one operation\n */\nexport async function generateAndSave(\n document: ReportComponentDefinition,\n filename: string,\n options?: JsonGenerationOptions\n): Promise<void> {\n const generatedDocument = await generateDocument(document, options);\n await saveDocument(generatedDocument, filename, options);\n}\n\n/**\n * Compose multiple transform functions\n * Utility for creating custom pipelines\n */\nexport function pipe<T>(...fns: Array<(_arg: T) => T>): (_arg: T) => T {\n return (_arg: T) => fns.reduce((acc, fn) => fn(acc), _arg);\n}\n\n/**\n * Export the main API\n */\nexport const DocumentGenerator = {\n generate: generateDocument,\n generateFromConfig,\n generateFromJson: generateDocumentFromJson,\n generateFromFile: generateDocumentFromFile,\n generateBufferFromJson,\n generateBufferFromFile,\n generateAndSaveFromJson,\n generateAndSaveFromFile,\n validateJsonSchema,\n save: saveDocument,\n generateAndSave,\n isReportComponentDefinition,\n};\n","import { ISectionOptions } from 'docx';\nimport type { ThemeName } from '../styles';\nimport type { ServicesConfig } from '@json-to-office/shared';\n\n// Import types from shared-docx that core needs for its internal use\nimport type {\n ComponentDefinition as SharedComponentDefinition,\n ReportComponent,\n SectionComponent,\n ColumnsComponent,\n HeadingComponent,\n ParagraphComponent,\n ImageComponent,\n HighchartsComponent,\n VisualComponent,\n StatisticComponent,\n TableComponent,\n ListComponent,\n TocComponent,\n TextBoxComponent,\n\n // Import props types needed internally\n ReportProps as SharedReportProps,\n SectionProps as SharedSectionProps,\n HeadingProps as SharedHeadingProps,\n ParagraphProps as SharedParagraphProps,\n ColumnsProps as SharedColumnsProps,\n ImageProps as SharedImageProps,\n VisualProps as SharedVisualProps,\n StatisticProps as SharedStatisticProps,\n TableProps as SharedTableProps,\n ListProps as SharedListProps,\n TocProps as SharedTocProps,\n TextBoxProps as SharedTextBoxProps,\n} from '@json-to-office/shared-docx';\n\n// Import type guards from shared-docx (these are runtime functions core needs)\nexport {\n isReportComponent,\n isSectionComponent,\n isHeadingComponent,\n isParagraphComponent,\n isColumnsComponent,\n isImageComponent,\n isTextBoxComponent,\n isStatisticComponent,\n isTableComponent,\n isListComponent,\n isTocComponent,\n isHighchartsComponent,\n isVisualComponent,\n} from '@json-to-office/shared-docx';\n\n// Re-export component definitions for internal use (type aliases for clarity)\nexport type ComponentDefinition = SharedComponentDefinition;\nexport type ReportComponentDefinition = ReportComponent & {\n /** Optional schema field for JSON validation */\n $schema?: string;\n};\nexport type SectionComponentDefinition = SectionComponent;\nexport type HeadingComponentDefinition = HeadingComponent;\nexport type ParagraphComponentDefinition = ParagraphComponent;\nexport type ColumnsComponentDefinition = ColumnsComponent;\nexport type ImageComponentDefinition = ImageComponent;\nexport type VisualComponentDefinition = VisualComponent;\nexport type TextBoxComponentDefinition = TextBoxComponent;\nexport type StatisticComponentDefinition = StatisticComponent;\nexport type TableComponentDefinition = TableComponent;\nexport type ListComponentDefinition = ListComponent;\nexport type TocComponentDefinition = TocComponent;\n\n// Export StandardComponentDefinition as union of all standard component types\nexport type StandardComponentDefinition =\n | ReportComponent\n | SectionComponent\n | ColumnsComponent\n | HeadingComponent\n | ParagraphComponent\n | TextBoxComponent\n | ImageComponent\n | HighchartsComponent\n | VisualComponent\n | StatisticComponent\n | TableComponent\n | ListComponent\n | TocComponent;\n\n// Re-export props types for internal use\nexport type ReportProps = SharedReportProps;\nexport type SectionProps = SharedSectionProps;\nexport type HeadingProps = SharedHeadingProps;\nexport type ParagraphProps = SharedParagraphProps;\nexport type ColumnsProps = SharedColumnsProps;\nexport type ImageProps = SharedImageProps;\nexport type VisualProps = SharedVisualProps;\nexport type TextBoxProps = SharedTextBoxProps;\nexport type StatisticProps = SharedStatisticProps;\nexport type TableProps = SharedTableProps;\nexport type ListProps = SharedListProps;\nexport type TocProps = SharedTocProps;\n\n// Re-export ThemeName for easier access\nexport type { ThemeName };\n\n// ============================================================================\n// CORE-SPECIFIC INTERFACES\n// ============================================================================\n\nexport interface ColumnSettings {\n count: number;\n equalWidth?: boolean;\n space?: number;\n /** Optional explicit column children with widths/spaces in twips */\n children?: { width?: number; space?: number }[];\n}\n\nexport interface PageSizeOptions {\n width: number;\n height: number;\n}\n\nexport interface PageMarginOptions {\n top: number;\n right: number;\n bottom: number;\n left: number;\n header?: number;\n footer?: number;\n}\n\nexport interface PageNumberOptions {\n start?: number;\n formatType?:\n | 'decimal'\n | 'upperRoman'\n | 'lowerRoman'\n | 'upperLetter'\n | 'lowerLetter';\n}\n\nexport interface PageBorderOptions {\n top?: { style: string; size: number; color: string };\n right?: { style: string; size: number; color: string };\n bottom?: { style: string; size: number; color: string };\n left?: { style: string; size: number; color: string };\n}\n\nexport interface SectionProperties {\n page?: {\n size?: PageSizeOptions;\n margin?: PageMarginOptions;\n pageNumbers?: PageNumberOptions;\n borders?: PageBorderOptions;\n textDirection?: 'ltr' | 'rtl';\n };\n column?: ColumnSettings;\n type?: 'continuous' | 'nextColumn' | 'nextPage' | 'evenPage' | 'oddPage';\n headers?: ISectionOptions['headers'];\n footers?: ISectionOptions['footers'];\n}\n\n// Internal interfaces used by DocumentGenerator helper methods\nexport interface ImageContent {\n path: string;\n caption?: string;\n width?: number;\n height?: number;\n alignment?: 'left' | 'center' | 'right';\n}\n\nexport interface StatisticContent {\n number: string;\n description: string;\n alignment?: 'left' | 'center' | 'right';\n}\n\nexport interface TableData {\n headers: string[];\n rows: (string | SharedComponentDefinition)[][];\n style?: 'minimal' | 'classic' | 'minimal';\n}\n\n/**\n * Rendering context for components\n */\nexport interface RenderContext {\n theme: {\n name: string;\n colors: Record<string, string>;\n fonts: Record<string, string>;\n spacing: Record<string, number>;\n };\n /** Full theme configuration for custom components */\n fullTheme: import('../styles').ThemeConfig;\n document: {\n title?: string;\n subtitle?: string;\n author?: string;\n company?: string;\n date: Date;\n };\n section: {\n currentLayout: 'single' | 'multi-column';\n columnCount: number;\n pageNumber: number;\n level?: number;\n /** Bookmark ID for section-scoped TOCs (when TOC is inside a section) */\n sectionBookmarkId?: string;\n /** Heading level of the parent section title (used to exclude it from section-scoped TOCs) */\n sectionTitleLevel?: number;\n };\n utils: {\n formatDate: (_date: Date) => string;\n parseText: (_text: string) => { text: string }[];\n getStyle: (_name: string) => { name: string };\n [key: string]: unknown;\n };\n parent?: SharedComponentDefinition;\n depth: number;\n custom?: Record<string, unknown>;\n services?: ServicesConfig;\n}\n","/**\n * Shared generation prologue.\n *\n * Both entry points — `generateBufferFromJson` (core) and\n * `createDocumentGenerator` (plugin) — must resolve the same theme, apply the\n * same in-document overrides, and derive the same cache key before the\n * structure → layout → render engine runs. Keeping two copies of that meant\n * `props.themeOverrides` reached only one of them (#133); this module is the\n * single definition so the next root-level prop cannot diverge (#132).\n *\n * The prologue deliberately stops before font resolution: the core path\n * resolves fonts straight after this, while the plugin path must first expand\n * custom components (which can introduce new families).\n */\n\nimport type { ReportComponentDefinition } from '../types';\nimport type { ThemeConfig } from '../styles';\nimport type {\n FontRuntimeOpts,\n GenerationWarning,\n} from '@json-to-office/shared';\nimport { applyExportMode, scopedThemeName } from '@json-to-office/shared';\nimport { resolveBuiltInTheme } from '../styles/theme-resolver';\nimport { applyThemeOverrides, themeOverridesDigest } from '../themes/overrides';\n\nexport interface ThemeContextOptions {\n customThemes?: { [key: string]: ThemeConfig };\n fonts?: FontRuntimeOpts;\n warnings?: GenerationWarning[];\n /**\n * Theme lookup for the base `props.theme` name. The plugin builder passes\n * its own (customThemes → doc-named built-in → constructor-supplied theme →\n * built-in); omit it to use customThemes → built-in. `authored` is true when\n * the name came from the document's own `props.theme` (not the 'minimal'\n * fallback), so the lookup can honor an explicitly doc-named built-in\n * without the constructor theme being shadowed for unnamed docs (#141).\n */\n resolveNamedTheme?: (\n name: string,\n warnings: GenerationWarning[] | undefined,\n authored: boolean\n ) => ThemeConfig;\n}\n\nexport interface GenerationThemeContext {\n /** The document after the export-mode pre-pass rewrote font references. */\n document: ReportComponentDefinition;\n theme: ThemeConfig;\n /** Cache key: base theme name + override digest + export-mode scope. */\n themeName: string;\n}\n\n/** customThemes lookup with the case-insensitive fallback, then built-ins. */\nfunction defaultNamedThemeLookup(\n themeName: string,\n customThemes: { [key: string]: ThemeConfig } | undefined,\n warnings?: GenerationWarning[]\n): ThemeConfig {\n if (customThemes) {\n if (customThemes[themeName]) return customThemes[themeName];\n const themeNameLower = themeName.toLowerCase();\n const matchingThemeKey = Object.keys(customThemes).find(\n (key) => key.toLowerCase() === themeNameLower\n );\n if (matchingThemeKey) return customThemes[matchingThemeKey];\n return resolveBuiltInTheme(themeName, { customThemes, warnings });\n }\n return resolveBuiltInTheme(themeName, { warnings });\n}\n\nexport function resolveThemeContext(\n documentIn: ReportComponentDefinition,\n options: ThemeContextOptions = {}\n): GenerationThemeContext {\n const { customThemes, fonts, warnings, resolveNamedTheme } = options;\n\n // A root written without a `props` key validates clean, so default it here —\n // otherwise every downstream `document.props.*` read (theme, componentDefaults,\n // noProofWords, trackRevisions, language, metadata) throws. Only `undefined`\n // is defaulted: `props: null` is malformed and must be rejected rather than\n // quietly rewritten into a valid shape.\n //\n // Both JSON entry points validate before reaching here, so null is already\n // a validation error there. `generateDocument` on a document without\n // `$schema` runs no validator at all, and used to surface this as\n // `Cannot read properties of null` from the theme read below.\n if (documentIn.props === null) {\n throw new Error(\n 'Document `props` is null. Omit it, or provide an object — ' +\n 'a null props cannot carry a theme.'\n );\n }\n const document =\n documentIn.props === undefined ? { ...documentIn, props: {} } : documentIn;\n\n const authoredThemeName = document.props.theme || undefined;\n const baseThemeName = authoredThemeName ?? 'minimal';\n let theme = resolveNamedTheme\n ? resolveNamedTheme(\n baseThemeName,\n warnings,\n authoredThemeName !== undefined\n )\n : defaultNamedThemeLookup(baseThemeName, customThemes, warnings);\n\n // In-document partial theme, merged before the export-mode pre-pass so a\n // font-family override is visible to it. The digest joins the cache key so\n // two documents sharing a theme name but not overrides never share slots.\n const themeOverrides = document.props.themeOverrides;\n let themeName = baseThemeName;\n if (themeOverrides) {\n theme = applyThemeOverrides(theme, themeOverrides);\n themeName = `${themeName}+ov:${themeOverridesDigest(themeOverrides)}`;\n }\n\n // Export-mode pre-pass: substitute (default) rewrites non-safe families to\n // safe equivalents; custom keeps refs as-is.\n const mode = applyExportMode({ doc: document, theme, fonts });\n for (const w of mode.warnings) {\n if (warnings) {\n warnings.push({\n component: 'fontRegistry',\n message: w.message,\n severity: 'warning',\n context: { code: w.code },\n });\n } else {\n // eslint-disable-next-line no-console\n console.warn(`[json-to-docx] [${w.code}] ${w.message}`);\n }\n }\n\n return {\n document: mode.doc,\n theme: mode.theme,\n // Scope by mode too: substitute rewrites the theme in place, so caches\n // must not share slots with custom-mode runs keyed on the same name.\n themeName: scopedThemeName(themeName, fonts?.mode),\n };\n}\n","import type { GenerationWarning } from '@json-to-office/shared';\nimport type { ThemeConfig } from './index';\nimport {\n getThemeNames,\n getThemeWithFallback,\n hasTheme,\n} from '../templates/themes';\n\n/**\n * Resolve a built-in theme by name, reporting a miss instead of swallowing it.\n *\n * `getThemeWithFallback` renders an unknown name as `minimal`, which used to be\n * invisible: a typo, or a `--theme-path` file whose internal `name` differs\n * from its filename, produced a plausible-looking document styled by the wrong\n * theme. The fallback is kept — a bad name should not fail a render — but it\n * now surfaces as a warning naming what was asked for and what is available.\n */\nexport function resolveBuiltInTheme(\n themeName: string,\n options: {\n customThemes?: { [key: string]: ThemeConfig };\n warnings?: GenerationWarning[];\n } = {}\n): ThemeConfig {\n if (!hasTheme(themeName)) {\n const available = [\n ...getThemeNames(),\n ...Object.keys(options.customThemes ?? {}),\n ].sort();\n options.warnings?.push({\n component: 'theme',\n message: `Theme \"${themeName}\" not found; falling back to \"minimal\". Available themes: ${available.join(', ')}.`,\n severity: 'warning',\n context: { code: 'theme_not_found', requested: themeName, available },\n });\n }\n\n return getThemeWithFallback(themeName);\n}\n","/**\n * In-document theme overrides: a partial theme from the document root's\n * `themeOverrides` prop, deep-merged over the resolved named theme.\n */\n\nimport { createHash } from 'crypto';\nimport type { ThemeConfig } from '../styles';\n\nexport interface ThemeOverrides {\n colors?: Partial<ThemeConfig['colors']>;\n fonts?: Partial<ThemeConfig['fonts']>;\n styles?: ThemeConfig['styles'];\n}\n\n/**\n * Merge a partial override object over a resolved theme.\n *\n * - `colors`: per-token replacement.\n * - `fonts`: per-role merge (an override role only replaces the fields it\n * sets, so `{ heading: { family: \"Geist\" } }` keeps the theme's size).\n * - `styles`: per-style merge, one level deep — nested objects inside a style\n * (spacing, lineSpacing, borders, indent) are replaced wholesale.\n */\nexport function applyThemeOverrides(\n theme: ThemeConfig,\n overrides: ThemeOverrides | undefined\n): ThemeConfig {\n if (!overrides) return theme;\n\n const fonts = { ...theme.fonts };\n for (const [role, def] of Object.entries(overrides.fonts ?? {})) {\n const key = role as keyof ThemeConfig['fonts'];\n fonts[key] = { ...theme.fonts[key], ...def };\n }\n\n const styles: Record<string, object> = { ...(theme.styles ?? {}) };\n for (const [name, def] of Object.entries(overrides.styles ?? {})) {\n styles[name] = { ...styles[name], ...(def as object) };\n }\n\n return {\n ...theme,\n colors: { ...theme.colors, ...(overrides.colors ?? {}) },\n fonts,\n ...(Object.keys(styles).length > 0 && { styles }),\n };\n}\n\n/** Short stable digest used to scope theme-keyed caches per override set. */\nexport function themeOverridesDigest(overrides: ThemeOverrides): string {\n return createHash('sha256')\n .update(JSON.stringify(overrides))\n .digest('hex')\n .slice(0, 8);\n}\n","import { format } from 'date-fns';\n\nexport const formatDate = (\n date: Date,\n formatString: string = 'MMMM d, yyyy'\n): string => {\n return format(date, formatString);\n};\n","/**\n * Component Default Resolution System\n * Provides theme-based default configurations for components\n */\n\nimport {\n ThemeConfig,\n ComponentDefaults,\n HeadingComponentDefaults,\n ParagraphComponentDefaults,\n ImageComponentDefaults,\n StatisticComponentDefaults,\n TableComponentDefaults,\n SectionComponentDefaults,\n ColumnsComponentDefaults,\n ListComponentDefaults,\n} from '../index';\nimport {\n HeadingProps,\n ParagraphProps,\n ImageProps,\n StatisticProps,\n TableProps,\n SectionProps,\n ColumnsProps,\n ListProps,\n} from '../../types';\nimport { mergeWithDefaults } from '@json-to-office/shared';\n\n/**\n * Get component defaults from theme configuration\n */\nexport function getComponentDefaults(theme: ThemeConfig): ComponentDefaults {\n return theme.componentDefaults || {};\n}\n\n/**\n * Get default configuration for heading components\n */\nexport function getHeadingDefaults(\n theme: ThemeConfig\n): HeadingComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.heading || {};\n}\n\n/**\n * Get level-specific heading defaults from theme styles\n */\nexport function getHeadingDefaultsForLevel(\n theme: ThemeConfig,\n level: number\n): Partial<HeadingComponentDefaults> {\n const defaults: Partial<HeadingComponentDefaults> = {};\n\n // Check styles for level-specific alignment\n if (theme.styles) {\n const styleKey = `heading${level}` as\n | 'heading1'\n | 'heading2'\n | 'heading3'\n | 'heading4'\n | 'heading5'\n | 'heading6';\n const headingStyle = theme.styles[styleKey];\n\n if (headingStyle?.alignment) {\n defaults.alignment = headingStyle.alignment;\n }\n }\n\n return defaults;\n}\n\n/**\n * Get default configuration for text components\n */\nexport function getTextDefaults(\n theme: ThemeConfig\n): ParagraphComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.paragraph || {};\n}\n\n/**\n * Get default configuration for image components\n */\nexport function getImageDefaults(theme: ThemeConfig): ImageComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.image || {};\n}\n\n/**\n * Get default configuration for statistic components\n */\nexport function getStatisticDefaults(\n theme: ThemeConfig\n): StatisticComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.statistic || {};\n}\n\n/**\n * Get default configuration for table components\n */\nexport function getTableDefaults(theme: ThemeConfig): TableComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.table || {};\n}\n\n/**\n * Get default configuration for section components\n */\nexport function getSectionDefaults(\n theme: ThemeConfig\n): SectionComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.section || {};\n}\n\n/**\n * Get default configuration for columns components\n */\nexport function getColumnsDefaults(\n theme: ThemeConfig\n): ColumnsComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.columns || {};\n}\n\n/**\n * Get default configuration for list components\n */\nexport function getListDefaults(theme: ThemeConfig): ListComponentDefaults {\n const defaults = getComponentDefaults(theme);\n return defaults?.list || {};\n}\n\n// mergeWithDefaults is re-exported from @json-to-office/shared\nexport { mergeWithDefaults } from '@json-to-office/shared';\n\n/**\n * Resolve heading component props with theme defaults\n */\nexport function resolveHeadingProps(\n props: HeadingProps,\n theme: ThemeConfig\n): HeadingProps {\n const defaults = getHeadingDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve paragraph component props with theme defaults\n */\nexport function resolveParagraphProps(\n props: ParagraphProps,\n theme: ThemeConfig\n): ParagraphProps {\n const defaults = getTextDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve image component props with theme defaults\n */\nexport function resolveImageProps(\n props: ImageProps,\n theme: ThemeConfig\n): ImageProps {\n const defaults = getImageDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve statistic component props with theme defaults\n */\nexport function resolveStatisticProps(\n props: StatisticProps,\n theme: ThemeConfig\n): StatisticProps {\n const defaults = getStatisticDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve table component props with theme defaults\n */\nexport function resolveTableProps(\n props: TableProps,\n theme: ThemeConfig\n): TableProps {\n const defaults = getTableDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve section component props with theme defaults\n */\nexport function resolveSectionProps(\n props: SectionProps,\n theme: ThemeConfig\n): SectionProps {\n const defaults = getSectionDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve columns component props with theme defaults\n */\nexport function resolveColumnsProps(\n props: ColumnsProps,\n theme: ThemeConfig\n): ColumnsProps {\n const defaults = getColumnsDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve list component props with theme defaults\n */\nexport function resolveListProps(\n props: ListProps,\n theme: ThemeConfig\n): ListProps {\n const defaults = getListDefaults(theme);\n return mergeWithDefaults(props, defaults);\n}\n\n/**\n * Resolve highcharts component props with theme defaults\n */\nexport function resolveHighchartsProps(\n props: import('@json-to-office/shared-docx').HighchartsProps,\n _theme: ThemeConfig\n): import('@json-to-office/shared-docx').HighchartsProps {\n // Highcharts component doesn't have theme defaults, just return the props as-is\n return props;\n}\n\n/**\n * Resolve visual component props with theme defaults.\n * The visual is rasterized by the pptx engine, so there are no docx-side theme\n * defaults to apply — return props as-is (mirrors highcharts).\n */\nexport function resolveVisualProps(\n props: import('@json-to-office/shared-docx').VisualProps,\n _theme: ThemeConfig\n): import('@json-to-office/shared-docx').VisualProps {\n return props;\n}\n\n/**\n * Get default configuration for custom components\n */\nexport function getCustomComponentDefaults(\n theme: ThemeConfig,\n componentName: string\n): Record<string, unknown> {\n const defaults = getComponentDefaults(theme);\n // Use type assertion since we're dealing with dynamic property access\n return ((defaults as any)?.[componentName] as Record<string, unknown>) || {};\n}\n\n/**\n * Resolve custom component props with theme defaults\n */\nexport function resolveCustomComponentProps<T extends Record<string, unknown>>(\n props: T,\n theme: ThemeConfig,\n componentName: string\n): T {\n const defaults = getCustomComponentDefaults(theme, componentName);\n return mergeWithDefaults(props, defaults as Partial<T>);\n}\n","/**\n * Centralized Component Defaults Resolution\n * Walks the component tree and resolves theme componentDefaults\n * on every component before any rendering or structure processing.\n */\n\nimport { ComponentDefinition, HeadingProps } from '../../types';\nimport { ThemeConfig } from '../index';\nimport {\n resolveHeadingProps,\n resolveParagraphProps,\n resolveImageProps,\n resolveStatisticProps,\n resolveTableProps,\n resolveSectionProps,\n resolveColumnsProps,\n resolveListProps,\n resolveHighchartsProps,\n resolveVisualProps,\n resolveCustomComponentProps,\n getHeadingDefaultsForLevel,\n} from './componentDefaults';\n\n/**\n * Heading resolver that also applies level-specific style defaults\n * (alignment from theme.styles.heading{N}).\n * Moved here from heading.ts to centralize all resolution.\n */\nfunction resolveHeadingWithLevelDefaults(\n props: HeadingProps,\n theme: ThemeConfig\n): HeadingProps {\n const resolved = resolveHeadingProps(props, theme);\n const level = resolved.level || 1;\n const levelDefaults = getHeadingDefaultsForLevel(theme, level);\n return {\n ...resolved,\n // Only apply level-specific defaults if no explicit alignment in original props\n ...(props.alignment ? {} : levelDefaults),\n };\n}\n\ntype Resolver = (props: any, theme: ThemeConfig) => any;\n\nconst RESOLVER_MAP: Record<string, Resolver> = {\n heading: resolveHeadingWithLevelDefaults,\n paragraph: resolveParagraphProps,\n image: resolveImageProps,\n statistic: resolveStatisticProps,\n table: resolveTableProps,\n section: resolveSectionProps,\n columns: resolveColumnsProps,\n list: resolveListProps,\n highcharts: resolveHighchartsProps,\n visual: resolveVisualProps,\n};\n\n/**\n * Resolve componentDefaults for a single component.\n * Known components use their typed resolver; unknown names\n * fall back to resolveCustomComponentProps.\n *\n * A missing `props` key is treated as `{}` — a propless node must still pick up\n * the theme's defaults (e.g. `componentDefaults.section.pageBreak: false`).\n */\nexport function resolveComponentDefaults(\n component: ComponentDefinition,\n theme: ThemeConfig\n): ComponentDefinition {\n const props = component.props ?? {};\n\n const resolver = RESOLVER_MAP[component.name];\n const resolvedProps = resolver\n ? resolver(props, theme)\n : resolveCustomComponentProps(\n props as Record<string, unknown>,\n theme,\n component.name\n );\n\n return { ...component, props: resolvedProps };\n}\n\n/**\n * Recursively walk the component tree and resolve componentDefaults\n * on every component. Returns a new tree (no mutation).\n */\nexport function resolveComponentTree(\n components: ComponentDefinition[],\n theme: ThemeConfig\n): ComponentDefinition[] {\n return components.map((component) => {\n const resolved = resolveComponentDefaults(component, theme);\n\n const children = (resolved as any).children as\n | ComponentDefinition[]\n | undefined;\n if (children && children.length > 0) {\n return {\n ...resolved,\n children: resolveComponentTree(children, theme),\n };\n }\n\n return resolved;\n });\n}\n","/**\n * Document Structure Functions\n * Handle document hierarchy and organization without layout concerns\n */\n\nimport {\n ComponentDefinition,\n ReportProps,\n ReportComponentDefinition,\n RenderContext,\n isSectionComponent,\n isColumnsComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { formatDate } from '../utils/formatters';\nimport {\n resolveComponentTree,\n resolveComponentDefaults,\n} from '../styles/utils/resolveComponentTree';\nimport { mergeWithDefaults } from '../styles/utils/componentDefaults';\n\nexport interface ProcessedDocument {\n metadata: DocumentMetadata;\n sections: ProcessedSection[];\n theme: ThemeConfig;\n themeName: string;\n /** Open the generated document in track-changes mode */\n trackRevisions?: boolean;\n /** Default document language (BCP-47) applied to docDefaults proofing */\n language?: string;\n}\n\nexport interface DocumentMetadata {\n title?: string;\n subtitle?: string;\n description?: string;\n author?: string;\n company?: string;\n version?: string;\n tags?: string[];\n date: Date;\n}\n\nexport interface ProcessedSection {\n title?: string;\n level?: number;\n components: ComponentDefinition[];\n header?: ComponentDefinition[] | 'linkToPrevious';\n footer?: ComponentDefinition[] | 'linkToPrevious';\n /** True if this section originates from an explicit Section component */\n isExplicitSection?: boolean;\n /** Whether this section should start on a new page */\n pageBreak?: boolean;\n /** Page configuration override for this section */\n page?: {\n size?: 'A4' | 'A3' | 'LETTER' | 'LEGAL' | { width: number; height: number };\n margins?: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n header?: number;\n footer?: number;\n gutter?: number;\n };\n };\n}\n\n/**\n * Process document definition into structured format\n */\nexport async function processDocument(\n document: ReportComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n generationDate?: Date\n): Promise<ProcessedDocument> {\n const metadata = createDocumentMetadata(document.props, generationDate);\n\n // Merge document-level componentDefaults on top of theme-level ones\n // (document overrides theme)\n const docDefaults = document.props.componentDefaults;\n const mergedComponentDefaults = docDefaults\n ? mergeWithDefaults(docDefaults, theme.componentDefaults || {})\n : undefined;\n\n // Fold the document's known-words allowlist into the theme object so it\n // reaches every text primitive (createText/createHeading) without threading\n // a new parameter through the whole render tree. Document words are added to\n // any house-style words the theme already defines.\n const docNoProofWords = document.props.noProofWords;\n const mergedNoProofWords =\n docNoProofWords || theme.noProofWords\n ? Array.from(\n new Set([...(theme.noProofWords || []), ...(docNoProofWords || [])])\n )\n : undefined;\n\n const effectiveTheme =\n mergedComponentDefaults || mergedNoProofWords\n ? {\n ...theme,\n ...(mergedComponentDefaults && {\n componentDefaults: mergedComponentDefaults,\n }),\n ...(mergedNoProofWords && { noProofWords: mergedNoProofWords }),\n }\n : theme;\n\n // Create context with effective theme so section-title headings\n // created in extractSections also see document-level defaults\n const context = createRenderContext(\n {\n metadata,\n sections: [],\n theme: effectiveTheme,\n themeName,\n },\n effectiveTheme,\n themeName\n );\n\n // Resolve componentDefaults on every component before\n // extractSections reads any props (fixes section pageBreak, table defaults, etc.)\n const resolvedChildren = resolveComponentTree(\n document.children || [],\n effectiveTheme\n );\n\n // Extract sections from components\n const sections = await extractSections(resolvedChildren, context);\n\n return {\n metadata,\n sections,\n theme: effectiveTheme,\n themeName,\n trackRevisions: document.props.trackRevisions,\n language: document.props.language,\n };\n}\n\n/**\n * Extract document metadata from report props\n */\nexport function createDocumentMetadata(\n props: ReportProps,\n generationDate = new Date()\n): DocumentMetadata {\n return {\n title: props.metadata?.title,\n subtitle: props.metadata?.subtitle,\n description: props.metadata?.description,\n author: props.metadata?.author,\n company: props.metadata?.company,\n version: props.metadata?.version,\n tags: props.metadata?.tags,\n date: props.metadata?.date ? new Date(props.metadata.date) : generationDate,\n };\n}\n\n/**\n * Extract and flatten sections from component hierarchy\n */\nexport async function extractSections(\n components: ComponentDefinition[],\n context: RenderContext\n): Promise<ProcessedSection[]> {\n const sections: ProcessedSection[] = [];\n\n // Filter out components with enabled: false (defaults to true when not specified)\n const activeComponents = components.filter(\n (m) => !('enabled' in m && m.enabled === false)\n );\n\n for (const component of activeComponents) {\n if (isSectionComponent(component)) {\n const sectionComponents = await flattenComponents(\n component.children || [],\n context\n );\n\n // Determine if page break should be applied (default to true)\n const shouldPageBreak = component.props?.pageBreak !== false;\n\n // Add section title as heading component if present\n if (component.props?.title) {\n // Ensure level is within valid range (1-6) for heading component\n const headingLevel = Math.min(\n Math.max(component.props.level || 1, 1),\n 6\n ) as 1 | 2 | 3 | 4 | 5 | 6;\n\n sectionComponents.unshift(\n resolveComponentDefaults(\n {\n name: 'heading',\n props: {\n text: component.props.title,\n level: headingLevel,\n pageBreak: shouldPageBreak,\n // Apply zero-spacing to prevent unwanted initial line\n spacing: {\n before: 0,\n after: 0,\n },\n },\n },\n context.fullTheme\n )\n );\n }\n\n sections.push({\n title: component.props?.title,\n level: component.props?.level,\n components: sectionComponents,\n header: component.props?.header,\n footer: component.props?.footer,\n isExplicitSection: true,\n // Store pageBreak for titleless sections to be handled at layout level\n pageBreak: !component.props?.title ? shouldPageBreak : undefined,\n // Preserve page configuration override if present\n page: component.props?.page,\n });\n } else {\n // Non-section components at root level become their own section\n sections.push({\n components: [component],\n isExplicitSection: false,\n });\n }\n }\n\n return sections;\n}\n\n/**\n * Flatten nested container components while preserving content components\n */\nexport async function flattenComponents(\n components: ComponentDefinition[],\n context: RenderContext\n): Promise<ComponentDefinition[]> {\n const flattened: ComponentDefinition[] = [];\n\n // Filter out components with enabled: false (defaults to true when not specified)\n const activeComponents = components.filter(\n (m) => !('enabled' in m && m.enabled === false)\n );\n\n for (const component of activeComponents) {\n if (isColumnsComponent(component) && component.children) {\n // Preserve columns structure but flatten its contents\n flattened.push({\n ...component,\n children: await flattenComponents(component.children, context),\n });\n } else if (isSectionComponent(component) && component.children) {\n // Flatten nested sections\n if (component.props?.title) {\n // Ensure level is within valid range (1-6) for heading component\n const headingLevel = Math.min(\n Math.max(component.props.level || 1, 1),\n 6\n ) as 1 | 2 | 3 | 4 | 5 | 6;\n\n // Convert section title to heading\n flattened.push(\n resolveComponentDefaults(\n {\n name: 'heading',\n props: {\n text: component.props.title,\n level: headingLevel,\n // Apply zero-spacing to prevent unwanted initial line\n spacing: {\n before: 0,\n after: 0,\n },\n },\n },\n context.fullTheme\n )\n );\n }\n flattened.push(...(await flattenComponents(component.children, context)));\n } else {\n // Keep content components as-is\n flattened.push(component);\n }\n }\n\n return flattened;\n}\n\n/**\n * Create render context from processed document\n */\nexport function createRenderContext(\n document: ProcessedDocument,\n theme: ThemeConfig,\n themeName: string\n): RenderContext {\n return {\n theme: {\n name: themeName,\n colors: theme.colors || {},\n fonts: theme.fonts\n ? Object.fromEntries(\n Object.entries(theme.fonts).map(([key, font]) => [key, font.family])\n )\n : {},\n spacing: { small: 120, medium: 240, large: 360, section: 480 },\n },\n fullTheme: theme,\n document: document.metadata,\n section: {\n currentLayout: 'single',\n columnCount: 1,\n pageNumber: 1,\n },\n utils: {\n formatDate: (date: Date) => formatDate(date),\n parseText: (text: string) => [{ text }],\n getStyle: (name: string) => ({ name }),\n },\n depth: 0,\n };\n}\n","/**\n * Layout Functions\n * Handle all layout concerns including columns, breaks, and section properties\n */\n\nimport { SectionType, Column as DocxColumn } from 'docx';\nimport {\n ComponentDefinition,\n ColumnSettings,\n isColumnsComponent,\n isSectionComponent,\n isHeadingComponent,\n isParagraphComponent,\n isTocComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { getPageSetup } from '../styles';\n// import { pointsToTwips } from '../styles/utils/styleHelpers';\nimport { ProcessedSection } from './structure';\nimport {\n getAvailableWidthTwips,\n relativeLengthToTwips,\n} from '../utils/widthUtils';\n\nexport interface LayoutPlan {\n sections: SectionLayout[];\n}\n\nexport interface WordSectionProperties {\n page: {\n size: {\n width: number;\n height: number;\n };\n margin: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n };\n column: ColumnSettings & { children?: DocxColumn[] };\n type?: (typeof SectionType)[keyof typeof SectionType];\n}\n\nexport interface SectionLayout {\n properties: WordSectionProperties;\n components: ComponentDefinition[];\n layoutType: 'single' | 'multi-column';\n breakBefore: boolean;\n header?: ComponentDefinition[] | 'linkToPrevious';\n footer?: ComponentDefinition[] | 'linkToPrevious';\n /** True if this layout section comes from a user-defined Section component */\n isUserSection: boolean;\n /** True if this layout chunk belongs to a user-defined Section (all chunks of that section) */\n belongsToUserSection: boolean;\n /** The heading level of the section title (e.g., 1 for Heading1) - used by TOCs to exclude section title from section-scoped TOCs */\n sectionTitleLevel?: number;\n /** Page configuration override for this section */\n pageOverride?: {\n size?: 'A4' | 'A3' | 'LETTER' | 'LEGAL' | { width: number; height: number };\n margins?: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n header?: number;\n footer?: number;\n gutter?: number;\n };\n };\n}\n\nexport interface LayoutGroup {\n layout: 'single' | 'multi-column';\n components: ComponentDefinition[];\n breakBefore: boolean;\n}\n\n/**\n * Apply layout to processed sections\n */\nexport function applyLayout(\n sections: ProcessedSection[],\n theme: ThemeConfig,\n themeName: string\n): LayoutPlan {\n const layoutSections: SectionLayout[] = [];\n\n for (let i = 0; i < sections.length; i++) {\n const section = sections[i];\n const layoutGroups = analyzeLayoutGroups(section.components);\n\n // Determine if this comes from an explicit Section component\n const isSourceUserSection = Boolean(section.isExplicitSection);\n\n // Handle sections with no components but with headers/footers\n // This ensures headers/footers are rendered even for empty sections\n if (layoutGroups.length === 0 && (section.header || section.footer)) {\n const isFirstSection = i === 0;\n const breakBefore = isFirstSection || Boolean(section.pageBreak);\n const sectionType = breakBefore ? 'nextPage' : 'continuous';\n\n layoutSections.push({\n properties: createSectionProperties(\n getColumnSettings('single'),\n theme,\n themeName,\n sectionType,\n section.page\n ),\n components: [],\n layoutType: 'single',\n breakBefore,\n header: section.header,\n footer: section.footer,\n isUserSection: isSourceUserSection,\n belongsToUserSection: isSourceUserSection,\n sectionTitleLevel: section.level,\n pageOverride: section.page,\n });\n continue;\n }\n\n for (let j = 0; j < layoutGroups.length; j++) {\n const group = layoutGroups[j];\n\n // Special handling: a single Columns component becomes its own section with explicit column children\n const isSingleColumnsGroup =\n group.components.length === 1 && isColumnsComponent(group.components[0]);\n\n const columnSettings = isSingleColumnsGroup\n ? createColumnSettingsFromConfig(group.components[0], theme, themeName)\n : getColumnSettings(group.layout);\n\n // Only break page if explicitly requested or this is the first section\n const isFirstSection = i === 0 && j === 0;\n // For titleless sections with pageBreak, apply break to first layout group\n const titlelessSectionBreak = Boolean(section.pageBreak && j === 0);\n const breakBefore =\n group.breakBefore || isFirstSection || titlelessSectionBreak;\n const sectionType = breakBefore ? 'nextPage' : 'continuous';\n\n // Build content components depending on whether this is an explicit columns group\n const contentComponents = isSingleColumnsGroup\n ? processLayoutComponents(\n (group.components[0] as unknown as { children?: ComponentDefinition[] })\n .children || []\n )\n : processLayoutComponents(group.components);\n\n layoutSections.push({\n properties: createSectionProperties(\n columnSettings,\n theme,\n themeName,\n sectionType,\n section.page\n ),\n components: contentComponents,\n layoutType: group.layout,\n breakBefore,\n header: section.header,\n footer: section.footer,\n // Only mark the FIRST layout section as user-defined to avoid\n // creating bookmark paragraphs in subsequent sections (e.g., when\n // transitioning to columns layout). This prevents unwanted newlines\n // at the start of column content.\n isUserSection: isSourceUserSection && j === 0,\n belongsToUserSection: isSourceUserSection,\n // Pass section title level for TOC scoping\n sectionTitleLevel: section.level,\n // Pass page override for this section\n pageOverride: section.page,\n });\n }\n }\n\n return { sections: layoutSections };\n}\n\n/**\n * Analyze components to determine layout groups\n */\nexport function analyzeLayoutGroups(\n components: ComponentDefinition[]\n): LayoutGroup[] {\n const groups: LayoutGroup[] = [];\n let currentLayout: 'single' | 'multi-column' = 'single';\n let currentComponents: ComponentDefinition[] = [];\n let breakNext = false;\n\n for (const component of components) {\n // Always isolate explicit Columns components into their own group\n if (isColumnsComponent(component)) {\n if (currentComponents.length > 0) {\n groups.push({\n layout: currentLayout,\n components: currentComponents,\n breakBefore: breakNext,\n });\n currentComponents = [];\n breakNext = false;\n }\n // Determine the actual layout based on the columns component configuration\n const columnsLayout = determineComponentLayout(component);\n groups.push({\n layout: columnsLayout,\n components: [component],\n breakBefore: breakNext,\n });\n breakNext = false;\n continue;\n }\n\n const componentLayout = determineComponentLayout(component);\n\n // Check for explicit break indicators\n if (hasPageBreak(component)) {\n if (currentComponents.length > 0) {\n // Finish previous group without break\n groups.push({\n layout: currentLayout,\n components: currentComponents,\n breakBefore: breakNext,\n });\n currentComponents = [];\n breakNext = false;\n }\n // Start new group with break for this component\n currentComponents = [component];\n breakNext = true;\n continue;\n }\n\n // Layout change requires new group\n if (componentLayout !== currentLayout && currentComponents.length > 0) {\n groups.push({\n layout: currentLayout,\n components: currentComponents,\n breakBefore: breakNext,\n });\n currentLayout = componentLayout;\n currentComponents = [component];\n breakNext = false;\n } else {\n currentComponents.push(component);\n }\n }\n\n // Add remaining components\n if (currentComponents.length > 0) {\n groups.push({\n layout: currentLayout,\n components: currentComponents,\n breakBefore: breakNext,\n });\n }\n\n return groups;\n}\n\n/**\n * Determine layout type for a component\n */\nexport function determineComponentLayout(\n component: ComponentDefinition\n): 'single' | 'multi-column' {\n if (isColumnsComponent(component)) {\n const columns = (component as any).props?.columns;\n\n // If columns is an array with specific configurations\n if (Array.isArray(columns)) {\n // Any columns array with 2+ items is multi-column\n return columns.length >= 2 ? 'multi-column' : 'single';\n }\n\n // No valid array provided; treat as single-column\n return 'single';\n }\n\n // Check if component contains children\n if ('children' in component && (component as any).children) {\n const hasColumns = (component as any).children.some((child: ComponentDefinition) =>\n isColumnsComponent(child)\n );\n return hasColumns ? 'multi-column' : 'single';\n }\n\n return 'single';\n}\n\n/**\n * Process components for layout (insert breaks where needed)\n */\nexport function processLayoutComponents(\n components: ComponentDefinition[]\n): ComponentDefinition[] {\n const processed: ComponentDefinition[] = [];\n\n for (let i = 0; i < components.length; i++) {\n const component = components[i];\n\n // Check if this component should have a column break\n if (shouldInsertColumnBreak()) {\n // Create a new component with columnBreak flag\n if (isHeadingComponent(component)) {\n processed.push({\n ...component,\n props: {\n ...((component as any).props || {}),\n columnBreak: true,\n },\n } as ComponentDefinition);\n } else {\n processed.push(component);\n }\n } else {\n processed.push(component);\n }\n }\n\n return processed;\n}\n\n/**\n * Determine if a column break should be inserted\n */\nfunction shouldInsertColumnBreak(): boolean {\n // Logic to determine column breaks based on content distribution\n // This is simplified - could be enhanced with more sophisticated logic\n return false;\n}\n\n/**\n * Check if component indicates a page break\n */\nfunction hasPageBreak(component: ComponentDefinition): boolean {\n if (isSectionComponent(component)) {\n // Default to true for section components when pageBreak is undefined\n return component.props?.pageBreak !== false;\n }\n if (isHeadingComponent(component)) {\n return component.props.pageBreak === true;\n }\n if (isParagraphComponent(component)) {\n return component.props.pageBreak === true;\n }\n // Allow TOC components to request a page break as well\n if (isTocComponent(component)) {\n return component.props?.pageBreak === true;\n }\n return false;\n}\n\n/**\n * Get column settings for layout type\n */\nexport function getColumnSettings(\n layout: 'single' | 'multi-column'\n): ColumnSettings {\n switch (layout) {\n case 'multi-column':\n // Default multi-column layout: 2 equal-width columns\n // Note: Specific column components will override this with their own settings via createColumnSettingsFromConfig\n return {\n count: 2,\n equalWidth: true,\n space: 720, // 0.5 inch in twips\n };\n case 'single':\n default:\n return { count: 1 };\n }\n}\n\n/**\n * Create Word section properties\n */\nexport function createSectionProperties(\n columnSettings: ColumnSettings,\n theme: ThemeConfig,\n themeName: string,\n sectionType?: 'continuous' | 'nextPage',\n pageOverride?: {\n size?: 'A4' | 'A3' | 'LETTER' | 'LEGAL' | { width: number; height: number };\n margins?: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n header?: number;\n footer?: number;\n gutter?: number;\n };\n }\n): WordSectionProperties {\n // Get base page setup from theme\n const basePageSetup = getPageSetup(theme, themeName);\n\n // Apply section-level page overrides if present\n const pageSetup = pageOverride\n ? {\n size: {\n ...basePageSetup.size,\n ...(pageOverride.size && typeof pageOverride.size === 'object'\n ? pageOverride.size\n : pageOverride.size\n ? (() => {\n // Convert string size to dimensions\n const sizes = {\n A4: { width: 11906, height: 16838 },\n A3: { width: 16838, height: 23811 },\n LETTER: { width: 12240, height: 15840 },\n LEGAL: { width: 12240, height: 20160 },\n };\n return sizes[pageOverride.size as keyof typeof sizes];\n })()\n : {}),\n },\n margin: {\n ...basePageSetup.margin,\n ...(pageOverride.margins || {}),\n },\n }\n : basePageSetup;\n\n const properties: WordSectionProperties = {\n page: pageSetup,\n column: {\n count: columnSettings.count,\n equalWidth: columnSettings.equalWidth,\n space: columnSettings.space,\n },\n };\n\n // If explicit children were provided, convert to docx Column instances\n if (\n (columnSettings as any).children &&\n Array.isArray((columnSettings as any).children)\n ) {\n const children = (columnSettings as any).children as {\n width?: number;\n space?: number;\n }[];\n // When we have explicit column children, ensure equalWidth is explicitly false\n // so Word doesn't override widths with equal distribution.\n properties.column.equalWidth = false;\n // Also remove top-level space to avoid conflicting with per-column spaces\n delete properties.column.space;\n\n properties.column.children = children.map(\n (c) =>\n new DocxColumn({\n width: c.width as number,\n ...(c.space !== undefined ? { space: c.space } : {}),\n })\n );\n }\n\n if (sectionType) {\n properties.type =\n sectionType === 'continuous'\n ? SectionType.CONTINUOUS\n : SectionType.NEXT_PAGE;\n }\n\n return properties;\n}\n\n/**\n * Create explicit column settings from a Columns component props\n * - width/gap accept number (points) or percentage string relative to available width\n */\nfunction createColumnSettingsFromConfig(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): ColumnSettings {\n const cfg = ((component as any).props || {}) as {\n columns?: Array<{ width?: number | string; gap?: number | string }>;\n };\n\n // Fallback to single column if no valid array is provided\n const columns = (cfg.columns || []) as Array<{\n width?: number | string;\n gap?: number | string;\n }>;\n\n if (!Array.isArray(columns) || columns.length === 0) {\n return { count: 1 };\n }\n\n const availableWidthTwips = getAvailableWidthTwips(theme, themeName);\n\n // First pass: compute defined widths/spaces; collect indexes without width\n const childSettings: { width?: number; space?: number }[] = [];\n let totalDefinedWidth = 0;\n let totalSpace = 0;\n const unspecifiedWidthIndexes: number[] = [];\n\n for (let i = 0; i < columns.length; i++) {\n const c = columns[i];\n const child: { width?: number; space?: number } = {};\n\n if (c.width !== undefined) {\n const widthTwips = relativeLengthToTwips(c.width, availableWidthTwips);\n if (widthTwips > 0) {\n child.width = widthTwips;\n totalDefinedWidth += widthTwips;\n }\n } else {\n unspecifiedWidthIndexes.push(i);\n }\n\n if (c.gap !== undefined) {\n const spaceTwips = relativeLengthToTwips(c.gap, availableWidthTwips);\n if (spaceTwips > 0) {\n child.space = spaceTwips;\n totalSpace += spaceTwips;\n }\n }\n\n childSettings.push(child);\n }\n\n // Validate that defined widths + gaps do not exceed available width (with tolerance)\n const totalUsedTwips = totalDefinedWidth + totalSpace;\n const tolerance = 0.005; // 0.5%\n const allowed = availableWidthTwips * (1 + tolerance);\n if (totalUsedTwips > allowed) {\n const usedPercent = (totalUsedTwips / availableWidthTwips) * 100;\n // Build diagnostics per column\n const details = childSettings\n .map((c, idx) => {\n const wPct = c.width\n ? ((c.width / availableWidthTwips) * 100).toFixed(1) + '%'\n : 'auto/unspecified';\n const gPct = c.space\n ? ((c.space / availableWidthTwips) * 100).toFixed(1) + '%'\n : '0%';\n return ` - Column ${idx + 1}: width=${wPct}, gap=${gPct}`;\n })\n .join('\\n');\n const suggestion =\n 'Reduce one or more widths/gaps so total <= 100%, remove the last gap, or set some widths to \"auto\" to consume remaining space.';\n throw new Error(\n `Columns configuration exceeds available width: widths + gaps = ${usedPercent.toFixed(1)}% (> 100% + ${(\n tolerance * 100\n ).toFixed(\n 1\n )}% tolerance)\\nDetails:\\n${details}\\nSuggestion: ${suggestion}`\n );\n }\n\n // Distribute remaining width equally among unspecified widths\n const remaining = Math.max(\n 0,\n availableWidthTwips - totalSpace - totalDefinedWidth\n );\n if (unspecifiedWidthIndexes.length > 0) {\n const each = Math.floor(remaining / unspecifiedWidthIndexes.length);\n for (const idx of unspecifiedWidthIndexes) {\n childSettings[idx].width = each;\n }\n }\n\n return {\n count: columns.length,\n equalWidth: false,\n children: childSettings,\n };\n}\n\n/**\n * Calculate optimal column distribution for content\n */\nexport function calculateColumnDistribution(\n components: ComponentDefinition[],\n columnCount: number\n): ComponentDefinition[][] {\n if (columnCount === 1) {\n return [components];\n }\n\n // Simple distribution - could be enhanced with content-aware logic\n const columns: ComponentDefinition[][] = Array(columnCount)\n .fill(null)\n .map(() => []);\n let currentColumn = 0;\n\n for (const component of components) {\n columns[currentColumn].push(component);\n currentColumn = (currentColumn + 1) % columnCount;\n }\n\n return columns;\n}\n","/**\n * Render Functions\n * Transform components and layout into Word document elements\n */\n\nimport {\n Document,\n Paragraph,\n Table,\n TableOfContents,\n IPropertiesOptions,\n ISectionOptions,\n TextRun,\n AlignmentType,\n BookmarkStart,\n BookmarkEnd,\n Textbox,\n} from 'docx';\nimport {\n calculateImageDimensions,\n getImageBuffer,\n parseWidthValue,\n detectImageType,\n createTypedImageRun,\n resolveImageSource,\n} from '../utils/imageUtils';\nimport {\n getThemeColors,\n getThemeFonts,\n getNormalStyle,\n} from '../themes/defaults';\nimport {\n ComponentDefinition,\n RenderContext,\n isHeadingComponent,\n isParagraphComponent,\n isColumnsComponent,\n isImageComponent,\n isVisualComponent,\n isTextBoxComponent,\n isStatisticComponent,\n isTableComponent,\n isSectionComponent,\n isListComponent,\n isTocComponent,\n isHighchartsComponent,\n ParagraphComponentDefinition,\n ImageComponentDefinition,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createWordStyles } from '../styles/themeToDocxAdapter';\nimport { resolveFontFamily } from '../styles/utils/styleHelpers';\nimport { getPageSetup } from '../styles/utils/layoutUtils';\nimport {\n DocumentMetadata,\n ProcessedDocument,\n createRenderContext,\n} from './structure';\nimport { LayoutPlan, SectionLayout } from './layout';\nimport {\n renderComponentWithCache,\n initializeComponentCache,\n} from './cached-render';\nimport { MemoryCache } from '../cache';\nimport type { ServicesConfig } from '@json-to-office/shared';\nimport {\n renderHeadingComponent,\n renderParagraphComponent,\n renderListComponent,\n renderImageComponent,\n renderTableComponent,\n renderSectionComponent,\n renderColumnsComponent,\n renderStatisticComponent,\n renderTocComponent,\n renderHighchartsComponent,\n renderVisualComponent,\n renderTextBoxComponent,\n} from '../components';\nimport {\n createText,\n createHeaderElement,\n createFooterElement,\n} from './content';\nimport { mapFloatingOptions } from '../utils/docxImagePositioning';\nimport { globalBookmarkRegistry } from '../utils/bookmarkRegistry';\nimport { globalNumberingRegistry } from '../utils/numberingConfig';\nimport { globalRevisionIdRegistry } from '../utils/revisionUtils';\nimport {\n runWithGenerationDate,\n runWithBaseDir,\n} from '../utils/generationContext';\n\ninterface RenderDocumentOptions {\n cache?: MemoryCache;\n bypassCache?: boolean;\n services?: ServicesConfig;\n /**\n * Directory that relative asset paths (image `path` props) resolve\n * against. Defaults to `process.cwd()` when absent (#142).\n */\n baseDir?: string;\n}\n\n/**\n * Convert alignment string to docx AlignmentType\n */\nfunction getAlignment(\n alignment: string\n): (typeof AlignmentType)[keyof typeof AlignmentType] {\n switch (alignment) {\n case 'center':\n return AlignmentType.CENTER;\n case 'right':\n return AlignmentType.RIGHT;\n case 'justify':\n return AlignmentType.JUSTIFIED;\n default:\n return AlignmentType.LEFT;\n }\n}\n\ntype CorePropertyOptions = Pick<\n IPropertiesOptions,\n | 'title'\n | 'subject'\n | 'creator'\n | 'description'\n | 'keywords'\n | 'lastModifiedBy'\n | 'customProperties'\n>;\n\n/**\n * Map root `props.metadata` onto Word's document properties.\n *\n * `date` is deliberately absent: it drives placeholder resolution, not the\n * package timestamps. dcterms:created/modified come from the `generatedAt`\n * generation option (docx always stamps them with the wall clock and offers no\n * override, so packageDocument rewrites them), which is why `metadata` exposes\n * no created/modified of its own.\n * `company` and `version` have no core-property slot, so they land in\n * docProps/custom.xml.\n */\nfunction coreProperties(metadata: DocumentMetadata): CorePropertyOptions {\n const { title, subtitle, description, author, company, version, tags } =\n metadata;\n\n const customProperties = [\n ...(company ? [{ name: 'Company', value: company }] : []),\n ...(version ? [{ name: 'Version', value: version }] : []),\n ];\n\n return {\n ...(title && { title }),\n ...(subtitle && { subject: subtitle }),\n ...(description && { description }),\n // Word surfaces both names; author is the only person the document knows.\n ...(author && { creator: author, lastModifiedBy: author }),\n ...(tags && tags.length > 0 && { keywords: tags.join(', ') }),\n ...(customProperties.length > 0 && { customProperties }),\n };\n}\n\n/**\n * Render a complete document from structure and layout\n */\nexport async function renderDocument(\n structure: ProcessedDocument,\n layout: LayoutPlan,\n options?: RenderDocumentOptions\n): Promise<Document> {\n return runWithGenerationDate(structure.metadata.date, () =>\n runWithBaseDir(options?.baseDir, () =>\n globalBookmarkRegistry.runScoped(() =>\n globalRevisionIdRegistry.runScoped(() =>\n globalNumberingRegistry.runScoped(() =>\n renderDocumentScoped(structure, layout, options)\n )\n )\n )\n )\n );\n}\n\nasync function renderDocumentScoped(\n structure: ProcessedDocument,\n layout: LayoutPlan,\n options?: RenderDocumentOptions\n): Promise<Document> {\n // Initialize component cache if provided\n if (options?.cache) {\n initializeComponentCache(options.cache);\n } else if (!options?.bypassCache) {\n // Initialize with default cache unless bypassed\n initializeComponentCache();\n }\n\n const sections: ISectionOptions[] = [];\n\n // Render all layout sections\n const context = createRenderContext(\n structure,\n structure.theme,\n structure.themeName\n );\n context.services = options?.services;\n\n // Initialize bookmark counter for this document (scoped to renderDocument call)\n let sectionBookmarkCounter = 0;\n\n // Track previous section's headers/footers for 'linkToPrevious' functionality\n let previousHeader: ComponentDefinition[] | undefined = undefined;\n let previousFooter: ComponentDefinition[] | undefined = undefined;\n\n // Render all layout sections\n for (let idx = 0; idx < layout.sections.length; idx++) {\n const layoutSection = layout.sections[idx];\n\n /**\n * Compute stable section ordinal for user-defined sections.\n *\n * When a user-defined Section component spans multiple layout chunks (e.g., due to\n * column transitions), all chunks must share the same bookmark ID for TOC scoping\n * to work correctly. This ensures:\n * 1. Bookmark start appears only in the first chunk\n * 2. All chunks use the same stable bookmark ID (no timestamp)\n * 3. Bookmark end appears only in the last chunk\n *\n * Previously used Date.now() in bookmark IDs, which caused different IDs per chunk.\n * Now we use a stable ordinal that's consistent across all chunks of the same section.\n */\n let sectionOrdinal: number | undefined = undefined;\n if (layoutSection.belongsToUserSection) {\n if (layoutSection.isUserSection) {\n // First chunk of this user-defined section: assign ordinal as next index\n sectionOrdinal = sectionBookmarkCounter + 1;\n } else {\n // Subsequent chunk: reuse last assigned ordinal\n sectionOrdinal = sectionBookmarkCounter; // previous value already incremented after first chunk\n }\n }\n // Handle 'linkToPrevious' value for headers\n let headerToUse: ComponentDefinition[] | undefined;\n if (layoutSection.header === 'linkToPrevious') {\n // Use the previous section's header\n headerToUse = previousHeader;\n } else if (layoutSection.header) {\n // Section has its own header\n headerToUse = layoutSection.header as ComponentDefinition[];\n previousHeader = headerToUse; // Update previous for next section\n } else {\n // No header explicitly set for this section.\n // Important: Word links headers/footers to previous by default.\n // To prevent unintended inheritance, emit an explicit empty header\n // when a previous header exists and caller didn't request linking.\n headerToUse = previousHeader ? [] : undefined;\n // Keep previousHeader cached for potential future explicit linkToPrevious\n }\n\n // Handle 'linkToPrevious' value for footers\n let footerToUse: ComponentDefinition[] | undefined;\n if (layoutSection.footer === 'linkToPrevious') {\n // Use the previous section's footer\n footerToUse = previousFooter;\n } else if (layoutSection.footer) {\n // Section has its own footer\n footerToUse = layoutSection.footer as ComponentDefinition[];\n previousFooter = footerToUse; // Update previous for next section\n } else {\n // No footer explicitly set for this section.\n // Prevent unintended inheritance by emitting an explicit empty footer\n // when a previous footer exists and caller didn't request linking.\n footerToUse = previousFooter ? [] : undefined;\n // Keep previousFooter cached for potential future explicit linkToPrevious\n }\n\n const sectionToRender = {\n ...layoutSection,\n header: headerToUse,\n footer: footerToUse,\n };\n\n // Determine if we should close the bookmark in this chunk.\n // Close when this is the last chunk belonging to the same user-defined section.\n let closeBookmark = false;\n if (layoutSection.belongsToUserSection && sectionOrdinal !== undefined) {\n const next = layout.sections[idx + 1];\n if (!next || !next.belongsToUserSection || next.isUserSection) {\n closeBookmark = true;\n }\n }\n\n const rendered = await renderSection(\n sectionToRender,\n structure.theme,\n structure.themeName,\n context,\n sectionOrdinal,\n closeBookmark,\n options?.bypassCache === true\n );\n\n // Increment counter if this section created a bookmark\n if (layoutSection.isUserSection) {\n sectionBookmarkCounter++;\n }\n\n if (rendered.children.length > 0) {\n sections.push(rendered);\n }\n }\n\n // Get all numbering configurations from the registry (already imported above)\n const numberingConfigs = globalNumberingRegistry.getAll();\n\n return new Document({\n styles: createWordStyles(structure.theme, structure.language),\n sections,\n ...coreProperties(structure.metadata),\n features: {\n updateFields: true, // Required for TOC fields to update correctly\n // Word opens the document in review mode (further edits are tracked)\n ...(structure.trackRevisions && { trackRevisions: true }),\n },\n // Add numbering configurations if any lists were rendered\n ...(numberingConfigs.length > 0 && {\n numbering: {\n config: numberingConfigs as readonly {\n readonly levels: readonly import('docx').ILevelsOptions[];\n readonly reference: string;\n }[],\n },\n }),\n });\n}\n\n/**\n * Render header/footer components into paragraphs\n */\nasync function renderHeaderFooterComponents(\n components: ComponentDefinition[] | undefined,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!components || components.length === 0) {\n return [];\n }\n\n // Filter out components with enabled: false (defaults to true when not specified)\n const activeComponents = components.filter(\n (m) => !('enabled' in m && m.enabled === false)\n );\n\n const elements: (Paragraph | Table)[] = [];\n\n for (const component of activeComponents) {\n if (isParagraphComponent(component)) {\n const textComp = component as ParagraphComponentDefinition;\n const font = textComp.props.font;\n\n // Header/footer text has no dedicated style, so unspecified font\n // properties resolve against the theme's Normal style.\n const normalStyle = getNormalStyle(theme);\n\n // Render through the shared paragraph primitive (same as body\n // paragraphs) so headers/footers honor lineSpacing, spacing\n // (before/after) and the full font set instead of silently dropping\n // them. When the component omits lineSpacing/spacing, createText leaves\n // them unset and the Normal style supplies the baseline.\n elements.push(\n createText(textComp.props.text, theme, themeName, {\n style: 'Normal',\n alignment: textComp.props.alignment,\n // Resolve explicit run styling against the Normal style, preserving\n // prior header/footer rendering for these properties.\n fontFamily:\n font?.family ||\n resolveFontFamily(theme, normalStyle.font) ||\n getThemeFonts(theme).body.family,\n fontSize: (font?.size ?? normalStyle.size ?? 11) as number,\n // Pass the raw color/token; createText resolves it. Fall back to the\n // Normal style color, then the theme's primary text color.\n fontColor: font?.color || normalStyle.color || 'textPrimary',\n bold: font?.bold ?? false,\n italic: font?.italic ?? false,\n underline: font?.underline,\n fontWeight: (font as { fontWeight?: number } | undefined)?.fontWeight,\n boldColor: textComp.props.boldColor,\n spacing: textComp.props.spacing,\n lineSpacing: font?.lineSpacing,\n })\n );\n } else if (isImageComponent(component)) {\n const imageComp = component as ImageComponentDefinition;\n // Get image source (svg, base64, or path)\n let imageSource = resolveImageSource(imageComp.props);\n if (!imageSource) {\n elements.push(\n new Paragraph({\n children: [\n new TextRun({\n text: '[IMAGE: Missing path, base64, or svg property]',\n font: getThemeFonts(theme).body.family,\n size: 20,\n bold: true,\n color: '#FF0000',\n }),\n ],\n alignment: imageComp.props.alignment\n ? getAlignment(imageComp.props.alignment)\n : undefined,\n style: 'Normal',\n })\n );\n continue;\n }\n\n let imageBuffer: Buffer;\n let responseContentType: string | undefined;\n\n try {\n // Try to use the provided source first\n const imageResult = await getImageBuffer(imageSource);\n imageBuffer = imageResult.buffer;\n responseContentType = imageResult.contentType;\n } catch (error) {\n throw new Error(\n `Failed to load image from ${imageSource.substring(0, 50)}`\n );\n }\n\n try {\n // Get page setup from theme for proper width calculations\n const pageSetup = getPageSetup(theme);\n\n // Convert twips to pixels: 1 twip = 1/1440 inch, 1 inch = 96 pixels at 96 DPI\n const TWIPS_TO_PIXELS = 96 / 1440;\n\n // Calculate page width and content width (page - left margin - right margin) in pixels\n const pageWidthPx = Math.round(pageSetup.size.width * TWIPS_TO_PIXELS);\n const contentWidthPx = Math.round(\n (pageSetup.size.width -\n pageSetup.margin.left -\n pageSetup.margin.right) *\n TWIPS_TO_PIXELS\n );\n\n // Determine reference dimensions based on widthRelativeTo/heightRelativeTo properties\n const widthRelativeTo = imageComp.props.widthRelativeTo || 'content';\n const heightRelativeTo = imageComp.props.heightRelativeTo || 'content';\n const referenceWidthPx =\n widthRelativeTo === 'page' ? pageWidthPx : contentWidthPx;\n\n // Calculate page height and content height in pixels\n const pageHeightPx = Math.round(\n pageSetup.size.height * TWIPS_TO_PIXELS\n );\n const contentHeightPx = Math.round(\n (pageSetup.size.height -\n pageSetup.margin.top -\n pageSetup.margin.bottom) *\n TWIPS_TO_PIXELS\n );\n const referenceHeightPx =\n heightRelativeTo === 'page' ? pageHeightPx : contentHeightPx;\n\n const fallbackHeight = Math.round(referenceWidthPx * 0.6);\n\n // Parse width value if it's a string percentage (like \"90%\")\n const parsedWidth =\n typeof imageComp.props.width === 'string'\n ? parseWidthValue(imageComp.props.width, referenceWidthPx) // Use appropriate reference width\n : imageComp.props.width;\n\n // Parse height value if it's a string percentage (like \"90%\")\n const parsedHeight =\n typeof imageComp.props.height === 'string'\n ? parseWidthValue(imageComp.props.height, referenceHeightPx) // Use reference height based on heightRelativeTo\n : imageComp.props.height;\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imageSource,\n parsedWidth,\n parsedHeight,\n referenceWidthPx,\n fallbackHeight\n );\n\n // Map floating options if present\n const floatingOptions = mapFloatingOptions(\n imageComp.props.floating,\n theme,\n themeName\n );\n\n const imageType = detectImageType(imageSource, responseContentType);\n\n const imageRun = createTypedImageRun({\n type: imageType,\n data: imageBuffer,\n transformation: {\n width: dimensions.width,\n height: dimensions.height,\n },\n ...(floatingOptions && { floating: floatingOptions }),\n });\n\n elements.push(\n new Paragraph({\n children: [imageRun],\n alignment: imageComp.props.alignment\n ? getAlignment(imageComp.props.alignment)\n : undefined,\n style: 'Normal',\n })\n );\n } catch (error) {\n // Fallback for missing images - log error for debugging.\n // Use the resolved source (svg/base64/path), truncated so an inline\n // data URI doesn't dump into the log or the placeholder text.\n const sourcePreview = imageSource.substring(0, 50);\n console.error(\n `[Header/Footer Image Error] Failed to render image: ${sourcePreview}...`,\n error instanceof Error ? error.message : error\n );\n elements.push(\n new Paragraph({\n children: [\n new TextRun({\n text: `[IMAGE: ${sourcePreview}]`,\n font: getThemeFonts(theme).body.family,\n size: 20,\n color: getThemeColors(theme).secondary,\n bold: true,\n }),\n ],\n style: 'Normal',\n })\n );\n }\n } else if (isTableComponent(component)) {\n // Use renderTableComponent for consistent table rendering in headers/footers\n // This ensures cellDefaults, padding, borders, and all table features work correctly\n const tables = await renderTableComponent(component, theme, themeName);\n elements.push(...tables);\n } else if (isVisualComponent(component)) {\n // A visual desugars to an image; needs the rasterization service from context.\n const visualEls = await renderVisualComponent(\n component,\n theme,\n themeName,\n context\n );\n elements.push(...visualEls);\n }\n // Other component types can be added here as needed\n }\n\n return elements;\n}\n\n/**\n * Render a section with layout\n */\nexport async function renderSection(\n section: SectionLayout,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext,\n sectionOrdinal?: number,\n closeBookmark?: boolean,\n bypassCache = false\n): Promise<ISectionOptions> {\n const elements: (Paragraph | Table | TableOfContents)[] = [];\n\n // Update context for this section\n // Generate a unique bookmark for this section so TOCs can scope to it\n const isFirstLayoutOfUserSection = section.isUserSection;\n // Use a stable bookmark ID across all layout sections of the same user-defined section\n const sharedLinkId =\n section.belongsToUserSection && sectionOrdinal ? sectionOrdinal : undefined;\n const sectionBookmarkId =\n sharedLinkId !== undefined ? `_Section_${sharedLinkId}` : undefined;\n\n const sectionContext: RenderContext = {\n ...context,\n section: {\n ...context.section,\n currentLayout: section.layoutType,\n columnCount: section.properties.column?.count || 1,\n // Always pass the same bookmark ID for all layout chunks of the same section\n sectionBookmarkId: sectionBookmarkId,\n // Pass section title level for TOC scoping (excludes section title from its own TOC)\n sectionTitleLevel: section.sectionTitleLevel,\n },\n };\n\n // Add bookmark start before all section content so TOCs can scope to it\n if (\n sectionBookmarkId &&\n isFirstLayoutOfUserSection &&\n sharedLinkId !== undefined\n ) {\n elements.push(\n new Paragraph({\n children: [new BookmarkStart(sectionBookmarkId, sharedLinkId)],\n spacing: {\n before: 0,\n after: 0,\n line: 0,\n },\n })\n );\n }\n\n // Filter out components with enabled: false and render remaining components (with caching)\n const activeComponents = section.components.filter(\n (m) => !('enabled' in m && m.enabled === false)\n );\n for (const component of activeComponents) {\n const rendered = await renderComponentWithCache(\n component,\n theme,\n themeName,\n sectionContext,\n bypassCache\n );\n elements.push(...rendered);\n }\n\n // Close bookmark after section content\n if (closeBookmark && sharedLinkId !== undefined) {\n elements.push(\n new Paragraph({\n children: [new BookmarkEnd(sharedLinkId)],\n })\n );\n }\n\n // Build section options with headers/footers if defined\n let headers: ISectionOptions['headers'] | undefined;\n let footers: ISectionOptions['footers'] | undefined;\n\n if (section.header || section.footer) {\n if (section.header && section.header !== 'linkToPrevious') {\n const headerComponents = section.header as ComponentDefinition[];\n const headerParagraphs = await renderHeaderFooterComponents(\n headerComponents,\n theme,\n themeName,\n sectionContext\n );\n // If components were provided but produced no paragraphs, still create\n // an empty Header to break Word's default link-to-previous behavior.\n if (headerComponents.length === 0 || headerParagraphs.length > 0) {\n headers = {\n default: createHeaderElement(headerParagraphs),\n };\n }\n }\n\n if (section.footer && section.footer !== 'linkToPrevious') {\n const footerComponents = section.footer as ComponentDefinition[];\n const footerParagraphs = await renderHeaderFooterComponents(\n footerComponents,\n theme,\n themeName,\n sectionContext\n );\n if (footerComponents.length === 0 || footerParagraphs.length > 0) {\n footers = {\n default: createFooterElement(footerParagraphs),\n };\n }\n }\n }\n\n const sectionOptions: ISectionOptions = {\n properties: section.properties,\n children: elements,\n headers,\n footers,\n };\n\n return sectionOptions;\n}\n\n/**\n * Render a single component to Word elements\n */\nexport async function renderComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<(Paragraph | Table | TableOfContents | Textbox)[]> {\n if (isHeadingComponent(component)) {\n return renderHeadingComponent(component, theme, themeName);\n } else if (isParagraphComponent(component)) {\n return renderParagraphComponent(component, theme, themeName);\n } else if (isColumnsComponent(component)) {\n return await renderColumnsComponent(component, theme, themeName, context);\n } else if (isImageComponent(component)) {\n return await renderImageComponent(component, theme, themeName);\n } else if (isTextBoxComponent(component)) {\n return await renderTextBoxComponent(component, theme, themeName, context);\n } else if (isStatisticComponent(component)) {\n return renderStatisticComponent(component, theme);\n } else if (isTableComponent(component)) {\n return await renderTableComponent(component, theme, themeName);\n } else if (isListComponent(component)) {\n return renderListComponent(component, theme, themeName);\n } else if (isTocComponent(component)) {\n return renderTocComponent(component, theme, context);\n } else if (isHighchartsComponent(component)) {\n return await renderHighchartsComponent(\n component,\n theme,\n themeName,\n context\n );\n } else if (isVisualComponent(component)) {\n return await renderVisualComponent(component, theme, themeName, context);\n } else if (isSectionComponent(component)) {\n return await renderSectionComponent(component, theme, themeName, context);\n }\n\n throw new Error(\n `Unknown component type: ${(component as ComponentDefinition).name}`\n );\n}\n","import { readFileSync } from 'fs';\nimport probe from 'probe-image-size';\nimport { resolveFromBaseDir } from './generationContext';\nimport { ImageRun, IFloating } from 'docx';\nimport { parsePercentageStringToFraction } from './widthUtils';\n\nexport interface ImageDimensions {\n width: number;\n height: number;\n}\n\nexport interface CalculatedDimensions {\n width: number;\n height: number;\n}\n\nexport interface ImageBufferResult {\n buffer: Buffer;\n contentType?: string;\n}\n\n/**\n * Parse width value - accepts either number (pixels) or percentage string\n * @param width - Width value as number or percentage string (e.g., \"90%\")\n * @param availableWidthPx - Available document width in pixels\n * @returns Width in pixels\n */\nexport function parseWidthValue(\n width: number | string,\n availableWidthPx: number\n): number {\n if (typeof width === 'number') {\n return width;\n }\n\n // Parse percentage string using shared util while preserving error semantics\n const percentageMatch = (width as string).match(/^(\\d+(?:\\.\\d+)?)%$/);\n if (percentageMatch) {\n const pct = parseFloat(percentageMatch[1]);\n if (pct < 0 || pct > 100) {\n throw new Error(\n `Invalid percentage value: ${width}. Must be between 0% and 100%`\n );\n }\n const fraction = parsePercentageStringToFraction(width as string);\n if (fraction !== undefined) {\n return Math.round(availableWidthPx * fraction);\n }\n }\n\n throw new Error(\n `Invalid width value: ${width}. Expected number (pixels) or percentage string (e.g., \"90%\")`\n );\n}\n\n/**\n * Parse a generic dimension value (number in px or percentage string)\n * @param value - numeric pixels or percentage string (e.g., \"100%\")\n * @param availablePx - available pixels for percentage reference\n */\nexport function parseDimensionValue(\n value: number | string,\n availablePx: number\n): number {\n if (typeof value === 'number') return value;\n const percentageMatch = (value as string).match(/^(\\d+(?:\\.\\d+)?)%$/);\n if (percentageMatch) {\n const pct = parseFloat(percentageMatch[1]);\n if (pct < 0 || pct > 100) {\n throw new Error(\n `Invalid percentage value: ${value}. Must be between 0% and 100%`\n );\n }\n const fraction = parsePercentageStringToFraction(value as string);\n if (fraction !== undefined) return Math.round(availablePx * fraction);\n }\n throw new Error(\n `Invalid dimension value: ${value}. Expected number (pixels) or percentage string (e.g., \"90%\")`\n );\n}\n\n/**\n * Check if a string is a valid URL\n */\nexport function isValidUrl(string: string): boolean {\n try {\n const url = new URL(string);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a string is a base64 data URI\n * Supports format: data:image/[type];base64,[data]\n */\nexport function isBase64Image(string: string): boolean {\n return /^data:image\\/[a-zA-Z+]+;base64,/.test(string);\n}\n\n/**\n * Decode base64 data URI to Buffer\n * @param dataUri - Base64 data URI (e.g., \"data:image/png;base64,iVBORw0KGgo...\")\n * @returns Decoded image buffer\n */\nexport function decodeBase64Image(dataUri: string): Buffer {\n try {\n // Extract the base64 data after the comma\n const base64Data = dataUri.split(',')[1];\n if (!base64Data) {\n throw new Error('Invalid base64 data URI format');\n }\n return Buffer.from(base64Data, 'base64');\n } catch (error) {\n throw new Error(\n `Failed to decode base64 image: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Extract MIME type from base64 data URI\n * @param dataUri - Base64 data URI (e.g., \"data:image/svg+xml;base64,...\")\n * @returns MIME type (e.g., \"image/svg+xml\") or undefined if not found\n */\nexport function extractMimeTypeFromDataUri(\n dataUri: string\n): string | undefined {\n const match = dataUri.match(/^data:(image\\/[a-zA-Z0-9+.-]+);base64,/);\n return match ? match[1] : undefined;\n}\n\n/**\n * Detect image type from file extension\n * @param path - File path or URL\n * @returns Image type (jpg, png, gif, bmp, svg) or undefined\n */\nexport function detectImageTypeFromExtension(\n path: string\n): 'jpg' | 'png' | 'gif' | 'bmp' | 'svg' | undefined {\n const extension = path.toLowerCase().split('.').pop()?.split('?')[0]; // Handle query params in URLs\n switch (extension) {\n case 'jpg':\n case 'jpeg':\n return 'jpg';\n case 'png':\n return 'png';\n case 'gif':\n return 'gif';\n case 'bmp':\n return 'bmp';\n case 'svg':\n return 'svg';\n default:\n return undefined;\n }\n}\n\n/**\n * Detect image type from MIME type\n * @param mimeType - MIME type string (e.g., \"image/svg+xml\", \"image/png\")\n * @returns Image type (jpg, png, gif, bmp, svg) or undefined\n */\nexport function detectImageTypeFromMimeType(\n mimeType: string\n): 'jpg' | 'png' | 'gif' | 'bmp' | 'svg' | undefined {\n const normalized = mimeType.toLowerCase();\n if (normalized.includes('svg')) return 'svg';\n if (normalized.includes('jpeg') || normalized.includes('jpg')) return 'jpg';\n if (normalized.includes('png')) return 'png';\n if (normalized.includes('gif')) return 'gif';\n if (normalized.includes('bmp')) return 'bmp';\n return undefined;\n}\n\n/**\n * Detect image type from path or base64 data URI\n * Prioritizes: response Content-Type > MIME type from base64 > file extension > default to 'png'\n * @param imagePath - File path, URL, or base64 data URI\n * @param responseContentType - Optional Content-Type header from HTTP response\n * @returns Image type (jpg, png, gif, bmp, svg)\n */\nexport function detectImageType(\n imagePath: string,\n responseContentType?: string\n): 'jpg' | 'png' | 'gif' | 'bmp' | 'svg' {\n // Highest priority: Content-Type from HTTP response\n if (responseContentType) {\n const typeFromResponse = detectImageTypeFromMimeType(responseContentType);\n if (typeFromResponse) return typeFromResponse;\n }\n\n // Check if it's a base64 data URI and extract MIME type\n if (isBase64Image(imagePath)) {\n const mimeType = extractMimeTypeFromDataUri(imagePath);\n if (mimeType) {\n const typeFromMime = detectImageTypeFromMimeType(mimeType);\n if (typeFromMime) return typeFromMime;\n }\n }\n\n // Try to detect from file extension\n const typeFromExtension = detectImageTypeFromExtension(imagePath);\n if (typeFromExtension) return typeFromExtension;\n\n // Default to PNG for backward compatibility\n return 'png';\n}\n\n/**\n * Create an ImageRun with correct type handling, including SVG fallback.\n * TODO: SVG fallback uses raw SVG as PNG — works in Word 2016+ which renders\n * SVG natively; fallback won't render correctly in older versions.\n */\nexport function createTypedImageRun(opts: {\n type: 'jpg' | 'png' | 'gif' | 'bmp' | 'svg';\n data: Buffer;\n transformation: { width: number; height: number };\n floating?: IFloating;\n}): ImageRun {\n const base = {\n data: opts.data,\n transformation: opts.transformation,\n ...(opts.floating && { floating: opts.floating }),\n };\n if (opts.type === 'svg') {\n return new ImageRun({\n type: 'svg',\n ...base,\n fallback: { type: 'png', data: opts.data },\n });\n }\n return new ImageRun({ type: opts.type, ...base });\n}\n\n/**\n * Download image from URL and return buffer\n * Uses native fetch with automatic redirect following and proper headers\n */\nexport async function downloadImageFromUrl(\n url: string\n): Promise<ImageBufferResult> {\n try {\n // Create an AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout\n\n const response = await fetch(url, {\n signal: controller.signal,\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; json-to-docx/1.0)',\n },\n redirect: 'follow', // Automatically follow redirects (default behavior)\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(\n `Failed to download image: HTTP ${response.status} ${response.statusText}`\n );\n }\n\n const contentType = response.headers.get('content-type') || undefined;\n\n // Get the response as an ArrayBuffer\n const arrayBuffer = await response.arrayBuffer();\n\n // Convert ArrayBuffer to Buffer\n return { buffer: Buffer.from(arrayBuffer), contentType };\n } catch (error) {\n if (error instanceof Error) {\n // Handle timeout errors\n if (error.name === 'AbortError') {\n throw new Error(\n 'Failed to download image: Request timeout after 10 seconds'\n );\n }\n throw new Error(`Failed to download image from ${url}: ${error.message}`);\n }\n throw new Error(`Failed to download image from ${url}: Unknown error`);\n }\n}\n\n/**\n * Resolve the effective image source string from image component props.\n * Precedence: raw inline `svg` markup (wrapped into an svg data URI) > `base64`\n * data URI > `path` (file/URL). Returns undefined when no source is provided.\n *\n * Raw SVG is encoded as a base64 svg+xml data URI so it flows through the same\n * pipeline as any other source (getImageBuffer / detectImageType / dimensions).\n */\nexport function resolveImageSource(props: {\n svg?: string;\n base64?: string;\n path?: string;\n}): string | undefined {\n const hasValue = (v?: string): v is string =>\n typeof v === 'string' && v.trim().length > 0;\n if (hasValue(props.svg)) {\n const encoded = Buffer.from(props.svg, 'utf-8').toString('base64');\n return `data:image/svg+xml;base64,${encoded}`;\n }\n // Blank base64/path count as absent (matching the source-conflict validator),\n // so a whitespace-only value can't shadow a real later source.\n if (hasValue(props.base64)) return props.base64;\n if (hasValue(props.path)) return props.path;\n return undefined;\n}\n\n/**\n * Get image buffer from base64 data URI, URL, or local file\n */\nexport async function getImageBuffer(\n imagePath: string\n): Promise<ImageBufferResult> {\n // Check for base64 data URI first\n if (isBase64Image(imagePath)) {\n return { buffer: decodeBase64Image(imagePath) };\n }\n // Check for URL\n if (isValidUrl(imagePath)) {\n return await downloadImageFromUrl(imagePath);\n }\n // Otherwise treat as local file path, relative to the document's base\n // directory when the generation scope set one (falls back to cwd, #142).\n return { buffer: readFileSync(resolveFromBaseDir(imagePath)) };\n}\n\n/**\n * Get the dimensions of an image file or URL\n */\nexport async function getImageDimensions(\n imagePath: string\n): Promise<ImageDimensions> {\n try {\n const { buffer: imageBuffer } = await getImageBuffer(imagePath);\n const result = probe.sync(imageBuffer);\n\n if (!result) {\n throw new Error(`Unable to determine dimensions for image: ${imagePath}`);\n }\n\n return {\n width: result.width,\n height: result.height,\n };\n } catch (error) {\n throw new Error(\n `Error reading image dimensions from ${imagePath}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Calculate missing dimension while preserving aspect ratio\n */\nexport function calculateMissingDimension(\n originalWidth: number,\n originalHeight: number,\n targetWidth?: number,\n targetHeight?: number\n): CalculatedDimensions {\n if (targetWidth && targetHeight) {\n // Both dimensions provided, use as-is\n return { width: targetWidth, height: targetHeight };\n }\n\n const aspectRatio = originalWidth / originalHeight;\n\n if (targetWidth && !targetHeight) {\n // Width provided, calculate height\n return {\n width: targetWidth,\n height: Math.round(targetWidth / aspectRatio),\n };\n }\n\n if (!targetWidth && targetHeight) {\n // Height provided, calculate width\n return {\n width: Math.round(targetHeight * aspectRatio),\n height: targetHeight,\n };\n }\n\n // Neither provided, return original dimensions\n return { width: originalWidth, height: originalHeight };\n}\n\n/**\n * Calculate image dimensions with aspect ratio preservation and fallback constraints\n */\nexport async function calculateImageDimensions(\n imagePath: string,\n targetWidth?: number,\n targetHeight?: number,\n fallbackWidth: number = 300,\n fallbackHeight: number = 180\n): Promise<CalculatedDimensions> {\n try {\n const originalDimensions = await getImageDimensions(imagePath);\n return calculateMissingDimension(\n originalDimensions.width,\n originalDimensions.height,\n targetWidth,\n targetHeight\n );\n } catch (error) {\n // If we can't read the image, use fallback logic\n if (targetWidth && targetHeight) {\n return { width: targetWidth, height: targetHeight };\n }\n\n if (targetWidth && !targetHeight) {\n // Use a default aspect ratio (16:9) for fallback\n return { width: targetWidth, height: Math.round((targetWidth * 9) / 16) };\n }\n\n if (!targetWidth && targetHeight) {\n // Use a default aspect ratio (16:9) for fallback\n return {\n width: Math.round((targetHeight * 16) / 9),\n height: targetHeight,\n };\n }\n\n // No dimensions provided and can't read image, use fallback\n return { width: fallbackWidth, height: fallbackHeight };\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { isAbsolute, resolve } from 'node:path';\n\nconst generationDateStorage = new AsyncLocalStorage<Date>();\n\n/** Scope render-time values without leaking them across concurrent documents. */\nexport function runWithGenerationDate<T>(date: Date, callback: () => T): T {\n return generationDateStorage.run(date, callback);\n}\n\n/** Current document date, falling back to the wall clock outside generation. */\nexport function getGenerationDate(): Date {\n return generationDateStorage.getStore() ?? new Date();\n}\n\nconst baseDirStorage = new AsyncLocalStorage<string>();\n\n/**\n * Scope the document base directory for a generation run, so relative asset\n * paths (`image.props.path` et al.) resolve against the document's own\n * location rather than `process.cwd()` (#142). No baseDir → plain callback,\n * preserving the historical cwd-relative behavior.\n */\nexport function runWithBaseDir<T>(\n baseDir: string | undefined,\n callback: () => T\n): T {\n return baseDir === undefined\n ? callback()\n : baseDirStorage.run(resolve(baseDir), callback);\n}\n\n/** The active document base directory, if a generation scope set one. */\nexport function getBaseDir(): string | undefined {\n return baseDirStorage.getStore();\n}\n\n/**\n * Resolve a relative file path against the active base directory. Absolute\n * paths pass through; with no active baseDir the path is returned as-is,\n * which downstream `fs` calls resolve against cwd — the legacy behavior.\n */\nexport function resolveFromBaseDir(filePath: string): string {\n const base = baseDirStorage.getStore();\n if (!base || isAbsolute(filePath)) return filePath;\n return resolve(base, filePath);\n}\n","import {\n IStylesOptions,\n IRunStylePropertiesOptions,\n IParagraphStylePropertiesOptions,\n AlignmentType,\n TabStopPosition,\n} from 'docx';\nimport { getTheme } from '../templates/themes';\nimport type { ThemeConfig } from './index';\nimport { resolveColor } from './utils/colorUtils';\nimport {\n convertLineSpacing,\n pointsToTwips,\n resolveFontProperties,\n mergeFontAndStyleProperties,\n} from './utils/styleHelpers';\n\n// Border types for paragraph borders in theme styles\ninterface ThemeBorderDefinition {\n style: string; // e.g., 'single', 'double', 'dotted', etc.\n size: number; // width in eighths of a point (docx sz)\n color: string; // hex or theme color key\n space?: number; // space in points\n}\n\ninterface ThemeBorders {\n top?: ThemeBorderDefinition;\n bottom?: ThemeBorderDefinition;\n left?: ThemeBorderDefinition;\n right?: ThemeBorderDefinition;\n}\n\n// Style properties for various text elements\ninterface StyleProperties {\n font?: 'heading' | 'body' | 'mono' | 'light';\n size?: number;\n color?: string;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n alignment?: 'left' | 'center' | 'right' | 'justify';\n lineSpacing?: {\n type: 'single' | 'atLeast' | 'exactly' | 'double' | 'multiple';\n value?: number;\n };\n spacing?: {\n before?: number;\n after?: number;\n };\n characterSpacing?: { type: 'condensed' | 'expanded'; value: number };\n scale?: number;\n priority?: number;\n baseStyle?: string;\n followingStyle?: string;\n widowControl?: boolean;\n keepNext?: boolean;\n keepLinesTogether?: boolean;\n outlineLevel?: number;\n borders?: ThemeBorders;\n indent?: {\n left?: number;\n hanging?: number;\n };\n}\n\n/**\n * Type-safe style name union\n */\ntype StyleName =\n | 'normal'\n | 'heading1'\n | 'heading2'\n | 'heading3'\n | 'heading4'\n | 'heading5'\n | 'heading6'\n | 'title'\n | 'subtitle';\n\n/**\n * Type guard to check if a style name is valid\n */\nfunction isValidStyleName(name: string): name is StyleName {\n return [\n 'normal',\n 'heading1',\n 'heading2',\n 'heading3',\n 'heading4',\n 'heading5',\n 'heading6',\n 'title',\n 'subtitle',\n ].includes(name);\n}\n\n/**\n * Type-safe style getter with proper error handling\n */\nfunction getStyleSafe(\n theme: ThemeConfig,\n styleName: string\n): StyleProperties | undefined {\n if (!isValidStyleName(styleName)) {\n console.warn(`Invalid style name: ${styleName}`);\n return undefined;\n }\n return theme.styles?.[styleName] as StyleProperties | undefined;\n}\n\n/**\n * Resolves a style with baseStyle inheritance.\n * If a style has a baseStyle property, recursively resolves the base style first\n * and merges its properties with the current style (current overrides base).\n *\n * @param theme - Theme configuration\n * @param styleName - Name of the style to resolve\n * @param visited - Set of visited style names to prevent circular references\n * @returns Resolved style with all inherited properties, or undefined if not found\n */\nfunction resolveStyleWithBaseStyle(\n theme: ThemeConfig,\n styleName: string,\n visited: Set<string> = new Set()\n): StyleProperties | undefined {\n // Prevent circular references\n if (visited.has(styleName)) {\n console.warn(\n `Circular baseStyle reference detected: ${Array.from(visited).join(\n ' → '\n )} → ${styleName}`\n );\n return undefined;\n }\n\n visited.add(styleName);\n\n // Use type-safe getter instead of type assertion\n const style = getStyleSafe(theme, styleName);\n if (!style) {\n return undefined;\n }\n\n // If no baseStyle, return style as-is\n if (!style.baseStyle) {\n return style;\n }\n\n // Recursively resolve base style\n const baseStyle = resolveStyleWithBaseStyle(\n theme,\n style.baseStyle,\n new Set(visited) // Pass copy to allow different branches\n );\n\n if (!baseStyle) {\n // If baseStyle doesn't exist, just return current style\n return style;\n }\n\n // Merge: base properties first, then override with current style properties\n // Filter out undefined values from current style to preserve base style values\n const mergedStyle = mergeFontAndStyleProperties(\n baseStyle,\n style\n ) as StyleProperties;\n\n // Manually merge properties not covered by mergeFontAndStyleProperties\n // Borders: inherit from baseStyle unless explicitly provided in current style\n if (style.borders === undefined && baseStyle.borders !== undefined) {\n mergedStyle.borders = baseStyle.borders;\n } else if (style.borders !== undefined) {\n mergedStyle.borders = style.borders;\n }\n\n return mergedStyle;\n}\n\nfunction convertAlignment(\n alignment: string\n): (typeof AlignmentType)[keyof typeof AlignmentType] {\n switch (alignment) {\n case 'center':\n return AlignmentType.CENTER;\n case 'right':\n return AlignmentType.RIGHT;\n case 'justify':\n return AlignmentType.JUSTIFIED;\n default:\n return AlignmentType.LEFT;\n }\n}\n\n/**\n * Resolve spacing from new nested format\n */\nfunction resolveSpacing(spacing?: { before?: number; after?: number }): {\n before?: number;\n after?: number;\n} {\n return {\n before: spacing?.before ? pointsToTwips(spacing.before) : undefined,\n after: spacing?.after ? pointsToTwips(spacing.after) : undefined,\n };\n}\n\n/**\n * Convert merged style properties to docx run properties\n */\nfunction convertRunProperties(\n merged: any,\n theme: ThemeConfig,\n defaultColor?: string,\n defaultSize?: number\n): IRunStylePropertiesOptions {\n return {\n font: merged.family || 'Arial',\n size: (merged.size || defaultSize || 11) * 2,\n color: resolveColor(\n merged.color || defaultColor || theme.colors.text,\n theme\n ),\n ...(merged.bold !== undefined && { bold: merged.bold }),\n ...(merged.italic !== undefined && { italic: merged.italic }),\n ...(merged.underline !== undefined &&\n merged.underline && { underline: { type: 'single' } }),\n ...(merged.characterSpacing && {\n characterSpacing:\n merged.characterSpacing.type === 'condensed'\n ? -merged.characterSpacing.value\n : merged.characterSpacing.value,\n }),\n ...(merged.scale && { scale: merged.scale }),\n };\n}\n\n/**\n * Convert merged style properties to docx paragraph properties\n */\nfunction convertParagraphProperties(\n merged: any,\n styleProps?: StyleProperties,\n theme?: ThemeConfig\n): IParagraphStylePropertiesOptions {\n return {\n spacing: {\n ...resolveSpacing(merged.spacing),\n ...convertLineSpacing(merged.lineSpacing),\n },\n alignment: convertAlignment(merged.alignment || 'left'),\n ...(styleProps?.keepNext !== undefined && {\n keepNext: styleProps.keepNext,\n }),\n ...(styleProps?.keepLinesTogether !== undefined && {\n keepLines: styleProps.keepLinesTogether,\n }),\n ...(styleProps?.widowControl !== undefined && {\n widowControl: styleProps.widowControl,\n }),\n ...(styleProps?.outlineLevel !== undefined && {\n outlineLevel: styleProps.outlineLevel,\n }),\n ...(styleProps?.borders &&\n theme && {\n border: convertBorders(styleProps.borders, theme),\n }),\n ...(styleProps?.indent && {\n indent: {\n ...(styleProps.indent.left !== undefined && {\n left: styleProps.indent.left,\n }),\n ...(styleProps.indent.hanging !== undefined && {\n hanging: styleProps.indent.hanging,\n }),\n },\n }),\n } as IParagraphStylePropertiesOptions;\n}\n\n/**\n * Convert theme border definitions to docx paragraph border options\n */\nfunction convertBorders(\n borders: ThemeBorders | undefined,\n theme: ThemeConfig\n):\n | {\n top?: { style: string; size: number; color: string; space?: number };\n bottom?: { style: string; size: number; color: string; space?: number };\n left?: { style: string; size: number; color: string; space?: number };\n right?: { style: string; size: number; color: string; space?: number };\n }\n | undefined {\n if (!borders) return undefined;\n\n const mapSide = (side?: ThemeBorderDefinition) =>\n side\n ? {\n style: side.style,\n size: side.size,\n color: resolveColor(side.color, theme),\n ...(side.space !== undefined ? { space: side.space } : {}),\n }\n : undefined;\n\n const top = mapSide(borders.top);\n const bottom = mapSide(borders.bottom);\n const left = mapSide(borders.left);\n const right = mapSide(borders.right);\n\n const anyDefined = top || bottom || left || right;\n return anyDefined\n ? {\n ...(top && { top }),\n ...(bottom && { bottom }),\n ...(left && { left }),\n ...(right && { right }),\n }\n : undefined;\n}\n\nexport interface WordStyleDefinition {\n id: string;\n name: string;\n basedOn?: string;\n next?: string;\n quickFormat?: boolean;\n run?: IRunStylePropertiesOptions;\n paragraph?: IParagraphStylePropertiesOptions;\n}\n\n/**\n * Creates Word document styles from theme configuration\n * @param themeNameOrObject The theme to use for styling (name string or theme object)\n * @returns IStylesOptions for docx Document\n */\nexport function createWordStyles(\n themeNameOrObject: string | ThemeConfig = 'minimal',\n language?: string\n): IStylesOptions {\n const theme: ThemeConfig =\n typeof themeNameOrObject === 'string'\n ? getTheme(themeNameOrObject) || getTheme('minimal')!\n : themeNameOrObject;\n\n const paragraphStyles: WordStyleDefinition[] = [\n // Normal body text style\n {\n id: 'Normal',\n name: 'Normal',\n quickFormat: true,\n run: (() => {\n const normalStyle =\n resolveStyleWithBaseStyle(theme, 'normal') || theme.styles?.normal;\n const fontProps = resolveFontProperties(theme, normalStyle?.font);\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: normalStyle?.size,\n color: normalStyle?.color,\n bold: normalStyle?.bold,\n italic: normalStyle?.italic,\n underline: normalStyle?.underline,\n characterSpacing: normalStyle?.characterSpacing,\n scale: normalStyle?.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.text);\n })(),\n paragraph: (() => {\n const normalStyle =\n resolveStyleWithBaseStyle(theme, 'normal') || theme.styles?.normal;\n const fontProps = resolveFontProperties(theme, normalStyle?.font);\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: normalStyle?.alignment,\n lineSpacing: normalStyle?.lineSpacing,\n spacing: normalStyle?.spacing,\n });\n\n return convertParagraphProperties(merged, normalStyle, theme);\n })(),\n },\n ];\n\n // Generate heading styles from theme configuration\n for (let i = 1; i <= 6; i++) {\n const headingKey = `heading${i}` as keyof typeof theme.styles;\n const rawHeadingStyle = theme.styles?.[headingKey] as\n | StyleProperties\n | undefined;\n\n if (rawHeadingStyle) {\n const headingStyle =\n resolveStyleWithBaseStyle(theme, headingKey) || rawHeadingStyle;\n paragraphStyles.push({\n id: `Heading${i}`,\n name: `Heading ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n headingStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: headingStyle.size,\n color: headingStyle.color,\n bold: headingStyle.bold,\n italic: headingStyle.italic,\n underline: headingStyle.underline,\n characterSpacing: headingStyle.characterSpacing,\n scale: headingStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.primary, 20);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n headingStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: headingStyle.alignment,\n lineSpacing: headingStyle.lineSpacing,\n spacing: headingStyle.spacing,\n });\n\n return convertParagraphProperties(merged, headingStyle, theme);\n })(),\n });\n } else {\n // Fallback heading style if not defined in theme\n const fontProps = resolveFontProperties(theme, 'heading');\n paragraphStyles.push({\n id: `Heading${i}`,\n name: `Heading ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: {\n font: fontProps.family || 'Arial',\n size: (fontProps.size || 20) * 2,\n color: resolveColor(fontProps.color || theme.colors.primary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n ...(fontProps.underline !== undefined &&\n fontProps.underline && { underline: { type: 'single' } }),\n },\n paragraph: {\n spacing: {\n before: 240 - (i - 1) * 40,\n after: 120 - (i - 1) * 20,\n ...convertLineSpacing(fontProps.lineSpacing),\n },\n alignment: convertAlignment(fontProps.alignment || 'left'),\n },\n });\n }\n }\n\n // Generate display-only heading styles for text components (non-TOC, non-outline)\n for (let i = 1; i <= 6; i++) {\n const headingKey = `heading${i}` as keyof typeof theme.styles;\n const rawHeadingStyle = theme.styles?.[headingKey] as\n | StyleProperties\n | undefined;\n\n if (rawHeadingStyle) {\n const headingStyle =\n resolveStyleWithBaseStyle(theme, `heading${i}`) || rawHeadingStyle;\n\n paragraphStyles.push({\n id: `JTD_HeadingText${i}`,\n name: `Heading Text ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: false,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n headingStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: headingStyle.size,\n color: headingStyle.color,\n bold: headingStyle.bold,\n italic: headingStyle.italic,\n underline: headingStyle.underline,\n characterSpacing: headingStyle.characterSpacing,\n scale: headingStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.primary, 20);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n headingStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: headingStyle.alignment,\n lineSpacing: headingStyle.lineSpacing,\n spacing: headingStyle.spacing,\n });\n\n // Explicitly drop outlineLevel to avoid TOC participation\n return convertParagraphProperties(\n merged,\n { ...(headingStyle as any), outlineLevel: undefined },\n theme\n );\n })(),\n });\n } else {\n // Fallback display heading style mirrors fallback heading visuals\n const fontProps = resolveFontProperties(theme, 'heading');\n paragraphStyles.push({\n id: `JTD_HeadingText${i}`,\n name: `Heading Text ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: false,\n run: {\n font: fontProps.family || 'Arial',\n size: (fontProps.size || 20) * 2,\n color: resolveColor(fontProps.color || theme.colors.primary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n ...(fontProps.underline !== undefined &&\n fontProps.underline && { underline: { type: 'single' } }),\n },\n paragraph: {\n spacing: {\n before: 240 - (i - 1) * 40,\n after: 120 - (i - 1) * 20,\n ...convertLineSpacing(fontProps.lineSpacing),\n },\n alignment: convertAlignment(fontProps.alignment || 'left'),\n },\n });\n }\n }\n\n // Add Title style from theme configuration\n if (theme.styles?.title) {\n const titleStyle =\n resolveStyleWithBaseStyle(theme, 'title') || theme.styles.title;\n paragraphStyles.push({\n id: 'Title',\n name: 'Title',\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n titleStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: titleStyle.size,\n color: titleStyle.color,\n bold: titleStyle.bold,\n italic: titleStyle.italic,\n underline: titleStyle.underline,\n characterSpacing: titleStyle.characterSpacing,\n scale: titleStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.primary, 20);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n titleStyle.font || 'heading'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: titleStyle.alignment,\n lineSpacing: titleStyle.lineSpacing,\n spacing: titleStyle.spacing,\n });\n\n return convertParagraphProperties(merged, titleStyle, theme);\n })(),\n });\n } else {\n // Fallback title style if no theme configuration\n const fontProps = resolveFontProperties(theme, 'heading');\n paragraphStyles.push({\n id: 'Title',\n name: 'Title',\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: {\n font: fontProps.family || 'Arial',\n size: (fontProps.size || 20) * 2,\n color: resolveColor(fontProps.color || theme.colors.primary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n ...(fontProps.underline !== undefined &&\n fontProps.underline && { underline: { type: 'single' } }),\n },\n paragraph: {\n spacing: {\n after: 400,\n ...convertLineSpacing(fontProps.lineSpacing),\n },\n alignment: convertAlignment(fontProps.alignment || 'left'),\n },\n });\n }\n\n // Add Subtitle style from theme configuration\n if (theme.styles?.subtitle) {\n const subtitleStyle =\n resolveStyleWithBaseStyle(theme, 'subtitle') || theme.styles.subtitle;\n paragraphStyles.push({\n id: 'Subtitle',\n name: 'Subtitle',\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n subtitleStyle.font || 'body'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: subtitleStyle.size,\n color: subtitleStyle.color,\n bold: subtitleStyle.bold,\n italic: subtitleStyle.italic,\n underline: subtitleStyle.underline,\n characterSpacing: subtitleStyle.characterSpacing,\n scale: subtitleStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.secondary);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n subtitleStyle.font || 'body'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: subtitleStyle.alignment,\n lineSpacing: subtitleStyle.lineSpacing,\n spacing: subtitleStyle.spacing,\n });\n\n return convertParagraphProperties(merged, subtitleStyle, theme);\n })(),\n });\n } else {\n // Fallback subtitle style if no theme configuration\n const fontProps = resolveFontProperties(theme, 'body');\n paragraphStyles.push({\n id: 'Subtitle',\n name: 'Subtitle',\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: true,\n run: {\n font: fontProps.family || 'Arial',\n size: (fontProps.size || 11) * 2,\n color: resolveColor(fontProps.color || theme.colors.secondary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n ...(fontProps.underline !== undefined &&\n fontProps.underline && { underline: { type: 'single' } }),\n },\n paragraph: {\n spacing: {\n after: 600,\n ...convertLineSpacing(fontProps.lineSpacing),\n },\n alignment: convertAlignment(fontProps.alignment || 'left'),\n },\n });\n }\n\n paragraphStyles.push(\n // Header style\n (() => {\n const fontProps = resolveFontProperties(theme, 'body');\n return {\n id: 'Header',\n name: 'Header',\n basedOn: 'Normal',\n next: 'Header',\n quickFormat: false,\n run: {\n font: fontProps.family || 'Arial',\n size: 20, // 10pt (override default)\n color: resolveColor(fontProps.color || theme.colors.secondary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n },\n paragraph: {\n alignment: 'right',\n },\n };\n })(),\n\n // Footer style\n (() => {\n const fontProps = resolveFontProperties(theme, 'body');\n return {\n id: 'Footer',\n name: 'Footer',\n basedOn: 'Normal',\n next: 'Footer',\n quickFormat: false,\n run: {\n font: fontProps.family || 'Arial',\n size: 18, // 9pt (override default)\n color: resolveColor(fontProps.color || theme.colors.secondary, theme),\n ...(fontProps.bold !== undefined && { bold: fontProps.bold }),\n ...(fontProps.italic !== undefined && { italic: fontProps.italic }),\n },\n paragraph: {\n spacing: {\n before: 120,\n },\n alignment: 'center',\n // Note: Borders are applied at the paragraph instance level, not in style definitions\n },\n };\n })()\n );\n\n // Process custom styles (any additional keys in theme.styles beyond predefined ones)\n const predefinedStyleKeys = new Set([\n 'normal',\n 'heading1',\n 'heading2',\n 'heading3',\n 'heading4',\n 'heading5',\n 'heading6',\n 'title',\n 'subtitle',\n ]);\n\n if (theme.styles) {\n for (const [styleKey, styleValue] of Object.entries(theme.styles)) {\n // Skip predefined styles (already processed above)\n if (predefinedStyleKeys.has(styleKey)) {\n continue;\n }\n\n // Skip if styleValue is not defined\n if (!styleValue) {\n continue;\n }\n\n // Generate Word-compatible style ID and name\n // Special-case TOC styles to the canonical Word display name (e.g., 'TOC 1')\n const tocMatch = /^TOC([1-9])$/.exec(styleKey);\n\n // For TOC styles, DO NOT resolve baseStyle inheritance to prevent coupling with Heading styles\n // TOC styles should only use their explicitly defined properties\n const customStyle = tocMatch\n ? styleValue\n : resolveStyleWithBaseStyle(theme, styleKey) || styleValue;\n // Use a namespaced ID for TOC styles to avoid any accidental ID collisions\n const styleId = tocMatch ? `JTD_TOC${tocMatch[1]}` : styleKey;\n const styleName = tocMatch\n ? `TOC ${tocMatch[1]}`\n : styleKey.replace(/([A-Z])/g, ' $1').trim(); // Convert camelCase/PascalCase to Title Case\n\n // Helper: map baseStyle (theme key) to Word style ID\n const mapBaseStyleId = (base?: string) => {\n if (!base) return 'Normal';\n const lower = base.toLowerCase();\n if (lower === 'normal') return 'Normal';\n if (lower === 'title') return 'Title';\n if (lower === 'subtitle') return 'Subtitle';\n const m = lower.match(/^heading([1-6])$/);\n if (m) return `Heading${m[1]}`;\n // Assume custom style ID (already registered with same id)\n return base;\n };\n\n paragraphStyles.push({\n id: styleId,\n name: styleName,\n basedOn: tocMatch\n ? 'Normal'\n : mapBaseStyleId((customStyle as StyleProperties).baseStyle),\n next: customStyle.followingStyle || 'Normal',\n quickFormat: tocMatch\n ? false\n : customStyle.priority !== undefined\n ? true\n : false,\n run: (() => {\n const fontProps = resolveFontProperties(\n theme,\n customStyle.font || 'body'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n size: customStyle.size,\n color: customStyle.color,\n bold: customStyle.bold,\n italic: customStyle.italic,\n underline: customStyle.underline,\n characterSpacing: customStyle.characterSpacing,\n scale: customStyle.scale,\n });\n\n return convertRunProperties(merged, theme, theme.colors.text);\n })(),\n paragraph: (() => {\n const fontProps = resolveFontProperties(\n theme,\n customStyle.font || 'body'\n );\n const merged = mergeFontAndStyleProperties(fontProps, {\n alignment: customStyle.alignment,\n lineSpacing: customStyle.lineSpacing,\n spacing: customStyle.spacing,\n });\n\n // Build base properties using converter\n const baseProps = convertParagraphProperties(\n merged,\n // Don't pass outlineLevel for TOC styles\n tocMatch\n ? { ...customStyle, outlineLevel: undefined }\n : customStyle,\n theme\n );\n\n // Add TOC-specific tab stops if needed\n const tabStops = (customStyle as any).tabStops;\n const defaultTocTabStops = tocMatch\n ? [{ type: 'right', position: 'max', leader: 'none' }]\n : undefined;\n const effectiveTabStops =\n tabStops && tabStops.length > 0 ? tabStops : defaultTocTabStops;\n\n return {\n ...baseProps,\n ...(effectiveTabStops && {\n tabStops: effectiveTabStops.map((ts: any) => ({\n type: ts.type,\n position:\n ts.position === 'max' ? TabStopPosition.MAX * 2 : ts.position,\n ...(ts.leader && { leader: ts.leader }),\n })),\n }),\n } as IParagraphStylePropertiesOptions;\n })(),\n });\n }\n }\n\n // Generate TOC level styles (TOC 1..6) using fixed, sober defaults.\n // These defaults do not depend on theme heading styles.\n for (let i = 1; i <= 6; i++) {\n // Skip if user already provided a custom TOC style via theme.styles (id must be 'TOC1'..'TOC6')\n if (\n theme.styles &&\n Object.prototype.hasOwnProperty.call(theme.styles, `TOC${i}`)\n ) {\n continue;\n }\n\n paragraphStyles.push({\n // Use a namespaced ID but canonical display name\n id: `JTD_TOC${i}`,\n name: `TOC ${i}`,\n basedOn: 'Normal',\n next: 'Normal',\n quickFormat: false,\n run: {\n font: 'Arial',\n size: 22, // 11pt\n color: resolveColor(theme.colors.text, theme),\n },\n paragraph: {\n spacing: {\n ...resolveSpacing({ before: 0, after: 6 }), // 0pt before, 6pt after\n },\n alignment: convertAlignment('left'),\n // Increase left indent per level for visual hierarchy\n indent: { left: (i - 1) * 360 }, // 0.25\" per level (360 twips)\n },\n });\n }\n\n return {\n paragraphStyles: paragraphStyles as WordStyleDefinition[], // Cast needed due to docx typing\n // Document-default proofing language (w:docDefaults/w:rPrDefault). Runs that\n // don't set their own w:lang inherit this, so Word spell-checks the whole\n // document in the requested language unless a component overrides it.\n ...(language && {\n default: {\n document: {\n run: {\n language: { value: language },\n },\n },\n },\n }),\n };\n}\n\n/**\n * Maps section levels to Word style IDs\n */\nexport function getStyleIdForLevel(level: number): string {\n const styleMap: { [key: number]: string } = {\n 1: 'Heading1',\n 2: 'Heading2',\n 3: 'Heading3',\n 4: 'Heading4',\n 5: 'Heading5',\n 6: 'Heading6',\n };\n return styleMap[level] || 'Heading1';\n}\n","/**\n * Cache Module Exports\n * Re-exports format-agnostic cache from shared + local key-generator\n */\n\nexport * from '@json-to-office/shared/cache';\nexport { CacheKeyGenerator } from './key-generator';\n","/**\n * Cache Key Generator\n * Generates deterministic cache keys for components\n */\n\nimport { createHash } from 'crypto';\nimport { ComponentDefinition, RenderContext } from '../types';\nimport { CacheKeyOptions } from '@json-to-office/shared/cache';\n\n/**\n * Cache key generator with deterministic hashing\n */\nexport class CacheKeyGenerator {\n private readonly version: string;\n\n constructor(version: string = '1.0') {\n this.version = version;\n }\n\n /**\n * Generate cache key for a component\n */\n generateKey(\n component: ComponentDefinition,\n context: RenderContext,\n options: CacheKeyOptions = {}\n ): string {\n const parts: string[] = [\n this.version,\n component.name,\n this.hashProps(component.props),\n ];\n\n if (options.includeTheme !== false) {\n parts.push(context.theme.name);\n }\n\n if (options.includeContext) {\n parts.push(this.hashContext(context));\n }\n\n if (options.additionalKeys) {\n parts.push(...options.additionalKeys);\n }\n\n if (options.version) {\n parts.push(options.version);\n }\n\n return parts.join(':');\n }\n\n /**\n * Hash component props\n */\n hashProps(props: any): string {\n if (!props) return 'null';\n\n // Sort keys for consistent hashing\n const normalized = this.normalizeObject(props);\n const json = JSON.stringify(normalized);\n\n return this.hash(json);\n }\n\n /**\n * Hash render context\n */\n private hashContext(context: RenderContext): string {\n // Only hash relevant context properties\n const relevant = {\n theme: context.theme.name,\n document: context.document,\n // Exclude runtime properties like sectionIndex, componentIndex\n };\n\n return this.hash(JSON.stringify(relevant));\n }\n\n /**\n * Normalize object for consistent hashing\n */\n private normalizeObject(obj: any): any {\n if (obj === null || obj === undefined) return obj;\n\n if (Array.isArray(obj)) {\n return obj.map((item) => this.normalizeObject(item));\n }\n\n if (obj instanceof Date) {\n return obj.toISOString();\n }\n\n if (typeof obj === 'object') {\n const sorted: any = {};\n const keys = Object.keys(obj).sort();\n\n for (const key of keys) {\n sorted[key] = this.normalizeObject(obj[key]);\n }\n\n return sorted;\n }\n\n return obj;\n }\n\n /**\n * Create hash\n */\n private hash(input: string): string {\n return createHash('sha256').update(input).digest('hex').substring(0, 16); // Use first 16 chars for shorter keys\n }\n}\n","/**\n * Revision (tracked-change) rendering utilities\n *\n * Turns `revision.segments` from the JSON definition into native Word\n * revision runs (w:ins / w:del) via docx.js InsertedTextRun / DeletedTextRun.\n */\n\nimport { TextRun, InsertedTextRun, DeletedTextRun } from 'docx';\nimport type { IRunOptions, ParagraphChild } from 'docx';\nimport type { Revision } from '@json-to-office/shared-docx';\nimport { normalizeUnicodeText } from './unicode';\nimport { processTextWithPlaceholders } from './placeholderProcessor';\nimport type { TextStyle } from './textParser';\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nexport const DEFAULT_REVISION_AUTHOR = 'json-to-office';\n// Deterministic fallback so identical inputs produce byte-identical XML\nexport const DEFAULT_REVISION_DATE = '1970-01-01T00:00:00Z';\n\n/**\n * OOXML requires a numeric id on every w:ins / w:del element, unique within\n * one document. Async-local state gives each render its own deterministic\n * counter without collisions when documents render concurrently.\n */\nclass RevisionIdRegistry {\n private fallbackCounter = 0;\n private readonly scopes = new AsyncLocalStorage<{ counter: number }>();\n\n runScoped<T>(callback: () => T): T {\n return this.scopes.run({ counter: 0 }, callback);\n }\n\n next(): number {\n const state = this.scopes.getStore();\n if (state) {\n state.counter += 1;\n return state.counter;\n }\n this.fallbackCounter += 1;\n return this.fallbackCounter;\n }\n\n /** Test-only: deterministic ids for snapshot assertions. */\n clear(): void {\n const state = this.scopes.getStore();\n if (state) {\n state.counter = 0;\n } else {\n this.fallbackCounter = 0;\n }\n }\n}\n\nexport const globalRevisionIdRegistry = new RevisionIdRegistry();\n\nexport type RevisionRun = TextRun | InsertedTextRun | DeletedTextRun;\n\nconst PLACEHOLDER_PATTERN = /\\{[^}]+\\}/;\n\ntype RevisionBaseStyle = Omit<IRunOptions, 'text' | 'children'>;\n\n/**\n * Build the runs for one segment, splitting on '\\n' so line breaks render\n * as <w:br/> (mirroring createTextRunsWithNewlines on the normal path).\n */\nfunction segmentRuns(\n text: string,\n makeRun: (options: IRunOptions) => RevisionRun\n): RevisionRun[] {\n const lines = text.split('\\n');\n return lines.map((line, index) =>\n makeRun(index === 0 ? { text: line } : { text: line, break: 1 })\n );\n}\n\n/**\n * Build paragraph children from revision segments.\n *\n * Segment text is rendered literally (no markdown parsing): a `**` opened in\n * one segment could close in another, so decorator parsing cannot work\n * per-segment. The diff engine strips markdown before diffing for this\n * reason. Placeholders ({DATE}, {PAGE}, ...) are resolved for unchanged\n * segments; inside inserted/deleted text they render literally (the diff\n * summary reports those).\n */\nexport function createRevisionRuns(\n revision: Revision,\n baseStyle: RevisionBaseStyle\n): ParagraphChild[] {\n const author = revision.author || DEFAULT_REVISION_AUTHOR;\n const date = revision.date || DEFAULT_REVISION_DATE;\n\n const runs: ParagraphChild[] = [];\n for (const segment of revision.segments) {\n if (!segment.text) continue;\n const text = normalizeUnicodeText(segment.text);\n\n if (segment.type === 'insert') {\n runs.push(\n ...segmentRuns(\n text,\n (options) =>\n new InsertedTextRun({\n ...options,\n ...baseStyle,\n id: globalRevisionIdRegistry.next(),\n author,\n date,\n })\n )\n );\n } else if (segment.type === 'delete') {\n runs.push(\n ...segmentRuns(\n text,\n (options) =>\n new DeletedTextRun({\n ...options,\n ...baseStyle,\n id: globalRevisionIdRegistry.next(),\n author,\n date,\n })\n )\n );\n } else if (PLACEHOLDER_PATTERN.test(text)) {\n // Unchanged text keeps full placeholder fidelity ({DATE}, {PAGE}, ...)\n runs.push(\n ...processTextWithPlaceholders(text, baseStyle as TextStyle, {})\n );\n } else {\n runs.push(\n ...segmentRuns(\n text,\n (options) => new TextRun({ ...options, ...baseStyle })\n )\n );\n }\n }\n return runs;\n}\n\n/**\n * True when a component carries revision data anywhere in its subtree\n * (own props, list items, or any descendant), meaning its render output\n * embeds document-scoped revision ids and must not be served from the\n * cross-document component cache.\n */\nexport function componentHasRevision(component: {\n props?: unknown;\n children?: unknown[];\n}): boolean {\n const props = component.props as Record<string, unknown> | undefined;\n if (props) {\n if (props.revision) return true;\n const items = props.items;\n if (Array.isArray(items)) {\n if (\n items.some(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n 'revision' in item &&\n (item as { revision?: unknown }).revision\n )\n ) {\n return true;\n }\n }\n }\n const children = component.children;\n if (Array.isArray(children)) {\n return children.some(\n (child) =>\n typeof child === 'object' &&\n child !== null &&\n componentHasRevision(child as { props?: unknown; children?: unknown[] })\n );\n }\n return false;\n}\n","/**\n * Normalize text to NFC so composed accented characters are preserved\n * consistently across DOCX renderers (including LibreOffice).\n */\nexport function normalizeUnicodeText(text: string | null | undefined): string {\n return (text ?? '').normalize('NFC');\n}\n","/**\n * Placeholder Processing System\n * Handles dynamic content replacement in text with support for rich text formatting\n */\n\nimport {\n TextRun,\n PageNumber,\n ExternalHyperlink,\n InternalHyperlink,\n} from 'docx';\nimport {\n parseTextWithDecorators,\n buildRunCommonProps,\n buildTextRuns,\n TextStyle,\n} from './textParser';\nimport { normalizeUnicodeText } from './unicode';\nimport { getGenerationDate } from './generationContext';\n\n// Type alias for elements that can appear in a paragraph\nexport type PlaceholderChild = TextRun | ExternalHyperlink | InternalHyperlink;\n\n/**\n * Placeholder handler function type\n */\nexport type PlaceholderHandler = (\n _context?: PlaceholderContext\n) => PlaceholderChild | PlaceholderChild[] | string;\n\n/**\n * Context passed to placeholder handlers\n */\nexport interface PlaceholderContext {\n style?: TextStyle;\n date?: Date;\n [key: string]: unknown;\n}\n\nfunction styledPlaceholderText(\n text: string,\n context?: PlaceholderContext\n): TextRun {\n return new TextRun({\n text,\n font: context?.style?.font,\n size: context?.style?.size,\n color: context?.style?.color,\n bold: context?.style?.bold,\n italics: context?.style?.italics,\n underline: context?.style?.underline,\n language: context?.style?.language,\n noProof: context?.style?.noProof,\n });\n}\n\nfunction placeholderDate(context?: PlaceholderContext): Date {\n return context?.date ?? getGenerationDate();\n}\n\nfunction isoDate(date: Date): string {\n return date.toISOString().slice(0, 10);\n}\n\nfunction isoDateTime(date: Date): string {\n return date\n .toISOString()\n .replace('T', ' ')\n .replace(/\\.\\d{3}Z$/, 'Z');\n}\n\n/**\n * Placeholder registry for managing dynamic content\n */\nexport class PlaceholderRegistry {\n private static handlers = new Map<string, PlaceholderHandler>();\n\n /**\n * Register a placeholder handler\n */\n static register(name: string, handler: PlaceholderHandler): void {\n this.handlers.set(name.toUpperCase(), handler);\n }\n\n /**\n * Get a placeholder handler\n */\n static get(name: string): PlaceholderHandler | undefined {\n return this.handlers.get(name.toUpperCase());\n }\n\n /**\n * Check if a placeholder is registered\n */\n static has(name: string): boolean {\n return this.handlers.has(name.toUpperCase());\n }\n\n /**\n * Get all registered placeholder names\n */\n static getRegisteredNames(): string[] {\n return Array.from(this.handlers.keys());\n }\n\n /**\n * Clear all registered placeholders\n */\n static clear(): void {\n this.handlers.clear();\n }\n}\n\n/**\n * Process text containing placeholders and return array of paragraph children\n */\nexport function processPlaceholders(\n text: string,\n baseStyle: TextStyle = {},\n context: PlaceholderContext = {}\n): PlaceholderChild[] {\n const normalizedText = normalizeUnicodeText(text);\n const placeholderRegex = /\\{([^}]+)\\}/g;\n const result: PlaceholderChild[] = [];\n let lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = placeholderRegex.exec(normalizedText)) !== null) {\n const beforeText = normalizedText.substring(lastIndex, match.index);\n const placeholderName = match[1];\n\n // Add text before placeholder\n if (beforeText) {\n result.push(...parseTextWithDecorators(beforeText, baseStyle));\n }\n\n // Process placeholder\n const handler = PlaceholderRegistry.get(placeholderName);\n if (handler) {\n const placeholderResult = handler({ ...context, style: baseStyle });\n\n if (Array.isArray(placeholderResult)) {\n result.push(...placeholderResult);\n } else if (typeof placeholderResult === 'string') {\n result.push(...parseTextWithDecorators(placeholderResult, baseStyle));\n } else {\n result.push(placeholderResult);\n }\n } else {\n // Unknown placeholder - keep as text\n result.push(...parseTextWithDecorators(match[0], baseStyle));\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text\n if (lastIndex < normalizedText.length) {\n const remainingText = normalizedText.substring(lastIndex);\n result.push(...parseTextWithDecorators(remainingText, baseStyle));\n }\n\n // If no placeholders found, process as normal text\n if (result.length === 0) {\n result.push(...parseTextWithDecorators(normalizedText, baseStyle));\n }\n\n return result;\n}\n\n/**\n * Process text with both decorators and placeholders\n */\nexport function processTextWithPlaceholders(\n text: string,\n baseStyle: TextStyle = {},\n context: PlaceholderContext = {},\n noProofWords?: string[]\n): PlaceholderChild[] {\n const normalizedText = normalizeUnicodeText(text);\n // Use a more sophisticated approach to handle both decorators and placeholders\n // This regex captures both markdown decorators and placeholders\n const combinedRegex =\n /(\\*\\*\\*|___)([\\s\\S]*?)\\1|(\\*\\*|__)([\\s\\S]*?)\\3|(\\*|_)([\\s\\S]*?)\\5|\\{([^}]+)\\}/g;\n const result: PlaceholderChild[] = [];\n let lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = combinedRegex.exec(normalizedText)) !== null) {\n // Add any text before the match as plain text\n if (match.index > lastIndex) {\n const beforeText = normalizedText.substring(lastIndex, match.index);\n if (beforeText) {\n result.push(\n ...createTextRunsWithNewlines(beforeText, baseStyle, noProofWords)\n );\n }\n }\n\n // Check if this is a placeholder (group 7)\n if (match[7]) {\n const placeholderName = match[7];\n const handler = PlaceholderRegistry.get(placeholderName);\n if (handler) {\n const placeholderResult = handler({ ...context, style: baseStyle });\n\n if (Array.isArray(placeholderResult)) {\n result.push(...placeholderResult);\n } else if (typeof placeholderResult === 'string') {\n result.push(\n ...createTextRunsWithNewlines(\n placeholderResult,\n baseStyle,\n noProofWords\n )\n );\n } else {\n result.push(placeholderResult);\n }\n } else {\n // Unknown placeholder - keep as text\n result.push(\n ...createTextRunsWithNewlines(match[0], baseStyle, noProofWords)\n );\n }\n } else {\n // This is a decorator match - determine the style\n let decoratedText: string;\n let bold = baseStyle.bold || false;\n let italics = baseStyle.italics || false;\n\n if (match[1] === '***' || match[1] === '___') {\n // Bold + Italic\n decoratedText = match[2];\n bold = true;\n italics = true;\n } else if (match[3] === '**' || match[3] === '__') {\n // Bold\n decoratedText = match[4];\n bold = true;\n } else if (match[5] === '*' || match[5] === '_') {\n // Italic\n decoratedText = match[6];\n italics = true;\n } else {\n // This shouldn't happen with our regex, but just in case\n decoratedText = match[0];\n }\n\n // Recursively process the decorated text (it might contain placeholders)\n const decoratedTextRuns = processTextWithPlaceholders(\n decoratedText,\n {\n ...baseStyle,\n bold,\n italics,\n },\n context\n );\n result.push(...decoratedTextRuns);\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add any remaining text after the last match\n if (lastIndex < normalizedText.length) {\n const remainingText = normalizedText.substring(lastIndex);\n if (remainingText) {\n result.push(\n ...createTextRunsWithNewlines(remainingText, baseStyle, noProofWords)\n );\n }\n }\n\n // If no matches were found, return text runs with newlines\n if (result.length === 0 && normalizedText) {\n result.push(\n ...createTextRunsWithNewlines(normalizedText, baseStyle, noProofWords)\n );\n }\n\n return result;\n}\n\n/**\n * Helper function to create TextRuns with newlines from text\n */\nfunction createTextRunsWithNewlines(\n text: string,\n baseStyle: TextStyle,\n noProofWords?: string[]\n): TextRun[] {\n return buildTextRuns(text, buildRunCommonProps(baseStyle), {\n noProof: baseStyle.noProof,\n noProofWords,\n });\n}\n\n/**\n * Initialize built-in placeholders\n */\nexport function initializeBuiltinPlaceholders(): void {\n // PAGE placeholder\n PlaceholderRegistry.register('PAGE', (context) => {\n return new TextRun({\n children: [PageNumber.CURRENT],\n font: context?.style?.font,\n size: context?.style?.size,\n color: context?.style?.color,\n bold: context?.style?.bold,\n italics: context?.style?.italics,\n underline: context?.style?.underline,\n });\n });\n\n // TOTAL_PAGES placeholder\n PlaceholderRegistry.register('TOTAL_PAGES', (context) => {\n return new TextRun({\n children: [PageNumber.TOTAL_PAGES],\n font: context?.style?.font,\n size: context?.style?.size,\n color: context?.style?.color,\n bold: context?.style?.bold,\n italics: context?.style?.italics,\n underline: context?.style?.underline,\n });\n });\n\n // DATE placeholder\n PlaceholderRegistry.register('DATE', (context) =>\n styledPlaceholderText(isoDate(placeholderDate(context)), context)\n );\n\n // DATETIME placeholder\n PlaceholderRegistry.register('DATETIME', (context) =>\n styledPlaceholderText(isoDateTime(placeholderDate(context)), context)\n );\n\n // YEAR placeholder\n PlaceholderRegistry.register('YEAR', (context) =>\n styledPlaceholderText(\n String(placeholderDate(context).getUTCFullYear()),\n context\n )\n );\n}\n\n// Initialize built-in placeholders\ninitializeBuiltinPlaceholders();\n","import { TextRun, ExternalHyperlink, InternalHyperlink, Tab } from 'docx';\nimport {\n processTextWithPlaceholders,\n type PlaceholderChild,\n type PlaceholderContext,\n} from './placeholderProcessor';\nimport { normalizeUnicodeText } from './unicode';\n\nexport interface TextStyle {\n font?: string;\n size?: number;\n color?: string;\n bold?: boolean;\n italics?: boolean;\n underline?: {\n type?:\n | 'single'\n | 'double'\n | 'thick'\n | 'dotted'\n | 'dash'\n | 'dotDash'\n | 'dotDotDash'\n | 'wave'\n | 'none'\n | 'words'\n | 'dottedHeavy'\n | 'dashedHeavy'\n | 'dashLong'\n | 'dashLongHeavy'\n | 'dashDotHeavy'\n | 'dashDotDotHeavy'\n | 'wavyHeavy'\n | 'wavyDouble';\n color?: string;\n }; // docx library expects an object or undefined, not boolean\n // Character width scaling in percent (w:w). 100 is normal.\n scale?: number;\n // Letter tracking (w:spacing) in twentieths of a point (signed).\n characterSpacing?: number;\n // Proofing language (BCP-47) for the run, e.g. { value: 'fr-FR' }\n language?: {\n value?: string;\n eastAsia?: string;\n bidirectional?: string;\n };\n // Disable spell/grammar checking for the run\n noProof?: boolean;\n}\n\nexport interface TextDecoratorOptions {\n boldColor?: string;\n placeholderContext?: PlaceholderContext;\n enableHyperlinks?: boolean;\n /**\n * \"Known words\" allowlist: each whole-word, case-insensitive occurrence is\n * emitted as its own no-proof run so Word never flags it, while surrounding\n * text stays spell-checked.\n */\n noProofWords?: string[];\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Build a matcher for the known-words allowlist, or null when there's nothing\n * to match. Matches each word as a whole token (no letter/number directly\n * adjacent on either side) so \"Wiseair\" doesn't match inside \"Wiseairy\", while\n * internal punctuation like \"json-to-office\" is matched literally.\n */\nexport function buildNoProofWordsRegex(noProofWords?: string[]): RegExp | null {\n const words = (noProofWords || []).filter((w) => w && w.trim().length > 0);\n if (words.length === 0) return null;\n // Longest first so alternation prefers the most specific match.\n const escaped = words\n .slice()\n .sort((a, b) => b.length - a.length)\n .map(escapeRegExp);\n return new RegExp(\n `(?<![\\\\p{L}\\\\p{N}])(?:${escaped.join('|')})(?![\\\\p{L}\\\\p{N}])`,\n 'giu'\n );\n}\n\n/**\n * Split a plain string into TextRuns, marking every known-word occurrence as a\n * no-proof run via `makeRun`. When there are no known words, returns a single\n * run for the whole text.\n */\nexport function splitByNoProofWords(\n text: string,\n makeRun: (segment: string, noProof: boolean) => TextRun,\n noProofWords?: string[]\n): TextRun[] {\n const regex = buildNoProofWordsRegex(noProofWords);\n if (!regex || !text) return [makeRun(text, false)];\n\n const runs: TextRun[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n runs.push(makeRun(text.slice(lastIndex, match.index), false));\n }\n runs.push(makeRun(match[0], true));\n lastIndex = match.index + match[0].length;\n // Guard against zero-length matches (shouldn't happen, but be safe).\n if (regex.lastIndex === match.index) regex.lastIndex++;\n }\n if (lastIndex < text.length) {\n runs.push(makeRun(text.slice(lastIndex), false));\n }\n return runs.length > 0 ? runs : [makeRun(text, false)];\n}\n\n/**\n * Parses text with inline markdown-style decorators, placeholders, and newlines, returning an array of TextRun objects\n * Supports:\n * - **bold** or __bold__\n * - *italic* or _italic_\n * - ***bold italic*** or ___bold italic___\n * - \\n for line breaks\n * - {PLACEHOLDER} for dynamic content\n * - [link text](url) for hyperlinks (when enableHyperlinks is true)\n *\n * @param text The text to parse\n * @param baseStyle The base style to apply to all text runs\n * @param options Additional options for text decoration\n * @returns Array of TextRun and hyperlink objects with appropriate styling\n */\nexport function parseTextWithDecorators(\n text: string,\n baseStyle: TextStyle = {},\n options: TextDecoratorOptions = {}\n): PlaceholderChild[] {\n // Guard against undefined or null text\n if (!text) {\n return [new TextRun({ text: '', ...baseStyle })];\n }\n const normalizedText = normalizeUnicodeText(text);\n\n // Check if text contains placeholders\n const hasPlaceholders = /\\{[^}]+\\}/.test(normalizedText);\n\n if (hasPlaceholders) {\n // Use new placeholder processor that handles both decorators and placeholders\n return processTextWithPlaceholders(\n normalizedText,\n baseStyle,\n options.placeholderContext || {},\n options.noProofWords\n );\n }\n\n // Process hyperlinks first if enabled\n if (options.enableHyperlinks) {\n return parseTextWithHyperlinks(normalizedText, baseStyle, options);\n }\n\n // Original decorator-only processing\n const runs: PlaceholderChild[] = [];\n\n // Process decorators on the entire text first (including newlines)\n const decoratorRegex =\n /(\\*\\*\\*|___)([\\s\\S]*?)\\1|(\\*\\*|__)([\\s\\S]*?)\\3|(\\*|_)([\\s\\S]*?)\\5/g;\n\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = decoratorRegex.exec(normalizedText)) !== null) {\n // Add any text before the match as plain text (handle newlines)\n if (match.index > lastIndex) {\n const plainText = normalizedText.substring(lastIndex, match.index);\n if (plainText) {\n runs.push(...createTextRunsWithNewlines(plainText, baseStyle, options));\n }\n }\n\n // Determine the style based on the decorator\n let decoratedText: string;\n let bold = baseStyle.bold || false;\n let italics = baseStyle.italics || false;\n\n if (match[1] === '***' || match[1] === '___') {\n // Bold + Italic\n decoratedText = match[2];\n bold = true;\n italics = true;\n } else if (match[3] === '**' || match[3] === '__') {\n // Bold\n decoratedText = match[4];\n bold = true;\n } else if (match[5] === '*' || match[5] === '_') {\n // Italic\n decoratedText = match[6];\n italics = true;\n } else {\n // This shouldn't happen with our regex, but just in case\n decoratedText = match[0];\n }\n\n // Create decorated text runs with newlines\n const decoratedRuns = createTextRunsWithNewlines(\n decoratedText,\n baseStyle,\n options,\n {\n bold,\n italics,\n }\n );\n runs.push(...decoratedRuns);\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add any remaining text after the last match\n if (lastIndex < normalizedText.length) {\n const remainingText = normalizedText.substring(lastIndex);\n if (remainingText) {\n runs.push(\n ...createTextRunsWithNewlines(remainingText, baseStyle, options)\n );\n }\n }\n\n // If no decorators were found, return text runs with newlines\n if (runs.length === 0 && normalizedText) {\n runs.push(\n ...createTextRunsWithNewlines(normalizedText, baseStyle, options)\n );\n }\n\n return runs;\n}\n\n/**\n * Run-level properties shared by every run produced for a piece of text.\n * Single assembly point for both the plain-text and placeholder paths — a\n * prop forwarded here reaches both, so the two cannot drift (issue #137).\n */\nexport function buildRunCommonProps(\n baseStyle: TextStyle,\n overrides?: { bold?: boolean; italics?: boolean; boldColor?: string }\n) {\n const bold = overrides?.bold ?? baseStyle.bold;\n const italics = overrides?.italics ?? baseStyle.italics;\n return {\n ...(baseStyle.font && { font: baseStyle.font }),\n ...(baseStyle.size && { size: baseStyle.size }),\n ...(baseStyle.color && {\n color:\n bold && overrides?.boldColor ? overrides.boldColor : baseStyle.color,\n }),\n ...(bold !== undefined && { bold }),\n ...(italics !== undefined && { italics }),\n ...(baseStyle.underline && { underline: baseStyle.underline }),\n ...(baseStyle.scale && { scale: baseStyle.scale }),\n ...(baseStyle.characterSpacing && {\n characterSpacing: baseStyle.characterSpacing,\n }),\n ...(baseStyle.language && { language: baseStyle.language }),\n };\n}\n\n/**\n * Build the runs for a single line of text: split on `\\t` into real\n * `<w:tab/>` runs (a tab char inside <w:t> would be silently dropped by\n * Word, and paragraph tabStops only apply to real tab runs), emit no-proof\n * word runs, and attach the line break to the first emitted run only.\n */\nfunction buildLineRuns(\n line: string,\n commonProps: ReturnType<typeof buildRunCommonProps>,\n opts: { needsLineBreak: boolean; noProof?: boolean; noProofWords?: string[] }\n): TextRun[] {\n const { needsLineBreak, noProof } = opts;\n // When the whole run is already no-proof, there's nothing to single out,\n // so skip word splitting and emit one run for the line.\n const wholeRunNoProof = noProof === true;\n const wordsForLine = wholeRunNoProof ? undefined : opts.noProofWords;\n\n // The line break belongs only on the first run of the line.\n let firstSegment = true;\n const lineRuns: TextRun[] = [];\n const tabSegments = line.split('\\t');\n tabSegments.forEach((tabSegment, tabIndex) => {\n if (tabIndex > 0) {\n lineRuns.push(\n new TextRun({\n children: [new Tab()],\n ...commonProps,\n ...(needsLineBreak && firstSegment && { break: 1 }),\n })\n );\n firstSegment = false;\n }\n if (!tabSegment && tabSegments.length > 1) return;\n lineRuns.push(\n ...splitByNoProofWords(\n tabSegment,\n (segment, matched) => {\n const run = new TextRun({\n text: segment,\n ...commonProps,\n ...((matched || noProof !== undefined) && {\n noProof: matched || wholeRunNoProof,\n }),\n ...(needsLineBreak && firstSegment && { break: 1 }),\n });\n firstSegment = false;\n return run;\n },\n wordsForLine\n )\n );\n });\n return lineRuns;\n}\n\n/**\n * Turn multi-line text into TextRuns: `\\n` becomes a run break, `\\t` a real\n * tab run, no-proof words their own runs. Shared by the plain-text path\n * (textParser) and the placeholder path (placeholderProcessor) so run-level\n * properties cannot diverge between them.\n */\nexport function buildTextRuns(\n text: string,\n commonProps: ReturnType<typeof buildRunCommonProps>,\n opts: { noProof?: boolean; noProofWords?: string[] } = {}\n): TextRun[] {\n const runs: TextRun[] = [];\n const lines = text.split('\\n');\n\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n const needsLineBreak = lineIndex > 0;\n\n // Create runs even for empty lines if they need a break\n if (line || needsLineBreak) {\n runs.push(\n ...buildLineRuns(line, commonProps, { needsLineBreak, ...opts })\n );\n }\n }\n\n return runs;\n}\n\n/**\n * Helper function to create TextRuns with newlines from text\n */\nfunction createTextRunsWithNewlines(\n text: string,\n baseStyle: TextStyle,\n options: TextDecoratorOptions,\n overrideStyle?: { bold?: boolean; italics?: boolean }\n): TextRun[] {\n return buildTextRuns(\n text,\n buildRunCommonProps(baseStyle, {\n bold: overrideStyle?.bold,\n italics: overrideStyle?.italics,\n boldColor: options.boldColor,\n }),\n { noProof: baseStyle.noProof, noProofWords: options.noProofWords }\n );\n}\n\n/**\n * Parse text with hyperlinks and decorators\n * Supports markdown-style links: [link text](url)\n */\nfunction parseTextWithHyperlinks(\n text: string,\n baseStyle: TextStyle = {},\n options: TextDecoratorOptions = {}\n): PlaceholderChild[] {\n const normalizedText = normalizeUnicodeText(text);\n const runs: PlaceholderChild[] = [];\n\n // Regex to match markdown-style links: [text](url)\n // This regex handles nested brackets in the link text\n const hyperlinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = hyperlinkRegex.exec(normalizedText)) !== null) {\n // Add any text before the hyperlink\n if (match.index > lastIndex) {\n const plainText = normalizedText.substring(lastIndex, match.index);\n if (plainText) {\n // Recursively parse the plain text for decorators\n const plainRuns = parseTextWithDecorators(plainText, baseStyle, {\n ...options,\n enableHyperlinks: false, // Disable hyperlinks in recursive call\n });\n runs.push(...plainRuns);\n }\n }\n\n const linkText = match[1];\n const linkUrl = match[2];\n\n // Determine if this is an internal or external link\n const isInternal = linkUrl.startsWith('#');\n\n // Parse the link text for decorators (bold, italic, etc.)\n const linkTextRuns = parseTextWithDecorators(linkText, baseStyle, {\n ...options,\n enableHyperlinks: false, // Disable hyperlinks in recursive call\n });\n\n // Create the appropriate hyperlink type\n if (isInternal) {\n // Internal link (bookmark)\n const bookmarkId = linkUrl.substring(1); // Remove the # prefix\n runs.push(\n new InternalHyperlink({\n children: linkTextRuns as TextRun[], // Cast needed for docx types\n anchor: bookmarkId,\n })\n );\n } else {\n // External link\n runs.push(\n new ExternalHyperlink({\n children: linkTextRuns as TextRun[], // Cast needed for docx types\n link: linkUrl,\n })\n );\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add any remaining text after the last hyperlink\n if (lastIndex < normalizedText.length) {\n const remainingText = normalizedText.substring(lastIndex);\n if (remainingText) {\n const remainingRuns = parseTextWithDecorators(remainingText, baseStyle, {\n ...options,\n enableHyperlinks: false, // Disable hyperlinks in recursive call\n });\n runs.push(...remainingRuns);\n }\n }\n\n // If no hyperlinks were found, fall back to regular decorator parsing\n if (runs.length === 0 && normalizedText) {\n return parseTextWithDecorators(normalizedText, baseStyle, {\n ...options,\n enableHyperlinks: false,\n });\n }\n\n return runs;\n}\n","/**\n * Cached component rendering system\n * Provides caching layer for component rendering operations\n */\n\nimport { Paragraph, Table, TableOfContents, Textbox } from 'docx';\nimport { ComponentDefinition, RenderContext } from '../types';\nimport { ThemeConfig } from '../styles';\nimport {\n MemoryCache,\n CacheKeyGenerator,\n CacheConfiguration,\n CachedComponent,\n} from '../cache';\nimport { renderComponent } from './render';\nimport { componentHasRevision } from '../utils/revisionUtils';\nimport { getBaseDir, getGenerationDate } from '../utils/generationContext';\nimport { createHash } from 'crypto';\n\n// Global component cache instance\nlet componentCache: MemoryCache | null = null;\nlet cacheKeyGen: CacheKeyGenerator | null = null;\n\n/**\n * Create a hash of the theme configuration for cache key generation\n * This ensures cache invalidation when theme changes\n */\nfunction createThemeHash(theme: ThemeConfig): string {\n // Serialize the theme object to JSON and create a hash\n const themeString = JSON.stringify(theme);\n return createHash('sha256').update(themeString).digest('hex').substring(0, 8);\n}\n\n/**\n * Initialize the component cache\n */\nexport function initializeComponentCache(cache?: MemoryCache): void {\n if (cache) {\n componentCache = cache;\n } else if (!componentCache) {\n // Create a default cache if none provided\n const config: CacheConfiguration = {\n enabled: true,\n evictionPolicy: 'lru',\n memory: {\n enabled: true,\n maxSize: 100, // 100MB for components\n maxEntries: 1000,\n defaultTTL: 3600, // 1 hour\n cleanupInterval: 300, // 5 minutes\n },\n performance: {\n trackMetrics: true,\n metricsSampleRate: 1.0,\n enableWarming: false,\n parallelProcessing: true,\n },\n };\n componentCache = new MemoryCache(config);\n }\n\n if (!cacheKeyGen) {\n cacheKeyGen = new CacheKeyGenerator();\n }\n}\n\n/**\n * Get the component cache instance\n */\nexport function getComponentCache(): MemoryCache | null {\n return componentCache;\n}\n\n/**\n * Clear the component cache\n */\nexport async function clearComponentCache(): Promise<void> {\n if (componentCache) {\n await componentCache.clear();\n }\n}\n\n/**\n * Render a component with caching\n */\nexport async function renderComponentWithCache(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext,\n bypassCache = false\n): Promise<(Paragraph | Table | TableOfContents | Textbox)[]> {\n // Certain components depend on dynamic runtime context and must not be cached.\n // - 'toc' depends on section bookmark IDs generated at render time; caching\n // can produce stale references to non-existent bookmarks on re-render.\n // - 'section' generates document-scoped bookmarks internally; caching would\n // duplicate bookmark IDs across sections.\n // - revision-bearing components embed document-scoped w:ins/w:del ids from\n // a per-render counter; caching would leak ids across documents.\n // - 'visual' rasterizes via the injected services.pptx (an in-process render\n // fn or an HTTP serverUrl) which is NOT part of the cache key; caching by\n // props alone could serve a stale image when the rasterizer differs across\n // renders. The rasterizer keeps its own content-addressed disk cache, so an\n // identical visual is still cheap to re-resolve.\n const forceBypassForType =\n component.name === 'toc' ||\n component.name === 'section' ||\n component.name === 'visual' ||\n component.name === 'heading' ||\n // Both explicit lists and markdown-list paragraphs register numbering in\n // the current document scope. Cached paragraphs can otherwise reference\n // definitions that only existed in a previous render.\n component.name === 'list' ||\n component.name === 'paragraph' ||\n 'id' in component ||\n componentHasRevision(component);\n\n // Initialize cache if needed\n if (!componentCache) {\n initializeComponentCache();\n }\n\n // If cache is disabled or bypassed, render directly\n if (\n !componentCache ||\n bypassCache ||\n forceBypassForType ||\n !componentCache.getConfig().enabled\n ) {\n return renderComponent(component, theme, themeName, context);\n }\n\n // Generate cache key for this component\n // Use theme hash instead of name to ensure cache invalidation on theme changes\n const componentProps = JSON.stringify(component.props || {});\n const themeHash = createThemeHash(theme);\n // Include minimal context for other components that might vary with context\n // For now we add section layout type and column count without exposing\n // bookmark IDs (TOC/section are bypassed above).\n const contextKey = context?.section\n ? `${context.section.currentLayout}:${context.section.columnCount}`\n : 'no-section';\n // Placeholder resolution is scoped to the document metadata/generatedAt\n // date. Include it for every cacheable component because dynamic text can\n // appear inside nested container props (for example a table cell), not only\n // in top-level paragraph components.\n const generationDateKey = getGenerationDate().toISOString();\n // Components that read local assets (images) resolve relative paths against\n // the active baseDir; identical props from different document directories\n // must not share cached bytes (#142).\n const baseDirKey = getBaseDir() ?? '';\n\n // For container components (columns, section, etc.), include children in cache key\n // This ensures cache invalidation when child component content changes\n const childrenKey =\n 'children' in component && component.children\n ? `:children:${JSON.stringify(component.children)}`\n : '';\n\n const cacheKey = `component:${component.name}:${themeHash}:${contextKey}:${generationDateKey}:${baseDirKey}:${componentProps}${childrenKey}`;\n\n // Try to get from cache\n const cached = await componentCache.get(cacheKey);\n\n if (cached) {\n // Cache hit - the cache internally tracks this as a hit\n // Return the rendered result from cache\n return cached.result as (Paragraph | Table | TableOfContents | Textbox)[];\n }\n\n // Cache miss - render the component\n const renderStartTime = Date.now();\n const rendered = await renderComponent(component, theme, themeName, context);\n // Track render time for analytics\n Date.now() - renderStartTime;\n\n // Calculate approximate size (rough estimate)\n const componentSize = JSON.stringify(rendered).length;\n\n // Create a proper CachedComponent structure\n const cachedEntry: CachedComponent = {\n result: rendered as unknown, // Store the rendered Paragraph/Table array as result\n componentName: component.name,\n propsHash: cacheKey,\n timestamp: Date.now(),\n hits: 0,\n size: componentSize,\n dependencies: [],\n signature: cacheKey,\n lastAccessed: Date.now(),\n };\n\n // Store in cache - the cache internally tracks this as a miss\n await componentCache.set(cacheKey, cachedEntry);\n\n return rendered;\n}\n\n// Note: Component statistics are automatically tracked by the cache itself\n// The cache's updateHitStats and updateMissStats methods handle this internally\n\n/**\n * Warm the cache with frequently used components\n */\nexport async function warmComponentCache(\n components: Array<{\n component: ComponentDefinition;\n theme: ThemeConfig;\n themeName: string;\n context: RenderContext;\n }>\n): Promise<void> {\n if (\n !componentCache ||\n !componentCache.getConfig().performance.enableWarming\n ) {\n return;\n }\n\n const warmingPromises = components.map(\n async ({ component, theme, themeName, context }) => {\n await renderComponentWithCache(\n component,\n theme,\n themeName,\n context,\n false\n );\n }\n );\n\n await Promise.all(warmingPromises);\n}\n\n/**\n * Get component cache statistics\n */\nexport function getComponentCacheStats() {\n if (!componentCache) {\n return null;\n }\n\n return componentCache.getStats();\n}\n\n/**\n * Export component cache for persistence\n */\nexport async function exportComponentCache(): Promise<Map<\n string,\n unknown\n> | null> {\n if (!componentCache) {\n return null;\n }\n\n const keys = await componentCache.getKeys();\n const exported = new Map<string, unknown>();\n\n for (const key of keys) {\n const value = await componentCache.get(key);\n if (value) {\n exported.set(key, value);\n }\n }\n\n return exported;\n}\n\n/**\n * Import component cache from persistence\n */\nexport async function importComponentCache(\n data: Map<string, unknown>\n): Promise<void> {\n if (!componentCache) {\n initializeComponentCache();\n }\n\n for (const [key, value] of data.entries()) {\n await componentCache!.set(key, value as CachedComponent);\n }\n}\n","/**\n * Content Creation Functions\n * Pure functions for creating Word document elements without layout concerns\n */\n\nimport {\n Paragraph,\n TextRun,\n Table,\n TableRow,\n TableCell,\n AlignmentType,\n ImageRun,\n PageBreak,\n WidthType,\n BorderStyle,\n Header,\n Footer,\n PageNumber,\n ColumnBreak,\n TableLayoutType,\n VerticalAlign,\n Bookmark,\n} from 'docx';\nimport {\n calculateImageDimensions,\n getImageBuffer,\n parseWidthValue,\n parseDimensionValue,\n detectImageType,\n createTypedImageRun,\n resolveImageSource,\n} from '../utils/imageUtils';\nimport { ThemeConfig } from '../styles';\nimport { getTableStyle } from '../styles';\nimport { getThemeColors, getThemeFonts } from '../themes/defaults';\nimport {\n parseTextWithDecorators,\n splitByNoProofWords,\n} from '../utils/textParser';\nimport {\n processTextWithPlaceholders,\n type PlaceholderChild,\n} from '../utils/placeholderProcessor';\nimport { normalizeUnicodeText } from '../utils/unicode';\nimport { getStyleIdForLevel } from '../styles/themeToDocxAdapter';\nimport { globalBookmarkRegistry } from '../utils/bookmarkRegistry';\nimport { createRevisionRuns } from '../utils/revisionUtils';\nimport type { Revision } from '@json-to-office/shared-docx';\nimport { resolveFontFamily } from '../styles/utils/styleHelpers';\nimport { synthesizeFamilyName } from '@json-to-office/shared';\nimport {\n ComponentDefinition,\n isParagraphComponent,\n ParagraphComponentDefinition,\n isImageComponent,\n ImageComponentDefinition,\n} from '../types';\nimport { resolveColor } from '../styles/utils/colorUtils';\nimport {\n pointsToTwips,\n convertLineSpacing as convertLineSpacingToDocx,\n} from '../styles/utils/styleHelpers';\nimport {\n resolveOffsetTwips,\n getPageWidthTwips,\n getPageHeightTwips,\n getAvailableWidthTwips,\n getAvailableHeightTwips,\n} from '../utils/widthUtils';\n\n/**\n * Resolve (family, bold, italic, fontWeight) into the values the docx lib\n * should receive. For non-RIBBI weights (anything other than 400/700),\n * rewrite the family to the canonical sub-family name (e.g. \"Inter Light\")\n * so Word / LibreOffice can resolve the matching installed face.\n * `bold: true` without fontWeight is shorthand for weight 700.\n */\nfunction applyFontWeightAlias(opts: {\n fontFamily?: string;\n bold?: boolean;\n italic?: boolean;\n fontWeight?: number;\n}): { font?: string; bold?: boolean; italics?: boolean } {\n if (!opts.fontFamily) {\n return { font: undefined, bold: opts.bold, italics: opts.italic };\n }\n const weight = opts.fontWeight ?? (opts.bold === true ? 700 : undefined);\n const synth = synthesizeFamilyName(\n opts.fontFamily,\n weight,\n opts.italic === true\n );\n return { font: synth.family, bold: synth.bold, italics: synth.italic };\n}\n\n/**\n * Combine the document-level known-words allowlist (carried on the theme) with\n * any component-level list, de-duplicated. Returns undefined when empty.\n */\nfunction resolveNoProofWords(\n theme: ThemeConfig,\n optionWords?: string[]\n): string[] | undefined {\n const themeWords = theme.noProofWords;\n const merged = [...(themeWords || []), ...(optionWords || [])];\n return merged.length > 0 ? Array.from(new Set(merged)) : undefined;\n}\n\nexport interface TextOptions {\n style?: string;\n alignment?: 'left' | 'center' | 'right' | 'justify';\n spacing?: {\n before?: number; // in points\n after?: number; // in points\n };\n lineSpacing?:\n | number\n | {\n type: 'single' | 'atLeast' | 'exactly' | 'double' | 'multiple';\n value?: number;\n };\n boldColor?: string;\n columnBreak?: boolean;\n // Font properties\n fontFamily?: string;\n fontSize?: number;\n fontColor?: string;\n bold?: boolean;\n /**\n * Per-run weight (100–900). Renderer picks the closest embedded variant\n * via the font-alias registry and emits the run under a synthetic family\n * (e.g. \"Inter Light\" for 300). Overrides `bold` when set.\n */\n fontWeight?: number;\n italic?: boolean;\n underline?: boolean;\n // Character width scaling in percent (w:w). 100 is normal.\n scale?: number;\n // Letter tracking (w:spacing) — value in twentieths of a point.\n characterSpacing?: { type: 'condensed' | 'expanded'; value: number };\n // Per-run language (BCP-47) for spell/grammar checking. Overrides the\n // document default for these runs.\n language?: string;\n // Disable spell/grammar checking for these runs\n noProof?: boolean;\n // Known-words allowlist: whole-word occurrences are emitted as no-proof runs.\n // Merged with any document-level list carried on the theme.\n noProofWords?: string[];\n // Additional children to prepend (e.g., bookmarks)\n prependChildren?: any[];\n // Outline level for TOC\n outlineLevel?: number;\n // Bookmark ID for internal linking\n bookmarkId?: string;\n // Floating frame properties\n floating?: {\n horizontalPosition?: {\n relative?: 'margin' | 'page' | 'text';\n align?: 'left' | 'center' | 'right' | 'inside' | 'outside';\n offset?: number | string;\n };\n verticalPosition?: {\n relative?: 'margin' | 'page' | 'text';\n align?: 'top' | 'center' | 'bottom' | 'inside' | 'outside' | 'inline';\n offset?: number | string;\n };\n wrap?: {\n type: 'around' | 'none' | 'notBeside' | 'through' | 'tight' | 'auto';\n };\n lockAnchor?: boolean;\n width?: number;\n height?: number;\n };\n // Keep paragraph with next paragraph\n keepNext?: boolean;\n // Keep all lines of paragraph together\n keepLines?: boolean;\n // Paragraph indentation (w:ind) in twips. hanging and firstLine are\n // mutually exclusive (validated upstream).\n indent?: {\n left?: number;\n right?: number;\n hanging?: number;\n firstLine?: number;\n };\n // Tab stops (w:tabs). Tab characters (\\t) in text jump to these positions.\n tabStops?: {\n type: 'left' | 'right' | 'center' | 'decimal' | 'bar';\n position: number;\n leader?: 'dot' | 'hyphen' | 'underscore' | 'middleDot' | 'none';\n }[];\n // Tracked-change segments: when present, text is rendered from these\n // (as native Word revisions) instead of the plain content string\n revision?: Revision;\n}\n\nexport interface ImageOptions {\n caption?: string;\n width?: number | string;\n height?: number | string;\n widthRelativeTo?: 'content' | 'page';\n heightRelativeTo?: 'content' | 'page';\n alignment?: 'left' | 'center' | 'right';\n spacing?: {\n before?: number; // in points\n after?: number; // in points\n };\n floating?: {\n horizontalPosition?: {\n relative?: 'character' | 'column' | 'margin' | 'page' | 'text';\n align?: 'left' | 'center' | 'right' | 'inside' | 'outside';\n offset?: number | string;\n };\n verticalPosition?: {\n relative?: 'margin' | 'page' | 'paragraph' | 'line' | 'text';\n align?: 'top' | 'center' | 'bottom' | 'inside' | 'outside';\n offset?: number | string;\n };\n wrap?: {\n // 'tight', 'around', 'through' are VML-style; only 'none', 'square', 'topAndBottom' are supported for images\n type: 'none' | 'square' | 'topAndBottom' | 'around' | 'tight' | 'through';\n side?: 'bothSides' | 'left' | 'right' | 'largest';\n margins?: {\n top?: number | string;\n bottom?: number | string;\n left?: number | string;\n right?: number | string;\n };\n };\n allowOverlap?: boolean;\n behindDocument?: boolean;\n lockAnchor?: boolean;\n layoutInCell?: boolean;\n zIndex?: number;\n rotation?: number;\n visibility?: 'hidden' | 'inherit';\n };\n // Keep paragraph with next paragraph\n keepNext?: boolean;\n // Keep all lines of paragraph together\n keepLines?: boolean;\n}\n\nexport interface TableOptions {\n style?: 'minimal' | 'classic' | 'minimal';\n}\n\nexport interface StatisticData {\n number: string;\n description: string;\n alignment?: 'left' | 'center' | 'right';\n}\n\nexport interface StatisticOptions {\n spacing?: {\n before?: number; // in points\n after?: number; // in points\n };\n}\n\nexport interface ListOptions {\n // Reference to the numbering configuration in the Document\n numberingReference?: string;\n spacing?: {\n before?: number; // in points\n after?: number; // in points\n item?: number; // in points\n };\n alignment?: 'left' | 'center' | 'right' | 'justify';\n}\n\n/**\n * Create a text paragraph\n */\nexport function createText(\n content: string,\n theme: ThemeConfig,\n themeName: string,\n options: TextOptions = {}\n): Paragraph {\n const normalizedContent = normalizeUnicodeText(content);\n // Always use Normal style for consistent formatting\n const style = options.style || 'Normal';\n\n // Convert points to twips for spacing\n const spacing: any = {};\n if (options.spacing?.before !== undefined) {\n spacing.before = pointsToTwips(options.spacing.before);\n }\n if (options.spacing?.after !== undefined) {\n spacing.after = pointsToTwips(options.spacing.after);\n }\n // Add line spacing if provided\n const lineSpacingConfig = convertLineSpacingToDocx(options.lineSpacing);\n if (lineSpacingConfig) {\n spacing.line = lineSpacingConfig.line;\n spacing.lineRule = lineSpacingConfig.lineRule;\n }\n\n // Build children array\n const children: (\n | PlaceholderChild\n | ColumnBreak\n | Bookmark\n | import('../utils/revisionUtils').RevisionRun\n )[] = [];\n\n // Add column break if requested\n if (options.columnBreak) {\n children.push(new ColumnBreak());\n }\n\n // Resolve the effective family so fontWeight can be aliased even when the\n // run relies on the theme's body font (no inline `family` override). Without\n // this, `{ font: { fontWeight: 300 } }` would fall through with no family\n // for the alias registry to look up.\n const hasWeightRequest = options.fontWeight != null || options.bold === true;\n const effectiveFamily =\n options.fontFamily ??\n (hasWeightRequest ? resolveFontFamily(theme, 'body') : undefined);\n const weighted = applyFontWeightAlias({\n fontFamily: effectiveFamily,\n bold: options.bold,\n italic: options.italic,\n fontWeight: options.fontWeight,\n });\n const baseTextStyle = {\n // Only emit `font` when it came from the caller or from an alias —\n // emitting the theme body family on every run would be a behavior change.\n ...((options.fontFamily ||\n (weighted.font && weighted.font !== effectiveFamily)) && {\n font: weighted.font,\n }),\n ...(options.fontSize && { size: options.fontSize * 2 }), // Convert points to half-points\n ...(options.fontColor && {\n color: resolveColor(options.fontColor, theme),\n }),\n ...(weighted.bold !== undefined && { bold: weighted.bold }),\n ...(weighted.italics !== undefined && { italics: weighted.italics }),\n ...(options.underline !== undefined && {\n underline: options.underline ? { type: 'single' as const } : undefined,\n }),\n // Character width scaling in percent (w:w)\n ...(options.scale && { scale: options.scale }),\n // Letter tracking (w:spacing, twentieths of a point; negative = condensed)\n ...(options.characterSpacing && {\n characterSpacing:\n options.characterSpacing.type === 'condensed'\n ? -options.characterSpacing.value\n : options.characterSpacing.value,\n }),\n // Proofing: per-run language and/or no-proof. Omitting language lets the\n // run inherit the document default set on docDefaults.\n ...(options.language && { language: { value: options.language } }),\n ...(options.noProof !== undefined && { noProof: options.noProof }),\n };\n\n if (options.revision) {\n // Tracked changes: render revision segments as native w:ins/w:del runs\n // (literal text, no markdown parsing). Bookmarks are preserved so\n // internal hyperlinks targeting this paragraph keep working.\n const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);\n if (options.bookmarkId) {\n globalBookmarkRegistry.register(\n options.bookmarkId,\n normalizedContent,\n 'paragraph'\n );\n children.push(\n new Bookmark({\n id: options.bookmarkId,\n children: revisionRuns as TextRun[],\n })\n );\n } else {\n children.push(...revisionRuns);\n }\n } else {\n // Add text content - parseTextWithDecorators handles both decorators and newlines\n const textRuns = parseTextWithDecorators(normalizedContent, baseTextStyle, {\n boldColor: options.boldColor\n ? resolveColor(options.boldColor, theme)\n : undefined,\n enableHyperlinks: true,\n noProofWords: resolveNoProofWords(theme, options.noProofWords),\n });\n\n // If bookmarkId is provided, wrap text runs in a bookmark\n if (options.bookmarkId) {\n // Register bookmark\n globalBookmarkRegistry.register(\n options.bookmarkId,\n normalizedContent,\n 'paragraph'\n );\n\n // Wrap text runs in bookmark\n children.push(\n new Bookmark({\n id: options.bookmarkId,\n children: textRuns as TextRun[],\n })\n );\n } else {\n // No bookmark, add text runs directly\n children.push(...textRuns);\n }\n }\n\n // Build frame options for floating text\n const isFloating = !!options.floating;\n const frameOptions =\n isFloating && options.floating\n ? mapFrameOptions(options.floating, theme, themeName)\n : undefined;\n\n return new Paragraph({\n children,\n style,\n alignment: options.alignment ? getAlignment(options.alignment) : undefined,\n spacing,\n ...(options.outlineLevel !== undefined && {\n outlineLevel: options.outlineLevel,\n }),\n ...(frameOptions && { frame: frameOptions }),\n ...(options.keepNext !== undefined && { keepNext: options.keepNext }),\n ...(options.keepLines !== undefined && { keepLines: options.keepLines }),\n ...(options.indent && { indent: options.indent }),\n ...(options.tabStops &&\n options.tabStops.length > 0 && { tabStops: options.tabStops }),\n });\n}\n\n/**\n * Map floating frame configuration to docx.js IFrameOptions\n * IFrameOptions can be either IXYFrameOptions (absolute positioning) or IAlignmentFrameOptions (aligned positioning)\n *\n * Supports mixed positioning: alignment on one axis, offset on the other.\n * When mixing, calculates the position for the aligned axis.\n */\nfunction mapFrameOptions(\n floating: NonNullable<TextOptions['floating']>,\n theme?: ThemeConfig,\n themeName?: string\n): any {\n const hasHorizontalOffset = floating.horizontalPosition?.offset !== undefined;\n const hasVerticalOffset = floating.verticalPosition?.offset !== undefined;\n const hasHorizontalAlign = floating.horizontalPosition?.align !== undefined;\n const hasVerticalAlign = floating.verticalPosition?.align !== undefined;\n\n // Choose exactly one mode: absolute if any offset is present; otherwise alignment\n const useAbsolute = hasHorizontalOffset || hasVerticalOffset;\n\n // Base frame options\n const frameWidth = floating.width || 2880; // 2in default\n const frameHeight = floating.height || 1440; // 1in default\n\n const baseOptions: any = {\n width: frameWidth,\n height: frameHeight,\n anchor: {\n horizontal: floating.horizontalPosition?.relative || 'page',\n vertical: floating.verticalPosition?.relative || 'page',\n },\n };\n\n if (floating.wrap?.type) {\n baseOptions.wrap = floating.wrap.type;\n }\n\n // Config lockAnchor maps to docx anchorLock\n if (floating.lockAnchor !== undefined) {\n baseOptions.anchorLock = floating.lockAnchor;\n } else if ((floating as any).anchorLock !== undefined) {\n baseOptions.anchorLock = (floating as any).anchorLock;\n }\n\n if (useAbsolute) {\n const rawX = floating.horizontalPosition?.offset ?? 0;\n const rawY = floating.verticalPosition?.offset ?? 0;\n let x: number;\n let y: number;\n if (typeof rawX === 'string' || typeof rawY === 'string') {\n const hRelative = floating.horizontalPosition?.relative;\n const vRelative = floating.verticalPosition?.relative;\n const hRef =\n hRelative && hRelative !== 'page'\n ? getAvailableWidthTwips(theme, themeName)\n : getPageWidthTwips(theme, themeName);\n const vRef =\n vRelative && vRelative !== 'page'\n ? getAvailableHeightTwips(theme, themeName)\n : getPageHeightTwips(theme, themeName);\n x = resolveOffsetTwips(rawX, hRef);\n y = resolveOffsetTwips(rawY, vRef);\n } else {\n x = rawX;\n y = rawY;\n }\n return {\n type: 'absolute',\n position: { x, y },\n ...baseOptions,\n };\n }\n\n // Alignment positioning: use provided aligns; default missing axis\n const xAlign = hasHorizontalAlign\n ? floating.horizontalPosition!.align!\n : 'left';\n const yAlign = hasVerticalAlign ? floating.verticalPosition!.align! : 'top';\n return {\n type: 'alignment',\n alignment: { x: xAlign, y: yAlign },\n ...baseOptions,\n };\n}\n\n/**\n * Create a header paragraph\n */\nexport function createHeading(\n text: string,\n level: number,\n theme: ThemeConfig,\n _themeName: string,\n options: TextOptions = {}\n): Paragraph {\n const normalizedText = normalizeUnicodeText(text);\n const styleId = getStyleIdForLevel(level);\n\n // Only apply spacing if explicitly provided in options\n // This allows theme style spacing to be used by default\n const spacing: any = {};\n let hasExplicitSpacing = false;\n\n if (options.spacing?.before !== undefined) {\n spacing.before = pointsToTwips(options.spacing.before);\n hasExplicitSpacing = true;\n }\n if (options.spacing?.after !== undefined) {\n spacing.after = pointsToTwips(options.spacing.after);\n hasExplicitSpacing = true;\n }\n // Add line spacing if provided\n const lineSpacingConfig = convertLineSpacingToDocx(options.lineSpacing);\n if (lineSpacingConfig) {\n spacing.line = lineSpacingConfig.line;\n spacing.lineRule = lineSpacingConfig.lineRule;\n hasExplicitSpacing = true;\n }\n\n // Build children array\n const children: any[] = [];\n\n // Add prepended children first (e.g., bookmarks)\n if (options.prependChildren) {\n children.push(...options.prependChildren);\n }\n\n // Add column break if requested\n if (options.columnBreak) {\n children.push(new ColumnBreak());\n }\n\n // Check if text has decorators (bold/italic markers)\n const hasDecorators = /(\\*\\*\\*|___|(\\*\\*|__)|(\\*|_))/.test(normalizedText);\n\n // Headings default to theme.fonts.heading when no explicit family is given.\n // Resolve it so fontWeight can be aliased through the same path as body runs.\n const headingHasWeightRequest =\n options.fontWeight != null || options.bold === true;\n const headingEffectiveFamily =\n options.fontFamily ??\n (headingHasWeightRequest ? resolveFontFamily(theme, 'heading') : undefined);\n const headingWeighted = applyFontWeightAlias({\n fontFamily: headingEffectiveFamily,\n bold: options.bold,\n italic: options.italic,\n fontWeight: options.fontWeight,\n });\n // Build base text style from options (overrides theme style at run level)\n const baseTextStyle = {\n ...((options.fontFamily ||\n (headingWeighted.font &&\n headingWeighted.font !== headingEffectiveFamily)) && {\n font: headingWeighted.font,\n }),\n ...(options.fontSize && { size: options.fontSize * 2 }), // points to half-points\n ...(options.fontColor && { color: resolveColor(options.fontColor, theme) }),\n ...(headingWeighted.bold !== undefined && { bold: headingWeighted.bold }),\n ...(headingWeighted.italics !== undefined && {\n italics: headingWeighted.italics,\n }),\n ...(options.underline !== undefined && {\n underline: options.underline ? { type: 'single' as const } : undefined,\n }),\n // Character width scaling in percent (w:w)\n ...(options.scale && { scale: options.scale }),\n // Letter tracking (w:spacing, twentieths of a point; negative = condensed)\n ...(options.characterSpacing && {\n characterSpacing:\n options.characterSpacing.type === 'condensed'\n ? -options.characterSpacing.value\n : options.characterSpacing.value,\n }),\n // Proofing: per-run language and/or no-proof (see createText).\n ...(options.language && { language: { value: options.language } }),\n ...(options.noProof !== undefined && { noProof: options.noProof }),\n };\n\n // Known-words allowlist (document + component) and a run builder that marks\n // matched words as no-proof. Used by the simple (no-decorator) heading paths;\n // the decorator paths route through parseTextWithDecorators instead.\n const headingNoProofWords = resolveNoProofWords(theme, options.noProofWords);\n const makeHeadingRuns = (value: string): TextRun[] =>\n splitByNoProofWords(\n value,\n (segment, matched) =>\n new TextRun({\n text: segment,\n ...baseTextStyle,\n ...(matched && { noProof: true }),\n }),\n headingNoProofWords\n );\n\n if (options.revision) {\n // Tracked changes: revision segments replace text rendering. The TOC\n // bookmark is preserved so TOC links and cross-references keep working.\n const revisionRuns = createRevisionRuns(options.revision, baseTextStyle);\n if (options.bookmarkId) {\n globalBookmarkRegistry.register(\n options.bookmarkId,\n normalizedText,\n 'heading'\n );\n children.push(\n new Bookmark({\n id: options.bookmarkId,\n children: revisionRuns as TextRun[],\n })\n );\n } else {\n children.push(...revisionRuns);\n }\n } else if (options.bookmarkId) {\n // Register bookmark\n globalBookmarkRegistry.register(\n options.bookmarkId,\n normalizedText,\n 'heading'\n );\n\n // Wrap heading text in bookmark\n const headingTextChildren: (TextRun | any)[] = [];\n\n if (hasDecorators) {\n // For headings with decorators, parse text runs first\n const textRuns = parseTextWithDecorators(normalizedText, baseTextStyle, {\n boldColor: options.boldColor\n ? resolveColor(options.boldColor, theme)\n : undefined,\n enableHyperlinks: true,\n noProofWords: headingNoProofWords,\n });\n headingTextChildren.push(...textRuns);\n } else {\n // For simple headings, add single text run (split on known words)\n headingTextChildren.push(...makeHeadingRuns(normalizedText));\n }\n\n // Wrap in bookmark\n children.push(\n new Bookmark({\n id: options.bookmarkId,\n children: headingTextChildren,\n })\n );\n } else {\n // No bookmark, add text directly\n if (hasDecorators) {\n // For headings with decorators, parse and add text runs\n const textRuns = parseTextWithDecorators(normalizedText, baseTextStyle, {\n boldColor: options.boldColor\n ? resolveColor(options.boldColor, theme)\n : undefined,\n enableHyperlinks: true,\n noProofWords: headingNoProofWords,\n });\n children.push(...textRuns);\n } else {\n // For simple headings, add single text run (split on known words)\n children.push(...makeHeadingRuns(normalizedText));\n }\n }\n\n return new Paragraph({\n children,\n style: styleId,\n alignment: getAlignment(options.alignment || 'left'),\n // Only override spacing if explicitly provided\n spacing: hasExplicitSpacing ? spacing : undefined,\n ...(options.keepNext !== undefined && { keepNext: options.keepNext }),\n ...(options.keepLines !== undefined && { keepLines: options.keepLines }),\n ...(options.indent && { indent: options.indent }),\n });\n}\n\n/**\n * Create title page content\n */\nexport function createTitleContent(\n title?: string,\n subtitle?: string\n): Paragraph[] {\n // If no title, return empty array (skip title section entirely)\n if (!title) {\n return [];\n }\n\n const normalizedTitle = normalizeUnicodeText(title);\n const elements: Paragraph[] = [];\n\n elements.push(\n new Paragraph({\n text: normalizedTitle,\n style: 'Title',\n })\n );\n\n if (subtitle) {\n const normalizedSubtitle = normalizeUnicodeText(subtitle);\n elements.push(\n new Paragraph({\n text: normalizedSubtitle,\n style: 'Subtitle',\n })\n );\n }\n\n elements.push(new Paragraph({ children: [new PageBreak()] }));\n\n return elements;\n}\n\n/**\n * Create an image with optional caption\n */\nexport async function createImage(\n path: string,\n theme: ThemeConfig,\n themeName?: string,\n options: ImageOptions = {}\n): Promise<Paragraph[]> {\n const elements: Paragraph[] = [];\n const isFloating = !!options.floating;\n const alignment = isFloating\n ? undefined\n : getAlignment(options.alignment || 'center');\n\n let imagePath = path;\n let imageBuffer: Buffer;\n let responseContentType: string | undefined;\n\n try {\n // Try to use the provided path first\n const imageResult = await getImageBuffer(imagePath);\n imageBuffer = imageResult.buffer;\n responseContentType = imageResult.contentType;\n\n // Calculate available document width/height for percentage calculations\n const {\n getAvailableWidthTwips,\n getPageWidthTwips,\n getAvailableHeightTwips,\n getPageHeightTwips,\n } = await import('../utils/widthUtils');\n const widthRef = options.widthRelativeTo || 'content';\n const heightRef = options.heightRelativeTo || 'content';\n const availableWidthTwips =\n widthRef === 'page'\n ? getPageWidthTwips(theme)\n : getAvailableWidthTwips(theme);\n const availableHeightTwips =\n heightRef === 'page'\n ? getPageHeightTwips(theme)\n : getAvailableHeightTwips(theme);\n // Convert twips to pixels: 1 twip = 1/1440 inch, 1 inch = 96 pixels (screen DPI)\n const availableWidthPx = Math.round((availableWidthTwips / 1440) * 96);\n const availableHeightPx = Math.round((availableHeightTwips / 1440) * 96);\n\n // Default size calculations (fallback)\n const columnWidthCm = 7.36;\n const pixelsPerCm = 37.795275591;\n const columnWidthPx = Math.round(columnWidthCm * pixelsPerCm);\n const fallbackHeight = Math.round(columnWidthPx * 0.6);\n\n // Parse width value (handles both number and percentage string)\n // Default to 100% if no width is specified\n const parsedWidth = parseWidthValue(\n options.width ?? '100%',\n availableWidthPx\n );\n\n // Parse height value if provided\n const parsedHeight =\n options.height !== undefined\n ? parseDimensionValue(options.height, availableHeightPx)\n : undefined;\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imagePath,\n parsedWidth,\n parsedHeight,\n columnWidthPx,\n fallbackHeight\n );\n\n // Build ImageRun configuration with optional floating\n const { mapFloatingOptions } = await import(\n '../utils/docxImagePositioning'\n );\n const floating = isFloating\n ? mapFloatingOptions(options.floating, theme, themeName)\n : undefined;\n\n // Detect image type from response Content-Type, path, or base64 data URI\n const imageType = detectImageType(imagePath, responseContentType);\n\n // Create ImageRun based on image type\n const imageRun = createTypedImageRun({\n type: imageType,\n data: imageBuffer,\n transformation: { width: dimensions.width, height: dimensions.height },\n ...(floating && { floating }),\n });\n\n // Convert spacing from points to twips\n const spacing: any = {};\n if (options.spacing?.before !== undefined) {\n spacing.before = pointsToTwips(options.spacing.before);\n }\n if (options.spacing?.after !== undefined) {\n spacing.after = pointsToTwips(options.spacing.after);\n }\n\n elements.push(\n new Paragraph({\n children: [imageRun],\n alignment,\n ...(Object.keys(spacing).length > 0 && { spacing }),\n ...(options.keepNext !== undefined && { keepNext: options.keepNext }),\n ...(options.keepLines !== undefined && {\n keepLines: options.keepLines,\n }),\n })\n );\n } catch (error) {\n // If the image cannot be loaded, try the placeholder\n throw new Error(`Failed to load image from ${imagePath}`);\n }\n\n if (options.caption) {\n // Check if caption has decorators (bold/italic markers)\n const hasDecorators = /(\\*\\*\\*|___|(\\*\\*|__)|(\\*|_))/.test(options.caption);\n\n if (!hasDecorators) {\n // No decorators - use Normal style for font inheritance\n elements.push(\n new Paragraph({\n text: normalizeUnicodeText(options.caption),\n style: 'Normal',\n alignment: AlignmentType.LEFT, // Captions default to left alignment\n })\n );\n } else {\n // Has decorators - use parseTextWithDecorators (same as text component)\n const textRuns = parseTextWithDecorators(\n options.caption,\n {},\n {\n enableHyperlinks: true,\n }\n );\n\n elements.push(\n new Paragraph({\n children: textRuns,\n style: 'Normal', // Use Normal style for consistent font inheritance\n alignment: AlignmentType.LEFT, // Captions default to left alignment\n })\n );\n }\n }\n\n return elements;\n}\n\n/**\n * Create a statistic display\n */\nexport function createStatistic(\n data: StatisticData,\n options: StatisticOptions = {}\n): Paragraph[] {\n const alignment = getAlignment(data.alignment || 'center');\n const normalizedNumber = normalizeUnicodeText(data.number);\n const normalizedDescription = normalizeUnicodeText(data.description);\n\n return [\n new Paragraph({\n text: normalizedNumber,\n style: 'StatisticNumber',\n alignment,\n spacing: options.spacing,\n }),\n new Paragraph({\n text: normalizedDescription,\n style: 'StatisticDescription',\n alignment,\n }),\n ];\n}\n\n/**\n * Create a list of items using proper docx numbering\n */\nexport function createList(\n items: (string | { text: string; level?: number; revision?: Revision })[],\n _theme: ThemeConfig,\n _themeName: string,\n options: ListOptions = {}\n): Paragraph[] {\n if (!items || items.length === 0) {\n return [];\n }\n\n const paragraphs: Paragraph[] = [];\n\n items.forEach((item, index) => {\n // Handle both string and object items\n const itemText = typeof item === 'string' ? item : item.text;\n const itemLevel = typeof item === 'object' ? item.level || 0 : 0;\n const itemRevision = typeof item === 'object' ? item.revision : undefined;\n\n // Skip empty items — unless they carry revision data (a fully deleted\n // item has empty new text but must still render its w:del runs)\n if (!itemText.trim() && !itemRevision) {\n return;\n }\n\n // Parse rich text decorators for each item\n // Don't pass font/size/color - let list items inherit from Normal paragraph style\n const textRuns = itemRevision\n ? createRevisionRuns(itemRevision, {})\n : parseTextWithDecorators(\n itemText,\n {},\n {\n enableHyperlinks: true,\n }\n );\n\n // Calculate spacing for this item (convert points to twips)\n const spacing: { before?: number; after?: number } = {};\n if (index === 0 && options.spacing?.before) {\n spacing.before = pointsToTwips(options.spacing.before);\n }\n if (index === items.length - 1 && options.spacing?.after) {\n spacing.after = pointsToTwips(options.spacing.after);\n } else if (options.spacing?.item) {\n spacing.after = pointsToTwips(options.spacing.item);\n }\n\n // Create the paragraph with proper numbering reference\n const paragraph = new Paragraph({\n style: 'Normal', // Apply Normal style for font inheritance\n children: textRuns,\n alignment: options.alignment\n ? getAlignment(options.alignment)\n : AlignmentType.LEFT,\n spacing,\n // Use proper docx numbering instead of prepending text\n ...(options.numberingReference && {\n numbering: {\n reference: options.numberingReference,\n level: itemLevel,\n },\n }),\n });\n\n paragraphs.push(paragraph);\n });\n\n return paragraphs;\n}\n\n/**\n * Create a table\n */\ntype TableFontConfig = {\n family?: string;\n size?: number;\n bold?: boolean;\n fontWeight?: number;\n italic?: boolean;\n underline?: boolean;\n};\n\ntype BorderColor =\n | string\n | {\n bottom?: string;\n top?: string;\n right?: string;\n left?: string;\n };\n\ntype BorderSize =\n | number\n | {\n bottom?: number;\n top?: number;\n right?: number;\n left?: number;\n };\n\ntype Padding =\n | number\n | {\n bottom?: number;\n top?: number;\n right?: number;\n left?: number;\n };\n\ntype CellDefaults = {\n color?: string;\n backgroundColor?: string;\n horizontalAlignment?: 'left' | 'center' | 'right' | 'justify';\n verticalAlignment?: 'top' | 'middle' | 'bottom';\n font?: TableFontConfig;\n borderColor?: BorderColor;\n borderSize?: BorderSize;\n padding?: Padding;\n height?: number;\n};\n\n// After merging, borders and padding are always normalized to per-side format\ntype NormalizedCellDefaults = {\n color?: string;\n backgroundColor?: string;\n horizontalAlignment?: 'left' | 'center' | 'right' | 'justify';\n verticalAlignment?: 'top' | 'middle' | 'bottom';\n font?: TableFontConfig;\n borderColor: { top: string; right: string; bottom: string; left: string };\n borderSize: { top: number; right: number; bottom: number; left: number };\n padding?: { top: number; right: number; bottom: number; left: number };\n height?: number;\n};\n\n// Hide borders configuration - can be boolean or per-side object\ntype HideBorders =\n | boolean\n | {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n insideHorizontal?: boolean;\n insideVertical?: boolean;\n };\n\ntype TableConfig = {\n borderColor?: BorderColor;\n borderSize?: BorderSize;\n hideBorders?: HideBorders;\n cellDefaults?: CellDefaults;\n headerCellDefaults?: CellDefaults;\n width?: number;\n columns: {\n /** Width in points (number) or as percentage string e.g. \"40%\" */\n width?: number | string;\n cellDefaults?: CellDefaults;\n header?: CellDefaults & {\n content?: string | ComponentDefinition;\n };\n cells?: (CellDefaults & {\n content?: string | ComponentDefinition;\n })[];\n }[];\n keepInOnePage?: boolean;\n keepNext?: boolean;\n repeatHeaderOnPageBreak?: boolean;\n};\n\nexport async function createTable(\n columns: TableConfig['columns'],\n tableConfig: TableConfig,\n theme: ThemeConfig,\n themeName: string,\n _options: TableOptions = {}\n): Promise<Table> {\n // Note: _options parameter is available for future table customization\n const tableStyle = getTableStyle(theme, themeName);\n\n // Determine number of rows from the first column\n const numRows = columns[0]?.cells?.length || 0;\n\n // Default values for missing cell defaults\n const getDefaultCellDefaults = (): CellDefaults => ({\n color: '000000',\n backgroundColor: 'transparent',\n horizontalAlignment: 'left',\n verticalAlignment: 'top',\n font: {\n family: 'Arial',\n size: 11,\n bold: false,\n italic: false,\n underline: false,\n },\n borderColor: '000000',\n borderSize: 1,\n });\n\n // No warning collector reaches createTable (the render path passes only\n // theme/themeName), so use the prefixed console.warn fallback the generator\n // uses when no collector is present. Deduped so a column of cells sharing the\n // same bad value warns once per table.\n const warnedCellColors = new Set<string>();\n const warnCellColor = (code: string, message: string): void => {\n if (warnedCellColors.has(message)) return;\n warnedCellColors.add(message);\n // eslint-disable-next-line no-console\n console.warn(`[json-to-docx] ${code}: ${message}`);\n };\n\n // Resolve a cell color the same way paragraph/heading font colors are\n // resolved: theme name (\"primary\") or \"#RRGGBB\". Bare 6-digit hex and \"auto\"\n // are passed through — those are the only raw values OOXML itself accepts, so\n // documents relying on them predate theme resolution and must keep working.\n // \"transparent\" is a backgroundColor-only sentinel consumed at the shading\n // site; on the text path nothing consumes it and it is not a legal w:color\n // value, so it is dropped with a warning rather than emitted.\n const resolveCellColor = (\n value: string | undefined,\n prop: 'color' | 'backgroundColor'\n ): string | undefined => {\n if (value === undefined || value === 'auto') return value;\n if (value === 'transparent') {\n if (prop === 'backgroundColor') return value;\n warnCellColor(\n 'TABLE_CELL_COLOR_INVALID',\n `\"transparent\" is not a valid table cell \"color\"; ignoring it and using the table style color. It only applies to \"backgroundColor\".`\n );\n return undefined;\n }\n if (/^[0-9A-Fa-f]{6}$/.test(value)) return value.toUpperCase();\n try {\n return resolveColor(value, theme);\n } catch {\n // Passing the value through instead would not save the document: docx\n // rejects any non-hex, non-\"auto\" fill/color, so it would still fail —\n // deeper in the stack with an opaque message.\n const allowed =\n prop === 'backgroundColor'\n ? '\"auto\", or \"transparent\" for no shading'\n : 'or \"auto\"';\n throw new Error(\n `Invalid table cell ${prop}: \"${value}\". Must be a hex color with # prefix (e.g. \"#000000\"), a theme color name, ${allowed}.`\n );\n }\n };\n\n // Helper function to normalize border color to per-side format\n const normalizeBorderColor = (\n border: BorderColor | undefined\n ):\n | { top: string; right: string; bottom: string; left: string }\n | undefined => {\n if (border === undefined) return undefined;\n if (typeof border === 'string') {\n return { top: border, right: border, bottom: border, left: border };\n }\n return {\n top: border.top ?? '',\n right: border.right ?? '',\n bottom: border.bottom ?? '',\n left: border.left ?? '',\n };\n };\n\n // Helper function to normalize border size to per-side format\n const normalizeBorderSize = (\n border: BorderSize | undefined\n ):\n | { top: number; right: number; bottom: number; left: number }\n | undefined => {\n if (border === undefined) return undefined;\n if (typeof border === 'number') {\n return { top: border, right: border, bottom: border, left: border };\n }\n return {\n top: border.top ?? -1,\n right: border.right ?? -1,\n bottom: border.bottom ?? -1,\n left: border.left ?? -1,\n };\n };\n\n // Helper function to normalize padding to per-side format\n const normalizePadding = (\n padding: Padding | undefined\n ):\n | { top: number; right: number; bottom: number; left: number }\n | undefined => {\n if (padding === undefined) return undefined;\n if (typeof padding === 'number') {\n return { top: padding, right: padding, bottom: padding, left: padding };\n }\n return {\n top: padding.top ?? -1,\n right: padding.right ?? -1,\n bottom: padding.bottom ?? -1,\n left: padding.left ?? -1,\n };\n };\n\n // Helper function to merge border colors at the side level\n const mergeBorderColorPerSide = (\n ...borders: (BorderColor | undefined)[]\n ): { top: string; right: string; bottom: string; left: string } => {\n const normalized = borders.map(normalizeBorderColor);\n const defaults = getDefaultCellDefaults();\n const defaultColor =\n typeof defaults.borderColor === 'string'\n ? defaults.borderColor\n : '000000';\n\n return {\n top: normalized.find((b) => b && b.top !== '')?.top ?? defaultColor,\n right: normalized.find((b) => b && b.right !== '')?.right ?? defaultColor,\n bottom:\n normalized.find((b) => b && b.bottom !== '')?.bottom ?? defaultColor,\n left: normalized.find((b) => b && b.left !== '')?.left ?? defaultColor,\n };\n };\n\n // Helper function to merge border sizes at the side level\n const mergeBorderSizePerSide = (\n ...borders: (BorderSize | undefined)[]\n ): { top: number; right: number; bottom: number; left: number } => {\n const normalized = borders.map(normalizeBorderSize);\n const defaults = getDefaultCellDefaults();\n const defaultSize =\n typeof defaults.borderSize === 'number' ? defaults.borderSize : 1;\n\n return {\n top: normalized.find((b) => b && b.top !== -1)?.top ?? defaultSize,\n right: normalized.find((b) => b && b.right !== -1)?.right ?? defaultSize,\n bottom:\n normalized.find((b) => b && b.bottom !== -1)?.bottom ?? defaultSize,\n left: normalized.find((b) => b && b.left !== -1)?.left ?? defaultSize,\n };\n };\n\n // Helper to create border override for table outer borders based on position\n const getTableOuterBorder = (\n position: {\n isHeader?: boolean;\n isFirstCol?: boolean;\n isLastCol?: boolean;\n isLastRow?: boolean;\n },\n tableBorderColor?: BorderColor,\n tableBorderSize?: BorderSize\n ): {\n borderColor?: Partial<{\n top: string;\n right: string;\n bottom: string;\n left: string;\n }>;\n borderSize?: Partial<{\n top: number;\n right: number;\n bottom: number;\n left: number;\n }>;\n } => {\n const result: {\n borderColor?: Partial<{\n top: string;\n right: string;\n bottom: string;\n left: string;\n }>;\n borderSize?: Partial<{\n top: number;\n right: number;\n bottom: number;\n left: number;\n }>;\n } = {};\n\n if (tableBorderColor) {\n const normalizedColor = normalizeBorderColor(tableBorderColor);\n if (normalizedColor) {\n result.borderColor = {};\n if (position.isHeader && normalizedColor.top !== '')\n result.borderColor.top = normalizedColor.top;\n if (position.isFirstCol && normalizedColor.left !== '')\n result.borderColor.left = normalizedColor.left;\n if (position.isLastCol && normalizedColor.right !== '')\n result.borderColor.right = normalizedColor.right;\n if (position.isLastRow && normalizedColor.bottom !== '')\n result.borderColor.bottom = normalizedColor.bottom;\n }\n }\n\n if (tableBorderSize) {\n const normalizedSize = normalizeBorderSize(tableBorderSize);\n if (normalizedSize) {\n result.borderSize = {};\n if (position.isHeader && normalizedSize.top !== -1)\n result.borderSize.top = normalizedSize.top;\n if (position.isFirstCol && normalizedSize.left !== -1)\n result.borderSize.left = normalizedSize.left;\n if (position.isLastCol && normalizedSize.right !== -1)\n result.borderSize.right = normalizedSize.right;\n if (position.isLastRow && normalizedSize.bottom !== -1)\n result.borderSize.bottom = normalizedSize.bottom;\n }\n }\n\n return result;\n };\n\n // Helper function to merge padding at the side level\n const mergePaddingPerSide = (\n ...paddings: (Padding | undefined)[]\n ):\n | { top: number; right: number; bottom: number; left: number }\n | undefined => {\n const normalized = paddings.map(normalizePadding);\n const hasAny = normalized.some((p) => p !== undefined);\n if (!hasAny) return undefined;\n\n return {\n top: normalized.find((p) => p && p.top !== -1)?.top ?? 0,\n right: normalized.find((p) => p && p.right !== -1)?.right ?? 0,\n bottom: normalized.find((p) => p && p.bottom !== -1)?.bottom ?? 0,\n left: normalized.find((p) => p && p.left !== -1)?.left ?? 0,\n };\n };\n\n // Helper function to merge cell defaults with priority: cell > column > table outer border (for specific sides) > table cellDefaults > default\n const mergeCellDefaults = (\n tableDef?: CellDefaults,\n columnDef?: CellDefaults,\n cellDef?: Partial<CellDefaults>,\n position?: {\n isFirstCol?: boolean;\n isLastCol?: boolean;\n isLastRow?: boolean;\n },\n tableOuterBorder?: { borderColor?: BorderColor; borderSize?: BorderSize }\n ): NormalizedCellDefaults => {\n const defaults = getDefaultCellDefaults();\n\n // Merge font configs\n const mergedFont: TableFontConfig = {\n ...defaults.font,\n ...tableDef?.font,\n ...columnDef?.font,\n ...cellDef?.font,\n };\n\n // Get table outer border overrides based on position\n const outerBorder =\n position && tableOuterBorder\n ? getTableOuterBorder(\n position,\n tableOuterBorder.borderColor,\n tableOuterBorder.borderSize\n )\n : {};\n\n // Merge border colors per side (priority: cell > column > table outer border > table cellDefaults > table borderColor > default)\n // tableOuterBorder.borderColor is used twice: via outerBorder for edge-specific application,\n // and directly as fallback for ALL borders when not overridden by cellDefaults\n const mergedBorderColor = mergeBorderColorPerSide(\n cellDef?.borderColor,\n columnDef?.borderColor,\n outerBorder.borderColor as BorderColor,\n tableDef?.borderColor,\n tableOuterBorder?.borderColor // Apply table-level borderColor to all cells as fallback\n );\n\n // Merge border sizes per side (priority: cell > column > table outer border > table cellDefaults > table borderSize > default)\n const mergedBorderSize = mergeBorderSizePerSide(\n cellDef?.borderSize,\n columnDef?.borderSize,\n outerBorder.borderSize as BorderSize,\n tableDef?.borderSize,\n tableOuterBorder?.borderSize // Apply table-level borderSize to all cells as fallback\n );\n\n // Merge padding per side (priority: cell > column > table)\n const mergedPadding = mergePaddingPerSide(\n cellDef?.padding,\n columnDef?.padding,\n tableDef?.padding\n );\n\n return {\n color: resolveCellColor(\n cellDef?.color ?? columnDef?.color ?? tableDef?.color ?? defaults.color,\n 'color'\n ),\n backgroundColor: resolveCellColor(\n cellDef?.backgroundColor ??\n columnDef?.backgroundColor ??\n tableDef?.backgroundColor ??\n defaults.backgroundColor,\n 'backgroundColor'\n ),\n horizontalAlignment:\n cellDef?.horizontalAlignment ??\n columnDef?.horizontalAlignment ??\n tableDef?.horizontalAlignment ??\n defaults.horizontalAlignment,\n verticalAlignment:\n cellDef?.verticalAlignment ??\n columnDef?.verticalAlignment ??\n tableDef?.verticalAlignment ??\n defaults.verticalAlignment,\n font: mergedFont,\n borderColor: mergedBorderColor,\n borderSize: mergedBorderSize,\n padding: mergedPadding,\n height: cellDef?.height ?? columnDef?.height ?? tableDef?.height,\n };\n };\n\n // Helper function to merge header cell defaults with priority: header > columnCellDefaults > table outer border (for specific sides) > headerCellDefaults > cellDefaults > default\n const mergeHeaderCellDefaults = (\n tableDef?: CellDefaults,\n headerTableDef?: CellDefaults,\n columnDef?: CellDefaults,\n headerDef?: Partial<CellDefaults>,\n position?: { isFirstCol?: boolean; isLastCol?: boolean },\n tableOuterBorder?: { borderColor?: BorderColor; borderSize?: BorderSize }\n ): NormalizedCellDefaults => {\n const defaults = getDefaultCellDefaults();\n\n // Merge font configs with new priority\n const mergedFont: TableFontConfig = {\n ...defaults.font,\n ...tableDef?.font,\n ...headerTableDef?.font,\n ...columnDef?.font,\n ...headerDef?.font,\n };\n\n // Get table outer border overrides based on position (headers always affect top border)\n const outerBorder =\n position && tableOuterBorder\n ? getTableOuterBorder(\n {\n isHeader: true,\n isFirstCol: position.isFirstCol,\n isLastCol: position.isLastCol,\n },\n tableOuterBorder.borderColor,\n tableOuterBorder.borderSize\n )\n : {};\n\n // Merge border colors per side (priority: header > columnCellDefaults > table outer border > headerCellDefaults > cellDefaults > table borderColor > default)\n // tableOuterBorder.borderColor is used twice: via outerBorder for edge-specific application,\n // and directly as fallback for ALL borders when not overridden by cellDefaults\n const mergedBorderColor = mergeBorderColorPerSide(\n headerDef?.borderColor,\n columnDef?.borderColor,\n outerBorder.borderColor as BorderColor,\n headerTableDef?.borderColor,\n tableDef?.borderColor,\n tableOuterBorder?.borderColor // Apply table-level borderColor to all cells as fallback\n );\n\n // Merge border sizes per side (priority: header > columnCellDefaults > table outer border > headerCellDefaults > cellDefaults > table borderSize > default)\n const mergedBorderSize = mergeBorderSizePerSide(\n headerDef?.borderSize,\n columnDef?.borderSize,\n outerBorder.borderSize as BorderSize,\n headerTableDef?.borderSize,\n tableDef?.borderSize,\n tableOuterBorder?.borderSize // Apply table-level borderSize to all cells as fallback\n );\n\n // Merge padding per side (priority: header > headerCellDefaults > columnCellDefaults > cellDefaults)\n const mergedPadding = mergePaddingPerSide(\n headerDef?.padding,\n headerTableDef?.padding,\n columnDef?.padding,\n tableDef?.padding\n );\n\n return {\n color: resolveCellColor(\n headerDef?.color ??\n headerTableDef?.color ??\n columnDef?.color ??\n tableDef?.color ??\n defaults.color,\n 'color'\n ),\n backgroundColor: resolveCellColor(\n headerDef?.backgroundColor ??\n headerTableDef?.backgroundColor ??\n columnDef?.backgroundColor ??\n tableDef?.backgroundColor ??\n defaults.backgroundColor,\n 'backgroundColor'\n ),\n horizontalAlignment:\n headerDef?.horizontalAlignment ??\n headerTableDef?.horizontalAlignment ??\n columnDef?.horizontalAlignment ??\n tableDef?.horizontalAlignment ??\n defaults.horizontalAlignment,\n verticalAlignment:\n headerDef?.verticalAlignment ??\n headerTableDef?.verticalAlignment ??\n columnDef?.verticalAlignment ??\n tableDef?.verticalAlignment ??\n defaults.verticalAlignment,\n font: mergedFont,\n borderColor: mergedBorderColor,\n borderSize: mergedBorderSize,\n padding: mergedPadding,\n height:\n headerDef?.height ??\n headerTableDef?.height ??\n columnDef?.height ??\n tableDef?.height,\n };\n };\n\n // Helper function to get border value for a specific side\n // After normalization, borders are always objects with side properties\n const getBorderValue = (\n border: {\n top: string | number;\n right: string | number;\n bottom: string | number;\n left: string | number;\n },\n side: 'top' | 'bottom' | 'left' | 'right'\n ) => {\n return border[side];\n };\n\n // Helper function to get padding value for a specific side\n // After normalization, padding is always an object with side properties or undefined\n const getPaddingValue = (\n padding:\n | { top: number; right: number; bottom: number; left: number }\n | undefined,\n side: 'top' | 'bottom' | 'left' | 'right'\n ): number | undefined => {\n if (padding === undefined) return undefined;\n return padding[side] * 20; // Convert points to twips\n };\n\n // Helper function to create margins object from padding\n // After normalization, padding is always an object with side properties or undefined\n // Returns ITableCellMarginOptions with marginUnitType set to DXA (twips)\n const createMarginsFromPadding = (\n padding:\n | { top: number; right: number; bottom: number; left: number }\n | undefined\n ) => {\n if (padding === undefined) return undefined;\n\n return {\n marginUnitType: WidthType.DXA, // Specify that values are in twips\n top: getPaddingValue(padding, 'top') ?? 0,\n bottom: getPaddingValue(padding, 'bottom') ?? 0,\n left: getPaddingValue(padding, 'left') ?? 0,\n right: getPaddingValue(padding, 'right') ?? 0,\n };\n };\n\n // Normalize hideBorders config to per-side format\n const normalizeHideBorders = (\n hideBorders: HideBorders | undefined\n ): {\n top: boolean;\n right: boolean;\n bottom: boolean;\n left: boolean;\n insideHorizontal: boolean;\n insideVertical: boolean;\n } => {\n if (hideBorders === undefined) {\n return {\n top: false,\n right: false,\n bottom: false,\n left: false,\n insideHorizontal: false,\n insideVertical: false,\n };\n }\n if (typeof hideBorders === 'boolean') {\n return {\n top: hideBorders,\n right: hideBorders,\n bottom: hideBorders,\n left: hideBorders,\n insideHorizontal: hideBorders,\n insideVertical: hideBorders,\n };\n }\n return {\n top: hideBorders.top ?? false,\n right: hideBorders.right ?? false,\n bottom: hideBorders.bottom ?? false,\n left: hideBorders.left ?? false,\n insideHorizontal: hideBorders.insideHorizontal ?? false,\n insideVertical: hideBorders.insideVertical ?? false,\n };\n };\n\n // Normalized hidden borders config\n const hiddenBorders = normalizeHideBorders(tableConfig.hideBorders);\n\n // Helper function to create border config\n const createBorder = (size: number, color: string, isHidden?: boolean) => {\n if (size === 0 || isHidden) {\n return { style: BorderStyle.NONE, size: 0, color: '000000' };\n }\n return {\n style: BorderStyle.SINGLE,\n size: size * 8, // Convert points to eighths of a point\n color: color || '000000',\n };\n };\n\n // Helper to determine if a specific border should be hidden based on cell position\n const shouldHideBorder = (\n side: 'top' | 'right' | 'bottom' | 'left',\n position: {\n isFirstRow?: boolean;\n isLastRow?: boolean;\n isFirstCol?: boolean;\n isLastCol?: boolean;\n }\n ): boolean => {\n // Map cell position to which hideBorders config applies\n // Outer borders use top/right/bottom/left, inner borders use insideHorizontal/insideVertical\n switch (side) {\n case 'top':\n return position.isFirstRow\n ? hiddenBorders.top\n : hiddenBorders.insideHorizontal;\n case 'bottom':\n return position.isLastRow\n ? hiddenBorders.bottom\n : hiddenBorders.insideHorizontal;\n case 'left':\n return position.isFirstCol\n ? hiddenBorders.left\n : hiddenBorders.insideVertical;\n case 'right':\n return position.isLastCol\n ? hiddenBorders.right\n : hiddenBorders.insideVertical;\n default:\n return false;\n }\n };\n\n // Helper function to process cell content\n const processCellContent = async (\n cell: string | ComponentDefinition | undefined,\n cellDefaults: NormalizedCellDefaults,\n baseCellStyle: typeof tableStyle.tableCell\n ): Promise<(PlaceholderChild | ImageRun)[]> => {\n let cellChildren: (PlaceholderChild | ImageRun)[] = [];\n\n // Handle undefined or empty content\n if (!cell) {\n return cellChildren;\n }\n\n // Create merged style with config overrides\n const cellWeighted = applyFontWeightAlias({\n fontFamily: cellDefaults.font?.family || baseCellStyle.font,\n bold: cellDefaults.font?.bold ?? false,\n italic: cellDefaults.font?.italic ?? false,\n fontWeight: cellDefaults.font?.fontWeight,\n });\n const mergedStyle = {\n font: cellWeighted.font,\n size: cellDefaults.font?.size\n ? cellDefaults.font.size * 2\n : baseCellStyle.size, // Convert to half-points\n bold: cellWeighted.bold ?? false,\n italics: cellWeighted.italics ?? false,\n underline: cellDefaults.font?.underline\n ? { type: 'single' as const }\n : undefined,\n color: cellDefaults.color || baseCellStyle.color,\n };\n\n if (typeof cell === 'object' && 'name' in cell && 'props' in cell) {\n // Handle ComponentDefinition\n if (isParagraphComponent(cell)) {\n const textComp = cell as ParagraphComponentDefinition;\n const paragraphFont = textComp.props.font;\n const paraWeighted = applyFontWeightAlias({\n fontFamily: paragraphFont?.family ?? mergedStyle.font,\n bold: paragraphFont?.bold,\n italic: paragraphFont?.italic,\n fontWeight: paragraphFont?.fontWeight,\n });\n const paragraphStyle = {\n ...mergedStyle,\n ...(paraWeighted.font && { font: paraWeighted.font }),\n ...(paragraphFont?.size && { size: paragraphFont.size * 2 }),\n ...(paraWeighted.bold !== undefined && {\n bold: paraWeighted.bold,\n }),\n ...(paraWeighted.italics !== undefined && {\n italics: paraWeighted.italics,\n }),\n ...(paragraphFont?.underline !== undefined && {\n underline: paragraphFont.underline\n ? { type: 'single' as const }\n : undefined,\n }),\n ...(paragraphFont?.color && {\n color: resolveColor(paragraphFont.color, theme),\n }),\n };\n cellChildren = parseTextWithDecorators(\n textComp.props.text,\n paragraphStyle,\n { enableHyperlinks: true }\n );\n } else if (isImageComponent(cell)) {\n const imageComp = cell as ImageComponentDefinition;\n try {\n // Get image source (svg, base64, or path)\n const imageSource = resolveImageSource(imageComp.props);\n if (!imageSource) {\n throw new Error(\n 'Image component requires one of \"path\", \"base64\", or \"svg\" property'\n );\n }\n\n // Read from local file, URL, or base64\n const imageResult = await getImageBuffer(imageSource);\n\n // Parse width value if it's a string percentage (like \"90%\")\n const parsedWidth =\n typeof imageComp.props.width === 'string'\n ? parseWidthValue(imageComp.props.width, 300) // Use a reasonable default for table context\n : imageComp.props.width;\n\n // Parse height value if it's a string percentage (like \"90%\")\n const parsedHeight =\n typeof imageComp.props.height === 'string'\n ? parseWidthValue(imageComp.props.height, 200) // Use a reasonable default for table context\n : imageComp.props.height;\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imageSource,\n parsedWidth,\n parsedHeight,\n 60, // fallback width\n 20 // fallback height\n );\n\n const imgType = detectImageType(imageSource, imageResult.contentType);\n const imageRun = createTypedImageRun({\n type: imgType,\n data: imageResult.buffer,\n transformation: {\n width: dimensions.width,\n height: dimensions.height,\n },\n });\n cellChildren = [imageRun];\n } catch (error) {\n // Fallback for missing images\n const imageSource = imageComp.props.svg?.trim()\n ? 'inline-svg'\n : imageComp.props.base64 || imageComp.props.path || 'unknown';\n cellChildren = [\n new TextRun({\n text: `[IMAGE: ${imageSource.substring(0, 50)}${imageSource.length > 50 ? '...' : ''}]`,\n font: mergedStyle.font,\n size: mergedStyle.size,\n color: '#999999',\n }),\n ];\n }\n } else {\n // Unsupported component type in table cell\n cellChildren = [\n new TextRun({\n text: `[Unsupported component type: ${cell.name}]`,\n font: mergedStyle.font,\n size: mergedStyle.size,\n color: '#999999',\n }),\n ];\n }\n } else {\n // Handle plain string\n cellChildren = parseTextWithDecorators(cell as string, mergedStyle, {\n enableHyperlinks: true,\n });\n }\n\n return cellChildren;\n };\n\n // Create header row by iterating through columns\n // Calculate row height from any header cell that defines it\n const numColumns = columns.length;\n const headerHeight = columns.reduce<number | undefined>(\n (maxHeight, column, colIndex) => {\n const headerCell = column.header;\n const position = {\n isFirstCol: colIndex === 0,\n isLastCol: colIndex === numColumns - 1,\n };\n const mergedDefaults = mergeHeaderCellDefaults(\n tableConfig.cellDefaults,\n tableConfig.headerCellDefaults,\n column.cellDefaults,\n headerCell,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n if (mergedDefaults.height !== undefined) {\n return maxHeight !== undefined\n ? Math.max(maxHeight, mergedDefaults.height)\n : mergedDefaults.height;\n }\n return maxHeight;\n },\n undefined\n );\n\n const headerRow = new TableRow({\n // Headers repeat across page breaks unless explicitly disabled\n tableHeader: tableConfig.repeatHeaderOnPageBreak ?? true,\n height:\n headerHeight !== undefined\n ? { value: headerHeight * 20, rule: 'atLeast' as const }\n : undefined,\n children: await Promise.all(\n columns.map(async (column, colIndex) => {\n const headerCell = column.header;\n\n // Determine position for outer border application and hideBorders\n const position = {\n isFirstRow: true, // Header is always the first row\n isLastRow: numRows === 0, // Header is last row only if no data rows\n isFirstCol: colIndex === 0,\n isLastCol: colIndex === numColumns - 1,\n };\n\n // Merge cell defaults with priority: header > columnCellDefaults > table outer border > headerCellDefaults > cellDefaults\n const mergedDefaults = mergeHeaderCellDefaults(\n tableConfig.cellDefaults,\n tableConfig.headerCellDefaults,\n column.cellDefaults,\n headerCell,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n\n const cellChildren = await processCellContent(\n headerCell?.content,\n mergedDefaults,\n tableStyle.tableHeader\n );\n\n const horizontalAlignment = mergedDefaults.horizontalAlignment!;\n const verticalAlignment = getVerticalAlignment(\n mergedDefaults.verticalAlignment\n );\n\n return new TableCell({\n children: [\n new Paragraph({\n ...(tableConfig.keepInOnePage && { keepNext: true }),\n spacing: tableStyle.headerParagraph,\n alignment: getAlignment(horizontalAlignment),\n children: cellChildren,\n }),\n ],\n\n verticalAlign: verticalAlignment,\n ...(mergedDefaults.backgroundColor !== 'transparent' && {\n shading: {\n fill: mergedDefaults.backgroundColor,\n },\n }),\n margins: createMarginsFromPadding(mergedDefaults.padding),\n borders: {\n top: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'top') as number,\n getBorderValue(mergedDefaults.borderColor, 'top') as string,\n shouldHideBorder('top', position)\n ),\n bottom: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'bottom') as number,\n getBorderValue(mergedDefaults.borderColor, 'bottom') as string,\n shouldHideBorder('bottom', position)\n ),\n left: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'left') as number,\n getBorderValue(mergedDefaults.borderColor, 'left') as string,\n shouldHideBorder('left', position)\n ),\n right: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'right') as number,\n getBorderValue(mergedDefaults.borderColor, 'right') as string,\n shouldHideBorder('right', position)\n ),\n },\n });\n })\n ),\n });\n\n // Create data rows\n const dataRows = await Promise.all(\n Array.from({ length: numRows }, async (_, rowIndex) => {\n const isLastRow = rowIndex === numRows - 1;\n\n // Calculate row height from any cell in this row that defines it\n const rowHeight = columns.reduce<number | undefined>(\n (maxHeight, column, colIndex) => {\n const cell = column.cells?.[rowIndex];\n if (cell) {\n const position = {\n isFirstCol: colIndex === 0,\n isLastCol: colIndex === numColumns - 1,\n isLastRow,\n };\n const mergedDefaults = mergeCellDefaults(\n tableConfig.cellDefaults,\n column.cellDefaults,\n cell,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n if (mergedDefaults.height !== undefined) {\n return maxHeight !== undefined\n ? Math.max(maxHeight, mergedDefaults.height)\n : mergedDefaults.height;\n }\n }\n return maxHeight;\n },\n undefined\n );\n\n return new TableRow({\n height:\n rowHeight !== undefined\n ? { value: rowHeight * 20, rule: 'atLeast' as const }\n : undefined,\n children: await Promise.all(\n columns.map(async (column, colIndex) => {\n const cell = column.cells?.[rowIndex];\n\n // Determine position for outer border application and hideBorders\n const position = {\n isFirstRow: false, // Data rows are never the first row (header is)\n isFirstCol: colIndex === 0,\n isLastCol: colIndex === numColumns - 1,\n isLastRow,\n };\n\n if (!cell) {\n // Handle missing cell data - merge defaults properly\n const mergedDefaultsForMissing = mergeCellDefaults(\n tableConfig.cellDefaults,\n column.cellDefaults,\n undefined,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n return new TableCell({\n children: [\n new Paragraph({\n ...((tableConfig.keepInOnePage && !isLastRow) ||\n (isLastRow && tableConfig.keepNext)\n ? { keepNext: true }\n : {}),\n spacing: tableStyle.cellParagraph,\n alignment: AlignmentType.LEFT,\n children: [],\n }),\n ],\n borders: {\n top: createBorder(\n getBorderValue(\n mergedDefaultsForMissing.borderSize,\n 'top'\n ) as number,\n getBorderValue(\n mergedDefaultsForMissing.borderColor,\n 'top'\n ) as string,\n shouldHideBorder('top', position)\n ),\n bottom: createBorder(\n getBorderValue(\n mergedDefaultsForMissing.borderSize,\n 'bottom'\n ) as number,\n getBorderValue(\n mergedDefaultsForMissing.borderColor,\n 'bottom'\n ) as string,\n shouldHideBorder('bottom', position)\n ),\n left: createBorder(\n getBorderValue(\n mergedDefaultsForMissing.borderSize,\n 'left'\n ) as number,\n getBorderValue(\n mergedDefaultsForMissing.borderColor,\n 'left'\n ) as string,\n shouldHideBorder('left', position)\n ),\n right: createBorder(\n getBorderValue(\n mergedDefaultsForMissing.borderSize,\n 'right'\n ) as number,\n getBorderValue(\n mergedDefaultsForMissing.borderColor,\n 'right'\n ) as string,\n shouldHideBorder('right', position)\n ),\n },\n });\n }\n\n // Merge cell defaults with priority: cell > column > table outer border > table cellDefaults\n const mergedDefaults = mergeCellDefaults(\n tableConfig.cellDefaults,\n column.cellDefaults,\n cell,\n position,\n {\n borderColor: tableConfig.borderColor,\n borderSize: tableConfig.borderSize,\n }\n );\n\n const cellChildren = await processCellContent(\n cell.content,\n mergedDefaults,\n tableStyle.tableCell\n );\n\n const horizontalAlignment = mergedDefaults.horizontalAlignment!;\n const verticalAlignment = getVerticalAlignment(\n mergedDefaults.verticalAlignment\n );\n\n return new TableCell({\n children: [\n new Paragraph({\n ...((tableConfig.keepInOnePage && !isLastRow) ||\n (isLastRow && tableConfig.keepNext)\n ? { keepNext: true }\n : {}),\n spacing: tableStyle.cellParagraph,\n alignment: getAlignment(horizontalAlignment),\n children: cellChildren,\n }),\n ],\n verticalAlign: verticalAlignment,\n ...(mergedDefaults.backgroundColor !== 'transparent' && {\n shading: {\n fill: mergedDefaults.backgroundColor,\n },\n }),\n margins: createMarginsFromPadding(mergedDefaults.padding),\n borders: {\n top: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'top') as number,\n getBorderValue(mergedDefaults.borderColor, 'top') as string,\n shouldHideBorder('top', position)\n ),\n bottom: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'bottom') as number,\n getBorderValue(\n mergedDefaults.borderColor,\n 'bottom'\n ) as string,\n shouldHideBorder('bottom', position)\n ),\n left: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'left') as number,\n getBorderValue(mergedDefaults.borderColor, 'left') as string,\n shouldHideBorder('left', position)\n ),\n right: createBorder(\n getBorderValue(mergedDefaults.borderSize, 'right') as number,\n getBorderValue(mergedDefaults.borderColor, 'right') as string,\n shouldHideBorder('right', position)\n ),\n },\n });\n })\n ),\n });\n })\n );\n\n // Calculate column widths - if any column has explicit width, use DXA for all\n const hasExplicitWidths = columns.some((col) => col.width !== undefined);\n\n let columnWidths: number[];\n let tableWidth: {\n size: number;\n type: (typeof WidthType)[keyof typeof WidthType];\n };\n\n if (hasExplicitWidths) {\n // Use explicit widths in DXA (twips) - convert from points\n const widthUtils = await import('../utils/widthUtils');\n const { getAvailableWidthTwips, relativeLengthToTwips } = widthUtils;\n\n // Get available table width in twips (page width minus margins)\n const availableTableWidth = getAvailableWidthTwips(theme, themeName);\n\n // Convert explicit column widths (points or percentage strings) to twips\n const columnsWithExplicitWidthTwips = columns.map((col) =>\n col.width !== undefined\n ? relativeLengthToTwips(col.width, availableTableWidth)\n : undefined\n );\n\n // Calculate total width used by columns with explicit widths\n const totalExplicitWidth = columnsWithExplicitWidthTwips.reduce(\n (sum: number, w) => sum + (w || 0),\n 0\n );\n\n if (totalExplicitWidth > availableTableWidth) {\n console.warn(\n `[json-to-office] Column widths total (${totalExplicitWidth} twips) exceeds available table width (${availableTableWidth} twips). Table may overflow.`\n );\n }\n\n // Count columns without explicit width\n const columnsWithoutWidth = columns.filter(\n (col) => col.width === undefined\n ).length;\n\n // Calculate remaining space and distribute among columns without explicit width\n const remainingWidth = Math.max(\n 0,\n availableTableWidth - totalExplicitWidth\n );\n const defaultColumnWidth =\n columnsWithoutWidth > 0\n ? remainingWidth / columnsWithoutWidth\n : pointsToTwips(72); // Fallback to 1 inch if all columns have explicit widths\n\n // Assign widths: use explicit width (in twips) or calculated default\n columnWidths = columnsWithExplicitWidthTwips.map(\n (w) => w || defaultColumnWidth\n );\n const totalWidth = columnWidths.reduce((sum, w) => sum + w, 0);\n tableWidth = { size: totalWidth, type: WidthType.DXA };\n } else {\n // Use percentage-based equal distribution\n const percentPerColumn = 100 / columns.length;\n columnWidths = columns.map(() => percentPerColumn);\n tableWidth = { size: tableConfig.width ?? 100, type: WidthType.PERCENTAGE };\n }\n\n return new Table({\n width: tableWidth,\n layout: TableLayoutType.FIXED,\n columnWidths: columnWidths,\n rows: [headerRow, ...dataRows],\n });\n}\n\n/**\n * Convert alignment string to docx AlignmentType\n */\nfunction getAlignment(\n alignment: string\n): (typeof AlignmentType)[keyof typeof AlignmentType] {\n switch (alignment) {\n case 'center':\n return AlignmentType.CENTER;\n case 'right':\n return AlignmentType.RIGHT;\n case 'justify':\n return AlignmentType.JUSTIFIED;\n default:\n return AlignmentType.LEFT;\n }\n}\n\n/**\n * Convert vertical alignment string to docx VerticalAlign\n */\nfunction getVerticalAlignment(\n alignment: string | undefined\n):\n | typeof VerticalAlign.TOP\n | typeof VerticalAlign.CENTER\n | typeof VerticalAlign.BOTTOM\n | undefined {\n if (!alignment) return undefined;\n\n switch (alignment) {\n case 'top':\n return VerticalAlign.TOP;\n case 'middle':\n return VerticalAlign.CENTER;\n case 'bottom':\n return VerticalAlign.BOTTOM;\n default:\n return undefined;\n }\n}\n\n/**\n * Create header element from content\n */\nexport function createHeaderElement(\n children: (Paragraph | Table)[],\n _options?: {\n position?: 'left' | 'center' | 'right';\n }\n): Header {\n return new Header({\n children: children,\n });\n}\n\n/**\n * Create footer element from content\n */\nexport function createFooterElement(\n children: (Paragraph | Table)[],\n _options?: {\n position?: 'left' | 'center' | 'right';\n }\n): Footer {\n return new Footer({\n children: children,\n });\n}\n\n/**\n * Create page number element\n */\nexport function createPageNumberElement(\n format?: string,\n alignment?: 'left' | 'center' | 'right'\n): Paragraph {\n const children: PlaceholderChild[] = [];\n\n if (format) {\n // Use placeholder processor to handle {PAGE} and other placeholders\n children.push(...processTextWithPlaceholders(format, {}));\n } else {\n // Default: just page number\n children.push(\n new TextRun({\n children: [PageNumber.CURRENT],\n })\n );\n }\n\n return new Paragraph({\n alignment: getAlignment(alignment || 'center'),\n children,\n });\n}\n\n/**\n * Create mixed content paragraph with text and image elements\n */\nexport async function createMixedContentParagraph(\n textContent: string,\n textOptions: {\n fontSize?: number;\n color?: string;\n bold?: boolean;\n italic?: boolean;\n },\n imagePath?: string,\n imageOptions?: {\n width?: number;\n height?: number;\n },\n alignment?: 'left' | 'center' | 'right',\n theme?: import('../styles').ThemeConfig\n): Promise<Paragraph> {\n const children: (TextRun | ImageRun)[] = [];\n const normalizedTextContent = normalizeUnicodeText(textContent);\n\n // Add text content\n if (normalizedTextContent) {\n children.push(\n new TextRun({\n text: normalizedTextContent,\n font: theme ? getThemeFonts(theme).body.family : undefined,\n size: textOptions.fontSize ? textOptions.fontSize * 2 : 20, // Convert to half-points\n color:\n textOptions.color ||\n (theme ? getThemeColors(theme).textPrimary : undefined),\n bold: textOptions.bold || false,\n italics: textOptions.italic || false,\n })\n );\n }\n\n // Add image if provided\n if (imagePath) {\n try {\n const imageResult = await getImageBuffer(imagePath);\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imagePath,\n imageOptions?.width,\n imageOptions?.height,\n 60, // fallback width\n 20 // fallback height\n );\n\n const imgType = detectImageType(imagePath, imageResult.contentType);\n const imageRun = createTypedImageRun({\n type: imgType,\n data: imageResult.buffer,\n transformation: { width: dimensions.width, height: dimensions.height },\n });\n\n // Add some spacing before the image\n children.push(new TextRun({ text: ' ' }));\n children.push(imageRun);\n } catch (error) {\n // Fallback for missing images\n children.push(\n new TextRun({\n text: ` [IMAGE: ${imagePath}]`,\n font: theme ? getThemeFonts(theme).body.family : undefined,\n size: (textOptions.fontSize || 10) * 2,\n color: theme ? getThemeColors(theme).secondary : undefined,\n bold: true,\n })\n );\n }\n }\n\n return new Paragraph({\n alignment: getAlignment(alignment || 'left'),\n children,\n });\n}\n\n/**\n * Create a table specifically for headers/footers with custom styling\n */\n\nexport async function createHeaderFooterTable(\n rows: (string | ComponentDefinition)[][],\n options: {\n cellAlignments?: ('left' | 'center' | 'right')[];\n fontSize?: number;\n bold?: boolean;\n color?: string;\n noBorders?: boolean;\n cellStyling?: {\n [rowIndex: number]: {\n [cellIndex: number]: {\n bold?: boolean;\n color?: string;\n fontSize?: number;\n };\n };\n };\n theme?: ThemeConfig;\n themeName?: string;\n } = {}\n): Promise<Table> {\n const {\n cellAlignments = ['left', 'right'],\n fontSize = 10,\n bold = false,\n color = '#000000',\n noBorders = true,\n cellStyling = {},\n theme,\n } = options;\n\n // Use theme's normal style for header/footer text since header/footer styles are removed\n const normalStyle = theme?.styles?.normal;\n\n const defaultFont = theme\n ? resolveFontFamily(theme, normalStyle?.font)\n : 'Arial';\n const defaultSize = normalStyle?.size || fontSize;\n const defaultColor =\n normalStyle?.color && theme\n ? resolveColor(normalStyle.color, theme)\n : color;\n\n const tableRows = await Promise.all(\n rows.map(\n async (row, rowIndex) =>\n new TableRow({\n children: await Promise.all(\n row.map(async (cell, cellIndex) => {\n const alignment = cellAlignments[cellIndex] || 'left';\n const cellStyle = cellStyling[rowIndex]?.[cellIndex] || {};\n\n let paragraphChildren: (PlaceholderChild | ImageRun)[] = [];\n\n // Handle ComponentDefinition first\n if (\n typeof cell === 'object' &&\n 'name' in cell &&\n 'props' in cell\n ) {\n // This is a ComponentDefinition\n if (isParagraphComponent(cell)) {\n const textComp = cell as ParagraphComponentDefinition;\n // Use parseTextWithDecorators to support rich text formatting\n const textStyle = {\n font:\n textComp.props.font?.family || (defaultFont as string),\n size:\n ((textComp.props.font?.size || defaultSize) as number) *\n 2, // Convert to half-points\n bold: textComp.props.font?.bold ?? false,\n color:\n (textComp.props.font?.color && theme\n ? resolveColor(textComp.props.font.color, theme)\n : undefined) || defaultColor,\n } as const;\n paragraphChildren = parseTextWithDecorators(\n textComp.props.text,\n textStyle,\n { enableHyperlinks: true }\n );\n } else if (isImageComponent(cell)) {\n const imageComp = cell as ImageComponentDefinition;\n try {\n // Get image source (svg, base64, or path)\n const imageSource = resolveImageSource(imageComp.props);\n if (!imageSource) {\n throw new Error(\n 'Image component requires one of \"path\", \"base64\", or \"svg\" property'\n );\n }\n\n // Read from local file, URL, or base64\n const imageResult = await getImageBuffer(imageSource);\n\n // Parse width value if it's a string percentage (like \"90%\")\n const parsedWidth =\n typeof imageComp.props.width === 'string'\n ? parseWidthValue(imageComp.props.width, 300) // Use a reasonable default for table context\n : imageComp.props.width;\n\n // Parse height value if it's a string percentage (like \"90%\")\n const parsedHeight =\n typeof imageComp.props.height === 'string'\n ? parseWidthValue(imageComp.props.height, 200) // Use a reasonable default for table context\n : imageComp.props.height;\n\n // Calculate dimensions with aspect ratio preservation\n const dimensions = await calculateImageDimensions(\n imageSource,\n parsedWidth,\n parsedHeight,\n 60, // fallback width\n 20 // fallback height\n );\n\n const imgType = detectImageType(\n imageSource,\n imageResult.contentType\n );\n const imageRun = createTypedImageRun({\n type: imgType,\n data: imageResult.buffer,\n transformation: {\n width: dimensions.width,\n height: dimensions.height,\n },\n });\n paragraphChildren = [imageRun];\n } catch (error) {\n // Fallback for missing images\n const imageSource = imageComp.props.svg?.trim()\n ? 'inline-svg'\n : imageComp.props.base64 ||\n imageComp.props.path ||\n 'unknown';\n paragraphChildren = [\n new TextRun({\n text: `[IMAGE: ${imageSource.substring(0, 50)}${imageSource.length > 50 ? '...' : ''}]`,\n size: fontSize * 2,\n bold: true,\n color: '#999999',\n }),\n ];\n }\n } else {\n // Unsupported component type in table cell\n paragraphChildren = [\n new TextRun({\n text: `[Unsupported component type: ${cell.name}]`,\n size: fontSize * 2,\n color: '#999999',\n }),\n ];\n }\n } else if (typeof cell === 'string') {\n // Handle plain string text (including placeholders)\n const textStyle = {\n font: defaultFont,\n size: (cellStyle.fontSize || defaultSize) * 2,\n bold: cellStyle.bold !== undefined ? cellStyle.bold : bold,\n color: cellStyle.color || defaultColor,\n };\n\n // Use parseTextWithDecorators which now handles both decorators and placeholders\n paragraphChildren = parseTextWithDecorators(cell, textStyle, {\n enableHyperlinks: true,\n });\n }\n\n return new TableCell({\n children: [\n new Paragraph({\n alignment: getAlignment(alignment),\n children: paragraphChildren,\n }),\n ],\n margins: {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n borders: noBorders\n ? {\n top: { style: BorderStyle.NONE, size: 0 },\n bottom: { style: BorderStyle.NONE, size: 0 },\n left: { style: BorderStyle.NONE, size: 0 },\n right: { style: BorderStyle.NONE, size: 0 },\n }\n : undefined,\n });\n })\n ),\n })\n )\n );\n\n return new Table({\n width: { size: 100, type: WidthType.PERCENTAGE },\n layout: TableLayoutType.FIXED, // Lock column widths to prevent horizontal resizing\n rows: tableRows,\n borders: noBorders\n ? {\n top: { style: BorderStyle.NONE, size: 0 },\n bottom: { style: BorderStyle.NONE, size: 0 },\n left: { style: BorderStyle.NONE, size: 0 },\n right: { style: BorderStyle.NONE, size: 0 },\n insideHorizontal: { style: BorderStyle.NONE, size: 0 },\n insideVertical: { style: BorderStyle.NONE, size: 0 },\n }\n : undefined,\n });\n}\n","/**\n * Bookmark Registry\n * Utilities for managing document bookmarks for internal hyperlinks\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface BookmarkInfo {\n id: string;\n title: string;\n type: string; // e.g., 'heading', 'paragraph', 'table', etc.\n}\n\ninterface BookmarkState {\n bookmarks: Map<string, BookmarkInfo>;\n}\n\n/**\n * Registry for managing document bookmarks\n * Used to track bookmark IDs and validate internal hyperlink targets\n */\nexport class BookmarkRegistry {\n private readonly fallback: BookmarkState = { bookmarks: new Map() };\n private readonly scopes = new AsyncLocalStorage<BookmarkState>();\n\n private get state(): BookmarkState {\n return this.scopes.getStore() ?? this.fallback;\n }\n\n /** Run work with an isolated registry that follows its async call chain. */\n runScoped<T>(callback: () => T): T {\n return this.scopes.run({ bookmarks: new Map() }, callback);\n }\n\n /**\n * Register a bookmark\n */\n register(id: string, title: string, type: string): void {\n if (this.state.bookmarks.has(id)) {\n console.warn(\n `Duplicate bookmark ID: ${id}. Using the latest registration.`\n );\n }\n this.state.bookmarks.set(id, { id, title, type });\n }\n\n /**\n * Generate a unique bookmark ID from text\n * Converts text to a URL-friendly format\n */\n generateId(text: string, _type: string = 'bookmark'): string {\n // Convert to lowercase, replace spaces with hyphens, remove special characters\n const baseId = text\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .substring(0, 40); // Limit length\n\n // Ensure uniqueness by appending counter if needed\n let id = baseId;\n let attempt = 0;\n while (this.state.bookmarks.has(id) && attempt < 100) {\n id = `${baseId}-${++attempt}`;\n }\n\n return id;\n }\n\n /**\n * Check if a bookmark exists\n */\n exists(id: string): boolean {\n return this.state.bookmarks.has(id);\n }\n\n /**\n * Get bookmark info by ID\n */\n get(id: string): BookmarkInfo | undefined {\n return this.state.bookmarks.get(id);\n }\n\n /**\n * Get all registered bookmarks\n */\n getAll(): BookmarkInfo[] {\n return Array.from(this.state.bookmarks.values());\n }\n\n /**\n * Clear all bookmarks\n */\n clear(): void {\n this.state.bookmarks.clear();\n }\n\n /**\n * Validate that all internal hyperlink references exist\n * Returns array of missing bookmark IDs\n */\n validateReferences(referencedIds: string[]): string[] {\n const missing: string[] = [];\n for (const id of referencedIds) {\n if (!this.exists(id)) {\n missing.push(id);\n }\n }\n return missing;\n }\n}\n\n// Global registry instance\nexport const globalBookmarkRegistry = new BookmarkRegistry();\n","/**\n * Heading Component\n * Standard component for rendering heading elements in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isHeadingComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createHeading } from '../core/content';\nimport { globalBookmarkRegistry } from '../utils/bookmarkRegistry';\n\n/**\n * Render heading component\n */\nexport function renderHeadingComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): Paragraph[] {\n if (!isHeadingComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree (componentDefaults + level-specific defaults)\n const config = component.props;\n\n // Generate or use bookmark ID for internal linking\n // If component has id, use it; otherwise generate from heading text\n const bookmarkId =\n (component as any).id ||\n globalBookmarkRegistry.generateId(config.text, 'heading');\n\n // Create heading with optional column break and bookmark\n const header = createHeading(\n config.text,\n config.level || 1,\n theme,\n themeName,\n {\n alignment: config.alignment,\n spacing: config.spacing,\n lineSpacing: config.lineSpacing,\n columnBreak: config.columnBreak,\n // Local font overrides\n fontFamily: config.font?.family,\n fontSize: config.font?.size,\n fontColor: config.font?.color,\n bold: config.font?.bold,\n fontWeight: (config.font as { fontWeight?: number } | undefined)\n ?.fontWeight,\n italic: config.font?.italic,\n underline: config.font?.underline,\n scale: config.font?.scale,\n characterSpacing: config.font?.characterSpacing,\n // Proofing: local language override + no-proof toggle + known-words list\n language: config.language,\n noProof: config.noProof,\n noProofWords: config.noProofWords,\n // Pagination control\n keepNext: config.keepNext,\n keepLines: config.keepLines,\n // Paragraph indentation (w:ind) in twips\n indent: config.indent,\n // Bookmark ID for internal linking\n bookmarkId: bookmarkId,\n // Tracked-change segments (rendered as native Word revisions)\n revision: config.revision,\n }\n );\n\n return [header];\n}\n","/**\n * Numbering Configuration Utilities\n * Utilities for creating and managing docx numbering configurations\n */\n\nimport { AlignmentType, convertInchesToTwip, LevelFormat } from 'docx';\nimport type { ILevelsOptions } from 'docx';\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\n// Type mapping from schema strings to docx LevelFormat values\nconst LEVEL_FORMAT_MAP: Record<\n string,\n (typeof LevelFormat)[keyof typeof LevelFormat]\n> = {\n decimal: LevelFormat.DECIMAL,\n upperRoman: LevelFormat.UPPER_ROMAN,\n lowerRoman: LevelFormat.LOWER_ROMAN,\n upperLetter: LevelFormat.UPPER_LETTER,\n lowerLetter: LevelFormat.LOWER_LETTER,\n bullet: LevelFormat.BULLET,\n ordinal: LevelFormat.ORDINAL,\n cardinalText: LevelFormat.CARDINAL_TEXT,\n ordinalText: LevelFormat.ORDINAL_TEXT,\n hex: LevelFormat.HEX,\n chicago: LevelFormat.CHICAGO,\n ideographDigital: LevelFormat.IDEOGRAPH__DIGITAL,\n japaneseCounting: LevelFormat.JAPANESE_COUNTING,\n aiueo: LevelFormat.AIUEO,\n iroha: LevelFormat.IROHA,\n decimalFullWidth: LevelFormat.DECIMAL_FULL_WIDTH,\n decimalHalfWidth: LevelFormat.DECIMAL_HALF_WIDTH,\n japaneseLegal: LevelFormat.JAPANESE_LEGAL,\n japaneseDigitalTenThousand: LevelFormat.JAPANESE_DIGITAL_TEN_THOUSAND,\n decimalEnclosedCircle: LevelFormat.DECIMAL_ENCLOSED_CIRCLE,\n decimalFullWidth2: LevelFormat.DECIMAL_FULL_WIDTH2,\n aiueoFullWidth: LevelFormat.AIUEO_FULL_WIDTH,\n irohaFullWidth: LevelFormat.IROHA_FULL_WIDTH,\n decimalZero: LevelFormat.DECIMAL_ZERO,\n ganada: LevelFormat.GANADA,\n chosung: LevelFormat.CHOSUNG,\n decimalEnclosedFullstop: LevelFormat.DECIMAL_ENCLOSED_FULLSTOP,\n decimalEnclosedParen: LevelFormat.DECIMAL_ENCLOSED_PARENTHESES,\n decimalEnclosedCircleChinese: LevelFormat.DECIMAL_ENCLOSED_CIRCLE_CHINESE,\n ideographEnclosedCircle: LevelFormat.IDEOGRAPH_ENCLOSED_CIRCLE,\n ideographTraditional: LevelFormat.IDEOGRAPH_TRADITIONAL,\n ideographZodiac: LevelFormat.IDEOGRAPH_ZODIAC,\n ideographZodiacTraditional: LevelFormat.IDEOGRAPH_ZODIAC_TRADITIONAL,\n taiwaneseCounting: LevelFormat.TAIWANESE_COUNTING,\n ideographLegalTraditional: LevelFormat.IDEOGRAPH_LEGAL_TRADITIONAL,\n taiwaneseCountingThousand: LevelFormat.TAIWANESE_COUNTING_THOUSAND,\n taiwaneseDigital: LevelFormat.TAIWANESE_DIGITAL,\n chineseCounting: LevelFormat.CHINESE_COUNTING,\n chineseLegalSimplified: LevelFormat.CHINESE_LEGAL_SIMPLIFIED,\n chineseCountingThousand: LevelFormat.CHINESE_COUNTING_THOUSAND,\n koreanDigital: LevelFormat.KOREAN_DIGITAL,\n koreanCounting: LevelFormat.KOREAN_COUNTING,\n koreanLegal: LevelFormat.KOREAN_LEGAL,\n koreanDigital2: LevelFormat.KOREAN_DIGITAL2,\n vietnameseCounting: LevelFormat.VIETNAMESE_COUNTING,\n russianLower: LevelFormat.RUSSIAN_LOWER,\n russianUpper: LevelFormat.RUSSIAN_UPPER,\n none: LevelFormat.NONE,\n numberInDash: LevelFormat.NUMBER_IN_DASH,\n hebrew1: LevelFormat.HEBREW1,\n hebrew2: LevelFormat.HEBREW2,\n arabicAlpha: LevelFormat.ARABIC_ALPHA,\n arabicAbjad: LevelFormat.ARABIC_ABJAD,\n hindiVowels: LevelFormat.HINDI_VOWELS,\n hindiConsonants: LevelFormat.HINDI_CONSONANTS,\n hindiNumbers: LevelFormat.HINDI_NUMBERS,\n hindiCounting: LevelFormat.HINDI_COUNTING,\n thaiLetters: LevelFormat.THAI_LETTERS,\n thaiNumbers: LevelFormat.THAI_NUMBERS,\n thaiCounting: LevelFormat.THAI_COUNTING,\n};\n\nconst ALIGNMENT_MAP: Record<\n string,\n (typeof AlignmentType)[keyof typeof AlignmentType]\n> = {\n start: AlignmentType.START,\n end: AlignmentType.END,\n left: AlignmentType.LEFT,\n right: AlignmentType.RIGHT,\n center: AlignmentType.CENTER,\n};\n\nexport interface ListLevelConfig {\n level: number;\n format?: string;\n text?: string;\n alignment?: string;\n indent?: {\n left?: number;\n hanging?: number;\n };\n start?: number;\n}\n\nexport interface NumberingConfig {\n reference: string;\n levels: ListLevelConfig[];\n}\n\ntype RegisteredNumberingConfig = {\n levels: ILevelsOptions[];\n reference: string;\n};\n\ninterface NumberingState {\n configs: Map<string, RegisteredNumberingConfig>;\n counter: number;\n}\n\n/**\n * Convert schema format string to docx LevelFormat\n */\nfunction getLevelFormat(\n format?: string\n): (typeof LevelFormat)[keyof typeof LevelFormat] {\n if (!format) return LevelFormat.BULLET;\n return LEVEL_FORMAT_MAP[format] || LevelFormat.BULLET;\n}\n\n/**\n * Convert schema alignment string to docx AlignmentType\n */\nfunction getAlignment(\n alignment?: string\n): (typeof AlignmentType)[keyof typeof AlignmentType] {\n if (!alignment) return AlignmentType.LEFT;\n return ALIGNMENT_MAP[alignment] || AlignmentType.LEFT;\n}\n\n/**\n * Create a default level configuration for a given level number\n */\nfunction createDefaultLevel(\n level: number,\n format: (typeof LevelFormat)[keyof typeof LevelFormat] = LevelFormat.BULLET,\n text?: string\n): ILevelsOptions {\n const baseIndent = 0.5 * (level + 1); // Increase indent for each level\n const hangingIndent = 0.25;\n\n return {\n level,\n format,\n text: text || (format === LevelFormat.BULLET ? '•' : '%1.'),\n alignment: AlignmentType.LEFT,\n style: {\n paragraph: {\n indent: {\n left: convertInchesToTwip(baseIndent),\n hanging: convertInchesToTwip(hangingIndent),\n },\n },\n },\n };\n}\n\n/**\n * Create numbering configuration from list config\n * Returns a single config item that can be added to INumberingOptions.config array\n */\nexport function createNumberingConfig(config: NumberingConfig): {\n levels: ILevelsOptions[];\n reference: string;\n} {\n const levels: ILevelsOptions[] = [];\n\n // Process each level\n for (const levelConfig of config.levels) {\n const format = getLevelFormat(levelConfig.format);\n const alignment = getAlignment(levelConfig.alignment);\n const text =\n levelConfig.text ||\n (format === LevelFormat.BULLET ? '•' : `%${levelConfig.level + 1}.`);\n\n // Calculate indentation\n const baseIndent =\n levelConfig.indent?.left !== undefined\n ? levelConfig.indent.left / 72 // Convert points to inches\n : 0.5 * (levelConfig.level + 1);\n\n const hangingIndent =\n levelConfig.indent?.hanging !== undefined\n ? levelConfig.indent.hanging / 72 // Convert points to inches\n : 0.25;\n\n const level: ILevelsOptions = {\n level: levelConfig.level,\n format,\n text,\n alignment,\n style: {\n paragraph: {\n indent: {\n left: convertInchesToTwip(baseIndent),\n hanging: convertInchesToTwip(hangingIndent),\n },\n },\n },\n // Add start number if specified\n ...(levelConfig.start !== undefined && { start: levelConfig.start }),\n };\n\n levels.push(level);\n }\n\n return {\n reference: config.reference,\n levels,\n };\n}\n\n/**\n * Create a simple bullet list configuration\n */\nexport function createBulletListConfig(\n reference: string,\n bullet: string = '•'\n): { levels: ILevelsOptions[]; reference: string } {\n return {\n reference,\n levels: [\n createDefaultLevel(0, LevelFormat.BULLET, bullet),\n createDefaultLevel(1, LevelFormat.BULLET, '◦'),\n createDefaultLevel(2, LevelFormat.BULLET, '▪'),\n ],\n };\n}\n\n/**\n * Create a simple numbered list configuration\n */\nexport function createNumberedListConfig(\n reference: string,\n start: number = 1\n): { levels: ILevelsOptions[]; reference: string } {\n return {\n reference,\n levels: [\n { ...createDefaultLevel(0, LevelFormat.DECIMAL, '%1.'), start },\n createDefaultLevel(1, LevelFormat.LOWER_LETTER, '%2.'),\n createDefaultLevel(2, LevelFormat.LOWER_ROMAN, '%3.'),\n ],\n };\n}\n\n/**\n * Registry for managing numbering configurations\n */\nexport class NumberingRegistry {\n private readonly fallback: NumberingState = {\n configs: new Map(),\n counter: 0,\n };\n private readonly scopes = new AsyncLocalStorage<NumberingState>();\n\n private get state(): NumberingState {\n return this.scopes.getStore() ?? this.fallback;\n }\n\n /** Run work with an isolated registry that follows its async call chain. */\n runScoped<T>(callback: () => T): T {\n return this.scopes.run({ configs: new Map(), counter: 0 }, callback);\n }\n\n /**\n * Register a numbering configuration\n */\n register(config: { levels: ILevelsOptions[]; reference: string }): string {\n const reference = config.reference;\n this.state.configs.set(reference, config);\n return reference;\n }\n\n /**\n * Generate a unique reference ID\n */\n generateReference(prefix: string = 'list'): string {\n return `${prefix}-${++this.state.counter}`;\n }\n\n /**\n * Get all registered configurations as an array suitable for INumberingOptions\n */\n getAll(): { levels: ILevelsOptions[]; reference: string }[] {\n return Array.from(this.state.configs.values());\n }\n\n /**\n * Clear all configurations\n */\n clear(): void {\n this.state.configs.clear();\n this.state.counter = 0;\n }\n\n /**\n * Check if a reference exists\n */\n has(reference: string): boolean {\n return this.state.configs.has(reference);\n }\n\n /**\n * Get a configuration by reference\n */\n get(\n reference: string\n ): { levels: ILevelsOptions[]; reference: string } | undefined {\n return this.state.configs.get(reference);\n }\n}\n\n// Global registry instance\nexport const globalNumberingRegistry = new NumberingRegistry();\n","/**\n * Paragraph Component\n * Standard component for rendering paragraph content in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isParagraphComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createText, createList } from '../core/content';\nimport {\n globalNumberingRegistry,\n createNumberingConfig,\n type NumberingConfig,\n type ListLevelConfig,\n} from '../utils/numberingConfig';\n\n/**\n * Parse markdown list syntax from paragraph text\n * Returns null if no list detected, or { type, items } if list found\n */\nfunction parseMarkdownList(text: string): {\n type: 'unordered' | 'ordered';\n items: { text: string; level: number }[];\n} | null {\n const lines = text.split('\\n');\n const items: { text: string; level: number }[] = [];\n let isUnordered: boolean | null = null;\n let isOrdered: boolean | null = null;\n\n for (const line of lines) {\n // Skip empty lines\n if (!line.trim()) continue;\n\n // Match unordered list: optional spaces + (- or *) + space + text\n const unorderedMatch = line.match(/^(\\s*)([-*])\\s+(.+)$/);\n if (unorderedMatch) {\n const indentLevel = Math.floor(unorderedMatch[1].length / 2); // 2 spaces = 1 level\n const text = unorderedMatch[3];\n items.push({ text, level: indentLevel });\n if (isUnordered === null) isUnordered = true;\n continue;\n }\n\n // Match ordered list: optional spaces + number + . + space + text\n const orderedMatch = line.match(/^(\\s*)(\\d+)\\.\\s+(.+)$/);\n if (orderedMatch) {\n const indentLevel = Math.floor(orderedMatch[1].length / 2); // 2 spaces = 1 level\n const text = orderedMatch[3];\n items.push({ text, level: indentLevel });\n if (isOrdered === null) isOrdered = true;\n continue;\n }\n\n // If we find a line that doesn't match list syntax, this isn't a list\n return null;\n }\n\n // If no items found, or mixed list types, not a valid list\n if (items.length === 0 || (isUnordered && isOrdered)) {\n return null;\n }\n\n return {\n type: isUnordered ? 'unordered' : 'ordered',\n items,\n };\n}\n\n/**\n * Render paragraph component\n */\nexport function renderParagraphComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): Paragraph[] {\n if (!isParagraphComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree\n const resolvedConfig = component.props;\n\n // Check if text contains markdown list syntax.\n // Revision paragraphs always render as plain text: their segments carry\n // literal text and cannot be re-split into list items.\n const listData = resolvedConfig.revision\n ? null\n : parseMarkdownList(resolvedConfig.text);\n\n if (listData) {\n // Text is a markdown list - render as proper docx list\n const reference =\n globalNumberingRegistry.generateReference('markdown-list');\n\n // Create appropriate numbering configuration\n const levels: ListLevelConfig[] = [];\n\n if (listData.type === 'unordered') {\n // Bullet list with different bullets for each level\n levels.push(\n { level: 0, format: 'bullet', text: '•', alignment: 'left' },\n { level: 1, format: 'bullet', text: '◦', alignment: 'left' },\n { level: 2, format: 'bullet', text: '▪', alignment: 'left' }\n );\n } else {\n // Ordered list with decimal, lowercase letter, lowercase roman\n levels.push(\n { level: 0, format: 'decimal', text: '%1.', alignment: 'left' },\n { level: 1, format: 'lowerLetter', text: '%2.', alignment: 'left' },\n { level: 2, format: 'lowerRoman', text: '%3.', alignment: 'left' }\n );\n }\n\n const numberingConfig: NumberingConfig = {\n reference,\n levels,\n };\n\n globalNumberingRegistry.register(createNumberingConfig(numberingConfig));\n\n // Create list paragraphs\n return createList(listData.items, theme, themeName, {\n numberingReference: reference,\n spacing: resolvedConfig.spacing as\n | { before?: number; after?: number; item?: number }\n | undefined,\n alignment: resolvedConfig.alignment,\n });\n }\n\n // Not a list - render as regular text paragraph\n // Map themeStyle (theme logical name) to DOCX style id\n // Supports both predefined styles and custom styles from theme.styles\n const styleFromTheme = (() => {\n const key = resolvedConfig.themeStyle;\n if (!key) return undefined;\n\n const lowerKey = key.toLowerCase();\n\n // Map predefined style names to Word style IDs\n if (lowerKey === 'normal') return 'Normal';\n if (lowerKey === 'title') return 'Title';\n if (lowerKey === 'subtitle') return 'Subtitle';\n const headingMatch = lowerKey.match(/^heading([1-6])$/);\n if (headingMatch) {\n // For paragraph components, use display-only heading styles that are visually\n // identical but do NOT participate in TOC/outline levels\n return `JTD_HeadingText${headingMatch[1]}`;\n }\n\n // For custom styles, use the exact key as the style ID\n // Custom styles are registered in themeToDocxAdapter with their exact key as ID\n return key;\n })();\n\n // Extract outline level from style if present (for TOC support)\n const outlineLevel = (() => {\n const key = resolvedConfig.themeStyle;\n if (!key) return undefined;\n\n // Never contribute paragraph component paragraphs to TOC when using heading styles\n // Even if the theme sets outlineLevel for heading styles, ignore it here\n const lowerKey = key.toLowerCase();\n const headingMatch = lowerKey.match(/^heading([1-6])$/);\n if (headingMatch) return undefined;\n\n // Check if this is a custom style with outline level\n const customStyle = theme.styles?.[key as keyof typeof theme.styles];\n if (\n customStyle &&\n typeof customStyle === 'object' &&\n 'outlineLevel' in customStyle\n ) {\n return (customStyle as any).outlineLevel;\n }\n\n return undefined;\n })();\n\n // Create text paragraph with optional column break and floating positioning\n const text = createText(resolvedConfig.text, theme, themeName, {\n style: styleFromTheme,\n spacing: resolvedConfig.spacing as\n | { before?: number; after?: number }\n | undefined,\n lineSpacing: resolvedConfig.font?.lineSpacing,\n alignment: resolvedConfig.alignment,\n boldColor: resolvedConfig.boldColor,\n columnBreak: resolvedConfig.columnBreak,\n // Pass font properties\n fontFamily: resolvedConfig.font?.family,\n fontSize: resolvedConfig.font?.size,\n fontColor: resolvedConfig.font?.color,\n bold: resolvedConfig.font?.bold,\n fontWeight: (resolvedConfig.font as { fontWeight?: number } | undefined)\n ?.fontWeight,\n italic: resolvedConfig.font?.italic,\n underline: resolvedConfig.font?.underline,\n scale: resolvedConfig.font?.scale,\n characterSpacing: resolvedConfig.font?.characterSpacing,\n // Proofing: local language override + no-proof toggle + known-words list\n language: resolvedConfig.language,\n noProof: resolvedConfig.noProof,\n noProofWords: resolvedConfig.noProofWords,\n // Pass outline level for TOC support\n outlineLevel: outlineLevel,\n // Pass floating positioning properties\n floating: resolvedConfig.floating,\n // Pass keepNext property\n keepNext: resolvedConfig.keepNext,\n // Pass keepLines property\n keepLines: resolvedConfig.keepLines,\n // Paragraph indentation (w:ind) in twips\n indent: resolvedConfig.indent,\n // Tab stops (w:tabs); \\t characters in text jump to these positions\n tabStops: resolvedConfig.tabStops,\n // Pass bookmark ID for internal linking\n bookmarkId: resolvedConfig.id,\n // Tracked-change segments (rendered as native Word revisions)\n revision: resolvedConfig.revision,\n });\n\n return [text];\n}\n","/**\n * List Component\n * Standard component for rendering list elements in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isListComponent, ListProps } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createList } from '../core/content';\nimport {\n globalNumberingRegistry,\n createNumberingConfig,\n type NumberingConfig,\n type ListLevelConfig,\n} from '../utils/numberingConfig';\n\n/**\n * Convert simplified format to proper level configurations\n */\nfunction createLevelsFromSimplifiedProps(props: ListProps): ListLevelConfig[] {\n const levels: ListLevelConfig[] = [];\n\n // Determine format from simplified options\n let format: string;\n let text: string | undefined;\n\n if (props.format) {\n if (props.format === 'numbered') {\n format = 'decimal';\n text = '%1.';\n } else if (props.format === 'none') {\n format = 'none';\n text = '';\n } else {\n format = props.format;\n }\n } else {\n // Default to bullet\n format = 'bullet';\n text = props.bullet || '•';\n }\n\n // Create level 0 configuration\n const level0: ListLevelConfig = {\n level: 0,\n format,\n text,\n alignment: 'left',\n start: props.start,\n };\n\n // Add indent if specified\n if (props.indent) {\n if (typeof props.indent === 'number') {\n level0.indent = { left: props.indent };\n } else {\n level0.indent = props.indent;\n }\n }\n\n levels.push(level0);\n\n // Add default sublevels for nested lists\n if (format === 'bullet') {\n levels.push(\n { level: 1, format: 'bullet', text: '◦', alignment: 'left' },\n { level: 2, format: 'bullet', text: '▪', alignment: 'left' }\n );\n } else if (format === 'decimal') {\n levels.push(\n { level: 1, format: 'lowerLetter', text: '%2.', alignment: 'left' },\n { level: 2, format: 'lowerRoman', text: '%3.', alignment: 'left' }\n );\n }\n\n return levels;\n}\n\n/**\n * Get the maximum level used in list items\n */\nfunction getMaxLevelFromItems(\n items: (string | { text: string; level?: number })[] | undefined\n): number {\n if (!items || !Array.isArray(items)) {\n return 0;\n }\n\n let maxLevel = 0;\n for (const item of items) {\n if (typeof item === 'object' && item.level !== undefined) {\n maxLevel = Math.max(maxLevel, item.level);\n }\n }\n return maxLevel;\n}\n\n/**\n * Fill in missing levels with default configurations\n */\nfunction fillMissingLevels(\n levels: ListLevelConfig[],\n maxLevel: number\n): ListLevelConfig[] {\n // Create a map of existing levels\n const levelMap = new Map<number, ListLevelConfig>();\n for (const level of levels) {\n levelMap.set(level.level, level);\n }\n\n // Get level 0 to determine the base format\n const level0 = levelMap.get(0);\n const baseFormat = level0?.format || 'bullet';\n\n // Create default levels for any missing ones\n const result: ListLevelConfig[] = [];\n for (let i = 0; i <= maxLevel; i++) {\n if (levelMap.has(i)) {\n result.push(levelMap.get(i)!);\n } else {\n // Create default sublevel based on parent format\n if (baseFormat === 'bullet') {\n const bullets = ['•', '◦', '▪', '▫', '‣'];\n result.push({\n level: i,\n format: 'bullet',\n text: bullets[i % bullets.length],\n alignment: 'left',\n });\n } else if (baseFormat === 'decimal' || baseFormat === 'numbered') {\n const formats = ['decimal', 'lowerLetter', 'lowerRoman'];\n const format = formats[i % formats.length];\n result.push({\n level: i,\n format,\n text: `%${i + 1}.`,\n alignment: 'left',\n });\n } else {\n // For other formats, continue with the same format\n result.push({\n level: i,\n format: baseFormat,\n text: `%${i + 1}.`,\n alignment: 'left',\n });\n }\n }\n }\n\n return result;\n}\n\n/**\n * Render list component\n */\nexport function renderListComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): Paragraph[] {\n if (!isListComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree\n const resolvedConfig = component.props;\n\n // Determine the maximum level needed from items\n const maxLevel = getMaxLevelFromItems(resolvedConfig.items);\n\n // Generate or use provided reference ID\n const reference =\n resolvedConfig.reference ||\n globalNumberingRegistry.generateReference('list');\n\n // Build numbering configuration if not already registered\n if (!globalNumberingRegistry.has(reference)) {\n let levels: ListLevelConfig[];\n\n if (resolvedConfig.levels && resolvedConfig.levels.length > 0) {\n // Use explicit level configurations, filling in missing levels\n levels = fillMissingLevels(\n resolvedConfig.levels as ListLevelConfig[],\n maxLevel\n );\n } else {\n // Build from simplified options\n const baseLevels = createLevelsFromSimplifiedProps(resolvedConfig);\n levels = fillMissingLevels(baseLevels, maxLevel);\n }\n\n const config: NumberingConfig = {\n reference,\n levels,\n };\n const numberingConfig = createNumberingConfig(config);\n globalNumberingRegistry.register(numberingConfig);\n }\n\n // Create the list paragraphs with numbering reference\n return createList(resolvedConfig.items, theme, themeName, {\n numberingReference: reference,\n spacing: resolvedConfig.spacing,\n alignment: resolvedConfig.alignment,\n });\n}\n","/**\n * Image Component\n * Standard component for rendering images in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isImageComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createImage } from '../core/content';\nimport { resolveImageSource } from '../utils/imageUtils';\n\n/**\n * Render image component\n */\nexport async function renderImageComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName?: string\n): Promise<Paragraph[]> {\n if (!isImageComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree\n const resolvedConfig = component.props;\n\n // Resolve source: inline svg > base64 > path\n const imageSource = resolveImageSource(resolvedConfig);\n\n if (!imageSource) {\n throw new Error(\n 'Image component requires one of \"path\", \"base64\", or \"svg\" property'\n );\n }\n\n return await createImage(imageSource, theme, themeName, {\n caption: resolvedConfig.caption,\n width: resolvedConfig.width,\n height: resolvedConfig.height,\n widthRelativeTo: (resolvedConfig as any).widthRelativeTo,\n heightRelativeTo: (resolvedConfig as any).heightRelativeTo,\n alignment: resolvedConfig.alignment,\n spacing: resolvedConfig.spacing,\n floating: resolvedConfig.floating,\n keepNext: resolvedConfig.keepNext,\n keepLines: resolvedConfig.keepLines,\n });\n}\n","/**\n * Text Box Component\n * Floating container that groups child paragraphs (from text/image components)\n */\n\nimport {\n Paragraph,\n Table,\n TableRow,\n TableCell,\n WidthType,\n TableAnchorType,\n RelativeHorizontalPosition,\n RelativeVerticalPosition,\n OverlapType,\n TableLayoutType,\n} from 'docx';\nimport {\n ComponentDefinition,\n TextBoxComponentDefinition,\n isTextBoxComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\n// No direct image or text parsing here; children components render themselves\nimport { renderComponent } from '../core/render';\nimport { NONE_BORDERS } from '../styles/utils/borderUtils';\nimport { buildCellOptions, CellStyleConfig } from '../styles/utils/cellUtils';\nimport {\n resolveOffsetTwips,\n getPageWidthTwips,\n getPageHeightTwips,\n getAvailableWidthTwips,\n getAvailableHeightTwips,\n} from '../utils/widthUtils';\n\n// VML style helpers removed in favor of floating table approach\n\n// Map floating config to docx paragraph frame options to enforce wrapping at paragraph level\n\n// Map floating config to table float options for a one-cell table container\nfunction mapTableFloatOptions(\n floating?: NonNullable<TextBoxComponentDefinition['props']['floating']>,\n theme?: ThemeConfig,\n themeName?: string\n): any | undefined {\n if (!floating) return undefined;\n\n const opt: any = {};\n\n // Determine reference dimensions for percentage resolution\n const hRelative = floating.horizontalPosition?.relative;\n const vRelative = floating.verticalPosition?.relative;\n const hRef =\n hRelative && hRelative !== 'page'\n ? getAvailableWidthTwips(theme, themeName)\n : getPageWidthTwips(theme, themeName);\n const vRef =\n vRelative && vRelative !== 'page'\n ? getAvailableHeightTwips(theme, themeName)\n : getPageHeightTwips(theme, themeName);\n\n const hp = floating.horizontalPosition;\n if (hp?.relative) {\n opt.horizontalAnchor =\n hp.relative === 'margin'\n ? TableAnchorType.MARGIN\n : hp.relative === 'page'\n ? TableAnchorType.PAGE\n : TableAnchorType.TEXT;\n }\n if (hp?.offset !== undefined) {\n opt.absoluteHorizontalPosition = resolveOffsetTwips(hp.offset, hRef);\n } else if (hp?.align) {\n const map: Record<\n string,\n (typeof RelativeHorizontalPosition)[keyof typeof RelativeHorizontalPosition]\n > = {\n left: RelativeHorizontalPosition.LEFT,\n center: RelativeHorizontalPosition.CENTER,\n right: RelativeHorizontalPosition.RIGHT,\n inside: RelativeHorizontalPosition.INSIDE,\n outside: RelativeHorizontalPosition.OUTSIDE,\n };\n opt.relativeHorizontalPosition = map[hp.align];\n }\n\n const vp = floating.verticalPosition;\n if (vp?.relative) {\n opt.verticalAnchor =\n vp.relative === 'margin'\n ? TableAnchorType.MARGIN\n : vp.relative === 'page'\n ? TableAnchorType.PAGE\n : TableAnchorType.TEXT;\n }\n if (vp?.offset !== undefined) {\n opt.absoluteVerticalPosition = resolveOffsetTwips(vp.offset, vRef);\n } else if (vp?.align) {\n const mapV: Record<\n string,\n (typeof RelativeVerticalPosition)[keyof typeof RelativeVerticalPosition]\n > = {\n top: RelativeVerticalPosition.TOP,\n center: RelativeVerticalPosition.CENTER,\n bottom: RelativeVerticalPosition.BOTTOM,\n inside: RelativeVerticalPosition.INSIDE,\n outside: RelativeVerticalPosition.OUTSIDE,\n } as any;\n opt.relativeVerticalPosition = mapV[vp.align];\n }\n\n // Map wrap margins to clearance distances (resolve percentages against page dimensions)\n const pageW = getPageWidthTwips(theme, themeName);\n const pageH = getPageHeightTwips(theme, themeName);\n const m = floating.wrap?.margins;\n if (m) {\n if (m.top !== undefined) opt.topFromText = resolveOffsetTwips(m.top, pageH);\n if (m.right !== undefined)\n opt.rightFromText = resolveOffsetTwips(m.right, pageW);\n if (m.bottom !== undefined)\n opt.bottomFromText = resolveOffsetTwips(m.bottom, pageH);\n if (m.left !== undefined)\n opt.leftFromText = resolveOffsetTwips(m.left, pageW);\n }\n\n opt.overlap = OverlapType.OVERLAP;\n\n return opt;\n}\n\nexport async function renderTextBoxComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n _context: import('../types').RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isTextBoxComponent(component)) return [];\n const tb = component as TextBoxComponentDefinition;\n\n const isInline = !tb.props.floating;\n const childComponents = tb.children || [];\n\n if (isInline) {\n // Inline: use a one-cell table container for multi-paragraph support\n const cellChildren: (Paragraph | Table)[] = [];\n // Create context with current text-box as parent\n const childContext: import('../types').RenderContext = {\n ..._context,\n parent: tb,\n };\n for (const child of childComponents) {\n const rendered = await renderComponent(\n child,\n theme,\n themeName,\n childContext\n );\n cellChildren.push(...rendered);\n }\n\n const styleCfg = (tb.props as any).style as CellStyleConfig | undefined;\n const cellOpts = buildCellOptions(cellChildren, styleCfg, theme);\n\n const row = new TableRow({ children: [new TableCell(cellOpts)] });\n const table = new Table({\n layout: TableLayoutType.FIXED, // Lock column widths\n rows: [row],\n width: { size: 100, type: WidthType.PERCENTAGE },\n borders: NONE_BORDERS,\n });\n return [table];\n }\n\n // Always use a floating one-cell table container for multi-paragraph support\n\n // If there is at least one table or image child, use a floating one-cell table container\n const cellChildren: (Paragraph | Table)[] = [];\n // Create context with current text-box as parent\n const childContext: import('../types').RenderContext = {\n ..._context,\n parent: tb,\n };\n for (const child of childComponents) {\n const rendered = await renderComponent(\n child,\n theme,\n themeName,\n childContext\n );\n cellChildren.push(...rendered);\n }\n\n const styleCfg = (tb.props as any).style as CellStyleConfig | undefined;\n const cellOpts = buildCellOptions(cellChildren, styleCfg, theme);\n\n const row = new TableRow({\n children: [new TableCell(cellOpts)],\n });\n\n const float = mapTableFloatOptions(tb.props.floating, theme, themeName);\n\n // Conversion factor: 1 pixel = 15 twips (at 96 DPI: 1440 twips/inch / 96 pixels/inch)\n const PIXELS_TO_TWIPS = 15;\n const DEFAULT_WIDTH_TWIPS = 5000; // ~333 pixels\n\n // Support width as number (pixels) or percentage string\n // Read from props.width (new location) with fallback to props.floating.width (legacy, in twips)\n const rawWidth = tb.props.width ?? (tb.props.floating as any)?.width;\n let widthSize: number;\n let widthType: (typeof WidthType)[keyof typeof WidthType];\n\n if (rawWidth === undefined) {\n // No width specified, use default\n widthSize = DEFAULT_WIDTH_TWIPS;\n widthType = WidthType.DXA;\n } else if (typeof rawWidth === 'string' && rawWidth.endsWith('%')) {\n // Percentage width\n widthSize = parseFloat(rawWidth);\n widthType = WidthType.PERCENTAGE;\n } else {\n // Number in pixels - convert to twips (DXA)\n widthSize =\n typeof rawWidth === 'number'\n ? rawWidth * PIXELS_TO_TWIPS\n : DEFAULT_WIDTH_TWIPS;\n widthType = WidthType.DXA;\n }\n\n const table = new Table({\n layout: TableLayoutType.FIXED, // Lock column widths\n rows: [row],\n width: { size: widthSize, type: widthType },\n float,\n borders: NONE_BORDERS,\n });\n return [table];\n}\n","/**\n * Border utilities for consistent border styling across modules\n */\n\nimport { BorderStyle } from 'docx';\nimport { resolveColor } from './colorUtils';\nimport { ThemeConfig } from '../index';\n\n/**\n * Standard \"no borders\" configuration for tables\n * Used when borders should be invisible/disabled\n */\nexport const NONE_BORDERS = {\n top: { style: BorderStyle.NONE, size: 0, color: '000000' },\n right: { style: BorderStyle.NONE, size: 0, color: '000000' },\n bottom: { style: BorderStyle.NONE, size: 0, color: '000000' },\n left: { style: BorderStyle.NONE, size: 0, color: '000000' },\n insideHorizontal: { style: BorderStyle.NONE, size: 0, color: '000000' },\n insideVertical: { style: BorderStyle.NONE, size: 0, color: '000000' },\n} as const;\n\n/**\n * Maps border style string to docx BorderStyle enum\n * @param s - Border style string ('dashed', 'dotted', 'double', 'none', 'single')\n * @returns Corresponding BorderStyle enum value\n */\nexport function mapBorderStyle(\n s?: string\n): (typeof BorderStyle)[keyof typeof BorderStyle] {\n switch (s) {\n case 'dashed':\n return BorderStyle.DASHED;\n case 'dotted':\n return BorderStyle.DOTTED;\n case 'double':\n return BorderStyle.DOUBLE;\n case 'none':\n return BorderStyle.NONE;\n default:\n return BorderStyle.SINGLE;\n }\n}\n\n/**\n * Border configuration object\n */\nexport interface BorderConfig {\n style?: string;\n width?: number;\n color?: string;\n}\n\n/**\n * Converts border configuration to docx border format\n * @param b - Border configuration object\n * @param theme - Theme configuration for color resolution\n * @returns Docx border object or undefined if no border\n */\nexport function convertBorder(\n b: BorderConfig | undefined,\n theme: ThemeConfig\n):\n | {\n style: (typeof BorderStyle)[keyof typeof BorderStyle];\n size: number;\n color: string;\n }\n | undefined {\n if (!b) return undefined;\n\n return {\n style: mapBorderStyle(b.style),\n size: b.width !== undefined ? Math.max(1, Math.round(b.width * 8)) : 1,\n color: b.color ? resolveColor(b.color, theme) : '000000',\n };\n}\n\n/**\n * Borders configuration for all four sides\n */\nexport interface BordersConfig {\n top?: BorderConfig;\n right?: BorderConfig;\n bottom?: BorderConfig;\n left?: BorderConfig;\n}\n\n/**\n * Converts borders configuration object to docx borders format\n * Returns undefined if no borders are defined\n * @param bordersConfig - Configuration for all four borders\n * @param theme - Theme configuration for color resolution\n * @returns Docx borders object or undefined\n */\nexport function convertBorders(\n bordersConfig: BordersConfig | undefined,\n theme: ThemeConfig\n):\n | Record<\n string,\n {\n style: (typeof BorderStyle)[keyof typeof BorderStyle];\n size: number;\n color: string;\n }\n >\n | undefined {\n if (!bordersConfig) return undefined;\n\n const borders: Record<\n string,\n {\n style: (typeof BorderStyle)[keyof typeof BorderStyle];\n size: number;\n color: string;\n }\n > = {};\n\n const top = convertBorder(bordersConfig.top, theme);\n const right = convertBorder(bordersConfig.right, theme);\n const bottom = convertBorder(bordersConfig.bottom, theme);\n const left = convertBorder(bordersConfig.left, theme);\n\n if (top) borders.top = top;\n if (right) borders.right = right;\n if (bottom) borders.bottom = bottom;\n if (left) borders.left = left;\n\n return Object.keys(borders).length > 0 ? borders : undefined;\n}\n","/**\n * Cell utilities for building table cell configurations\n */\n\nimport { Paragraph, Table } from 'docx';\nimport { pointsToTwips } from './styleHelpers';\nimport { resolveColor } from './colorUtils';\nimport { ThemeConfig } from '../index';\nimport { convertBorders, BordersConfig } from './borderUtils';\n\n/**\n * Padding configuration for all four sides\n */\nexport interface PaddingConfig {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\n/**\n * Shading configuration\n */\nexport interface ShadingConfig {\n fill?: string;\n}\n\n/**\n * Complete cell style configuration\n */\nexport interface CellStyleConfig {\n padding?: PaddingConfig;\n border?: BordersConfig;\n shading?: ShadingConfig;\n}\n\n/**\n * Builds cell options object for TableCell constructor\n * Handles margins (padding), shading, and borders consistently\n * @param children - Child elements to include in the cell\n * @param styleCfg - Style configuration for the cell\n * @param theme - Theme configuration for color resolution\n * @returns Cell options object ready for TableCell constructor\n */\nexport function buildCellOptions(\n children: (Paragraph | Table)[],\n styleCfg: CellStyleConfig | undefined,\n theme: ThemeConfig\n): {\n children: (Paragraph | Table)[];\n margins: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n shading?: { fill: string };\n borders?: Record<string, { style: any; size: number; color: string }>;\n} {\n const cellOpts: any = {\n children: children.length ? children : [new Paragraph({})],\n margins: {\n top: styleCfg?.padding?.top ? pointsToTwips(styleCfg.padding.top) : 0,\n right: styleCfg?.padding?.right\n ? pointsToTwips(styleCfg.padding.right)\n : 0,\n bottom: styleCfg?.padding?.bottom\n ? pointsToTwips(styleCfg.padding.bottom)\n : 0,\n left: styleCfg?.padding?.left ? pointsToTwips(styleCfg.padding.left) : 0,\n },\n };\n\n // Apply shading if configured\n if (styleCfg?.shading?.fill) {\n cellOpts.shading = { fill: resolveColor(styleCfg.shading.fill, theme) };\n }\n\n // Apply borders if configured\n if (styleCfg?.border) {\n const borders = convertBorders(styleCfg.border, theme);\n if (borders && Object.keys(borders).length > 0) {\n cellOpts.borders = borders;\n }\n }\n\n return cellOpts;\n}\n","/**\n * Table Component\n * Standard component for rendering tables in documents\n */\n\nimport { Table } from 'docx';\nimport { ComponentDefinition, isTableComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createTable } from '../core/content';\n\ntype CellContent = string | ComponentDefinition;\n\ntype HorizontalAlignment = 'left' | 'center' | 'right' | 'justify';\n\ntype VerticalAlignment = 'top' | 'middle' | 'bottom';\n\ntype FontConfig = {\n family?: string;\n size?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n};\n\ntype BorderColor =\n | string\n | {\n bottom?: string;\n top?: string;\n right?: string;\n left?: string;\n };\n\ntype BorderSize =\n | number\n | {\n bottom?: number;\n top?: number;\n right?: number;\n left?: number;\n };\n\ntype Padding =\n | number\n | {\n bottom?: number;\n top?: number;\n right?: number;\n left?: number;\n };\n\ntype CellDefaults = {\n color?: string;\n backgroundColor?: string;\n horizontalAlignment?: HorizontalAlignment;\n verticalAlignment?: VerticalAlignment;\n font?: FontConfig;\n borderColor?: BorderColor;\n borderSize?: BorderSize;\n padding?: Padding;\n height?: number;\n};\n\ntype TableConfig = {\n borderColor?: BorderColor;\n borderSize?: BorderSize;\n cellDefaults?: CellDefaults;\n headerCellDefaults?: CellDefaults;\n width?: number;\n columns: {\n /** Width in points (number) or as percentage string e.g. \"40%\" */\n width?: number | string;\n cellDefaults?: CellDefaults;\n header?: CellDefaults & {\n content?: CellContent;\n };\n cells?: (CellDefaults & {\n content?: CellContent;\n })[];\n }[];\n keepInOnePage?: boolean;\n keepNext?: boolean;\n repeatHeaderOnPageBreak?: boolean;\n};\n\n/**\n * Render table component\n * Supports new column-based format with cell defaults and legacy headers/rows format\n */\nexport async function renderTableComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string\n): Promise<Table[]> {\n if (!isTableComponent(component)) return [];\n\n const rawConfig = component.props as any;\n const result: Table[] = [];\n\n // Check if this is the old format (has headers and rows properties)\n if (rawConfig.headers && rawConfig.rows) {\n // Convert old format to new format\n const headers = rawConfig.headers as string[];\n const rows = rawConfig.rows as string[][];\n\n const defaultCellDefaults: CellDefaults = {\n color: '000000',\n backgroundColor: 'transparent',\n horizontalAlignment: 'left',\n verticalAlignment: 'top',\n font: {\n family: 'Arial',\n size: 11,\n bold: false,\n italic: false,\n underline: false,\n },\n borderColor: '000000',\n borderSize: 1,\n };\n\n const config: TableConfig = {\n borderColor: '000000',\n borderSize: 1,\n cellDefaults: defaultCellDefaults,\n width: 100,\n columns: headers.map((header, colIndex) => ({\n cellDefaults: { ...defaultCellDefaults },\n header: {\n ...defaultCellDefaults,\n content: header,\n },\n cells: rows.map((row) => ({\n ...defaultCellDefaults,\n content: row[colIndex] || '',\n })),\n })),\n };\n\n result.push(await createTable(config.columns, config, theme, themeName));\n\n return result;\n }\n\n // New column-based format\n const config = rawConfig as TableConfig;\n\n result.push(await createTable(config.columns, config, theme, themeName));\n\n return result;\n}\n","/**\n * Section Component\n * Standard component for rendering document sections with child components\n */\n\nimport { Paragraph, Table, BookmarkStart, BookmarkEnd } from 'docx';\nimport {\n ComponentDefinition,\n RenderContext,\n isSectionComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { renderComponent } from '../core/render';\n\ninterface SectionBookmarkState {\n next: number;\n}\n\n/** Generate a document-scoped, reproducible bookmark ID. */\nfunction generateSectionBookmarkId(context: RenderContext): {\n id: string;\n linkId: number;\n} {\n const custom = (context.custom ??= {});\n const state = (custom.sectionBookmarks ??= {\n next: 1,\n }) as SectionBookmarkState;\n const ordinal = state.next++;\n // Keep nested component IDs away from the low ordinals used by layout\n // section bookmarks in core/render.ts.\n const linkId = 1_000_000 + ordinal;\n return {\n id: `_NestedSection_${ordinal}`,\n linkId,\n };\n}\n\n/**\n * Render section component with bookmark support for scoped TOCs\n */\nexport async function renderSectionComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isSectionComponent(component)) return [];\n\n const elements: (Paragraph | Table)[] = [];\n\n // Generate unique bookmark ID for this section\n const { id: sectionBookmarkId, linkId: bookmarkLinkId } =\n generateSectionBookmarkId(context);\n\n // Add bookmark in a zero-spacing paragraph at section start\n // This prevents visual gaps while maintaining bookmark functionality\n elements.push(\n new Paragraph({\n children: [new BookmarkStart(sectionBookmarkId, bookmarkLinkId)],\n spacing: {\n before: 0,\n after: 0,\n line: 0,\n },\n })\n );\n\n // Update context with section bookmark ID for child components (especially TOCs)\n const sectionContext: RenderContext = {\n ...context,\n section: {\n ...context.section,\n sectionBookmarkId,\n },\n };\n\n // Render child components with updated context\n if (component.children) {\n for (const child of component.children) {\n const childElements = await renderComponent(\n child,\n theme,\n themeName,\n sectionContext\n );\n elements.push(...childElements);\n }\n }\n\n // Add bookmark end after section content\n // Use zero spacing to prevent visual gap\n elements.push(\n new Paragraph({\n children: [new BookmarkEnd(bookmarkLinkId)],\n spacing: {\n before: 0,\n after: 0,\n line: 0,\n },\n })\n );\n\n return elements;\n}\n","/**\n * Columns Component\n * Standard component for rendering content in columns layout\n */\n\nimport {\n Paragraph,\n Table,\n TableRow,\n TableCell,\n WidthType,\n BorderStyle,\n VerticalAlign,\n TableLayoutType,\n} from 'docx';\nimport {\n ComponentDefinition,\n RenderContext,\n isColumnsComponent,\n isTextBoxComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { renderComponent } from '../core/render';\nimport {\n getAvailableWidthTwips,\n relativeLengthToTwips,\n} from '../utils/widthUtils';\nimport { NONE_BORDERS } from '../styles/utils/borderUtils';\n\n/**\n * Render columns component\n */\nexport async function renderColumnsComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isColumnsComponent(component)) return [];\n\n // Check if parent is a text-box component\n if (context.parent && isTextBoxComponent(context.parent)) {\n // Render as table-based columns when inside a text-box\n return await renderColumnsAsTable(component, theme, themeName, context);\n }\n\n // Standard section-based rendering (existing behavior)\n // Props are pre-resolved by resolveComponentTree\n const elements: (Paragraph | Table)[] = [];\n\n if (component.children) {\n for (const child of component.children) {\n const childElements = await renderComponent(\n child,\n theme,\n themeName,\n context\n );\n elements.push(...childElements);\n }\n }\n\n return elements;\n}\n\n/**\n * Render columns as a multi-column table (for use inside text-boxes)\n */\nasync function renderColumnsAsTable(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context: RenderContext\n): Promise<Table[]> {\n const cfg = (component as any).props || {};\n const columns = cfg.columns || [];\n\n // Normalize columns configuration\n let columnConfigs: Array<{ width?: number | string; gap?: number | string }> =\n [];\n if (typeof columns === 'number') {\n // Equal-width columns\n columnConfigs = Array(columns).fill({ width: 'auto' });\n } else if (Array.isArray(columns)) {\n columnConfigs = columns;\n } else {\n // Invalid config, return empty\n return [];\n }\n\n const columnCount = columnConfigs.length;\n if (columnCount === 0) return [];\n\n // Calculate column widths\n const availableWidthTwips = getAvailableWidthTwips(theme, themeName);\n const columnWidths: number[] = [];\n const columnGaps: number[] = [];\n let totalDefinedWidth = 0;\n let totalGaps = 0;\n const autoWidthIndexes: number[] = [];\n\n for (let i = 0; i < columnCount; i++) {\n const col = columnConfigs[i];\n\n // Calculate width\n if (col.width === undefined || col.width === 'auto') {\n autoWidthIndexes.push(i);\n columnWidths.push(0); // Placeholder\n } else {\n const widthTwips = relativeLengthToTwips(col.width, availableWidthTwips);\n columnWidths.push(widthTwips);\n totalDefinedWidth += widthTwips;\n }\n\n // Calculate gap (space after this column)\n if (i < columnCount - 1) {\n const gapTwips =\n col.gap !== undefined\n ? relativeLengthToTwips(col.gap, availableWidthTwips)\n : cfg.gap !== undefined\n ? relativeLengthToTwips(cfg.gap, availableWidthTwips)\n : 720; // Default: 0.5 inch\n columnGaps.push(gapTwips);\n totalGaps += gapTwips;\n } else {\n columnGaps.push(0); // No gap after last column\n }\n }\n\n // Distribute remaining width among auto-width columns\n const remainingWidth = Math.max(\n 0,\n availableWidthTwips - totalDefinedWidth - totalGaps\n );\n if (autoWidthIndexes.length > 0) {\n const autoColumnWidth = Math.floor(\n remainingWidth / autoWidthIndexes.length\n );\n for (const idx of autoWidthIndexes) {\n columnWidths[idx] = autoColumnWidth;\n }\n }\n\n // Distribute child components across columns\n const childComponents = (component as any).children || [];\n const columnContents: ComponentDefinition[][] = Array(columnCount)\n .fill(null)\n .map(() => []);\n\n // Simple distribution: round-robin\n for (let i = 0; i < childComponents.length; i++) {\n const colIndex = i % columnCount;\n columnContents[colIndex].push(childComponents[i]);\n }\n\n // Render each column's content\n const cells: TableCell[] = [];\n for (let i = 0; i < columnCount; i++) {\n const columnElements: (Paragraph | Table)[] = [];\n\n for (const child of columnContents[i]) {\n const rendered = await renderComponent(child, theme, themeName, context);\n columnElements.push(...rendered);\n }\n\n // If column is empty, add empty paragraph\n if (columnElements.length === 0) {\n columnElements.push(new Paragraph({}));\n }\n\n cells.push(\n new TableCell({\n children: columnElements,\n width: { size: columnWidths[i], type: WidthType.DXA },\n margins: {\n top: 0,\n right: columnGaps[i] / 2,\n bottom: 0,\n left: i > 0 ? columnGaps[i - 1] / 2 : 0,\n },\n verticalAlign: VerticalAlign.TOP,\n borders: {\n top: { style: BorderStyle.NONE, size: 0, color: '000000' },\n right: { style: BorderStyle.NONE, size: 0, color: '000000' },\n bottom: { style: BorderStyle.NONE, size: 0, color: '000000' },\n left: { style: BorderStyle.NONE, size: 0, color: '000000' },\n },\n })\n );\n }\n\n const row = new TableRow({ children: cells });\n const table = new Table({\n rows: [row],\n width: { size: 100, type: WidthType.PERCENTAGE },\n layout: TableLayoutType.FIXED, // Lock column widths\n borders: NONE_BORDERS,\n });\n\n return [table];\n}\n","/**\n * Statistic Component\n * Standard component for rendering statistic displays in documents\n */\n\nimport { Paragraph } from 'docx';\nimport { ComponentDefinition, isStatisticComponent } from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createStatistic } from '../core/content';\n\n/**\n * Render statistic component\n */\nexport function renderStatisticComponent(\n component: ComponentDefinition,\n _theme: ThemeConfig\n): Paragraph[] {\n if (!isStatisticComponent(component)) return [];\n\n // Props are pre-resolved by resolveComponentTree\n const resolvedConfig = component.props;\n\n return createStatistic(\n {\n number: resolvedConfig.number,\n description: resolvedConfig.description,\n alignment: resolvedConfig.alignment,\n },\n {\n spacing: resolvedConfig.spacing as\n | { before?: number; after?: number }\n | undefined,\n }\n );\n}\n","/**\n * Table of Contents Component\n * Renders TOC using Word's native TableOfContents field with bookmark scoping support\n */\n\nimport {\n Paragraph,\n TableOfContents,\n AlignmentType,\n TextRun,\n StyleLevel,\n} from 'docx';\nimport type { ITableOfContentsOptions } from 'docx';\nimport type { TocProps } from '@json-to-office/shared-docx';\nimport type { ThemeConfig } from '../../styles';\nimport type { RenderContext } from '../../types';\n\nexport interface TocComponentDefinition {\n name: 'toc';\n id?: string;\n props: TocProps;\n}\n\n/**\n * Parse and validate a depth range configuration\n * @param rawDepth - Raw depth configuration from user input\n * @param fieldName - Name of the field (for error messages)\n * @param defaultFrom - Default 'from' value if not specified\n * @param defaultTo - Default 'to' value if not specified\n * @returns Validated depth range with from and to values\n */\nfunction parseDepthRange(\n rawDepth: any,\n fieldName: string,\n defaultFrom = 1,\n defaultTo = 3\n): { from: number; to: number } {\n if (typeof rawDepth !== 'object' || rawDepth === null) {\n throw new Error(\n `${fieldName} must be a range object with optional \"from\" and/or \"to\" fields, received: ${JSON.stringify(rawDepth)}`\n );\n }\n\n // Apply defaults for missing values\n const from = rawDepth.from ?? defaultFrom;\n const to = rawDepth.to ?? defaultTo;\n\n // Validate range\n if (from < 1 || from > 6 || to < 1 || to > 6) {\n throw new Error(\n `${fieldName} range values must be between 1 and 6, received: from=${from}, to=${to}`\n );\n }\n if (from > to) {\n throw new Error(\n `${fieldName} \"from\" must be less than or equal to \"to\", received: from=${from}, to=${to}`\n );\n }\n\n return { from, to };\n}\n\n/**\n * Render TOC component using Word's native TableOfContents field with bookmark scoping\n *\n * This creates a dynamic TOC that:\n * - Auto-populates with headings from configured scope\n * - Updates automatically when document structure changes\n * - Includes clickable hyperlinks to content\n * - Shows page numbers (if enabled)\n * - Respects configured depth limits\n *\n * Scope behavior:\n * - scope: 'document' → Scans entire document (default when TOC is at report level)\n * - scope: 'section' → Scans only parent section content (uses bookmark)\n * - scope: 'auto' → Automatically detects: section if inside section, otherwise document\n */\nexport function renderTocComponent(\n component: TocComponentDefinition,\n theme: ThemeConfig,\n context?: RenderContext\n): (Paragraph | TableOfContents)[] {\n const componentProps = component.props;\n\n // Parse depth parameter - supports range with optional from/to\n const rawDepth = componentProps.depth ?? { to: 3 };\n const depthRange = parseDepthRange(rawDepth, 'TOC depth', 1, 3);\n const depthStart = depthRange.from;\n const depthEnd = depthRange.to;\n\n // Parse pageNumbersDepth parameter - controls which levels show page numbers\n let pageNumbersStart: number | undefined;\n let pageNumbersEnd: number | undefined;\n\n if (componentProps.pageNumbersDepth !== undefined) {\n const pageNumbersRange = parseDepthRange(\n componentProps.pageNumbersDepth,\n 'TOC pageNumbersDepth',\n 1,\n 3\n );\n pageNumbersStart = pageNumbersRange.from;\n pageNumbersEnd = pageNumbersRange.to;\n }\n\n // numberingStyle has no representation in Word's TOC field: the field carries\n // no numbering switch, so entries always inherit the numbering of the heading\n // styles they point at. The prop stays in the schema (documents already set it\n // and props are additionalProperties:false), but the no-op is announced rather\n // than swallowed.\n if (componentProps.numberingStyle !== undefined) {\n console.warn(\n `TOC numberingStyle \"${componentProps.numberingStyle}\" is ignored: Word's ` +\n 'table-of-contents field has no numbering switch. TOC entries inherit ' +\n 'numbering from the heading styles they reference.'\n );\n }\n\n const includePageNumbers = componentProps.includePageNumbers !== false; // default true\n const scope = componentProps.scope ?? 'auto';\n\n // Determine effective scope based on configuration and context\n const effectiveScope =\n scope === 'auto'\n ? context?.section?.sectionBookmarkId\n ? 'section'\n : 'document'\n : scope;\n\n // Get section bookmark ID if scoped to section\n const sectionBookmarkId =\n effectiveScope === 'section'\n ? context?.section?.sectionBookmarkId\n : undefined;\n\n // Validate bookmark if section-scoped\n if (effectiveScope === 'section' && !sectionBookmarkId) {\n // Log warning but gracefully fall back to document scope\n console.warn(\n 'TOC configured for section scope but no section bookmark found. Falling back to document scope.'\n );\n }\n\n const paragraphs: (Paragraph | TableOfContents)[] = [];\n\n // Add TOC title only if explicitly provided\n if (componentProps.title) {\n paragraphs.push(\n new Paragraph({\n children: [\n new TextRun({\n text: componentProps.title,\n bold: true,\n size: 28, // 14pt (size is in half-points)\n }),\n ],\n spacing: {\n before: theme.componentDefaults?.heading?.spacing?.before ?? 240,\n // Increase spacing between the title and the TOC list\n // 180 ~= 9pt, provides clearer separation by default\n after: 180,\n },\n alignment: AlignmentType.LEFT,\n })\n );\n }\n\n // Build style mappings for TOC levels based on depth\n // StyleLevel requires styleName (string) and level (number)\n const stylesWithLevels: StyleLevel[] = [];\n\n // For section-scoped TOCs, exclude heading levels equal to or above the section title level\n // This prevents the section title from appearing in its own TOC\n const sectionTitleLevel = context?.section?.sectionTitleLevel;\n const startLevel =\n effectiveScope === 'section' && sectionTitleLevel\n ? sectionTitleLevel // Start from the level after the section title\n : 0; // Document scope starts from level 1 (index 0)\n\n // Do NOT map built-in heading styles via \\t switch.\n // Use headingStyleRange (\\o) exclusively for Heading 1..6 to avoid any interference\n // between TOC styles and document heading styles.\n\n // Add custom style mappings if provided\n // These allow arbitrary theme styles to appear in the TOC at specified levels\n if (componentProps.styles && componentProps.styles.length > 0) {\n for (const styleMapping of componentProps.styles) {\n // The TOC \\t (stylesWithLevels) switch expects Word style DISPLAY NAMES, not IDs.\n // Our theme registers custom styles with:\n // - id: original key (e.g., \"MySpectacularStyle\")\n // - name: Title Case with spaces (e.g., \"My Spectacular Style\")\n // Convert known custom style IDs to their display names to ensure Word matches them.\n const styleId = styleMapping.styleId;\n const isCustomStyle =\n !!theme.styles &&\n Object.prototype.hasOwnProperty.call(theme.styles, styleId);\n const styleDisplayName = isCustomStyle\n ? styleId\n .replace(/([A-Z])/g, ' $1')\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n : styleId; // If it's not a custom style key, assume it's already a display name\n\n stylesWithLevels.push(\n new StyleLevel(styleDisplayName, styleMapping.level)\n );\n }\n }\n\n // Create Word TOC field with optional bookmark scoping\n // The TableOfContents class generates a field code that Word will populate\n // Format (document scope): { TOC \\o \"1-N\" \\h \\z \\u }\n // Format (section scope): { TOC \\b BookmarkName \\o \"1-N\" \\h \\z \\u }\n // - \\b BookmarkName: Limit TOC to entries within specified bookmark\n // - \\o \"1-N\": Include outline levels 1 through N\n // - \\h: Make TOC entries hyperlinks\n // - \\z: Hide page numbers in web layout\n // - \\u: Use outline levels instead of TC fields\n\n // Calculate heading range for \\o switch\n // For section-scoped TOCs: start AFTER section title level (e.g., level 2 if section is level 1)\n // For document-scoped TOCs: use depthStart and depthEnd from parsed depth config\n const effectiveDepthStart =\n effectiveScope === 'section' && sectionTitleLevel\n ? Math.max(depthStart, startLevel + 1) // Skip section title level, but respect user's depthStart\n : depthStart;\n const effectiveDepthEnd = depthEnd;\n\n // Build TOC options\n const tocOptions: ITableOfContentsOptions = {\n hyperlink: true, // Enable clickable hyperlinks (\\h switch)\n headingStyleRange: `${effectiveDepthStart}-${effectiveDepthEnd}`, // Outline level range (\\o switch)\n stylesWithLevels, // Style-to-TOC-level mappings (\\t switch)\n // Add bookmark scope if within a section (\\b switch)\n entriesFromBookmark: sectionBookmarkId,\n // Handle page number visibility\n // If pageNumbersDepth is specified, use it to control which levels show page numbers\n // Otherwise, respect includePageNumbers boolean (default true)\n ...(() => {\n if (pageNumbersStart !== undefined && pageNumbersEnd !== undefined) {\n // pageNumbersDepth specified: hide page numbers outside the specified range\n // Word's \\n switch omits page numbers for specified levels\n // We need to invert the logic: specify levels to OMIT, not levels to SHOW\n const levelsToOmit: string[] = [];\n\n // Omit levels before pageNumbersStart\n if (pageNumbersStart > effectiveDepthStart) {\n levelsToOmit.push(`${effectiveDepthStart}-${pageNumbersStart - 1}`);\n }\n\n // Omit levels after pageNumbersEnd\n if (pageNumbersEnd < effectiveDepthEnd) {\n levelsToOmit.push(`${pageNumbersEnd + 1}-${effectiveDepthEnd}`);\n }\n\n // Only add the option if there are levels to omit\n return levelsToOmit.length > 0\n ? { pageNumbersEntryLevelsRange: levelsToOmit.join(',') }\n : {};\n } else if (!includePageNumbers) {\n // includePageNumbers is false: omit page numbers for all levels\n return {\n pageNumbersEntryLevelsRange: `${effectiveDepthStart}-${effectiveDepthEnd}`,\n };\n } else {\n // includePageNumbers is true and no pageNumbersDepth: show page numbers for all levels\n return {};\n }\n })(),\n // Add separator between entry text and page number\n // Boolean: true = \"\\t\" (tab, default), false = \" \" (space)\n ...(componentProps.numberSeparator !== undefined\n ? {\n entryAndPageNumberSeparator: componentProps.numberSeparator\n ? '\\t'\n : ' ',\n }\n : { entryAndPageNumberSeparator: '\\t' }), // default to tab\n };\n\n // Insert TOC as a top-level block (not wrapped in a Paragraph).\n // Wrapping TableOfContents inside a Paragraph produces an empty SDT above\n // the actual entries in Word. Adding directly avoids that artifact.\n paragraphs.push(\n new TableOfContents(componentProps.title ?? 'Table of Contents', tocOptions)\n );\n\n // Do not append an extra empty paragraph after TOC to avoid\n // unwanted blank lines/newlines at the end of the TOC block.\n\n // Note: Word will automatically handle:\n // - Page number display (based on document view mode)\n // - Numbering style (inherited from heading styles)\n // - Indentation (based on heading levels)\n // - Updates (right-click TOC → Update Field in Word)\n\n return paragraphs;\n}\n","/**\n * Highcharts Component\n * Standard component for generating charts using Highcharts Export Server\n */\n\nimport { Paragraph, Table } from 'docx';\nimport {\n ComponentDefinition,\n RenderContext,\n isHighchartsComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createImage } from '../core/content';\nimport { resolveColor } from '../styles/utils/colorUtils';\nimport { isNodeEnvironment } from '../utils/environment';\nimport { resolveServiceUrl, postJsonToService } from '../utils/serviceClient';\n\n// Import only the types we actually use from shared package\nimport type { HighchartsProps } from '@json-to-office/shared-docx';\nimport type { HighchartsServiceConfig } from '@json-to-office/shared';\nimport { DEFAULT_CHART_THEME_COLORS } from '@json-to-office/shared';\n\n// Re-export HighchartsProps for backward compatibility\nexport type { HighchartsProps } from '@json-to-office/shared-docx';\n\n/**\n * Chart generation result\n */\nexport interface ChartGenerationResult {\n base64DataUri: string;\n width: number;\n height: number;\n}\n\nconst DEFAULT_EXPORT_SERVER_URL = 'http://localhost:7801';\n\n/**\n * Generate chart using Highcharts Export Server\n */\nasync function generateChart(\n config: HighchartsProps,\n servicesConfig?: HighchartsServiceConfig\n): Promise<ChartGenerationResult> {\n // Only run in Node.js environments\n if (!isNodeEnvironment()) {\n throw new Error(\n 'Highcharts export server requires a Node.js environment. ' +\n 'Chart generation is not available in browser environments.'\n );\n }\n\n const serverUrl = resolveServiceUrl(\n config.serverUrl,\n servicesConfig?.serverUrl,\n DEFAULT_EXPORT_SERVER_URL\n );\n\n const requestBody: Record<string, unknown> = {\n infile: config.options,\n type: 'png',\n b64: true,\n scale: config.scale,\n // Forward resources verbatim only when present so the payload stays\n // byte-identical to before for callers that omit it.\n ...(config.resources ? { resources: config.resources } : {}),\n };\n\n const response = await postJsonToService({\n url: serverUrl,\n path: '/export',\n body: requestBody,\n headers: servicesConfig?.headers,\n serviceLabel: 'Highcharts export server',\n onUnreachable: (url, cause) =>\n `Highcharts Export Server is not running at ${url}. ` +\n 'Start it with: npx highcharts-export-server --enableServer true\\n' +\n `Cause: ${cause}`,\n });\n\n const base64Data = await response.text();\n const base64DataUri = `data:image/png;base64,${base64Data}`;\n const width = config.options.chart.width;\n const height = config.options.chart.height;\n\n return {\n base64DataUri,\n width,\n height,\n };\n}\n\n/**\n * Turn one theme color value into a `#RRGGBB` string, or undefined when it\n * cannot be resolved. The theme schema lets a color be another token's name\n * (`\"accent4\": \"primary\"`), so a bare `#` prefix would post \"#primary\" to the\n * export server; `resolveColor` walks the reference chain and throws on\n * anything unresolvable, which we treat as an unset slot.\n */\nfunction toChartColor(value: string, theme: ThemeConfig): string | undefined {\n // Literal hex passes through untouched — resolveColor would upper-case it,\n // and it rejects the bare (no '#') form the schema still accepts.\n if (/^#?[0-9A-Fa-f]{6}$/.test(value)) {\n return value.startsWith('#') ? value : `#${value}`;\n }\n try {\n return `#${resolveColor(value, theme)}`;\n } catch {\n return undefined;\n }\n}\n\n/**\n * When the Highcharts config sets no top-level `colors`, series render in the\n * Highcharts default palette (blue-first) and ignore the document theme. Inject\n * the theme's chart palette — the same token list PPTX charts resolve — as\n * series colors so charts follow the theme by default. accent4-6 are optional\n * in the theme schema; slots the theme leaves unset are skipped, in both\n * formats, so the palette never carries gaps or repeats and Highcharts wraps\n * the shorter list (see DEFAULT_CHART_THEME_COLORS). Explicit `colors` always\n * wins.\n */\nfunction withThemeColors(\n config: HighchartsProps,\n theme: ThemeConfig\n): HighchartsProps {\n const options = config.options as Record<string, unknown> | undefined;\n if (!options || options.colors || !theme?.colors) return config;\n const themeColors = theme.colors as Record<string, string | undefined>;\n const palette = DEFAULT_CHART_THEME_COLORS.map((token) => {\n const value = themeColors[token];\n return typeof value === 'string' && value.length > 0\n ? toChartColor(value, theme)\n : undefined;\n }).filter((c): c is string => c !== undefined);\n if (palette.length === 0) return config;\n return {\n ...config,\n options: { ...config.options, colors: palette },\n };\n}\n\n/**\n * Render highcharts component\n */\nexport async function renderHighchartsComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName: string,\n context?: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isHighchartsComponent(component)) return [];\n\n const config = withThemeColors(component.props as HighchartsProps, theme);\n\n // Generate the chart\n const chartResult = await generateChart(\n config,\n context?.services?.highcharts\n );\n\n // If either config.width or config.height is provided, use config dimensions only\n // Otherwise fall back to chart dimensions\n const hasConfigDimensions =\n config.width !== undefined || config.height !== undefined;\n const renderWidth = hasConfigDimensions ? config.width : chartResult.width;\n const renderHeight = hasConfigDimensions ? config.height : chartResult.height;\n\n // Add chart image using the image component with base64 data URI\n const imageParagraphs = await createImage(\n chartResult.base64DataUri,\n theme,\n themeName,\n {\n width: renderWidth,\n height: renderHeight,\n alignment: 'center',\n }\n );\n\n return imageParagraphs;\n}\n","/**\n * Environment detection utilities\n */\n\n/**\n * Check if the current environment is Node.js\n * This is used to conditionally load Node.js-only modules\n */\nexport function isNodeEnvironment(): boolean {\n // Check for Node.js-specific globals\n return (\n typeof process !== 'undefined' &&\n process.versions != null &&\n process.versions.node != null &&\n typeof process.versions.node === 'string'\n );\n}\n\n/**\n * Check if Node.js built-in modules are available\n * More specific check for modules that require Node.js built-ins\n */\nexport function hasNodeBuiltins(): boolean {\n try {\n // Check if we can access Node.js built-in modules\n // This will fail in browser environments\n return (\n typeof require !== 'undefined' ||\n (typeof process !== 'undefined' &&\n typeof process.versions === 'object' &&\n typeof process.versions.node === 'string')\n );\n } catch {\n return false;\n }\n}\n","/**\n * Shared client for \"service-rendered image\" components (highcharts, visual).\n *\n * Both offload rendering to an injected HTTP service: resolve a base URL, POST a\n * JSON body with optional dynamic headers, and normalize transport errors — now\n * with a request timeout so a wedged service can't hang the render forever.\n * Callers decode the response body themselves (highcharts returns base64 text,\n * visual returns JSON), so this returns the raw Response on success.\n */\n\nexport type ServiceHeaders =\n | Record<string, string>\n | ((\n body: unknown\n ) => Record<string, string> | Promise<Record<string, string>>);\n\nconst DEFAULT_TIMEOUT_MS = 30000;\n\n/**\n * Resolve a service base URL: per-call override → services config → default.\n * Adds an `http://` scheme to a bare host and strips trailing slashes so callers\n * can append `${url}/path` without producing a `//path` that breaks routers.\n */\nexport function resolveServiceUrl(\n propsUrl: string | undefined,\n servicesUrl: string | undefined,\n defaultUrl: string\n): string {\n const raw = (propsUrl || servicesUrl || defaultUrl).trim();\n const withScheme = /^https?:\\/\\//i.test(raw) ? raw : `http://${raw}`;\n return withScheme.replace(/\\/+$/, '');\n}\n\nexport interface PostJsonOptions {\n /** Resolved base URL (use resolveServiceUrl). */\n url: string;\n /** Path appended to the base URL, e.g. '/export' or '/rasterize'. */\n path: string;\n /** Request body (JSON-serialized). */\n body: unknown;\n /** Static headers or an async resolver receiving the body. */\n headers?: ServiceHeaders;\n /** Abort timeout in ms (default 30s). */\n timeoutMs?: number;\n /** Label used in the timeout message and the non-2xx error. */\n serviceLabel: string;\n /** Message builder for a connection failure (distinct from a timeout). */\n onUnreachable: (url: string, cause: string) => string;\n}\n\n/**\n * POST a JSON body to `${url}${path}` with a timeout. Returns the Response on a\n * 2xx; throws a normalized Error on timeout, connection failure, or non-2xx.\n */\nexport async function postJsonToService(\n opts: PostJsonOptions\n): Promise<Response> {\n const resolvedHeaders =\n typeof opts.headers === 'function'\n ? await opts.headers(opts.body)\n : opts.headers;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...resolvedHeaders,\n };\n\n const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n let response: Response;\n try {\n response = await fetch(`${opts.url}${opts.path}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts.body),\n signal: controller.signal,\n });\n } catch (error) {\n if ((error as Error)?.name === 'AbortError') {\n throw new Error(\n `${opts.serviceLabel} timed out after ${timeoutMs}ms at ${opts.url}.`\n );\n }\n const cause = error instanceof Error ? error.message : String(error);\n throw new Error(opts.onUnreachable(opts.url, cause));\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n throw new Error(\n `${opts.serviceLabel} returned ${response.status}: ${response.statusText}`\n );\n }\n return response;\n}\n","/**\n * Visual Component\n *\n * Renders a free-canvas graphic authored as a single pptx slide and embeds it\n * as a rasterized PNG. The slide is rendered to an image by an injected\n * rasterization service (`services.pptx`) — exactly the way the `highcharts`\n * component offloads chart rendering to an export server — then desugars to a\n * plain `image`.\n */\n\nimport { Paragraph, Table } from 'docx';\nimport {\n ComponentDefinition,\n RenderContext,\n isVisualComponent,\n} from '../types';\nimport { ThemeConfig } from '../styles';\nimport { createImage, type ImageOptions } from '../core/content';\nimport { isNodeEnvironment } from '../utils/environment';\nimport { getBaseDir } from '../utils/generationContext';\nimport { resolveServiceUrl, postJsonToService } from '../utils/serviceClient';\n\nimport type { VisualProps } from '@json-to-office/shared-docx';\nimport {\n clampVisualDpi,\n DEFAULT_VISUAL_DPI,\n type PptxServiceConfig,\n type PptxRasterizeResult,\n} from '@json-to-office/shared';\n\nconst DEFAULT_RASTERIZE_SERVER_URL = 'http://localhost:7802';\n/** 1 inch = 96 CSS pixels — used to size the embedded image at its physical canvas size. */\nconst PIXELS_PER_INCH = 96;\n\n/**\n * Build a single-slide pptx presentation component definition from visual props.\n * The shape mirrors a normal `.pptx.json` document so the pptx engine renders\n * it unchanged. Exported for reuse by the `flattenVisuals` transform.\n */\nexport function buildVisualPresentation(\n props: VisualProps\n): Record<string, unknown> {\n const { canvas, elements } = props;\n\n const presentationProps: Record<string, unknown> = {\n slideWidth: canvas.width,\n slideHeight: canvas.height,\n };\n if (canvas.theme) presentationProps.theme = canvas.theme;\n\n const slideProps: Record<string, unknown> = {};\n if (canvas.background) slideProps.background = canvas.background;\n\n return {\n name: 'pptx',\n props: presentationProps,\n children: [\n {\n name: 'slide',\n props: slideProps,\n children: elements ?? [],\n },\n ],\n };\n}\n\n/**\n * Default rendered width (px) for a visual: its physical canvas inches, so a\n * 6×4 canvas prints 6×4 unless `width` overrides.\n */\nexport function defaultVisualWidthPx(props: VisualProps): number {\n return Math.round(props.canvas.width * PIXELS_PER_INCH);\n}\n\n/**\n * Shared image-placement options derived from a visual's props. Used by BOTH\n * the render-time createImage call and the flatten transform so the two\n * desugaring paths can't drift (width default, alignment default, caption,\n * spacing, floating, keepNext/keepLines all live here once).\n */\nexport function visualToImageOptions(props: VisualProps): ImageOptions {\n return {\n width: props.width ?? defaultVisualWidthPx(props),\n ...(props.height !== undefined && { height: props.height }),\n alignment: props.alignment ?? 'center',\n ...(props.caption !== undefined && { caption: props.caption }),\n ...(props.spacing !== undefined && { spacing: props.spacing }),\n ...(props.floating !== undefined && { floating: props.floating }),\n ...(props.keepNext !== undefined && { keepNext: props.keepNext }),\n ...(props.keepLines !== undefined && { keepLines: props.keepLines }),\n };\n}\n\n/**\n * Map visual props to the `image` props they desugar to (used by the\n * `flattenVisuals` transform to produce a portable, service-free document).\n */\nexport function visualToImageProps(\n props: VisualProps,\n base64DataUri: string\n): Record<string, unknown> {\n return {\n base64: base64DataUri,\n ...visualToImageOptions(props),\n ...(props.alt !== undefined && { alt: props.alt }),\n };\n}\n\n/**\n * Rasterize a single-slide presentation to a PNG via the configured service.\n * An in-process `render` callback takes precedence over an HTTP `serverUrl`.\n */\nasync function rasterize(\n presentation: Record<string, unknown>,\n dpi: number,\n propsServerUrl: string | undefined,\n serviceConfig: PptxServiceConfig | undefined,\n baseDir: string | undefined\n): Promise<PptxRasterizeResult> {\n if (!isNodeEnvironment()) {\n throw new Error(\n 'Visual rasterization requires a Node.js environment. ' +\n 'It is not available in browser environments.'\n );\n }\n\n // In-process renderer wins (ideal for tests and single-process hosts).\n if (serviceConfig?.render) {\n return serviceConfig.render({ presentation, dpi, baseDir });\n }\n\n const serverUrl = resolveServiceUrl(\n propsServerUrl,\n serviceConfig?.serverUrl,\n DEFAULT_RASTERIZE_SERVER_URL\n );\n\n const response = await postJsonToService({\n url: serverUrl,\n path: '/rasterize',\n body: { presentation, dpi, ...(baseDir !== undefined && { baseDir }) },\n headers: serviceConfig?.headers,\n serviceLabel: 'PPTX rasterization service',\n onUnreachable: (url, cause) =>\n `PPTX rasterization service is not reachable at ${url}. ` +\n 'Configure services.pptx with a `render` callback or a running `serverUrl`.\\n' +\n `Cause: ${cause}`,\n });\n\n let result: PptxRasterizeResult;\n try {\n result = (await response.json()) as PptxRasterizeResult;\n } catch {\n throw new Error(\n 'PPTX rasterization service returned a non-JSON response (expected { base64DataUri, width, height }).'\n );\n }\n if (!result?.base64DataUri) {\n throw new Error(\n 'PPTX rasterization service returned a malformed response (missing base64DataUri).'\n );\n }\n return result;\n}\n\n/**\n * Render visual component\n */\nexport async function renderVisualComponent(\n component: ComponentDefinition,\n theme: ThemeConfig,\n themeName?: string,\n context?: RenderContext\n): Promise<(Paragraph | Table)[]> {\n if (!isVisualComponent(component)) return [];\n\n const props = component.props as VisualProps;\n const serviceConfig = context?.services?.pptx;\n\n const presentation = buildVisualPresentation(props);\n const dpi = clampVisualDpi(\n props.dpi ?? serviceConfig?.dpi ?? DEFAULT_VISUAL_DPI\n );\n\n // Relative asset paths inside the visual's nested presentation must\n // resolve against the same base directory as the docx document itself —\n // the rasterizer runs in another process/cwd (#142).\n const result = await rasterize(\n presentation,\n dpi,\n props.serverUrl,\n serviceConfig,\n getBaseDir()\n );\n\n // Size and placement options are derived once in visualToImageOptions (shared\n // with the flatten transform): default width = canvas physical inches; height\n // left unset so aspect ratio is preserved from the PNG.\n return await createImage(\n result.base64DataUri,\n theme,\n themeName,\n visualToImageOptions(props)\n );\n}\n","/**\n * Text Space After Custom Component\n * A text component with hardcoded spacing after the paragraph\n *\n * This component is provided as an example of the legacy custom component system.\n * For new custom components, use the plugin system instead:\n * @see packages/core/src/plugin/example/ for modern examples\n */\n\nimport { Type, Static } from '@sinclair/typebox';\nimport { createComponent, createVersion } from '../plugin/createComponent';\nimport type { ComponentDefinition } from '@json-to-office/shared-docx';\n\n/**\n * Props schema for text-space-after component\n */\nconst TextSpaceAfterPropsSchema = Type.Object({\n text: Type.String({\n description: 'Text content to display',\n }),\n // Retained for backwards compatibility of props shape, but not applied\n spacing: Type.Optional(\n Type.Object({\n before: Type.Optional(Type.Number()),\n after: Type.Optional(Type.Number()),\n })\n ),\n});\n\nexport type TextSpaceAfterProps = Static<typeof TextSpaceAfterPropsSchema>;\n\n/**\n * Text space after component - adds hardcoded spacing after paragraphs\n */\nexport const textSpaceAfterComponent = createComponent({\n name: 'text-space-after',\n versions: {\n '1.0.0': createVersion({\n propsSchema: TextSpaceAfterPropsSchema,\n description: 'Text component with hardcoded spacing after the paragraph',\n render: async ({ props }) => {\n // Create paragraph component with hardcoded spacing after\n const result: ComponentDefinition = {\n name: 'paragraph',\n props: {\n text: props.text,\n spacing: {\n ...props.spacing,\n after: props.spacing?.after || 12,\n },\n },\n };\n\n return [result];\n },\n }),\n },\n});\n","import type { TSchema } from '@sinclair/typebox';\nimport type { ComponentDefinition } from '@json-to-office/shared-docx';\nimport type { ThemeConfig } from '../styles';\nimport {\n createVersion as sharedCreateVersion,\n createComponent as sharedCreateComponent,\n} from '@json-to-office/shared/plugin';\nimport type {\n RenderContext as SharedRenderContext,\n RenderFunction as SharedRenderFunction,\n ComponentVersion as SharedComponentVersion,\n ComponentVersionMap as SharedComponentVersionMap,\n CustomComponent as SharedCustomComponent,\n} from '@json-to-office/shared/plugin';\n\n// ---- DOCX-specific type aliases (backward compat) ----\n\n/**\n * DOCX render context with ThemeConfig baked in\n */\nexport type RenderContext<T> = SharedRenderContext<T, ThemeConfig>;\n\nexport type RenderFunction<\n TProps,\n TComponentDefinition = ComponentDefinition,\n> = SharedRenderFunction<TProps, TComponentDefinition, ThemeConfig>;\n\nexport type ComponentVersion<\n TComponentDefinition = ComponentDefinition,\n TPropsSchema extends TSchema = TSchema,\n> = SharedComponentVersion<TComponentDefinition, TPropsSchema, ThemeConfig>;\n\nexport type ComponentVersionMap<TComponentDefinition = ComponentDefinition> =\n SharedComponentVersionMap<TComponentDefinition, ThemeConfig>;\n\nexport type CustomComponent<\n TComponentDefinition = ComponentDefinition,\n TVersions extends\n ComponentVersionMap<TComponentDefinition> = ComponentVersionMap<TComponentDefinition>,\n TName extends string = string,\n> = SharedCustomComponent<TComponentDefinition, TVersions, TName>;\n\n// ---- Re-export factory functions (thin wrappers for DOCX defaults) ----\n\nexport function createVersion<\n TPropsSchema extends TSchema,\n TComponentDefinition = ComponentDefinition,\n>(\n version: ComponentVersion<TComponentDefinition, TPropsSchema>\n): ComponentVersion<TComponentDefinition, TPropsSchema> {\n return sharedCreateVersion(version);\n}\n\nexport function createComponent<\n TComponentDefinition = ComponentDefinition,\n TVersions extends\n ComponentVersionMap<TComponentDefinition> = ComponentVersionMap<TComponentDefinition>,\n TName extends string = string,\n>(\n component: CustomComponent<TComponentDefinition, TVersions, TName>\n): CustomComponent<TComponentDefinition, TVersions, TName> {\n return sharedCreateComponent(component);\n}\n","/**\n * Shared font-resolution helper used by BOTH entry paths into renderDocument:\n *\n * - generator.ts → generateDocumentWithCustomThemes (non-plugin)\n * - plugin/createDocumentGenerator.ts → generate (plugin-aware)\n *\n * Keeping it in one place ensures the two paths behave identically around\n * validation, SAFE_FONTS awareness, Google Fonts materialization, and the\n * `onResolved` side-channel consumed by the LibreOffice preview font stager.\n */\n\nimport type {\n FontRuntimeOpts,\n ResolvedFont,\n GenerationWarning,\n} from '@json-to-office/shared';\nimport {\n collectFontNamesFromDocx,\n validateFontReferences,\n FontRegistry,\n} from '@json-to-office/shared';\nimport {\n loadFileFontSource,\n FontDiskCache,\n fetchVariableFontSource,\n} from '@json-to-office/shared/fonts/node';\nimport type { ThemeConfig } from '../styles';\nimport type { ReportComponentDefinition } from '../types';\n\nexport async function resolveDocumentFonts(\n document: ReportComponentDefinition,\n theme: ThemeConfig,\n fonts?: FontRuntimeOpts,\n warnings?: GenerationWarning[]\n): Promise<ResolvedFont[]> {\n const emit = (code: string, message: string) => {\n if (warnings) {\n warnings.push({\n component: 'fontRegistry',\n message,\n severity: 'warning',\n context: { code },\n });\n } else {\n // eslint-disable-next-line no-console\n console.warn(`[json-to-docx] ${code}: ${message}`);\n }\n };\n\n // Walk document + theme. The document typically names fonts only indirectly\n // via `theme: \"my-theme\"`, so fonts declared in the theme JSON would be\n // invisible without this second pass.\n const names = new Set<string>();\n for (const n of collectFontNamesFromDocx(document)) names.add(n);\n for (const n of collectFontNamesFromDocx(theme as unknown)) names.add(n);\n if (names.size === 0) return [];\n\n // Validate unconditionally — strict mode must fire even when no consumer\n // is listening via onResolved (CLI / library callers that just want\n // build-time validation of font references).\n const validation = validateFontReferences({\n referencedNames: names,\n registeredEntries: fonts?.extraEntries,\n });\n if (validation.warnings.length > 0) {\n if (fonts?.strict) {\n throw new Error(\n `Unresolved font references (strict mode):\\n` +\n validation.warnings.map((w) => ` - ${w.message}`).join('\\n')\n );\n }\n for (const w of validation.warnings) {\n emit(w.code, w.message);\n }\n }\n\n // Registry resolution (Google/URL/file fetches) only runs when a consumer\n // is listening via onResolved — typically the LibreOffice preview stager.\n // Office output never embeds bytes, so skipping fetches when nobody cares\n // keeps library callers from paying network cost.\n if (!fonts?.onResolved) return [];\n\n const registry = new FontRegistry({\n opts: fonts,\n fileLoader: loadFileFontSource,\n variableLoader: fetchVariableFontSource,\n diskCache: fonts?.googleFonts?.cacheDir\n ? new FontDiskCache(fonts.googleFonts.cacheDir)\n : undefined,\n });\n const resolved = await registry.resolveMany(names);\n for (const r of resolved) {\n for (const msg of r.warnings) {\n emit('FONT_UNRESOLVED', msg);\n }\n }\n // Fire the side-channel here so callers never have to remember. The\n // short-circuit above guarantees we only reach this point when a\n // listener is registered.\n fonts.onResolved(resolved);\n return resolved;\n}\n","import AdmZip from 'adm-zip';\nimport { type Document, Packer } from 'docx';\nimport { fixFloatingImageIdsInBuffer } from './fixFloatingImageIds';\n\nexport interface DocumentPackageOptions {\n /** Normalize volatile OOXML metadata and ZIP timestamps. Defaults to true. */\n deterministic?: boolean;\n /** Timestamp used for generated metadata. Defaults to a stable epoch. */\n generatedAt?: string | Date;\n}\n\n/** Stable, valid OOXML/ZIP timestamp used when no build timestamp is supplied. */\nexport const DEFAULT_GENERATION_DATE = new Date('2000-01-01T00:00:00.000Z');\n\nexport function resolveGenerationDate(options?: DocumentPackageOptions): Date {\n if (options?.generatedAt !== undefined) {\n const date = new Date(options.generatedAt);\n if (Number.isNaN(date.getTime())) {\n throw new RangeError('generatedAt must be a valid date');\n }\n if (date.getUTCFullYear() < 1980) {\n throw new RangeError(\n 'generatedAt must be on or after 1980-01-01 for ZIP compatibility'\n );\n }\n return date;\n }\n\n return options?.deterministic === false\n ? new Date()\n : new Date(DEFAULT_GENERATION_DATE);\n}\n\n/** Encode a UTC instant into the packed MS-DOS date/time field ZIP headers use. */\nfunction toDosTime(date: Date): number {\n const dosDate =\n (((date.getUTCFullYear() - 1980) & 0x7f) << 9) |\n ((date.getUTCMonth() + 1) << 5) |\n date.getUTCDate();\n const dosTime =\n (date.getUTCHours() << 11) |\n (date.getUTCMinutes() << 5) |\n (date.getUTCSeconds() >> 1);\n return ((dosDate << 16) | dosTime) >>> 0;\n}\n\n/**\n * Normalize package-level values that otherwise change on every render.\n * ZIP headers are written from UTC components because DOS timestamps carry no\n * timezone; this produces identical header bits in every locale.\n */\nexport function canonicalizeDocxBuffer(\n buffer: Buffer,\n generatedAt: Date = DEFAULT_GENERATION_DATE\n): Buffer {\n const zip = new AdmZip(buffer);\n const isoTimestamp = generatedAt.toISOString();\n const coreProperties = zip.getEntry('docProps/core.xml');\n\n if (coreProperties) {\n const normalized = coreProperties\n .getData()\n .toString('utf8')\n .replace(\n /(<dcterms:(?:created|modified)\\b[^>]*>)[^<]*(<\\/dcterms:(?:created|modified)>)/g,\n `$1${isoTimestamp}$2`\n );\n zip.updateFile(coreProperties, Buffer.from(normalized, 'utf8'));\n }\n\n // AdmZip's `header.time` setter encodes the timezone-less DOS field from\n // local getters, so the emitted bits would vary by host. Write the raw field\n // from UTC components instead. Going through a reconstructed local Date is\n // not enough: a value inside a DST spring-forward gap has no local\n // representation and the runtime silently shifts it an hour.\n // `timeval` is the raw DOS field; @types/adm-zip@0.5.7 only declares the\n // `time` Date accessor that wraps it, hence the cast.\n const zipTimestamp = toDosTime(generatedAt);\n for (const entry of zip.getEntries()) {\n (entry.header as unknown as { timeval: number }).timeval = zipTimestamp;\n }\n\n return zip.toBuffer();\n}\n\n/** Package a DOCX and apply all required OOXML post-processing once. */\nexport async function packageDocument(\n document: Document,\n options?: DocumentPackageOptions\n): Promise<Buffer> {\n const packed = (await Packer.toBuffer(document)) as Buffer;\n const fixed = fixFloatingImageIdsInBuffer(packed);\n\n if (options?.deterministic === false) {\n return fixed;\n }\n\n return canonicalizeDocxBuffer(fixed, resolveGenerationDate(options));\n}\n","/**\n * Post-processing utility to fix docx.js floating image bugs\n *\n * The docx library (as of v9.5.1) has a known issue with floating images:\n * 1. Duplicate wp:docPr IDs (GitHub issue #2719)\n *\n * Historical note: We previously also post-processed relativeHeight and\n * wrapTight elements. Those steps were removed because we always provide a\n * valid zIndex upstream and we do not support 'tight' wrapping.\n *\n * This utility extracts the DOCX, fixes duplicate IDs, and re-packages it.\n */\n\nimport AdmZip from 'adm-zip';\nimport { readFile, writeFile } from 'fs/promises';\n\n/** Fix duplicate floating-image IDs without touching the filesystem. */\nexport function fixFloatingImageIdsInBuffer(buffer: Buffer): Buffer {\n const zip = new AdmZip(buffer);\n const documentEntry = zip.getEntry('word/document.xml');\n\n if (!documentEntry) {\n throw new Error('document.xml not found in DOCX');\n }\n\n let idCounter = 1;\n const documentXml = documentEntry\n .getData()\n .toString('utf8')\n .replace(/<wp:docPr\\s+id=\"(\\d+)\"/g, () => {\n const newId = idCounter++;\n return `<wp:docPr id=\"${newId}\"`;\n });\n\n zip.updateFile(documentEntry, Buffer.from(documentXml, 'utf8'));\n return zip.toBuffer();\n}\n\n/**\n * Fix floating image issues in a generated DOCX file\n * @param docxPath - Path to the DOCX file to fix\n */\nexport async function fixFloatingImageIds(docxPath: string): Promise<void> {\n const buffer = await readFile(docxPath);\n await writeFile(docxPath, fixFloatingImageIdsInBuffer(buffer));\n}\n","/**\n * JSON Document Parser - Re-exports from shared package\n *\n * This module re-exports the JSON parsing functionality from the shared package\n * and provide a clean interface for the core package.\n */\n\n// Re-export everything from shared package's JSON parser\nexport {\n JsonDocumentParser,\n JsonParsingError,\n JsonValidationError,\n parseJsonComponent,\n validateJsonComponent,\n parseJsonWithLineNumbers,\n} from '@json-to-office/shared-docx';\n\n// Re-export types needed by other modules\nexport type {\n DocumentValidationResult,\n DocumentValidationError,\n} from '@json-to-office/shared-docx';\n","/**\n * Component Normalizer - Transforms JSON components where business logic requires it\n *\n * This module ONLY handles transformations that are actually necessary:\n * 1. Columns shorthand notation (columns: 3 → array format)\n * 2. Recursive processing of nested components\n * 3. Gap application for columns\n *\n * All other properties are preserved as-is from TypeBox validation.\n * This prevents information loss and maintains single source of truth.\n */\n\nimport {\n ComponentDefinition,\n ReportComponentDefinition,\n SectionComponentDefinition,\n ColumnsComponentDefinition,\n ColumnsProps,\n} from '../types';\n\n/**\n * Normalize a component definition and its nested children\n * Preserves all validated properties - only transforms where business logic requires\n */\nexport function normalizeComponent(\n component: ComponentDefinition\n): ComponentDefinition {\n // Handle columns component with shorthand notation\n if (component.name === 'columns') {\n return normalizeColumnsComponent(component as ColumnsComponentDefinition);\n }\n\n // Handle components with children - recursively normalize\n if ('children' in component && component.children) {\n return {\n ...component, // Preserve ALL properties from validated component\n children: component.children.map(normalizeComponent),\n } as ComponentDefinition;\n }\n\n // Handle section component with header/footer arrays\n if (component.name === 'section') {\n return normalizeSectionComponent(component as SectionComponentDefinition);\n }\n\n // All other components: return as-is (already validated by TypeBox)\n return component;\n}\n\n/**\n * Normalize columns component\n * Converts shorthand notation and applies gap logic\n */\nfunction normalizeColumnsComponent(\n component: ColumnsComponentDefinition\n): ColumnsComponentDefinition {\n const cfg = component.props || ({} as any);\n\n // Helper: apply top-level gap to all columns except last where not overridden\n const applyTopLevelGap = (\n cols: Array<{ width?: unknown; gap?: unknown }>,\n topGap: unknown\n ) =>\n cols.map((c, i) => {\n const isLast = i === cols.length - 1;\n if (!isLast && c.gap === undefined && topGap !== undefined) {\n return { ...c, gap: topGap };\n }\n return c;\n });\n\n // Helper: normalize 'auto' to unspecified width (internal layout splits remainder)\n const normalizeAutoWidth = (\n cols: Array<{ width?: unknown; gap?: unknown }>\n ) =>\n cols.map((c) => ({\n ...c,\n width: c.width === 'auto' ? undefined : c.width,\n }));\n\n let columnsArray: Array<{ width?: unknown; gap?: unknown }>;\n\n if (typeof cfg.columns === 'number' && cfg.columns > 0) {\n // Shorthand: N equal-width columns; apply gap after each except last\n const n = cfg.columns as number;\n const base = Array.from(\n { length: n },\n () => ({}) as { width?: unknown; gap?: unknown }\n );\n const topLevelGap = cfg.gap !== undefined ? cfg.gap : '5%';\n columnsArray = applyTopLevelGap(base, topLevelGap);\n } else if (Array.isArray(cfg.columns)) {\n // Array form; honor per-column config\n columnsArray = cfg.columns as Array<{ width?: unknown; gap?: unknown }>;\n // Apply top-level gap unless column overrides; skip last column\n const topLevelGap = cfg.gap !== undefined ? cfg.gap : '5%';\n columnsArray = applyTopLevelGap(columnsArray, topLevelGap);\n // Normalize 'auto' widths to unspecified so layout can allocate remainder\n columnsArray = normalizeAutoWidth(columnsArray);\n } else {\n // Minimal valid shape\n columnsArray = [{}];\n }\n\n const normalizedProps: ColumnsProps = {\n columns: columnsArray,\n } as ColumnsProps;\n\n return {\n ...component, // Preserve any additional properties\n name: 'columns',\n props: normalizedProps,\n children: component.children\n ? component.children.map(normalizeComponent)\n : undefined,\n };\n}\n\n/**\n * Normalize section component\n * Handles recursive processing of header/footer component arrays\n */\nfunction normalizeSectionComponent(\n component: SectionComponentDefinition\n): SectionComponentDefinition {\n const props = component.props || ({} as any);\n\n return {\n ...component, // Preserve ALL properties\n props: {\n ...props, // Preserve ALL props properties\n header: props.header\n ? props.header === 'linkToPrevious'\n ? 'linkToPrevious'\n : props.header.map((m: ComponentDefinition) => normalizeComponent(m))\n : undefined,\n footer: props.footer\n ? props.footer === 'linkToPrevious'\n ? 'linkToPrevious'\n : props.footer.map((m: ComponentDefinition) => normalizeComponent(m))\n : undefined,\n },\n children: component.children\n ? component.children.map(normalizeComponent)\n : undefined,\n };\n}\n\n/**\n * Normalize entire document (top-level report component)\n * Returns as single-element tuple for backward compatibility\n */\nexport function normalizeDocument(\n document: ComponentDefinition | ReportComponentDefinition\n): [ReportComponentDefinition] {\n // Validate it's a report component\n if (document.name !== 'docx') {\n throw new Error(\n 'Top-level document must be a docx component with name=\"docx\"'\n );\n }\n\n const normalized = normalizeComponent(document) as ReportComponentDefinition;\n return [normalized];\n}\n\n/**\n * Validate component structure (container vs content components)\n */\nexport function validateComponentStructure(component: any): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n\n // Components that can have children\n const containerComponents = ['docx', 'section', 'columns', 'text-box'];\n\n // Check if content components have children (they shouldn't)\n if (\n !containerComponents.includes(component.name) &&\n component.children &&\n component.children.length > 0\n ) {\n errors.push(\n `Component name \"${component.name}\" cannot have child components`\n );\n }\n\n // Recursively validate child components\n if (component.children) {\n component.children.forEach(\n (childComponent: ComponentDefinition, index: number) => {\n const childResult = validateComponentStructure(childComponent);\n if (!childResult.valid) {\n errors.push(\n ...childResult.errors.map(\n (error) => `Component[${index}]: ${error}`\n )\n );\n }\n }\n );\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","import { promises as fs } from 'fs';\nimport { join, resolve, isAbsolute } from 'path';\nimport { watch, FSWatcher } from 'fs';\nimport { ComponentDefinition } from '@json-to-office/shared-docx';\nimport { parseJsonWithLineNumbers } from './parser';\n\n/**\n * File System utilities for JSON report definitions\n */\n\n/**\n * Load JSON report definition from file\n * Supports both relative and absolute file paths\n */\nexport async function loadJsonDefinition(\n filePath: string\n): Promise<ComponentDefinition> {\n try {\n // Resolve path (handles both relative and absolute paths)\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(filePath);\n\n // Check if file exists\n await fs.access(absolutePath);\n\n // Read file content\n const fileContent = await fs.readFile(absolutePath, 'utf-8');\n\n // Parse JSON with line number tracking for better errors\n return parseJsonWithLineNumbers(fileContent) as ComponentDefinition;\n } catch (error) {\n if (error instanceof Error && 'code' in error) {\n const fsError = error as Error & { code?: string };\n\n switch (fsError.code) {\n case 'ENOENT':\n throw new JsonFileError(\n `File not found: ${filePath}`,\n 'FILE_NOT_FOUND'\n );\n case 'EACCES':\n throw new JsonFileError(\n `Permission denied: ${filePath}`,\n 'PERMISSION_DENIED'\n );\n case 'EISDIR':\n throw new JsonFileError(\n `Path is a directory: ${filePath}`,\n 'IS_DIRECTORY'\n );\n default:\n throw new JsonFileError(\n `File system error: ${fsError.message}`,\n 'FS_ERROR'\n );\n }\n }\n\n // Re-throw parsing errors with file context\n if (error instanceof Error) {\n throw new JsonFileError(\n `Error loading ${filePath}: ${error.message}`,\n 'PARSE_ERROR',\n error\n );\n }\n\n throw new JsonFileError(\n `Unknown error loading ${filePath}`,\n 'UNKNOWN_ERROR'\n );\n }\n}\n\n/**\n * Load JSON definition with validation but without throwing on validation errors\n */\nexport async function loadJsonDefinitionSafe(filePath: string): Promise<{\n success: boolean;\n definition?: ComponentDefinition;\n error?: JsonFileError;\n}> {\n try {\n const definition = await loadJsonDefinition(filePath);\n return { success: true, definition };\n } catch (error) {\n return {\n success: false,\n error:\n error instanceof JsonFileError\n ? error\n : new JsonFileError(\n error instanceof Error ? error.message : String(error),\n 'UNKNOWN_ERROR'\n ),\n };\n }\n}\n\n/**\n * Watch JSON file for changes and call callback on modifications\n * Useful for development workflows\n */\nexport function watchJsonFile(\n filePath: string,\n callback: (\n _definition: ComponentDefinition | null,\n _error?: JsonFileError\n ) => void\n): JsonFileWatcher {\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(filePath);\n\n // Initial load\n loadJsonDefinitionSafe(absolutePath).then((result) => {\n if (result.success) {\n callback(result.definition!);\n } else {\n callback(null, result.error);\n }\n });\n\n // Set up file watcher\n const watcher = watch(absolutePath, { persistent: true }, (eventType) => {\n if (eventType === 'change') {\n // Debounce rapid file changes\n setTimeout(async () => {\n const result = await loadJsonDefinitionSafe(absolutePath);\n if (result.success) {\n callback(result.definition!);\n } else {\n callback(null, result.error);\n }\n }, 100);\n }\n });\n\n return new JsonFileWatcher(watcher, absolutePath);\n}\n\n/**\n * Watch multiple JSON files and call callback when any changes\n */\nexport function watchJsonFiles(\n filePaths: string[],\n callback: (\n _filePath: string,\n _definition: ComponentDefinition | null,\n _error?: JsonFileError\n ) => void\n): JsonFileWatcher[] {\n return filePaths.map((filePath) => {\n return watchJsonFile(filePath, (definition, error) => {\n callback(filePath, definition, error);\n });\n });\n}\n\n/**\n * Check if file exists and is accessible\n */\nexport async function checkJsonFile(filePath: string): Promise<{\n exists: boolean;\n readable: boolean;\n isDirectory: boolean;\n error?: string;\n}> {\n try {\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(filePath);\n const stats = await fs.stat(absolutePath);\n\n return {\n exists: true,\n readable: true,\n isDirectory: stats.isDirectory(),\n };\n } catch (error) {\n if (error instanceof Error && 'code' in error) {\n const fsError = error as Error & { code?: string };\n\n switch (fsError.code) {\n case 'ENOENT':\n return {\n exists: false,\n readable: false,\n isDirectory: false,\n error: 'File not found',\n };\n case 'EACCES':\n return {\n exists: true,\n readable: false,\n isDirectory: false,\n error: 'Permission denied',\n };\n default:\n return {\n exists: false,\n readable: false,\n isDirectory: false,\n error: fsError.message,\n };\n }\n }\n\n return {\n exists: false,\n readable: false,\n isDirectory: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Find JSON files in a directory (non-recursive)\n */\nexport async function findJsonFiles(directoryPath: string): Promise<string[]> {\n try {\n const absolutePath = isAbsolute(directoryPath)\n ? directoryPath\n : resolve(directoryPath);\n const entries = await fs.readdir(absolutePath, { withFileTypes: true });\n\n return entries\n .filter((entry) => entry.isFile() && entry.name.endsWith('.json'))\n .map((entry) => join(absolutePath, entry.name));\n } catch (error) {\n if (error instanceof Error && 'code' in error) {\n const fsError = error as Error & { code?: string };\n\n switch (fsError.code) {\n case 'ENOENT':\n throw new JsonFileError(\n `Directory not found: ${directoryPath}`,\n 'DIRECTORY_NOT_FOUND'\n );\n case 'ENOTDIR':\n throw new JsonFileError(\n `Path is not a directory: ${directoryPath}`,\n 'NOT_DIRECTORY'\n );\n case 'EACCES':\n throw new JsonFileError(\n `Permission denied: ${directoryPath}`,\n 'PERMISSION_DENIED'\n );\n default:\n throw new JsonFileError(\n `Directory error: ${fsError.message}`,\n 'DIRECTORY_ERROR'\n );\n }\n }\n\n throw new JsonFileError(\n `Unknown error reading directory ${directoryPath}`,\n 'UNKNOWN_ERROR'\n );\n }\n}\n\n/**\n * Save JSON report definition to file\n */\nexport async function saveJsonDefinition(\n definition: ComponentDefinition,\n filePath: string,\n options: { pretty?: boolean; backup?: boolean } = {}\n): Promise<void> {\n const { pretty = true, backup = false } = options;\n\n try {\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(filePath);\n\n // Create backup if requested\n if (backup) {\n try {\n const backupPath = `${absolutePath}.backup`;\n await fs.copyFile(absolutePath, backupPath);\n } catch (error) {\n // Ignore backup errors if original file doesn't exist\n if (\n error instanceof Error &&\n 'code' in error &&\n (error as Error & { code?: string }).code !== 'ENOENT'\n ) {\n console.warn(`Failed to create backup: ${error.message}`);\n }\n }\n }\n\n // Serialize JSON\n const jsonContent = pretty\n ? JSON.stringify(definition, null, 2)\n : JSON.stringify(definition);\n\n // Write file\n await fs.writeFile(absolutePath, jsonContent, 'utf-8');\n } catch (error) {\n if (error instanceof Error && 'code' in error) {\n const fsError = error as Error & { code?: string };\n\n switch (fsError.code) {\n case 'EACCES':\n throw new JsonFileError(\n `Permission denied: ${filePath}`,\n 'PERMISSION_DENIED'\n );\n case 'ENOSPC':\n throw new JsonFileError(\n `No space left on device: ${filePath}`,\n 'NO_SPACE'\n );\n default:\n throw new JsonFileError(\n `Write error: ${fsError.message}`,\n 'WRITE_ERROR'\n );\n }\n }\n\n throw new JsonFileError(\n `Unknown error saving ${filePath}`,\n 'UNKNOWN_ERROR'\n );\n }\n}\n\n/**\n * File watcher wrapper class\n */\nexport class JsonFileWatcher {\n private watcher: FSWatcher;\n private filePath: string;\n\n constructor(watcher: FSWatcher, filePath: string) {\n this.watcher = watcher;\n this.filePath = filePath;\n }\n\n /**\n * Stop watching the file\n */\n public close(): void {\n this.watcher.close();\n }\n\n /**\n * Get the watched file path\n */\n public getFilePath(): string {\n return this.filePath;\n }\n}\n\n/**\n * Custom error class for file system operations\n */\nexport class JsonFileError extends Error {\n public readonly code: string;\n public readonly originalError?: Error;\n\n constructor(message: string, code: string, originalError?: Error) {\n super(message);\n this.name = 'JsonFileError';\n this.code = code;\n this.originalError = originalError;\n }\n}\n\n/**\n * Utility function to validate JSON file extension\n */\nexport function hasJsonExtension(filePath: string): boolean {\n return filePath.toLowerCase().endsWith('.json');\n}\n\n/**\n * Utility to ensure a path has .json extension\n */\nexport function ensureJsonExtension(filePath: string): string {\n return hasJsonExtension(filePath) ? filePath : `${filePath}.json`;\n}\n","/**\n * flattenVisuals — desugar `visual` components to plain `image` components ahead\n * of time, producing a portable, service-free `.docx.json`.\n *\n * The normal pipeline rasterizes `visual` nodes at render time via\n * `services.pptx`. This transform does the same desugaring offline: walk the\n * document tree, rasterize each `visual` with the supplied rasterizer, and\n * replace it with `{ name: 'image', props: { base64, ... } }`. The result builds\n * with no rasterization service configured — handy for shipping documents that\n * generate on hosts without LibreOffice/poppler.\n *\n * The walk covers every place the docx model can hold a child component, not\n * just `children`: section `props.header`/`props.footer`, and table\n * `props.columns[].cells[].content` / `props.columns[].header.content`.\n */\n\nimport {\n clampVisualDpi,\n DEFAULT_VISUAL_DPI,\n type PptxRasterizer,\n} from '@json-to-office/shared';\nimport type { VisualProps } from '@json-to-office/shared-docx';\nimport {\n buildVisualPresentation,\n visualToImageProps,\n} from '../components/visual';\n\nconst DEFAULT_CONCURRENCY = 4;\n\nexport interface FlattenVisualsOptions {\n /** Rasterizer that turns a single-slide pptx presentation into a PNG. */\n rasterize: PptxRasterizer;\n /** Default DPI applied when a `visual` does not specify one (default 200). */\n dpi?: number;\n /** Max concurrent rasterizations (default 4). */\n concurrency?: number;\n /**\n * Directory that relative asset paths inside visuals resolve against —\n * the document's own directory. Absent → the rasterizer's cwd (#142).\n */\n baseDir?: string;\n}\n\ninterface FlattenCtx {\n rasterize: PptxRasterizer;\n dpi?: number;\n baseDir?: string;\n limit: <T>(fn: () => Promise<T>) => Promise<T>;\n}\n\n/** Minimal promise pool bounding concurrent rasterizations. */\nfunction createLimiter(max: number): <T>(fn: () => Promise<T>) => Promise<T> {\n let active = 0;\n const queue: Array<() => void> = [];\n const release = () => {\n active--;\n queue.shift()?.();\n };\n return async function limit<T>(fn: () => Promise<T>): Promise<T> {\n if (active >= max)\n await new Promise<void>((resolve) => queue.push(resolve));\n active++;\n try {\n return await fn();\n } finally {\n release();\n }\n };\n}\n\n/**\n * Return a deep copy of `doc` with every `visual` node replaced by the `image`\n * node it rasterizes to. Visuals rasterize with bounded concurrency. A\n * `visual` with `enabled: false` is left untouched (it's filtered out at render\n * anyway, so rasterizing it would be wasted work). Non-visual nodes are copied\n * structurally and otherwise unchanged.\n */\nexport async function flattenVisuals<T = unknown>(\n doc: T,\n options: FlattenVisualsOptions\n): Promise<T> {\n const ctx: FlattenCtx = {\n rasterize: options.rasterize,\n dpi: options.dpi,\n baseDir: options.baseDir,\n limit: createLimiter(\n Math.max(1, options.concurrency ?? DEFAULT_CONCURRENCY)\n ),\n };\n return (await flattenNode(doc, ctx)) as T;\n}\n\nasync function rasterizeVisual(\n obj: Record<string, unknown>,\n ctx: FlattenCtx\n): Promise<Record<string, unknown>> {\n const props = obj.props as VisualProps;\n const dpi = clampVisualDpi(props.dpi ?? ctx.dpi ?? DEFAULT_VISUAL_DPI);\n const result = await ctx.limit(() =>\n ctx.rasterize({\n presentation: buildVisualPresentation(props),\n dpi,\n baseDir: ctx.baseDir,\n })\n );\n const image: Record<string, unknown> = {\n name: 'image',\n props: visualToImageProps(props, result.base64DataUri),\n };\n // Preserve identity/visibility metadata from the original node.\n if (obj.id !== undefined) image.id = obj.id;\n if (obj.enabled !== undefined) image.enabled = obj.enabled;\n return image;\n}\n\nasync function flattenNode(node: unknown, ctx: FlattenCtx): Promise<unknown> {\n if (Array.isArray(node)) {\n return Promise.all(node.map((n) => flattenNode(n, ctx)));\n }\n if (!node || typeof node !== 'object') return node;\n\n const obj = node as Record<string, unknown>;\n\n // Replace an enabled visual with its rasterized image. A disabled visual is\n // left as-is (filtered at render; rasterizing it would be wasted work).\n if (obj.name === 'visual' && obj.props && obj.enabled !== false) {\n return rasterizeVisual(obj, ctx);\n }\n\n const next: Record<string, unknown> = { ...obj };\n\n if (Array.isArray(obj.children)) {\n next.children = await flattenNode(obj.children, ctx);\n }\n\n if (obj.props && typeof obj.props === 'object') {\n const props = obj.props as Record<string, unknown>;\n let propsChanged = false;\n const nextProps: Record<string, unknown> = { ...props };\n\n // Section header/footer: arrays of component definitions (or a literal\n // 'linkToPrevious' string, which flattenNode returns unchanged).\n for (const key of ['header', 'footer'] as const) {\n if (Array.isArray(props[key])) {\n nextProps[key] = await flattenNode(props[key], ctx);\n propsChanged = true;\n }\n }\n\n // Table columns: each cell's `content` and the column header's `content`\n // hold a component definition (or a string).\n if (Array.isArray(props.columns)) {\n nextProps.columns = await Promise.all(\n (props.columns as unknown[]).map((col) => flattenColumn(col, ctx))\n );\n propsChanged = true;\n }\n\n if (propsChanged) next.props = nextProps;\n }\n\n return next;\n}\n\nasync function flattenColumn(col: unknown, ctx: FlattenCtx): Promise<unknown> {\n if (!col || typeof col !== 'object') return col;\n const column = col as Record<string, unknown>;\n const nextCol: Record<string, unknown> = { ...column };\n\n const header = column.header as Record<string, unknown> | undefined;\n if (header && typeof header === 'object' && 'content' in header) {\n nextCol.header = {\n ...header,\n content: await flattenNode(header.content, ctx),\n };\n }\n\n if (Array.isArray(column.cells)) {\n nextCol.cells = await Promise.all(\n (column.cells as unknown[]).map(async (cell) => {\n if (cell && typeof cell === 'object' && 'content' in cell) {\n const c = cell as Record<string, unknown>;\n return { ...c, content: await flattenNode(c.content, ctx) };\n }\n return cell;\n })\n );\n }\n\n return nextCol;\n}\n","/**\n * Warnings Document Generator\n * Utility to generate a document from generation warnings\n */\n\nimport type { GenerationWarning } from '@json-to-office/shared-docx';\nimport type { ComponentDefinition, ReportComponentDefinition } from '../types';\n\n/**\n * Generate a report document from warnings\n * Returns null if there are no warnings\n */\nexport function generateWarningsDocument(\n warnings: GenerationWarning[] | null\n): ReportComponentDefinition | null {\n if (!warnings || warnings.length === 0) {\n return null;\n }\n\n const children: ComponentDefinition[] = [\n {\n name: 'heading',\n props: {\n level: 1,\n text: 'Document Generation Warnings',\n },\n },\n {\n name: 'paragraph',\n props: {\n text: `${warnings.length} warning(s) were generated during document processing.`,\n spacing: {\n after: 24,\n },\n },\n },\n ];\n\n // Group warnings by component\n const warningsByComponent = new Map<string, GenerationWarning[]>();\n for (const warning of warnings) {\n const existing = warningsByComponent.get(warning.component) || [];\n existing.push(warning);\n warningsByComponent.set(warning.component, existing);\n }\n\n // Create sections for each component with warnings\n for (const [componentName, componentWarnings] of warningsByComponent.entries()) {\n children.push({\n name: 'heading',\n props: {\n level: 3,\n text: `Component: ${componentName}`,\n },\n });\n\n // Add each warning as a list item with details\n const warningItems: string[] = [];\n for (const warning of componentWarnings) {\n let warningText = warning.message;\n\n // Add context if present\n if (warning.context && Object.keys(warning.context).length > 0) {\n const contextStr = Object.entries(warning.context)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ');\n warningText += ` (${contextStr})`;\n }\n\n warningItems.push(warningText);\n }\n\n children.push({\n name: 'list',\n props: {\n items: warningItems,\n spacing: {\n after: 12,\n },\n },\n });\n }\n\n return {\n name: 'docx',\n props: {\n metadata: {\n title: 'Generation Warnings',\n },\n theme: 'minimal',\n },\n children,\n };\n}\n\n/**\n * Format warnings as plain text\n * Useful for logging or text output\n */\nexport function formatWarningsText(\n warnings: GenerationWarning[] | null\n): string {\n if (!warnings || warnings.length === 0) {\n return 'No warnings generated.';\n }\n\n const lines: string[] = [\n `Document Generation Warnings (${warnings.length} total)`,\n '='.repeat(50),\n '',\n ];\n\n // Group by component\n const warningsByComponent = new Map<string, GenerationWarning[]>();\n for (const warning of warnings) {\n const existing = warningsByComponent.get(warning.component) || [];\n existing.push(warning);\n warningsByComponent.set(warning.component, existing);\n }\n\n for (const [componentName, componentWarnings] of warningsByComponent.entries()) {\n lines.push(`Component: ${componentName}`);\n lines.push('-'.repeat(30));\n\n for (let i = 0; i < componentWarnings.length; i++) {\n const warning = componentWarnings[i];\n lines.push(` ${i + 1}. ${warning.message}`);\n\n if (warning.context && Object.keys(warning.context).length > 0) {\n lines.push(` Context: ${JSON.stringify(warning.context, null, 2)}`);\n }\n }\n\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","// Version information\nexport function getCoreVersion(): string {\n return 'Core v1.0.0';\n}\n\n// Core functional API\nexport {\n generateDocument,\n generateFromConfig,\n generateDocumentFromJson,\n generateDocumentFromFile,\n generateBufferFromJson,\n generateBufferFromFile,\n generateAndSaveFromJson,\n generateAndSaveFromFile,\n validateJsonSchema,\n isReportComponentDefinition,\n saveDocument,\n generateAndSave,\n DocumentGenerator as CoreDocumentGenerator,\n} from './core/generator';\n\n// Visual flattening (desugar `visual` → `image` for portable, service-free docs)\nexport {\n flattenVisuals,\n type FlattenVisualsOptions,\n} from './core/flattenVisuals';\n\n// Cache API (general purpose caching, not specific to custom components)\nexport {\n MemoryCache,\n CacheKeyGenerator,\n DEFAULT_CACHE_CONFIG,\n getCacheConfigFromEnv,\n mergeConfigs,\n ComponentCacheAnalytics,\n // Types\n type CacheConfiguration,\n type CachedComponent,\n type CacheStatistics,\n type CacheKeyOptions,\n type CacheEvents,\n type CacheAnalyticsReport,\n type ComponentPerformanceMetrics,\n type ComponentCacheTrends,\n type CacheOptimizationRecommendation,\n type TimeSeriesPoint,\n} from './cache/index';\n\n// Component cache functions from core\nexport {\n initializeComponentCache,\n getComponentCache,\n clearComponentCache,\n getComponentCacheStats,\n warmComponentCache,\n} from './core/cached-render';\n\n// Legacy class-based API is now removed - use functional API above\n\n// Runtime exports (only type guards and functions)\nexport {\n // Type guards\n isReportComponent,\n isSectionComponent,\n isHeadingComponent,\n isParagraphComponent,\n isColumnsComponent,\n isImageComponent,\n isStatisticComponent,\n isTableComponent,\n isListComponent,\n isHighchartsComponent,\n isVisualComponent,\n} from './types/index';\n\n// Export core-specific types only\nexport type {\n // Core-specific types\n ImageContent,\n StatisticContent,\n TableData,\n SectionProperties,\n ColumnSettings,\n PageSizeOptions,\n PageMarginOptions,\n PageNumberOptions,\n PageBorderOptions,\n RenderContext,\n} from './types/index';\n\n// Utilities\nexport * from './utils/formatters';\nexport { parseTextWithDecorators } from './utils/textParser';\nexport { isNodeEnvironment, hasNodeBuiltins } from './utils/environment';\nexport {\n generateWarningsDocument,\n formatWarningsText,\n} from './utils/warningsDocument';\n\n// Styles and themes\nexport {\n themes,\n minimalTheme,\n corporateTheme,\n modernTheme,\n} from './styles/index';\nexport type { ThemeName } from './styles/index';\n\n// JSON Theme System\nexport {\n loadThemeFromJson,\n loadThemeFromFile,\n exportThemeToJson,\n validateThemeJsonString,\n ThemeValidationError,\n ThemeParseError,\n ThemeFileError,\n createMinimalTheme,\n} from './themes/json/index';\n\n// Examples and utilities\nexport {\n examples,\n getExample,\n getExampleNames,\n loadJsonExample,\n} from './templates/documents/index';\nexport { runExample } from './utils/exampleRunner';\n\n// Export component implementations\nimport './components/index';\n\n// Re-export types from components (excluding those that come from shared)\nexport type {\n // ChartGenerationResult is specific to the component implementation\n ChartGenerationResult,\n} from './components/highcharts';\n\n// Note: TextSpaceAfterProps and HighchartsProps types are now in shared package\n// and should be imported from there to maintain single source of truth\n\n// Plugin System API\nexport {\n // Core plugin functions\n createComponent,\n createVersion,\n createDocumentGenerator,\n\n // Validation utilities\n validateComponentProps,\n validateDocument,\n cleanComponentProps,\n ComponentValidationError,\n UnknownPreservedComponentError,\n\n // Schema utilities\n generatePluginDocumentSchema,\n exportPluginSchema,\n generateComponentSchemas,\n mergeSchemas,\n\n // Types\n type CustomComponent,\n type ComponentVersion,\n type ComponentVersionMap,\n type RenderFunction,\n type RenderContext as ComponentRenderContext,\n type DocumentGenerator,\n type DocumentGeneratorOptions,\n type GenerateOptions,\n type GenerateFileOptions,\n type GenerationResult,\n type BufferGenerationResult,\n type FileGenerationResult,\n type ValidationResult,\n type ValidationError,\n\n // Type utilities for custom components\n type ExtractCustomComponentType,\n type CustomComponentUnion,\n type ExtendedComponentDefinition,\n type ExtendedReportComponent,\n type InferCustomComponents,\n} from './plugin/index';\n\n// Plugin types\nexport type {\n PluginComponent,\n PluginRenderFunction,\n PluginValidationError,\n PluginValidationResult,\n} from './types/plugin';\n","/**\n * Examples registry - JSON-based examples\n * This file provides a unified interface to the JSON examples system\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { ComponentDefinition } from '@json-to-office/shared-docx';\n\nlet _dirname: string | null = null;\n\nfunction getDirname(): string {\n if (_dirname === null) {\n try {\n _dirname = path.dirname(fileURLToPath(import.meta.url));\n } catch {\n throw new Error(\n 'Cannot resolve file paths in a bundled environment. Example loading from disk is not available.'\n );\n }\n }\n return _dirname;\n}\n\n/**\n * Load a JSON example by name\n */\nexport function loadJsonExample(name: string): ComponentDefinition {\n // Since this file is bundled into dist/index.js, getDirname() will be the dist directory\n // The JSON files are copied to dist/templates/documents/ by the tsup config\n const filePath = path.join(\n getDirname(),\n 'templates',\n 'documents',\n `${name}.docx.json`\n );\n\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n return JSON.parse(content) as ComponentDefinition;\n } catch (error) {\n throw new Error(\n `Failed to load JSON example \"${name}\": ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Get list of available JSON examples\n */\nexport function getAvailableJsonExamples(): string[] {\n // Since this file is bundled into dist/index.js, getDirname() will be the dist directory\n // The JSON files are copied to dist/templates/documents/ by the tsup config\n const examplesDir = path.join(getDirname(), 'templates', 'documents');\n\n try {\n const files = fs.readdirSync(examplesDir);\n return files\n .filter((file) => file.endsWith('.docx.json'))\n .map((file) => path.basename(file, '.docx.json'))\n .sort();\n } catch (error) {\n console.warn('Could not read JSON examples directory:', error);\n return [];\n }\n}\n\n/**\n * Example descriptions for documentation\n */\nexport const EXAMPLE_DESCRIPTIONS: Record<string, string> = {\n 'technical-guide':\n 'Arcline Platform integration guide with TOC, headers/footers, OAuth code samples, API reference tables, webhook docs, and troubleshooting',\n proposal:\n 'Apex Consulting cloud migration proposal with TOC, headers/footers, images, statistics, compliance tables, cost comparisons, and risk matrix',\n};\n\n/**\n * Registry of available JSON examples (lazy-loaded)\n * For backward compatibility, this returns ComponentDefinition objects\n */\nconst _exampleCache: Record<string, ComponentDefinition> = {};\n\nexport const examples = new Proxy({} as Record<string, ComponentDefinition>, {\n get(_target, prop: string) {\n if (!_exampleCache[prop]) {\n try {\n _exampleCache[prop] = loadJsonExample(prop);\n } catch {\n return undefined;\n }\n }\n return _exampleCache[prop];\n },\n\n ownKeys(_target) {\n return getAvailableJsonExamples();\n },\n\n has(_target, prop: string) {\n return getAvailableJsonExamples().includes(prop);\n },\n});\n\n/**\n * Get example definition by name\n */\nexport const getExample = (\n exampleName: string\n): ComponentDefinition | undefined => {\n return examples[exampleName];\n};\n\n/**\n * Get all available example names\n */\nexport const getExampleNames = (): string[] => {\n return getAvailableJsonExamples();\n};\n\n// Use loadJsonExample() directly or access via the examples proxy\nexport const technicalGuideExample = () => loadJsonExample('technical-guide');\nexport const proposalExample = () => loadJsonExample('proposal');\n\n/**\n * Print usage information\n */\nexport function printExampleUsage(): void {\n const available = getAvailableJsonExamples();\n\n console.log('📋 Available JSON Examples:');\n console.log('===========================');\n\n available.forEach((name) => {\n const description =\n EXAMPLE_DESCRIPTIONS[name] || 'No description available';\n console.log(`\\n📄 ${name}:`);\n console.log(` ${description}`);\n console.log(` Usage: loadJsonExample('${name}')`);\n });\n\n console.log('\\n🔧 Example code:');\n console.log('```typescript');\n console.log(\n 'import { loadJsonExample, generateDocumentFromJson } from \"cool-report-generator\";'\n );\n console.log('');\n console.log('const jsonConfig = loadJsonExample(\"comprehensive\");');\n console.log('const document = await generateDocumentFromJson(jsonConfig);');\n console.log('```');\n}\n","/**\n * Universal example runner utility\n * Provides common functionality for running examples\n */\n\nimport { generateDocument, saveDocument } from '../core/generator';\nimport { ReportComponentDefinition } from '../types';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nexport interface ExampleRunnerOptions {\n outputFilename?: string;\n outputDir?: string;\n verbose?: boolean;\n}\n\n/**\n * Run an example and generate a document\n * @param example - The example definition to run\n * @param options - Options for running the example\n */\nexport async function runExample(\n example: ReportComponentDefinition,\n options: ExampleRunnerOptions = {}\n): Promise<void> {\n const { outputFilename, outputDir, verbose = true } = options;\n\n if (!example.props) {\n throw new Error('Example must have props');\n }\n\n const reportTitle = String(example.props.metadata?.title) || 'Document';\n const baseFilename =\n outputFilename || `${reportTitle.toLowerCase().replace(/\\s+/g, '-')}.docx`;\n\n // Use output directory if provided, otherwise use default output/examples path\n const defaultOutputDir = path.join(process.cwd(), 'output', 'examples');\n const finalOutputDir = outputDir || defaultOutputDir;\n const filename = path.join(finalOutputDir, baseFilename);\n\n if (verbose) {\n console.log(`=== ${reportTitle} Generation ===\\n`);\n console.log(`Generating ${reportTitle} with modular system...`);\n }\n\n try {\n // Ensure output directory exists\n await fs.promises.mkdir(finalOutputDir, { recursive: true });\n\n const document = await generateDocument(example);\n await saveDocument(document, filename);\n\n if (verbose) {\n console.log(`✓ ${reportTitle} saved: ${filename}`);\n console.log(`\\n✅ ${reportTitle} generated successfully!`);\n }\n } catch (error) {\n if (verbose) {\n console.error(`${reportTitle} generation failed:`, error);\n }\n throw error;\n }\n}\n","import type { TSchema } from '@sinclair/typebox';\nimport type { CustomComponent } from './createComponent';\nimport type { ComponentDefinition, ReportComponentDefinition } from '../types';\nimport { type ThemeConfig } from '../styles';\nimport { resolveBuiltInTheme } from '../styles/theme-resolver';\nimport { hasTheme } from '../templates/themes';\nimport { resolveThemeContext } from '../core/generationContext';\nimport type { GenerationWarning } from '@json-to-office/shared-docx';\nimport type { ServicesConfig, FontRuntimeOpts } from '@json-to-office/shared';\nimport { resolveDocumentFonts } from '../core/fontResolution';\nimport type {\n ExtendedReportComponent,\n DocumentGeneratorBuilder,\n GenerateOptions,\n GenerateFileOptions,\n GenerationResult,\n BufferGenerationResult,\n FileGenerationResult,\n ValidationResult,\n GenerationValidationOptions,\n} from './types';\nimport {\n validateDocument,\n cleanComponentProps,\n ComponentValidationError,\n DuplicateComponentError,\n} from './validation';\nimport { UnknownPreservedComponentError } from '@json-to-office/shared/plugin';\nimport { resolveComponentVersion } from './version-resolver';\nimport { generatePluginDocumentSchema, exportPluginSchema } from './schema';\nimport { processDocument } from '../core/structure';\nimport { applyLayout } from '../core/layout';\nimport { renderDocument } from '../core/render';\nimport { normalizeDocument } from '../json/normalizer';\nimport {\n packageDocument,\n resolveGenerationDate,\n} from '../utils/packageDocument';\n\n/**\n * Options for creating a document generator\n */\nexport interface DocumentGeneratorOptions {\n /** Default theme used when no custom or built-in theme matches */\n theme?: ThemeConfig;\n /** Custom themes keyed by name, resolved per-document via document.props.theme */\n customThemes?: Record<string, ThemeConfig>;\n /** Enable caching for better performance */\n enableCache?: boolean;\n /** Enable debug logging */\n debug?: boolean;\n /** External service configuration (e.g. Highcharts export server) */\n services?: ServicesConfig;\n /** Font resolution options — extraEntries, Google Fonts config, onResolved hook. */\n fonts?: FontRuntimeOpts;\n /**\n * Default validation behavior for every generate/generateBuffer/generateFile\n * call. Per-call `options.validation` overrides these. Validation is on by\n * default; pass `{ enabled: false }` to opt out.\n */\n validation?: GenerationValidationOptions;\n /** Normalize volatile OOXML values for byte-identical output. Defaults true. */\n deterministic?: boolean;\n /** Default build timestamp for generated metadata. */\n generatedAt?: string | Date;\n /**\n * Directory that relative asset paths (image `path` props) resolve against.\n * Per-call `options.baseDir` overrides it; defaults to `process.cwd()`\n * when neither is set (#142).\n */\n baseDir?: string;\n}\n\n/**\n * Internal state held by each builder instance\n */\ninterface BuilderState {\n components: readonly CustomComponent<any, any, any>[];\n componentNames: Set<string>;\n theme?: ThemeConfig;\n customThemes?: Record<string, ThemeConfig>;\n debug: boolean;\n enableCache: boolean;\n services?: ServicesConfig;\n fonts?: FontRuntimeOpts;\n validation?: GenerationValidationOptions;\n deterministic: boolean;\n generatedAt?: string | Date;\n baseDir?: string;\n}\n\n/**\n * Create the builder implementation with the given state\n */\nfunction createBuilderImpl<\n TComponents extends readonly CustomComponent<any, any, any>[],\n>(state: BuilderState): DocumentGeneratorBuilder<TComponents> {\n // Create component map for quick lookup\n const componentMap = new Map(state.components.map((c) => [c.name, c]));\n\n /**\n * Resolve theme for a document: customThemes → doc-named built-in →\n * constructor theme → built-in resolver fallback.\n *\n * A document explicitly naming a known built-in gets it; the constructor\n * `theme` object fills in when the document names nothing or names\n * something nothing recognizes (#141). The `authored` guard on the\n * built-in step matters twice over: the unauthored 'minimal' fallback\n * must not shadow the constructor theme, and an authored UNKNOWN name\n * must still reach the constructor theme rather than silently rendering\n * the resolver's minimal fallback.\n */\n function resolveDocumentTheme(\n themeName: string,\n warnings: GenerationWarning[] | undefined,\n authored: boolean\n ): ThemeConfig {\n if (state.customThemes) {\n if (state.customThemes[themeName]) {\n return state.customThemes[themeName];\n }\n const key = Object.keys(state.customThemes).find(\n (k) => k.toLowerCase() === themeName.toLowerCase()\n );\n if (key) {\n return state.customThemes[key];\n }\n }\n if (authored && hasTheme(themeName)) {\n return resolveBuiltInTheme(themeName, {\n customThemes: state.customThemes,\n warnings,\n });\n }\n if (state.theme) {\n return state.theme;\n }\n return resolveBuiltInTheme(themeName, {\n customThemes: state.customThemes,\n warnings,\n });\n }\n\n /**\n * Process custom components in the document.\n *\n * Returns two parallel trees built in a single pass:\n * - `standard`: fully expanded — every custom component resolved to standard primitives.\n * - `preserved`: partially expanded — nodes whose name is in `preserveSet` are kept\n * verbatim (children NOT recursed); everything else is expanded the same as `standard`.\n *\n * `render()` always runs, even for preserved components, because the docx pipeline\n * builds from `standard` and we still need their warnings/font registrations.\n */\n async function processDocumentComponents(\n components: ComponentDefinition[],\n preserveSet: ReadonlySet<string> | undefined,\n warningsCollector: GenerationWarning[],\n resolvedTheme: ThemeConfig,\n validateEmitted:\n | ((emitted: ComponentDefinition[], componentLabel: string) => void)\n | undefined,\n depth = 0\n ): Promise<{\n standard: ComponentDefinition[];\n preserved: ComponentDefinition[];\n }> {\n if (depth > 20) {\n throw new Error(\n 'Maximum component nesting depth exceeded (20). Check for circular component references.'\n );\n }\n const standardOut: ComponentDefinition[] = [];\n const preservedOut: ComponentDefinition[] = [];\n\n for (const componentData of components) {\n // Safe type narrowing for custom component detection\n const componentName = (componentData as { name?: string })?.name;\n\n if (!componentName) {\n standardOut.push(componentData);\n preservedOut.push(componentData);\n continue;\n }\n\n const customComponent = componentMap.get(componentName);\n\n if (customComponent) {\n // This is a custom component - validate and process it\n try {\n const componentWithName = componentData as {\n name: string;\n version?: string;\n props?: unknown;\n children?: unknown;\n };\n\n if (!componentWithName.props) {\n throw new Error(\n `Custom component '${componentName}' must have a 'props' property. Use format: { name: '${componentName}', props: {...} }`\n );\n }\n\n // Resolve the correct version entry\n const versionEntry = resolveComponentVersion(\n customComponent.name,\n customComponent.versions,\n componentWithName.version\n );\n\n // Validate and clean the props against the resolved version's schema\n const cleanedProps = cleanComponentProps(\n versionEntry,\n componentWithName.props\n );\n\n // Process nested children if this is a container.\n // For the standard tree we need the fully-expanded children to feed render().\n let nestedChildren: unknown[] | undefined;\n if (\n componentWithName.children &&\n Array.isArray(componentWithName.children)\n ) {\n const nested = await processDocumentComponents(\n componentWithName.children as ComponentDefinition[],\n preserveSet,\n warningsCollector,\n resolvedTheme,\n validateEmitted,\n depth + 1\n );\n nestedChildren = nested.standard;\n }\n\n // Create addWarning callback for this component\n const versionLabel = componentWithName.version\n ? `${customComponent.name}@${componentWithName.version}`\n : customComponent.name;\n\n const addWarning = (\n message: string,\n context?: Record<string, unknown>\n ) => {\n warningsCollector.push({\n component: versionLabel,\n message,\n severity: 'warning',\n context,\n });\n };\n\n // Call the render function with context object\n const result = await versionEntry.render({\n props: cleanedProps,\n theme: resolvedTheme,\n addWarning,\n children: nestedChildren,\n });\n\n // Ensure result is an array\n const resultComponents = (\n Array.isArray(result) ? result : [result]\n ) as ComponentDefinition[];\n\n // Validate the standard tree this render() emitted, applying the same\n // schema gate authored standard components pass through up front. The\n // pre-expansion pass never saw these nodes, so without this an invalid\n // prop produced by a plugin would ride through into standardDefinition\n // and only surface when that output is validated separately.\n if (validateEmitted) {\n validateEmitted(resultComponents, versionLabel);\n }\n\n // Recursively process the result in case it contains more custom components\n const processedResult = await processDocumentComponents(\n resultComponents,\n preserveSet,\n warningsCollector,\n resolvedTheme,\n validateEmitted,\n depth + 1\n );\n standardOut.push(...processedResult.standard);\n\n if (preserveSet && preserveSet.has(componentName)) {\n // Keep this custom node verbatim in the preserved tree.\n // Per spec: do NOT recurse into authored children — leave the\n // entire subtree as the user wrote it.\n preservedOut.push(componentData);\n } else {\n // Non-preserved custom: emit the recursed expansion (which itself\n // honors preserveSet for any nested customs).\n preservedOut.push(...processedResult.preserved);\n }\n\n if (state.debug) {\n console.log(\n `Processed custom component '${versionLabel}':`,\n processedResult.standard\n );\n }\n } catch (error) {\n if (error instanceof ComponentValidationError) {\n throw error;\n }\n throw new Error(\n `Error processing custom component '${customComponent.name}': ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n } else {\n // This is a standard component or nested container - process recursively\n if (\n 'children' in componentData &&\n Array.isArray(componentData.children)\n ) {\n const processedNested = await processDocumentComponents(\n componentData.children,\n preserveSet,\n warningsCollector,\n resolvedTheme,\n validateEmitted,\n depth + 1\n );\n standardOut.push({\n ...componentData,\n children: processedNested.standard,\n });\n preservedOut.push({\n ...componentData,\n children: processedNested.preserved,\n });\n } else {\n standardOut.push(componentData);\n preservedOut.push(componentData);\n }\n }\n }\n\n return { standard: standardOut, preserved: preservedOut };\n }\n\n /**\n * Add a custom component to the generator\n */\n function addComponent<TNewComponent extends CustomComponent<any, any, any>>(\n component: TNewComponent\n ): DocumentGeneratorBuilder<readonly [...TComponents, TNewComponent]> {\n if (!component.name) {\n throw new Error('Component name is required');\n }\n\n if (state.componentNames.has(component.name)) {\n throw new DuplicateComponentError(component.name);\n }\n\n // Create NEW immutable state\n const newComponentNames = new Set(state.componentNames);\n newComponentNames.add(component.name);\n\n const newState: BuilderState = {\n components: [...state.components, component],\n componentNames: newComponentNames,\n theme: state.theme,\n customThemes: state.customThemes,\n debug: state.debug,\n enableCache: state.enableCache,\n services: state.services,\n fonts: state.fonts,\n validation: state.validation,\n deterministic: state.deterministic,\n generatedAt: state.generatedAt,\n baseDir: state.baseDir,\n };\n\n // Return NEW builder with expanded type\n return createBuilderImpl<readonly [...TComponents, TNewComponent]>(\n newState\n );\n }\n\n /**\n * Resolve and validate the preserve set for a per-call options object.\n * Returns `undefined` when the caller did not opt in.\n * Throws `UnknownPreservedComponentError` when any listed name is not registered.\n */\n function resolvePreserveSet(\n options?: GenerateOptions\n ): ReadonlySet<string> | undefined {\n const list = options?.preserveCustomComponents;\n if (!list || list.length === 0) {\n return undefined;\n }\n const registered = new Set(state.componentNames);\n const unknown = list.filter((n) => !registered.has(n));\n if (unknown.length > 0) {\n throw new UnknownPreservedComponentError(\n unknown,\n Array.from(state.componentNames)\n );\n }\n return new Set(list);\n }\n\n /**\n * Generate a document\n */\n async function generate(\n document: ExtendedReportComponent<TComponents>,\n options?: GenerateOptions\n ): Promise<GenerationResult<TComponents>> {\n try {\n const preserveSet = resolvePreserveSet(options);\n\n // Cast to ReportComponentDefinition for internal processing. A root\n // written without a `props` key validates clean, so default it to `{}`\n // — otherwise every downstream `props.*` read throws. Only `undefined`\n // is defaulted, so a malformed `props: null` still reaches the\n // validator. Matches core/generator.ts.\n const rootIn = document as unknown as ReportComponentDefinition;\n const internalDocument: ReportComponentDefinition =\n rootIn.props === undefined ? { ...rootIn, props: {} } : rootIn;\n\n // Validate the document first (plugin-aware), unless disabled. Throwing\n // here stops a malformed document from silently building into a corrupt\n // or incomplete DOCX.\n const vOpts: GenerationValidationOptions = {\n ...state.validation,\n ...options?.validation,\n };\n if (vOpts.enabled !== false) {\n const result = validateDocument(\n internalDocument,\n state.components as unknown as CustomComponent<TSchema>[],\n { allowUnknownFields: vOpts.allowUnknownFields }\n );\n if (!result.valid) {\n throw new ComponentValidationError(\n (result.errors ?? []).map((e) => ({\n path: e.path ?? '',\n message: e.message,\n })),\n internalDocument\n );\n }\n }\n\n // Re-apply the same gate to the tree each custom component's render()\n // emits. The pre-expansion pass above only saw authored nodes, so a\n // standard component produced by a plugin would otherwise reach\n // standardDefinition unchecked. We validate the emitted nodes in their\n // pre-normalization form — exactly how authored nodes are validated —\n // by reusing the already-validated document props as a wrapper, so the\n // only new errors come from the emitted children. Undefined when\n // validation is disabled, which short-circuits the boundary check.\n const validateEmitted =\n vOpts.enabled === false\n ? undefined\n : (emitted: ComponentDefinition[], componentLabel: string) => {\n const result = validateDocument(\n { ...internalDocument, children: emitted },\n state.components as unknown as CustomComponent<TSchema>[],\n { allowUnknownFields: vOpts.allowUnknownFields }\n );\n if (!result.valid) {\n throw new ComponentValidationError(\n (result.errors ?? []).map((e) => ({\n path: e.path ?? '',\n message: `custom component '${componentLabel}' emitted invalid output — ${e.message}`,\n })),\n emitted\n );\n }\n };\n\n // Initialize warnings collector\n const warnings: GenerationWarning[] = [];\n\n // Props defaulting, theme resolution (customThemes → doc-named\n // built-in → constructor theme → built-in fallback, see\n // resolveDocumentTheme), in-document overrides, export-mode pre-pass and cache-key\n // scoping — shared with the core pipeline so the two cannot drift (see\n // core/generationContext.ts). The pre-pass runs BEFORE custom-component\n // expansion so components reading `theme.fonts.*` during render see the\n // substituted names, not the original non-safe ones.\n const {\n document: modedRoot,\n theme: modedTheme,\n themeName,\n } = resolveThemeContext(internalDocument, {\n customThemes: state.customThemes,\n fonts: state.fonts,\n warnings,\n resolveNamedTheme: resolveDocumentTheme,\n });\n\n // Process custom components to convert them to standard components.\n // Builds standard (fully expanded) and preserved (partial) trees in one pass.\n const processed = await processDocumentComponents(\n modedRoot.children || [],\n preserveSet,\n warnings,\n modedTheme,\n validateEmitted\n );\n\n // Create a new document definition with processed components\n const processedDocument: ReportComponentDefinition = {\n ...modedRoot,\n children: processed.standard,\n };\n\n // Normalize components (handle shorthand notations and nested structures)\n // We bypass JSON validation since we've already validated with custom schemas\n const [modedDoc] = normalizeDocument(processedDocument);\n\n // Resolve fonts (reads document + resolved theme). The helper fires\n // `fonts.onResolved` internally when a listener is registered\n // (LibreOffice preview stager). DOCX output itself never embeds\n // bytes; recipients rely on system-installed fonts.\n await resolveDocumentFonts(modedDoc, modedTheme, state.fonts, warnings);\n\n // Use the document generation pipeline directly\n const packageOptions = {\n deterministic: options?.deterministic ?? state.deterministic,\n generatedAt: options?.generatedAt ?? state.generatedAt,\n };\n const structure = await processDocument(\n modedDoc,\n modedTheme,\n themeName,\n resolveGenerationDate(packageOptions)\n );\n const layout = applyLayout(structure.sections, modedTheme, themeName);\n const generatedDocument = await renderDocument(structure, layout, {\n services: state.services,\n bypassCache: !state.enableCache,\n baseDir: options?.baseDir ?? state.baseDir,\n });\n\n // Build preservedDefinition iff the caller opted in. Reuses the same\n // doc shell as standardDefinition but with partially-expanded children.\n // Not normalized — preserved subtrees are meant to be \"as authored\".\n const preservedDefinition = preserveSet\n ? ({\n ...modedRoot,\n children: processed.preserved,\n } as unknown as ExtendedReportComponent<TComponents>)\n : undefined;\n\n return {\n document: generatedDocument,\n warnings: warnings.length > 0 ? warnings : null,\n standardDefinition: modedDoc,\n preservedDefinition,\n };\n } catch (error) {\n if (state.debug) {\n console.error('Document generation error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Generate a document and return as buffer\n */\n async function generateBuffer(\n document: ExtendedReportComponent<TComponents>,\n options?: GenerateOptions\n ): Promise<BufferGenerationResult<TComponents>> {\n const {\n document: doc,\n warnings,\n standardDefinition,\n preservedDefinition,\n } = await generate(document, options);\n const buffer = await packageDocument(doc, {\n deterministic: options?.deterministic ?? state.deterministic,\n generatedAt: options?.generatedAt ?? state.generatedAt,\n });\n return { buffer, warnings, standardDefinition, preservedDefinition };\n }\n\n /**\n * Generate a document and save to file\n */\n async function generateFile(\n document: ExtendedReportComponent<TComponents>,\n outputPath: string,\n options?: GenerateFileOptions\n ): Promise<FileGenerationResult<TComponents>> {\n const { buffer, warnings, standardDefinition, preservedDefinition } =\n await generateBuffer(document, options);\n const fs = await import('fs/promises');\n await fs.writeFile(outputPath, new Uint8Array(buffer));\n\n let preservedOutputPath: string | undefined;\n if (preservedDefinition !== undefined) {\n const path = await import('path');\n preservedOutputPath =\n options?.preservedOutputPath ??\n (() => {\n const ext = path.extname(outputPath);\n const base = ext ? outputPath.slice(0, -ext.length) : outputPath;\n return `${base}-preserved.json`;\n })();\n await fs.writeFile(\n preservedOutputPath,\n JSON.stringify(preservedDefinition, null, 2),\n 'utf8'\n );\n }\n\n return {\n warnings,\n standardDefinition,\n preservedDefinition,\n preservedOutputPath,\n };\n }\n\n /**\n * Get registered component names\n */\n function getComponentNames(): string[] {\n return Array.from(state.componentNames);\n }\n\n /**\n * Validate a document without generating it\n */\n function validate(\n document: ExtendedReportComponent<TComponents>\n ): ValidationResult {\n try {\n // Cast to ReportComponentDefinition for internal validation\n const internalDocument = document as unknown as ReportComponentDefinition;\n const result = validateDocument(\n internalDocument,\n state.components as unknown as CustomComponent<TSchema>[]\n );\n if (result.valid) {\n return { valid: true };\n }\n return {\n valid: false,\n errors: (result.errors ?? []).map((e) => ({\n path: e.path ?? '',\n message: e.message,\n })),\n };\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: 'document',\n message: error instanceof Error ? error.message : String(error),\n },\n ],\n };\n }\n }\n\n /**\n * @deprecated Read `standardDefinition` off `generate(...)` instead. This wrapper\n * runs the full generation pipeline (including `render()` for every custom)\n * just to surface the JSON tree, so calling it alongside `generate*` doubles\n * the work. Kept for backwards compatibility; will be removed in a future major.\n */\n async function getStandardComponentsDefinition(\n document: ExtendedReportComponent<TComponents>\n ): Promise<ReportComponentDefinition> {\n const { standardDefinition } = await generate(document);\n return standardDefinition;\n }\n\n /**\n * Generate the extended JSON schema for document validation\n */\n function generateSchema(includeStandardComponents = true): TSchema {\n return generatePluginDocumentSchema(\n state.components as unknown as CustomComponent<TSchema>[],\n includeStandardComponents\n );\n }\n\n /**\n * Export the extended JSON schema to a file\n */\n async function exportSchemaToFile(\n outputPath: string,\n options?: {\n includeStandardComponents?: boolean;\n prettyPrint?: boolean;\n }\n ): Promise<void> {\n await exportPluginSchema(\n state.components as unknown as CustomComponent<TSchema>[],\n outputPath,\n options\n );\n }\n\n // Return frozen builder object\n return Object.freeze({\n addComponent,\n generate,\n generateBuffer,\n generateFile,\n getComponentNames,\n validate,\n generateSchema,\n exportSchema: exportSchemaToFile,\n getStandardComponentsDefinition,\n });\n}\n\n/**\n * Create a document generator with chainable component registration.\n */\nexport function createDocumentGenerator(\n options: DocumentGeneratorOptions\n): DocumentGeneratorBuilder<readonly []> {\n const initialState: BuilderState = {\n components: [],\n componentNames: new Set(),\n theme: options.theme,\n customThemes: options.customThemes,\n debug: options.debug ?? false,\n enableCache: options.enableCache ?? false,\n services: options.services,\n fonts: options.fonts,\n validation: options.validation,\n deterministic: options.deterministic ?? true,\n generatedAt: options.generatedAt,\n baseDir: options.baseDir,\n };\n\n return createBuilderImpl<readonly []>(initialState);\n}\n","export { resolveComponentVersion } from '@json-to-office/shared/plugin';\n","import type { TSchema, Static } from '@sinclair/typebox';\nimport type { CustomComponent } from './createComponent';\nimport type { ReportComponentDefinition } from '../types';\nimport { resolveComponentVersion } from './version-resolver';\nimport {\n validateCustomComponentProps,\n ComponentValidationError,\n type ComponentValidationResult,\n} from '@json-to-office/shared/plugin';\nimport {\n validateDocument as validateDocumentUnified,\n type ValidationError,\n} from '@json-to-office/shared-docx/validation/unified';\nimport type { ValidationResult } from '@json-to-office/shared';\n\n// Re-export errors from shared\nexport {\n DuplicateComponentError,\n ComponentValidationError,\n UnknownPreservedComponentError,\n} from '@json-to-office/shared/plugin';\n\n/**\n * Validate a component props against a schema.\n * Accepts a narrower interface — only needs { propsSchema }.\n */\nexport function validateComponentProps<TPropsSchema extends TSchema>(\n schema: { propsSchema: TPropsSchema },\n props: unknown,\n componentName?: string,\n opts?: { clean?: boolean; applyDefaults?: boolean }\n): ComponentValidationResult<TPropsSchema> {\n // `clean` defaults to true so the render path (getValidatedProps) keeps\n // normalizing props (strip unknown + apply defaults). The validation path\n // passes `clean: false` to reject unknown keys instead of silently dropping\n // them — strict unless the caller opts into allowUnknownFields.\n return validateCustomComponentProps<TPropsSchema>(schema.propsSchema, props, {\n clean: opts?.clean ?? true,\n applyDefaults: opts?.applyDefaults ?? true,\n componentName,\n });\n}\n\n/**\n * Validate document and all custom components (version-aware).\n *\n * Standard components (paragraph, section, …) are validated against their\n * schemas via the unified validator, which is told the registered custom names\n * so it neither rejects them as unknown nor checks them against a standard\n * schema. Custom component props are then validated version-aware below. Errors\n * from both passes are merged so a single call reports the whole document.\n */\nexport function validateDocument(\n document: ReportComponentDefinition,\n customComponents: CustomComponent<any, any, any>[],\n options?: { allowUnknownFields?: boolean }\n): ValidationResult & { success: boolean } {\n const knownCustomNames = new Set(customComponents.map((c) => c.name));\n\n // Validate the standard-component structure (custom components deferred).\n const documentResult = validateDocumentUnified(document, {\n knownCustomNames,\n allowUnknownFields: options?.allowUnknownFields,\n });\n\n // Collect standard-structure errors, then append custom-component errors.\n const errors: ValidationError[] = [...(documentResult.errors || [])];\n\n function validateComponents(components: any[], pathPrefix = 'children') {\n components.forEach((componentData, index) => {\n const customComponent = customComponents.find(\n (cc) => cc.name === componentData.name\n );\n if (!customComponent) {\n return;\n }\n\n const versionEntry = resolveComponentVersion(\n customComponent.name,\n customComponent.versions,\n componentData.version\n );\n\n const validation = validateComponentProps(\n versionEntry,\n componentData.props,\n customComponent.name,\n // Reject unknown custom props unless the caller allows them.\n { clean: options?.allowUnknownFields === true }\n );\n\n if (!validation.valid && validation.errors) {\n const indexedErrors = validation.errors.map(\n (error: ValidationError) => ({\n ...error,\n path: `${pathPrefix}[${index}].${error.path}`,\n })\n );\n errors.push(...indexedErrors);\n }\n\n if (componentData.children && Array.isArray(componentData.children)) {\n validateComponents(\n componentData.children,\n `${pathPrefix}[${index}].children`\n );\n }\n });\n }\n\n if (document.children) {\n validateComponents(document.children);\n }\n\n return errors.length > 0\n ? { success: false, errors, valid: false }\n : { success: true, errors: [], valid: true };\n}\n\n/**\n * Validates component props and returns the typed props or throws.\n */\nexport function getValidatedProps<TPropsSchema extends TSchema>(\n schema: { propsSchema: TPropsSchema },\n props: unknown\n): Static<TPropsSchema> {\n const validation = validateComponentProps(schema, props);\n\n if (!validation.valid) {\n throw new ComponentValidationError(validation.errors || [], props);\n }\n\n return validation.data!;\n}\n\n// Re-export types\nexport type { ValidationError } from '@json-to-office/shared-docx/validation/unified';\nexport type { ComponentValidationResult } from '@json-to-office/shared/plugin';\n\nexport const cleanComponentProps = getValidatedProps;\n","import { Type, TSchema, TObject } from '@sinclair/typebox';\nimport { latestVersion } from '@json-to-office/shared-docx';\nimport type { CustomComponent } from './createComponent';\nimport {\n ReportPropsSchema,\n SectionPropsSchema,\n HeadingPropsSchema,\n ParagraphPropsSchema,\n ListPropsSchema,\n ImagePropsSchema,\n TablePropsSchema,\n} from '@json-to-office/shared-docx';\nimport { generateUnifiedDocumentSchema } from '@json-to-office/shared-docx/schemas/generator';\n\n// Schema cache to avoid regenerating identical schemas\nconst schemaCache = new Map<string, TSchema>();\n\n/**\n * Generate a JSON schema for plugin-enhanced documents at RUNTIME.\n *\n * Iterates each component's versions map to produce per-version\n * CustomComponentInfo entries for the unified schema generator.\n */\nexport function generatePluginDocumentSchema(\n customComponents: CustomComponent<any, any, any>[],\n includeStandardComponents = true\n): TSchema {\n // Produce per-version CustomComponentInfo entries for version-discriminated validation\n const customComponentInfos = customComponents.map((component) => {\n const versionKeys = Object.keys(component.versions);\n\n // Build per-version props entries\n const versionedProps = versionKeys.map((v) => ({\n version: v,\n propsSchema: component.versions[v].propsSchema,\n hasChildren: component.versions[v].hasChildren === true,\n description: component.versions[v].description,\n }));\n\n // propsSchema is used as fallback label — use latest version's props\n const latestKey = versionKeys.reduce((a, b) => (a > b ? a : b));\n\n return {\n name: component.name,\n propsSchema: component.versions[latestKey].propsSchema,\n hasChildren: versionKeys.some(\n (v) => component.versions[v].hasChildren === true\n ),\n versionedProps,\n };\n });\n\n return generateUnifiedDocumentSchema({\n includeStandardComponents: includeStandardComponents,\n includeTheme: true,\n customComponents: customComponentInfos,\n title: 'Plugin Document Definition',\n description: 'Document definition with custom plugin components',\n });\n}\n\n/**\n * Create a union type from an array of schemas\n */\nexport function createUnionSchema(schemas: TSchema[]): TSchema {\n if (schemas.length === 0) {\n return Type.Any();\n }\n if (schemas.length === 1) {\n return schemas[0];\n }\n return Type.Union(schemas as [TSchema, TSchema, ...TSchema[]]);\n}\n\n/**\n * Export a plugin-enhanced JSON schema to a file at RUNTIME\n */\nexport async function exportPluginSchema(\n customComponents: CustomComponent<any, any, any>[],\n outputPath: string,\n options: {\n includeStandardComponents?: boolean;\n prettyPrint?: boolean;\n } = {}\n): Promise<void> {\n const { includeStandardComponents = true, prettyPrint = true } = options;\n\n const { convertToJsonSchema, exportSchemaToFile } = await import(\n '@json-to-office/shared-docx/schemas/export'\n );\n\n const schema = generatePluginDocumentSchema(\n customComponents,\n includeStandardComponents\n );\n\n const jsonSchema = convertToJsonSchema(schema, {\n $schema: 'http://json-schema.org/draft-07/schema#',\n });\n\n await exportSchemaToFile(jsonSchema, outputPath, { prettyPrint });\n}\n\n/**\n * Generate schemas for individual custom components (version-aware).\n * Produces per-version schemas keyed as `name` or `name@version`.\n */\nexport function generateComponentSchemas(\n customComponents: CustomComponent<any, any, any>[]\n): Record<string, TSchema> {\n const schemas: Record<string, TSchema> = {};\n\n for (const component of customComponents) {\n const versionKeys = Object.keys(component.versions);\n const latest = latestVersion(versionKeys);\n\n for (const v of versionKeys) {\n const entry = component.versions[v];\n const cacheKey = `component_${component.name}@${v}`;\n\n if (schemaCache.has(cacheKey)) {\n schemas[`${component.name}@${v}`] = schemaCache.get(cacheKey)!;\n } else {\n const schemaObj = entry.propsSchema as TObject;\n const properties = schemaObj.properties || {};\n\n const componentSchemaProps: Record<string, TSchema> = {\n name: Type.Literal(component.name),\n version: Type.Optional(Type.Literal(v)),\n id: Type.Optional(Type.String()),\n ...properties,\n };\n\n if (entry.hasChildren) {\n componentSchemaProps.children = Type.Optional(Type.Array(Type.Any()));\n }\n\n const componentSchema = Type.Object(componentSchemaProps);\n schemaCache.set(cacheKey, componentSchema);\n schemas[`${component.name}@${v}`] = componentSchema;\n }\n }\n\n // Also add a \"default\" entry keyed by name (uses latest)\n const latestEntry = component.versions[latest];\n const defaultCacheKey = `component_${component.name}_default`;\n\n if (schemaCache.has(defaultCacheKey)) {\n schemas[component.name] = schemaCache.get(defaultCacheKey)!;\n } else {\n const schemaObj = latestEntry.propsSchema as TObject;\n const properties = schemaObj.properties || {};\n\n const componentSchemaProps: Record<string, TSchema> = {\n name: Type.Literal(component.name),\n id: Type.Optional(Type.String()),\n ...properties,\n };\n\n if (latestEntry.hasChildren) {\n componentSchemaProps.children = Type.Optional(Type.Array(Type.Any()));\n }\n\n const componentSchema = Type.Object(componentSchemaProps);\n schemaCache.set(defaultCacheKey, componentSchema);\n schemas[component.name] = componentSchema;\n }\n }\n\n return schemas;\n}\n\n/**\n * Merge custom component schemas with standard schemas\n */\nexport function mergeSchemas(\n customComponents: CustomComponent<any, any, any>[],\n standardSchemas?: Record<string, TSchema>\n): Record<string, TSchema> {\n const customSchemas = generateComponentSchemas(customComponents);\n\n if (standardSchemas) {\n return {\n ...standardSchemas,\n ...customSchemas,\n };\n }\n\n const defaultStandardSchemas: Record<string, TSchema> = {\n docx: Type.Object({\n name: Type.Literal('docx'),\n id: Type.Optional(Type.String()),\n props: ReportPropsSchema,\n children: Type.Optional(Type.Array(Type.Any())),\n }),\n section: Type.Object({\n name: Type.Literal('section'),\n id: Type.Optional(Type.String()),\n props: SectionPropsSchema,\n children: Type.Optional(Type.Array(Type.Any())),\n }),\n heading: Type.Object({\n name: Type.Literal('heading'),\n id: Type.Optional(Type.String()),\n props: HeadingPropsSchema,\n }),\n text: Type.Object({\n name: Type.Literal('text'),\n id: Type.Optional(Type.String()),\n props: ParagraphPropsSchema,\n }),\n list: Type.Object({\n name: Type.Literal('list'),\n id: Type.Optional(Type.String()),\n props: ListPropsSchema,\n }),\n image: Type.Object({\n name: Type.Literal('image'),\n id: Type.Optional(Type.String()),\n props: ImagePropsSchema,\n }),\n table: Type.Object({\n name: Type.Literal('table'),\n id: Type.Optional(Type.String()),\n props: TablePropsSchema,\n }),\n };\n\n return {\n ...defaultStandardSchemas,\n ...customSchemas,\n };\n}\n"],"mappings":"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","names":["themes","path","fs","path","isValidThemeConfig","resolve","mergeWithDefaults","mergeWithDefaults","Paragraph","TextRun","AlignmentType","BookmarkStart","BookmarkEnd","path","createHash","TextRun","TextRun","TextRun","createTextRunsWithNewlines","TextRun","AsyncLocalStorage","TextRun","createHash","TextRun","AlignmentType","BorderStyle","PageNumber","AsyncLocalStorage","TextRun","path","getAvailableWidthTwips","getPageWidthTwips","getAvailableHeightTwips","getPageHeightTwips","mapFloatingOptions","AlignmentType","BorderStyle","TextRun","relativeLengthToTwips","AlignmentType","AsyncLocalStorage","format","getAlignment","format","getAlignment","AsyncLocalStorage","text","format","Table","TableRow","TableCell","WidthType","TableLayoutType","BorderStyle","convertBorders","Paragraph","Paragraph","convertBorders","cellChildren","childContext","styleCfg","cellOpts","row","TableRow","TableCell","table","Table","TableLayoutType","WidthType","config","Paragraph","Paragraph","Paragraph","Table","TableRow","TableCell","WidthType","BorderStyle","VerticalAlign","TableLayoutType","Paragraph","TableCell","WidthType","VerticalAlign","BorderStyle","TableRow","Table","TableLayoutType","Paragraph","AlignmentType","TextRun","getAlignment","AlignmentType","Paragraph","TextRun","BookmarkStart","BookmarkEnd","AdmZip","AdmZip","coreProperties","fs","resolve","isAbsolute","isAbsolute","resolve","fs","resolve","clampVisualDpi","DEFAULT_VISUAL_DPI","resolve","clampVisualDpi","DEFAULT_VISUAL_DPI","fs","path","fileURLToPath","path","fs","ComponentValidationError","UnknownPreservedComponentError","Type","Type","ComponentValidationError","UnknownPreservedComponentError","fs","path"]}