@pixldocs/canvas-renderer 0.5.186 → 0.5.188

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.
@@ -1 +1 @@
1
- {"version":3,"file":"vectorPdfExport-v3mr9nks.js","sources":["../../../src/lib/vectorPdfExport.ts"],"sourcesContent":["import { jsPDF, ShadingPattern } from 'jspdf';\nimport { svg2pdf } from 'svg2pdf.js';\nimport * as fabric from 'fabric';\nimport { CanvasElement, flattenChildren, CanvasNode, GroupNode, isGroup, isElement, findNodeById } from '@/types/editor';\nimport { getAbsoluteBounds } from '@/lib/layoutEngine';\nimport { embedFont, embedFontWithGoogleFallback, FONT_FALLBACK_SYMBOLS, FONT_FALLBACK_DEVANAGARI, FONT_FALLBACK_MATH, getEmbeddedJsPDFFontName, isFontAvailable, isFamilyEmbedded, resolveFontWeight, hasItalicVariant, resolveBestRegisteredVariant, doesVariantSupportChar, resetPdfFontRegistry, getEmbeddedVariantsList } from './pdfFonts';\nimport { getCanvasForPage } from '@/store/fabricCanvasRegistry';\nimport { getProxiedImageUrl } from './canvasImageLoader';\nimport { API_URL, getImageProxyFetchOptions } from '@/lib/api';\nimport { getRoundedRectRadii, getTrianglePoints, normalizeShapeType, buildRoundedTrianglePath, TRIANGLE_STROKE_MITER_LIMIT } from './shapeGeometry';\nimport { renderSmartElementToSvg } from '@/lib/smartElements/registry';\nimport { hasEdgeFade as elementHasEdgeFade, bakeEdgeFade, EdgeFadeProps } from './imageEdgeFade';\nimport { parseTextMarkdown } from '@/lib/textMarkdown';\nimport { captureFabricCanvasSvgForPdf } from './canvasSvgCapture';\n\n/**\n * Shared JIT font-variant embedder. Scans the live Fabric SVG for every\n * (family, weight, italic) tuple actually used by `<text>`/`<tspan>` (including\n * rich-text spans introduced by inline markdown bold/italic) and registers\n * any missing variant into the supplied jsPDF instance via\n * `embedFontWithGoogleFallback` (local TTF → Fontshare → Google Fonts).\n *\n * MUST run BEFORE `prepareLiveCanvasSvgForPdf` (which rewrites font-family\n * to the embedded jsPDF font names). If a variant isn't registered when\n * the rewriter runs, jsPDF falls back to a different glyph set → different\n * advance widths → horizontal text shift in the exported PDF.\n *\n * Used by BOTH the host UsePackage flow and the unified `exportMultiPagePdf`\n * live-canvas branch (which is the server EC2 path) so both PDFs reach\n * identical glyph-width parity.\n */\nexport async function embedFontsForSvg(pdf: jsPDF, svgStr: string): Promise<void> {\n const {\n embedFontWithGoogleFallback: _embedFontWithGoogleFallback,\n isVariantEmbedded,\n resolveFontWeight: _resolveFontWeight,\n FONT_FALLBACK_SYMBOLS,\n FONT_FALLBACK_DEVANAGARI,\n FONT_FALLBACK_MATH,\n } = await import('@/lib/pdfFonts');\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(svgStr, 'image/svg+xml');\n const textEls = Array.from(doc.querySelectorAll('text, tspan, textPath'));\n\n const readStyleToken = (style: string, prop: string): string | null => {\n const m = style.match(new RegExp(`${prop}\\\\s*:\\\\s*([^;]+)`, 'i'));\n return m?.[1]?.trim() || null;\n };\n const resolveInherited = (el: Element, attr: string, styleProp = attr): string | null => {\n let cur: Element | null = el;\n while (cur) {\n const a = cur.getAttribute(attr)?.trim();\n if (a) return a;\n const s = readStyleToken(cur.getAttribute('style') || '', styleProp);\n if (s) return s;\n cur = cur.parentElement;\n }\n return null;\n };\n const parseWeight = (raw: string): number => {\n const n = Number.parseInt(raw, 10);\n if (Number.isFinite(n)) return n;\n const s = raw.toLowerCase();\n if (/bold/.test(s)) return 700;\n if (/semi|demi/.test(s)) return 600;\n if (/medium/.test(s)) return 500;\n if (/light|thin/.test(s)) return 300;\n return 400;\n };\n\n const needed = new Map<string, { family: string; weight: number; italic: boolean }>();\n for (const el of textEls) {\n const rawFf = resolveInherited(el, 'font-family');\n if (!rawFf) continue;\n const family = rawFf.split(',')[0]?.replace(/['\"]/g, '').trim();\n if (!family) continue;\n const weight = _resolveFontWeight(parseWeight(resolveInherited(el, 'font-weight') || '400'));\n const italic = /italic|oblique/i.test(resolveInherited(el, 'font-style') || 'normal');\n const key = `${family}\\u001F${weight}\\u001F${italic ? 'i' : 'n'}`;\n if (!needed.has(key)) needed.set(key, { family, weight, italic });\n }\n\n let embedded = 0;\n for (const { family, weight, italic } of needed.values()) {\n if (isVariantEmbedded(family, weight, italic)) continue;\n await _embedFontWithGoogleFallback(pdf, family, weight, italic);\n if (isVariantEmbedded(family, weight, italic)) embedded++;\n }\n // Pre-embed per-character fallback fonts so the SVG rewriter's symbol/math/\n // devanagari runs resolve to real glyphs instead of `.notdef`.\n const fallbackFamilies: Array<{ family: string; weight: number }> = [\n { family: FONT_FALLBACK_SYMBOLS, weight: 400 },\n { family: FONT_FALLBACK_MATH, weight: 400 },\n ];\n for (const w of [300, 400, 500, 600, 700]) {\n fallbackFamilies.push({ family: FONT_FALLBACK_DEVANAGARI, weight: w });\n }\n for (const { family, weight } of fallbackFamilies) {\n if (isVariantEmbedded(family, weight, false)) continue;\n await _embedFontWithGoogleFallback(pdf, family, weight, false);\n if (isVariantEmbedded(family, weight, false)) embedded++;\n }\n // Italic + heavy-weight fallback so the rewriter can downgrade weight while\n // keeping italic glyphs (synthetic bold via stroke).\n for (const { family, weight, italic } of needed.values()) {\n if (!italic) continue;\n if (!isVariantEmbedded(family, weight, false)) {\n await _embedFontWithGoogleFallback(pdf, family, weight, false);\n if (isVariantEmbedded(family, weight, false)) embedded++;\n }\n if (!isVariantEmbedded(family, 400, false)) {\n await _embedFontWithGoogleFallback(pdf, family, 400, false);\n if (isVariantEmbedded(family, 400, false)) embedded++;\n }\n if (weight <= 400) continue;\n if (isVariantEmbedded(family, 400, true)) continue;\n await _embedFontWithGoogleFallback(pdf, family, 400, true);\n if (isVariantEmbedded(family, 400, true)) embedded++;\n }\n console.log('[Vector PDF Debug] embedFontsForSvg', {\n requested: needed.size,\n newlyEmbedded: embedded,\n sample: [...needed.values()].slice(0, 12),\n });\n}\n\n/**\n * If the element has any per-side edge fade configured, bake the fade into the\n * given raster data URL and return a fresh PNG data URL. Otherwise returns null.\n * Used by the vector-PDF image paths so the fade visible in the editor matches\n * what gets embedded into the exported PDF (raster only — vector SVG paths\n * fall back to raster when fade is active).\n */\nasync function bakeEdgeFadeIntoDataUrl(\n dataUrl: string,\n element: CanvasElement,\n): Promise<string | null> {\n const fade = element as unknown as EdgeFadeProps;\n if (!elementHasEdgeFade(fade)) return null;\n if (!dataUrl || typeof dataUrl !== 'string') return null;\n return await new Promise<string | null>((resolve) => {\n try {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n try {\n const c = bakeEdgeFade(img, fade);\n resolve(c.toDataURL('image/png'));\n } catch {\n resolve(null);\n }\n };\n img.onerror = () => resolve(null);\n img.src = dataUrl;\n } catch {\n resolve(null);\n }\n });\n}\n\nfunction elementHasFade(element: CanvasElement): boolean {\n return elementHasEdgeFade(element as unknown as EdgeFadeProps);\n}\n\n/** Set to true to log PDF export draw order and SVG paths for debugging color/order issues. */\nconst DEBUG_PDF_EXPORT = false;\n\n/**\n * Yield control back to the browser's event loop so animations (spinners, progress bars)\n * can paint between heavy synchronous computation chunks.\n * Uses requestAnimationFrame + setTimeout double-yield for reliable frame painting.\n */\nconst yieldToUI = (): Promise<void> =>\n new Promise((resolve) => {\n requestAnimationFrame(() => setTimeout(resolve, 0));\n });\n\n/** Set to true to log SVG structure: <use> expansion and top-level tags (for \"half rendered\" debug). */\nconst DEBUG_SVG_STRUCTURE = false;\n\n/**\n * Set to true to flatten all SVG gradients to solid colors for PDF export.\n * - Prevents color leaking between SVGs (every path has explicit fill, svg2pdf sets it).\n * - Trade-off: gradients in PDF become flat (one color per shape, from gradient's first stop).\n * Set to true to guarantee no color leak (gradients become flat in PDF).\n */\nconst FLATTEN_SVG_GRADIENTS_FOR_PDF = false;\n\n/** Set to true to log every setFillColor/setDrawColor/setTextColor from svg2pdf (noisy). */\nconst DEBUG_PDF_COLOR_VERBOSE = false;\n\n/** Browser SVG-filter rasterization renders soft shadows a little denser than Canvas2D. */\nconst SHADOW_RASTER_ALPHA_COMPENSATION = 0.84;\n\n/**\n * Scan an SVG markup fragment for every distinct font-family / font-weight /\n * font-style / font-size combination used by `<text>` / `<tspan>` elements.\n * Returns a list of CSS `font-shorthand` specs suitable for\n * `document.fonts.load(spec)`. Used by the shadow rasterizer to wait for\n * every font referenced inside the offscreen SVG-in-img render BEFORE\n * painting — without this, on real browsers the shadow silhouette paints\n * with a fallback font (wider glyphs / wrong metrics) and visibly mis-\n * registers against the real text above it. Puppeteer happens to dodge\n * this because the harness preloads all Google Fonts before rendering, so\n * the bug only shows up in the user's own browser export.\n */\nfunction collectFontSpecsFromShadowMarkup(markup: string): string[] {\n const specs = new Set<string>();\n const re = /<(?:text|tspan)\\b[^>]*>/gi;\n let match: RegExpExecArray | null;\n while ((match = re.exec(markup)) !== null) {\n const tag = match[0];\n const get = (attr: string): string | null => {\n const m = tag.match(new RegExp(`\\\\s${attr}\\\\s*=\\\\s*\"([^\"]*)\"`, 'i'));\n if (m) return m[1];\n const styleM = tag.match(/\\sstyle\\s*=\\s*\"([^\"]*)\"/i);\n if (styleM) {\n const sm = styleM[1].match(new RegExp(`${attr}\\\\s*:\\\\s*([^;]+)`, 'i'));\n if (sm) return sm[1].trim();\n }\n return null;\n };\n const family = (get('font-family') || '').split(',')[0].replace(/['\"]/g, '').trim();\n if (!family) continue;\n const weight = get('font-weight') || '400';\n const style = get('font-style') || 'normal';\n const size = get('font-size') || '16px';\n const sizePx = /[a-z%]/i.test(size) ? size : `${size}px`;\n const famSpec = /\\s/.test(family) ? `\"${family}\"` : family;\n specs.add(`${style} ${weight} ${sizePx} ${famSpec}`);\n }\n return Array.from(specs);\n}\n\n/** Increments each time we're about to draw an SVG (for debug logs). */\nlet debugSvgDrawSequence = 0;\n\nfunction debugLog(...args: unknown[]) {\n if (DEBUG_PDF_EXPORT) console.log('[PDF export]', ...args);\n}\n\n/** Wrap pdf so we log every color change made by svg2pdf (to debug leak). */\nfunction pdfWithColorLogging(pdf: jsPDF, seq: number, elementId: string): jsPDF {\n if (!DEBUG_PDF_COLOR_VERBOSE) return pdf;\n return new Proxy(pdf, {\n get(target, prop: string) {\n const val = (target as any)[prop];\n if (prop === 'setFillColor' && typeof val === 'function') {\n return function (this: any, ...args: unknown[]) {\n debugLog(`[COLOR] svg2pdf #${seq} elementId=${elementId} setFillColor(${args.join(',')})`);\n return val.apply(target, args);\n };\n }\n if (prop === 'setDrawColor' && typeof val === 'function') {\n return function (this: any, ...args: unknown[]) {\n debugLog(`[COLOR] svg2pdf #${seq} elementId=${elementId} setDrawColor(${args.join(',')})`);\n return val.apply(target, args);\n };\n }\n if (prop === 'setTextColor' && typeof val === 'function') {\n return function (this: any, ...args: unknown[]) {\n debugLog(`[COLOR] svg2pdf #${seq} elementId=${elementId} setTextColor(${args.join(',')})`);\n return val.apply(target, args);\n };\n }\n return val;\n },\n }) as jsPDF;\n}\n\n/** Separator for embedded font key \"fontFamily\\u001Fweight\" (unit separator, not in font names) */\nconst FONT_KEY_SEP = '\\u001F';\n\nfunction normalizePdfFontWeight(raw: unknown): number {\n if (typeof raw === 'number' && Number.isFinite(raw)) return resolveFontWeight(raw);\n const str = String(raw ?? '').trim().toLowerCase();\n const parsed = Number.parseInt(str, 10);\n if (Number.isFinite(parsed)) return resolveFontWeight(parsed);\n if (str === 'bold' || str === 'bolder') return 700;\n if (str === 'semibold' || str === 'demibold') return 600;\n if (str === 'medium') return 500;\n if (str === 'light' || str === 'lighter' || str === 'thin') return 300;\n return 400;\n}\n\nfunction collectTextFontVariantsForPdf(\n el: any,\n fontKeysNeeded: Set<string>,\n italicKeysNeeded: Set<string>,\n): void {\n const baseFamily = el?.fontFamily || el?.style?.fontFamily;\n if (!baseFamily) return;\n\n const addVariant = (family: string, weightRaw: unknown, styleRaw: unknown) => {\n const resolved = normalizePdfFontWeight(weightRaw);\n if (/italic|oblique/i.test(String(styleRaw ?? ''))) {\n italicKeysNeeded.add(`${family}${FONT_KEY_SEP}${resolved}${FONT_KEY_SEP}italic`);\n } else {\n fontKeysNeeded.add(`${family}${FONT_KEY_SEP}${resolved}`);\n }\n };\n\n addVariant(baseFamily, el.fontWeight ?? el.style?.fontWeight ?? 400, el.fontStyle ?? el.style?.fontStyle ?? 'normal');\n\n // Fabric rich text stores per-character inline styles as object-keyed maps:\n // { lineIndex: { charIndex: { fontWeight/fontStyle/fontFamily } } }.\n const styles = el.styles;\n if (styles && typeof styles === 'object') {\n for (const lineStyles of Object.values(styles) as any[]) {\n if (!lineStyles || typeof lineStyles !== 'object') continue;\n for (const s of Object.values(lineStyles) as any[]) {\n if (!s || typeof s !== 'object') continue;\n addVariant(s.fontFamily || baseFamily, s.fontWeight ?? el.fontWeight ?? 400, s.fontStyle ?? el.fontStyle ?? 'normal');\n }\n }\n }\n\n // Inline markdown (`formattingEnabled`) is parsed into Fabric styles only at\n // render time. The PDF pre-embed pass must mirror that parse, otherwise\n // `<tspan font-weight=\"700\">` runs render with the regular font or Helvetica.\n if (el.formattingEnabled === true && typeof el.text === 'string') {\n try {\n const parsed = parseTextMarkdown(el.text);\n for (const lineStyles of Object.values(parsed.styles || {}) as any[]) {\n if (!lineStyles || typeof lineStyles !== 'object') continue;\n for (const s of Object.values(lineStyles) as any[]) {\n if (!s || typeof s !== 'object') continue;\n addVariant(s.fontFamily || baseFamily, s.fontWeight ?? el.fontWeight ?? 400, s.fontStyle ?? el.fontStyle ?? 'normal');\n }\n }\n } catch {\n // Markdown parsing is best-effort; base font embedding above still applies.\n }\n }\n}\n\n/** True if the character is in Basic Latin or Latin-1 (typical for embedded body fonts). Otherwise use symbol fallback font. */\nfunction isBasicLatinOrLatin1(char: string): boolean {\n const c = char.codePointAt(0) ?? 0;\n return (c >= 0x20 && c <= 0x7e) || (c >= 0xa0 && c <= 0xff);\n}\n\n/**\n * Common typographic punctuation that virtually every modern Latin font\n * (Google Fonts, Fontshare, etc.) includes in its default subset. We must\n * NOT route these to the symbol-fallback font (Noto Sans) because doing so\n * makes them look visually different from the live canvas — e.g. an em-dash\n * (U+2014) rendered through a fallback can appear as a thin \"artificial line\"\n * instead of the matching dash glyph from the active font.\n *\n * Whitelist: General Punctuation block characters covered by Google Fonts'\n * Latin subset (em/en-dashes, smart quotes, ellipsis, bullet, primes, etc.)\n * plus ™ (U+2122) which is also part of the Latin subset.\n */\nfunction isCommonLatinPunctuation(char: string): boolean {\n const c = char.codePointAt(0) ?? 0;\n // Hyphens & dashes, smart quotes, daggers, bullets, ellipsis, primes,\n // single guillemets, fraction slash, etc.\n if (c >= 0x2010 && c <= 0x2049) return true;\n // ℓ (script l), ™\n if (c === 0x2113 || c === 0x2122) return true;\n return false;\n}\n\n/** True if the char is a math operator / arrow / supplemental-math glyph that\n * is typically MISSING from main Latin fonts AND from the FONT_FALLBACK_SYMBOLS\n * Latin subset (e.g. ≠ ≤ ≥ ≈ ∞ → ← ∑ √ ∈ ∀ ∃ ∂ ∇ etc.). These need the\n * dedicated FONT_FALLBACK_MATH font to render. */\nfunction isMathOperator(char: string): boolean {\n const c = char.codePointAt(0) ?? 0;\n if (c >= 0x2190 && c <= 0x21FF) return true; // Arrows\n if (c >= 0x2200 && c <= 0x22FF) return true; // Mathematical Operators (≠ ≤ ≥ ≈ ∞ ∑ √ ∈ …)\n if (c >= 0x2300 && c <= 0x23FF) return true; // Misc Technical (⌐ ⌒ …)\n if (c >= 0x27C0 && c <= 0x27EF) return true; // Misc Mathematical Symbols-A\n if (c >= 0x2980 && c <= 0x29FF) return true; // Misc Mathematical Symbols-B\n if (c >= 0x2A00 && c <= 0x2AFF) return true; // Supplemental Math Operators\n if (c >= 0x2B00 && c <= 0x2B59) return true; // additional arrows / geometric\n return false;\n}\n\n/** True if the character is in the Devanagari Unicode block (Hindi, Marathi, Sanskrit, etc.) */\nfunction isDevanagari(char: string): boolean {\n const c = char.codePointAt(0) ?? 0;\n return (c >= 0x0900 && c <= 0x097F) || (c >= 0xA8E0 && c <= 0xA8FF) || (c >= 0x1CD0 && c <= 0x1CFF);\n}\n\n/** Check if a string contains any Devanagari characters */\nfunction containsDevanagari(text: string): boolean {\n if (!text) return false;\n for (const char of text) {\n if (isDevanagari(char)) return true;\n }\n return false;\n}\n\n/** Classify a character's font run type: 'main' (Latin), 'devanagari' (Hindi script),\n * 'math' (math operator / arrow needing FONT_FALLBACK_MATH), or 'symbol' (general fallback). */\ntype RunType = 'main' | 'devanagari' | 'math' | 'symbol';\nfunction classifyChar(char: string, mainSupportsChar?: (char: string) => boolean): RunType {\n if (isBasicLatinOrLatin1(char)) return 'main';\n if (isCommonLatinPunctuation(char)) return 'main';\n if (!isDevanagari(char) && mainSupportsChar?.(char)) return 'main';\n if (isDevanagari(char)) return 'devanagari';\n if (isMathOperator(char)) return 'math';\n return 'symbol';\n}\n\n/** Fast check: true when every character is Basic Latin / Latin-1 — no run-splitting needed. */\nfunction isPureLatin(line: string): boolean {\n for (let i = 0; i < line.length; i++) {\n const c = line.charCodeAt(i);\n if (\n !((c >= 0x20 && c <= 0x7e) ||\n (c >= 0xa0 && c <= 0xff) ||\n (c >= 0x2010 && c <= 0x2049) ||\n c === 0x2113 || c === 0x2122)\n ) return false;\n }\n return true;\n}\n\n/** Split a line into runs of main-font, devanagari-font, or symbol-fallback-font. */\nfunction splitLineIntoRuns(line: string, mainSupportsChar?: (char: string) => boolean): { text: string; runType: RunType }[] {\n if (!line) return [];\n const runs: { text: string; runType: RunType }[] = [];\n const chars = [...line];\n let current = '';\n let currentType: RunType = 'main';\n for (const char of chars) {\n const charType = classifyChar(char, mainSupportsChar);\n if (current && charType !== currentType) {\n runs.push({ text: current, runType: currentType });\n current = '';\n }\n currentType = charType;\n current += char;\n }\n if (current) runs.push({ text: current, runType: currentType });\n return runs;\n}\n\n/** Load image from URL and return natural dimensions (used when Fabric image has baked/display size after move). */\nfunction loadNaturalDimensionsFromUrl(imageUrl: string): Promise<{ width: number; height: number } | null> {\n return new Promise((resolve) => {\n if (!imageUrl) {\n resolve(null);\n return;\n }\n const img = new Image();\n img.crossOrigin = imageUrl.startsWith('data:') || imageUrl.startsWith('blob:') ? undefined : 'anonymous';\n img.onload = () => {\n const w = img.naturalWidth || 0;\n const h = img.naturalHeight || 0;\n resolve(w > 0 && h > 0 ? { width: w, height: h } : null);\n };\n img.onerror = () => resolve(null);\n try {\n img.src = imageUrl.startsWith('data:') || imageUrl.startsWith('blob:') ? imageUrl : getProxiedImageUrl(imageUrl);\n } catch {\n resolve(null);\n }\n });\n}\n\nasync function rasterizeStoredCropImageToPng(options: {\n imageUrl: string;\n frameW: number;\n frameH: number;\n clipShape?: string;\n borderRadius?: number;\n panX?: number;\n panY?: number;\n zoom?: number;\n naturalWidth?: number;\n naturalHeight?: number;\n maintainResolution?: boolean;\n backgroundColor?: string;\n}): Promise<string | null> {\n const {\n imageUrl,\n frameW,\n frameH,\n clipShape,\n borderRadius = 0,\n panX = 0.5,\n panY = 0.5,\n zoom = 1,\n naturalWidth,\n naturalHeight,\n maintainResolution = true,\n backgroundColor,\n } = options;\n\n if (!imageUrl || frameW <= 0 || frameH <= 0) return null;\n\n const img = await new Promise<HTMLImageElement | null>((resolve) => {\n const el = new Image();\n el.crossOrigin = imageUrl.startsWith('data:') || imageUrl.startsWith('blob:') ? undefined : 'anonymous';\n el.onload = () => resolve(el);\n el.onerror = () => resolve(null);\n try {\n el.src = imageUrl.startsWith('data:') || imageUrl.startsWith('blob:') ? imageUrl : getProxiedImageUrl(imageUrl);\n } catch {\n resolve(null);\n }\n });\n\n if (!img) return null;\n\n const natW = Math.max(1, naturalWidth || img.naturalWidth || frameW);\n const natH = Math.max(1, naturalHeight || img.naturalHeight || frameH);\n const baseScale = Math.max(frameW / natW, frameH / natH);\n const finalScale = Math.max(1, zoom) * baseScale;\n const drawW = natW * finalScale;\n const drawH = natH * finalScale;\n\n const clampedPanX = Math.max(0, Math.min(1, panX));\n const clampedPanY = Math.max(0, Math.min(1, panY));\n const overflowX = Math.max(0, drawW - frameW);\n const overflowY = Math.max(0, drawH - frameH);\n const offsetX = overflowX > 0 ? -overflowX * (clampedPanX - 0.5) : 0;\n const offsetY = overflowY > 0 ? -overflowY * (clampedPanY - 0.5) : 0;\n const imgX = frameW / 2 + offsetX - drawW / 2;\n const imgY = frameH / 2 + offsetY - drawH / 2;\n\n const outW = maintainResolution && natW > frameW ? Math.max(1, Math.round(natW)) : Math.max(1, Math.round(frameW * 2));\n const outH = maintainResolution && natH > frameH ? Math.max(1, Math.round(natH)) : Math.max(1, Math.round(frameH * 2));\n\n const canvas = document.createElement('canvas');\n canvas.width = outW;\n canvas.height = outH;\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n\n const bgFill = backgroundColor && backgroundColor !== 'transparent' && backgroundColor !== 'none'\n ? normalizeBgColor(backgroundColor)\n : undefined;\n\n if (bgFill) {\n ctx.fillStyle = bgFill;\n ctx.fillRect(0, 0, outW, outH);\n } else {\n ctx.clearRect(0, 0, outW, outH);\n }\n\n const sx = outW / frameW;\n const sy = outH / frameH;\n ctx.save();\n ctx.scale(sx, sy);\n ctx.beginPath();\n\n if (clipShape === 'circle') {\n ctx.ellipse(frameW / 2, frameH / 2, frameW / 2, frameH / 2, 0, 0, 2 * Math.PI);\n } else {\n const isRounded = clipShape === 'rounded' || clipShape === 'roundRect' || (borderRadius ?? 0) > 0;\n const r = isRounded ? Math.max(0, Math.min(borderRadius, frameW / 2, frameH / 2)) : 0;\n if (r > 0) {\n ctx.moveTo(r, 0);\n ctx.lineTo(frameW - r, 0);\n ctx.quadraticCurveTo(frameW, 0, frameW, r);\n ctx.lineTo(frameW, frameH - r);\n ctx.quadraticCurveTo(frameW, frameH, frameW - r, frameH);\n ctx.lineTo(r, frameH);\n ctx.quadraticCurveTo(0, frameH, 0, frameH - r);\n ctx.lineTo(0, r);\n ctx.quadraticCurveTo(0, 0, r, 0);\n ctx.closePath();\n } else {\n ctx.rect(0, 0, frameW, frameH);\n }\n }\n\n ctx.clip();\n ctx.drawImage(img, imgX, imgY, drawW, drawH);\n ctx.restore();\n\n return canvas.toDataURL('image/png');\n}\n\n/** svg2pdf options sanitizer: keep sub-pixel precision for accurate placement while guarding invalid values. */\nfunction svg2pdfOpts(x: number, y: number, width: number, height: number) {\n const sanitize = (value: number, fallback: number): number => {\n if (!Number.isFinite(value)) return fallback;\n return Number(value.toFixed(3));\n };\n\n const w = Math.max(0.001, sanitize(width, 1));\n const h = Math.max(0.001, sanitize(height, 1));\n\n return {\n x: sanitize(x, 0),\n y: sanitize(y, 0),\n width: w,\n height: h,\n };\n}\n\n/**\n * For axis-aligned matrices (no skew/rotation and no mirroring), compute a stable page-space frame\n * so we can render SVGs without CTM (avoids occasional transform drift).\n */\nfunction getAxisAlignedSvgFrameFromMatrix(\n matrix: Matrix6,\n localX: number,\n localY: number,\n width: number,\n height: number\n): { x: number; y: number; width: number; height: number } | null {\n const [a, b, c, d, e, f] = matrix;\n const EPS = 1e-5;\n if (Math.abs(b) > EPS || Math.abs(c) > EPS) return null;\n\n // Mirrored (negative) scales must use matrix path; flattening to page-space frame\n // loses orientation and can shift visible placement for directional SVGs.\n if (a < -EPS || d < -EPS) return null;\n\n const x1 = a * localX + e;\n const x2 = a * (localX + width) + e;\n const y1 = d * localY + f;\n const y2 = d * (localY + height) + f;\n\n const left = Math.min(x1, x2);\n const top = Math.min(y1, y2);\n const frameW = Math.max(0, Math.abs(x2 - x1));\n const frameH = Math.max(0, Math.abs(y2 - y1));\n\n if (!Number.isFinite(left) || !Number.isFinite(top) || !Number.isFinite(frameW) || !Number.isFinite(frameH)) {\n return null;\n }\n if (frameW < EPS || frameH < EPS) return null;\n\n return { x: left, y: top, width: frameW, height: frameH };\n}\n\nfunction transformPointWithMatrix(matrix: Matrix6, x: number, y: number): { x: number; y: number } {\n const [a, b, c, d, e, f] = matrix;\n return {\n x: a * x + c * y + e,\n y: b * x + d * y + f,\n };\n}\n\nfunction buildMatrixTransformedSvgForPage(\n svg: Element,\n matrix: Matrix6,\n localX: number,\n localY: number,\n width: number,\n height: number\n): { svg: SVGSVGElement; frame: { x: number; y: number; width: number; height: number } } | null {\n const EPS = 1e-5;\n const corners = [\n transformPointWithMatrix(matrix, localX, localY),\n transformPointWithMatrix(matrix, localX + width, localY),\n transformPointWithMatrix(matrix, localX, localY + height),\n transformPointWithMatrix(matrix, localX + width, localY + height),\n ];\n\n const minX = Math.min(...corners.map((p) => p.x));\n const minY = Math.min(...corners.map((p) => p.y));\n const maxX = Math.max(...corners.map((p) => p.x));\n const maxY = Math.max(...corners.map((p) => p.y));\n const frameW = maxX - minX;\n const frameH = maxY - minY;\n\n if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(frameW) || !Number.isFinite(frameH)) {\n return null;\n }\n if (frameW < EPS || frameH < EPS) return null;\n\n const ns = 'http://www.w3.org/2000/svg';\n const wrapper = document.createElementNS(ns, 'svg') as SVGSVGElement;\n wrapper.setAttribute('xmlns', ns);\n wrapper.setAttribute('width', String(frameW));\n wrapper.setAttribute('height', String(frameH));\n wrapper.setAttribute('viewBox', `0 0 ${frameW} ${frameH}`);\n\n const g = document.createElementNS(ns, 'g');\n const [a, b, c, d, e, f] = matrix;\n g.setAttribute('transform', `matrix(${a} ${b} ${c} ${d} ${e - minX} ${f - minY})`);\n\n const nested = svg.cloneNode(true) as Element;\n nested.setAttribute('x', String(localX));\n nested.setAttribute('y', String(localY));\n nested.setAttribute('width', String(width));\n nested.setAttribute('height', String(height));\n\n g.appendChild(nested);\n wrapper.appendChild(g);\n\n return {\n svg: wrapper,\n frame: { x: minX, y: minY, width: frameW, height: frameH },\n };\n}\n\n/**\n * Mount SVG in the DOM temporarily so svg2pdf can resolve gradient <defs> references,\n * then run svg2pdf, then unmount. This fixes gradient rendering issues where svg2pdf\n * couldn't find referenced paint servers in detached SVG clones.\n */\nasync function svg2pdfWithDomMount(\n svg: Element,\n pdf: jsPDF,\n opts: ReturnType<typeof svg2pdfOpts>\n): Promise<void> {\n const wrap = document.createElement('div');\n wrap.style.cssText = 'position:fixed;left:-9999px;top:0;width:0;height:0;overflow:hidden;pointer-events:none;opacity:0';\n wrap.appendChild(svg);\n document.body.appendChild(wrap);\n try {\n await svg2pdf(svg, pdf, opts);\n } finally {\n svg.remove();\n if (wrap.parentNode) document.body.removeChild(wrap);\n }\n}\n\n/**\n * WHY COLOR LEAKS BETWEEN SVGs (two causes):\n * 1) jsPDF reuses form objects (gradients, patterns) by ID. If two SVGs both have a gradient id=\"linear-gradient\",\n * the second SVG gets the first SVG's gradient (same form object) → wrong color. Fix: prefix all ids per SVG\n * (prefixSvgIds) so each SVG has unique ids. See yWorks/svg2pdf.js#171, #166, PR #188.\n * 2) PDF has a single \"current\" fill/stroke. svg2pdf may not call setFillColor for gradient elements, so the\n * current fill can stay from the previous SVG. Fix: reset + setPdfColorFromSvg before each svg2pdf, reset after.\n */\nfunction resetPdfColorState(pdf: jsPDF, label?: string) {\n if (DEBUG_PDF_EXPORT && label) debugLog(`[COLOR] reset → black (${label})`);\n pdf.setFillColor(0, 0, 0);\n pdf.setDrawColor(0, 0, 0);\n if (typeof (pdf as any).setTextColor === 'function') (pdf as any).setTextColor(0, 0, 0);\n}\n\n/** Get the first explicit fill/stroke color found in the SVG tree (hex or rgb), for use as PDF currentColor. Resolves url(#gradient) to a solid so the default is correct per-SVG (avoids leaking previous SVG's color). */\nfunction getFirstExplicitColorFromSvg(svg: Element): { fill: string | null; stroke: string | null } {\n let fill: string | null = null;\n let stroke: string | null = null;\n const isRealColor = (v: string | null): boolean => {\n if (!v || v === 'none') return false;\n const s = v.trim().toLowerCase();\n return s !== 'currentcolor' && s !== 'inherit' && (s.startsWith('#') || s.startsWith('rgb'));\n };\n const resolveUrl = (v: string | null): string | null => {\n if (!v || v === 'none') return null;\n const gradientId = extractGradientIdFromPaint(v);\n if (!gradientId) return null;\n return getGradientStopColorAsHex(svg, gradientId);\n };\n function walk(el: Element) {\n if (fill && stroke) return;\n const f = el.getAttribute('fill') ?? (el as SVGElement).style?.getPropertyValue('fill');\n const s = el.getAttribute('stroke') ?? (el as SVGElement).style?.getPropertyValue('stroke');\n if (!fill) {\n if (isRealColor(f)) fill = f;\n else if (f) {\n const resolved = resolveUrl(f);\n if (resolved) fill = resolved;\n }\n }\n if (!stroke) {\n if (isRealColor(s)) stroke = s;\n else if (s) {\n const resolved = resolveUrl(s);\n if (resolved) stroke = resolved;\n }\n }\n for (let i = 0; i < el.children.length; i++) walk(el.children[i]);\n }\n walk(svg);\n return { fill, stroke };\n}\n\n/** Set PDF fill and stroke from the SVG's first explicit colors so svg2pdf has a sensible default. Call resetPdfColorState(pdf) before this so we never leak the previous SVG's colors. */\nfunction setPdfColorFromSvg(pdf: jsPDF, svg: Element, elementId?: string) {\n const { fill, stroke } = getFirstExplicitColorFromSvg(svg);\n const rgbFill = fill ? parseColor(fill) : null;\n const rgbStroke = stroke ? parseColor(stroke) : null;\n if (DEBUG_PDF_EXPORT && elementId) {\n debugLog(`[COLOR] setPdfColorFromSvg elementId=${elementId} fill=${fill ?? 'black'} stroke=${stroke ?? 'black'} → rgb(${rgbFill ? `${rgbFill.r},${rgbFill.g},${rgbFill.b}` : '0,0,0'}) / (${rgbStroke ? `${rgbStroke.r},${rgbStroke.g},${rgbStroke.b}` : '0,0,0'})`);\n }\n if (rgbFill) pdf.setFillColor(rgbFill.r, rgbFill.g, rgbFill.b);\n else pdf.setFillColor(0, 0, 0);\n if (rgbStroke) pdf.setDrawColor(rgbStroke.r, rgbStroke.g, rgbStroke.b);\n else pdf.setDrawColor(0, 0, 0);\n}\n\n/** Tags that draw and need explicit fill/stroke so svg2pdf renders them (it often only reads attributes, not CSS). */\nconst SVG_DRAWABLE_TAGS = new Set(['path', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'line', 'text', 'tspan']);\n\n/**\n * Non-rendering / definition subtrees must not inherit synthesized paint from ancestors.\n * Doing so can turn mask/clipPath helper geometry into visible filled rectangles in svg2pdf.\n */\nconst SVG_DEFINITION_CONTAINER_TAGS = new Set([\n 'defs',\n 'clippath',\n 'mask',\n 'pattern',\n 'marker',\n 'symbol',\n 'filter',\n 'lineargradient',\n 'radialgradient',\n]);\n\nfunction isInSvgDefinitionSubtree(el: Element): boolean {\n let current: Element | null = el;\n while (current) {\n const tag = current.tagName?.toLowerCase() ?? '';\n if (SVG_DEFINITION_CONTAINER_TAGS.has(tag)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\nfunction parseInlineSvgStyleDeclarations(styleText: string): Array<{ key: string; value: string }> {\n return styleText\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => {\n const idx = part.indexOf(':');\n if (idx <= 0) return null;\n return {\n key: part.slice(0, idx).trim().toLowerCase(),\n value: part.slice(idx + 1).trim(),\n };\n })\n .filter((x): x is { key: string; value: string } => !!x);\n}\n\nfunction logGradientBindingDiagnostics(svg: Element): void {\n const gradientCount = svg.querySelectorAll('linearGradient, radialGradient').length;\n if (gradientCount === 0) return;\n\n let gradientRefCount = 0;\n svg.querySelectorAll('*').forEach((el) => {\n const fill = el.getAttribute('fill');\n const stroke = el.getAttribute('stroke');\n const style = el.getAttribute('style');\n if (extractGradientIdFromPaint(fill) || extractGradientIdFromPaint(stroke)) {\n gradientRefCount++;\n return;\n }\n if (style) {\n const declarations = parseInlineSvgStyleDeclarations(style);\n if (declarations.some(({ value }) => !!extractGradientIdFromPaint(value))) {\n gradientRefCount++;\n }\n }\n });\n\n if (gradientRefCount === 0) {\n console.warn('[PDF export] SVG gradient diagnostics: defs exist but no gradient refs bound after style inlining. Export may render black.', {\n gradientCount,\n drawableCount: svg.querySelectorAll('path, rect, circle, ellipse, polygon, polyline, line').length,\n });\n }\n}\n\nconst SVG_STYLE_PROPS = new Set([\n 'fill',\n 'stroke',\n 'color',\n 'opacity',\n 'fill-opacity',\n 'stroke-opacity',\n 'fill-rule',\n 'stroke-width',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'display',\n 'visibility',\n 'stop-color',\n 'stop-opacity',\n 'clip-rule',\n 'clip-path',\n 'mask',\n 'filter',\n]);\n\nfunction inlineSvgStyleBlockDeclarations(svg: Element): void {\n const styleNodes = Array.from(svg.querySelectorAll('style'));\n if (styleNodes.length === 0) return;\n\n const cssText = styleNodes\n .map((node) => node.textContent || '')\n .join('\\n')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, ' ');\n if (!cssText.trim()) return;\n\n const allElements = [svg, ...Array.from(svg.querySelectorAll('*'))];\n const classIndex = new Map<string, Element[]>();\n allElements.forEach((el) => {\n const raw = el.getAttribute('class') || '';\n raw.split(/\\s+/)\n .map((token) => token.trim())\n .filter(Boolean)\n .forEach((token) => {\n const list = classIndex.get(token) ?? [];\n list.push(el);\n classIndex.set(token, list);\n });\n });\n\n const normalizePresentationValue = (key: string, value: string): string => {\n // Strip !important — valid in CSS but invalid in SVG presentation attributes\n const cleaned = value.replace(/\\s*!important\\s*$/i, '').trim();\n if (['fill', 'stroke', 'clip-path', 'mask', 'filter'].includes(key)) {\n return normalizeGradientPaintRef(cleaned);\n }\n return cleaned;\n };\n\n const applyDeclarations = (\n elements: Iterable<Element>,\n declarations: Array<{ key: string; value: string }>\n ) => {\n for (const el of elements) {\n const inlineStyle = el.getAttribute('style') || '';\n const inlineDeclMap = new Map(\n parseInlineSvgStyleDeclarations(inlineStyle).map(({ key, value }) => [key, value])\n );\n\n for (const { key, value } of declarations) {\n if (!value || inlineDeclMap.has(key)) continue;\n el.setAttribute(key, normalizePresentationValue(key, value));\n }\n }\n };\n\n const ruleRegex = /([^{}]+)\\{([^}]*)\\}/g;\n let ruleMatch: RegExpExecArray | null;\n while ((ruleMatch = ruleRegex.exec(cssText))) {\n const selectors = ruleMatch[1].split(',').map((s) => s.trim()).filter(Boolean);\n const declarations = parseInlineSvgStyleDeclarations(ruleMatch[2]).filter((decl) => SVG_STYLE_PROPS.has(decl.key));\n if (selectors.length === 0 || declarations.length === 0) continue;\n\n for (const selector of selectors) {\n if (!selector || selector.startsWith('@')) continue;\n\n const classOnlyMatch = selector.match(/^\\.([A-Za-z_][\\w-]*)$/);\n if (classOnlyMatch) {\n applyDeclarations(classIndex.get(classOnlyMatch[1]) ?? [], declarations);\n continue;\n }\n\n try {\n applyDeclarations(svg.querySelectorAll(selector), declarations);\n } catch {\n const classMatch = selector.match(/\\.([A-Za-z0-9_-]+)/);\n if (classMatch) {\n applyDeclarations(classIndex.get(classMatch[1]) ?? [], declarations);\n }\n }\n }\n }\n\n for (const el of allElements) {\n const style = el.getAttribute('style');\n if (!style) continue;\n\n const keptDecls: string[] = [];\n let changed = false;\n for (const { key, value } of parseInlineSvgStyleDeclarations(style)) {\n if (SVG_STYLE_PROPS.has(key)) {\n el.setAttribute(key, normalizePresentationValue(key, value));\n changed = true;\n } else {\n keptDecls.push(`${key}: ${value}`);\n }\n }\n\n if (changed) {\n if (keptDecls.length > 0) el.setAttribute('style', keptDecls.join('; '));\n else el.removeAttribute('style');\n }\n }\n\n for (const styleNode of styleNodes) {\n const css = styleNode.textContent || '';\n let cleaned = css;\n for (const prop of SVG_STYLE_PROPS) {\n const regex = new RegExp(`${prop.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&')}\\\\s*:\\\\s*[^;}{]+;?`, 'gi');\n cleaned = cleaned.replace(regex, '');\n }\n styleNode.textContent = cleaned\n .replace(/;\\s*;/g, ';')\n .replace(/\\{\\s*;/g, '{')\n .replace(/;\\s*}/g, '}')\n .replace(/\\{\\s*}/g, '{}');\n }\n}\n\n/** Inline fill/stroke onto drawable nodes so svg2pdf sees resolved values without forcing black over class-based gradients. */\nfunction normalizeSvgExplicitColors(svg: Element): Element {\n const clone = svg.cloneNode(true) as Element;\n inlineSvgStyleBlockDeclarations(clone);\n logGradientBindingDiagnostics(clone);\n\n const parseColorAttr = (v: string | null): string | null => {\n if (!v) return null;\n const s = v.trim().toLowerCase();\n if (!s || s === 'none' || s === 'transparent' || s === 'currentcolor') return null;\n return normalizeGradientPaintRef(v);\n };\n\n const getRawAttr = (el: Element, attr: 'fill' | 'stroke' | 'color'): string =>\n (el.getAttribute(attr) ?? (el as SVGElement).style?.getPropertyValue(attr) ?? '').trim().toLowerCase();\n\n const getRawOpacityAttr = (el: Element, attr: 'fill' | 'stroke' | 'color'): string => {\n if (attr === 'color') return '';\n return (el.getAttribute(`${attr}-opacity`) ?? (el as SVGElement).style?.getPropertyValue(`${attr}-opacity`) ?? '').trim().toLowerCase();\n };\n\n const hasExplicitNonePaint = (el: Element, attr: 'fill' | 'stroke'): boolean => {\n const raw = getRawAttr(el, attr);\n if (raw === 'none' || raw === 'transparent') return true;\n const rawOpacity = getRawOpacityAttr(el, attr);\n return rawOpacity === '0' || rawOpacity === '0%' || rawOpacity === '0.0';\n };\n\n const getAttr = (el: Element, attr: 'fill' | 'stroke' | 'color'): string | null => {\n const v = el.getAttribute(attr) ?? (el as SVGElement).style?.getPropertyValue(attr);\n return parseColorAttr(v);\n };\n\n function walk(el: Element, parentFill: string | null, parentStroke: string | null, parentColor: string | null) {\n if (isInSvgDefinitionSubtree(el)) {\n for (let i = 0; i < el.children.length; i++) {\n walk(el.children[i], null, null, null);\n }\n return;\n }\n\n const tag = el.tagName?.toLowerCase() ?? '';\n const isDrawable = SVG_DRAWABLE_TAGS.has(tag);\n let fill = getAttr(el, 'fill');\n let stroke = getAttr(el, 'stroke');\n const color = getAttr(el, 'color') ?? parentColor;\n const fillNone = hasExplicitNonePaint(el, 'fill');\n const strokeNone = hasExplicitNonePaint(el, 'stroke');\n const inheritedFill = parentFill === 'none' ? null : parentFill;\n const inheritedStroke = parentStroke === 'none' ? null : parentStroke;\n\n if (isDrawable) {\n if (fillNone) {\n el.setAttribute('fill', 'none');\n fill = null;\n } else {\n const resolved = fill ?? color ?? inheritedFill;\n if (resolved) {\n el.setAttribute('fill', resolved);\n fill = resolved;\n } else if (tag !== 'text' && tag !== 'tspan') {\n // Fabric / editor use transparent canvas; missing fill must not fall through to svg2pdf\n // using jsPDF's current fill (black after setPdfColorFromSvg). SVG defaults would be black\n // for shapes — explicit none matches on-screen transparent areas (e.g. icon bounding rects).\n el.setAttribute('fill', 'none');\n fill = null;\n }\n }\n }\n\n if (isDrawable) {\n if (strokeNone) {\n el.setAttribute('stroke', 'none');\n stroke = null;\n } else if (stroke != null || color != null || inheritedStroke != null) {\n const resolved = stroke ?? color ?? inheritedStroke;\n if (resolved) {\n el.setAttribute('stroke', resolved);\n stroke = resolved;\n }\n }\n }\n\n const nextColor = color ?? parentColor;\n const nextFill = fillNone ? 'none' : (fill ?? inheritedFill);\n const nextStroke = strokeNone ? 'none' : (stroke ?? inheritedStroke);\n for (let i = 0; i < el.children.length; i++) {\n walk(el.children[i], nextFill, nextStroke, nextColor);\n }\n }\n\n const rootColor = getAttr(clone, 'color') ?? (clone.getAttribute('color') || null);\n const rootFill = getAttr(clone, 'fill') ?? rootColor;\n const rootStroke = getAttr(clone, 'stroke') ?? rootColor;\n const rootFillNone = hasExplicitNonePaint(clone, 'fill');\n const rootStrokeNone = hasExplicitNonePaint(clone, 'stroke');\n\n if (rootFillNone) {\n clone.setAttribute('fill', 'none');\n } else if (rootFill) {\n clone.setAttribute('fill', rootFill);\n }\n if (rootStrokeNone) {\n clone.setAttribute('stroke', 'none');\n } else if (rootStroke) {\n clone.setAttribute('stroke', rootStroke);\n }\n\n for (let i = 0; i < clone.children.length; i++) {\n walk(\n clone.children[i],\n rootFillNone ? 'none' : (rootFill ?? null),\n rootStrokeNone ? 'none' : (rootStroke ?? null),\n rootColor\n );\n }\n\n return clone;\n}\n\n/** Bake element-level opacity into SVG nodes so svg2pdf preserves opacity consistently.\n * We multiply existing per-node opacity values instead of relying on PDF GState opacity,\n * because svg2pdf may override GState while drawing nested paths/gradients. */\nfunction parseSvgOpacity(value: string | null): number | null {\n if (!value) return null;\n const raw = value.trim();\n if (!raw) return null;\n if (raw.endsWith('%')) {\n const pct = Number.parseFloat(raw.slice(0, -1));\n if (!Number.isFinite(pct)) return null;\n return Math.max(0, Math.min(1, pct / 100));\n }\n const n = Number.parseFloat(raw);\n if (!Number.isFinite(n)) return null;\n return Math.max(0, Math.min(1, n));\n}\n\nfunction formatSvgOpacity(value: number): string {\n const clamped = Math.max(0, Math.min(1, value));\n return Number(clamped.toFixed(4)).toString();\n}\n\nfunction multiplySvgOpacityAttr(\n el: Element,\n attr: 'opacity' | 'fill-opacity' | 'stroke-opacity' | 'stop-opacity',\n factor: number\n): void {\n const existing = parseSvgOpacity(el.getAttribute(attr));\n const next = (existing ?? 1) * factor;\n el.setAttribute(attr, formatSvgOpacity(next));\n}\n\nfunction injectOpacityIntoSvg(svg: Element, opacity: number): void {\n if (opacity >= 0.999) return; // fully opaque, no change needed\n const factor = Math.max(0, Math.min(1, opacity));\n\n // svg2pdf can inconsistently honor element/root \"opacity\" in complex SVGs.\n // Bake alpha directly into paint opacity channels so BOTH solid fills and\n // gradient fills render with consistent transparency.\n const drawable = svg.querySelectorAll('path, rect, circle, ellipse, polygon, polyline, line, text, tspan');\n drawable.forEach((el) => {\n multiplySvgOpacityAttr(el, 'fill-opacity', factor);\n multiplySvgOpacityAttr(el, 'stroke-opacity', factor);\n });\n\n // Gradients need stop-opacity baked as well.\n svg.querySelectorAll('stop').forEach((stop) => {\n multiplySvgOpacityAttr(stop, 'stop-opacity', factor);\n });\n}\n\n/**\n * Flatten `opacity` attributes into paint channels so svg2pdf renders transparency\n * consistently, especially for nested `<g opacity=\"...\">` structures.\n */\nfunction bakeGroupOpacityIntoChildren(svg: Element): void {\n const DRAWABLE_TAGS = new Set(['path', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'line', 'text', 'tspan']);\n\n function walkAndBake(el: Element, inheritedOpacity: number): void {\n if (isInSvgDefinitionSubtree(el)) {\n for (let i = 0; i < el.children.length; i++) {\n walkAndBake(el.children[i], 1);\n }\n return;\n }\n\n const tag = el.tagName?.toLowerCase() ?? '';\n const opacityAttr = parseSvgOpacity(el.getAttribute('opacity'));\n const styleOpacity = parseSvgOpacity((el as SVGElement).style?.getPropertyValue('opacity') || null);\n const ownOpacity = opacityAttr ?? styleOpacity ?? 1;\n const combinedOpacity = inheritedOpacity * ownOpacity;\n\n // Remove explicit opacity once it's baked so svg2pdf does not re-apply it.\n // EXCEPTION: <image> takes raw `opacity` (no fill-opacity equivalent), so\n // we must keep an opacity attribute on it set to the COMBINED value (own\n // × inherited) — otherwise images inside a group with opacity render at\n // full alpha in the PDF.\n if (ownOpacity < 0.999 && tag !== 'image') {\n el.removeAttribute('opacity');\n if ((el as SVGElement).style?.opacity) {\n (el as SVGElement).style.removeProperty('opacity');\n }\n }\n\n if (DRAWABLE_TAGS.has(tag) && combinedOpacity < 0.999) {\n multiplySvgOpacityAttr(el, 'fill-opacity', combinedOpacity);\n multiplySvgOpacityAttr(el, 'stroke-opacity', combinedOpacity);\n }\n\n // <image> has no fill/stroke channels — bake combined opacity onto the\n // element's own `opacity` attribute so svg2pdf renders the alpha.\n if (tag === 'image' && combinedOpacity < 0.999) {\n el.setAttribute('opacity', String(Number(combinedOpacity.toFixed(4))));\n if ((el as SVGElement).style?.opacity) {\n (el as SVGElement).style.removeProperty('opacity');\n }\n }\n\n // Only bake stop-local opacity into stop-opacity.\n // Inherited group opacity is already baked on drawable consumers via fill/stroke opacity.\n if (tag === 'stop' && ownOpacity < 0.999) {\n multiplySvgOpacityAttr(el, 'stop-opacity', ownOpacity);\n }\n\n for (let i = 0; i < el.children.length; i++) {\n walkAndBake(el.children[i], combinedOpacity);\n }\n }\n\n walkAndBake(svg, 1);\n}\n\n/** Match paint servers in fill/stroke like url(#id), url(\"#id\"), or url(\"https://...#id\"). */\nconst URL_GRADIENT_RE = /^\\s*url\\s*\\(\\s*(['\"]?)([^)]+?)\\1\\s*\\)/i;\n\nfunction extractGradientIdFromPaint(value: string | null): string | null {\n if (!value) return null;\n const match = value.trim().match(URL_GRADIENT_RE);\n if (!match) return null;\n const rawRef = (match[2] || '').trim();\n if (!rawRef) return null;\n\n // Support url(#id), url(\"#id\") and url(\"https://host/file.svg#id\")\n const hashIdx = rawRef.lastIndexOf('#');\n if (hashIdx < 0 || hashIdx === rawRef.length - 1) return null;\n\n const id = rawRef.slice(hashIdx + 1).trim();\n if (!id) return null;\n return id.replace(/[\\s\"')].*$/, '');\n}\n\nfunction normalizeGradientPaintRef(value: string): string {\n const id = extractGradientIdFromPaint(value);\n return id ? `url(#${id})` : value;\n}\n\n/** svg2pdf only accepts stop offsets in 0–1; convert percentage to decimal. */\nfunction normalizeSvgGradientStopOffsets(svg: Element): void {\n for (const stop of svg.querySelectorAll('linearGradient stop, radialGradient stop')) {\n const offset = stop.getAttribute('offset');\n if (!offset) continue;\n const trimmed = offset.trim();\n if (trimmed.endsWith('%')) {\n const num = parseFloat(trimmed.slice(0, -1)) / 100;\n if (Number.isFinite(num)) stop.setAttribute('offset', String(Math.max(0, Math.min(1, num))));\n }\n }\n}\n\nfunction decodeSvgDataUri(href: string): string | null {\n if (!href.startsWith('data:image/svg+xml')) return null;\n\n const commaIdx = href.indexOf(',');\n if (commaIdx < 0) return null;\n\n const meta = href.slice(0, commaIdx).toLowerCase();\n const payload = href.slice(commaIdx + 1);\n\n try {\n if (meta.includes(';base64')) {\n const binary = atob(payload);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return new TextDecoder('utf-8').decode(bytes);\n }\n return decodeURIComponent(payload);\n } catch {\n try {\n return atob(payload);\n } catch {\n return null;\n }\n }\n}\n\nfunction inlineNestedSvgImageDataUris(svgString: string, domParser = new DOMParser()): string {\n try {\n const doc = domParser.parseFromString(svgString, 'image/svg+xml');\n if (doc.querySelector('parsererror')) return svgString;\n\n const root = doc.documentElement;\n if (!root || root.tagName.toLowerCase() !== 'svg') return svgString;\n\n let changed = false;\n const images = Array.from(doc.querySelectorAll('image'));\n\n for (const img of images) {\n const href = img.getAttribute('href') || img.getAttributeNS('http://www.w3.org/1999/xlink', 'href');\n if (!href || !href.startsWith('data:image/svg+xml')) continue;\n\n try {\n const svgContent = decodeSvgDataUri(href);\n if (!svgContent || !/<svg[\\s>]/i.test(svgContent)) continue;\n\n const innerDoc = domParser.parseFromString(svgContent, 'image/svg+xml');\n if (innerDoc.querySelector('parsererror')) continue;\n const innerSvg = innerDoc.documentElement;\n if (!innerSvg || innerSvg.tagName.toLowerCase() !== 'svg') continue;\n\n const ix = parseFloat(img.getAttribute('x') || '0') || 0;\n const iy = parseFloat(img.getAttribute('y') || '0') || 0;\n const iw = parseFloat(img.getAttribute('width') || '0');\n const ih = parseFloat(img.getAttribute('height') || '0');\n if (!(iw > 0 && ih > 0)) continue;\n\n const nestedSvg = doc.importNode(innerSvg, true) as unknown as SVGElement;\n const vb = nestedSvg.getAttribute('viewBox');\n if (!vb) {\n nestedSvg.setAttribute('viewBox', `0 0 ${iw} ${ih}`);\n }\n nestedSvg.setAttribute('x', '0');\n nestedSvg.setAttribute('y', '0');\n nestedSvg.setAttribute('width', String(iw));\n nestedSvg.setAttribute('height', String(ih));\n nestedSvg.setAttribute(\n 'preserveAspectRatio',\n img.getAttribute('preserveAspectRatio') || nestedSvg.getAttribute('preserveAspectRatio') || 'xMidYMid meet'\n );\n\n const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g');\n const existingTransform = img.getAttribute('transform') || '';\n let transform = existingTransform;\n transform += `${transform ? ' ' : ''}translate(${ix},${iy})`;\n if (transform) {\n g.setAttribute('transform', transform);\n }\n\n const passthroughAttrs = new Set([\n 'id',\n 'class',\n 'style',\n 'opacity',\n 'display',\n 'visibility',\n 'clip-path',\n 'mask',\n 'filter',\n 'pointer-events',\n ]);\n Array.from(img.attributes).forEach((attr) => {\n if (passthroughAttrs.has(attr.name)) {\n g.setAttribute(attr.name, attr.value);\n }\n });\n\n g.appendChild(nestedSvg);\n\n img.parentNode?.replaceChild(g, img);\n changed = true;\n } catch {\n // Ignore nested SVGs we can't safely inline.\n }\n }\n\n return changed ? new XMLSerializer().serializeToString(doc.documentElement) : svgString;\n } catch {\n return svgString;\n }\n}\n\nfunction hasInvalidSvgNumericToken(value: string | null | undefined): value is string {\n return typeof value === 'string' && /\\b(?:NaN|-?Infinity|undefined|null)\\b/.test(value);\n}\n\nfunction sanitizeSvgNumericTokens(value: string): string {\n return value\n .replace(/\\bNaN\\b/g, '0')\n .replace(/\\b-?Infinity\\b/g, '0')\n .replace(/\\bundefined\\b/g, '0')\n .replace(/\\bnull\\b/g, '0');\n}\n\nfunction sanitizeSvgTreeForPdf(svg: Element): void {\n const attrsToSanitize = [\n 'd',\n 'points',\n 'transform',\n 'gradientTransform',\n 'patternTransform',\n 'viewBox',\n 'x',\n 'y',\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'cx',\n 'cy',\n 'r',\n 'rx',\n 'ry',\n 'width',\n 'height',\n 'dx',\n 'dy',\n 'opacity',\n 'fill-opacity',\n 'stroke-opacity',\n 'stroke-width',\n 'stroke-dashoffset',\n 'font-size',\n 'letter-spacing',\n 'word-spacing',\n ];\n\n const nodes = [svg, ...Array.from(svg.querySelectorAll('*'))];\n for (const node of nodes) {\n for (const attr of attrsToSanitize) {\n const value = node.getAttribute(attr);\n if (!hasInvalidSvgNumericToken(value)) continue;\n node.setAttribute(attr, sanitizeSvgNumericTokens(value));\n }\n }\n}\n\nfunction stripRootPageBackgroundFromSvg(svg: Element): void {\n const rootChildren = Array.from(svg.children);\n for (const child of rootChildren) {\n const tag = child.tagName.toLowerCase();\n if (tag !== 'rect' && tag !== 'path') continue;\n\n const x = Number.parseFloat(child.getAttribute('x') || '0');\n const y = Number.parseFloat(child.getAttribute('y') || '0');\n const width = Number.parseFloat(child.getAttribute('width') || '0');\n const height = Number.parseFloat(child.getAttribute('height') || '0');\n const fill = child.getAttribute('fill') || getInlineStyleValue(child, 'fill');\n const stroke = child.getAttribute('stroke') || getInlineStyleValue(child, 'stroke');\n const opacity = parseSvgOpacity(child.getAttribute('opacity')) ?? 1;\n\n const isFullPageRect =\n tag === 'rect' &&\n Math.abs(x) < 0.01 &&\n Math.abs(y) < 0.01 &&\n Math.abs(width - Number.parseFloat(svg.getAttribute('width') || '0')) < 0.5 &&\n Math.abs(height - Number.parseFloat(svg.getAttribute('height') || '0')) < 0.5;\n\n const isVisiblePaint = opacity > 0.0001 && !isTransparentColorToken(fill) && (!stroke || isTransparentColorToken(stroke));\n if (isFullPageRect && isVisiblePaint) {\n child.remove();\n return;\n }\n }\n}\n\nfunction stripSuspiciousFullPageOverlayNodes(svg: Element): void {\n const rootWidth = Number.parseFloat(svg.getAttribute('width') || '0');\n const rootHeight = Number.parseFloat(svg.getAttribute('height') || '0');\n const viewBox = (svg.getAttribute('viewBox') || '').trim().split(/[\\s,]+/).map((n) => Number.parseFloat(n));\n const pageWidth = Number.isFinite(rootWidth) && rootWidth > 0 ? rootWidth : (viewBox[2] || 0);\n const pageHeight = Number.isFinite(rootHeight) && rootHeight > 0 ? rootHeight : (viewBox[3] || 0);\n if (!(pageWidth > 0 && pageHeight > 0)) return;\n\n const isNear = (a: number, b: number, tolerance = 0.75) => Math.abs(a - b) <= tolerance;\n const hasVisibleStyleToken = (value: string | null, token: string) => {\n if (!value) return false;\n return new RegExp(`(?:^|;)\\\\s*${token}\\\\s*:\\\\s*([^;]+)`, 'i').test(value);\n };\n const hasHiddenDisplay = (el: Element) => {\n const display = (el.getAttribute('display') || getInlineStyleValue(el, 'display') || '').trim().toLowerCase();\n const visibility = (el.getAttribute('visibility') || getInlineStyleValue(el, 'visibility') || '').trim().toLowerCase();\n return display === 'none' || visibility === 'hidden';\n };\n const getNodeOpacity = (el: Element) => {\n return (\n parseSvgOpacity(el.getAttribute('opacity')) ??\n parseSvgOpacity(getInlineStyleValue(el, 'opacity')) ??\n 1\n );\n };\n const isDarkPaint = (value: string | null) => {\n const rgb = value ? parseColor(value) : null;\n if (!rgb) return false;\n return rgb.r <= 32 && rgb.g <= 32 && rgb.b <= 32;\n };\n const removeIfSuspicious = (el: Element) => {\n if (hasHiddenDisplay(el)) return;\n const opacity = getNodeOpacity(el);\n if (opacity <= 0.001) return;\n const fill = el.getAttribute('fill') || getInlineStyleValue(el, 'fill');\n const stroke = el.getAttribute('stroke') || getInlineStyleValue(el, 'stroke');\n if (!isDarkPaint(fill) && !isDarkPaint(stroke)) return;\n\n const width = Number.parseFloat(el.getAttribute('width') || '0');\n const height = Number.parseFloat(el.getAttribute('height') || '0');\n const x = Number.parseFloat(el.getAttribute('x') || '0');\n const y = Number.parseFloat(el.getAttribute('y') || '0');\n const isRectLike = el.tagName.toLowerCase() === 'rect' && isNear(x, 0) && isNear(y, 0) && isNear(width, pageWidth, 1.5) && isNear(height, pageHeight, 1.5);\n\n let isPathLike = false;\n if (el.tagName.toLowerCase() === 'path') {\n const d = (el.getAttribute('d') || '').replace(/\\s+/g, ' ').trim();\n isPathLike = !!d && (\n new RegExp(`^M\\s*0(?:\\.0+)?\\s+0(?:\\.0+)?\\s*H\\s*${Math.round(pageWidth)}(?:\\.0+)?\\s*V\\s*${Math.round(pageHeight)}(?:\\.0+)?\\s*H\\s*0(?:\\.0+)?\\s*Z?$`, 'i').test(d) ||\n new RegExp(`^M\\s*0(?:\\.0+)?\\s+0(?:\\.0+)?\\s*L\\s*${Math.round(pageWidth)}(?:\\.0+)?\\s+0(?:\\.0+)?\\s*L\\s*${Math.round(pageWidth)}(?:\\.0+)?\\s+${Math.round(pageHeight)}(?:\\.0+)?\\s*L\\s*0(?:\\.0+)?\\s+${Math.round(pageHeight)}(?:\\.0+)?\\s*Z?$`, 'i').test(d)\n );\n }\n\n const inlineStyle = el.getAttribute('style') || '';\n const likelyOverlay = isRectLike || isPathLike || hasVisibleStyleToken(inlineStyle, 'mix-blend-mode');\n if (likelyOverlay) {\n el.remove();\n }\n };\n\n // Check direct children AND children of top-level <g> wrappers (Fabric.js wraps elements in groups)\n const candidates: Element[] = [];\n for (const child of Array.from(svg.children)) {\n const tag = child.tagName.toLowerCase();\n if (tag === 'defs' || tag === 'style' || tag === 'title' || tag === 'desc' || tag === 'metadata') continue;\n if (tag === 'g') {\n // Also scan inside top-level groups for suspicious overlay rects\n for (const grandchild of Array.from(child.children)) {\n candidates.push(grandchild);\n }\n }\n candidates.push(child);\n }\n for (const el of candidates) {\n removeIfSuspicious(el);\n }\n}\n\n// ─── Text Decoration → Explicit Lines ───\n// svg2pdf.js does NOT support text-decoration on <tspan>/<text> elements.\n// Fabric.js toSVG() outputs text-decoration=\"underline\" on tspans.\n// This converts those decorations into explicit <line> elements.\n\nasync function convertTextDecorationsToLines(svg: Element): Promise<void> {\n // (function continues below)\n return _convertTextDecorationsToLines_impl(svg);\n}\n\n// ─── v0.5.131 PARITY FIX (text-anchor → start, baked from canvas measurement) ─\n// Root cause of the centered-text horizontal drift between the on-screen\n// canvas preview and the client-side vector PDF:\n//\n// Fabric writes <text x=\"cx\" text-anchor=\"middle\">. Fabric chose `cx`\n// from the BROWSER's canvas `measureText` width when it drew the preview.\n// Inside the PDF pipeline:\n// • svg2pdf re-resolves the leftmost glyph x as `cx - jsPDF.getTextWidth(...)/2`.\n// • opentype-based outlining (`svgTextToPath.ts`) does the same with\n// `cx - opentypeAdvance/2`.\n// Both width sources differ slightly from the browser's `measureText`\n// (especially for decorative fonts like GreatVibes / Cinzel / Pacifico),\n// so centered text lands a few px off horizontally — and any shadow,\n// background fill, or padding effect inherits the same drift.\n//\n// Fix: BEFORE we hand the SVG to svg2pdf or the outliner, mount a clone in\n// the live DOM (with the real web-fonts loaded), read the actual rendered\n// `getStartPositionOfChar(0).x` for every <text>/<tspan> with\n// text-anchor in {middle,end}, write that x back as the element's `x`\n// attribute, and switch the anchor to `start`. After this, no downstream\n// width math matters — the leftmost glyph is anchored at the exact\n// position the canvas preview placed it.\nexport async function bakeTextAnchorPositionsFromLiveSvg(svg: Element): Promise<void> {\n if (typeof document === 'undefined' || typeof window === 'undefined') return;\n if (!svg) return;\n\n const _resolveAnchor = (el: Element): string => {\n let cur: Element | null = el;\n while (cur) {\n const a = cur.getAttribute('text-anchor');\n if (a) return a.trim().toLowerCase();\n const style = cur.getAttribute('style') || '';\n const m = style.match(/(?:^|;)\\s*text-anchor\\s*:\\s*([^;]+)/i);\n if (m) return m[1].trim().toLowerCase();\n cur = cur.parentElement;\n }\n return 'start';\n };\n\n // Cheap pre-check: if there's no centered/end anchor anywhere, skip the\n // whole DOM-mount round-trip.\n const allTextish = Array.from(svg.querySelectorAll('text, tspan'));\n let needsBake = false;\n for (const el of allTextish) {\n const a = _resolveAnchor(el);\n if (a === 'middle' || a === 'end') { needsBake = true; break; }\n }\n if (!needsBake) return;\n\n // Make sure web-fonts referenced by the SVG are actually loaded so\n // measureText / getStartPositionOfChar use the same metrics the canvas\n // preview used. Same approach as `convertTextDecorationsToLines`.\n //\n // CENTER-PARITY FIX (v0.5.142): `document.fonts.ready` only resolves the\n // CURRENTLY-loading set. A FontFace registered via `new FontFace(...)` +\n // `document.fonts.add(...)` stays in `unloaded` state until something\n // actually requests it. On the server (puppeteer) Fabric's canvas measure\n // pulled in some weights but not the exact `font-weight` written into the\n // SVG (e.g. weight=600 when only 400 was registered as a non-aliased face).\n // The cloned SVG then renders that tspan with a SYSTEM fallback, so\n // `getStartPositionOfChar(0).x` returns a different start than the client\n // (which has those weights pre-loaded via the site-level Google Fonts\n // <link>). Explicitly call `document.fonts.load(...)` for every\n // family/weight/style triple referenced by the SVG before measuring so\n // BOTH environments see identical glyph metrics.\n try {\n if ((document as any).fonts) {\n const loadKeys = new Set<string>();\n for (const tn of svg.querySelectorAll('text, tspan, textPath')) {\n const ff =\n tn.getAttribute('data-source-font-family') ||\n tn.getAttribute('font-family');\n if (!ff) continue;\n const fw =\n tn.getAttribute('data-source-font-weight') ||\n tn.getAttribute('font-weight') ||\n '400';\n const fs =\n tn.getAttribute('data-source-font-style') ||\n tn.getAttribute('font-style') ||\n 'normal';\n const cleanFamily = ff.replace(/['\"]/g, '').trim();\n if (!cleanFamily) continue;\n loadKeys.add(`${fs} ${fw} 16px \"${cleanFamily}\"`);\n }\n const loads: Promise<unknown>[] = [];\n for (const spec of loadKeys) {\n try {\n loads.push((document as any).fonts.load(spec).catch(() => {}));\n } catch { /* noop */ }\n }\n if (loads.length > 0) await Promise.all(loads);\n if ((document as any).fonts?.ready) await (document as any).fonts.ready;\n }\n } catch { /* noop */ }\n\n const tempContainer = document.createElement('div');\n tempContainer.style.cssText =\n 'position:fixed;left:-9999px;top:-9999px;visibility:hidden;pointer-events:none;';\n const clone = svg.cloneNode(true) as Element;\n // Apply the original (data-source-*) font attributes that Fabric stamped on\n // each text node, so the live measurement uses the SAME family/weight/style\n // the on-screen preview used.\n for (const tn of clone.querySelectorAll('text, tspan, textPath')) {\n const sf = tn.getAttribute('data-source-font-family');\n const sw = tn.getAttribute('data-source-font-weight');\n const ss = tn.getAttribute('data-source-font-style');\n if (sf) tn.setAttribute('font-family', sf);\n if (sw) tn.setAttribute('font-weight', sw);\n if (ss) tn.setAttribute('font-style', ss);\n const inlineStyle = tn.getAttribute('style') || '';\n if (sf || sw || ss) {\n const stylePairs = inlineStyle\n .split(';')\n .map((p) => p.trim())\n .filter(Boolean)\n .filter((p) => !/^font-(family|weight|style)\\s*:/i.test(p));\n if (sf) stylePairs.push(`font-family: ${sf}`);\n if (sw) stylePairs.push(`font-weight: ${sw}`);\n if (ss) stylePairs.push(`font-style: ${ss}`);\n if (stylePairs.length > 0) tn.setAttribute('style', stylePairs.join('; '));\n }\n }\n tempContainer.appendChild(clone);\n document.body.appendChild(tempContainer);\n\n let baked = 0;\n // Canvas2D measureText is deterministic and matches Fabric's measurement\n // (which the parity log confirms is byte-identical between client and\n // server). We use it as the primary source of truth for width, falling\n // back to DOM `getStartPositionOfChar` only if the canvas context is\n // unavailable. This eliminates a class of client/server centering drift\n // caused by paint-cycle delays in headless browsers where the live SVG\n // <text> hasn't yet picked up the freshly loaded FontFace even though\n // Canvas2D has — leading to subtly different `getStartPositionOfChar`\n // values vs the client.\n const _measureCanvas = (typeof document !== 'undefined') ? document.createElement('canvas') : null;\n const _mctx = _measureCanvas?.getContext('2d') || null;\n const _resolveFontSize = (node: Element): number => {\n let cur: Element | null = node;\n while (cur) {\n const fs = cur.getAttribute('font-size');\n if (fs) {\n const n = parseFloat(fs);\n if (Number.isFinite(n) && n > 0) return n;\n }\n cur = cur.parentElement;\n }\n return 16;\n };\n const _resolveFontAttr = (node: Element, attr: string, fallback: string): string => {\n let cur: Element | null = node;\n while (cur) {\n const v = cur.getAttribute(`data-source-${attr}`) || cur.getAttribute(attr);\n if (v) return v;\n cur = cur.parentElement;\n }\n return fallback;\n };\n const _measureWidthCanvas = (srcNode: Element, content: string): number | null => {\n if (!_mctx || !content) return null;\n const family = _resolveFontAttr(srcNode, 'font-family', '').replace(/['\"]/g, '').trim();\n const weight = _resolveFontAttr(srcNode, 'font-weight', '400');\n const style = _resolveFontAttr(srcNode, 'font-style', 'normal');\n const size = _resolveFontSize(srcNode);\n if (!family) return null;\n try {\n _mctx.font = `${style} ${weight} ${size}px \"${family}\"`;\n const w = _mctx.measureText(content).width;\n return Number.isFinite(w) && w > 0 ? w : null;\n } catch { return null; }\n };\n try {\n const srcTexts = Array.from(svg.querySelectorAll('text'));\n const liveTexts = Array.from(clone.querySelectorAll('text')) as SVGTextElement[];\n for (let i = 0; i < srcTexts.length; i++) {\n const srcText = srcTexts[i];\n const liveText = liveTexts[i];\n if (!liveText) continue;\n const srcTspans = Array.from(srcText.querySelectorAll('tspan'));\n const liveTspans = Array.from(liveText.querySelectorAll('tspan')) as SVGTSpanElement[];\n\n const stripTextAnchorStyle = (node: Element) => {\n const style = node.getAttribute('style') || '';\n if (!/text-anchor\\s*:/i.test(style)) return;\n const cleaned = style\n .split(';')\n .map((p) => p.trim())\n .filter(Boolean)\n .filter((p) => !/^text-anchor\\s*:/i.test(p))\n .join('; ');\n if (cleaned) node.setAttribute('style', cleaned);\n else node.removeAttribute('style');\n };\n\n const readInheritedX = (node: Element): number => {\n let cur: Element | null = node;\n while (cur) {\n const v = cur.getAttribute('x');\n if (v) {\n const parsed = parseFloat(v.split(/[\\s,]+/)[0]);\n return Number.isFinite(parsed) ? parsed : NaN;\n }\n cur = cur.parentElement;\n }\n return NaN;\n };\n\n const bakeNode = (srcNode: Element, liveNode: any, anchorOverride?: string, refXOverride?: number) => {\n const anchor = (anchorOverride || _resolveAnchor(srcNode)).trim().toLowerCase();\n if (anchor !== 'middle' && anchor !== 'end') return;\n const stampedWidth = parseFloat(srcNode.getAttribute('data-pd-line-width') || '');\n const stampedStart = parseFloat(srcNode.getAttribute('data-pd-line-start') || '');\n if (Number.isFinite(stampedWidth) && stampedWidth > 0 && Number.isFinite(stampedStart)) {\n srcNode.setAttribute('x', String(stampedStart));\n srcNode.setAttribute('text-anchor', 'start');\n srcNode.setAttribute('textLength', String(stampedWidth));\n srcNode.setAttribute('lengthAdjust', 'spacing');\n stripTextAnchorStyle(srcNode);\n baked++;\n return;\n }\n // PRIMARY: compute new x from Canvas2D measureText. Fabric uses\n // Canvas2D for its measurement so this matches exactly what the\n // editor / preview rendered. Source x for middle anchor is the\n // center reference; for end anchor it's the right edge.\n try {\n const content = (srcNode.textContent || '');\n if (content.length > 0) {\n const width = _measureWidthCanvas(srcNode, content);\n // Resolve the reference x from the ORIGINAL source SVG (the value\n // Fabric wrote alongside text-anchor). For multi-line Textbox SVGs,\n // child <tspan>s often inherit x from the parent <text>; never read\n // that parent after mutating it, otherwise every line bakes from the\n // already-shifted first line and drifts left on server exports.\n const refX = Number.isFinite(refXOverride as number) ? (refXOverride as number) : readInheritedX(srcNode);\n if (width !== null && Number.isFinite(refX)) {\n const newX = anchor === 'middle' ? refX - width / 2 : refX - width;\n srcNode.setAttribute('x', String(newX));\n srcNode.setAttribute('text-anchor', 'start');\n stripTextAnchorStyle(srcNode);\n baked++;\n return;\n }\n }\n } catch { /* fall through to DOM measurement */ }\n try {\n const n = typeof liveNode.getNumberOfChars === 'function' ? liveNode.getNumberOfChars() : 0;\n if (!n) return;\n const start = liveNode.getStartPositionOfChar(0);\n if (!Number.isFinite(start?.x)) return;\n // Write the absolute glyph-start x back. Drop any inherited anchor\n // and any inline-style anchor so the new `start` anchor sticks.\n srcNode.setAttribute('x', String(start.x));\n srcNode.setAttribute('text-anchor', 'start');\n stripTextAnchorStyle(srcNode);\n baked++;\n } catch { /* live node not measurable — leave as-is */ }\n };\n\n if (srcTspans.length > 0) {\n const parentAnchor = _resolveAnchor(srcText);\n const tspanAnchors = srcTspans.map((tspan) => _resolveAnchor(tspan));\n const parentRefX = readInheritedX(srcText);\n const tspanRefXs = srcTspans.map((tspan) => readInheritedX(tspan));\n // Multi-line Fabric Textbox SVGs put each visual line in a <tspan>.\n // Bake each line independently from the unmodified parent center x;\n // do NOT bake the parent using concatenated textContent because that\n // corrupts the inherited x used by following tspans.\n for (let j = 0; j < srcTspans.length; j++) {\n const refX = Number.isFinite(tspanRefXs[j]) ? tspanRefXs[j] : parentRefX;\n if (liveTspans[j]) bakeNode(srcTspans[j], liveTspans[j], tspanAnchors[j] || parentAnchor, refX);\n }\n if (parentAnchor === 'middle' || parentAnchor === 'end') {\n srcText.setAttribute('text-anchor', 'start');\n stripTextAnchorStyle(srcText);\n }\n } else {\n bakeNode(srcText, liveText);\n }\n }\n } finally {\n try { document.body.removeChild(tempContainer); } catch { /* noop */ }\n }\n\n if (baked > 0) {\n try {\n console.log(`[Vector PDF][parity] baked text-anchor → start on ${baked} node(s) using live canvas measurement`);\n } catch { /* noop */ }\n }\n}\n\n\n/**\n * DIAGNOSTIC (temp v0.5.145): log per-<text> width measurements from THREE\n * sources so we can pinpoint exactly where client-vs-server PDF disparity\n * comes from on real exports. Output goes through console.log so it shows\n * in both the browser devtools AND puppeteer's `[browser:log]` capture on\n * the EC2 server — making client/server numbers directly comparable.\n *\n * • dom = getStartPositionOfChar(0).x of the live-mounted SVG\n * (what bakeTextAnchorPositionsFromLiveSvg writes back).\n * • measureCtx = canvas2d measureText(textContent).width of the same\n * string at the same font/size — the metric Fabric used\n * when it wrote text-anchor + x in toSVG().\n * • bbox = getBBox().width of the live-mounted node.\n * • srcAnchor / srcX = original anchor + x stamped by Fabric (pre-bake).\n *\n * Removable diagnostic — wrap behind `?pdfdiag=1` URL param so it doesn't\n * spam normal exports.\n */\nexport async function logTextMeasurementDiagnostic(svg: Element): Promise<void> {\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\n try {\n const params = new URLSearchParams(window.location?.search || '');\n if (params.get('pdfdiag') !== '1') return;\n } catch { return; }\n if (!svg) return;\n\n const tempContainer = document.createElement('div');\n tempContainer.style.cssText =\n 'position:fixed;left:-9999px;top:-9999px;visibility:hidden;pointer-events:none;';\n const clone = svg.cloneNode(true) as Element;\n for (const tn of clone.querySelectorAll('text, tspan, textPath')) {\n const sf = tn.getAttribute('data-source-font-family');\n const sw = tn.getAttribute('data-source-font-weight');\n const ss = tn.getAttribute('data-source-font-style');\n if (sf) tn.setAttribute('font-family', sf);\n if (sw) tn.setAttribute('font-weight', sw);\n if (ss) tn.setAttribute('font-style', ss);\n }\n tempContainer.appendChild(clone);\n document.body.appendChild(tempContainer);\n\n const measureCanvas = document.createElement('canvas');\n const mctx = measureCanvas.getContext('2d');\n\n try {\n const liveTexts = Array.from(clone.querySelectorAll('text')) as SVGTextElement[];\n const srcTexts = Array.from(svg.querySelectorAll('text'));\n const rows: any[] = [];\n for (let i = 0; i < liveTexts.length; i++) {\n const live = liveTexts[i];\n const src = srcTexts[i];\n if (!live || !src) continue;\n const liveTspans = Array.from(live.querySelectorAll('tspan')) as SVGTSpanElement[];\n const srcTspans = Array.from(src.querySelectorAll('tspan'));\n const tspans = liveTspans.length ? liveTspans : [live as any];\n const srcs = srcTspans.length ? srcTspans : [src];\n for (let j = 0; j < tspans.length; j++) {\n const ln = tspans[j];\n const sn = srcs[j];\n const text = ln.textContent || '';\n const fam = (ln.getAttribute('font-family') || '').replace(/['\"]/g, '').trim();\n const wt = ln.getAttribute('font-weight') || '400';\n const sty = ln.getAttribute('font-style') || 'normal';\n const sz = parseFloat(ln.getAttribute('font-size') || src.getAttribute('font-size') || '16') || 16;\n let domX: number | null = null;\n let bboxW: number | null = null;\n try {\n if ((ln as any).getNumberOfChars && (ln as any).getNumberOfChars() > 0) {\n domX = (ln as any).getStartPositionOfChar(0).x;\n }\n } catch {}\n try { bboxW = (ln as any).getBBox?.().width ?? null; } catch {}\n let canvasW: number | null = null;\n if (mctx) {\n mctx.font = `${sty} ${wt} ${sz}px \"${fam}\"`;\n try { canvasW = mctx.measureText(text).width; } catch {}\n }\n rows.push({\n line: text.length > 40 ? text.slice(0, 37) + '...' : text,\n font: `${fam} ${wt} ${sty}`,\n size: sz,\n srcAnchor: sn.getAttribute('text-anchor') || sn.parentElement?.getAttribute('text-anchor') || '',\n srcX: sn.getAttribute('x') || sn.parentElement?.getAttribute('x') || '',\n domX: domX !== null ? +domX.toFixed(2) : null,\n bboxW: bboxW !== null ? +bboxW.toFixed(2) : null,\n measureCtxW: canvasW !== null ? +canvasW.toFixed(2) : null,\n });\n }\n }\n if (rows.length > 0) {\n console.log('[PDF-DIAG] ===== text measurement diagnostic =====');\n console.log('[PDF-DIAG] env=', typeof navigator !== 'undefined' ? navigator.userAgent.slice(0, 80) : 'n/a',\n 'dpr=', window.devicePixelRatio,\n 'fontsReady=', !!(document as any).fonts?.ready);\n for (const r of rows) {\n console.log('[PDF-DIAG]', JSON.stringify(r));\n }\n console.log('[PDF-DIAG] ===== end =====');\n }\n } finally {\n try { document.body.removeChild(tempContainer); } catch {}\n }\n}\n\nasync function _convertTextDecorationsToLines_impl(svg: Element): Promise<void> {\n const doc = svg.ownerDocument;\n if (!doc) return;\n\n const resolveInheritedSvgValue = (el: Element, attr: string, styleProp = attr): string | null => {\n let current: Element | null = el;\n while (current) {\n const attrValue = current.getAttribute(attr)?.trim();\n if (attrValue) return attrValue;\n const styleValue = getInlineStyleValue(current, styleProp)?.trim();\n if (styleValue) return styleValue;\n current = current.parentElement;\n }\n return null;\n };\n\n // Ensure all fonts used in the SVG are loaded before measuring text widths.\n // Without this, Canvas 2D measureText and SVG getComputedTextLength both\n // return inaccurate (shorter) values because the browser uses a fallback font.\n if (typeof document !== 'undefined' && document.fonts) {\n // Collect unique font families from text elements\n const fontFamilies = new Set<string>();\n for (const textEl of svg.querySelectorAll('text')) {\n const ff = textEl.getAttribute('data-source-font-family') || textEl.getAttribute('font-family');\n if (ff) fontFamilies.add(ff.replace(/'/g, ''));\n for (const tspan of textEl.querySelectorAll('tspan')) {\n const tff = tspan.getAttribute('data-source-font-family') || tspan.getAttribute('font-family');\n if (tff) fontFamilies.add(tff.replace(/'/g, ''));\n }\n }\n // Load each font (triggers Google Fonts fetch if needed)\n const loadPromises: Promise<void>[] = [];\n for (const ff of fontFamilies) {\n if (!document.fonts.check(`16px \"${ff}\"`)) {\n loadPromises.push(\n document.fonts.load(`16px \"${ff}\"`).then(() => {}).catch(() => {})\n );\n loadPromises.push(\n document.fonts.load(`bold 16px \"${ff}\"`).then(() => {}).catch(() => {})\n );\n }\n }\n if (loadPromises.length > 0) {\n await Promise.all(loadPromises);\n }\n await document.fonts.ready;\n }\n\n // To get accurate text widths we temporarily insert the SVG into the real DOM\n // so that SVG's native getComputedTextLength() works with the loaded Google Fonts.\n let tempContainer: HTMLDivElement | null = null;\n let liveSvg: Element | null = null;\n try {\n if (typeof document !== 'undefined') {\n tempContainer = document.createElement('div');\n tempContainer.style.cssText = 'position:fixed;left:-9999px;top:-9999px;visibility:hidden;pointer-events:none;';\n document.body.appendChild(tempContainer);\n const clone = svg.cloneNode(true) as Element;\n for (const textNode of clone.querySelectorAll('text, tspan, textPath')) {\n const sourceFamily = textNode.getAttribute('data-source-font-family');\n const sourceWeight = textNode.getAttribute('data-source-font-weight');\n const sourceStyle = textNode.getAttribute('data-source-font-style');\n if (sourceFamily) textNode.setAttribute('font-family', sourceFamily);\n if (sourceWeight) textNode.setAttribute('font-weight', sourceWeight);\n if (sourceStyle) textNode.setAttribute('font-style', sourceStyle);\n\n const inlineStyle = textNode.getAttribute('style') || '';\n const stylePairs = inlineStyle\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .filter((part) => !/^font-family\\s*:/i.test(part) && !/^font-weight\\s*:/i.test(part) && !/^font-style\\s*:/i.test(part));\n if (sourceFamily) stylePairs.push(`font-family: ${sourceFamily}`);\n if (sourceWeight) stylePairs.push(`font-weight: ${sourceWeight}`);\n if (sourceStyle) stylePairs.push(`font-style: ${sourceStyle}`);\n if (stylePairs.length > 0) textNode.setAttribute('style', stylePairs.join('; '));\n }\n tempContainer.appendChild(clone);\n liveSvg = clone;\n }\n } catch { /* noop */ }\n\n // Canvas 2D for measurement (matches server/EC2 pipeline)\n let ctx: CanvasRenderingContext2D | null = null;\n try {\n const realDoc = typeof document !== 'undefined' ? document : doc;\n const measureCanvas = realDoc.createElement('canvas') as HTMLCanvasElement;\n ctx = measureCanvas.getContext('2d');\n } catch { /* noop */ }\n\n const textEls = Array.from(svg.querySelectorAll('text'));\n // If we have a live clone, query that in parallel for measurement\n const liveTextEls = liveSvg ? Array.from(liveSvg.querySelectorAll('text')) : null;\n\n for (let ti = 0; ti < textEls.length; ti++) {\n const textEl = textEls[ti];\n const liveTextEl = liveTextEls?.[ti] as SVGTextElement | undefined;\n const tspans = Array.from(textEl.querySelectorAll('tspan'));\n if (tspans.length === 0) continue;\n const liveTspans = liveTextEl ? Array.from(liveTextEl.querySelectorAll('tspan')) as SVGTSpanElement[] : null;\n\n const textDecOnText = (textEl.getAttribute('text-decoration') || '').toLowerCase();\n const textStyleDec = (getInlineStyleValue(textEl, 'text-decoration') || '').toLowerCase();\n const textHasUnderline = textDecOnText.includes('underline') || textStyleDec.includes('underline');\n const textHasLinethrough = textDecOnText.includes('line-through') || textStyleDec.includes('line-through');\n\n for (let si = 0; si < tspans.length; si++) {\n const tspan = tspans[si];\n const liveTspan = liveTspans?.[si];\n const tspanDec = (tspan.getAttribute('text-decoration') || '').toLowerCase();\n const tspanStyleDec = (getInlineStyleValue(tspan, 'text-decoration') || '').toLowerCase();\n const hasUnderline = tspanDec.includes('underline') || tspanStyleDec.includes('underline') || textHasUnderline;\n const hasLinethrough = tspanDec.includes('line-through') || tspanStyleDec.includes('line-through') || textHasLinethrough;\n\n if (!hasUnderline && !hasLinethrough) continue;\n\n const content = tspan.textContent || '';\n if (!content.trim()) continue;\n\n const xAttr = tspan.getAttribute('x') ?? textEl.getAttribute('x') ?? '0';\n const yAttr = tspan.getAttribute('y') ?? textEl.getAttribute('y') ?? '0';\n const x = parseFloat(xAttr) || 0;\n const y = parseFloat(yAttr) || 0;\n\n const fontSize = parseFloat(\n tspan.getAttribute('font-size') || textEl.getAttribute('font-size') || '16'\n );\n const fontFamily =\n tspan.getAttribute('data-source-font-family') ||\n textEl.getAttribute('data-source-font-family') ||\n resolveInheritedSvgValue(tspan, 'font-family') ||\n 'sans-serif';\n const fontWeight =\n tspan.getAttribute('data-source-font-weight') ||\n textEl.getAttribute('data-source-font-weight') ||\n resolveInheritedSvgValue(tspan, 'font-weight') ||\n 'normal';\n const fontStyle =\n tspan.getAttribute('data-source-font-style') ||\n textEl.getAttribute('data-source-font-style') ||\n resolveInheritedSvgValue(tspan, 'font-style') ||\n 'normal';\n // Resolve fill via attribute AND inline style up the inheritance chain.\n // Fabric.js writes the text color as `style=\"fill: rgb(...)\"` on <text>,\n // which is *not* picked up by getAttribute('fill'). Falling back to\n // '#000000' caused underlines to render black regardless of the text\n // color. Walk the chain so the underline matches the glyph color.\n const fill =\n tspan.getAttribute('fill') ||\n getInlineStyleValue(tspan, 'fill') ||\n resolveInheritedSvgValue(tspan, 'fill') ||\n textEl.getAttribute('fill') ||\n getInlineStyleValue(textEl, 'fill') ||\n '#000000';\n const fillOpacity =\n tspan.getAttribute('fill-opacity') ||\n getInlineStyleValue(tspan, 'fill-opacity') ||\n resolveInheritedSvgValue(tspan, 'fill-opacity') ||\n textEl.getAttribute('fill-opacity') ||\n getInlineStyleValue(textEl, 'fill-opacity') ||\n null;\n\n // Canvas-based fallback width — only used if the live SVG is not\n // available (e.g. when running outside a browser DOM).\n let textWidth = content.length * fontSize * 0.6;\n if (ctx) {\n ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily.replace(/'/g, '')}`;\n textWidth = ctx.measureText(content).width;\n }\n\n const textAnchorRaw = (resolveInheritedSvgValue(tspan, 'text-anchor') || 'start').toLowerCase();\n const textAnchor = textAnchorRaw === 'middle' || textAnchorRaw === 'end' ? textAnchorRaw : 'start';\n let lineStartX = x - (textAnchor === 'middle' ? textWidth / 2 : textAnchor === 'end' ? textWidth : 0);\n let lineEndX = lineStartX + textWidth;\n let baselineY = y;\n\n // Source of truth: the live SVG's per-glyph caret positions. This\n // exactly mirrors what Fabric's canvas `_renderTextDecoration` paints\n // from `__charBounds` (sum of glyph advances — NOT including italic\n // overhang or trailing-space padding). Using getBBox() OR `Math.max`\n // against canvas measureText would over-extend the underline past the\n // actual glyph endpoints, especially for italic — the bug the user\n // reported. We deliberately do NOT clamp with bbox/canvas width here.\n if (liveTspan) {\n try {\n const liveCharCount = liveTspan.getNumberOfChars();\n if (liveCharCount > 0) {\n const start = liveTspan.getStartPositionOfChar(0);\n const end = liveTspan.getEndPositionOfChar(liveCharCount - 1);\n if (Number.isFinite(start.x)) lineStartX = start.x;\n if (Number.isFinite(start.y)) baselineY = start.y;\n if (Number.isFinite(end.x)) lineEndX = end.x;\n if (Number.isFinite(end.y) && !Number.isFinite(baselineY)) baselineY = end.y;\n } else {\n const svgWidth = liveTspan.getComputedTextLength();\n if (Number.isFinite(svgWidth) && svgWidth > 0) {\n textWidth = svgWidth;\n lineEndX = lineStartX + textWidth;\n }\n }\n } catch { /* fall back to canvas width */ }\n }\n\n if (!(lineEndX > lineStartX)) {\n lineStartX = x - (textAnchor === 'middle' ? textWidth / 2 : textAnchor === 'end' ? textWidth : 0);\n lineEndX = lineStartX + textWidth;\n }\n\n const thickness = Math.max(0.5, fontSize * 0.066667);\n const strokeColor = fill.startsWith('url(') ? '#000000' : fill;\n const decorations: number[] = [];\n if (hasUnderline) decorations.push(baselineY + fontSize * 0.15);\n if (hasLinethrough) decorations.push(baselineY - fontSize * 0.3);\n for (const decoY of decorations) {\n const line = doc.createElementNS('http://www.w3.org/2000/svg', 'line');\n line.setAttribute('x1', String(lineStartX));\n line.setAttribute('y1', String(decoY));\n line.setAttribute('x2', String(lineEndX));\n line.setAttribute('y2', String(decoY));\n line.setAttribute('stroke', strokeColor);\n line.setAttribute('stroke-width', String(thickness));\n line.setAttribute('stroke-linecap', 'butt');\n line.setAttribute('fill', 'none');\n if (fillOpacity) line.setAttribute('stroke-opacity', fillOpacity);\n if (textEl.parentElement) {\n textEl.parentElement.insertBefore(line, textEl.nextSibling);\n }\n }\n }\n }\n\n // Clean up temporary DOM node\n if (tempContainer) {\n try { document.body.removeChild(tempContainer); } catch { /* noop */ }\n }\n}\n\n// ─── String wrapper for the underline conversion ───\n// Parses an SVG string, runs `convertTextDecorationsToLines` on the live\n// document, and serializes back. Used by callers (e.g. UsePackage) to insert\n// explicit <line> underlines BEFORE text-to-path outlining destroys the\n// `text-decoration` metadata on <text>/<tspan> nodes.\nexport async function convertSvgTextDecorationsToLinesString(svgStr: string): Promise<string> {\n if (typeof DOMParser === 'undefined' || typeof XMLSerializer === 'undefined') {\n return svgStr;\n }\n if (!/text-decoration/i.test(svgStr) && !/underline/i.test(svgStr)) {\n return svgStr;\n }\n try {\n const parser = new DOMParser();\n const docEl = parser.parseFromString(svgStr, 'image/svg+xml');\n const rootSvg = docEl.documentElement;\n if (!rootSvg) return svgStr;\n await convertTextDecorationsToLines(rootSvg as unknown as Element);\n const serializer = new XMLSerializer();\n return serializer.serializeToString(rootSvg);\n } catch {\n return svgStr;\n }\n}\n\n// ─── Text Shadow Raster Markers ───\n// svg2pdf.js does not render SVG filters (`feGaussianBlur`), so blur > 0 text\n// shadows cannot stay as real vector blur in the generated PDF. The editor's\n// `toSVG()` emits `__pdShadowRaster` placeholders for those layers; this step\n// converts only the soft shadow layer into a transparent PNG and keeps the real\n// text/background as vector.\nasync function rasterizeShadowMarkers(svg: SVGElement): Promise<void> {\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\n const markers = Array.from(svg.querySelectorAll('g.__pdShadowRaster')) as SVGGElement[];\n if (markers.length === 0) return;\n\n const SVG_NS = 'http://www.w3.org/2000/svg';\n const XLINK_NS = 'http://www.w3.org/1999/xlink';\n\n try { if ((document as any).fonts?.ready) await (document as any).fonts.ready; } catch { /* noop */ }\n // Inline @font-face URL() refs as base64 data URIs so the offscreen <img>\n // (loaded from a blob:) can render with the correct fonts. Without this\n // step the browser falls back to a default sans-serif inside the blob,\n // producing a shadow that looks smaller / narrower than the real text.\n const fontFaceCss = await collectInlinedFontFaceCss();\n\n for (const marker of markers) {\n try {\n const blur = parseFloat(marker.getAttribute('data-blur') || '0');\n const ox = parseFloat(marker.getAttribute('data-ox') || '0');\n const oy = parseFloat(marker.getAttribute('data-oy') || '0');\n const bx = parseFloat(marker.getAttribute('data-bx') || '0');\n const by = parseFloat(marker.getAttribute('data-by') || '0');\n const bw = parseFloat(marker.getAttribute('data-bw') || '0');\n const bh = parseFloat(marker.getAttribute('data-bh') || '0');\n\n if (!Number.isFinite(bw) || !Number.isFinite(bh) || bw <= 0 || bh <= 0) {\n marker.parentNode?.removeChild(marker);\n continue;\n }\n\n const innerXml = restoreSourceFontsForShadowRaster(\n Array.from(marker.childNodes)\n .map((n) => (n instanceof Element ? new XMLSerializer().serializeToString(n) : ''))\n .join(''),\n );\n\n // ── Race-condition guard: explicitly load every font referenced inside\n // this marker BEFORE rasterizing. Without this, on the user's browser\n // (where `document.fonts.ready` can resolve before custom fonts like\n // Excon/Fontshare are fully loaded) the offscreen <img> paints the\n // shadow silhouette with a fallback font whose wider glyphs merge\n // adjacent lines into solid horizontal bars instead of per-line halos.\n // Puppeteer (server) preloads Google Fonts via the harness, so the\n // bug was only visible in client-side exports. Mirrors the fix in\n // packages/canvas-renderer/src/pdf-export.ts.\n try {\n const fontSpecs = collectFontSpecsFromShadowMarkup(innerXml);\n if (fontSpecs.length > 0 && (document as any).fonts?.load) {\n await Promise.all(\n fontSpecs.map((spec) =>\n (document as any).fonts.load(spec).catch(() => undefined),\n ),\n );\n }\n } catch { /* noop */ }\n\n const scale = 2;\n const pxW = Math.min(4096, Math.max(8, Math.ceil(bw * scale)));\n const pxH = Math.min(4096, Math.max(8, Math.ceil(bh * scale)));\n // Canvas2D `shadowBlur` is roughly 2× SVG `feGaussianBlur stdDeviation`\n // (Canvas spec uses a Gaussian where the blur radius ≈ 2σ). Without\n // this conversion the rasterized PDF shadow spreads ~2× wider than the\n // canvas preview at the same blur value.\n const stdDev = Math.max(0, blur / 2);\n const filterId = `pdShadowBlur_${Math.random().toString(36).slice(2, 9)}`;\n const styleBlock = fontFaceCss ? `<style>${fontFaceCss}</style>` : '';\n // The filter region MUST cover the entire viewBox — otherwise the blurred\n // output is clipped at the source bbox and produces a hard rectangular\n // edge in the rasterized PNG. We anchor the filter region to the viewBox\n // in absolute user-space coordinates so it always matches no matter how\n // small the inner geometry is relative to the padded canvas.\n const miniSvg =\n `<svg xmlns=\"${SVG_NS}\" xmlns:xlink=\"${XLINK_NS}\" width=\"${pxW}\" height=\"${pxH}\" viewBox=\"${bx} ${by} ${bw} ${bh}\">` +\n `${styleBlock}<defs><filter id=\"${filterId}\" filterUnits=\"userSpaceOnUse\" x=\"${bx}\" y=\"${by}\" width=\"${bw}\" height=\"${bh}\" color-interpolation-filters=\"sRGB\">` +\n `<feOffset dx=\"${ox}\" dy=\"${oy}\" result=\"offsetShadow\" />` +\n `<feGaussianBlur in=\"offsetShadow\" stdDeviation=\"${stdDev}\" />` +\n `</filter></defs><g filter=\"url(#${filterId})\">${innerXml}</g></svg>`;\n\n const dataUrl = await rasterSvgToPngDataUrl(miniSvg, pxW, pxH);\n if (!dataUrl) {\n marker.parentNode?.removeChild(marker);\n continue;\n }\n\n const img = svg.ownerDocument!.createElementNS(SVG_NS, 'image') as SVGImageElement;\n img.setAttribute('x', String(bx));\n img.setAttribute('y', String(by));\n img.setAttribute('width', String(bw));\n img.setAttribute('height', String(bh));\n img.setAttribute('opacity', String(SHADOW_RASTER_ALPHA_COMPENSATION));\n img.setAttribute('preserveAspectRatio', 'none');\n img.setAttributeNS(XLINK_NS, 'xlink:href', dataUrl);\n img.setAttribute('href', dataUrl);\n marker.parentNode?.replaceChild(img, marker);\n } catch (error) {\n console.warn('[Vector PDF] text shadow rasterization failed for one marker:', error);\n try { marker.parentNode?.removeChild(marker); } catch { /* noop */ }\n }\n }\n}\n\nfunction restoreSourceFontsForShadowRaster(markup: string): string {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(`<svg xmlns=\"http://www.w3.org/2000/svg\">${markup}</svg>`, 'image/svg+xml');\n if (doc.querySelector('parsererror')) return markup;\n for (const node of Array.from(doc.querySelectorAll('text, tspan, textPath'))) {\n const family = node.getAttribute('data-source-font-family');\n const weight = node.getAttribute('data-source-font-weight');\n const style = node.getAttribute('data-source-font-style');\n if (!family && !weight && !style) continue;\n const stylePairs = (node.getAttribute('style') || '')\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .filter((part) => !/^font-family\\s*:/i.test(part) && !/^font-weight\\s*:/i.test(part) && !/^font-style\\s*:/i.test(part));\n if (family) { node.setAttribute('font-family', family); stylePairs.push(`font-family: ${family}`); }\n if (weight) { node.setAttribute('font-weight', weight); stylePairs.push(`font-weight: ${weight}`); }\n if (style) { node.setAttribute('font-style', style); stylePairs.push(`font-style: ${style}`); }\n if (stylePairs.length > 0) node.setAttribute('style', stylePairs.join('; '));\n }\n const root = doc.documentElement;\n return Array.from(root.childNodes)\n .map((n) => (n instanceof Element ? new XMLSerializer().serializeToString(n) : n.textContent || ''))\n .join('');\n } catch {\n return markup;\n }\n}\n\nfunction rasterSvgToPngDataUrl(svgMarkup: string, pxW: number, pxH: number): Promise<string | null> {\n return new Promise((resolve) => {\n try {\n const blob = new Blob([svgMarkup], { type: 'image/svg+xml;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const img = new Image();\n const cleanup = () => { try { URL.revokeObjectURL(url); } catch { /* noop */ } };\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = pxW;\n canvas.height = pxH;\n const ctx = canvas.getContext('2d');\n if (!ctx) { cleanup(); resolve(null); return; }\n ctx.clearRect(0, 0, pxW, pxH);\n ctx.drawImage(img, 0, 0, pxW, pxH);\n const dataUrl = canvas.toDataURL('image/png');\n cleanup();\n resolve(dataUrl);\n } catch {\n cleanup();\n resolve(null);\n }\n };\n img.onerror = () => { cleanup(); resolve(null); };\n img.src = url;\n } catch {\n resolve(null);\n }\n });\n}\n\nlet cachedShadowFontFaceCss: string | null = null;\nfunction collectDocumentFontFaceCss(): string {\n if (cachedShadowFontFaceCss !== null) return cachedShadowFontFaceCss;\n const out: string[] = [];\n try {\n for (const sheet of Array.from(document.styleSheets)) {\n let rules: CSSRuleList | null = null;\n try { rules = sheet.cssRules; } catch { rules = null; }\n if (!rules) continue;\n for (const rule of Array.from(rules)) {\n const r = rule as CSSRule & { cssText?: string };\n if (r && (r.type === 5 || /@font-face/i.test(r.cssText || '')) && r.cssText) out.push(r.cssText);\n }\n }\n } catch { /* noop */ }\n cachedShadowFontFaceCss = out.join('\\n');\n return cachedShadowFontFaceCss;\n}\n\n// ─── Font inlining for shadow rasterization ────────────────────────────────\n// We need the offscreen blob-SVG to render text with the same fonts the\n// document uses. Browsers won't load fonts via @font-face URL() inside a\n// blob: SVG loaded via <img> reliably (CORS + timing). Inlining the woff2\n// payload as a data: URI works in every browser.\n\nlet cachedInlinedFontFaceCss: string | null = null;\nconst fontUrlDataCache = new Map<string, string | null>();\n\nasync function fetchFontAsDataUri(url: string): Promise<string | null> {\n if (fontUrlDataCache.has(url)) return fontUrlDataCache.get(url) ?? null;\n try {\n const resp = await fetch(url, { mode: 'cors', credentials: 'omit' });\n if (!resp.ok) { fontUrlDataCache.set(url, null); return null; }\n const blob = await resp.blob();\n const dataUri: string = await new Promise((resolve, reject) => {\n const fr = new FileReader();\n fr.onload = () => resolve(String(fr.result));\n fr.onerror = () => reject(fr.error);\n fr.readAsDataURL(blob);\n });\n fontUrlDataCache.set(url, dataUri);\n return dataUri;\n } catch {\n fontUrlDataCache.set(url, null);\n return null;\n }\n}\n\nasync function inlineUrlsInCss(css: string): Promise<string> {\n // Match url(...) inside @font-face blocks. We replace each http(s) URL with\n // a data: URI; relative URLs are resolved against document.baseURI first.\n const urlRe = /url\\((['\"]?)([^'\")]+)\\1\\)/gi;\n const matches: { full: string; url: string }[] = [];\n let m: RegExpExecArray | null;\n while ((m = urlRe.exec(css)) !== null) {\n const raw = m[2].trim();\n if (raw.startsWith('data:')) continue;\n let abs = raw;\n try { abs = new URL(raw, document.baseURI).toString(); } catch { /* keep raw */ }\n matches.push({ full: m[0], url: abs });\n }\n if (matches.length === 0) return css;\n const unique = Array.from(new Set(matches.map((m) => m.url)));\n const results = await Promise.all(unique.map((u) => fetchFontAsDataUri(u)));\n const map = new Map<string, string | null>();\n unique.forEach((u, i) => map.set(u, results[i]));\n let out = css;\n for (const { full, url } of matches) {\n const data = map.get(url);\n if (!data) continue;\n // escape replacement specials\n const safeFull = full.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n out = out.replace(new RegExp(safeFull, 'g'), `url(\"${data}\")`);\n }\n return out;\n}\n\nasync function collectInlinedFontFaceCss(): Promise<string> {\n if (cachedInlinedFontFaceCss !== null) return cachedInlinedFontFaceCss;\n const raw = collectDocumentFontFaceCss();\n if (!raw) { cachedInlinedFontFaceCss = ''; return ''; }\n try {\n cachedInlinedFontFaceCss = await inlineUrlsInCss(raw);\n } catch {\n cachedInlinedFontFaceCss = raw;\n }\n return cachedInlinedFontFaceCss;\n}\n\nasync function prepareLiveCanvasSvgForPdf(\n rawSvg: string,\n pageWidth: number,\n pageHeight: number,\n pageKey: string,\n options?: {\n stripPageBackground?: boolean;\n },\n): Promise<Element | null> {\n try {\n const parser = new DOMParser();\n const processedSvg = inlineNestedSvgImageDataUris(rawSvg, parser);\n const doc = parser.parseFromString(processedSvg, 'image/svg+xml');\n if (doc.querySelector('parsererror')) return null;\n\n const svg = doc.documentElement;\n if (!svg || svg.tagName.toLowerCase() !== 'svg') return null;\n\n svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n if (/xlink:href/i.test(processedSvg) && !svg.getAttribute('xmlns:xlink')) {\n svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n }\n svg.setAttribute('width', String(pageWidth));\n svg.setAttribute('height', String(pageHeight));\n svg.setAttribute('viewBox', `0 0 ${pageWidth} ${pageHeight}`);\n\n sanitizeSvgTreeForPdf(svg);\n normalizeSvgViewBoxOrigin(svg);\n disambiguateNestedSvgIds(svg);\n expandSvgUseElements(svg, pageKey);\n\n let svgToDraw = normalizeSvgExplicitColors(svg);\n // Match EC2/server parity: flatten computed paint so transparent fills become explicit fill=\"none\"\n // instead of being left implicit and defaulting to black inside svg2pdf.\n inlineComputedStyles(svgToDraw);\n sanitizeSvgTreeForPdf(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n prefixSvgIds(svgToDraw, pageKey);\n bakeGroupOpacityIntoChildren(svgToDraw);\n stripSuspiciousFullPageOverlayNodes(svgToDraw);\n if (options?.stripPageBackground) {\n stripRootPageBackgroundFromSvg(svgToDraw);\n }\n sanitizeSvgTreeForPdf(svgToDraw);\n // ─── v0.5.131 PARITY: bake text-anchor → start from live canvas\n // measurement BEFORE any downstream code (shadow-bound outlining,\n // svg2pdf, decoration-to-line) tries to do its own width math.\n // After this pass every <text>/<tspan> uses anchor=start with x = the\n // exact leftmost glyph position the on-screen preview drew.\n try {\n await logTextMeasurementDiagnostic(svgToDraw);\n await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);\n } catch (e) {\n console.warn('[Vector PDF] anchor-bake pass failed (continuing):', e);\n }\n await rasterizeShadowMarkers(svgToDraw as SVGElement);\n await convertTextDecorationsToLines(svgToDraw);\n\n // Live Fabric SVG still carries browser font-family/style attributes. svg2pdf\n // only uses fonts that were registered in jsPDF, so rewrite to the embedded\n // jsPDF font names and synthesize italic when the family has no italic file\n // (e.g. Pacifico Regular + fontStyle italic).\n const rewritten = rewriteSvgFontsForJsPDFWithSourceMeta(new XMLSerializer().serializeToString(svgToDraw));\n const rewrittenDoc = parser.parseFromString(rewritten, 'image/svg+xml');\n if (!rewrittenDoc.querySelector('parsererror') && rewrittenDoc.documentElement?.tagName.toLowerCase() === 'svg') {\n return rewrittenDoc.documentElement;\n }\n\n return svgToDraw;\n } catch {\n return null;\n }\n}\n\nexport async function drawPreparedLiveCanvasSvgPageToPdf(options: {\n rawSvg: string;\n pdf: jsPDF;\n pageWidth: number;\n pageHeight: number;\n pageKey: string;\n stripPageBackground?: boolean;\n}): Promise<boolean> {\n const { rawSvg, pdf, pageWidth, pageHeight, pageKey, stripPageBackground } = options;\n const svgToDraw = await prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey, {\n stripPageBackground,\n });\n if (!svgToDraw) return false;\n\n const seq = ++debugSvgDrawSequence;\n // Match EC2 pipeline: saveGraphicsState → reset colors → svg2pdf → restoreGraphicsState → reset\n // This prevents color leaking from the SVG into subsequent PDF operations and vice versa\n pdf.setFillColor(0, 0, 0);\n pdf.setDrawColor(0, 0, 0);\n pdf.saveGraphicsState();\n setPdfColorFromSvg(pdf, svgToDraw, pageKey);\n const pdfToUse = pdfWithColorLogging(pdf, seq, pageKey);\n // ─── DIAGNOSTIC (text-parity): dump every <text> element's raw outerHTML\n // and per-tspan x positions right before svg2pdf consumes the SVG. This\n // lets us diff the IDENTICAL SVG snapshot between client-Chrome and\n // server-Puppeteer to confirm whether divergence happens upstream (SVG\n // generation) or downstream (svg2pdf / jsPDF font rendering).\n try {\n const texts = Array.from((svgToDraw as Element).querySelectorAll('text'));\n for (let i = 0; i < texts.length; i++) {\n const t = texts[i];\n const content = (t.textContent || '').replace(/\\s+/g, ' ').trim().slice(0, 60);\n const tspans = Array.from(t.querySelectorAll('tspan')).map((s) => ({\n x: s.getAttribute('x'),\n y: s.getAttribute('y'),\n text: (s.textContent || '').slice(0, 40),\n }));\n const parentG = t.parentElement?.tagName === 'g' ? t.parentElement : null;\n console.log('[svg-parity-dump]', JSON.stringify({\n page: pageKey,\n idx: i,\n snippet: content,\n textAttrs: {\n x: t.getAttribute('x'),\n y: t.getAttribute('y'),\n anchor: t.getAttribute('text-anchor'),\n fontFamily: t.getAttribute('font-family'),\n fontSize: t.getAttribute('font-size'),\n fontWeight: t.getAttribute('font-weight'),\n },\n parentTransform: parentG?.getAttribute('transform') || null,\n tspans,\n }));\n }\n } catch (e) {\n console.warn('[svg-parity-dump] failed:', e);\n }\n await svg2pdfWithDomMount(svgToDraw, pdfToUse, svg2pdfOpts(0, 0, pageWidth, pageHeight));\n pdf.restoreGraphicsState();\n pdf.setFillColor(0, 0, 0);\n pdf.setDrawColor(0, 0, 0);\n return true;\n}\n\nexport function rewriteSvgFontsForJsPDFWithSourceMeta(svgStr: string): string {\n const parser = new DOMParser();\n const doc = parser.parseFromString(svgStr, 'image/svg+xml');\n const allTextEls = Array.from(doc.querySelectorAll('text, tspan, textPath'));\n\n const readStyleToken = (style: string, prop: string): string | null => {\n const match = style.match(new RegExp(`${prop}\\\\s*:\\\\s*([^;]+)`, 'i'));\n return match?.[1]?.trim() || null;\n };\n\n const resolveInheritedValue = (el: Element, attr: string, styleProp = attr): string | null => {\n let current: Element | null = el;\n while (current) {\n const attrVal = current.getAttribute(attr)?.trim();\n if (attrVal) return attrVal;\n const styleVal = readStyleToken(current.getAttribute('style') || '', styleProp);\n if (styleVal) return styleVal;\n current = current.parentElement;\n }\n return null;\n };\n\n const getDepth = (el: Element): number => {\n let depth = 0;\n let current = el.parentElement;\n while (current) { depth++; current = current.parentElement; }\n return depth;\n };\n\n const setRunFontAttrs = (target: Element, fontName: string, baseStyle = target.getAttribute('style') || '') => {\n target.setAttribute('font-family', fontName);\n target.setAttribute('font-weight', 'normal');\n target.setAttribute('font-style', 'normal');\n const stylePairs = baseStyle\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .filter((part) => !/^font-family\\s*:/i.test(part) && !/^font-weight\\s*:/i.test(part) && !/^font-style\\s*:/i.test(part));\n stylePairs.push(`font-family: ${fontName}`);\n stylePairs.push('font-weight: normal');\n stylePairs.push('font-style: normal');\n target.setAttribute('style', stylePairs.join('; '));\n };\n\n const needsSyntheticBold = (requestedWeight: number, actualWeight: number): boolean =>\n requestedWeight >= 600 && actualWeight < 600;\n\n // True when italic was requested but the best registered variant we found is\n // upright. We then apply synthetic italic via skewX on the <text>/<tspan>.\n const needsSyntheticItalic = (requestedItalic: boolean, actualItalic: boolean): boolean =>\n requestedItalic && !actualItalic;\n\n const SYNTHETIC_ITALIC_SKEW_DEG = 12;\n\n const applySyntheticItalicTransform = (el: Element): void => {\n // Skew around the element's anchor (x, y). Mixed rich-text styles usually\n // live on child <tspan>s, not the parent <text>, so read the closest\n // inherited x/y and apply the transform to the exact run that requested\n // italic while keeping the text live/selectable.\n const xRaw = resolveInheritedValue(el, 'x') ?? '0';\n const yRaw = resolveInheritedValue(el, 'y') ?? '0';\n const x = Number.parseFloat(xRaw) || 0;\n const y = Number.parseFloat(yRaw) || 0;\n const existing = el.getAttribute('transform') || '';\n // skewX is applied around (x, y) by translating to origin first.\n const synth = `translate(${x} ${y}) skewX(-${SYNTHETIC_ITALIC_SKEW_DEG}) translate(${-x} ${-y})`;\n el.setAttribute('transform', existing ? `${existing} ${synth}` : synth);\n };\n\n const sourceMeta = new Map<Element, {\n clean: string;\n requestedWeight: number;\n resolvedWeight: number;\n requestedItalic: boolean;\n italic: boolean;\n jsPdfName: string;\n inlineStyle: string;\n }>();\n\n for (const el of allTextEls) {\n const inlineStyle = el.getAttribute('style') || '';\n const rawFf = resolveInheritedValue(el, 'font-family');\n if (!rawFf) continue;\n const clean = rawFf.split(',')[0]?.replace(/['\"]/g, '').trim();\n if (!clean) continue;\n // Rewrite local fonts and runtime-embedded Google/Fontshare fonts. If a\n // remote font could not be embedded, leave its original SVG family intact\n // so svg2pdf can fall back gracefully instead of selecting a non-existent\n // jsPDF font name.\n if (!isFontAvailable(clean) && !isFamilyEmbedded(clean)) continue;\n\n const weightRaw = resolveInheritedValue(el, 'font-weight') || '400';\n const styleRaw = resolveInheritedValue(el, 'font-style') || 'normal';\n const parsedWeight = Number.parseInt(weightRaw, 10);\n const weight = Number.isFinite(parsedWeight)\n ? parsedWeight\n : /bold/i.test(weightRaw)\n ? 700\n : /medium/i.test(weightRaw)\n ? 500\n : /semi/i.test(weightRaw)\n ? 600\n : /light/i.test(weightRaw)\n ? 300\n : 400;\n const resolvedWeight = resolveFontWeight(weight);\n const italic = /italic|oblique/i.test(styleRaw);\n // Pick the closest variant ACTUALLY registered into jsPDF. Without this,\n // the rewriter could emit e.g. \"DMSerifDisplay-Bold\" when only Regular\n // was embedded (because the family has no real Bold and Google's\n // fallback fetch returned 404), causing jsPDF to silently fall back to\n // Helvetica and breaking visual font parity with the canvas preview.\n const best = resolveBestRegisteredVariant(clean, resolvedWeight, italic);\n if (!best) {\n // Family has no embedded variants at all — leave SVG family intact so\n // svg2pdf can degrade gracefully instead of selecting a bogus name.\n continue;\n }\n const jsPdfName = getEmbeddedJsPDFFontName(clean, best.weight, best.italic);\n sourceMeta.set(el, {\n clean,\n requestedWeight: resolvedWeight,\n resolvedWeight: best.weight,\n requestedItalic: italic,\n italic: best.italic,\n jsPdfName,\n inlineStyle,\n });\n }\n\n // Process children before parents. Fabric SVG commonly stores actual text on\n // <tspan> children; rewriting the parent <text> first would make the child\n // inherit the jsPDF-only name (e.g. PlayfairDisplay-Regular), causing us to\n // skip glyph fallback splitting for strings like \"₹18 LPA\".\n const textEls = allTextEls.sort((a, b) => getDepth(b) - getDepth(a));\n\n for (const el of textEls) {\n if (!el.isConnected) continue;\n const meta = sourceMeta.get(el);\n if (!meta) continue;\n const { clean, requestedWeight, resolvedWeight, requestedItalic, italic, jsPdfName, inlineStyle } = meta;\n\n el.setAttribute('data-source-font-family', clean);\n el.setAttribute('data-source-font-weight', String(requestedWeight));\n el.setAttribute('data-source-font-style', requestedItalic ? 'italic' : 'normal');\n if (needsSyntheticBold(requestedWeight, resolvedWeight)) {\n const fill = resolveInheritedValue(el, 'fill') || readStyleToken(inlineStyle, 'fill') || '#000000';\n el.setAttribute('stroke', fill);\n el.setAttribute('stroke-width', String(Math.max(0.35, Math.min(1.2, requestedWeight === 700 ? 0.7 : 0.5))));\n el.setAttribute('stroke-linejoin', 'round');\n }\n // Synthetic italic: when italic was requested but no italic-bearing\n // variant of this family was registered (e.g. a bold-italic span on a\n // family with no italic file), skew the glyphs around the anchor so\n // the PDF visually carries italic shape. Only apply when this element\n // has its OWN font-style:italic — otherwise both the parent <text>\n // and its child <tspan>s would each get a skew, producing a doubled\n // shear after the tspan→<text> promotion post-pass below.\n const hasOwnItalicStyle = /italic|oblique/i.test(\n `${el.getAttribute('font-style') || ''};${readStyleToken(inlineStyle, 'font-style') || ''}`,\n );\n if (needsSyntheticItalic(requestedItalic, italic) && hasOwnItalicStyle) {\n applySyntheticItalicTransform(el);\n }\n\n // ── Per-character font fallback (₹, €, ★, Devanagari, etc.) ──\n // Split direct text node children into <tspan> runs by classifyChar()\n // so non-Latin glyphs use the embedded fallback font (Noto Sans /\n // Noto Sans Devanagari) instead of rendering as missing glyphs.\n const directTextChildren = Array.from(el.childNodes).filter((n) => n.nodeType === 3);\n if (directTextChildren.length === 0) {\n setRunFontAttrs(el, jsPdfName, inlineStyle);\n continue;\n }\n\n const symbolJsPdfName = isFontAvailable(FONT_FALLBACK_SYMBOLS)\n ? getEmbeddedJsPDFFontName(FONT_FALLBACK_SYMBOLS, 400)\n : jsPdfName;\n const devanagariJsPdfName = isFontAvailable(FONT_FALLBACK_DEVANAGARI)\n ? getEmbeddedJsPDFFontName(FONT_FALLBACK_DEVANAGARI, resolvedWeight)\n : jsPdfName;\n const mathJsPdfName = isFontAvailable(FONT_FALLBACK_MATH)\n ? getEmbeddedJsPDFFontName(FONT_FALLBACK_MATH, 400)\n : symbolJsPdfName;\n const mainSupportsChar = (char: string) => doesVariantSupportChar(clean, resolvedWeight, italic, char);\n\n for (const node of directTextChildren) {\n const txt = node.textContent || '';\n if (!txt) continue;\n const runs = splitLineIntoRuns(txt, mainSupportsChar);\n // Skip if entire run is plain Latin — already handled by the parent rewrite above.\n if (runs.length === 1 && runs[0].runType === 'main') continue;\n\n const fragment = doc.createDocumentFragment();\n for (const run of runs) {\n const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');\n let runFont = jsPdfName;\n if (run.runType === 'symbol') runFont = symbolJsPdfName;\n else if (run.runType === 'devanagari') runFont = devanagariJsPdfName;\n else if (run.runType === 'math') runFont = mathJsPdfName;\n tspan.setAttribute('font-family', runFont);\n tspan.setAttribute('font-weight', 'normal');\n tspan.setAttribute('font-style', 'normal');\n tspan.textContent = run.text;\n fragment.appendChild(tspan);\n }\n el.replaceChild(fragment, node);\n }\n\n setRunFontAttrs(el, jsPdfName, inlineStyle);\n }\n\n // ── Synthetic italic post-pass ──\n // applySyntheticItalicTransform may have put a `transform` on <tspan>s.\n // SVG <tspan> does NOT honor `transform`. Promote each transformed\n // <tspan> to a wrapping sibling <text> that DOES honor it, while\n // keeping the text live/selectable.\n const SVG_NS = 'http://www.w3.org/2000/svg';\n const transformedTspans = Array.from(doc.querySelectorAll('tspan[transform]'));\n for (const tspan of transformedTspans) {\n const parentText = tspan.parentElement;\n if (!parentText || parentText.tagName.toLowerCase() !== 'text') continue;\n const transformVal = tspan.getAttribute('transform') || '';\n if (!/skewX/i.test(transformVal)) continue;\n\n const wrapper = doc.createElementNS(SVG_NS, 'text');\n let parentTransform = '';\n for (const attr of Array.from(parentText.attributes)) {\n if (attr.name === 'transform') {\n parentTransform = attr.value;\n continue;\n }\n wrapper.setAttribute(attr.name, attr.value);\n }\n const combined = parentTransform ? `${parentTransform} ${transformVal}` : transformVal;\n wrapper.setAttribute('transform', combined);\n tspan.removeAttribute('transform');\n wrapper.appendChild(tspan);\n parentText.parentNode?.insertBefore(wrapper, parentText.nextSibling);\n }\n\n return new XMLSerializer().serializeToString(doc.documentElement);\n}\n\n/** Find gradient element by id within the given SVG tree (clone), not the document. */\nfunction findGradientInTree(svgRoot: Element, gradientId: string): Element | null {\n for (const el of svgRoot.querySelectorAll('[id]')) {\n if (el.getAttribute('id') === gradientId) return el;\n }\n return null;\n}\n\n/** Return true if hex is white or very light (so shape would be invisible on white). */\nfunction isNearWhite(hex: string): boolean {\n if (!/^#[0-9a-f]{6}$/i.test(hex)) return false;\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n return r >= 250 && g >= 250 && b >= 250;\n}\n\nfunction getInlineStyleValue(el: Element, key: string): string | null {\n const style = el.getAttribute('style') || '';\n if (!style) return null;\n const hit = parseInlineSvgStyleDeclarations(style).find((decl) => decl.key === key);\n return hit?.value ?? null;\n}\n\nfunction isTransparentColorToken(value: string | null): boolean {\n if (!value) return false;\n const s = value.trim().toLowerCase();\n if (!s || s === 'none' || s === 'transparent') return true;\n\n if (/^#[0-9a-f]{8}$/i.test(s)) {\n const alphaHex = s.slice(7, 9);\n return Number.parseInt(alphaHex, 16) === 0;\n }\n\n const rgba = s.match(/^rgba\\s*\\(([^)]+)\\)$/i);\n if (rgba) {\n const parts = rgba[1].split(',').map((part) => part.trim());\n if (parts.length >= 4) {\n const alpha = parseSvgOpacity(parts[3]);\n return alpha != null && alpha <= 0.0001;\n }\n }\n\n return false;\n}\n\nfunction getStopOpacity(stop: Element): number | null {\n const fromAttr = parseSvgOpacity(stop.getAttribute('stop-opacity'));\n if (fromAttr != null) return fromAttr;\n\n const fromStyleObj = parseSvgOpacity((stop as SVGElement).style?.getPropertyValue('stop-opacity') || null);\n if (fromStyleObj != null) return fromStyleObj;\n\n const fromStyleAttr = parseSvgOpacity(getInlineStyleValue(stop, 'stop-opacity'));\n return fromStyleAttr;\n}\n\nfunction getStopColorRaw(stop: Element): string | null {\n return (\n stop.getAttribute('stop-color') ??\n (stop as SVGElement).style?.getPropertyValue('stop-color')?.trim() ??\n getInlineStyleValue(stop, 'stop-color')\n );\n}\n\nfunction isGradientStopFullyTransparent(stop: Element): boolean {\n const stopOpacity = getStopOpacity(stop);\n if (stopOpacity != null && stopOpacity <= 0.0001) return true;\n\n const stopColor = getStopColorRaw(stop);\n return isTransparentColorToken(stopColor);\n}\n\nfunction isGradientFullyTransparent(svgRoot: Element, gradientId: string, visited = new Set<string>()): boolean {\n if (visited.has(gradientId)) return false;\n visited.add(gradientId);\n\n const gradient = findGradientInTree(svgRoot, gradientId);\n if (!gradient) return false;\n\n const tag = gradient.tagName?.toLowerCase();\n if (tag !== 'lineargradient' && tag !== 'radialgradient') return false;\n\n const stops = Array.from(gradient.querySelectorAll('stop'));\n if (stops.length > 0) {\n return stops.every((stop) => isGradientStopFullyTransparent(stop));\n }\n\n const href = (gradient.getAttribute('href') || gradient.getAttribute('xlink:href') || '').trim();\n if (href.startsWith('#')) {\n return isGradientFullyTransparent(svgRoot, href.slice(1), visited);\n }\n\n return false;\n}\n\n/** Get a solid color from a gradient: first stop, or last stop if first is near-white. Follows xlink:href when gradient has no stops. */\nfunction getGradientStopColorAsHex(svgRoot: Element, gradientId: string, visited = new Set<string>()): string | null {\n if (visited.has(gradientId)) return null;\n visited.add(gradientId);\n const gradient = findGradientInTree(svgRoot, gradientId);\n if (!gradient) return null;\n const tag = gradient.tagName?.toLowerCase();\n if (tag !== 'lineargradient' && tag !== 'radialgradient') return null;\n const stops = Array.from(gradient.querySelectorAll('stop'));\n if (stops.length === 0) {\n const href = (gradient.getAttribute('href') || gradient.getAttribute('xlink:href') || '').trim();\n if (href.startsWith('#')) {\n const refId = href.slice(1);\n return getGradientStopColorAsHex(svgRoot, refId, visited);\n }\n return null;\n }\n const getStopColor = (stop: Element): string | null => {\n if (isGradientStopFullyTransparent(stop)) return null;\n const stopColor = getStopColorRaw(stop);\n return stopColor ? cssColorToHex(stopColor) : null;\n };\n const firstHex = getStopColor(stops[0]);\n if (firstHex && !isNearWhite(firstHex)) return firstHex;\n const lastStop = stops[stops.length - 1];\n if (lastStop !== stops[0]) {\n const lastHex = getStopColor(lastStop);\n if (lastHex) return lastHex;\n }\n return firstHex;\n}\n\nconst GRADIENT_ATTRS_LINEAR = ['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform', 'spreadMethod'];\nconst GRADIENT_ATTRS_RADIAL = ['cx', 'cy', 'r', 'fx', 'fy', 'gradientUnits', 'gradientTransform', 'spreadMethod'];\n\n/** Copy gradient geometry from ref to gradient for any attribute the gradient doesn't have (so expanded href gradient renders correctly). */\nfunction copyGradientAttrsFromRef(gradient: Element, ref: Element): void {\n const tag = gradient.tagName?.toLowerCase();\n const attrs = tag === 'radialgradient' ? GRADIENT_ATTRS_RADIAL : GRADIENT_ATTRS_LINEAR;\n for (const name of attrs) {\n if (!gradient.hasAttribute(name) && ref.hasAttribute(name)) {\n gradient.setAttribute(name, ref.getAttribute(name)!);\n }\n }\n}\n\n/** Inline xlink:href gradient refs: if a gradient has no stops but href=\"#id\", copy the referenced gradient's stops and geometry so svg2pdf can render it (including inner shapes). */\nfunction expandSvgGradientHrefs(svg: Element): void {\n const visited = new Set<string>();\n function expand(gradient: Element): void {\n const id = gradient.getAttribute('id');\n if (!id || visited.has(id)) return;\n visited.add(id);\n const stops = gradient.querySelectorAll('stop');\n if (stops.length > 0) return;\n const href = (gradient.getAttribute('href') || gradient.getAttribute('xlink:href') || '').trim();\n if (!href.startsWith('#')) return;\n const refId = href.slice(1);\n const ref = findGradientInTree(svg, refId);\n if (!ref) return;\n expand(ref);\n copyGradientAttrsFromRef(gradient, ref);\n const refStops = ref.querySelectorAll('stop');\n for (const stop of refStops) gradient.appendChild(stop.cloneNode(true));\n gradient.removeAttribute('href');\n gradient.removeAttribute('xlink:href');\n }\n for (const g of svg.querySelectorAll('linearGradient, radialGradient')) {\n expand(g);\n }\n}\n\n/** Convert a CSS color (hex, rgb, rgba, or name) to #rrggbb. */\nfunction cssColorToHex(css: string): string | null {\n const s = css.trim();\n if (/^#[0-9a-f]{3}$/i.test(s)) {\n const r = s[1] + s[1], g = s[2] + s[2], b = s[3] + s[3];\n return '#' + r + g + b;\n }\n if (/^#[0-9a-f]{6}$/i.test(s)) return s;\n if (/^#[0-9a-f]{8}$/i.test(s)) return '#' + s.slice(1, 7);\n const rgb = s.match(/^rgba?\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/i);\n if (rgb) {\n const r = Number(rgb[1]).toString(16).padStart(2, '0');\n const g = Number(rgb[2]).toString(16).padStart(2, '0');\n const b = Number(rgb[3]).toString(16).padStart(2, '0');\n return '#' + r + g + b;\n }\n if (typeof document === 'undefined') return null;\n const div = document.createElement('div');\n div.style.color = s;\n const computed = document.defaultView?.getComputedStyle(div).color;\n if (!computed || !computed.startsWith('rgb')) return null;\n const m = computed.match(/\\d+/g);\n if (!m || m.length < 3) return null;\n const r = Number(m[0]).toString(16).padStart(2, '0');\n const g = Number(m[1]).toString(16).padStart(2, '0');\n const b = Number(m[2]).toString(16).padStart(2, '0');\n return '#' + r + g + b;\n}\n\n/** Return true if this gradient has at least one stop (so svg2pdf can render it). */\nfunction gradientHasStops(svgRoot: Element, gradientId: string): boolean {\n const gradient = findGradientInTree(svgRoot, gradientId);\n if (!gradient) return false;\n return gradient.querySelectorAll('stop').length > 0;\n}\n\n/** Replace fill/stroke url(#id) with solid only when the gradient has no stops. Otherwise leave url() so svg2pdf can render gradients. */\nfunction resolveSvgGradientRefsToSolid(svg: Element, elementId?: string): void {\n const drawable = svg.querySelectorAll('path, rect, circle, ellipse, polygon, polyline, line');\n if (DEBUG_SVG_STRUCTURE && drawable.length > 0) {\n const before = Array.from(drawable).map((el) => ({ tag: el.tagName, fill: el.getAttribute('fill'), stroke: el.getAttribute('stroke') }));\n console.log('[PDF export] gradient resolve BEFORE', elementId ?? '', before);\n }\n const all = svg.querySelectorAll('*');\n let fallbackHex: string | null = null;\n for (const el of all) {\n for (const attr of ['fill', 'stroke'] as const) {\n const val = el.getAttribute(attr);\n if (!val) continue;\n const id = extractGradientIdFromPaint(val);\n if (!id) continue;\n // Keep paint-server refs in canonical local form for svg2pdf compatibility.\n const normalizedRef = `url(#${id})`;\n if (val !== normalizedRef) el.setAttribute(attr, normalizedRef);\n\n // If mapped gradient is fully transparent, force no paint so export can't fall back to black.\n if (isGradientFullyTransparent(svg, id)) {\n el.setAttribute(attr, 'none');\n continue;\n }\n\n if (!FLATTEN_SVG_GRADIENTS_FOR_PDF && gradientHasStops(svg, id)) continue;\n let hex = getGradientStopColorAsHex(svg, id);\n if (!hex && fallbackHex) hex = fallbackHex;\n if (!hex) {\n const firstGradient = svg.querySelector('linearGradient[id], radialGradient[id]');\n if (firstGradient) {\n const firstId = firstGradient.getAttribute('id');\n if (firstId) hex = getGradientStopColorAsHex(svg, firstId);\n }\n if (!hex) hex = '#000000';\n }\n if (hex) {\n el.setAttribute(attr, hex);\n if (!fallbackHex) fallbackHex = hex;\n }\n }\n }\n if (DEBUG_SVG_STRUCTURE && drawable.length > 0) {\n const after = Array.from(drawable).map((el) => ({ tag: el.tagName, fill: el.getAttribute('fill'), stroke: el.getAttribute('stroke') }));\n console.log('[PDF export] gradient resolve AFTER', elementId ?? '', after);\n }\n}\n\n/**\n * Disambiguate IDs across nested <svg> elements on the same page.\n * Two SVG images may share internal IDs (e.g. \"linearGradient-1\") —\n * without per-SVG prefixing the second one references the first's defs.\n */\nfunction disambiguateNestedSvgIds(rootSvg: Element): void {\n const nestedSvgs = Array.from(rootSvg.querySelectorAll('svg'));\n const toProcess = nestedSvgs.filter((s) => s !== rootSvg);\n if (toProcess.length < 2) return;\n\n toProcess.forEach((nested, idx) => {\n prefixSvgIds(nested, `n${idx}`);\n });\n}\n\n/**\n * Prefix all IDs and url(#id) refs in the SVG so this SVG's gradients/defs don't collide with others.\n * Fixes \"gradients with same id in different SVGs rendered in same color\" (yWorks/svg2pdf.js#171).\n * jsPDF reuses form objects by id; different SVGs must use different ids.\n */\nfunction prefixSvgIds(svg: Element, prefix: string): void {\n const safePrefix = String(prefix).replace(/[^a-zA-Z0-9-]/g, '_');\n const idMap = new Map<string, string>();\n\n svg.querySelectorAll('[id]').forEach((el) => {\n const id = el.getAttribute('id');\n if (id) idMap.set(id, `${safePrefix}_${id}`);\n });\n\n if (idMap.size === 0) return;\n\n // Rename actual IDs first\n idMap.forEach((newId, oldId) => {\n svg.querySelectorAll(`[id=\"${oldId}\"]`).forEach((el) => el.setAttribute('id', newId));\n });\n\n const replaceUrlRefs = (value: string): string => {\n // Replace only url(...#id) refs (safe for colors like #aabbcc)\n return value.replace(/url\\(\\s*(['\"]?)([^)]+?)\\1\\s*\\)/gi, (full, quoteRaw, refRaw) => {\n const ref = String(refRaw || '').trim();\n const hashIdx = ref.lastIndexOf('#');\n if (hashIdx < 0 || hashIdx === ref.length - 1) return full;\n const base = ref.slice(0, hashIdx + 1);\n const oldId = ref.slice(hashIdx + 1).trim().replace(/[\\s\"')].*$/, '');\n const mapped = idMap.get(oldId);\n if (!mapped) return full;\n const quote = String(quoteRaw || '');\n return `url(${quote}${base}${mapped}${quote})`;\n });\n };\n\n const replaceHrefRef = (value: string): string => {\n const trimmed = value.trim();\n if (trimmed.startsWith('#')) {\n const oldId = trimmed.slice(1);\n const mapped = idMap.get(oldId);\n return mapped ? `#${mapped}` : value;\n }\n return replaceUrlRefs(value);\n };\n\n const refAttrs = [\n 'fill',\n 'stroke',\n 'clip-path',\n 'mask',\n 'filter',\n 'href',\n 'xlink:href',\n 'marker-start',\n 'marker-mid',\n 'marker-end',\n ];\n\n svg.querySelectorAll('*').forEach((el) => {\n refAttrs.forEach((attr) => {\n const val = el.getAttribute(attr);\n if (!val) return;\n const next = attr === 'href' || attr === 'xlink:href' ? replaceHrefRef(val) : replaceUrlRefs(val);\n if (next !== val) el.setAttribute(attr, next);\n });\n\n const style = el.getAttribute('style');\n if (style) {\n const nextStyle = replaceUrlRefs(style);\n if (nextStyle !== style) el.setAttribute('style', nextStyle);\n }\n });\n\n // Keep <style> blocks consistent too\n svg.querySelectorAll('style').forEach((styleNode) => {\n const text = styleNode.textContent || '';\n const next = replaceUrlRefs(text);\n if (next !== text) styleNode.textContent = next;\n });\n}\n\n/** Expand <use href=\"#id\"> into a clone of the referenced element so svg2pdf draws it (inner \"house\" etc.). */\nfunction expandSvgUseElements(svg: Element, elementId?: string): void {\n const doc = svg.ownerDocument;\n const uses = Array.from(svg.querySelectorAll('use'));\n if (DEBUG_SVG_STRUCTURE && (uses.length > 0 || elementId)) {\n console.log('[PDF export] SVG structure', elementId ?? 'unknown', {\n useCount: uses.length,\n defsIds: Array.from(svg.querySelectorAll('defs [id], symbol[id]')).map((el) => el.getAttribute('id')),\n });\n }\n for (const use of uses) {\n const ref = (use.getAttribute('href') || use.getAttribute('xlink:href') || '').trim();\n if (!ref.startsWith('#')) {\n if (DEBUG_SVG_STRUCTURE) console.log('[PDF export] use skip (no #ref)', ref);\n continue;\n }\n const id = ref.slice(1);\n const target = doc.getElementById(id);\n if (DEBUG_SVG_STRUCTURE) {\n console.log('[PDF export] use', ref, 'targetFound=', !!target, 'targetTag=', target?.tagName, 'targetChildren=', target?.children?.length);\n }\n if (!target) continue;\n const x = parseFloat(use.getAttribute('x') || '0') || 0;\n const y = parseFloat(use.getAttribute('y') || '0') || 0;\n const w = parseFloat(use.getAttribute('width') || '0') || 0;\n const h = parseFloat(use.getAttribute('height') || '0') || 0;\n const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g');\n if (target.tagName?.toLowerCase() === 'symbol') {\n const viewBox = target.getAttribute('viewBox');\n for (let i = 0; i < target.children.length; i++) {\n g.appendChild(target.children[i].cloneNode(true));\n }\n if (viewBox && w && h) {\n const parts = viewBox.split(/\\s+/).map(Number);\n const vbW = parts[2];\n const vbH = parts[3];\n if (vbW && vbH) g.setAttribute('transform', `translate(${x},${y}) scale(${w / vbW},${h / vbH})`);\n else g.setAttribute('transform', `translate(${x},${y})`);\n } else if (x || y) {\n g.setAttribute('transform', `translate(${x},${y})`);\n }\n if (DEBUG_SVG_STRUCTURE) console.log('[PDF export] expanded symbol', id, 'children=', target.children.length);\n } else {\n const clone = target.cloneNode(true) as Element;\n if (x || y) g.setAttribute('transform', `translate(${x},${y})`);\n g.appendChild(clone);\n if (DEBUG_SVG_STRUCTURE) console.log('[PDF export] expanded use', id, 'tag=', target.tagName);\n }\n if (use.parentNode) use.parentNode.replaceChild(g, use);\n }\n if (DEBUG_SVG_STRUCTURE) {\n const topTags = Array.from(svg.children).map((c) => c.tagName + (c.id ? '#' + c.id : ''));\n const count = (sel: string) => svg.querySelectorAll(sel).length;\n console.log('[PDF export] SVG after expand', elementId ?? '', {\n topLevel: topTags,\n path: count('path'),\n rect: count('rect'),\n circle: count('circle'),\n g: count('g'),\n use: count('use'),\n });\n }\n}\n\nfunction normalizeSvgViewBoxOrigin(svg: Element): void {\n const viewBox = svg.getAttribute('viewBox');\n if (!viewBox) return;\n\n const parts = viewBox\n .split(/[\\s,]+/)\n .map((n) => Number.parseFloat(n))\n .filter((n) => Number.isFinite(n));\n\n if (parts.length !== 4) return;\n\n const [vx, vy, vw, vh] = parts;\n if (vw <= 0 || vh <= 0) return;\n if (Math.abs(vx) < 0.001 && Math.abs(vy) < 0.001) return;\n\n const doc = svg.ownerDocument;\n if (!doc) return;\n\n const keepAtRoot = new Set(['defs', 'style', 'title', 'desc', 'metadata']);\n const translatableChildren = Array.from(svg.children).filter(\n (child) => !keepAtRoot.has(child.tagName.toLowerCase())\n );\n if (translatableChildren.length === 0) {\n svg.setAttribute('viewBox', `0 0 ${vw} ${vh}`);\n return;\n }\n\n const wrapper = doc.createElementNS('http://www.w3.org/2000/svg', 'g');\n wrapper.setAttribute('transform', `translate(${-vx} ${-vy})`);\n\n for (const child of translatableChildren) {\n wrapper.appendChild(child);\n }\n\n svg.appendChild(wrapper);\n svg.setAttribute('viewBox', `0 0 ${vw} ${vh}`);\n}\n\n/** Fetch SVG from URL and return as DOM Element for vector embedding (svg2pdf). */\nasync function fetchSvgAsElement(imageUrl: string, colorMap?: Record<string, string>): Promise<Element | null> {\n if (!imageUrl) return null;\n const isSvgUrl = imageUrl.toLowerCase().includes('.svg') || imageUrl.startsWith('data:image/svg+xml');\n if (!isSvgUrl) return null;\n try {\n let text: string;\n if (imageUrl.startsWith('data:image/svg+xml;base64,')) {\n const b64 = imageUrl.slice('data:image/svg+xml;base64,'.length);\n const binary = atob(b64);\n try {\n text = decodeURIComponent(\n Array.from(binary)\n .map((ch) => `%${ch.charCodeAt(0).toString(16).padStart(2, '0')}`)\n .join('')\n );\n } catch {\n text = binary;\n }\n } else if (imageUrl.startsWith('data:image/svg+xml,')) {\n text = decodeURIComponent(imageUrl.slice('data:image/svg+xml,'.length).replace(/\\+/g, ' '));\n } else if (imageUrl.startsWith('data:') || imageUrl.startsWith('blob:')) {\n const res = await fetch(imageUrl);\n if (!res.ok) return null;\n text = await res.text();\n } else {\n const url = getProxiedImageUrl(imageUrl);\n const res = await fetch(url);\n if (!res.ok) return null;\n text = await res.text();\n }\n\n // Normalize legacy namespaced SVG markup so DOMParser/svg2pdf can consume it.\n text = text\n .trim()\n .replace(/^\\uFEFF/, '')\n .replace(/<(\\/?)\\s*svg:svg\\b/gi, '<$1svg')\n .replace(/<(\\/?)\\s*svg:/gi, '<$1')\n .replace(/(\\s)svg:([a-zA-Z_][\\w:.-]*)(\\s*=)/gi, '$1$2$3')\n .replace(/\\s+xmlns:svg\\s*=\\s*\"[^\"]*\"/gi, '')\n .replace(/\\s+xmlns:svg\\s*=\\s*'[^']*'/gi, '');\n\n if (!/\\sxmlns\\s*=\\s*[\"'][^\"']+[\"']/i.test(text)) {\n text = text.replace(/<svg\\b/i, '<svg xmlns=\"http://www.w3.org/2000/svg\"');\n }\n\n // Apply SVG color replacements before parsing into DOM\n if (colorMap && Object.keys(colorMap).length > 0) {\n const { applySvgColorMap } = await import('./svgColorUtils');\n text = applySvgColorMap(text, colorMap);\n }\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(text, 'image/svg+xml');\n if (doc.querySelector('parsererror')) return null;\n\n const svg = doc.documentElement;\n if (!svg || svg.tagName.toUpperCase() !== 'SVG') return null;\n\n if (/xlink:href/i.test(text) && !svg.getAttribute('xmlns:xlink')) {\n svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n }\n\n // Normalize non-zero viewBox origins to avoid svg2pdf transform drift/flip issues.\n normalizeSvgViewBoxOrigin(svg);\n\n return svg;\n } catch {\n return null;\n }\n}\n\n/** Get a recolored SVG as a data URL for raster fallback paths. Returns null if no colorMap or not SVG. */\nasync function getRecoloredSvgDataUrl(imageUrl: string, colorMap?: Record<string, string>): Promise<string | null> {\n if (!colorMap || Object.keys(colorMap).length === 0) return null;\n try {\n const { getNormalizedSvgUrl } = await import('./canvasImageLoader');\n return await getNormalizedSvgUrl(imageUrl, colorMap);\n } catch {\n return null;\n }\n}\n\n/**\n * True Vector PDF Export\n * Draws Fabric.js objects directly to jsPDF using native PDF primitives\n * Result: Small file size, infinite scalability, pixel-perfect match\n * \n * SCHEMA: Uses Fabric.js native properties exclusively:\n * - Position: left, top\n * - Dimensions: width, height, scaleX, scaleY\n * - Transform: angle, skewX, skewY, flipX, flipY\n * - Appearance: fill, stroke, strokeWidth, opacity\n * - Text: text, fontSize, fontFamily, fontWeight, textAlign, lineHeight\n */\n\n/**\n * Normalize element properties to Fabric.js schema\n * Handles both new Fabric.js format and legacy format with fallbacks\n */\nfunction normalizeElement(el: CanvasElement): {\n x: number;\n y: number;\n w: number;\n h: number;\n angle: number;\n skewX: number;\n skewY: number;\n opacity: number;\n fill: string;\n stroke: string;\n strokeWidth: number;\n strokeDashArray: string | undefined;\n // Text properties\n text: string;\n fontSize: number;\n fontFamily: string;\n fontWeight: number;\n fontStyle: 'normal' | 'italic';\n underline: boolean;\n letterSpacing: number;\n textAlign: 'left' | 'center' | 'right';\n lineHeight: number;\n splitByGrapheme: boolean;\n // Shape properties\n shapeType: string;\n borderRadius: number;\n rxTL?: number;\n rxTR?: number;\n rxBR?: number;\n rxBL?: number;\n // Triangle corner radii\n triRTop?: number;\n triRBR?: number;\n triRBL?: number;\n // Image properties\n imageUrl: string | undefined;\n // Origin properties\n originX: string;\n originY: string;\n} {\n // Dimensions: Apply scale to get final size\n const baseW = el.width ?? el.size?.width ?? 100;\n const baseH = el.height ?? el.size?.height ?? 100;\n const scaleX = el.scaleX ?? 1;\n const scaleY = el.scaleY ?? 1;\n const w = baseW * scaleX;\n const h = baseH * scaleY;\n\n // Origin point (Fabric.js default is 'left'/'top')\n const originX = el.originX ?? 'left';\n const originY = el.originY ?? 'top';\n\n // Position: left/top refer to the origin point position\n const rawX = el.left ?? el.position?.x ?? 0;\n const rawY = el.top ?? el.position?.y ?? 0;\n\n // Convert origin-based position to top-left corner position\n let x = rawX;\n let y = rawY;\n\n if (originX === 'center') x = rawX - w / 2;\n else if (originX === 'right') x = rawX - w;\n\n if (originY === 'center') y = rawY - h / 2;\n else if (originY === 'bottom') y = rawY - h;\n\n // Transform\n const angle = el.angle ?? el.rotation ?? 0;\n const skewX = el.skewX ?? 0;\n const skewY = el.skewY ?? 0;\n\n // Appearance (Fabric properties first, then legacy style object)\n const style = el.style || {};\n const opacity = el.opacity ?? style.opacity ?? 1;\n // Resolve fill: if a gradient is configured (`fillGradient` / `strokeGradient`),\n // use the FIRST stop colour as the PDF solid fallback. The host's vector PDF\n // pipeline draws text via `pdf.text()` (selectable text) and primitives via\n // direct jsPDF shape calls — neither path can render a real gradient. Falling\n // back to the first stop matches the gradient's dominant colour rather than\n // silently rendering as black (when the underlying solid `el.fill` is unset\n // or still its pre-gradient default like `#000000`).\n const firstStop = (g: any): string | null => {\n const stops = g?.stops;\n if (!Array.isArray(stops) || stops.length === 0) return null;\n const sorted = [...stops].sort((a: any, b: any) => (Number(a?.offset) || 0) - (Number(b?.offset) || 0));\n const c = sorted[0]?.color;\n return typeof c === 'string' && c ? c : null;\n };\n const fillGradientFirst = firstStop((el as any).fillGradient);\n const strokeGradientFirst = firstStop((el as any).strokeGradient);\n const fill = fillGradientFirst ?? (el.fill || style.fill || '');\n const stroke = strokeGradientFirst ?? (el.stroke || style.stroke || '');\n const strokeWidth = el.strokeWidth ?? style.strokeWidth ?? 0;\n const strokeDashArray = el.strokeDashArray?.join(',') || style.strokeDasharray;\n\n // Text properties\n const text = el.text || el.content || '';\n const fontSize = el.fontSize ?? style.fontSize ?? 16;\n const fontFamily = el.fontFamily || style.fontFamily || 'Open Sans';\n const fontWeightRaw = el.fontWeight ?? style.fontWeight ?? 400;\n const fontWeight = typeof fontWeightRaw === 'number'\n ? fontWeightRaw\n : parseInt(String(fontWeightRaw), 10) || 400;\n const fontStyleRaw = el.fontStyle || style.fontStyle || 'normal';\n const fontStyle: 'normal' | 'italic' = fontStyleRaw === 'italic' ? 'italic' : 'normal';\n const underline = el.underline ?? false;\n const letterSpacing = el.charSpacing ?? el.letterSpacing ?? style.letterSpacing ?? 0;\n const rawTextAlign = el.textAlign || style.textAlign || 'left';\n const textAlign = (rawTextAlign === 'left' || rawTextAlign === 'center' || rawTextAlign === 'right')\n ? rawTextAlign\n : 'left';\n const lineHeight = el.lineHeight ?? style.lineHeight ?? 1.2;\n \n // Word wrapping behavior\n const splitByGrapheme = el.splitByGrapheme ?? (el.wordWrap === 'break-word');\n\n // Shape properties\n const normalizedShapeType = normalizeShapeType(el.shapeType);\n const shapeType = normalizedShapeType === 'unsupported' ? (el.shapeType || 'rounded-rect') : normalizedShapeType;\n const borderRadius = el.rx ?? style.borderRadius ?? 0;\n const rxTL = el.rxTL;\n const rxTR = el.rxTR;\n const rxBR = el.rxBR;\n const rxBL = el.rxBL;\n const triRTop = el.triRTop;\n const triRBR = el.triRBR;\n const triRBL = el.triRBL;\n\n // Image properties\n const imageUrl = el.src || el.imageUrl;\n\n return {\n x,\n y,\n w,\n h,\n angle,\n skewX,\n skewY,\n opacity,\n fill,\n stroke,\n strokeWidth,\n strokeDashArray,\n text,\n fontSize,\n fontFamily,\n fontWeight,\n fontStyle,\n underline,\n letterSpacing,\n textAlign,\n lineHeight,\n splitByGrapheme,\n shapeType,\n borderRadius,\n rxTL,\n rxTR,\n rxBR,\n rxBL,\n triRTop,\n triRBR,\n triRBL,\n imageUrl,\n originX,\n originY,\n };\n}\n\nfunction createTransformReferenceObject(el: CanvasElement): fabric.FabricObject {\n const left = el.left ?? el.position?.x ?? 0;\n const top = el.top ?? el.position?.y ?? 0;\n const width = el.width ?? el.size?.width ?? 100;\n const height = el.height ?? el.size?.height ?? 100;\n\n const common = {\n left,\n top,\n width,\n height,\n scaleX: el.scaleX ?? 1,\n scaleY: el.scaleY ?? 1,\n angle: el.angle ?? el.rotation ?? 0,\n skewX: el.skewX ?? 0,\n skewY: el.skewY ?? 0,\n flipX: el.flipX ?? false,\n flipY: el.flipY ?? false,\n originX: el.originX ?? 'left',\n originY: el.originY ?? 'top',\n } as const;\n\n switch (el.type) {\n case 'text': {\n const textbox = new fabric.Textbox(el.text || el.content || '', {\n ...common,\n // Fabric uses these to compute internal layout\n fontSize: el.fontSize ?? el.style?.fontSize ?? 16,\n fontFamily: el.fontFamily ?? el.style?.fontFamily ?? 'Open Sans',\n lineHeight: el.lineHeight ?? 1.2,\n // Match the canvas splitByGrapheme setting\n splitByGrapheme: el.splitByGrapheme ?? (el.wordWrap === 'break-word'),\n });\n // Initialize dimensions to match canvas behavior\n textbox.initDimensions();\n return textbox;\n }\n\n case 'shape': {\n const shapeType = normalizeShapeType(el.shapeType);\n if (shapeType === 'circle') {\n return new fabric.Ellipse({\n ...common,\n rx: width / 2,\n ry: height / 2,\n });\n }\n\n return new fabric.Rect({\n ...common,\n rx: el.rx ?? el.style?.borderRadius ?? 0,\n ry: el.ry ?? el.style?.borderRadius ?? 0,\n });\n }\n\n case 'line': {\n // Represent line as a simple fabric.Line in local space\n return new fabric.Line([0, 0, width, 0], {\n ...common,\n });\n }\n\n case 'image': {\n // Matrix for image is identical to a rectangle with same box props.\n return new fabric.Rect({\n ...common,\n });\n }\n\n default: {\n return new fabric.Rect({\n ...common,\n });\n }\n }\n}\n// Helper to convert CSS colors to jsPDF-compatible RGB format\nfunction parseColor(color: string | undefined): { r: number; g: number; b: number } | null {\n if (!color) return null;\n\n const raw = color.trim().toLowerCase();\n if (!raw || raw === 'transparent' || raw === 'none') return null;\n\n const clamp = (value: number) => Math.max(0, Math.min(255, Math.round(value)));\n const parseNumeric = (token: string) => {\n const value = parseFloat(token);\n return Number.isFinite(value) ? value : NaN;\n };\n const parseRgbComponent = (token: string) => {\n const value = parseNumeric(token);\n if (!Number.isFinite(value)) return NaN;\n return token.endsWith('%') ? (value / 100) * 255 : value;\n };\n const parseAlpha = (token: string | undefined): number => {\n if (!token) return 1;\n const value = parseNumeric(token);\n if (!Number.isFinite(value)) return 1;\n return token.endsWith('%') ? value / 100 : value;\n };\n\n const toRgbFromHsl = (h: number, s: number, l: number) => {\n const hue = ((h % 360) + 360) % 360;\n const sat = Math.max(0, Math.min(1, s));\n const light = Math.max(0, Math.min(1, l));\n\n if (sat === 0) {\n const gray = clamp(light * 255);\n return { r: gray, g: gray, b: gray };\n }\n\n const q = light < 0.5 ? light * (1 + sat) : light + sat - light * sat;\n const p = 2 * light - q;\n const hueToRgb = (t: number) => {\n let tt = t;\n if (tt < 0) tt += 1;\n if (tt > 1) tt -= 1;\n if (tt < 1 / 6) return p + (q - p) * 6 * tt;\n if (tt < 1 / 2) return q;\n if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6;\n return p;\n };\n\n return {\n r: clamp(hueToRgb(hue / 360 + 1 / 3) * 255),\n g: clamp(hueToRgb(hue / 360) * 255),\n b: clamp(hueToRgb(hue / 360 - 1 / 3) * 255),\n };\n };\n\n // #RGB, #RGBA, #RRGGBB, #RRGGBBAA\n if (raw.startsWith('#')) {\n const hex = raw.slice(1);\n const expanded =\n hex.length === 3 || hex.length === 4\n ? hex.split('').map((char) => char + char).join('')\n : hex;\n\n if (expanded.length !== 6 && expanded.length !== 8) return null;\n\n const intValue = parseInt(expanded.slice(0, 6), 16);\n if (!Number.isFinite(intValue)) return null;\n\n if (expanded.length === 8) {\n const alphaHex = parseInt(expanded.slice(6, 8), 16);\n if (Number.isFinite(alphaHex) && alphaHex <= 0) return null;\n }\n\n return {\n r: (intValue >> 16) & 255,\n g: (intValue >> 8) & 255,\n b: intValue & 255,\n };\n }\n\n // rgb()/rgba() in comma or space syntax (e.g. rgb(255,0,0), rgb(255 0 0 / 50%))\n const rgbMatch = raw.match(/^rgba?\\((.+)\\)$/);\n if (rgbMatch) {\n const normalized = rgbMatch[1].replace(/\\//g, ' ').replace(/,/g, ' ');\n const parts = normalized.split(/\\s+/).filter(Boolean);\n if (parts.length >= 3) {\n const alpha = parseAlpha(parts[3]);\n if (alpha <= 0) return null;\n\n const r = parseRgbComponent(parts[0]);\n const g = parseRgbComponent(parts[1]);\n const b = parseRgbComponent(parts[2]);\n if (Number.isFinite(r) && Number.isFinite(g) && Number.isFinite(b)) {\n return { r: clamp(r), g: clamp(g), b: clamp(b) };\n }\n }\n }\n\n // hsl()/hsla() in comma or space syntax\n const hslMatch = raw.match(/^hsla?\\((.+)\\)$/);\n if (hslMatch) {\n const normalized = hslMatch[1].replace(/\\//g, ' ').replace(/,/g, ' ');\n const parts = normalized.split(/\\s+/).filter(Boolean);\n if (parts.length >= 3) {\n const alpha = parseAlpha(parts[3]);\n if (alpha <= 0) return null;\n\n const h = parseNumeric(parts[0].replace(/deg$/, ''));\n const sRaw = parseNumeric(parts[1].replace(/%$/, ''));\n const lRaw = parseNumeric(parts[2].replace(/%$/, ''));\n if (Number.isFinite(h) && Number.isFinite(sRaw) && Number.isFinite(lRaw)) {\n return toRgbFromHsl(h, sRaw / 100, lRaw / 100);\n }\n }\n }\n\n return null;\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((x) => Math.max(0, Math.min(255, Math.round(x))).toString(16).padStart(2, '0')).join('');\n}\n\n/** Mount SVG in document, read computed fill/stroke for every drawable element, set as attributes, unmount. Ensures each path has its actual rendered color so svg2pdf draws orange as orange (not e.g. first-found blue). */\nfunction inlineComputedStyles(svg: Element): void {\n if (typeof document === 'undefined') return;\n const wrap = document.createElement('div');\n wrap.style.cssText = 'position:fixed;left:-9999px;top:0;width:400px;height:400px;overflow:hidden;pointer-events:none';\n const root = svg as SVGElement;\n if (!root.hasAttribute('width')) root.setAttribute('width', '400');\n if (!root.hasAttribute('height')) root.setAttribute('height', '400');\n wrap.appendChild(root);\n document.body.appendChild(wrap);\n try {\n const drawable = ['path', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'line', 'text', 'tspan'];\n function walk(el: Element) {\n const tag = el.tagName?.toLowerCase();\n if (drawable.includes(tag)) {\n const cs = window.getComputedStyle(el as SVGElement);\n const fill = cs.fill;\n const stroke = cs.stroke;\n if (fill && fill !== 'none' && fill !== 'rgba(0, 0, 0, 0)') {\n const parsed = parseColor(fill);\n if (parsed) el.setAttribute('fill', rgbToHex(parsed.r, parsed.g, parsed.b));\n } else if (fill === 'rgba(0, 0, 0, 0)' || fill === 'transparent') {\n // Prevent implicit black fill: svg2pdf defaults to black when no fill is set,\n // so we must explicitly mark transparent fills as 'none'\n el.setAttribute('fill', 'none');\n }\n if (stroke && stroke !== 'none' && stroke !== 'rgba(0, 0, 0, 0)') {\n const parsed = parseColor(stroke);\n if (parsed) el.setAttribute('stroke', rgbToHex(parsed.r, parsed.g, parsed.b));\n }\n }\n for (let i = 0; i < el.children.length; i++) walk(el.children[i]);\n }\n walk(root);\n root.remove();\n } finally {\n if (wrap.parentNode) document.body.removeChild(wrap);\n }\n}\n\ntype PaintStyle = 'FD' | 'F' | 'S';\n\ntype PdfPathOp = {\n op: 'm' | 'l' | 'c' | 'h';\n c: number[];\n};\n\nfunction applyPaintStyle(pdf: jsPDF, style: PaintStyle): void {\n if (style === 'FD') {\n pdf.fillStroke();\n return;\n }\n if (style === 'F') {\n pdf.fill();\n return;\n }\n pdf.stroke();\n}\n\n/**\n * jsPDF path() behaves differently between compat/advanced APIs.\n * Draw with path+explicit paint first, then fallback to path(style).\n */\nfunction drawPathWithStyle(pdf: jsPDF, pathOps: PdfPathOp[], style: PaintStyle): boolean {\n const anyPdf = pdf as any;\n if (typeof anyPdf.path !== 'function') return false;\n\n try {\n anyPdf.path(pathOps);\n applyPaintStyle(pdf, style);\n return true;\n } catch {\n // fallback below\n }\n\n try {\n anyPdf.path(pathOps, style);\n return true;\n } catch {\n return false;\n }\n}\n\n// Draw a rectangle (with optional rounded corners, including individual per-corner radii)\nfunction drawRect(\n pdf: jsPDF,\n x: number, y: number, w: number, h: number,\n fill: string | undefined,\n stroke: string | undefined,\n strokeWidth: number,\n borderRadius?: number,\n rxTL?: number, rxTR?: number, rxBR?: number, rxBL?: number\n): void {\n const fillColor = parseColor(fill);\n const strokeColor = parseColor(stroke);\n\n if (fillColor) {\n pdf.setFillColor(fillColor.r, fillColor.g, fillColor.b);\n }\n if (strokeColor && strokeWidth > 0) {\n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n // Use round joins only for uniformly rounded corners; miter for sharp or mixed corners\n // For individual corners (path-based), always use miter — the Bezier curves handle rounding\n const hasIndividualVals = (rxTL != null && rxTL > 0) || (rxTR != null && rxTR > 0) || (rxBR != null && rxBR > 0) || (rxBL != null && rxBL > 0);\n const hasUniformRounding = !hasIndividualVals && borderRadius != null && borderRadius > 0;\n // For paths with mixed radii, miter is correct — curves handle the rounding, lineJoin only affects straight-line junctions\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin(hasUniformRounding ? 'round' : 'miter');\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap(hasUniformRounding ? 'round' : 'butt');\n }\n\n const style: PaintStyle | undefined = fillColor && strokeColor && strokeWidth > 0\n ? 'FD'\n : fillColor\n ? 'F'\n : strokeColor && strokeWidth > 0\n ? 'S'\n : undefined;\n\n if (!style) return;\n\n const hasIndividualCorners = (rxTL != null && rxTL > 0) || (rxTR != null && rxTR > 0) || (rxBR != null && rxBR > 0) || (rxBL != null && rxBL > 0);\n\n if (hasIndividualCorners) {\n const { tl, tr, br, bl } = getRoundedRectRadii(w, h, {\n rx: borderRadius ?? 0,\n rxTL,\n rxTR,\n rxBR,\n rxBL,\n });\n\n const k = 0.5522847498307936;\n const pathOps: PdfPathOp[] = [\n { op: 'm', c: [x + tl, y] },\n { op: 'l', c: [x + w - tr, y] },\n ...(tr > 0\n ? [{ op: 'c' as const, c: [x + w - tr + tr * k, y, x + w, y + tr - tr * k, x + w, y + tr] }]\n : [{ op: 'l' as const, c: [x + w, y] }]),\n { op: 'l', c: [x + w, y + h - br] },\n ...(br > 0\n ? [{ op: 'c' as const, c: [x + w, y + h - br + br * k, x + w - br + br * k, y + h, x + w - br, y + h] }]\n : [{ op: 'l' as const, c: [x + w, y + h] }]),\n { op: 'l', c: [x + bl, y + h] },\n ...(bl > 0\n ? [{ op: 'c' as const, c: [x + bl - bl * k, y + h, x, y + h - bl + bl * k, x, y + h - bl] }]\n : [{ op: 'l' as const, c: [x, y + h] }]),\n { op: 'l', c: [x, y + tl] },\n ...(tl > 0\n ? [{ op: 'c' as const, c: [x, y + tl - tl * k, x + tl - tl * k, y, x + tl, y] }]\n : [{ op: 'l' as const, c: [x, y] }]),\n { op: 'h', c: [] },\n ];\n\n if (drawPathWithStyle(pdf, pathOps, style)) return;\n }\n\n if (borderRadius && borderRadius > 0) {\n const r = Math.min(borderRadius, w / 2, h / 2);\n pdf.roundedRect(x, y, w, h, r, r, style);\n } else {\n pdf.rect(x, y, w, h, style);\n }\n}\n\n// Draw an ellipse/circle\nfunction drawEllipse(\n pdf: jsPDF,\n cx: number, cy: number, rx: number, ry: number,\n fill: string | undefined,\n stroke: string | undefined,\n strokeWidth: number\n): void {\n const fillColor = parseColor(fill);\n const strokeColor = parseColor(stroke);\n\n if (fillColor) {\n pdf.setFillColor(fillColor.r, fillColor.g, fillColor.b);\n }\n if (strokeColor && strokeWidth > 0) {\n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin('round');\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap('round');\n }\n\n const style: PaintStyle | undefined = fillColor && strokeColor && strokeWidth > 0\n ? 'FD'\n : fillColor\n ? 'F'\n : strokeColor && strokeWidth > 0\n ? 'S'\n : undefined;\n\n if (!style) return;\n if (!Number.isFinite(rx) || !Number.isFinite(ry) || rx <= 0 || ry <= 0) return;\n\n const k = 0.5522847498307936;\n const ox = rx * k;\n const oy = ry * k;\n\n const pathOps: PdfPathOp[] = [\n { op: 'm', c: [cx - rx, cy] },\n { op: 'c', c: [cx - rx, cy - oy, cx - ox, cy - ry, cx, cy - ry] },\n { op: 'c', c: [cx + ox, cy - ry, cx + rx, cy - oy, cx + rx, cy] },\n { op: 'c', c: [cx + rx, cy + oy, cx + ox, cy + ry, cx, cy + ry] },\n { op: 'c', c: [cx - ox, cy + ry, cx - rx, cy + oy, cx - rx, cy] },\n { op: 'h', c: [] },\n ];\n\n if (drawPathWithStyle(pdf, pathOps, style)) return;\n\n pdf.ellipse(cx, cy, rx, ry, style);\n}\n\n// Draw a line\nfunction drawLine(\n pdf: jsPDF,\n x1: number, y1: number, x2: number, y2: number,\n stroke: string | undefined,\n strokeWidth: number,\n dashArray?: string\n) {\n const strokeColor = parseColor(stroke);\n if (!strokeColor || strokeWidth <= 0) return;\n \n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap('round');\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin('round');\n \n // Handle dash patterns\n if (dashArray) {\n const dashes = dashArray.split(/[\\s,]+/).map(Number).filter(n => !isNaN(n));\n if (dashes.length > 0) {\n pdf.setLineDashPattern(dashes, 0);\n }\n }\n \n pdf.line(x1, y1, x2, y2);\n \n // Reset dash pattern\n if (dashArray) {\n pdf.setLineDashPattern([], 0);\n }\n}\n\n// Draw a rounded triangle using SVG-style path converted to PDF path ops\nfunction drawRoundedTrianglePdf(\n pdf: jsPDF,\n x: number, y: number, w: number, h: number,\n svgPath: string,\n fill: string | undefined,\n stroke: string | undefined,\n strokeWidth: number\n): void {\n const fillColor = parseColor(fill);\n const strokeColor = parseColor(stroke);\n\n if (fillColor) pdf.setFillColor(fillColor.r, fillColor.g, fillColor.b);\n if (strokeColor && strokeWidth > 0) {\n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin('miter');\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap('butt');\n if (typeof (pdf as any).setMiterLimit === 'function') (pdf as any).setMiterLimit(TRIANGLE_STROKE_MITER_LIMIT);\n }\n\n const style: PaintStyle | undefined = fillColor && strokeColor && strokeWidth > 0\n ? 'FD'\n : fillColor\n ? 'F'\n : strokeColor && strokeWidth > 0\n ? 'S'\n : undefined;\n\n if (!style) return;\n\n // Parse SVG path and convert to PDF path ops with offset\n const pathOps: PdfPathOp[] = [];\n const tokens = svgPath.match(/[MLQZmlqz]|[-+]?[0-9]*\\.?[0-9]+/g) || [];\n let i = 0;\n while (i < tokens.length) {\n const cmd = tokens[i];\n if (cmd === 'M' || cmd === 'm') {\n i++;\n pathOps.push({ op: 'm', c: [x + parseFloat(tokens[i]), y + parseFloat(tokens[i + 1])] });\n i += 2;\n } else if (cmd === 'L' || cmd === 'l') {\n i++;\n pathOps.push({ op: 'l', c: [x + parseFloat(tokens[i]), y + parseFloat(tokens[i + 1])] });\n i += 2;\n } else if (cmd === 'Q' || cmd === 'q') {\n i++;\n // Convert quadratic bezier to cubic bezier for PDF\n // Q cx,cy ex,ey → approximate with cubic\n const qcx = x + parseFloat(tokens[i]);\n const qcy = y + parseFloat(tokens[i + 1]);\n const qex = x + parseFloat(tokens[i + 2]);\n const qey = y + parseFloat(tokens[i + 3]);\n // Get last point from previous op\n const lastOp = pathOps[pathOps.length - 1];\n const px = lastOp ? lastOp.c[lastOp.c.length - 2] : x;\n const py = lastOp ? lastOp.c[lastOp.c.length - 1] : y;\n // Quadratic to cubic: CP1 = P0 + 2/3*(QCP-P0), CP2 = P1 + 2/3*(QCP-P1)\n const cp1x = px + (2 / 3) * (qcx - px);\n const cp1y = py + (2 / 3) * (qcy - py);\n const cp2x = qex + (2 / 3) * (qcx - qex);\n const cp2y = qey + (2 / 3) * (qcy - qey);\n pathOps.push({ op: 'c', c: [cp1x, cp1y, cp2x, cp2y, qex, qey] });\n i += 4;\n } else if (cmd === 'Z' || cmd === 'z') {\n pathOps.push({ op: 'h', c: [] });\n i++;\n } else {\n i++; // skip unknown\n }\n }\n\n if (drawPathWithStyle(pdf, pathOps, style)) return;\n}\n\n// Draw a polygon (triangles and backwards-compatible legacy polygons)\nfunction drawPolygon(\n pdf: jsPDF,\n points: { x: number; y: number }[],\n fill: string | undefined,\n stroke: string | undefined,\n strokeWidth: number\n) {\n if (points.length < 3) return;\n \n const fillColor = parseColor(fill);\n const strokeColor = parseColor(stroke);\n \n if (fillColor) {\n pdf.setFillColor(fillColor.r, fillColor.g, fillColor.b);\n }\n if (strokeColor && strokeWidth > 0) {\n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin('miter');\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap('butt');\n if (typeof (pdf as any).setMiterLimit === 'function') (pdf as any).setMiterLimit(TRIANGLE_STROKE_MITER_LIMIT);\n }\n \n const style: PaintStyle | undefined = fillColor && strokeColor && strokeWidth > 0\n ? 'FD'\n : fillColor\n ? 'F'\n : strokeColor && strokeWidth > 0\n ? 'S'\n : undefined;\n \n if (!style) return;\n\n const pathOps: PdfPathOp[] = [\n { op: 'm', c: [points[0].x, points[0].y] },\n ...points.slice(1).map((point) => ({ op: 'l' as const, c: [point.x, point.y] })),\n { op: 'h', c: [] },\n ];\n\n if (drawPathWithStyle(pdf, pathOps, style)) return;\n \n // Fallback for older jsPDF path APIs\n pdf.moveTo(points[0].x, points[0].y);\n for (let i = 1; i < points.length; i++) {\n pdf.lineTo(points[i].x, points[i].y);\n }\n pdf.lineTo(points[0].x, points[0].y);\n applyPaintStyle(pdf, style);\n}\n\n/**\n * Add a clickable link annotation to the PDF\n * jsPDF uses bottom-left origin, so we need to flip Y coordinates\n */\nfunction addLinkAnnotation(\n pdf: jsPDF,\n url: string,\n x: number,\n y: number,\n w: number,\n h: number,\n canvasHeight: number\n): void {\n if (!url || !url.trim()) return;\n \n try {\n // jsPDF link uses top-left origin when unit is 'px' with hotfixes\n // The link method signature: link(x, y, w, h, options)\n pdf.link(x, y, w, h, { url: url.trim() });\n } catch {\n // Link annotation failed (e.g. invalid URL); skip\n }\n}\n\n// Draw text with proper font handling\n// IMPORTANT: jsPDF always interprets setFontSize() as POINTS, even when unit is 'px'.\n// Canvas/Fabric uses pixels, so we must convert: points = pixels * 72 / 96 = pixels * 0.75\nconst PX_TO_PT = 72 / 96; // 0.75\n// Fabric getHeightOfLine() includes _fontSizeMult (1.13) for underline/overline space. Use a slightly\n// higher divisor for the first line so text sits edge-to-edge with the section (not a little bit down).\nconst FABRIC_FONT_SIZE_MULT = 1.13;\nconst FIRST_LINE_BASELINE_MULT = 1.18;\n/** Nudge all text up by this many px so it aligns edge-to-edge with the section in PDF. */\nconst TEXT_UP_NUDGE_PX = 2;\n\n/** Scale down symbol (fallback font) size in PDF so it matches canvas. Tweak if still off: lower = smaller in PDF, higher = larger. */\nconst SYMBOL_FONT_SCALE = 0.78;\n\nfunction drawText(\n pdf: jsPDF,\n text: string,\n x: number, y: number, width: number,\n fontSizePx: number,\n fontFamily: string,\n fontWeight: number,\n fontStyle: 'normal' | 'italic',\n underline: boolean,\n letterSpacing: number,\n fill: string | undefined,\n textAlign: 'left' | 'center' | 'right',\n lineHeight: number,\n embeddedFonts: Set<string>,\n splitByGrapheme: boolean = true,\n liveFabricText?: fabric.FabricObject | null\n): void {\n const fillColor = parseColor(fill);\n if (!fillColor) return;\n \n // Convert pixel font size to points for jsPDF\n const fontSizePt = fontSizePx * PX_TO_PT;\n \n pdf.setTextColor(fillColor.r, fillColor.g, fillColor.b);\n pdf.setFontSize(fontSizePt);\n \n // Try to use actual italic font if available, otherwise fall back to skew transform\n const isItalic = fontStyle === 'italic';\n const resolvedWeight = resolveFontWeight(fontWeight);\n const fontKey = `${fontFamily}${FONT_KEY_SEP}${resolvedWeight}`;\n const italicFontKey = `${fontFamily}${FONT_KEY_SEP}${resolvedWeight}${FONT_KEY_SEP}italic`;\n const hasEmbeddedItalic = isItalic && embeddedFonts.has(italicFontKey);\n\n const mainJsPdfFontName = hasEmbeddedItalic\n ? (embeddedFonts.has(italicFontKey) ? getEmbeddedJsPDFFontName(fontFamily, fontWeight, true) : null)\n : (embeddedFonts.has(fontKey) ? getEmbeddedJsPDFFontName(fontFamily, fontWeight) : null);\n const mainStyle = fontWeight >= 600 ? 'bold' : 'normal';\n if (mainJsPdfFontName) {\n try {\n pdf.setFont(mainJsPdfFontName, 'normal');\n } catch {\n pdf.setFont('helvetica', mainStyle);\n }\n } else {\n pdf.setFont('helvetica', mainStyle);\n }\n // Only use skew for italic if we don't have an actual italic font embedded\n const useSkewForItalic = isItalic && !hasEmbeddedItalic;\n\n const fallbackFontKey = `${FONT_FALLBACK_SYMBOLS}${FONT_KEY_SEP}400`;\n const fallbackJsPdfName = embeddedFonts.has(fallbackFontKey) ? getEmbeddedJsPDFFontName(FONT_FALLBACK_SYMBOLS, 400) : null;\n\n const devanagariWeight = resolveFontWeight(fontWeight);\n const devanagariFontKey = `${FONT_FALLBACK_DEVANAGARI}${FONT_KEY_SEP}${devanagariWeight}`;\n const devanagariJsPdfName = embeddedFonts.has(devanagariFontKey) ? getEmbeddedJsPDFFontName(FONT_FALLBACK_DEVANAGARI, devanagariWeight) : null;\n\n function setRunFont(runType: RunType): void {\n if (runType === 'devanagari' && devanagariJsPdfName) {\n try { pdf.setFont(devanagariJsPdfName, 'normal'); } catch {\n if (mainJsPdfFontName) pdf.setFont(mainJsPdfFontName, 'normal');\n else pdf.setFont('helvetica', mainStyle);\n }\n } else if (runType === 'symbol' && fallbackJsPdfName) {\n try { pdf.setFont(fallbackJsPdfName, 'normal'); } catch {\n if (mainJsPdfFontName) pdf.setFont(mainJsPdfFontName, 'normal');\n else pdf.setFont('helvetica', mainStyle);\n }\n } else if (mainJsPdfFontName) {\n try {\n pdf.setFont(mainJsPdfFontName, 'normal');\n } catch {\n pdf.setFont('helvetica', mainStyle);\n }\n } else {\n pdf.setFont('helvetica', mainStyle);\n }\n }\n\n // Apply letter spacing if set (Fabric.js charSpacing is in 1/1000 em units)\n const charSpacePt = letterSpacing !== 0 ? (letterSpacing / 1000) * fontSizePt : 0;\n if (letterSpacing !== 0) {\n try {\n (pdf as any).setCharSpace?.(charSpacePt);\n } catch {\n // Ignore if not supported\n }\n }\n \n // Prefer live Fabric text object so line positions match preview exactly (WYSIWYG)\n let textLines: string[] = [];\n let getBaselineFromTopPx: (lineIndex: number) => number;\n let getLineLeftOffset: (lineIndex: number) => number;\n // Live object line heights are in canvas/design units (same as PDF points). Fallback Textbox uses px.\n let baselineInPoints = false;\n\n if (liveFabricText && typeof (liveFabricText as any).getHeightOfLine === 'function') {\n const live = liveFabricText as any;\n // Fabric: textLines is string[] (line strings); _textLines is string[][] (grapheme lines)\n textLines = (live.textLines && Array.isArray(live.textLines) ? live.textLines : []).map((line: string | string[]) => Array.isArray(line) ? line.join('') : line);\n const lh = (live.lineHeight ?? lineHeight) || 1.2;\n baselineInPoints = true; // Live object uses same coordinate system as canvas = PDF points\n getBaselineFromTopPx = (lineIndex: number): number => {\n let sum = 0;\n for (let j = 0; j < lineIndex; j++) {\n sum += live.getHeightOfLine(j);\n }\n const lineH = live.getHeightOfLine(lineIndex);\n return sum + lineH / lh;\n };\n getLineLeftOffset = (i: number) => (typeof live._getLineLeftOffset === 'function' ? live._getLineLeftOffset(i) : 0) ?? 0;\n } else {\n // Fallback: create a Fabric Textbox with same settings for layout (measures in px)\n const textbox = new fabric.Textbox(text, {\n width,\n fontSize: fontSizePx,\n fontFamily,\n fontWeight: String(fontWeight),\n charSpacing: letterSpacing,\n textAlign,\n lineHeight: lineHeight || 1.2,\n splitByGrapheme,\n left: 0,\n top: 0,\n originX: 'left',\n originY: 'top',\n });\n textbox.initDimensions();\n textLines = textbox.textLines || [];\n const lh = lineHeight || 1.2;\n getBaselineFromTopPx = (lineIndex: number): number => {\n let sum = 0;\n for (let j = 0; j < lineIndex; j++) {\n sum += (textbox as any).getHeightOfLine?.(j) ?? (fontSizePx * lh);\n }\n const lineH = (textbox as any).getHeightOfLine?.(lineIndex) ?? (fontSizePx * lh);\n return sum + lineH / lh;\n };\n getLineLeftOffset = (i: number) => (textbox as any)._getLineLeftOffset?.(i) ?? 0;\n }\n\n if (textLines.length === 0) return;\n \n // Italic skew angle (approx 12 degrees, like CSS oblique)\n const italicSkewAngle = isItalic ? -0.21 : 0; // tan(12°) ≈ 0.21\n \n // Draw each line at its Fabric.js-calculated position (by runs so symbols like ● use fallback font)\n for (let i = 0; i < textLines.length; i++) {\n const lineText = textLines[i];\n if (!lineText) continue;\n\n // ── Fast-path: pure Latin line → single pdf.text() call, no run-splitting ──\n const pureLatin = isPureLatin(lineText);\n\n let totalLineWidth: number;\n if (pureLatin) {\n setRunFont('main');\n totalLineWidth = pdf.getTextWidth(lineText);\n } else {\n const runs = splitLineIntoRuns(lineText);\n totalLineWidth = 0;\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n totalLineWidth += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) totalLineWidth += charSpacePt;\n }\n // Store runs for rendering below\n (lineText as any).__runs = runs;\n }\n\n let lineLeftOffset = getLineLeftOffset(i);\n if (lineLeftOffset === 0 && (textAlign === 'center' || textAlign === 'right')) {\n if (textAlign === 'center') {\n lineLeftOffset = (width - totalLineWidth) / 2;\n } else if (textAlign === 'right') {\n lineLeftOffset = width - totalLineWidth;\n }\n }\n\n const rawBaseline = getBaselineFromTopPx(i);\n const firstLineRaw = getBaselineFromTopPx(0);\n const baselineFromTop = i === 0\n ? rawBaseline / FIRST_LINE_BASELINE_MULT\n : (firstLineRaw / FIRST_LINE_BASELINE_MULT) + (rawBaseline - firstLineRaw);\n const lineY = y + (baselineInPoints ? baselineFromTop : baselineFromTop * PX_TO_PT) - TEXT_UP_NUDGE_PX;\n const lineX = x + lineLeftOffset;\n\n if (pureLatin) {\n // Single call — no font switching, preserves exact pre-Hindi metrics\n setRunFont('main');\n if (useSkewForItalic) {\n (pdf as any).saveGraphicsState?.();\n try {\n const pdfInternal = (pdf as any).internal;\n if (pdfInternal?.write) {\n pdfInternal.write('q');\n pdfInternal.write(`1 0 ${italicSkewAngle.toFixed(4)} 1 ${lineX.toFixed(2)} ${lineY.toFixed(2)} cm`);\n pdf.text(lineText, 0, 0);\n pdfInternal.write('Q');\n } else {\n pdf.text(lineText, lineX, lineY);\n }\n } catch {\n pdf.text(lineText, lineX, lineY);\n }\n (pdf as any).restoreGraphicsState?.();\n } else {\n pdf.text(lineText, lineX, lineY);\n }\n } else {\n // Multi-run path for non-Latin text\n const runs: { text: string; runType: RunType }[] = (lineText as any).__runs || splitLineIntoRuns(lineText);\n let runX = lineX;\n\n if (useSkewForItalic) {\n (pdf as any).saveGraphicsState?.();\n try {\n const pdfInternal = (pdf as any).internal;\n if (pdfInternal?.write) {\n pdfInternal.write('q');\n pdfInternal.write(`1 0 ${italicSkewAngle.toFixed(4)} 1 ${lineX.toFixed(2)} ${lineY.toFixed(2)} cm`);\n runX = 0;\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n pdf.text(runs[r].text, runX, 0);\n runX += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) runX += charSpacePt;\n }\n pdfInternal.write('Q');\n } else {\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n pdf.text(runs[r].text, runX, lineY);\n runX += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) runX += charSpacePt;\n }\n }\n } catch {\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n pdf.text(runs[r].text, runX, lineY);\n runX += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) runX += charSpacePt;\n }\n }\n (pdf as any).restoreGraphicsState?.();\n } else {\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n pdf.text(runs[r].text, runX, lineY);\n runX += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) runX += charSpacePt;\n }\n }\n }\n\n if (underline && lineText.trim()) {\n const underlineY = lineY + fontSizePt * 0.15;\n const underlineThickness = Math.max(0.5, fontSizePt * 0.066667);\n pdf.setDrawColor(fillColor.r, fillColor.g, fillColor.b);\n pdf.setLineWidth(underlineThickness);\n pdf.line(lineX, underlineY, lineX + totalLineWidth, underlineY);\n }\n }\n \n // Reset letter spacing\n if (letterSpacing !== 0) {\n try {\n (pdf as any).setCharSpace?.(0);\n } catch {\n // Ignore\n }\n }\n}\n\ntype PdfImageData = { data: string; format: 'PNG' | 'JPEG' };\n\ntype FetchImageOptions = {\n /** Used when we must flatten transparency (fallback). */\n backgroundColor?: string;\n /** Target placement size in PDF points (used to downscale for speed/size). */\n targetWidthPt?: number;\n targetHeightPt?: number;\n /** If true, preserve transparency (e.g., border/frame overlays). */\n preserveAlpha?: boolean;\n /** Extra scale for rasterization (e.g. 4 for SVG so PDF stays sharp when zoomed). */\n resolutionMultiplier?: number;\n};\n\nfunction normalizeBgColor(bg?: string): string {\n if (!bg || bg === 'transparent' || bg === 'none') return '#ffffff';\n return bg;\n}\n\nfunction blobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = () => reject(new Error('Failed to read blob'));\n reader.readAsDataURL(blob);\n });\n}\n\nfunction readPngHeader(buf: ArrayBuffer): { bitDepth: number; colorType: number } | null {\n try {\n const bytes = new Uint8Array(buf);\n // PNG signature\n if (\n bytes[0] !== 0x89 ||\n bytes[1] !== 0x50 ||\n bytes[2] !== 0x4e ||\n bytes[3] !== 0x47\n ) {\n return null;\n }\n\n // Must have IHDR first\n const type = String.fromCharCode(bytes[12], bytes[13], bytes[14], bytes[15]);\n if (type !== 'IHDR') return null;\n\n const bitDepth = bytes[24];\n const colorType = bytes[25];\n return { bitDepth, colorType };\n } catch {\n return null;\n }\n}\n\nasync function detectAlpha(blob: Blob): Promise<boolean> {\n const bitmap = await createImageBitmap(blob);\n const w = 32;\n const h = 32;\n const c = document.createElement('canvas');\n c.width = w;\n c.height = h;\n const ctx = c.getContext('2d');\n if (!ctx) return false;\n ctx.clearRect(0, 0, w, h);\n ctx.drawImage(bitmap, 0, 0, w, h);\n const data = ctx.getImageData(0, 0, w, h).data;\n for (let i = 3; i < data.length; i += 4) {\n if (data[i] !== 255) return true;\n }\n return false;\n}\n\nfunction getTargetPixelSize(bitmap: ImageBitmap, opts: FetchImageOptions): { w: number; h: number } {\n // Points are 1/72\"; for sharp output we aim ~144 DPI (= 2 px per point). SVG uses higher multiplier so zoom stays crisp.\n const dpiScale = 1.5 * (opts.resolutionMultiplier ?? 1);\n const maxPx = opts.resolutionMultiplier && opts.resolutionMultiplier > 1 ? 4400 : 2200;\n const capByBitmap = !(opts.resolutionMultiplier && opts.resolutionMultiplier > 1);\n\n const desiredW = Math.max(1, Math.round((opts.targetWidthPt ?? bitmap.width) * dpiScale));\n const desiredH = Math.max(1, Math.round((opts.targetHeightPt ?? bitmap.height) * dpiScale));\n\n return {\n w: Math.min(maxPx, desiredW, capByBitmap ? bitmap.width : Infinity),\n h: Math.min(maxPx, desiredH, capByBitmap ? bitmap.height : Infinity),\n };\n}\n\nasync function rasterizeToDataUrl(\n blob: Blob,\n opts: FetchImageOptions,\n out: 'PNG' | 'JPEG',\n flattenBackground?: boolean\n): Promise<string> {\n const bitmap = await createImageBitmap(blob);\n const { w, h } = getTargetPixelSize(bitmap, opts);\n\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('Canvas context not available');\n\n // If flattening, paint background first (prevents black where alpha existed)\n if (flattenBackground) {\n ctx.fillStyle = normalizeBgColor(opts.backgroundColor);\n ctx.fillRect(0, 0, w, h);\n } else {\n ctx.clearRect(0, 0, w, h);\n }\n\n ctx.imageSmoothingEnabled = true;\n try {\n // @ts-ignore\n ctx.imageSmoothingQuality = 'high';\n } catch {\n // ignore\n }\n\n ctx.drawImage(bitmap, 0, 0, w, h);\n\n if (out === 'JPEG') {\n return canvas.toDataURL('image/jpeg', 0.82);\n }\n return canvas.toDataURL('image/png');\n}\n\n// Fetch image for PDF embedding.\n// Strategy:\n// - If the proxy returns real PNG/JPEG: embed original bytes (small + preserves alpha)\n// - If it returns WEBP/AVIF or a 16-bit PNG: rasterize to an 8-bit PNG (keeps alpha)\n// - Only flatten to JPEG when the image has no alpha (smaller) or as a last-resort\nasync function fetchImageAsBase64(imageUrl: string, opts: FetchImageOptions = {}): Promise<PdfImageData | null> {\n try {\n const forcePreserveAlpha = opts.preserveAlpha === true;\n\n // Normalize data URLs (some may be WEBP/PNG/etc)\n if (imageUrl.startsWith('data:')) {\n const res = await fetch(imageUrl);\n const blob = await res.blob();\n const type = (blob.type || '').toLowerCase();\n\n if (type === 'image/jpeg' || type === 'image/jpg') {\n return { data: imageUrl, format: 'JPEG' };\n }\n\n if (forcePreserveAlpha) {\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', false);\n return { data: pngUrl, format: 'PNG' };\n }\n\n const hasAlpha = await detectAlpha(blob);\n if (hasAlpha) {\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', false);\n return { data: pngUrl, format: 'PNG' };\n }\n\n const jpegUrl = await rasterizeToDataUrl(blob, opts, 'JPEG', true);\n return { data: jpegUrl, format: 'JPEG' };\n }\n\n // Determine fetch URL (proxy for external URLs via API server or Supabase edge function)\n let fetchUrl = imageUrl;\n if (imageUrl.startsWith('http://') || imageUrl.startsWith('https://')) {\n const { isPrivateUrl } = await import('./canvasImageLoader');\n if (isPrivateUrl(imageUrl)) return null;\n const proxyUrl = new URL(`${API_URL}/image-proxy`);\n proxyUrl.searchParams.set('url', imageUrl);\n fetchUrl = proxyUrl.toString();\n }\n\n const response = await fetch(fetchUrl, { cache: 'no-store', ...getImageProxyFetchOptions() });\n\n if (!response.ok) return null;\n\n const blob = await response.blob();\n const type = (blob.type || '').toLowerCase();\n\n // JPEG: keep as-is\n if (type === 'image/jpeg' || type === 'image/jpg') {\n const dataUrl = await blobToDataUrl(blob);\n return { data: dataUrl, format: 'JPEG' };\n }\n\n // PNG: try to embed original bytes (best size + preserves transparency)\n if (type === 'image/png') {\n const buf = await blob.arrayBuffer();\n const hdr = readPngHeader(buf);\n\n // 16-bit PNGs are known to break/blur in some jsPDF versions -> rasterize to 8-bit\n if (hdr?.bitDepth === 16) {\n const flattenWithBg = !forcePreserveAlpha && !!(opts.backgroundColor && opts.backgroundColor !== 'transparent' && opts.backgroundColor !== 'none');\n const pngUrl = await rasterizeToDataUrl(new Blob([buf], { type: 'image/png' }), opts, 'PNG', flattenWithBg);\n return { data: pngUrl, format: 'PNG' };\n }\n\n if (forcePreserveAlpha) {\n const dataUrl = await blobToDataUrl(blob);\n return { data: dataUrl, format: 'PNG' };\n }\n\n // When we have a background color, rasterize so transparent areas show it in PDF (not black)\n const flattenWithBg = !!(opts.backgroundColor && opts.backgroundColor !== 'transparent' && opts.backgroundColor !== 'none');\n if (flattenWithBg) {\n const hasAlpha = hdr?.colorType === 4 || hdr?.colorType === 6; // grayscale+alpha or RGBA\n if (hasAlpha) {\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', true);\n return { data: pngUrl, format: 'PNG' };\n }\n }\n\n // For typical 8-bit PNGs (including transparent frames), embed original bytes.\n const dataUrl = await blobToDataUrl(blob);\n return { data: dataUrl, format: 'PNG' };\n }\n\n // WEBP/AVIF/GIF/SVG/etc: rasterize.\n if (forcePreserveAlpha) {\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', false);\n return { data: pngUrl, format: 'PNG' };\n }\n\n const hasAlpha = await detectAlpha(blob);\n if (hasAlpha) {\n // Flatten with background when provided so transparent areas show page color in PDF (not black)\n const flattenWithBg = !!(opts.backgroundColor && opts.backgroundColor !== 'transparent' && opts.backgroundColor !== 'none');\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', flattenWithBg);\n return { data: pngUrl, format: 'PNG' };\n }\n\n const jpegUrl = await rasterizeToDataUrl(blob, opts, 'JPEG', true);\n return { data: jpegUrl, format: 'JPEG' };\n } catch {\n return null;\n }\n}\n\n// Generate polygon points for various shapes\nfunction getShapePoints(\n shapeType: string,\n x: number, y: number, w: number, h: number\n): { x: number; y: number }[] | null {\n const cx = x + w / 2;\n const cy = y + h / 2;\n \n switch (shapeType) {\n case 'triangle':\n return getTrianglePoints(x, y, w, h);\n\n case 'diamond':\n return [\n { x: cx, y: y },\n { x: x + w, y: cy },\n { x: cx, y: y + h },\n { x: x, y: cy },\n ];\n \n case 'pentagon':\n return generateRegularPolygon(5, cx, cy, Math.min(w, h) / 2);\n \n case 'hexagon':\n return generateRegularPolygon(6, cx, cy, Math.min(w, h) / 2);\n \n case 'octagon':\n return generateRegularPolygon(8, cx, cy, Math.min(w, h) / 2);\n \n case 'star':\n return generateStar(5, cx, cy, Math.min(w, h) / 2);\n \n case 'arrow':\n return [\n { x: x, y: y + h * 0.3 },\n { x: x + w * 0.6, y: y + h * 0.3 },\n { x: x + w * 0.6, y: y },\n { x: x + w, y: cy },\n { x: x + w * 0.6, y: y + h },\n { x: x + w * 0.6, y: y + h * 0.7 },\n { x: x, y: y + h * 0.7 },\n ];\n \n case 'parallelogram':\n return [\n { x: x + w * 0.2, y: y },\n { x: x + w, y: y },\n { x: x + w * 0.8, y: y + h },\n { x: x, y: y + h },\n ];\n \n case 'trapezoid':\n return [\n { x: x + w * 0.2, y: y },\n { x: x + w * 0.8, y: y },\n { x: x + w, y: y + h },\n { x: x, y: y + h },\n ];\n \n case 'cross':\n const t = 0.35; // thickness ratio\n return [\n { x: x + w * t, y: y },\n { x: x + w * (1 - t), y: y },\n { x: x + w * (1 - t), y: y + h * t },\n { x: x + w, y: y + h * t },\n { x: x + w, y: y + h * (1 - t) },\n { x: x + w * (1 - t), y: y + h * (1 - t) },\n { x: x + w * (1 - t), y: y + h },\n { x: x + w * t, y: y + h },\n { x: x + w * t, y: y + h * (1 - t) },\n { x: x, y: y + h * (1 - t) },\n { x: x, y: y + h * t },\n { x: x + w * t, y: y + h * t },\n ];\n \n default:\n return null;\n }\n}\n\nfunction generateRegularPolygon(sides: number, cx: number, cy: number, radius: number): { x: number; y: number }[] {\n const points: { x: number; y: number }[] = [];\n const angleOffset = -Math.PI / 2;\n \n for (let i = 0; i < sides; i++) {\n const angle = angleOffset + (2 * Math.PI * i) / sides;\n points.push({\n x: cx + radius * Math.cos(angle),\n y: cy + radius * Math.sin(angle),\n });\n }\n \n return points;\n}\n\nfunction generateStar(points: number, cx: number, cy: number, outerRadius: number): { x: number; y: number }[] {\n const result: { x: number; y: number }[] = [];\n const innerRadius = outerRadius * 0.4;\n const angleOffset = -Math.PI / 2;\n \n for (let i = 0; i < points * 2; i++) {\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const angle = angleOffset + (Math.PI * i) / points;\n result.push({\n x: cx + radius * Math.cos(angle),\n y: cy + radius * Math.sin(angle),\n });\n }\n \n return result;\n}\n\n/**\n * Matrix math helpers (2D affine) for converting Fabric.js transforms to jsPDF's ADVANCED mode.\n *\n * Fabric canvas space: origin top-left, +Y down.\n * jsPDF ADVANCED space: origin bottom-left, +Y up.\n */\n\ntype Matrix6 = [number, number, number, number, number, number];\n\nfunction mulM(a: Matrix6, b: Matrix6): Matrix6 {\n return [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n a[0] * b[4] + a[2] * b[5] + a[4],\n a[1] * b[4] + a[3] * b[5] + a[5],\n ];\n}\n\nfunction getMatrixScaleFactors(matrix: number[] | Matrix6 | null | undefined): { sx: number; sy: number } {\n if (!matrix || matrix.length !== 6) return { sx: 1, sy: 1 };\n const [a, b, c, d] = matrix;\n const sx = Math.hypot(a, b);\n const sy = Math.hypot(c, d);\n return {\n sx: Number.isFinite(sx) && sx > 0 ? sx : 1,\n sy: Number.isFinite(sy) && sy > 0 ? sy : 1,\n };\n}\n\nfunction getStrokeScaleCompensationForMatrix(element: CanvasElement, matrix: number[] | Matrix6 | null | undefined): number {\n if (element.type !== 'shape' && element.type !== 'line') return 1;\n\n const { sx, sy } = getMatrixScaleFactors(matrix);\n if (sx <= 0 || sy <= 0) return 1;\n\n const isUniformScale = Math.abs(sx - sy) < 0.0001;\n const referenceScale = isUniformScale ? sx : Math.max(sx, sy);\n if (!Number.isFinite(referenceScale) || referenceScale <= 0) return 1;\n\n const compensation = 1 / referenceScale;\n return Math.max(0.0001, Math.min(1000, compensation));\n}\n\nfunction withCompensatedStrokeWidth(\n norm: ReturnType<typeof normalizeElement>,\n element: CanvasElement,\n matrix: number[] | Matrix6 | null | undefined\n): ReturnType<typeof normalizeElement> {\n if (norm.strokeWidth <= 0) return norm;\n\n const compensation = getStrokeScaleCompensationForMatrix(element, matrix);\n if (Math.abs(compensation - 1) < 0.0001) return norm;\n\n return {\n ...norm,\n strokeWidth: Number((norm.strokeWidth * compensation).toFixed(4)),\n };\n}\n\n/**\n * Convert a Fabric calcTransformMatrix() into a matrix usable in jsPDF ADVANCED mode.\n *\n * IMPORTANT: jsPDF's coordinate system is also Y-down (like canvas), even in advancedAPI.\n * So we can apply Fabric's matrix directly.\n */\nfunction fabricMatrixToJsPdfAdvancedMatrix(fabricM: number[], _pageHeight: number): Matrix6 {\n return (fabricM.length === 6 ? (fabricM as Matrix6) : ([1, 0, 0, 1, 0, 0] as Matrix6));\n}\n\n/** Stored crop/natural from element – used at export so we don't rely on Fabric's baked state after move. */\ninterface StoredCropExportInfo {\n naturalWidth?: number;\n naturalHeight?: number;\n panX?: number;\n panY?: number;\n zoom?: number;\n}\n\n/**\n * Rasterize a crop group (masked image) to PNG with clipPath applied.\n * When forceBlobReplace is true (retry after SecurityError), replace clone's image with same-origin blob.\n * Prefer stored when present so export is correct after move.\n * When backgroundColor is set, transparent areas of the image (e.g. transparent SVG) are filled with that\n * color so the PDF matches the preview (no black behind transparent regions).\n */\nasync function rasterizeCropGroupToPng(\n liveGroup: fabric.Group,\n frameW: number,\n frameH: number,\n multiplier = 2,\n maintainResolution = false,\n imageUrl?: string,\n forceBlobReplace = false,\n stored?: StoredCropExportInfo,\n backgroundColor?: string\n): Promise<string> {\n const bgFill = backgroundColor && backgroundColor !== 'transparent' && backgroundColor !== 'none'\n ? normalizeBgColor(backgroundColor)\n : undefined;\n const cropData = (liveGroup as any).__cropData;\n const rxRatio = cropData?.rx || 0;\n const minFrameDim = Math.min(frameW, frameH);\n const clipRx = Math.min(rxRatio > 0.5 ? rxRatio : rxRatio * minFrameDim, frameW / 2, frameH / 2);\n const shape = cropData?.shape || 'rect';\n const panX = Math.max(0, Math.min(1, stored?.panX ?? (cropData?._img as any)?._ct?.panX ?? 0.5));\n const panY = Math.max(0, Math.min(1, stored?.panY ?? (cropData?._img as any)?._ct?.panY ?? 0.5));\n const zoom = Math.max(1, stored?.zoom ?? (cropData?._img as any)?._ct?.zoom ?? 1);\n\n // Keep Resolution: full-resolution 2D canvas crop (any URL including data:). Embed visible crop at 1:1 pixels, draw at frame size in PDF.\n if (maintainResolution && imageUrl) {\n const dims = await loadNaturalDimensionsFromUrl(imageUrl);\n const natW = dims?.width ?? stored?.naturalWidth ?? frameW;\n const natH = dims?.height ?? stored?.naturalHeight ?? frameH;\n const useNatW = natW > 0 && natH > 0 ? natW : frameW;\n const useNatH = natW > 0 && natH > 0 ? natH : frameH;\n if (useNatW > frameW || useNatH > frameH) {\n let htmlImg: HTMLImageElement | null = null;\n if (imageUrl.startsWith('data:') || imageUrl.startsWith('blob:')) {\n try {\n htmlImg = await new Promise<HTMLImageElement>((resolve, reject) => {\n const im = new Image();\n im.onload = () => resolve(im);\n im.onerror = () => reject(new Error('Image load failed'));\n im.src = imageUrl;\n });\n } catch {\n htmlImg = null;\n }\n } else {\n try {\n const proxied = getProxiedImageUrl(imageUrl);\n const res = await fetch(proxied);\n if (!res.ok) throw new Error('Fetch failed');\n const blob = await res.blob();\n const blobUrl = URL.createObjectURL(blob);\n try {\n htmlImg = await new Promise<HTMLImageElement>((resolve, reject) => {\n const im = new Image();\n im.crossOrigin = 'anonymous';\n im.onload = () => resolve(im);\n im.onerror = () => reject(new Error('Image load failed'));\n im.src = blobUrl;\n });\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n } catch {\n htmlImg = null;\n }\n }\n if (htmlImg) {\n const iw = htmlImg.naturalWidth || useNatW;\n const ih = htmlImg.naturalHeight || useNatH;\n const baseScale = Math.max(frameW / iw, frameH / ih);\n const finalScale = baseScale * zoom;\n const drawW = iw * finalScale;\n const drawH = ih * finalScale;\n const overflowX = Math.max(0, drawW - frameW);\n const overflowY = Math.max(0, drawH - frameH);\n const offsetX = overflowX > 0 ? -overflowX * (panX - 0.5) : 0;\n const offsetY = overflowY > 0 ? -overflowY * (panY - 0.5) : 0;\n const imageLeft = frameW / 2 + offsetX - (iw * finalScale) / 2;\n const imageTop = frameH / 2 + offsetY - (ih * finalScale) / 2;\n const srcX = Math.max(0, Math.floor(-imageLeft / finalScale));\n const srcY = Math.max(0, Math.floor(-imageTop / finalScale));\n const srcW = Math.min(Math.ceil(frameW / finalScale), iw - srcX);\n const srcH = Math.min(Math.ceil(frameH / finalScale), ih - srcY);\n if (srcW >= 1 && srcH >= 1) {\n const cropCanvas = document.createElement('canvas');\n cropCanvas.width = srcW;\n cropCanvas.height = srcH;\n const ctx = cropCanvas.getContext('2d');\n if (ctx) {\n if (bgFill) {\n ctx.fillStyle = bgFill;\n ctx.fillRect(0, 0, srcW, srcH);\n } else {\n ctx.clearRect(0, 0, srcW, srcH);\n }\n ctx.drawImage(htmlImg, srcX, srcY, srcW, srcH, 0, 0, srcW, srcH);\n // Apply clip shape (circle or rounded rect) so export matches preview\n if (shape === 'circle' || shape === 'roundRect' || shape === 'rect') {\n ctx.globalCompositeOperation = 'destination-in';\n if (shape === 'circle') {\n ctx.beginPath();\n ctx.ellipse(srcW / 2, srcH / 2, srcW / 2, srcH / 2, 0, 0, 2 * Math.PI);\n ctx.fill();\n } else {\n const rx = Math.min(\n (rxRatio > 0.5 ? rxRatio : rxRatio * minFrameDim) * (srcW / frameW),\n srcW / 2,\n srcH / 2\n );\n const r = Math.max(0, rx);\n ctx.beginPath();\n ctx.moveTo(r, 0);\n ctx.lineTo(srcW - r, 0);\n if (r > 0) ctx.quadraticCurveTo(srcW, 0, srcW, r);\n ctx.lineTo(srcW, srcH - r);\n if (r > 0) ctx.quadraticCurveTo(srcW, srcH, srcW - r, srcH);\n ctx.lineTo(r, srcH);\n if (r > 0) ctx.quadraticCurveTo(0, srcH, 0, srcH - r);\n ctx.lineTo(0, r);\n if (r > 0) ctx.quadraticCurveTo(0, 0, r, 0);\n ctx.closePath();\n ctx.fill();\n }\n }\n return cropCanvas.toDataURL('image/png');\n }\n }\n }\n }\n }\n\n // BLOB-ONLY PATH: build from scratch (no clone). Avoids all baked-state issues after move.\n if (forceBlobReplace && imageUrl && !imageUrl.startsWith('data:') && !imageUrl.startsWith('blob:')) {\n const dims = await loadNaturalDimensionsFromUrl(imageUrl);\n const natW = dims?.width ?? stored?.naturalWidth ?? frameW;\n const natH = dims?.height ?? stored?.naturalHeight ?? frameH;\n const useNatW = natW > 0 && natH > 0 ? natW : frameW;\n const useNatH = natW > 0 && natH > 0 ? natH : frameH;\n const outW = maintainResolution && useNatW > frameW ? Math.max(1, Math.round(useNatW)) : Math.max(1, Math.round(frameW * multiplier));\n const outH = maintainResolution && useNatH > frameH ? Math.max(1, Math.round(useNatH)) : Math.max(1, Math.round(frameH * multiplier));\n const proxied = getProxiedImageUrl(imageUrl);\n const res = await fetch(proxied);\n if (!res.ok) throw new Error(`Export blob fetch failed: ${res.status}`);\n const blob = await res.blob();\n const blobUrl = URL.createObjectURL(blob);\n try {\n const img = await fabric.FabricImage.fromURL(blobUrl, { crossOrigin: 'anonymous' });\n img.set({ width: useNatW, height: useNatH, originX: 'center', originY: 'center', objectCaching: false, dirty: true });\n const baseScale = Math.max(frameW / useNatW, frameH / useNatH);\n const finalScale = baseScale * zoom;\n img.set({ scaleX: finalScale, scaleY: finalScale });\n const dispW = useNatW * finalScale;\n const dispH = useNatH * finalScale;\n const overflowX = Math.max(0, dispW - frameW);\n const overflowY = Math.max(0, dispH - frameH);\n img.set({ left: overflowX > 0 ? -overflowX * (panX - 0.5) : 0, top: overflowY > 0 ? -overflowY * (panY - 0.5) : 0 });\n img.setCoords();\n const clip = shape === 'circle'\n ? new fabric.Ellipse({ rx: frameW / 2, ry: frameH / 2, left: 0, top: 0, originX: 'center', originY: 'center', selectable: false, evented: false })\n : new fabric.Rect({ width: frameW, height: frameH, rx: clipRx, ry: clipRx, left: 0, top: 0, originX: 'center', originY: 'center', selectable: false, evented: false });\n (clip as any).absolutePositioned = false;\n (clip as any).excludeFromExport = false;\n const group = new fabric.Group([img], { left: outW / 2, top: outH / 2, originX: 'center', originY: 'center', width: frameW, height: frameH, scaleX: outW / frameW, scaleY: outH / frameH, angle: 0, opacity: liveGroup.opacity ?? 1, objectCaching: false });\n group.clipPath = clip;\n (group.clipPath as any).absolutePositioned = false;\n (group.clipPath as any).excludeFromExport = false;\n group.set({ width: frameW, height: frameH });\n group.setCoords();\n if (group.clipPath) group.clipPath.setCoords();\n const el = document.createElement('canvas');\n el.width = outW;\n el.height = outH;\n const exportCanvas = new fabric.StaticCanvas(el, {\n width: outW,\n height: outH,\n backgroundColor: bgFill ?? 'transparent',\n renderOnAddRemove: false,\n });\n exportCanvas.add(group);\n exportCanvas.renderAll();\n const png = exportCanvas.toDataURL({ format: 'png', multiplier: 1, enableRetinaScaling: false });\n exportCanvas.dispose();\n return png;\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n }\n\n // CLONE PATH\n let outW: number;\n let outH: number;\n let clipScaleX = 1;\n let clipScaleY = 1;\n const rx = rxRatio > 0.5 ? rxRatio : rxRatio * minFrameDim;\n let exportNaturalW = 0;\n let exportNaturalH = 0;\n let urlDims: { width: number; height: number } | null = null;\n if (imageUrl && (forceBlobReplace || maintainResolution)) {\n urlDims = await loadNaturalDimensionsFromUrl(imageUrl);\n }\n if (maintainResolution) {\n // Prefer URL-fetched (blob path), then stored, then Fabric\n let naturalWidth = urlDims?.width ?? ((stored?.naturalWidth ?? 0) > 0 && (stored?.naturalHeight ?? 0) > 0 ? stored!.naturalWidth! : 0);\n let naturalHeight = urlDims?.height ?? (naturalWidth > 0 ? stored!.naturalHeight! : 0);\n if (naturalWidth <= 0 || naturalHeight <= 0) {\n let img = cropData?._img;\n if (!img || (typeof (img as any).getElement !== 'function' && !(img as any)._element)) {\n const objects = liveGroup.getObjects();\n img = objects.find((o: fabric.FabricObject) => o instanceof fabric.FabricImage || (o as any).getElement) as fabric.FabricImage | undefined;\n }\n if (img && (typeof (img as any).getElement === 'function' || (img as any)._element)) {\n const orig = typeof (img as any).getOriginalSize === 'function' ? (img as any).getOriginalSize() : null;\n const htmlImg = orig ? null : (typeof (img as any).getElement === 'function' ? (img as any).getElement() : (img as any)._element);\n naturalWidth = (orig?.width ?? htmlImg?.naturalWidth ?? (img as any).width) || 0;\n naturalHeight = (orig?.height ?? htmlImg?.naturalHeight ?? (img as any).height) || 0;\n }\n }\n // After move/transform Fabric may bake dimensions. If still no good size, try URL.\n const fromFabricLooksBaked = naturalWidth > 0 && naturalHeight > 0 && naturalWidth <= frameW + 2 && naturalHeight <= frameH + 2;\n if (imageUrl && (naturalWidth <= 0 || naturalHeight <= 0 || fromFabricLooksBaked)) {\n const dims = await loadNaturalDimensionsFromUrl(imageUrl);\n if (dims && dims.width > 0 && dims.height > 0) {\n naturalWidth = dims.width;\n naturalHeight = dims.height;\n } else if (fromFabricLooksBaked) {\n // URL load failed or skipped (e.g. data:); don't use baked size - use at least 4x frame for export quality\n naturalWidth = Math.max(naturalWidth, Math.round(frameW * 4));\n naturalHeight = Math.max(naturalHeight, Math.round(frameH * 4));\n }\n }\n if (naturalWidth > 0 && naturalHeight > 0) {\n exportNaturalW = naturalWidth;\n exportNaturalH = naturalHeight;\n // Use frame aspect at high res so export matches preview; avoid image aspect (which crops wrong).\n let scaleUp = Math.max(naturalWidth / frameW, naturalHeight / frameH, multiplier);\n // SVG sources: ensure at least 4x resolution so PDF stays sharp when zoomed\n if (imageUrl && imageUrl.toLowerCase().includes('.svg')) {\n scaleUp = Math.max(scaleUp, 4);\n }\n outW = Math.max(1, Math.round(frameW * scaleUp));\n outH = Math.max(1, Math.round(frameH * scaleUp));\n clipScaleX = outW / frameW;\n clipScaleY = outH / frameH;\n } else {\n outW = Math.max(1, Math.round(frameW * multiplier));\n outH = Math.max(1, Math.round(frameH * multiplier));\n clipScaleX = multiplier;\n clipScaleY = multiplier;\n }\n } else {\n outW = Math.max(1, Math.round(frameW * multiplier));\n outH = Math.max(1, Math.round(frameH * multiplier));\n clipScaleX = multiplier;\n clipScaleY = multiplier;\n }\n\n const el = document.createElement('canvas');\n el.width = outW;\n el.height = outH;\n\n const exportCanvas = new fabric.StaticCanvas(el, {\n width: outW,\n height: outH,\n backgroundColor: bgFill ?? 'transparent',\n renderOnAddRemove: false,\n });\n\n // Fabric.js v6: clone() returns a Promise directly\n const clonedGroup = await liveGroup.clone() as fabric.Group;\n\n // Make sure clip exports + disable caching everywhere\n // CRITICAL: Preserve opacity from the original group\n clonedGroup.set({ \n objectCaching: false, \n dirty: true,\n opacity: liveGroup.opacity ?? 1, // Preserve opacity\n });\n (clonedGroup as any)._objects?.forEach((o: any) => o.set({ objectCaching: false, dirty: true }));\n \n // CRITICAL: Ensure clipPath is properly configured for export\n // The clip path is in group-local coordinates, so it will scale with the group\n // (shape already declared at top of function)\n \n // When Keep Resolution: use clip path and group at EXPORT size (outW x outH) so the clip is not at canvas resolution.\n // Otherwise Fabric can effectively clip at frame size and we see only a small region.\n const groupScaleX = maintainResolution ? 1 : multiplier;\n const groupScaleY = maintainResolution ? 1 : multiplier;\n const clipW = maintainResolution ? outW : frameW;\n const clipH = maintainResolution ? outH : frameH;\n const scaledClipRx = maintainResolution ? Math.min(clipRx * (outW / frameW), outW / 2, outH / 2) : Math.min(clipRx, clipW / 2, clipH / 2);\n \n // If clipPath wasn't cloned, recreate it from the original\n if (!clonedGroup.clipPath && liveGroup.clipPath) {\n if (shape === 'circle') {\n clonedGroup.clipPath = new fabric.Ellipse({\n rx: clipW / 2,\n ry: clipH / 2,\n left: 0,\n top: 0,\n originX: 'center',\n originY: 'center',\n selectable: false,\n evented: false,\n hasControls: false,\n hasBorders: false,\n });\n } else {\n clonedGroup.clipPath = new fabric.Rect({\n width: clipW,\n height: clipH,\n rx: scaledClipRx,\n ry: scaledClipRx,\n left: 0,\n top: 0,\n originX: 'center',\n originY: 'center',\n selectable: false,\n evented: false,\n hasControls: false,\n hasBorders: false,\n });\n }\n (clonedGroup.clipPath as any).absolutePositioned = false;\n (clonedGroup.clipPath as any).excludeFromExport = false;\n } else if (clonedGroup.clipPath) {\n // Update existing clipPath (works for both maintainResolution true and false)\n if (shape === 'circle' && clonedGroup.clipPath instanceof fabric.Ellipse) {\n clonedGroup.clipPath.set({\n rx: clipW / 2,\n ry: clipH / 2,\n });\n } else if (clonedGroup.clipPath instanceof fabric.Rect) {\n clonedGroup.clipPath.set({\n width: clipW,\n height: clipH,\n rx: scaledClipRx,\n ry: scaledClipRx,\n });\n }\n }\n \n // CRITICAL: Always ensure clipPath is configured for export\n if (clonedGroup.clipPath) {\n clonedGroup.clipPath.set({ \n excludeFromExport: false, \n objectCaching: false, \n dirty: true,\n absolutePositioned: false,\n });\n clonedGroup.clipPath.setCoords();\n }\n\n // CRITICAL: Ensure clipPath is properly configured BEFORE setting transforms\n if (clonedGroup.clipPath) {\n // Ensure clipPath is included in export\n clonedGroup.clipPath.set({ \n excludeFromExport: false,\n absolutePositioned: false,\n objectCaching: false,\n dirty: true,\n });\n clonedGroup.clipPath.setCoords();\n }\n\n // When maintainResolution: group is already at export size (clipW x clipH = outW x outH), scale 1.\n // Otherwise: group at frame size, scaled to fill canvas.\n clonedGroup.set({ width: clipW, height: clipH });\n clonedGroup.setCoords();\n\n // Reset transforms in clone-space, then place it in our export canvas\n clonedGroup.set({\n left: outW / 2,\n top: outH / 2,\n originX: 'center',\n originY: 'center',\n scaleX: groupScaleX,\n scaleY: groupScaleY,\n angle: 0,\n skewX: 0,\n skewY: 0,\n flipX: false,\n flipY: false,\n });\n clonedGroup.setCoords();\n \n // CRITICAL: Re-apply clipPath after setting transforms to ensure it's properly associated\n if (clonedGroup.clipPath) {\n clonedGroup.clipPath.setCoords();\n }\n\n // Only replace with blob on retry (forceBlobReplace). New image MUST use natural dimensions, not oldImg's baked (frame) size.\n if (forceBlobReplace && imageUrl && !imageUrl.startsWith('data:') && !imageUrl.startsWith('blob:')) {\n const objects = clonedGroup.getObjects();\n const imgIndex = objects.findIndex((o: fabric.FabricObject) => o instanceof fabric.FabricImage);\n if (imgIndex >= 0) {\n const oldImg = objects[imgIndex] as fabric.FabricImage;\n try {\n // Use urlDims we already fetched at top when forceBlobReplace, else fetch now\n const dims = urlDims ?? (await loadNaturalDimensionsFromUrl(imageUrl));\n const natW = dims?.width ?? stored?.naturalWidth ?? 0;\n const natH = dims?.height ?? stored?.naturalHeight ?? 0;\n const useNatW = natW > 0 && natH > 0 ? natW : frameW;\n const useNatH = natW > 0 && natH > 0 ? natH : frameH;\n\n const proxied = getProxiedImageUrl(imageUrl);\n const res = await fetch(proxied);\n if (!res.ok) {\n // blob fetch failed, fall through to clone path\n } else {\n const blob = await res.blob();\n const blobUrl = URL.createObjectURL(blob);\n try {\n const newImg = await fabric.FabricImage.fromURL(blobUrl, { crossOrigin: 'anonymous' });\n exportNaturalW = useNatW;\n exportNaturalH = useNatH;\n newImg.set({\n width: useNatW,\n height: useNatH,\n left: 0,\n top: 0,\n scaleX: 1,\n scaleY: 1,\n angle: oldImg.angle ?? 0,\n originX: 'center',\n originY: 'center',\n objectCaching: false,\n dirty: true,\n });\n newImg.setCoords();\n clonedGroup.remove(oldImg);\n clonedGroup.insertAt(imgIndex, newImg);\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n }\n } catch (_e) {\n // blob replace failed, clone path continues with existing image\n }\n }\n }\n\n // Reapply cover layout on clone image so export is correct even when Fabric baked dimensions.\n // When maintainResolution the \"frame\" is (outW x outH) so the image covers the full export area.\n const cloneImg = clonedGroup.getObjects().find((o: fabric.FabricObject) => o instanceof fabric.FabricImage) as fabric.FabricImage | undefined;\n if (cloneImg) {\n let natW = exportNaturalW;\n let natH = exportNaturalH;\n if (natW <= 0 || natH <= 0) {\n const el = (cloneImg as any).getElement?.() ?? (cloneImg as any)._element;\n natW = el?.naturalWidth ?? stored?.naturalWidth ?? 0;\n natH = el?.naturalHeight ?? stored?.naturalHeight ?? 0;\n }\n if (natW > 0 && natH > 0) {\n const _ct = (cropData?._img as any)?._ct;\n const panX = Math.max(0, Math.min(1, stored?.panX ?? _ct?.panX ?? 0.5));\n const panY = Math.max(0, Math.min(1, stored?.panY ?? _ct?.panY ?? 0.5));\n const zoom = Math.max(1, stored?.zoom ?? _ct?.zoom ?? 1);\n const layoutW = maintainResolution ? outW : frameW;\n const layoutH = maintainResolution ? outH : frameH;\n const baseScale = Math.max(layoutW / natW, layoutH / natH);\n const finalScale = baseScale * zoom;\n cloneImg.set({\n width: natW,\n height: natH,\n scaleX: finalScale,\n scaleY: finalScale,\n originX: 'center',\n originY: 'center',\n objectCaching: false,\n dirty: true,\n });\n const dispW = natW * finalScale;\n const dispH = natH * finalScale;\n const overflowX = Math.max(0, dispW - layoutW);\n const overflowY = Math.max(0, dispH - layoutH);\n const offsetX = overflowX > 0 ? -overflowX * (panX - 0.5) : 0;\n const offsetY = overflowY > 0 ? -overflowY * (panY - 0.5) : 0;\n cloneImg.set({ left: offsetX, top: offsetY });\n cloneImg.setCoords();\n }\n }\n\n clonedGroup.set({ width: clipW, height: clipH });\n clonedGroup.setCoords();\n\n exportCanvas.add(clonedGroup);\n exportCanvas.renderAll();\n const png = exportCanvas.toDataURL({\n format: 'png',\n multiplier: 1,\n enableRetinaScaling: false,\n });\n exportCanvas.dispose();\n return png;\n}\n\n/**\n * Draw a single element to the PDF.\n * \n * When a live Fabric transform matrix is available (from calcTransformMatrix),\n * we use it directly to get pixel-perfect positioning and rotation matching Fabric exactly.\n * Otherwise we fall back to normalizeElement() calculations.\n */\nasync function drawElement(\n pdf: jsPDF,\n element: CanvasElement,\n embeddedFonts: Set<string>,\n canvasWidth: number,\n canvasHeight: number,\n backgroundColor?: string,\n fabricMatrix?: number[] | null,\n /**\n * When we use a live Fabric transform matrix, we must also use the SAME intrinsic\n * width/height that Fabric used to compute that matrix (especially for images,\n * where the element's stored width/height represent the frame, not the source bitmap).\n */\n fabricIntrinsic?: { w: number; h: number } | null,\n pageId?: string,\n /** When provided, use this Fabric text object's exact line layout for WYSIWYG text export */\n liveFabricText?: fabric.FabricObject | null,\n /** When provided and no fabricMatrix, use getAbsoluteBounds so grouped elements export at correct position/size */\n pageChildren?: CanvasNode[]\n): Promise<void> {\n if (!element.visible) return;\n\n debugLog(`drawElement START id=${element.id} type=${element.type}`);\n const norm = normalizeElement(element);\n if (!fabricMatrix && pageChildren?.length) {\n const node = findNodeById(pageChildren, element.id);\n if (node) {\n const abs = getAbsoluteBounds(node, pageChildren);\n (norm as { x: number; y: number; w: number; h: number }).x = abs.left;\n (norm as { x: number; y: number; w: number; h: number }).y = abs.top;\n (norm as { x: number; y: number; w: number; h: number }).w = abs.width;\n (norm as { x: number; y: number; w: number; h: number }).h = abs.height;\n }\n }\n\n // ✅ Smart Element SVG regeneration — use the SAME shared renderer as the server\n // This ensures QR codes, ratings, tables, badges etc. produce identical SVGs\n // on both client and server, eliminating rendering drift.\n if (element.smartElementType && element.smartProps && norm.w > 0 && norm.h > 0) {\n const propsWithFont = {\n ...element.smartProps,\n fontFamily: element.smartProps.fontFamily || (element as any).fontFamily || 'sans-serif',\n };\n const freshSvg = renderSmartElementToSvg(element.smartElementType, propsWithFont, norm.w, norm.h);\n if (freshSvg) {\n // Overwrite the stale data URI with a freshly-rendered SVG\n element = {\n ...element,\n sourceFormat: 'svg',\n src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(freshSvg)}`,\n imageUrl: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(freshSvg)}`,\n };\n // Re-normalize with updated src\n Object.assign(norm, { imageUrl: element.src });\n debugLog(`Smart element regenerated: type=${element.smartElementType} id=${element.id}`);\n }\n }\n\n // ✅ EARLY: if this element is a live crop-group, rasterize it (with clip) and draw that PNG instead\n if (element.type === 'image' && pageId) {\n const liveCanvas = getCanvasForPage(pageId);\n if (liveCanvas) {\n const liveGroup = liveCanvas.getObjects().find(\n (obj) => (obj as any).__docuforgeId === element.id && (obj as any).__cropGroup\n ) as fabric.Group | undefined;\n\n if (liveGroup) {\n const cropData = (liveGroup as any).__cropData;\n const frameW = cropData?.frameW || liveGroup.width || norm.w;\n const frameH = cropData?.frameH || liveGroup.height || norm.h;\n const shape = cropData?.shape || 'rect';\n const rx = cropData?.rx || 0;\n // Check maintainResolution from element - only maintain if explicitly true\n // If undefined, default to true (checked by default)\n // If false, don't maintain resolution\n const maintainResolution = element.maintainResolution !== false;\n \n // Get natural image dimensions if maintainResolution is enabled\n let exportMultiplier = 2; // Default multiplier\n let exportFrameW = frameW;\n let exportFrameH = frameH;\n \n // Only maintain resolution if maintainResolution is true (checkbox is checked)\n if (maintainResolution) {\n let img = cropData?._img;\n if (!img || (typeof (img as any).getElement !== 'function' && !(img as any)._element)) {\n const objects = liveGroup.getObjects();\n img = objects.find((o: fabric.FabricObject) => o instanceof fabric.FabricImage || (o as any).getElement) as fabric.FabricImage | undefined;\n }\n if (img && (typeof (img as any).getElement === 'function' || (img as any)._element)) {\n const orig = typeof (img as any).getOriginalSize === 'function' ? (img as any).getOriginalSize() : null;\n const htmlImg = orig ? null : (typeof (img as any).getElement === 'function' ? (img as any).getElement() : (img as any)._element);\n const naturalWidth = (orig?.width ?? htmlImg?.naturalWidth ?? (img as any).width) || frameW;\n const naturalHeight = (orig?.height ?? htmlImg?.naturalHeight ?? (img as any).height) || frameH;\n const scaleX = naturalWidth / frameW;\n const scaleY = naturalHeight / frameH;\n exportMultiplier = Math.max(scaleX, scaleY, 2);\n exportFrameW = naturalWidth;\n exportFrameH = naturalHeight;\n }\n }\n\n const imageUrlForRaster = element.src || element.imageUrl || (liveGroup as any).__imageSrc;\n const isSvgSource = element.sourceFormat === 'svg' || (imageUrlForRaster && imageUrlForRaster.toLowerCase().includes('.svg'));\n if (isSvgSource) {\n exportMultiplier = Math.max(exportMultiplier, 4);\n }\n\n // SVG images: always use vector path (with clip for crop)\n // Edge fade requires raster; skip vector when fade is active so the\n // baked PNG carries the per-side feather.\n const canVectorizeSvg = isSvgSource && !!imageUrlForRaster && !elementHasFade(element);\n if (canVectorizeSvg) {\n const svgEl = await fetchSvgAsElement(imageUrlForRaster, element.svgColorMap);\n if (svgEl) {\n expandSvgUseElements(svgEl, element.id);\n const svgToDraw = normalizeSvgExplicitColors(svgEl);\n inlineComputedStyles(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n resolveSvgGradientRefsToSolid(svgToDraw, element.id);\n prefixSvgIds(svgToDraw, element.id);\n bakeGroupOpacityIntoChildren(svgToDraw);\n injectOpacityIntoSvg(svgToDraw, norm.opacity);\n try {\n const anyPdf = pdf as any;\n const canUseAdvancedTransforms =\n typeof anyPdf.advancedAPI === 'function' &&\n typeof anyPdf.setCurrentTransformationMatrix === 'function' &&\n typeof anyPdf.Matrix === 'function';\n // For vector SVGs, opacity is baked into SVG paint attributes\n // via injectOpacityIntoSvg(), so keep PDF GState neutral.\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n\n // Compute crop zoom/pan offsets for SVG draw area\n const cropZoomVal = cropData ? Math.max(1, (cropData._img as any)?._ct?.zoom ?? (element as any).cropZoom ?? 1) : 1;\n const cropPanXVal = cropData ? Math.max(0, Math.min(1, (cropData._img as any)?._ct?.panX ?? (element as any).cropPanX ?? 0.5)) : 0.5;\n const cropPanYVal = cropData ? Math.max(0, Math.min(1, (cropData._img as any)?._ct?.panY ?? (element as any).cropPanY ?? 0.5)) : 0.5;\n\n const naturalW = Math.max(1, Number((element as any).imageNaturalWidth ?? 0) || Number((cropData?._img as any)?.width ?? 0) || frameW);\n const naturalH = Math.max(1, Number((element as any).imageNaturalHeight ?? 0) || Number((cropData?._img as any)?.height ?? 0) || frameH);\n const fitContain = ((cropData as any)?.fit ?? (element as any).imageFit ?? 'cover') === 'contain';\n\n // Helper: given a clip rect (frame), compute the zoomed/panned SVG draw rect\n // using the same cover/contain math as canvas crop groups.\n const cropSvgRect = (clipX: number, clipY: number, clipW: number, clipH: number) => {\n const baseScale = fitContain ? Math.min(clipW / naturalW, clipH / naturalH) : Math.max(clipW / naturalW, clipH / naturalH);\n const finalScale = baseScale * (fitContain ? 1 : cropZoomVal);\n const drawW = naturalW * finalScale;\n const drawH = naturalH * finalScale;\n const overflowX = Math.max(0, drawW - clipW);\n const overflowY = Math.max(0, drawH - clipH);\n const offX = overflowX > 0 ? -overflowX * (cropPanXVal - 0.5) : 0;\n const offY = overflowY > 0 ? -overflowY * (cropPanYVal - 0.5) : 0;\n return {\n x: clipX + clipW / 2 + offX - drawW / 2,\n y: clipY + clipH / 2 + offY - drawH / 2,\n width: drawW,\n height: drawH,\n };\n };\n\n const localX = -frameW / 2;\n const localY = -frameH / 2;\n if (canUseAdvancedTransforms && fabricMatrix && fabricMatrix.length === 6) {\n const mPdf = fabricMatrixToJsPdfAdvancedMatrix(fabricMatrix, canvasHeight);\n const axisFrame = getAxisAlignedSvgFrameFromMatrix(mPdf, localX, localY, frameW, frameH);\n if (axisFrame) {\n const svgDrawRect = cropSvgRect(axisFrame.x, axisFrame.y, axisFrame.width, axisFrame.height);\n // Axis-aligned frame: draw directly in page space to avoid CTM flip/drift issues.\n const seq = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq} elementId=${element.id} path=cropGroup-axis`);\n resetPdfColorState(pdf, `before save #${seq} ${element.id}`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq} ${element.id}`);\n pdf.setLineWidth(0);\n pdf.rect(axisFrame.x, axisFrame.y, axisFrame.width, axisFrame.height, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n const pdfToUse = pdfWithColorLogging(pdf, seq, element.id);\n await svg2pdfWithDomMount(svgToDraw, pdfToUse, svg2pdfOpts(svgDrawRect.x, svgDrawRect.y, svgDrawRect.width, svgDrawRect.height));\n debugLog(`svg2pdf DONE #${seq} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq} ${element.id}`);\n } else {\n const transformed = buildMatrixTransformedSvgForPage(svgToDraw, mPdf, localX, localY, frameW, frameH);\n if (transformed) {\n const seq = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq} elementId=${element.id} path=cropGroup-matrix-wrapper`);\n resetPdfColorState(pdf, `before save #${seq} ${element.id} matrix-wrapper`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq} ${element.id}`);\n pdf.setLineWidth(0);\n pdf.rect(transformed.frame.x, transformed.frame.y, transformed.frame.width, transformed.frame.height, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq} ${element.id}`);\n setPdfColorFromSvg(pdf, transformed.svg, element.id);\n const tfCropRect = cropSvgRect(transformed.frame.x, transformed.frame.y, transformed.frame.width, transformed.frame.height);\n await svg2pdfWithDomMount(\n transformed.svg,\n pdfWithColorLogging(pdf, seq, element.id),\n svg2pdfOpts(tfCropRect.x, tfCropRect.y, tfCropRect.width, tfCropRect.height)\n );\n debugLog(`svg2pdf DONE #${seq} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq} ${element.id}`);\n } else {\n const pdfForSvg = new Proxy(pdf, {\n get(target, prop) {\n if (prop === 'advancedAPI') return () => {};\n return (target as any)[prop];\n },\n });\n await new Promise<void>((resolve, reject) => {\n anyPdf.advancedAPI(async () => {\n try {\n const seq = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq} elementId=${element.id} path=cropGroup-matrix-fallback`);\n resetPdfColorState(pdf, `before save #${seq} ${element.id} matrix`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq} ${element.id}`);\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n pdf.setLineWidth(0);\n pdf.rect(localX, localY, frameW, frameH, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n const mfCropRect = cropSvgRect(localX, localY, frameW, frameH);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq, element.id), svg2pdfOpts(mfCropRect.x, mfCropRect.y, mfCropRect.width, mfCropRect.height));\n debugLog(`svg2pdf DONE #${seq} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq} ${element.id}`);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n });\n }\n }\n } else {\n const angle = norm.angle ?? 0;\n const hasRotation = Math.abs(angle) > 0.01;\n const cx = norm.x + frameW / 2;\n const cy = norm.y + frameH / 2;\n if (hasRotation && canUseAdvancedTransforms) {\n const rad = (angle * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const computedM: Matrix6 = [cos, sin, -sin, cos, cx, cy];\n const localX2 = -frameW / 2;\n const localY2 = -frameH / 2;\n const pdfForSvg = new Proxy(pdf, {\n get(target, prop) {\n if (prop === 'advancedAPI') return () => {};\n return (target as any)[prop];\n },\n });\n await new Promise<void>((resolve, reject) => {\n anyPdf.advancedAPI(async () => {\n try {\n const seq2 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq2} elementId=${element.id} path=cropGroup-rotation`);\n resetPdfColorState(pdf, `before save #${seq2} ${element.id} rotation`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq2} ${element.id}`);\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...computedM));\n pdf.setLineWidth(0);\n pdf.rect(localX2, localY2, frameW, frameH, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq2} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n const rotCropRect = cropSvgRect(localX2, localY2, frameW, frameH);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq2, element.id), svg2pdfOpts(rotCropRect.x, rotCropRect.y, rotCropRect.width, rotCropRect.height));\n debugLog(`svg2pdf DONE #${seq2} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq2} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq2} ${element.id}`);\n resolve();\n } catch (e) {\n reject(e);\n }\n });\n });\n } else {\n const seq3 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq3} elementId=${element.id} path=cropGroup-norm`);\n resetPdfColorState(pdf, `before save #${seq3} ${element.id} norm`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq3} ${element.id}`);\n pdf.setLineWidth(0);\n pdf.rect(norm.x, norm.y, frameW, frameH, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq3} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n const normCropRect = cropSvgRect(norm.x, norm.y, frameW, frameH);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq3, element.id), svg2pdfOpts(normCropRect.x, normCropRect.y, normCropRect.width, normCropRect.height));\n debugLog(`svg2pdf DONE #${seq3} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq3} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq3} ${element.id}`);\n }\n }\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n return;\n } catch {\n // Fall through to raster path\n }\n }\n }\n\n const storedCrop: StoredCropExportInfo | undefined =\n (element as any).imageNaturalWidth != null && (element as any).imageNaturalHeight != null\n ? {\n naturalWidth: (element as any).imageNaturalWidth,\n naturalHeight: (element as any).imageNaturalHeight,\n panX: (element as any).cropPanX,\n panY: (element as any).cropPanY,\n zoom: (element as any).cropZoom,\n }\n : undefined;\n let png: string;\n try {\n png = await rasterizeCropGroupToPng(liveGroup, frameW, frameH, exportMultiplier, maintainResolution, imageUrlForRaster, false, storedCrop, backgroundColor);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isTainted = msg.includes('Tainted canvases') || (err as Error)?.name === 'SecurityError';\n if (isTainted && imageUrlForRaster && !imageUrlForRaster.startsWith('data:') && !imageUrlForRaster.startsWith('blob:')) {\n png = await rasterizeCropGroupToPng(liveGroup, frameW, frameH, exportMultiplier, maintainResolution, imageUrlForRaster, true, storedCrop, backgroundColor);\n } else {\n throw err;\n }\n }\n\n // If we have a matrix, draw the raster INSIDE the matrix (so rotation/scale matches perfectly)\n const anyPdf = pdf as any;\n const canUseAdvancedTransforms =\n typeof anyPdf.advancedAPI === 'function' &&\n typeof anyPdf.setCurrentTransformationMatrix === 'function' &&\n typeof anyPdf.Matrix === 'function';\n\n // Apply element opacity so export matches editor (rasterized PNG may not always bake group opacity correctly)\n const clampedOpacity = Math.max(0, Math.min(1, norm.opacity));\n pdf.setGState(pdf.GState({ opacity: clampedOpacity }));\n\n // Ensure we have valid PNG data for jsPDF (avoids corrupt/small image in PDF)\n if (!png || typeof png !== 'string' || !png.startsWith('data:image/') || png.length < 200) {\n return;\n }\n\n // Bake edge fade into the rasterized crop PNG so masked images keep\n // the same per-side fade visible in the editor.\n const fadedMasked = await bakeEdgeFadeIntoDataUrl(png, element);\n if (fadedMasked) {\n png = fadedMasked;\n }\n\n if (canUseAdvancedTransforms && fabricMatrix && fabricMatrix.length === 6) {\n const mPdf = fabricMatrixToJsPdfAdvancedMatrix(fabricMatrix, canvasHeight);\n const localX = -frameW / 2;\n const localY = -frameH / 2;\n anyPdf.advancedAPI(() => {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n\n // local origin is center; draw at frame size so PDF matches canvas frame\n pdf.addImage(png, 'PNG', localX, localY, frameW, frameH, undefined, 'SLOW');\n pdf.restoreGraphicsState();\n });\n \n // CRITICAL: Reset opacity to 1.0 after drawing masked image to avoid affecting subsequent elements\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n\n return; // ✅ done\n }\n\n // No matrix path: draw at element position with frame size (same as matrix path)\n pdf.addImage(png, 'PNG', norm.x, norm.y, frameW, frameH, undefined, 'SLOW');\n \n // CRITICAL: Reset opacity to 1.0 after drawing masked image to avoid affecting subsequent elements\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n \n return; // ✅ done\n }\n }\n }\n\n // CRITICAL: Always set opacity explicitly (even if 1.0) to ensure previous opacity state is cleared\n // Clamp opacity to valid range [0, 1]. For vector SVG image paths, opacity is baked\n // into SVG attributes (injectOpacityIntoSvg), so avoid double-application.\n const clampedOpacity = Math.max(0, Math.min(1, norm.opacity));\n const isSvgImageElement = element.type === 'image' && (\n element.sourceFormat === 'svg' ||\n ((norm.imageUrl || '').toLowerCase().includes('.svg')) ||\n (norm.imageUrl || '').startsWith('data:image/svg+xml')\n );\n pdf.setGState(pdf.GState({ opacity: isSvgImageElement ? 1 : clampedOpacity, 'stroke-opacity': isSvgImageElement ? 1 : clampedOpacity }));\n\n const { angle } = norm;\n const hasRotation = Math.abs(angle) > 0.01;\n\n const intrinsicW = (fabricIntrinsic?.w ?? 0) > 0 ? fabricIntrinsic!.w : (element.width ?? norm.w);\n const intrinsicH = (fabricIntrinsic?.h ?? 0) > 0 ? fabricIntrinsic!.h : (element.height ?? norm.h);\n\n const scaleX = element.scaleX ?? 1;\n const scaleY = element.scaleY ?? 1;\n\n // Visual size (what user sees on canvas)\n const visualW = intrinsicW * scaleX;\n const visualH = intrinsicH * scaleY;\n\n const anyPdf = pdf as any;\n const canUseAdvancedTransforms =\n typeof anyPdf.advancedAPI === 'function' &&\n typeof anyPdf.setCurrentTransformationMatrix === 'function' &&\n typeof anyPdf.Matrix === 'function';\n\n const drawWithMatrixAdvanced = async (fabricM: number[]) => {\n const mPdf = fabricMatrixToJsPdfAdvancedMatrix(fabricM, canvasHeight);\n\n // For images we must fetch bytes first (async), then draw inside advancedAPI.\n if (element.type === 'image') {\n const imageUrl = norm.imageUrl;\n if (!imageUrl) return;\n\n const isSvg = element.sourceFormat === 'svg' || (imageUrl && imageUrl.toLowerCase().includes('.svg'));\n // Edge-fade requires raster (alpha mask), so skip vector embed when fade is active.\n const canVectorizeSvg = isSvg && !elementHasFade(element);\n if (canVectorizeSvg) {\n const svgElement = await fetchSvgAsElement(imageUrl, element.svgColorMap);\n if (svgElement) {\n expandSvgUseElements(svgElement, element.id);\n const svgToDraw = normalizeSvgExplicitColors(svgElement);\n inlineComputedStyles(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n resolveSvgGradientRefsToSolid(svgToDraw, element.id);\n prefixSvgIds(svgToDraw, element.id);\n bakeGroupOpacityIntoChildren(svgToDraw);\n injectOpacityIntoSvg(svgToDraw, norm.opacity);\n try {\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n const axisFrame = getAxisAlignedSvgFrameFromMatrix(mPdf, localX, localY, intrinsicW, intrinsicH);\n const seq4 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq4} elementId=${element.id} path=${axisFrame ? 'drawContentCore-image-axis' : 'drawContentCore-image-matrix'}`);\n resetPdfColorState(pdf, `before setPdfColor #${seq4} ${element.id}`);\n\n if (axisFrame) {\n pdf.saveGraphicsState();\n pdf.setLineWidth(0);\n pdf.rect(axisFrame.x, axisFrame.y, axisFrame.width, axisFrame.height, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq4} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n await svg2pdfWithDomMount(\n svgToDraw,\n pdfWithColorLogging(pdf, seq4, element.id),\n svg2pdfOpts(axisFrame.x, axisFrame.y, axisFrame.width, axisFrame.height)\n );\n\n debugLog(`svg2pdf DONE #${seq4} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq4} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq4} ${element.id}`);\n } else {\n const transformed = buildMatrixTransformedSvgForPage(svgToDraw, mPdf, localX, localY, intrinsicW, intrinsicH);\n if (transformed) {\n pdf.saveGraphicsState();\n pdf.setLineWidth(0);\n pdf.rect(transformed.frame.x, transformed.frame.y, transformed.frame.width, transformed.frame.height, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq4} ${element.id}`);\n setPdfColorFromSvg(pdf, transformed.svg, element.id);\n await svg2pdfWithDomMount(\n transformed.svg,\n pdfWithColorLogging(pdf, seq4, element.id),\n svg2pdfOpts(transformed.frame.x, transformed.frame.y, transformed.frame.width, transformed.frame.height)\n );\n debugLog(`svg2pdf DONE #${seq4} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq4} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq4} ${element.id}`);\n } else {\n await new Promise<void>((resolve, reject) => {\n anyPdf.advancedAPI(async () => {\n try {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq4} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq4, element.id), svg2pdfOpts(localX, localY, intrinsicW, intrinsicH));\n debugLog(`svg2pdf DONE #${seq4} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq4} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq4} ${element.id}`);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n });\n }\n }\n } catch {\n const imageData = await fetchImageAsBase64(imageUrl, {\n backgroundColor,\n targetWidthPt: visualW,\n targetHeightPt: visualH,\n preserveAlpha: isSvg || (visualW > canvasWidth * 0.7 && visualH > canvasHeight * 0.7),\n resolutionMultiplier: 4,\n });\n if (imageData) {\n const fadedAdv = await bakeEdgeFadeIntoDataUrl(imageData.data, element);\n if (fadedAdv) {\n imageData.data = fadedAdv;\n imageData.format = 'PNG';\n }\n anyPdf.advancedAPI(() => {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n pdf.addImage(imageData.data, imageData.format, localX, localY, intrinsicW, intrinsicH, undefined, 'SLOW');\n pdf.restoreGraphicsState();\n });\n }\n }\n return;\n }\n }\n\n const preserveAlpha = isSvg || (visualW > canvasWidth * 0.7 && visualH > canvasHeight * 0.7);\n const imageData = await fetchImageAsBase64(imageUrl, {\n backgroundColor,\n targetWidthPt: visualW,\n targetHeightPt: visualH,\n preserveAlpha: preserveAlpha || elementHasFade(element),\n resolutionMultiplier: isSvg ? 4 : undefined,\n });\n if (!imageData) return;\n const fadedMain = await bakeEdgeFadeIntoDataUrl(imageData.data, element);\n if (fadedMain) {\n imageData.data = fadedMain;\n imageData.format = 'PNG';\n }\n\n anyPdf.advancedAPI(() => {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n pdf.addImage(imageData.data, imageData.format, localX, localY, intrinsicW, intrinsicH, undefined, 'SLOW');\n pdf.restoreGraphicsState();\n });\n\n return;\n }\n\n // Non-images: draw synchronously inside advancedAPI.\n anyPdf.advancedAPI(() => {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n const normForMatrix = withCompensatedStrokeWidth(norm, element, fabricM);\n\n // This is safe: for non-image element types, drawElementContentCore performs no awaits.\n void drawElementContentCore(\n pdf,\n element,\n normForMatrix,\n localX,\n localY,\n intrinsicW,\n intrinsicH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n 1.0,\n liveFabricText ?? undefined\n );\n\n pdf.restoreGraphicsState();\n });\n };\n\n const hasIndividualRoundedCorners =\n element.type === 'shape' &&\n norm.shapeType === 'rounded-rect' &&\n (norm.rxTL != null || norm.rxTR != null || norm.rxBR != null || norm.rxBL != null);\n const hasNonIdentityScale = Math.abs(scaleX - 1) > 0.0001 || Math.abs(scaleY - 1) > 0.0001;\n const hasSkew = Math.abs(norm.skewX) > 0.01 || Math.abs(norm.skewY) > 0.01;\n const hasLiveFabricMatrix = !!(fabricMatrix && fabricMatrix.length === 6);\n\n // Rounded-rect with custom corners relies on jsPDF path(); draw in page space only for truly static elements.\n // If a live matrix exists (group transforms, matrix-normalized objects), always use the matrix path.\n const canDrawRoundedRectInPageSpace =\n hasIndividualRoundedCorners &&\n !hasLiveFabricMatrix &&\n !hasNonIdentityScale &&\n !hasRotation &&\n !hasSkew &&\n !(element.flipX ?? false) &&\n !(element.flipY ?? false);\n\n if (canDrawRoundedRectInPageSpace) {\n await drawElementContent(\n pdf,\n element,\n norm,\n norm.x,\n norm.y,\n visualW,\n visualH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n scaleY,\n liveFabricText ?? undefined\n );\n\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n\n const linkUrl = element.linkConfig?.url;\n if (linkUrl) {\n addLinkAnnotation(pdf, linkUrl, norm.x, norm.y, visualW, visualH, canvasHeight);\n }\n\n debugLog(`drawElement END id=${element.id}`);\n return;\n }\n\n // Prefer live Fabric matrix when available (pixel-perfect + correct rotation direction)\n if (canUseAdvancedTransforms && fabricMatrix && fabricMatrix.length === 6) {\n await drawWithMatrixAdvanced(fabricMatrix);\n } else if (canUseAdvancedTransforms && hasIndividualRoundedCorners && hasNonIdentityScale) {\n // Force matrix path for scaled rounded-rect paths so corner geometry + stroke match Fabric exactly.\n const cx = norm.x + visualW / 2;\n const cy = norm.y + visualH / 2;\n const computedFabricM: number[] = [scaleX, 0, 0, scaleY, cx, cy];\n await drawWithMatrixAdvanced(computedFabricM);\n } else if (canUseAdvancedTransforms && hasRotation) {\n // No live matrix, compute equivalent Fabric-style matrix (y-down), then convert.\n const cx = norm.x + visualW / 2;\n const cy = norm.y + visualH / 2;\n const radians = (angle * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n\n const computedFabricM: number[] = [\n scaleX * cos,\n scaleX * sin,\n -scaleY * sin,\n scaleY * cos,\n cx,\n cy,\n ];\n\n await drawWithMatrixAdvanced(computedFabricM);\n } else if (fabricMatrix && fabricMatrix.length === 6) {\n // Fallback (no advanced API): apply the matrix directly (may differ by jsPDF version).\n pdf.saveGraphicsState();\n if (typeof anyPdf.setCurrentTransformationMatrix === 'function' && typeof anyPdf.Matrix === 'function') {\n const [a, b, c, d, e, f] = fabricMatrix;\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(a, b, c, d, e, f));\n }\n\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n const normForMatrix = withCompensatedStrokeWidth(norm, element, fabricMatrix);\n await drawElementContentWithIntrinsic(\n pdf,\n element,\n normForMatrix,\n localX,\n localY,\n intrinsicW,\n intrinsicH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n liveFabricText ?? undefined\n );\n pdf.restoreGraphicsState();\n } else if (hasRotation) {\n // Fallback rotation (no advanced transforms)\n const cx = norm.x + visualW / 2;\n const cy = norm.y + visualH / 2;\n const radians = (angle * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const computedMatrix: Matrix6 = [scaleX * cos, scaleX * sin, -scaleY * sin, scaleY * cos, cx, cy];\n\n pdf.saveGraphicsState();\n if (typeof anyPdf.setCurrentTransformationMatrix === 'function' && typeof anyPdf.Matrix === 'function') {\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...computedMatrix));\n }\n\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n const normForMatrix = withCompensatedStrokeWidth(norm, element, computedMatrix);\n await drawElementContentWithIntrinsic(\n pdf,\n element,\n normForMatrix,\n localX,\n localY,\n intrinsicW,\n intrinsicH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n liveFabricText ?? undefined\n );\n\n pdf.restoreGraphicsState();\n } else {\n // No rotation - draw directly at computed position with visual size\n // Pass scaleY as fontScale since dimensions are pre-scaled but fontSize isn't\n await drawElementContent(\n pdf,\n element,\n norm,\n norm.x,\n norm.y,\n visualW,\n visualH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n scaleY,\n liveFabricText ?? undefined\n );\n }\n\n // CRITICAL: Always reset opacity to 1.0 after drawing element to avoid affecting subsequent elements\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n \n // Add link annotation if element has a link\n const linkUrl = element.linkConfig?.url;\n if (linkUrl) {\n addLinkAnnotation(pdf, linkUrl, norm.x, norm.y, visualW, visualH, canvasHeight);\n }\n debugLog(`drawElement END id=${element.id}`);\n}\n\n/**\n * Draw the actual content of an element at the given position (uses visual w/h)\n */\nasync function drawElementContent(\n pdf: jsPDF,\n element: CanvasElement,\n norm: ReturnType<typeof normalizeElement>,\n x: number,\n y: number,\n w: number,\n h: number,\n embeddedFonts: Set<string>,\n canvasWidth: number,\n canvasHeight: number,\n backgroundColor?: string,\n fontScale: number = 1.0,\n liveFabricText?: fabric.FabricObject | null\n): Promise<void> {\n await drawElementContentCore(pdf, element, norm, x, y, w, h, embeddedFonts, canvasWidth, canvasHeight, backgroundColor, fontScale, liveFabricText);\n}\n\n/**\n * Draw element content using intrinsic dimensions (for transformed contexts where scale is in the matrix)\n * fontScale is 1.0 because the transformation matrix handles scaling\n */\nasync function drawElementContentWithIntrinsic(\n pdf: jsPDF,\n element: CanvasElement,\n norm: ReturnType<typeof normalizeElement>,\n x: number,\n y: number,\n intrinsicW: number,\n intrinsicH: number,\n embeddedFonts: Set<string>,\n canvasWidth: number,\n canvasHeight: number,\n backgroundColor?: string,\n liveFabricText?: fabric.FabricObject | null\n): Promise<void> {\n await drawElementContentCore(pdf, element, norm, x, y, intrinsicW, intrinsicH, embeddedFonts, canvasWidth, canvasHeight, backgroundColor, 1.0, liveFabricText);\n}\n\n/**\n * Core drawing logic for element content\n * @param fontScale - Scale factor to apply to fontSize (1.0 when transforms handle scaling, scaleY when no transforms)\n */\nasync function drawElementContentCore(\n pdf: jsPDF,\n element: CanvasElement,\n norm: ReturnType<typeof normalizeElement>,\n x: number,\n y: number,\n w: number,\n h: number,\n embeddedFonts: Set<string>,\n canvasWidth: number,\n canvasHeight: number,\n backgroundColor?: string,\n fontScale: number = 1.0,\n liveFabricText?: fabric.FabricObject | null\n): Promise<void> {\n switch (element.type) {\n case 'shape': {\n const { shapeType, fill, stroke, strokeWidth, borderRadius, rxTL, rxTR, rxBR, rxBL } = norm;\n const canonicalShape = normalizeShapeType(shapeType);\n\n if (canonicalShape === 'rounded-rect') {\n drawRect(pdf, x, y, w, h, fill, stroke, strokeWidth, borderRadius, rxTL, rxTR, rxBR, rxBL);\n } else if (canonicalShape === 'circle') {\n const diameter = Math.max(1, Math.min(w, h));\n drawEllipse(pdf, x + diameter / 2, y + diameter / 2, diameter / 2, diameter / 2, fill, stroke, strokeWidth);\n } else if (canonicalShape === 'triangle') {\n const rTop = Math.max(0, Number(norm.triRTop ?? 0));\n const rBR = Math.max(0, Number(norm.triRBR ?? 0));\n const rBL = Math.max(0, Number(norm.triRBL ?? 0));\n const hasRounding = rTop > 0 || rBR > 0 || rBL > 0;\n\n if (hasRounding) {\n // Draw rounded triangle using path\n const pathStr = buildRoundedTrianglePath(w, h, rTop, rBR, rBL);\n drawRoundedTrianglePdf(pdf, x, y, w, h, pathStr, fill, stroke, strokeWidth);\n } else {\n const points = getTrianglePoints(x, y, w, h);\n drawPolygon(pdf, points, fill, stroke, strokeWidth);\n }\n } else {\n const points = getShapePoints(shapeType, x, y, w, h);\n if (points) {\n drawPolygon(pdf, points, fill, stroke, strokeWidth);\n }\n }\n break;\n }\n\n case 'line': {\n const { stroke, strokeWidth, strokeDashArray } = norm;\n drawLine(pdf, x, y, x + w, y, stroke, strokeWidth || 2, strokeDashArray);\n break;\n }\n\n case 'text': {\n const { text: originalText, fontSize, fontFamily, fontWeight, fontStyle, underline, letterSpacing, fill, textAlign, lineHeight, splitByGrapheme } = norm;\n const overflowPolicy = element.overflowPolicy || 'grow-and-push';\n const minFontSize = (element.minFontSize || 8) * fontScale;\n const maxLines = element.maxLines || 3;\n const effectiveSplitByGrapheme = overflowPolicy === 'auto-shrink' ? false : splitByGrapheme;\n \n let finalText = originalText;\n let finalFontSize = fontSize * fontScale;\n \n // For auto-shrink: keep width fixed, avoid implicit wrapping, and reduce font size until it fits.\n if (overflowPolicy === 'auto-shrink') {\n const explicitLineCount = Math.max(1, finalText.split('\\n').length);\n const measureWidth = Math.max(1, w / PX_TO_PT);\n while (finalFontSize > 1) {\n const testTextbox = new fabric.Textbox(finalText, {\n width: measureWidth,\n fontSize: finalFontSize / PX_TO_PT,\n fontFamily,\n fontWeight,\n fontStyle,\n lineHeight: lineHeight || 1.2,\n charSpacing: letterSpacing || 0,\n splitByGrapheme: false,\n });\n testTextbox.initDimensions();\n \n const textHeight = (testTextbox.height || 0) * PX_TO_PT;\n const renderedLineCount = testTextbox.textLines?.length || 1;\n const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;\n const fitsHeight = h <= 0 || textHeight <= h;\n // Also check that no line overflows the fixed width (single long word case)\n const actualTextboxWidth = testTextbox.width ?? measureWidth;\n const widthDidGrow = actualTextboxWidth > measureWidth + 0.5;\n const lineWidths = (testTextbox as any).__lineWidths as number[] | undefined;\n const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;\n const fitsWidth = !widthDidGrow && maxLineWidth <= measureWidth + 1;\n\n if (hasNoImplicitWrap && fitsHeight && fitsWidth) {\n break;\n }\n finalFontSize--;\n }\n }\n \n // For max-lines-ellipsis: truncate text\n if (overflowPolicy === 'max-lines-ellipsis') {\n const testTextbox = new fabric.Textbox(originalText, {\n width: w / PX_TO_PT,\n fontSize: finalFontSize / PX_TO_PT,\n fontFamily,\n lineHeight: lineHeight || 1.2,\n splitByGrapheme: effectiveSplitByGrapheme,\n });\n testTextbox.initDimensions();\n \n const lines = testTextbox.textLines || [];\n if (lines.length > maxLines) {\n // Helper to count lines for a given text\n const countLines = (testText: string): number => {\n const tb = new fabric.Textbox(testText, {\n width: w / PX_TO_PT,\n fontSize: finalFontSize / PX_TO_PT,\n fontFamily,\n lineHeight: lineHeight || 1.2,\n splitByGrapheme: effectiveSplitByGrapheme,\n });\n tb.initDimensions();\n return tb.textLines?.length || 1;\n };\n \n // Binary search for the right cutoff point\n let low = 0;\n let high = originalText.length;\n let result = originalText;\n \n while (low < high) {\n const mid = Math.floor((low + high + 1) / 2);\n const testText = originalText.slice(0, mid) + '...';\n const lineCount = countLines(testText);\n \n if (lineCount <= maxLines) {\n low = mid;\n result = testText;\n } else {\n high = mid - 1;\n }\n }\n \n // Trim trailing spaces before ellipsis\n if (result.endsWith('...') && result.length > 3) {\n const beforeEllipsis = result.slice(0, -3).trimEnd();\n result = beforeEllipsis + '...';\n }\n \n finalText = result;\n }\n }\n \n drawText(pdf, finalText, x, y, w, finalFontSize, fontFamily, fontWeight, fontStyle, underline, letterSpacing, fill, textAlign, lineHeight, embeddedFonts, effectiveSplitByGrapheme, liveFabricText);\n break;\n }\n\n case 'image': {\n // Regular image export (masked images are handled early in drawElement())\n const { imageUrl } = norm;\n if (imageUrl) {\n const isSvg = element.sourceFormat === 'svg' || imageUrl.toLowerCase().includes('.svg');\n\n // Fallback crop path (when live crop-group isn't available):\n // use stored crop pan/zoom + frame clipping from element data.\n const hasStoredCrop = Boolean(\n (element as any).useCropHandles ||\n (element as any).cropZoom != null ||\n (element as any).cropPanX != null ||\n (element as any).cropPanY != null\n );\n\n // For SVGs with crop: use vector embed with PDF clip rect (no rasterization)\n if (hasStoredCrop && isSvg && !elementHasFade(element)) {\n const svgElement = await fetchSvgAsElement(imageUrl, element.svgColorMap);\n if (svgElement) {\n expandSvgUseElements(svgElement, element.id);\n const svgToDraw = normalizeSvgExplicitColors(svgElement);\n inlineComputedStyles(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n resolveSvgGradientRefsToSolid(svgToDraw, element.id);\n prefixSvgIds(svgToDraw, element.id);\n bakeGroupOpacityIntoChildren(svgToDraw);\n injectOpacityIntoSvg(svgToDraw, norm.opacity);\n\n const cropZoom = Math.max(1, Number((element as any).cropZoom ?? 1));\n const cropPanX = Math.max(0, Math.min(1, Number((element as any).cropPanX ?? 0.5)));\n const cropPanY = Math.max(0, Math.min(1, Number((element as any).cropPanY ?? 0.5)));\n const naturalW = Math.max(1, Number((element as any).imageNaturalWidth ?? 0) || w);\n const naturalH = Math.max(1, Number((element as any).imageNaturalHeight ?? 0) || h);\n const fitContain = ((element as any).imageFit ?? 'cover') === 'contain';\n const baseScale = fitContain ? Math.min(w / naturalW, h / naturalH) : Math.max(w / naturalW, h / naturalH);\n const finalScale = baseScale * (fitContain ? 1 : cropZoom);\n\n // Draw SVG at zoomed size, offset by pan, clipped to frame\n const drawW = naturalW * finalScale;\n const drawH = naturalH * finalScale;\n const overflowX = Math.max(0, drawW - w);\n const overflowY = Math.max(0, drawH - h);\n const offsetX = overflowX > 0 ? -overflowX * (cropPanX - 0.5) : 0;\n const offsetY = overflowY > 0 ? -overflowY * (cropPanY - 0.5) : 0;\n const svgX = x + w / 2 + offsetX - drawW / 2;\n const svgY = y + h / 2 + offsetY - drawH / 2;\n\n try {\n const seq6 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq6} elementId=${element.id} path=drawElement-svg-crop`);\n pdf.saveGraphicsState();\n // Clip to frame\n pdf.setLineWidth(0);\n pdf.rect(x, y, w, h, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `before svg2pdf #${seq6} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq6, element.id), svg2pdfOpts(svgX, svgY, drawW, drawH));\n debugLog(`svg2pdf DONE #${seq6} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq6} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq6} ${element.id}`);\n break;\n } catch {\n pdf.restoreGraphicsState();\n // fall through to raster\n }\n }\n }\n\n // For raster images with crop: rasterize with clipping\n if (hasStoredCrop && !isSvg) {\n const croppedPng = await rasterizeStoredCropImageToPng({\n imageUrl,\n frameW: w,\n frameH: h,\n clipShape: (element as any).clipShape,\n borderRadius: Number((element as any).rx ?? (element as any).borderRadius ?? norm.borderRadius ?? 0) || 0,\n panX: Number((element as any).cropPanX ?? 0.5),\n panY: Number((element as any).cropPanY ?? 0.5),\n zoom: Number((element as any).cropZoom ?? 1),\n naturalWidth: Number((element as any).imageNaturalWidth ?? 0),\n naturalHeight: Number((element as any).imageNaturalHeight ?? 0),\n maintainResolution: (element as any).maintainResolution !== false,\n backgroundColor,\n });\n if (croppedPng) {\n try {\n const fadedCrop = await bakeEdgeFadeIntoDataUrl(croppedPng, element);\n const finalCropPng = fadedCrop || croppedPng;\n pdf.addImage(finalCropPng, 'PNG', x, y, w, h, undefined, 'SLOW');\n break;\n } catch {\n // fall through to default image path\n }\n }\n }\n\n // Embed SVG as vector for infinite scalability\n // Edge-fade requires a raster mask; skip vector embed when fade is active.\n const canVectorizeSvg = isSvg && !elementHasFade(element);\n if (canVectorizeSvg) {\n const svgElement = await fetchSvgAsElement(imageUrl, element.svgColorMap);\n if (svgElement) {\n expandSvgUseElements(svgElement, element.id);\n const svgToDraw = normalizeSvgExplicitColors(svgElement);\n inlineComputedStyles(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n resolveSvgGradientRefsToSolid(svgToDraw, element.id);\n prefixSvgIds(svgToDraw, element.id);\n bakeGroupOpacityIntoChildren(svgToDraw);\n injectOpacityIntoSvg(svgToDraw, norm.opacity);\n try {\n const seq5 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq5} elementId=${element.id} path=drawElement-image`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `before svg2pdf #${seq5} ${element.id}`);\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq5} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq5, element.id), svg2pdfOpts(x, y, w, h));\n debugLog(`svg2pdf DONE #${seq5} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq5} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq5} ${element.id}`);\n } catch {\n // Raster fallback for SVG vector embed failure — use recolored URL if available\n const rasterUrl = await getRecoloredSvgDataUrl(imageUrl, element.svgColorMap) || imageUrl;\n const imageData = await fetchImageAsBase64(rasterUrl, {\n backgroundColor,\n targetWidthPt: w,\n targetHeightPt: h,\n preserveAlpha: true,\n resolutionMultiplier: 4,\n });\n if (imageData) {\n const fadedFallback = await bakeEdgeFadeIntoDataUrl(imageData.data, element);\n if (fadedFallback) {\n imageData.data = fadedFallback;\n imageData.format = 'PNG';\n }\n try {\n pdf.addImage(imageData.data, imageData.format, x, y, w, h, undefined, 'SLOW');\n } catch {\n // Skip\n }\n }\n }\n break;\n }\n }\n // Raster path (PNG/JPG or SVG fallback)\n const rasterUrlFinal = isSvg ? (await getRecoloredSvgDataUrl(imageUrl, element.svgColorMap) || imageUrl) : imageUrl;\n const preserveAlpha = isSvg || (w > canvasWidth * 0.7 && h > canvasHeight * 0.7);\n const imageData = await fetchImageAsBase64(rasterUrlFinal, {\n backgroundColor: backgroundColor,\n targetWidthPt: w,\n targetHeightPt: h,\n preserveAlpha: preserveAlpha || elementHasFade(element),\n resolutionMultiplier: isSvg ? 4 : undefined,\n });\n if (imageData) {\n const faded = await bakeEdgeFadeIntoDataUrl(imageData.data, element);\n if (faded) {\n imageData.data = faded;\n imageData.format = 'PNG';\n }\n try {\n pdf.addImage(imageData.data, imageData.format, x, y, w, h, undefined, 'SLOW');\n } catch {\n // Skip image on add failure\n }\n }\n }\n break;\n }\n }\n}\n\n/**\n * Export canvas elements to a true vector PDF (single page)\n * @param _fabricCanvas - Deprecated, kept for API compatibility. Elements are read from options.\n */\nexport async function exportFabricCanvasToVectorPdf(\n _fabricCanvas: fabric.Canvas,\n options: {\n filename?: string;\n width: number;\n height: number;\n title?: string;\n elements: CanvasElement[];\n backgroundColor?: string;\n }\n): Promise<void> {\n const { filename = 'document.pdf', width, height, title, elements, backgroundColor } = options;\n resetPdfFontRegistry();\n\n // Create PDF with px units to match canvas exactly\n const orientation = width > height ? 'landscape' : 'portrait';\n const pdf = new jsPDF({\n orientation,\n unit: 'px',\n format: [width, height],\n hotfixes: ['px_scaling'],\n compress: true,\n });\n\n if (title) {\n pdf.setProperties({ title, creator: 'DocuForge' });\n }\n\n // Draw background\n if (backgroundColor && backgroundColor !== 'transparent') {\n const bgColor = parseColor(backgroundColor);\n if (bgColor) {\n pdf.setFillColor(bgColor.r, bgColor.g, bgColor.b);\n pdf.rect(0, 0, width, height, 'F');\n }\n }\n\n const fontKeysNeeded = new Set<string>();\n const italicKeysNeeded = new Set<string>();\n elements.forEach(el => {\n if (el.type === 'text') {\n collectTextFontVariantsForPdf(el, fontKeysNeeded, italicKeysNeeded);\n }\n });\n // Always embed symbol fallback so ● ◆ ★ etc. render\n fontKeysNeeded.add(`${FONT_FALLBACK_SYMBOLS}${FONT_KEY_SEP}400`);\n // Always embed math fallback so ≠ ≤ ≥ ≈ ∞ → ∑ √ ∈ … render\n fontKeysNeeded.add(`${FONT_FALLBACK_MATH}${FONT_KEY_SEP}400`);\n // Always embed Devanagari fallback for Hindi text support\n for (const w of [300, 400, 500, 600, 700]) {\n fontKeysNeeded.add(`${FONT_FALLBACK_DEVANAGARI}${FONT_KEY_SEP}${w}`);\n }\n\n const embeddedFonts = new Set<string>();\n for (const key of fontKeysNeeded) {\n const sep = key.indexOf(FONT_KEY_SEP);\n const fontName = key.slice(0, sep);\n const weight = parseInt(key.slice(sep + 1), 10);\n const success = await embedFontWithGoogleFallback(pdf, fontName, weight);\n if (success) embeddedFonts.add(key);\n }\n // Embed italic variants\n for (const key of italicKeysNeeded) {\n const parts = key.split(FONT_KEY_SEP);\n const fontName = parts[0];\n const weight = parseInt(parts[1], 10);\n const success = await embedFontWithGoogleFallback(pdf, fontName, weight, true);\n if (success) embeddedFonts.add(key);\n }\n\n // Diagnostic embed list\n try {\n const list = getEmbeddedVariantsList();\n // eslint-disable-next-line no-console\n console.log(`[pdfFonts] embedded variants (${list.length}):`, list);\n } catch {}\n\n // Draw elements in order (bottom to top) using the helper\n debugLog(`single-page export: drawing ${elements.length} elements (order = first=back, last=front)`);\n elements.forEach((el, i) => debugLog(` [${i}] id=${el.id} type=${el.type}`));\n for (const element of elements) {\n await drawElement(pdf, element, embeddedFonts, width, height, backgroundColor);\n }\n\n // Save the PDF\n pdf.save(filename);\n}\n\n/** Group background rect drawn in PDF (same z-order as on canvas) */\nexport type GroupBackgroundDrawable = {\n type: 'groupBackground';\n id: string;\n left: number;\n top: number;\n width: number;\n height: number;\n fill: string;\n};\n\nexport type PageDrawableItem = CanvasElement | GroupBackgroundDrawable;\n\nfunction isGroupBackgroundDrawable(item: PageDrawableItem): item is GroupBackgroundDrawable {\n return (item as GroupBackgroundDrawable).type === 'groupBackground';\n}\n\n/** Build draw list in tree order (group bgs behind their content) so PDF matches canvas. */\nfunction buildPageDrawList(\n children: CanvasNode[],\n pageTree: CanvasNode[],\n visibilityFilter: 'strict' | 'lenient'\n): PageDrawableItem[] {\n const out: PageDrawableItem[] = [];\n function visit(nodes: CanvasNode[], reverseGroupChildren: boolean) {\n const list = reverseGroupChildren ? [...nodes].reverse() : nodes;\n for (const n of list) {\n if (isElement(n)) {\n if (visibilityFilter === 'strict' ? n.visible !== false : n.visible) out.push(n);\n } else if (isGroup(n)) {\n const g = n as GroupNode;\n if (g.backgroundColor && g.backgroundColor !== 'transparent') {\n const abs = getAbsoluteBounds(g, pageTree);\n out.push({\n type: 'groupBackground',\n id: g.id,\n left: abs.left,\n top: abs.top,\n width: Math.max(1, abs.width),\n height: Math.max(1, abs.height),\n fill: g.backgroundColor,\n });\n }\n visit(g.children ?? [], true);\n }\n }\n }\n visit(children, false);\n return out;\n}\n\n/**\n * Prepare pages data for PDF export from either editor canvas or use template preview\n * This ensures consistent filtering and sorting across both export paths.\n * Includes group background rects in tree order so they appear in the rendered PDF.\n */\nexport function preparePagesForExport(\n pages: Array<{\n id?: string;\n children?: CanvasNode[] | any[];\n settings?: { backgroundColor?: string; backgroundGradient?: any };\n }>,\n canvasWidth: number,\n canvasHeight: number,\n options?: {\n sortByTop?: boolean; // Sort elements by top position (for z-order when no group bgs)\n visibilityFilter?: 'strict' | 'lenient'; // 'strict' = el.visible !== false, 'lenient' = el.visible\n }\n): Array<{\n pageId?: string;\n elements: PageDrawableItem[];\n pageChildren?: CanvasNode[];\n width: number;\n height: number;\n backgroundColor?: string;\n}> {\n const { sortByTop = false, visibilityFilter = 'strict' } = options || {};\n\n return pages.map(page => {\n const pageChildren = (page.children || []) as CanvasNode[];\n const drawList = buildPageDrawList(pageChildren, pageChildren, visibilityFilter);\n\n // If no group backgrounds were added, we can optionally sort elements by top for z-order\n const elements =\n sortByTop && drawList.every(item => !isGroupBackgroundDrawable(item))\n ? [...drawList].sort((a, b) => {\n const aTop = 'top' in a ? (a.top ?? (a as CanvasElement).position?.y ?? 0) : 0;\n const bTop = 'top' in b ? (b.top ?? (b as CanvasElement).position?.y ?? 0) : 0;\n return aTop - bTop;\n })\n : drawList;\n\n return {\n pageId: page.id,\n elements,\n pageChildren,\n width: canvasWidth,\n height: canvasHeight,\n backgroundColor: page.settings?.backgroundColor || '#ffffff',\n backgroundGradient: page.settings?.backgroundGradient,\n };\n });\n}\n\n/**\n * Export multiple pages to a single PDF.\n *\n * By default writes the PDF as a download via `pdf.save(filename)`. When\n * `returnBlob: true` is passed, returns `{ blob, arrayBuffer, totalPages, pages }`\n * instead so callers (e.g. the canvas-renderer package server harness) can use\n * the exact same draw pipeline without triggering a browser download.\n */\nexport async function exportMultiPagePdf(\n pages: Array<{\n pageId?: string;\n elements: PageDrawableItem[];\n pageChildren?: CanvasNode[];\n width: number;\n height: number;\n backgroundColor?: string;\n backgroundGradient?: any;\n }>,\n options: {\n filename?: string;\n title?: string;\n watermark?: boolean;\n /** When true, skip pdf.save() and return PDF blob/arraybuffer instead. */\n returnBlob?: boolean;\n /**\n * PDF text rendering mode. Affects how gradient text fills are handled:\n * - 'selectable' (default): text stays live; gradient fills resolve to the\n * first stop colour because svg2pdf can't render gradients on live text.\n * - 'auto': text with a gradient fill is outlined to <path> so the\n * gradient renders in the PDF (only that text loses selectability;\n * everything else stays selectable).\n * - 'pixel-perfect': every text element is outlined to vector paths for\n * visual parity, whether it uses a gradient fill or not.\n */\n pdfTextMode?: 'auto' | 'selectable' | 'pixel-perfect';\n }\n): Promise<void | { blob: Blob; arrayBuffer: ArrayBuffer; totalPages: number; pages: Array<{ width: number; height: number }> }> {\n const { filename = 'document.pdf', title, watermark = false, returnBlob = false, pdfTextMode = 'selectable' } = options;\n resetPdfFontRegistry();\n\n if (pages.length === 0) {\n throw new Error('No pages to export');\n }\n\n const firstPage = pages[0];\n const orientation = firstPage.width > firstPage.height ? 'landscape' : 'portrait';\n\n const pdf = new jsPDF({\n orientation,\n unit: 'px',\n format: [firstPage.width, firstPage.height],\n hotfixes: ['px_scaling'],\n compress: true,\n });\n\n if (title) {\n pdf.setProperties({ title, creator: 'DocuForge' });\n }\n\n const fontKeysNeeded = new Set<string>();\n const italicKeysNeeded = new Set<string>();\n pages.forEach(page => {\n page.elements.forEach(item => {\n if (!isGroupBackgroundDrawable(item) && item.type === 'text') {\n collectTextFontVariantsForPdf(item, fontKeysNeeded, italicKeysNeeded);\n }\n });\n });\n fontKeysNeeded.add(`${FONT_FALLBACK_SYMBOLS}${FONT_KEY_SEP}400`);\n fontKeysNeeded.add(`${FONT_FALLBACK_MATH}${FONT_KEY_SEP}400`);\n for (const w of [300, 400, 500, 600, 700]) {\n fontKeysNeeded.add(`${FONT_FALLBACK_DEVANAGARI}${FONT_KEY_SEP}${w}`);\n }\n\n const embeddedFonts = new Set<string>();\n for (const key of fontKeysNeeded) {\n const sep = key.indexOf(FONT_KEY_SEP);\n const fontName = key.slice(0, sep);\n const weight = parseInt(key.slice(sep + 1), 10);\n const success = await embedFontWithGoogleFallback(pdf, fontName, weight);\n if (success) embeddedFonts.add(key);\n await yieldToUI(); // Let spinner animate between font embeds\n }\n for (const key of italicKeysNeeded) {\n const parts = key.split(FONT_KEY_SEP);\n const fontName = parts[0];\n const weight = parseInt(parts[1], 10);\n const success = await embedFontWithGoogleFallback(pdf, fontName, weight, true);\n if (success) embeddedFonts.add(key);\n await yieldToUI();\n }\n\n await yieldToUI(); // Yield before page rendering begins\n\n // Diagnostic: log the exact embed list so we can compare client vs server.\n // Helps pinpoint file-size discrepancies between the two pipelines.\n try {\n const list = getEmbeddedVariantsList();\n // eslint-disable-next-line no-console\n console.log(`[pdfFonts] embedded variants (${list.length}):`, list);\n } catch {}\n\n // Draw each page\n for (let pageIndex = 0; pageIndex < pages.length; pageIndex++) {\n const page = pages[pageIndex];\n\n // Add new page for pages after the first\n if (pageIndex > 0) {\n const pageOrientation = page.width > page.height ? 'landscape' : 'portrait';\n pdf.addPage([page.width, page.height], pageOrientation);\n }\n\n // Draw background — gradient using native PDF shading patterns (axial/radial).\n // This produces perfectly smooth gradients with minimal file size — no strips needed.\n if (page.backgroundGradient && page.backgroundGradient.stops?.length >= 2) {\n const grad = page.backgroundGradient;\n const colorStops = grad.stops\n .map((s: any) => {\n const c = parseColor(s.color);\n return {\n offset: Math.max(0, Math.min(1, Number(s.offset))),\n color: c ? [c.r, c.g, c.b] as [number, number, number] : [0, 0, 0] as [number, number, number],\n };\n })\n .filter((s: any) => Number.isFinite(s.offset))\n .sort((a: any, b: any) => a.offset - b.offset);\n\n const normalizedStops = [...colorStops];\n if (normalizedStops.length > 0) {\n if (normalizedStops[0].offset > 0) {\n normalizedStops.unshift({ offset: 0, color: normalizedStops[0].color });\n }\n if (normalizedStops[normalizedStops.length - 1].offset < 1) {\n const last = normalizedStops[normalizedStops.length - 1];\n normalizedStops.push({ offset: 1, color: last.color });\n }\n }\n\n const shadingColors = normalizedStops.map(s => ({ offset: s.offset, color: s.color }));\n const patternKey = `bg-grad-${pageIndex}`;\n\n try {\n pdf.advancedAPI((doc: any) => {\n const isLinear = grad.type === 'linear';\n const isConic = grad.type === 'conic';\n\n if (isLinear || isConic) {\n // For conic gradients, approximate with a linear gradient at the specified angle\n // PDF doesn't support conic natively. We use a linear sweep as a reasonable fallback.\n const angleDeg = grad.angle ?? (isConic ? 0 : 90);\n const angleRad = (angleDeg * Math.PI) / 180;\n const sinA = Math.sin(angleRad);\n const cosA = Math.cos(angleRad);\n\n // Project page corners onto gradient direction to find extent\n const corners = [[0, 0], [page.width, 0], [page.width, page.height], [0, page.height]];\n const projs = corners.map(([x, y]) => x * sinA - y * cosA);\n const minP = Math.min(...projs);\n const maxP = Math.max(...projs);\n const gradLen = maxP - minP;\n\n const midX = page.width / 2;\n const midY = page.height / 2;\n const halfLen = gradLen / 2;\n const x1 = midX - sinA * halfLen;\n const y1 = midY + cosA * halfLen;\n const x2 = midX + sinA * halfLen;\n const y2 = midY - cosA * halfLen;\n\n // For conic, duplicate stops to wrap around (simulate the sweep)\n let finalStops = shadingColors;\n if (isConic && shadingColors.length >= 2) {\n // Mirror the stops to create a sweep effect: original + reversed\n const reversed = [...shadingColors].reverse().map((s, idx, arr) => ({\n offset: 0.5 + (1 - s.offset) * 0.5,\n color: s.color,\n }));\n const firstHalf = shadingColors.map(s => ({\n offset: s.offset * 0.5,\n color: s.color,\n }));\n finalStops = [...firstHalf, ...reversed.slice(1)];\n }\n\n doc.addShadingPattern(\n patternKey,\n new ShadingPattern('axial', [x1, y1, x2, y2], finalStops)\n );\n } else {\n // Radial gradient\n const cx = (grad.cx ?? 0.5) * page.width;\n const cy = (grad.cy ?? 0.5) * page.height;\n // Match canvas/Fabric radial gradient radius mapping for color parity.\n const maxR = (grad.r ?? 0.5) * Math.max(page.width, page.height);\n\n doc.addShadingPattern(\n patternKey,\n new ShadingPattern('radial', [cx, cy, 0, cx, cy, maxR], shadingColors)\n );\n }\n\n // Draw rect clipping path then fill with the shading pattern\n doc.rect(0, 0, page.width, page.height);\n doc.fill({ key: patternKey, matrix: doc.Matrix(1, 0, 0, 1, 0, 0) });\n });\n } catch (e) {\n debugLog(`Native gradient shading failed, falling back to solid: ${e}`);\n const fallback = colorStops[0]?.color || [255, 255, 255];\n pdf.setFillColor(fallback[0], fallback[1], fallback[2]);\n pdf.rect(0, 0, page.width, page.height, 'F');\n }\n } else {\n const bgColor = parseColor(page.backgroundColor && page.backgroundColor !== 'transparent' ? page.backgroundColor : '#ffffff');\n debugLog(`page ${pageIndex + 1} background: ${page.backgroundColor ?? 'default'} → rgb(${bgColor?.r ?? 0},${bgColor?.g ?? 0},${bgColor?.b ?? 0})`);\n if (bgColor) {\n pdf.setFillColor(bgColor.r, bgColor.g, bgColor.b);\n pdf.rect(0, 0, page.width, page.height, 'F');\n }\n }\n\n const liveCanvasForPage = page.pageId ? getCanvasForPage(page.pageId) : null;\n let allowLiveCanvasFallback = !!liveCanvasForPage;\n\n // Prefer exporting the actual live Fabric canvas as SVG first.\n // This is the closest client-side match to the server's Fabric -> SVG -> svg2pdf pipeline.\n if (liveCanvasForPage) {\n try {\n // SHARED CAPTURE: identical to the client `renderPageSvg` pipeline —\n // does VPT/retina neutralization, edge-fade bake, toSVG, and root\n // <svg> normalization in one place so client and server PDFs match.\n const liveSvgString = captureFabricCanvasSvgForPdf(\n liveCanvasForPage as any,\n page.width,\n page.height,\n );\n const liveSvgWidth = page.width;\n const liveSvgHeight = page.height;\n // SHARED JIT FONT EMBED: must run BEFORE prepareLiveCanvasSvgForPdf\n // so the SVG-font rewriter (inside prepareLiveCanvasSvgForPdf) maps\n // each (family, weight, italic) tuple in the live SVG to the correct\n // embedded jsPDF font. Without this the rewriter can fall back to a\n // different variant on the server (which never ran the JIT pass),\n // changing glyph advance widths → horizontal text drift on\n // center-aligned text and a slight shadow offset (the rasterized\n // shadow marker is anchored to the text's bounding box).\n try {\n await embedFontsForSvg(pdf, liveSvgString);\n } catch (fontEmbedErr) {\n console.warn('[client-pdf-export] JIT font embed for live SVG failed', fontEmbedErr);\n }\n // Shared text-prep contract with @pixldocs/canvas-renderer:\n // pixel-perfect → outline all text\n // auto → outline only gradient text\n // selectable → keep text live, replace gradient with first stop\n let preppedSvgString = liveSvgString;\n try {\n const { prepareSvgTextForPdfMode } = await import('@/lib/svgTextToPath');\n preppedSvgString = await prepareSvgTextForPdfMode(liveSvgString, pdfTextMode);\n console.log('[client-pdf-export] gradient text mode', {\n pdfTextMode,\n outlinedAllText: pdfTextMode === 'pixel-perfect',\n outlinedGradientText: pdfTextMode === 'auto',\n });\n } catch (gradErr) {\n console.warn('[client-pdf-export] gradient-text fill resolution failed', gradErr);\n }\n const liveSvg = await prepareLiveCanvasSvgForPdf(\n preppedSvgString,\n liveSvgWidth,\n liveSvgHeight,\n `page-${pageIndex + 1}`,\n { stripPageBackground: !!page.backgroundGradient },\n );\n\n if (liveSvg) {\n const seq = ++debugSvgDrawSequence;\n console.log(`[client-pdf-export] live SVG path active for page ${pageIndex + 1}`);\n debugLog(`live canvas svg2pdf START #${seq} page=${pageIndex + 1}`);\n resetPdfColorState(pdf, `before live canvas svg2pdf page ${pageIndex + 1}`);\n setPdfColorFromSvg(pdf, liveSvg, `page-${pageIndex + 1}`);\n await svg2pdfWithDomMount(\n liveSvg,\n pdfWithColorLogging(pdf, seq, `page-${pageIndex + 1}`),\n svg2pdfOpts(0, 0, page.width, page.height),\n );\n debugLog(`live canvas svg2pdf DONE #${seq} page=${pageIndex + 1}`);\n resetPdfColorState(pdf, `after live canvas svg2pdf page ${pageIndex + 1}`);\n await yieldToUI();\n continue;\n }\n allowLiveCanvasFallback = false;\n console.error(`[client-pdf-export] live SVG prep returned null for page ${pageIndex + 1}`, {\n pageId: page.pageId,\n hasLiveCanvas: !!liveCanvasForPage,\n svgLength: liveSvgString?.length ?? 0,\n });\n } catch (error) {\n allowLiveCanvasFallback = false;\n console.error(`[client-pdf-export] live SVG export failed for page ${pageIndex + 1}`, error);\n debugLog(`live canvas svg export failed on page ${pageIndex + 1}, falling back to config-space export without live matrices: ${error}`);\n }\n }\n\n // If we have a live Fabric canvas for this page, use its objects' transform matrices.\n // This avoids any subtle drift between stored values and Fabric's internal layout math.\n // IMPORTANT: For grouped elements, we need to look inside fabric.Group objects\n // because group members are not top-level canvas objects.\n const matrixByElementId = new Map<string, number[]>();\n const intrinsicByElementId = new Map<string, { w: number; h: number }>();\n\n const getIntrinsic = (o: fabric.FabricObject): { w: number; h: number } => {\n if (o instanceof fabric.Circle) {\n const r = (o as any).radius ?? 0;\n return { w: r * 2, h: r * 2 };\n }\n if (o instanceof fabric.Ellipse) {\n return { w: (o.rx ?? 0) * 2, h: (o.ry ?? 0) * 2 };\n }\n return { w: o.width ?? 0, h: o.height ?? 0 };\n };\n\n // Live Fabric text objects: use their exact line layout for WYSIWYG text export\n const liveTextByElementId = new Map<string, fabric.FabricObject>();\n\n if (page.pageId && allowLiveCanvasFallback) {\n const liveCanvas = getCanvasForPage(page.pageId);\n if (liveCanvas) {\n const objects = liveCanvas.getObjects();\n const isTextLike = (o: fabric.FabricObject) =>\n o instanceof fabric.Textbox || o instanceof fabric.IText || (o as any).constructor?.name === 'Textbox' || (o as any).constructor?.name === 'Text';\n\n for (const obj of objects) {\n const isCropGroup = obj instanceof fabric.Group && (obj as any).__cropGroup;\n if (isCropGroup) {\n const id = (obj as any).__docuforgeId as string | undefined;\n if (!id || id === '__background__') continue;\n (obj as any).__exportAsRenderedImage = true;\n intrinsicByElementId.set(id, getIntrinsic(obj));\n try {\n matrixByElementId.set(id, (obj as any).calcTransformMatrix());\n } catch {\n }\n continue;\n }\n\n const isSectionGroup = obj instanceof fabric.Group && (obj as any).__docuforgeSectionGroup;\n const groupId = (obj as any).__docuforgeGroupId as string | undefined;\n if ((groupId || isSectionGroup) && obj instanceof fabric.Group) {\n const groupMatrix = obj.calcTransformMatrix();\n const memberObjects = obj.getObjects();\n for (const memberObj of memberObjects) {\n const memberId = (memberObj as any).__docuforgeId as string | undefined;\n if (!memberId) continue;\n\n intrinsicByElementId.set(memberId, getIntrinsic(memberObj));\n if (isTextLike(memberObj)) {\n liveTextByElementId.set(memberId, memberObj);\n }\n\n try {\n const memberLocalMatrix =\n (memberObj as any).calcOwnMatrix?.() ?? (memberObj as any).calcTransformMatrix?.();\n\n if (memberLocalMatrix && memberLocalMatrix.length === 6) {\n const [a1, b1, c1, d1, e1, f1] = groupMatrix;\n const [a2, b2, c2, d2, e2, f2] = memberLocalMatrix;\n const absoluteMatrix = [\n a1 * a2 + c1 * b2,\n b1 * a2 + d1 * b2,\n a1 * c2 + c1 * d2,\n b1 * c2 + d1 * d2,\n a1 * e2 + c1 * f2 + e1,\n b1 * e2 + d1 * f2 + f1,\n ];\n matrixByElementId.set(memberId, absoluteMatrix);\n }\n } catch {\n }\n }\n continue;\n }\n\n const id = (obj as any).__docuforgeId as string | undefined;\n if (!id || id === '__background__') continue;\n\n intrinsicByElementId.set(id, getIntrinsic(obj));\n if (isTextLike(obj)) {\n liveTextByElementId.set(id, obj);\n }\n\n try {\n matrixByElementId.set(id, (obj as any).calcTransformMatrix());\n } catch {\n }\n }\n }\n }\n\n // When we have a live canvas, use its object order so PDF z-order matches what's on screen.\n // (sortByTop in preparePagesForExport can reorder by y-position and break stacking.)\n let drawList = page.elements;\n if (page.pageId && allowLiveCanvasFallback) {\n const liveCanvas = getCanvasForPage(page.pageId);\n const hasGroupBgs = page.elements.some(item => isGroupBackgroundDrawable(item));\n if (liveCanvas && !hasGroupBgs) {\n const canvasOrderIds = liveCanvas.getObjects().map((o: fabric.FabricObject) => (o as any).__docuforgeId as string).filter(Boolean);\n const byId = new Map((page.elements as CanvasElement[]).map(el => [el.id, el]));\n const reordered: PageDrawableItem[] = [];\n for (const id of canvasOrderIds) {\n const el = byId.get(id);\n if (el) reordered.push(el);\n }\n for (const item of page.elements) {\n if (!reordered.includes(item)) reordered.push(item);\n }\n drawList = reordered.length ? reordered : page.elements;\n }\n }\n\n // ── CLIENT PARITY LOG: print text positions in same format as EC2 server ──\n const clientTextPositions: Array<{p:number; id:string; top:number; left:number; w:number; h:number; fs:number; lh:number; angle:number; text:string}> = [];\n for (const item of drawList) {\n if (isGroupBackgroundDrawable(item)) continue;\n const el = item as CanvasElement;\n if (el.type !== 'text') continue;\n const n = normalizeElement(el);\n // If we have pageChildren, use getAbsoluteBounds for true position\n let absX = n.x, absY = n.y, absW = n.w, absH = n.h;\n if (page.pageChildren?.length) {\n const node = findNodeById(page.pageChildren, el.id);\n if (node) {\n const abs = getAbsoluteBounds(node, page.pageChildren);\n absX = abs.left; absY = abs.top; absW = abs.width; absH = abs.height;\n }\n }\n clientTextPositions.push({\n p: pageIndex + 1,\n id: el.id.slice(0, 50),\n top: Math.round(absY * 100) / 100,\n left: Math.round(absX * 100) / 100,\n w: Math.round(absW * 100) / 100,\n h: Math.round(absH * 100) / 100,\n fs: n.fontSize,\n lh: n.lineHeight,\n angle: n.angle,\n text: (n.text || '').replace(/\\s+/g, ' ').trim().slice(0, 60),\n });\n }\n if (clientTextPositions.length > 0) {\n console.log(`[client-pdf-export] page ${pageIndex + 1} textPositions (${clientTextPositions.length}):`, JSON.stringify(clientTextPositions));\n }\n\n // Draw items in order (first=back, last=front)\n debugSvgDrawSequence = 0;\n debugLog(`page ${pageIndex + 1}: drawing ${drawList.length} items (order = first=back, last=front)`);\n resetPdfColorState(pdf, `page ${pageIndex + 1} start`);\n for (let drawIndex = 0; drawIndex < drawList.length; drawIndex++) {\n const item = drawList[drawIndex];\n if (isGroupBackgroundDrawable(item)) {\n debugLog(` [${drawIndex}] groupBg id=${item.id}`);\n const c = parseColor(item.fill);\n if (c) {\n pdf.setFillColor(c.r, c.g, c.b);\n pdf.rect(item.left, item.top, item.width, item.height, 'F');\n }\n continue;\n }\n const element = item;\n const imgUrl = element.type === 'image' ? (element.imageUrl || element.src || '').slice(-40) : '';\n debugLog(` [${drawIndex}] element id=${element.id} type=${element.type} ${imgUrl ? `imageUrl=...${imgUrl}` : ''}`);\n // Prefer live canvas matrix, fall back to stored transformMatrix if available\n const liveMatrix = matrixByElementId.get(element.id);\n const storedMatrix = element.transformMatrix;\n const m = liveMatrix ?? storedMatrix ?? null;\n let intrinsic = intrinsicByElementId.get(element.id) ?? null;\n \n const liveText = element.type === 'text' ? liveTextByElementId.get(element.id) : undefined;\n await drawElement(pdf, element, embeddedFonts, page.width, page.height, page.backgroundColor, m, intrinsic, page.pageId, liveText, page.pageChildren);\n\n // Yield every 3 elements to keep UI responsive (spinners, progress bars)\n if (drawIndex % 3 === 2) await yieldToUI();\n }\n\n // Yield between pages\n await yieldToUI();\n }\n\n // Add watermark if requested (free downloads)\n if (watermark) {\n const { addWatermarkToAllPages } = await import('@/lib/pdfWatermark');\n addWatermarkToAllPages(pdf);\n }\n\n if (returnBlob) {\n const arrayBuffer = (pdf.output('arraybuffer') as ArrayBuffer);\n const blob = new Blob([arrayBuffer], { type: 'application/pdf' });\n return {\n blob,\n arrayBuffer,\n totalPages: pages.length,\n pages: pages.map(p => ({ width: p.width, height: p.height })),\n };\n }\n\n pdf.save(filename);\n}\n"],"names":["FONT_FALLBACK_SYMBOLS","FONT_FALLBACK_DEVANAGARI","FONT_FALLBACK_MATH","_a","elementHasEdgeFade","m","r","g","b","_b","blob","type","hasAlpha","jpegUrl","flattenWithBg","dataUrl","rx","outW","outH","el","exportCanvas","png","_e","panX","panY","zoom","scaleX","scaleY","anyPdf","canUseAdvancedTransforms","angle","hasRotation","clampedOpacity","imageData","linkUrl","id"],"mappings":"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"}
1
+ {"version":3,"file":"vectorPdfExport-CSh0zFox.js","sources":["../../../src/lib/vectorPdfExport.ts"],"sourcesContent":["import { jsPDF, ShadingPattern } from 'jspdf';\nimport { svg2pdf } from 'svg2pdf.js';\nimport * as fabric from 'fabric';\nimport { CanvasElement, flattenChildren, CanvasNode, GroupNode, isGroup, isElement, findNodeById } from '@/types/editor';\nimport { getAbsoluteBounds } from '@/lib/layoutEngine';\nimport { embedFont, embedFontWithGoogleFallback, FONT_FALLBACK_SYMBOLS, FONT_FALLBACK_DEVANAGARI, FONT_FALLBACK_MATH, getEmbeddedJsPDFFontName, isFontAvailable, isFamilyEmbedded, resolveFontWeight, hasItalicVariant, resolveBestRegisteredVariant, doesVariantSupportChar, resetPdfFontRegistry, getEmbeddedVariantsList } from './pdfFonts';\nimport { getCanvasForPage } from '@/store/fabricCanvasRegistry';\nimport { getProxiedImageUrl } from './canvasImageLoader';\nimport { API_URL, getImageProxyFetchOptions } from '@/lib/api';\nimport { getRoundedRectRadii, getTrianglePoints, normalizeShapeType, buildRoundedTrianglePath, TRIANGLE_STROKE_MITER_LIMIT } from './shapeGeometry';\nimport { renderSmartElementToSvg } from '@/lib/smartElements/registry';\nimport { hasEdgeFade as elementHasEdgeFade, bakeEdgeFade, EdgeFadeProps } from './imageEdgeFade';\nimport { parseTextMarkdown } from '@/lib/textMarkdown';\nimport { captureFabricCanvasSvgForPdf } from './canvasSvgCapture';\n\n/**\n * Shared JIT font-variant embedder. Scans the live Fabric SVG for every\n * (family, weight, italic) tuple actually used by `<text>`/`<tspan>` (including\n * rich-text spans introduced by inline markdown bold/italic) and registers\n * any missing variant into the supplied jsPDF instance via\n * `embedFontWithGoogleFallback` (local TTF → Fontshare → Google Fonts).\n *\n * MUST run BEFORE `prepareLiveCanvasSvgForPdf` (which rewrites font-family\n * to the embedded jsPDF font names). If a variant isn't registered when\n * the rewriter runs, jsPDF falls back to a different glyph set → different\n * advance widths → horizontal text shift in the exported PDF.\n *\n * Used by BOTH the host UsePackage flow and the unified `exportMultiPagePdf`\n * live-canvas branch (which is the server EC2 path) so both PDFs reach\n * identical glyph-width parity.\n */\nexport async function embedFontsForSvg(pdf: jsPDF, svgStr: string): Promise<void> {\n const {\n embedFontWithGoogleFallback: _embedFontWithGoogleFallback,\n isVariantEmbedded,\n resolveFontWeight: _resolveFontWeight,\n FONT_FALLBACK_SYMBOLS,\n FONT_FALLBACK_DEVANAGARI,\n FONT_FALLBACK_MATH,\n } = await import('@/lib/pdfFonts');\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(svgStr, 'image/svg+xml');\n const textEls = Array.from(doc.querySelectorAll('text, tspan, textPath'));\n\n const readStyleToken = (style: string, prop: string): string | null => {\n const m = style.match(new RegExp(`${prop}\\\\s*:\\\\s*([^;]+)`, 'i'));\n return m?.[1]?.trim() || null;\n };\n const resolveInherited = (el: Element, attr: string, styleProp = attr): string | null => {\n let cur: Element | null = el;\n while (cur) {\n const a = cur.getAttribute(attr)?.trim();\n if (a) return a;\n const s = readStyleToken(cur.getAttribute('style') || '', styleProp);\n if (s) return s;\n cur = cur.parentElement;\n }\n return null;\n };\n const parseWeight = (raw: string): number => {\n const n = Number.parseInt(raw, 10);\n if (Number.isFinite(n)) return n;\n const s = raw.toLowerCase();\n if (/bold/.test(s)) return 700;\n if (/semi|demi/.test(s)) return 600;\n if (/medium/.test(s)) return 500;\n if (/light|thin/.test(s)) return 300;\n return 400;\n };\n\n const needed = new Map<string, { family: string; weight: number; italic: boolean }>();\n for (const el of textEls) {\n const rawFf = resolveInherited(el, 'font-family');\n if (!rawFf) continue;\n const family = rawFf.split(',')[0]?.replace(/['\"]/g, '').trim();\n if (!family) continue;\n const weight = _resolveFontWeight(parseWeight(resolveInherited(el, 'font-weight') || '400'));\n const italic = /italic|oblique/i.test(resolveInherited(el, 'font-style') || 'normal');\n const key = `${family}\\u001F${weight}\\u001F${italic ? 'i' : 'n'}`;\n if (!needed.has(key)) needed.set(key, { family, weight, italic });\n }\n\n let embedded = 0;\n for (const { family, weight, italic } of needed.values()) {\n if (isVariantEmbedded(family, weight, italic)) continue;\n await _embedFontWithGoogleFallback(pdf, family, weight, italic);\n if (isVariantEmbedded(family, weight, italic)) embedded++;\n }\n // Pre-embed per-character fallback fonts so the SVG rewriter's symbol/math/\n // devanagari runs resolve to real glyphs instead of `.notdef`.\n const fallbackFamilies: Array<{ family: string; weight: number }> = [\n { family: FONT_FALLBACK_SYMBOLS, weight: 400 },\n { family: FONT_FALLBACK_MATH, weight: 400 },\n ];\n for (const w of [300, 400, 500, 600, 700]) {\n fallbackFamilies.push({ family: FONT_FALLBACK_DEVANAGARI, weight: w });\n }\n for (const { family, weight } of fallbackFamilies) {\n if (isVariantEmbedded(family, weight, false)) continue;\n await _embedFontWithGoogleFallback(pdf, family, weight, false);\n if (isVariantEmbedded(family, weight, false)) embedded++;\n }\n // Italic + heavy-weight fallback so the rewriter can downgrade weight while\n // keeping italic glyphs (synthetic bold via stroke).\n for (const { family, weight, italic } of needed.values()) {\n if (!italic) continue;\n if (!isVariantEmbedded(family, weight, false)) {\n await _embedFontWithGoogleFallback(pdf, family, weight, false);\n if (isVariantEmbedded(family, weight, false)) embedded++;\n }\n if (!isVariantEmbedded(family, 400, false)) {\n await _embedFontWithGoogleFallback(pdf, family, 400, false);\n if (isVariantEmbedded(family, 400, false)) embedded++;\n }\n if (weight <= 400) continue;\n if (isVariantEmbedded(family, 400, true)) continue;\n await _embedFontWithGoogleFallback(pdf, family, 400, true);\n if (isVariantEmbedded(family, 400, true)) embedded++;\n }\n console.log('[Vector PDF Debug] embedFontsForSvg', {\n requested: needed.size,\n newlyEmbedded: embedded,\n sample: [...needed.values()].slice(0, 12),\n });\n}\n\n/**\n * If the element has any per-side edge fade configured, bake the fade into the\n * given raster data URL and return a fresh PNG data URL. Otherwise returns null.\n * Used by the vector-PDF image paths so the fade visible in the editor matches\n * what gets embedded into the exported PDF (raster only — vector SVG paths\n * fall back to raster when fade is active).\n */\nasync function bakeEdgeFadeIntoDataUrl(\n dataUrl: string,\n element: CanvasElement,\n): Promise<string | null> {\n const fade = element as unknown as EdgeFadeProps;\n if (!elementHasEdgeFade(fade)) return null;\n if (!dataUrl || typeof dataUrl !== 'string') return null;\n return await new Promise<string | null>((resolve) => {\n try {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n try {\n const c = bakeEdgeFade(img, fade);\n resolve(c.toDataURL('image/png'));\n } catch {\n resolve(null);\n }\n };\n img.onerror = () => resolve(null);\n img.src = dataUrl;\n } catch {\n resolve(null);\n }\n });\n}\n\nfunction elementHasFade(element: CanvasElement): boolean {\n return elementHasEdgeFade(element as unknown as EdgeFadeProps);\n}\n\n/** Set to true to log PDF export draw order and SVG paths for debugging color/order issues. */\nconst DEBUG_PDF_EXPORT = false;\n\n/**\n * Yield control back to the browser's event loop so animations (spinners, progress bars)\n * can paint between heavy synchronous computation chunks.\n * Uses requestAnimationFrame + setTimeout double-yield for reliable frame painting.\n */\nconst yieldToUI = (): Promise<void> =>\n new Promise((resolve) => {\n requestAnimationFrame(() => setTimeout(resolve, 0));\n });\n\n/** Set to true to log SVG structure: <use> expansion and top-level tags (for \"half rendered\" debug). */\nconst DEBUG_SVG_STRUCTURE = false;\n\n/**\n * Set to true to flatten all SVG gradients to solid colors for PDF export.\n * - Prevents color leaking between SVGs (every path has explicit fill, svg2pdf sets it).\n * - Trade-off: gradients in PDF become flat (one color per shape, from gradient's first stop).\n * Set to true to guarantee no color leak (gradients become flat in PDF).\n */\nconst FLATTEN_SVG_GRADIENTS_FOR_PDF = false;\n\n/** Set to true to log every setFillColor/setDrawColor/setTextColor from svg2pdf (noisy). */\nconst DEBUG_PDF_COLOR_VERBOSE = false;\n\n/** Browser SVG-filter rasterization renders soft shadows a little denser than Canvas2D. */\nconst SHADOW_RASTER_ALPHA_COMPENSATION = 0.84;\n\n/**\n * Scan an SVG markup fragment for every distinct font-family / font-weight /\n * font-style / font-size combination used by `<text>` / `<tspan>` elements.\n * Returns a list of CSS `font-shorthand` specs suitable for\n * `document.fonts.load(spec)`. Used by the shadow rasterizer to wait for\n * every font referenced inside the offscreen SVG-in-img render BEFORE\n * painting — without this, on real browsers the shadow silhouette paints\n * with a fallback font (wider glyphs / wrong metrics) and visibly mis-\n * registers against the real text above it. Puppeteer happens to dodge\n * this because the harness preloads all Google Fonts before rendering, so\n * the bug only shows up in the user's own browser export.\n */\nfunction collectFontSpecsFromShadowMarkup(markup: string): string[] {\n const specs = new Set<string>();\n const re = /<(?:text|tspan)\\b[^>]*>/gi;\n let match: RegExpExecArray | null;\n while ((match = re.exec(markup)) !== null) {\n const tag = match[0];\n const get = (attr: string): string | null => {\n const m = tag.match(new RegExp(`\\\\s${attr}\\\\s*=\\\\s*\"([^\"]*)\"`, 'i'));\n if (m) return m[1];\n const styleM = tag.match(/\\sstyle\\s*=\\s*\"([^\"]*)\"/i);\n if (styleM) {\n const sm = styleM[1].match(new RegExp(`${attr}\\\\s*:\\\\s*([^;]+)`, 'i'));\n if (sm) return sm[1].trim();\n }\n return null;\n };\n const family = (get('font-family') || '').split(',')[0].replace(/['\"]/g, '').trim();\n if (!family) continue;\n const weight = get('font-weight') || '400';\n const style = get('font-style') || 'normal';\n const size = get('font-size') || '16px';\n const sizePx = /[a-z%]/i.test(size) ? size : `${size}px`;\n const famSpec = /\\s/.test(family) ? `\"${family}\"` : family;\n specs.add(`${style} ${weight} ${sizePx} ${famSpec}`);\n }\n return Array.from(specs);\n}\n\n/** Increments each time we're about to draw an SVG (for debug logs). */\nlet debugSvgDrawSequence = 0;\n\nfunction debugLog(...args: unknown[]) {\n if (DEBUG_PDF_EXPORT) console.log('[PDF export]', ...args);\n}\n\n/** Wrap pdf so we log every color change made by svg2pdf (to debug leak). */\nfunction pdfWithColorLogging(pdf: jsPDF, seq: number, elementId: string): jsPDF {\n if (!DEBUG_PDF_COLOR_VERBOSE) return pdf;\n return new Proxy(pdf, {\n get(target, prop: string) {\n const val = (target as any)[prop];\n if (prop === 'setFillColor' && typeof val === 'function') {\n return function (this: any, ...args: unknown[]) {\n debugLog(`[COLOR] svg2pdf #${seq} elementId=${elementId} setFillColor(${args.join(',')})`);\n return val.apply(target, args);\n };\n }\n if (prop === 'setDrawColor' && typeof val === 'function') {\n return function (this: any, ...args: unknown[]) {\n debugLog(`[COLOR] svg2pdf #${seq} elementId=${elementId} setDrawColor(${args.join(',')})`);\n return val.apply(target, args);\n };\n }\n if (prop === 'setTextColor' && typeof val === 'function') {\n return function (this: any, ...args: unknown[]) {\n debugLog(`[COLOR] svg2pdf #${seq} elementId=${elementId} setTextColor(${args.join(',')})`);\n return val.apply(target, args);\n };\n }\n return val;\n },\n }) as jsPDF;\n}\n\n/** Separator for embedded font key \"fontFamily\\u001Fweight\" (unit separator, not in font names) */\nconst FONT_KEY_SEP = '\\u001F';\n\nfunction normalizePdfFontWeight(raw: unknown): number {\n if (typeof raw === 'number' && Number.isFinite(raw)) return resolveFontWeight(raw);\n const str = String(raw ?? '').trim().toLowerCase();\n const parsed = Number.parseInt(str, 10);\n if (Number.isFinite(parsed)) return resolveFontWeight(parsed);\n if (str === 'bold' || str === 'bolder') return 700;\n if (str === 'semibold' || str === 'demibold') return 600;\n if (str === 'medium') return 500;\n if (str === 'light' || str === 'lighter' || str === 'thin') return 300;\n return 400;\n}\n\nfunction collectTextFontVariantsForPdf(\n el: any,\n fontKeysNeeded: Set<string>,\n italicKeysNeeded: Set<string>,\n): void {\n const baseFamily = el?.fontFamily || el?.style?.fontFamily;\n if (!baseFamily) return;\n\n const addVariant = (family: string, weightRaw: unknown, styleRaw: unknown) => {\n const resolved = normalizePdfFontWeight(weightRaw);\n if (/italic|oblique/i.test(String(styleRaw ?? ''))) {\n italicKeysNeeded.add(`${family}${FONT_KEY_SEP}${resolved}${FONT_KEY_SEP}italic`);\n } else {\n fontKeysNeeded.add(`${family}${FONT_KEY_SEP}${resolved}`);\n }\n };\n\n addVariant(baseFamily, el.fontWeight ?? el.style?.fontWeight ?? 400, el.fontStyle ?? el.style?.fontStyle ?? 'normal');\n\n // Fabric rich text stores per-character inline styles as object-keyed maps:\n // { lineIndex: { charIndex: { fontWeight/fontStyle/fontFamily } } }.\n const styles = el.styles;\n if (styles && typeof styles === 'object') {\n for (const lineStyles of Object.values(styles) as any[]) {\n if (!lineStyles || typeof lineStyles !== 'object') continue;\n for (const s of Object.values(lineStyles) as any[]) {\n if (!s || typeof s !== 'object') continue;\n addVariant(s.fontFamily || baseFamily, s.fontWeight ?? el.fontWeight ?? 400, s.fontStyle ?? el.fontStyle ?? 'normal');\n }\n }\n }\n\n // Inline markdown (`formattingEnabled`) is parsed into Fabric styles only at\n // render time. The PDF pre-embed pass must mirror that parse, otherwise\n // `<tspan font-weight=\"700\">` runs render with the regular font or Helvetica.\n if (el.formattingEnabled === true && typeof el.text === 'string') {\n try {\n const parsed = parseTextMarkdown(el.text);\n for (const lineStyles of Object.values(parsed.styles || {}) as any[]) {\n if (!lineStyles || typeof lineStyles !== 'object') continue;\n for (const s of Object.values(lineStyles) as any[]) {\n if (!s || typeof s !== 'object') continue;\n addVariant(s.fontFamily || baseFamily, s.fontWeight ?? el.fontWeight ?? 400, s.fontStyle ?? el.fontStyle ?? 'normal');\n }\n }\n } catch {\n // Markdown parsing is best-effort; base font embedding above still applies.\n }\n }\n}\n\n/** True if the character is in Basic Latin or Latin-1 (typical for embedded body fonts). Otherwise use symbol fallback font. */\nfunction isBasicLatinOrLatin1(char: string): boolean {\n const c = char.codePointAt(0) ?? 0;\n return (c >= 0x20 && c <= 0x7e) || (c >= 0xa0 && c <= 0xff);\n}\n\n/**\n * Common typographic punctuation that virtually every modern Latin font\n * (Google Fonts, Fontshare, etc.) includes in its default subset. We must\n * NOT route these to the symbol-fallback font (Noto Sans) because doing so\n * makes them look visually different from the live canvas — e.g. an em-dash\n * (U+2014) rendered through a fallback can appear as a thin \"artificial line\"\n * instead of the matching dash glyph from the active font.\n *\n * Whitelist: General Punctuation block characters covered by Google Fonts'\n * Latin subset (em/en-dashes, smart quotes, ellipsis, bullet, primes, etc.)\n * plus ™ (U+2122) which is also part of the Latin subset.\n */\nfunction isCommonLatinPunctuation(char: string): boolean {\n const c = char.codePointAt(0) ?? 0;\n // Hyphens & dashes, smart quotes, daggers, bullets, ellipsis, primes,\n // single guillemets, fraction slash, etc.\n if (c >= 0x2010 && c <= 0x2049) return true;\n // ℓ (script l), ™\n if (c === 0x2113 || c === 0x2122) return true;\n return false;\n}\n\n/** True if the char is a math operator / arrow / supplemental-math glyph that\n * is typically MISSING from main Latin fonts AND from the FONT_FALLBACK_SYMBOLS\n * Latin subset (e.g. ≠ ≤ ≥ ≈ ∞ → ← ∑ √ ∈ ∀ ∃ ∂ ∇ etc.). These need the\n * dedicated FONT_FALLBACK_MATH font to render. */\nfunction isMathOperator(char: string): boolean {\n const c = char.codePointAt(0) ?? 0;\n if (c >= 0x2190 && c <= 0x21FF) return true; // Arrows\n if (c >= 0x2200 && c <= 0x22FF) return true; // Mathematical Operators (≠ ≤ ≥ ≈ ∞ ∑ √ ∈ …)\n if (c >= 0x2300 && c <= 0x23FF) return true; // Misc Technical (⌐ ⌒ …)\n if (c >= 0x27C0 && c <= 0x27EF) return true; // Misc Mathematical Symbols-A\n if (c >= 0x2980 && c <= 0x29FF) return true; // Misc Mathematical Symbols-B\n if (c >= 0x2A00 && c <= 0x2AFF) return true; // Supplemental Math Operators\n if (c >= 0x2B00 && c <= 0x2B59) return true; // additional arrows / geometric\n return false;\n}\n\n/** True if the character is in the Devanagari Unicode block (Hindi, Marathi, Sanskrit, etc.) */\nfunction isDevanagari(char: string): boolean {\n const c = char.codePointAt(0) ?? 0;\n return (c >= 0x0900 && c <= 0x097F) || (c >= 0xA8E0 && c <= 0xA8FF) || (c >= 0x1CD0 && c <= 0x1CFF);\n}\n\n/** Check if a string contains any Devanagari characters */\nfunction containsDevanagari(text: string): boolean {\n if (!text) return false;\n for (const char of text) {\n if (isDevanagari(char)) return true;\n }\n return false;\n}\n\n/** Classify a character's font run type: 'main' (Latin), 'devanagari' (Hindi script),\n * 'math' (math operator / arrow needing FONT_FALLBACK_MATH), or 'symbol' (general fallback). */\ntype RunType = 'main' | 'devanagari' | 'math' | 'symbol';\nfunction classifyChar(char: string, mainSupportsChar?: (char: string) => boolean): RunType {\n if (isBasicLatinOrLatin1(char)) return 'main';\n if (isCommonLatinPunctuation(char)) return 'main';\n if (!isDevanagari(char) && mainSupportsChar?.(char)) return 'main';\n if (isDevanagari(char)) return 'devanagari';\n if (isMathOperator(char)) return 'math';\n return 'symbol';\n}\n\n/** Fast check: true when every character is Basic Latin / Latin-1 — no run-splitting needed. */\nfunction isPureLatin(line: string): boolean {\n for (let i = 0; i < line.length; i++) {\n const c = line.charCodeAt(i);\n if (\n !((c >= 0x20 && c <= 0x7e) ||\n (c >= 0xa0 && c <= 0xff) ||\n (c >= 0x2010 && c <= 0x2049) ||\n c === 0x2113 || c === 0x2122)\n ) return false;\n }\n return true;\n}\n\n/** Split a line into runs of main-font, devanagari-font, or symbol-fallback-font. */\nfunction splitLineIntoRuns(line: string, mainSupportsChar?: (char: string) => boolean): { text: string; runType: RunType }[] {\n if (!line) return [];\n const runs: { text: string; runType: RunType }[] = [];\n const chars = [...line];\n let current = '';\n let currentType: RunType = 'main';\n for (const char of chars) {\n const charType = classifyChar(char, mainSupportsChar);\n if (current && charType !== currentType) {\n runs.push({ text: current, runType: currentType });\n current = '';\n }\n currentType = charType;\n current += char;\n }\n if (current) runs.push({ text: current, runType: currentType });\n return runs;\n}\n\n/** Load image from URL and return natural dimensions (used when Fabric image has baked/display size after move). */\nfunction loadNaturalDimensionsFromUrl(imageUrl: string): Promise<{ width: number; height: number } | null> {\n return new Promise((resolve) => {\n if (!imageUrl) {\n resolve(null);\n return;\n }\n const img = new Image();\n img.crossOrigin = imageUrl.startsWith('data:') || imageUrl.startsWith('blob:') ? undefined : 'anonymous';\n img.onload = () => {\n const w = img.naturalWidth || 0;\n const h = img.naturalHeight || 0;\n resolve(w > 0 && h > 0 ? { width: w, height: h } : null);\n };\n img.onerror = () => resolve(null);\n try {\n img.src = imageUrl.startsWith('data:') || imageUrl.startsWith('blob:') ? imageUrl : getProxiedImageUrl(imageUrl);\n } catch {\n resolve(null);\n }\n });\n}\n\nasync function rasterizeStoredCropImageToPng(options: {\n imageUrl: string;\n frameW: number;\n frameH: number;\n clipShape?: string;\n borderRadius?: number;\n panX?: number;\n panY?: number;\n zoom?: number;\n naturalWidth?: number;\n naturalHeight?: number;\n maintainResolution?: boolean;\n backgroundColor?: string;\n}): Promise<string | null> {\n const {\n imageUrl,\n frameW,\n frameH,\n clipShape,\n borderRadius = 0,\n panX = 0.5,\n panY = 0.5,\n zoom = 1,\n naturalWidth,\n naturalHeight,\n maintainResolution = true,\n backgroundColor,\n } = options;\n\n if (!imageUrl || frameW <= 0 || frameH <= 0) return null;\n\n const img = await new Promise<HTMLImageElement | null>((resolve) => {\n const el = new Image();\n el.crossOrigin = imageUrl.startsWith('data:') || imageUrl.startsWith('blob:') ? undefined : 'anonymous';\n el.onload = () => resolve(el);\n el.onerror = () => resolve(null);\n try {\n el.src = imageUrl.startsWith('data:') || imageUrl.startsWith('blob:') ? imageUrl : getProxiedImageUrl(imageUrl);\n } catch {\n resolve(null);\n }\n });\n\n if (!img) return null;\n\n const natW = Math.max(1, naturalWidth || img.naturalWidth || frameW);\n const natH = Math.max(1, naturalHeight || img.naturalHeight || frameH);\n const baseScale = Math.max(frameW / natW, frameH / natH);\n const finalScale = Math.max(1, zoom) * baseScale;\n const drawW = natW * finalScale;\n const drawH = natH * finalScale;\n\n const clampedPanX = Math.max(0, Math.min(1, panX));\n const clampedPanY = Math.max(0, Math.min(1, panY));\n const overflowX = Math.max(0, drawW - frameW);\n const overflowY = Math.max(0, drawH - frameH);\n const offsetX = overflowX > 0 ? -overflowX * (clampedPanX - 0.5) : 0;\n const offsetY = overflowY > 0 ? -overflowY * (clampedPanY - 0.5) : 0;\n const imgX = frameW / 2 + offsetX - drawW / 2;\n const imgY = frameH / 2 + offsetY - drawH / 2;\n\n const outW = maintainResolution && natW > frameW ? Math.max(1, Math.round(natW)) : Math.max(1, Math.round(frameW * 2));\n const outH = maintainResolution && natH > frameH ? Math.max(1, Math.round(natH)) : Math.max(1, Math.round(frameH * 2));\n\n const canvas = document.createElement('canvas');\n canvas.width = outW;\n canvas.height = outH;\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n\n const bgFill = backgroundColor && backgroundColor !== 'transparent' && backgroundColor !== 'none'\n ? normalizeBgColor(backgroundColor)\n : undefined;\n\n if (bgFill) {\n ctx.fillStyle = bgFill;\n ctx.fillRect(0, 0, outW, outH);\n } else {\n ctx.clearRect(0, 0, outW, outH);\n }\n\n const sx = outW / frameW;\n const sy = outH / frameH;\n ctx.save();\n ctx.scale(sx, sy);\n ctx.beginPath();\n\n if (clipShape === 'circle') {\n ctx.ellipse(frameW / 2, frameH / 2, frameW / 2, frameH / 2, 0, 0, 2 * Math.PI);\n } else {\n const isRounded = clipShape === 'rounded' || clipShape === 'roundRect' || (borderRadius ?? 0) > 0;\n const r = isRounded ? Math.max(0, Math.min(borderRadius, frameW / 2, frameH / 2)) : 0;\n if (r > 0) {\n ctx.moveTo(r, 0);\n ctx.lineTo(frameW - r, 0);\n ctx.quadraticCurveTo(frameW, 0, frameW, r);\n ctx.lineTo(frameW, frameH - r);\n ctx.quadraticCurveTo(frameW, frameH, frameW - r, frameH);\n ctx.lineTo(r, frameH);\n ctx.quadraticCurveTo(0, frameH, 0, frameH - r);\n ctx.lineTo(0, r);\n ctx.quadraticCurveTo(0, 0, r, 0);\n ctx.closePath();\n } else {\n ctx.rect(0, 0, frameW, frameH);\n }\n }\n\n ctx.clip();\n ctx.drawImage(img, imgX, imgY, drawW, drawH);\n ctx.restore();\n\n return canvas.toDataURL('image/png');\n}\n\n/** svg2pdf options sanitizer: keep sub-pixel precision for accurate placement while guarding invalid values. */\nfunction svg2pdfOpts(x: number, y: number, width: number, height: number) {\n const sanitize = (value: number, fallback: number): number => {\n if (!Number.isFinite(value)) return fallback;\n return Number(value.toFixed(3));\n };\n\n const w = Math.max(0.001, sanitize(width, 1));\n const h = Math.max(0.001, sanitize(height, 1));\n\n return {\n x: sanitize(x, 0),\n y: sanitize(y, 0),\n width: w,\n height: h,\n };\n}\n\n/**\n * For axis-aligned matrices (no skew/rotation and no mirroring), compute a stable page-space frame\n * so we can render SVGs without CTM (avoids occasional transform drift).\n */\nfunction getAxisAlignedSvgFrameFromMatrix(\n matrix: Matrix6,\n localX: number,\n localY: number,\n width: number,\n height: number\n): { x: number; y: number; width: number; height: number } | null {\n const [a, b, c, d, e, f] = matrix;\n const EPS = 1e-5;\n if (Math.abs(b) > EPS || Math.abs(c) > EPS) return null;\n\n // Mirrored (negative) scales must use matrix path; flattening to page-space frame\n // loses orientation and can shift visible placement for directional SVGs.\n if (a < -EPS || d < -EPS) return null;\n\n const x1 = a * localX + e;\n const x2 = a * (localX + width) + e;\n const y1 = d * localY + f;\n const y2 = d * (localY + height) + f;\n\n const left = Math.min(x1, x2);\n const top = Math.min(y1, y2);\n const frameW = Math.max(0, Math.abs(x2 - x1));\n const frameH = Math.max(0, Math.abs(y2 - y1));\n\n if (!Number.isFinite(left) || !Number.isFinite(top) || !Number.isFinite(frameW) || !Number.isFinite(frameH)) {\n return null;\n }\n if (frameW < EPS || frameH < EPS) return null;\n\n return { x: left, y: top, width: frameW, height: frameH };\n}\n\nfunction transformPointWithMatrix(matrix: Matrix6, x: number, y: number): { x: number; y: number } {\n const [a, b, c, d, e, f] = matrix;\n return {\n x: a * x + c * y + e,\n y: b * x + d * y + f,\n };\n}\n\nfunction buildMatrixTransformedSvgForPage(\n svg: Element,\n matrix: Matrix6,\n localX: number,\n localY: number,\n width: number,\n height: number\n): { svg: SVGSVGElement; frame: { x: number; y: number; width: number; height: number } } | null {\n const EPS = 1e-5;\n const corners = [\n transformPointWithMatrix(matrix, localX, localY),\n transformPointWithMatrix(matrix, localX + width, localY),\n transformPointWithMatrix(matrix, localX, localY + height),\n transformPointWithMatrix(matrix, localX + width, localY + height),\n ];\n\n const minX = Math.min(...corners.map((p) => p.x));\n const minY = Math.min(...corners.map((p) => p.y));\n const maxX = Math.max(...corners.map((p) => p.x));\n const maxY = Math.max(...corners.map((p) => p.y));\n const frameW = maxX - minX;\n const frameH = maxY - minY;\n\n if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(frameW) || !Number.isFinite(frameH)) {\n return null;\n }\n if (frameW < EPS || frameH < EPS) return null;\n\n const ns = 'http://www.w3.org/2000/svg';\n const wrapper = document.createElementNS(ns, 'svg') as SVGSVGElement;\n wrapper.setAttribute('xmlns', ns);\n wrapper.setAttribute('width', String(frameW));\n wrapper.setAttribute('height', String(frameH));\n wrapper.setAttribute('viewBox', `0 0 ${frameW} ${frameH}`);\n\n const g = document.createElementNS(ns, 'g');\n const [a, b, c, d, e, f] = matrix;\n g.setAttribute('transform', `matrix(${a} ${b} ${c} ${d} ${e - minX} ${f - minY})`);\n\n const nested = svg.cloneNode(true) as Element;\n nested.setAttribute('x', String(localX));\n nested.setAttribute('y', String(localY));\n nested.setAttribute('width', String(width));\n nested.setAttribute('height', String(height));\n\n g.appendChild(nested);\n wrapper.appendChild(g);\n\n return {\n svg: wrapper,\n frame: { x: minX, y: minY, width: frameW, height: frameH },\n };\n}\n\n/**\n * Mount SVG in the DOM temporarily so svg2pdf can resolve gradient <defs> references,\n * then run svg2pdf, then unmount. This fixes gradient rendering issues where svg2pdf\n * couldn't find referenced paint servers in detached SVG clones.\n */\nasync function svg2pdfWithDomMount(\n svg: Element,\n pdf: jsPDF,\n opts: ReturnType<typeof svg2pdfOpts>\n): Promise<void> {\n const wrap = document.createElement('div');\n wrap.style.cssText = 'position:fixed;left:-9999px;top:0;width:0;height:0;overflow:hidden;pointer-events:none;opacity:0';\n wrap.appendChild(svg);\n document.body.appendChild(wrap);\n try {\n await svg2pdf(svg, pdf, opts);\n } finally {\n svg.remove();\n if (wrap.parentNode) document.body.removeChild(wrap);\n }\n}\n\n/**\n * WHY COLOR LEAKS BETWEEN SVGs (two causes):\n * 1) jsPDF reuses form objects (gradients, patterns) by ID. If two SVGs both have a gradient id=\"linear-gradient\",\n * the second SVG gets the first SVG's gradient (same form object) → wrong color. Fix: prefix all ids per SVG\n * (prefixSvgIds) so each SVG has unique ids. See yWorks/svg2pdf.js#171, #166, PR #188.\n * 2) PDF has a single \"current\" fill/stroke. svg2pdf may not call setFillColor for gradient elements, so the\n * current fill can stay from the previous SVG. Fix: reset + setPdfColorFromSvg before each svg2pdf, reset after.\n */\nfunction resetPdfColorState(pdf: jsPDF, label?: string) {\n if (DEBUG_PDF_EXPORT && label) debugLog(`[COLOR] reset → black (${label})`);\n pdf.setFillColor(0, 0, 0);\n pdf.setDrawColor(0, 0, 0);\n if (typeof (pdf as any).setTextColor === 'function') (pdf as any).setTextColor(0, 0, 0);\n}\n\n/** Get the first explicit fill/stroke color found in the SVG tree (hex or rgb), for use as PDF currentColor. Resolves url(#gradient) to a solid so the default is correct per-SVG (avoids leaking previous SVG's color). */\nfunction getFirstExplicitColorFromSvg(svg: Element): { fill: string | null; stroke: string | null } {\n let fill: string | null = null;\n let stroke: string | null = null;\n const isRealColor = (v: string | null): boolean => {\n if (!v || v === 'none') return false;\n const s = v.trim().toLowerCase();\n return s !== 'currentcolor' && s !== 'inherit' && (s.startsWith('#') || s.startsWith('rgb'));\n };\n const resolveUrl = (v: string | null): string | null => {\n if (!v || v === 'none') return null;\n const gradientId = extractGradientIdFromPaint(v);\n if (!gradientId) return null;\n return getGradientStopColorAsHex(svg, gradientId);\n };\n function walk(el: Element) {\n if (fill && stroke) return;\n const f = el.getAttribute('fill') ?? (el as SVGElement).style?.getPropertyValue('fill');\n const s = el.getAttribute('stroke') ?? (el as SVGElement).style?.getPropertyValue('stroke');\n if (!fill) {\n if (isRealColor(f)) fill = f;\n else if (f) {\n const resolved = resolveUrl(f);\n if (resolved) fill = resolved;\n }\n }\n if (!stroke) {\n if (isRealColor(s)) stroke = s;\n else if (s) {\n const resolved = resolveUrl(s);\n if (resolved) stroke = resolved;\n }\n }\n for (let i = 0; i < el.children.length; i++) walk(el.children[i]);\n }\n walk(svg);\n return { fill, stroke };\n}\n\n/** Set PDF fill and stroke from the SVG's first explicit colors so svg2pdf has a sensible default. Call resetPdfColorState(pdf) before this so we never leak the previous SVG's colors. */\nfunction setPdfColorFromSvg(pdf: jsPDF, svg: Element, elementId?: string) {\n const { fill, stroke } = getFirstExplicitColorFromSvg(svg);\n const rgbFill = fill ? parseColor(fill) : null;\n const rgbStroke = stroke ? parseColor(stroke) : null;\n if (DEBUG_PDF_EXPORT && elementId) {\n debugLog(`[COLOR] setPdfColorFromSvg elementId=${elementId} fill=${fill ?? 'black'} stroke=${stroke ?? 'black'} → rgb(${rgbFill ? `${rgbFill.r},${rgbFill.g},${rgbFill.b}` : '0,0,0'}) / (${rgbStroke ? `${rgbStroke.r},${rgbStroke.g},${rgbStroke.b}` : '0,0,0'})`);\n }\n if (rgbFill) pdf.setFillColor(rgbFill.r, rgbFill.g, rgbFill.b);\n else pdf.setFillColor(0, 0, 0);\n if (rgbStroke) pdf.setDrawColor(rgbStroke.r, rgbStroke.g, rgbStroke.b);\n else pdf.setDrawColor(0, 0, 0);\n}\n\n/** Tags that draw and need explicit fill/stroke so svg2pdf renders them (it often only reads attributes, not CSS). */\nconst SVG_DRAWABLE_TAGS = new Set(['path', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'line', 'text', 'tspan']);\n\n/**\n * Non-rendering / definition subtrees must not inherit synthesized paint from ancestors.\n * Doing so can turn mask/clipPath helper geometry into visible filled rectangles in svg2pdf.\n */\nconst SVG_DEFINITION_CONTAINER_TAGS = new Set([\n 'defs',\n 'clippath',\n 'mask',\n 'pattern',\n 'marker',\n 'symbol',\n 'filter',\n 'lineargradient',\n 'radialgradient',\n]);\n\nfunction isInSvgDefinitionSubtree(el: Element): boolean {\n let current: Element | null = el;\n while (current) {\n const tag = current.tagName?.toLowerCase() ?? '';\n if (SVG_DEFINITION_CONTAINER_TAGS.has(tag)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\nfunction parseInlineSvgStyleDeclarations(styleText: string): Array<{ key: string; value: string }> {\n return styleText\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => {\n const idx = part.indexOf(':');\n if (idx <= 0) return null;\n return {\n key: part.slice(0, idx).trim().toLowerCase(),\n value: part.slice(idx + 1).trim(),\n };\n })\n .filter((x): x is { key: string; value: string } => !!x);\n}\n\nfunction logGradientBindingDiagnostics(svg: Element): void {\n const gradientCount = svg.querySelectorAll('linearGradient, radialGradient').length;\n if (gradientCount === 0) return;\n\n let gradientRefCount = 0;\n svg.querySelectorAll('*').forEach((el) => {\n const fill = el.getAttribute('fill');\n const stroke = el.getAttribute('stroke');\n const style = el.getAttribute('style');\n if (extractGradientIdFromPaint(fill) || extractGradientIdFromPaint(stroke)) {\n gradientRefCount++;\n return;\n }\n if (style) {\n const declarations = parseInlineSvgStyleDeclarations(style);\n if (declarations.some(({ value }) => !!extractGradientIdFromPaint(value))) {\n gradientRefCount++;\n }\n }\n });\n\n if (gradientRefCount === 0) {\n console.warn('[PDF export] SVG gradient diagnostics: defs exist but no gradient refs bound after style inlining. Export may render black.', {\n gradientCount,\n drawableCount: svg.querySelectorAll('path, rect, circle, ellipse, polygon, polyline, line').length,\n });\n }\n}\n\nconst SVG_STYLE_PROPS = new Set([\n 'fill',\n 'stroke',\n 'color',\n 'opacity',\n 'fill-opacity',\n 'stroke-opacity',\n 'fill-rule',\n 'stroke-width',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'display',\n 'visibility',\n 'stop-color',\n 'stop-opacity',\n 'clip-rule',\n 'clip-path',\n 'mask',\n 'filter',\n]);\n\nfunction inlineSvgStyleBlockDeclarations(svg: Element): void {\n const styleNodes = Array.from(svg.querySelectorAll('style'));\n if (styleNodes.length === 0) return;\n\n const cssText = styleNodes\n .map((node) => node.textContent || '')\n .join('\\n')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, ' ');\n if (!cssText.trim()) return;\n\n const allElements = [svg, ...Array.from(svg.querySelectorAll('*'))];\n const classIndex = new Map<string, Element[]>();\n allElements.forEach((el) => {\n const raw = el.getAttribute('class') || '';\n raw.split(/\\s+/)\n .map((token) => token.trim())\n .filter(Boolean)\n .forEach((token) => {\n const list = classIndex.get(token) ?? [];\n list.push(el);\n classIndex.set(token, list);\n });\n });\n\n const normalizePresentationValue = (key: string, value: string): string => {\n // Strip !important — valid in CSS but invalid in SVG presentation attributes\n const cleaned = value.replace(/\\s*!important\\s*$/i, '').trim();\n if (['fill', 'stroke', 'clip-path', 'mask', 'filter'].includes(key)) {\n return normalizeGradientPaintRef(cleaned);\n }\n return cleaned;\n };\n\n const applyDeclarations = (\n elements: Iterable<Element>,\n declarations: Array<{ key: string; value: string }>\n ) => {\n for (const el of elements) {\n const inlineStyle = el.getAttribute('style') || '';\n const inlineDeclMap = new Map(\n parseInlineSvgStyleDeclarations(inlineStyle).map(({ key, value }) => [key, value])\n );\n\n for (const { key, value } of declarations) {\n if (!value || inlineDeclMap.has(key)) continue;\n el.setAttribute(key, normalizePresentationValue(key, value));\n }\n }\n };\n\n const ruleRegex = /([^{}]+)\\{([^}]*)\\}/g;\n let ruleMatch: RegExpExecArray | null;\n while ((ruleMatch = ruleRegex.exec(cssText))) {\n const selectors = ruleMatch[1].split(',').map((s) => s.trim()).filter(Boolean);\n const declarations = parseInlineSvgStyleDeclarations(ruleMatch[2]).filter((decl) => SVG_STYLE_PROPS.has(decl.key));\n if (selectors.length === 0 || declarations.length === 0) continue;\n\n for (const selector of selectors) {\n if (!selector || selector.startsWith('@')) continue;\n\n const classOnlyMatch = selector.match(/^\\.([A-Za-z_][\\w-]*)$/);\n if (classOnlyMatch) {\n applyDeclarations(classIndex.get(classOnlyMatch[1]) ?? [], declarations);\n continue;\n }\n\n try {\n applyDeclarations(svg.querySelectorAll(selector), declarations);\n } catch {\n const classMatch = selector.match(/\\.([A-Za-z0-9_-]+)/);\n if (classMatch) {\n applyDeclarations(classIndex.get(classMatch[1]) ?? [], declarations);\n }\n }\n }\n }\n\n for (const el of allElements) {\n const style = el.getAttribute('style');\n if (!style) continue;\n\n const keptDecls: string[] = [];\n let changed = false;\n for (const { key, value } of parseInlineSvgStyleDeclarations(style)) {\n if (SVG_STYLE_PROPS.has(key)) {\n el.setAttribute(key, normalizePresentationValue(key, value));\n changed = true;\n } else {\n keptDecls.push(`${key}: ${value}`);\n }\n }\n\n if (changed) {\n if (keptDecls.length > 0) el.setAttribute('style', keptDecls.join('; '));\n else el.removeAttribute('style');\n }\n }\n\n for (const styleNode of styleNodes) {\n const css = styleNode.textContent || '';\n let cleaned = css;\n for (const prop of SVG_STYLE_PROPS) {\n const regex = new RegExp(`${prop.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&')}\\\\s*:\\\\s*[^;}{]+;?`, 'gi');\n cleaned = cleaned.replace(regex, '');\n }\n styleNode.textContent = cleaned\n .replace(/;\\s*;/g, ';')\n .replace(/\\{\\s*;/g, '{')\n .replace(/;\\s*}/g, '}')\n .replace(/\\{\\s*}/g, '{}');\n }\n}\n\n/** Inline fill/stroke onto drawable nodes so svg2pdf sees resolved values without forcing black over class-based gradients. */\nfunction normalizeSvgExplicitColors(svg: Element): Element {\n const clone = svg.cloneNode(true) as Element;\n inlineSvgStyleBlockDeclarations(clone);\n logGradientBindingDiagnostics(clone);\n\n const parseColorAttr = (v: string | null): string | null => {\n if (!v) return null;\n const s = v.trim().toLowerCase();\n if (!s || s === 'none' || s === 'transparent' || s === 'currentcolor') return null;\n return normalizeGradientPaintRef(v);\n };\n\n const getRawAttr = (el: Element, attr: 'fill' | 'stroke' | 'color'): string =>\n (el.getAttribute(attr) ?? (el as SVGElement).style?.getPropertyValue(attr) ?? '').trim().toLowerCase();\n\n const getRawOpacityAttr = (el: Element, attr: 'fill' | 'stroke' | 'color'): string => {\n if (attr === 'color') return '';\n return (el.getAttribute(`${attr}-opacity`) ?? (el as SVGElement).style?.getPropertyValue(`${attr}-opacity`) ?? '').trim().toLowerCase();\n };\n\n const hasExplicitNonePaint = (el: Element, attr: 'fill' | 'stroke'): boolean => {\n const raw = getRawAttr(el, attr);\n if (raw === 'none' || raw === 'transparent') return true;\n const rawOpacity = getRawOpacityAttr(el, attr);\n return rawOpacity === '0' || rawOpacity === '0%' || rawOpacity === '0.0';\n };\n\n const getAttr = (el: Element, attr: 'fill' | 'stroke' | 'color'): string | null => {\n const v = el.getAttribute(attr) ?? (el as SVGElement).style?.getPropertyValue(attr);\n return parseColorAttr(v);\n };\n\n function walk(el: Element, parentFill: string | null, parentStroke: string | null, parentColor: string | null) {\n if (isInSvgDefinitionSubtree(el)) {\n for (let i = 0; i < el.children.length; i++) {\n walk(el.children[i], null, null, null);\n }\n return;\n }\n\n const tag = el.tagName?.toLowerCase() ?? '';\n const isDrawable = SVG_DRAWABLE_TAGS.has(tag);\n let fill = getAttr(el, 'fill');\n let stroke = getAttr(el, 'stroke');\n const color = getAttr(el, 'color') ?? parentColor;\n const fillNone = hasExplicitNonePaint(el, 'fill');\n const strokeNone = hasExplicitNonePaint(el, 'stroke');\n const inheritedFill = parentFill === 'none' ? null : parentFill;\n const inheritedStroke = parentStroke === 'none' ? null : parentStroke;\n\n if (isDrawable) {\n if (fillNone) {\n el.setAttribute('fill', 'none');\n fill = null;\n } else {\n const resolved = fill ?? color ?? inheritedFill;\n if (resolved) {\n el.setAttribute('fill', resolved);\n fill = resolved;\n } else if (tag !== 'text' && tag !== 'tspan') {\n // Fabric / editor use transparent canvas; missing fill must not fall through to svg2pdf\n // using jsPDF's current fill (black after setPdfColorFromSvg). SVG defaults would be black\n // for shapes — explicit none matches on-screen transparent areas (e.g. icon bounding rects).\n el.setAttribute('fill', 'none');\n fill = null;\n }\n }\n }\n\n if (isDrawable) {\n if (strokeNone) {\n el.setAttribute('stroke', 'none');\n stroke = null;\n } else if (stroke != null || color != null || inheritedStroke != null) {\n const resolved = stroke ?? color ?? inheritedStroke;\n if (resolved) {\n el.setAttribute('stroke', resolved);\n stroke = resolved;\n }\n }\n }\n\n const nextColor = color ?? parentColor;\n const nextFill = fillNone ? 'none' : (fill ?? inheritedFill);\n const nextStroke = strokeNone ? 'none' : (stroke ?? inheritedStroke);\n for (let i = 0; i < el.children.length; i++) {\n walk(el.children[i], nextFill, nextStroke, nextColor);\n }\n }\n\n const rootColor = getAttr(clone, 'color') ?? (clone.getAttribute('color') || null);\n const rootFill = getAttr(clone, 'fill') ?? rootColor;\n const rootStroke = getAttr(clone, 'stroke') ?? rootColor;\n const rootFillNone = hasExplicitNonePaint(clone, 'fill');\n const rootStrokeNone = hasExplicitNonePaint(clone, 'stroke');\n\n if (rootFillNone) {\n clone.setAttribute('fill', 'none');\n } else if (rootFill) {\n clone.setAttribute('fill', rootFill);\n }\n if (rootStrokeNone) {\n clone.setAttribute('stroke', 'none');\n } else if (rootStroke) {\n clone.setAttribute('stroke', rootStroke);\n }\n\n for (let i = 0; i < clone.children.length; i++) {\n walk(\n clone.children[i],\n rootFillNone ? 'none' : (rootFill ?? null),\n rootStrokeNone ? 'none' : (rootStroke ?? null),\n rootColor\n );\n }\n\n return clone;\n}\n\n/** Bake element-level opacity into SVG nodes so svg2pdf preserves opacity consistently.\n * We multiply existing per-node opacity values instead of relying on PDF GState opacity,\n * because svg2pdf may override GState while drawing nested paths/gradients. */\nfunction parseSvgOpacity(value: string | null): number | null {\n if (!value) return null;\n const raw = value.trim();\n if (!raw) return null;\n if (raw.endsWith('%')) {\n const pct = Number.parseFloat(raw.slice(0, -1));\n if (!Number.isFinite(pct)) return null;\n return Math.max(0, Math.min(1, pct / 100));\n }\n const n = Number.parseFloat(raw);\n if (!Number.isFinite(n)) return null;\n return Math.max(0, Math.min(1, n));\n}\n\nfunction formatSvgOpacity(value: number): string {\n const clamped = Math.max(0, Math.min(1, value));\n return Number(clamped.toFixed(4)).toString();\n}\n\nfunction multiplySvgOpacityAttr(\n el: Element,\n attr: 'opacity' | 'fill-opacity' | 'stroke-opacity' | 'stop-opacity',\n factor: number\n): void {\n const existing = parseSvgOpacity(el.getAttribute(attr));\n const next = (existing ?? 1) * factor;\n el.setAttribute(attr, formatSvgOpacity(next));\n}\n\nfunction injectOpacityIntoSvg(svg: Element, opacity: number): void {\n if (opacity >= 0.999) return; // fully opaque, no change needed\n const factor = Math.max(0, Math.min(1, opacity));\n\n // svg2pdf can inconsistently honor element/root \"opacity\" in complex SVGs.\n // Bake alpha directly into paint opacity channels so BOTH solid fills and\n // gradient fills render with consistent transparency.\n const drawable = svg.querySelectorAll('path, rect, circle, ellipse, polygon, polyline, line, text, tspan');\n drawable.forEach((el) => {\n multiplySvgOpacityAttr(el, 'fill-opacity', factor);\n multiplySvgOpacityAttr(el, 'stroke-opacity', factor);\n });\n\n // Gradients need stop-opacity baked as well.\n svg.querySelectorAll('stop').forEach((stop) => {\n multiplySvgOpacityAttr(stop, 'stop-opacity', factor);\n });\n}\n\n/**\n * Flatten `opacity` attributes into paint channels so svg2pdf renders transparency\n * consistently, especially for nested `<g opacity=\"...\">` structures.\n */\nfunction bakeGroupOpacityIntoChildren(svg: Element): void {\n const DRAWABLE_TAGS = new Set(['path', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'line', 'text', 'tspan']);\n\n function walkAndBake(el: Element, inheritedOpacity: number): void {\n if (isInSvgDefinitionSubtree(el)) {\n for (let i = 0; i < el.children.length; i++) {\n walkAndBake(el.children[i], 1);\n }\n return;\n }\n\n const tag = el.tagName?.toLowerCase() ?? '';\n const opacityAttr = parseSvgOpacity(el.getAttribute('opacity'));\n const styleOpacity = parseSvgOpacity((el as SVGElement).style?.getPropertyValue('opacity') || null);\n const ownOpacity = opacityAttr ?? styleOpacity ?? 1;\n const combinedOpacity = inheritedOpacity * ownOpacity;\n\n // Remove explicit opacity once it's baked so svg2pdf does not re-apply it.\n // EXCEPTION: <image> takes raw `opacity` (no fill-opacity equivalent), so\n // we must keep an opacity attribute on it set to the COMBINED value (own\n // × inherited) — otherwise images inside a group with opacity render at\n // full alpha in the PDF.\n if (ownOpacity < 0.999 && tag !== 'image') {\n el.removeAttribute('opacity');\n if ((el as SVGElement).style?.opacity) {\n (el as SVGElement).style.removeProperty('opacity');\n }\n }\n\n if (DRAWABLE_TAGS.has(tag) && combinedOpacity < 0.999) {\n multiplySvgOpacityAttr(el, 'fill-opacity', combinedOpacity);\n multiplySvgOpacityAttr(el, 'stroke-opacity', combinedOpacity);\n }\n\n // <image> has no fill/stroke channels — bake combined opacity onto the\n // element's own `opacity` attribute so svg2pdf renders the alpha.\n if (tag === 'image' && combinedOpacity < 0.999) {\n el.setAttribute('opacity', String(Number(combinedOpacity.toFixed(4))));\n if ((el as SVGElement).style?.opacity) {\n (el as SVGElement).style.removeProperty('opacity');\n }\n }\n\n // Only bake stop-local opacity into stop-opacity.\n // Inherited group opacity is already baked on drawable consumers via fill/stroke opacity.\n if (tag === 'stop' && ownOpacity < 0.999) {\n multiplySvgOpacityAttr(el, 'stop-opacity', ownOpacity);\n }\n\n for (let i = 0; i < el.children.length; i++) {\n walkAndBake(el.children[i], combinedOpacity);\n }\n }\n\n walkAndBake(svg, 1);\n}\n\n/** Match paint servers in fill/stroke like url(#id), url(\"#id\"), or url(\"https://...#id\"). */\nconst URL_GRADIENT_RE = /^\\s*url\\s*\\(\\s*(['\"]?)([^)]+?)\\1\\s*\\)/i;\n\nfunction extractGradientIdFromPaint(value: string | null): string | null {\n if (!value) return null;\n const match = value.trim().match(URL_GRADIENT_RE);\n if (!match) return null;\n const rawRef = (match[2] || '').trim();\n if (!rawRef) return null;\n\n // Support url(#id), url(\"#id\") and url(\"https://host/file.svg#id\")\n const hashIdx = rawRef.lastIndexOf('#');\n if (hashIdx < 0 || hashIdx === rawRef.length - 1) return null;\n\n const id = rawRef.slice(hashIdx + 1).trim();\n if (!id) return null;\n return id.replace(/[\\s\"')].*$/, '');\n}\n\nfunction normalizeGradientPaintRef(value: string): string {\n const id = extractGradientIdFromPaint(value);\n return id ? `url(#${id})` : value;\n}\n\n/** svg2pdf only accepts stop offsets in 0–1; convert percentage to decimal. */\nfunction normalizeSvgGradientStopOffsets(svg: Element): void {\n for (const stop of svg.querySelectorAll('linearGradient stop, radialGradient stop')) {\n const offset = stop.getAttribute('offset');\n if (!offset) continue;\n const trimmed = offset.trim();\n if (trimmed.endsWith('%')) {\n const num = parseFloat(trimmed.slice(0, -1)) / 100;\n if (Number.isFinite(num)) stop.setAttribute('offset', String(Math.max(0, Math.min(1, num))));\n }\n }\n}\n\nfunction decodeSvgDataUri(href: string): string | null {\n if (!href.startsWith('data:image/svg+xml')) return null;\n\n const commaIdx = href.indexOf(',');\n if (commaIdx < 0) return null;\n\n const meta = href.slice(0, commaIdx).toLowerCase();\n const payload = href.slice(commaIdx + 1);\n\n try {\n if (meta.includes(';base64')) {\n const binary = atob(payload);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return new TextDecoder('utf-8').decode(bytes);\n }\n return decodeURIComponent(payload);\n } catch {\n try {\n return atob(payload);\n } catch {\n return null;\n }\n }\n}\n\nfunction inlineNestedSvgImageDataUris(svgString: string, domParser = new DOMParser()): string {\n try {\n const doc = domParser.parseFromString(svgString, 'image/svg+xml');\n if (doc.querySelector('parsererror')) return svgString;\n\n const root = doc.documentElement;\n if (!root || root.tagName.toLowerCase() !== 'svg') return svgString;\n\n let changed = false;\n const images = Array.from(doc.querySelectorAll('image'));\n\n for (const img of images) {\n const href = img.getAttribute('href') || img.getAttributeNS('http://www.w3.org/1999/xlink', 'href');\n if (!href || !href.startsWith('data:image/svg+xml')) continue;\n\n try {\n const svgContent = decodeSvgDataUri(href);\n if (!svgContent || !/<svg[\\s>]/i.test(svgContent)) continue;\n\n const innerDoc = domParser.parseFromString(svgContent, 'image/svg+xml');\n if (innerDoc.querySelector('parsererror')) continue;\n const innerSvg = innerDoc.documentElement;\n if (!innerSvg || innerSvg.tagName.toLowerCase() !== 'svg') continue;\n\n const ix = parseFloat(img.getAttribute('x') || '0') || 0;\n const iy = parseFloat(img.getAttribute('y') || '0') || 0;\n const iw = parseFloat(img.getAttribute('width') || '0');\n const ih = parseFloat(img.getAttribute('height') || '0');\n if (!(iw > 0 && ih > 0)) continue;\n\n const nestedSvg = doc.importNode(innerSvg, true) as unknown as SVGElement;\n const vb = nestedSvg.getAttribute('viewBox');\n if (!vb) {\n nestedSvg.setAttribute('viewBox', `0 0 ${iw} ${ih}`);\n }\n nestedSvg.setAttribute('x', '0');\n nestedSvg.setAttribute('y', '0');\n nestedSvg.setAttribute('width', String(iw));\n nestedSvg.setAttribute('height', String(ih));\n nestedSvg.setAttribute(\n 'preserveAspectRatio',\n img.getAttribute('preserveAspectRatio') || nestedSvg.getAttribute('preserveAspectRatio') || 'xMidYMid meet'\n );\n\n const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g');\n const existingTransform = img.getAttribute('transform') || '';\n let transform = existingTransform;\n transform += `${transform ? ' ' : ''}translate(${ix},${iy})`;\n if (transform) {\n g.setAttribute('transform', transform);\n }\n\n const passthroughAttrs = new Set([\n 'id',\n 'class',\n 'style',\n 'opacity',\n 'display',\n 'visibility',\n 'clip-path',\n 'mask',\n 'filter',\n 'pointer-events',\n ]);\n Array.from(img.attributes).forEach((attr) => {\n if (passthroughAttrs.has(attr.name)) {\n g.setAttribute(attr.name, attr.value);\n }\n });\n\n g.appendChild(nestedSvg);\n\n img.parentNode?.replaceChild(g, img);\n changed = true;\n } catch {\n // Ignore nested SVGs we can't safely inline.\n }\n }\n\n return changed ? new XMLSerializer().serializeToString(doc.documentElement) : svgString;\n } catch {\n return svgString;\n }\n}\n\nfunction hasInvalidSvgNumericToken(value: string | null | undefined): value is string {\n return typeof value === 'string' && /\\b(?:NaN|-?Infinity|undefined|null)\\b/.test(value);\n}\n\nfunction sanitizeSvgNumericTokens(value: string): string {\n return value\n .replace(/\\bNaN\\b/g, '0')\n .replace(/\\b-?Infinity\\b/g, '0')\n .replace(/\\bundefined\\b/g, '0')\n .replace(/\\bnull\\b/g, '0');\n}\n\nfunction sanitizeSvgTreeForPdf(svg: Element): void {\n const attrsToSanitize = [\n 'd',\n 'points',\n 'transform',\n 'gradientTransform',\n 'patternTransform',\n 'viewBox',\n 'x',\n 'y',\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'cx',\n 'cy',\n 'r',\n 'rx',\n 'ry',\n 'width',\n 'height',\n 'dx',\n 'dy',\n 'opacity',\n 'fill-opacity',\n 'stroke-opacity',\n 'stroke-width',\n 'stroke-dashoffset',\n 'font-size',\n 'letter-spacing',\n 'word-spacing',\n ];\n\n const nodes = [svg, ...Array.from(svg.querySelectorAll('*'))];\n for (const node of nodes) {\n for (const attr of attrsToSanitize) {\n const value = node.getAttribute(attr);\n if (!hasInvalidSvgNumericToken(value)) continue;\n node.setAttribute(attr, sanitizeSvgNumericTokens(value));\n }\n }\n}\n\nfunction stripRootPageBackgroundFromSvg(svg: Element): void {\n const rootChildren = Array.from(svg.children);\n for (const child of rootChildren) {\n const tag = child.tagName.toLowerCase();\n if (tag !== 'rect' && tag !== 'path') continue;\n\n const x = Number.parseFloat(child.getAttribute('x') || '0');\n const y = Number.parseFloat(child.getAttribute('y') || '0');\n const width = Number.parseFloat(child.getAttribute('width') || '0');\n const height = Number.parseFloat(child.getAttribute('height') || '0');\n const fill = child.getAttribute('fill') || getInlineStyleValue(child, 'fill');\n const stroke = child.getAttribute('stroke') || getInlineStyleValue(child, 'stroke');\n const opacity = parseSvgOpacity(child.getAttribute('opacity')) ?? 1;\n\n const isFullPageRect =\n tag === 'rect' &&\n Math.abs(x) < 0.01 &&\n Math.abs(y) < 0.01 &&\n Math.abs(width - Number.parseFloat(svg.getAttribute('width') || '0')) < 0.5 &&\n Math.abs(height - Number.parseFloat(svg.getAttribute('height') || '0')) < 0.5;\n\n const isVisiblePaint = opacity > 0.0001 && !isTransparentColorToken(fill) && (!stroke || isTransparentColorToken(stroke));\n if (isFullPageRect && isVisiblePaint) {\n child.remove();\n return;\n }\n }\n}\n\nfunction stripSuspiciousFullPageOverlayNodes(svg: Element): void {\n const rootWidth = Number.parseFloat(svg.getAttribute('width') || '0');\n const rootHeight = Number.parseFloat(svg.getAttribute('height') || '0');\n const viewBox = (svg.getAttribute('viewBox') || '').trim().split(/[\\s,]+/).map((n) => Number.parseFloat(n));\n const pageWidth = Number.isFinite(rootWidth) && rootWidth > 0 ? rootWidth : (viewBox[2] || 0);\n const pageHeight = Number.isFinite(rootHeight) && rootHeight > 0 ? rootHeight : (viewBox[3] || 0);\n if (!(pageWidth > 0 && pageHeight > 0)) return;\n\n const isNear = (a: number, b: number, tolerance = 0.75) => Math.abs(a - b) <= tolerance;\n const hasVisibleStyleToken = (value: string | null, token: string) => {\n if (!value) return false;\n return new RegExp(`(?:^|;)\\\\s*${token}\\\\s*:\\\\s*([^;]+)`, 'i').test(value);\n };\n const hasHiddenDisplay = (el: Element) => {\n const display = (el.getAttribute('display') || getInlineStyleValue(el, 'display') || '').trim().toLowerCase();\n const visibility = (el.getAttribute('visibility') || getInlineStyleValue(el, 'visibility') || '').trim().toLowerCase();\n return display === 'none' || visibility === 'hidden';\n };\n const getNodeOpacity = (el: Element) => {\n return (\n parseSvgOpacity(el.getAttribute('opacity')) ??\n parseSvgOpacity(getInlineStyleValue(el, 'opacity')) ??\n 1\n );\n };\n const isDarkPaint = (value: string | null) => {\n const rgb = value ? parseColor(value) : null;\n if (!rgb) return false;\n return rgb.r <= 32 && rgb.g <= 32 && rgb.b <= 32;\n };\n const removeIfSuspicious = (el: Element) => {\n if (hasHiddenDisplay(el)) return;\n const opacity = getNodeOpacity(el);\n if (opacity <= 0.001) return;\n const fill = el.getAttribute('fill') || getInlineStyleValue(el, 'fill');\n const stroke = el.getAttribute('stroke') || getInlineStyleValue(el, 'stroke');\n if (!isDarkPaint(fill) && !isDarkPaint(stroke)) return;\n\n const width = Number.parseFloat(el.getAttribute('width') || '0');\n const height = Number.parseFloat(el.getAttribute('height') || '0');\n const x = Number.parseFloat(el.getAttribute('x') || '0');\n const y = Number.parseFloat(el.getAttribute('y') || '0');\n const isRectLike = el.tagName.toLowerCase() === 'rect' && isNear(x, 0) && isNear(y, 0) && isNear(width, pageWidth, 1.5) && isNear(height, pageHeight, 1.5);\n\n let isPathLike = false;\n if (el.tagName.toLowerCase() === 'path') {\n const d = (el.getAttribute('d') || '').replace(/\\s+/g, ' ').trim();\n isPathLike = !!d && (\n new RegExp(`^M\\s*0(?:\\.0+)?\\s+0(?:\\.0+)?\\s*H\\s*${Math.round(pageWidth)}(?:\\.0+)?\\s*V\\s*${Math.round(pageHeight)}(?:\\.0+)?\\s*H\\s*0(?:\\.0+)?\\s*Z?$`, 'i').test(d) ||\n new RegExp(`^M\\s*0(?:\\.0+)?\\s+0(?:\\.0+)?\\s*L\\s*${Math.round(pageWidth)}(?:\\.0+)?\\s+0(?:\\.0+)?\\s*L\\s*${Math.round(pageWidth)}(?:\\.0+)?\\s+${Math.round(pageHeight)}(?:\\.0+)?\\s*L\\s*0(?:\\.0+)?\\s+${Math.round(pageHeight)}(?:\\.0+)?\\s*Z?$`, 'i').test(d)\n );\n }\n\n const inlineStyle = el.getAttribute('style') || '';\n const likelyOverlay = isRectLike || isPathLike || hasVisibleStyleToken(inlineStyle, 'mix-blend-mode');\n if (likelyOverlay) {\n el.remove();\n }\n };\n\n // Check direct children AND children of top-level <g> wrappers (Fabric.js wraps elements in groups)\n const candidates: Element[] = [];\n for (const child of Array.from(svg.children)) {\n const tag = child.tagName.toLowerCase();\n if (tag === 'defs' || tag === 'style' || tag === 'title' || tag === 'desc' || tag === 'metadata') continue;\n if (tag === 'g') {\n // Also scan inside top-level groups for suspicious overlay rects\n for (const grandchild of Array.from(child.children)) {\n candidates.push(grandchild);\n }\n }\n candidates.push(child);\n }\n for (const el of candidates) {\n removeIfSuspicious(el);\n }\n}\n\n// ─── Text Decoration → Explicit Lines ───\n// svg2pdf.js does NOT support text-decoration on <tspan>/<text> elements.\n// Fabric.js toSVG() outputs text-decoration=\"underline\" on tspans.\n// This converts those decorations into explicit <line> elements.\n\nasync function convertTextDecorationsToLines(svg: Element): Promise<void> {\n // (function continues below)\n return _convertTextDecorationsToLines_impl(svg);\n}\n\n// ─── v0.5.131 PARITY FIX (text-anchor → start, baked from canvas measurement) ─\n// Root cause of the centered-text horizontal drift between the on-screen\n// canvas preview and the client-side vector PDF:\n//\n// Fabric writes <text x=\"cx\" text-anchor=\"middle\">. Fabric chose `cx`\n// from the BROWSER's canvas `measureText` width when it drew the preview.\n// Inside the PDF pipeline:\n// • svg2pdf re-resolves the leftmost glyph x as `cx - jsPDF.getTextWidth(...)/2`.\n// • opentype-based outlining (`svgTextToPath.ts`) does the same with\n// `cx - opentypeAdvance/2`.\n// Both width sources differ slightly from the browser's `measureText`\n// (especially for decorative fonts like GreatVibes / Cinzel / Pacifico),\n// so centered text lands a few px off horizontally — and any shadow,\n// background fill, or padding effect inherits the same drift.\n//\n// Fix: BEFORE we hand the SVG to svg2pdf or the outliner, mount a clone in\n// the live DOM (with the real web-fonts loaded), read the actual rendered\n// `getStartPositionOfChar(0).x` for every <text>/<tspan> with\n// text-anchor in {middle,end}, write that x back as the element's `x`\n// attribute, and switch the anchor to `start`. After this, no downstream\n// width math matters — the leftmost glyph is anchored at the exact\n// position the canvas preview placed it.\nexport async function bakeTextAnchorPositionsFromLiveSvg(svg: Element): Promise<void> {\n if (typeof document === 'undefined' || typeof window === 'undefined') return;\n if (!svg) return;\n\n const _resolveAnchor = (el: Element): string => {\n let cur: Element | null = el;\n while (cur) {\n const a = cur.getAttribute('text-anchor');\n if (a) return a.trim().toLowerCase();\n const style = cur.getAttribute('style') || '';\n const m = style.match(/(?:^|;)\\s*text-anchor\\s*:\\s*([^;]+)/i);\n if (m) return m[1].trim().toLowerCase();\n cur = cur.parentElement;\n }\n return 'start';\n };\n\n // Cheap pre-check: if there's no centered/end anchor anywhere, skip the\n // whole DOM-mount round-trip.\n const allTextish = Array.from(svg.querySelectorAll('text, tspan'));\n let needsBake = false;\n for (const el of allTextish) {\n const a = _resolveAnchor(el);\n if (a === 'middle' || a === 'end') { needsBake = true; break; }\n }\n if (!needsBake) return;\n\n // Make sure web-fonts referenced by the SVG are actually loaded so\n // measureText / getStartPositionOfChar use the same metrics the canvas\n // preview used. Same approach as `convertTextDecorationsToLines`.\n //\n // CENTER-PARITY FIX (v0.5.142): `document.fonts.ready` only resolves the\n // CURRENTLY-loading set. A FontFace registered via `new FontFace(...)` +\n // `document.fonts.add(...)` stays in `unloaded` state until something\n // actually requests it. On the server (puppeteer) Fabric's canvas measure\n // pulled in some weights but not the exact `font-weight` written into the\n // SVG (e.g. weight=600 when only 400 was registered as a non-aliased face).\n // The cloned SVG then renders that tspan with a SYSTEM fallback, so\n // `getStartPositionOfChar(0).x` returns a different start than the client\n // (which has those weights pre-loaded via the site-level Google Fonts\n // <link>). Explicitly call `document.fonts.load(...)` for every\n // family/weight/style triple referenced by the SVG before measuring so\n // BOTH environments see identical glyph metrics.\n try {\n if ((document as any).fonts) {\n const loadKeys = new Set<string>();\n for (const tn of svg.querySelectorAll('text, tspan, textPath')) {\n const ff =\n tn.getAttribute('data-source-font-family') ||\n tn.getAttribute('font-family');\n if (!ff) continue;\n const fw =\n tn.getAttribute('data-source-font-weight') ||\n tn.getAttribute('font-weight') ||\n '400';\n const fs =\n tn.getAttribute('data-source-font-style') ||\n tn.getAttribute('font-style') ||\n 'normal';\n const cleanFamily = ff.replace(/['\"]/g, '').trim();\n if (!cleanFamily) continue;\n loadKeys.add(`${fs} ${fw} 16px \"${cleanFamily}\"`);\n }\n const loads: Promise<unknown>[] = [];\n for (const spec of loadKeys) {\n try {\n loads.push((document as any).fonts.load(spec).catch(() => {}));\n } catch { /* noop */ }\n }\n if (loads.length > 0) await Promise.all(loads);\n if ((document as any).fonts?.ready) await (document as any).fonts.ready;\n }\n } catch { /* noop */ }\n\n const tempContainer = document.createElement('div');\n tempContainer.style.cssText =\n 'position:fixed;left:-9999px;top:-9999px;visibility:hidden;pointer-events:none;';\n const clone = svg.cloneNode(true) as Element;\n // Apply the original (data-source-*) font attributes that Fabric stamped on\n // each text node, so the live measurement uses the SAME family/weight/style\n // the on-screen preview used.\n for (const tn of clone.querySelectorAll('text, tspan, textPath')) {\n const sf = tn.getAttribute('data-source-font-family');\n const sw = tn.getAttribute('data-source-font-weight');\n const ss = tn.getAttribute('data-source-font-style');\n if (sf) tn.setAttribute('font-family', sf);\n if (sw) tn.setAttribute('font-weight', sw);\n if (ss) tn.setAttribute('font-style', ss);\n const inlineStyle = tn.getAttribute('style') || '';\n if (sf || sw || ss) {\n const stylePairs = inlineStyle\n .split(';')\n .map((p) => p.trim())\n .filter(Boolean)\n .filter((p) => !/^font-(family|weight|style)\\s*:/i.test(p));\n if (sf) stylePairs.push(`font-family: ${sf}`);\n if (sw) stylePairs.push(`font-weight: ${sw}`);\n if (ss) stylePairs.push(`font-style: ${ss}`);\n if (stylePairs.length > 0) tn.setAttribute('style', stylePairs.join('; '));\n }\n }\n tempContainer.appendChild(clone);\n document.body.appendChild(tempContainer);\n\n let baked = 0;\n // Canvas2D measureText is deterministic and matches Fabric's measurement\n // (which the parity log confirms is byte-identical between client and\n // server). We use it as the primary source of truth for width, falling\n // back to DOM `getStartPositionOfChar` only if the canvas context is\n // unavailable. This eliminates a class of client/server centering drift\n // caused by paint-cycle delays in headless browsers where the live SVG\n // <text> hasn't yet picked up the freshly loaded FontFace even though\n // Canvas2D has — leading to subtly different `getStartPositionOfChar`\n // values vs the client.\n const _measureCanvas = (typeof document !== 'undefined') ? document.createElement('canvas') : null;\n const _mctx = _measureCanvas?.getContext('2d') || null;\n const _resolveFontSize = (node: Element): number => {\n let cur: Element | null = node;\n while (cur) {\n const fs = cur.getAttribute('font-size');\n if (fs) {\n const n = parseFloat(fs);\n if (Number.isFinite(n) && n > 0) return n;\n }\n cur = cur.parentElement;\n }\n return 16;\n };\n const _resolveFontAttr = (node: Element, attr: string, fallback: string): string => {\n let cur: Element | null = node;\n while (cur) {\n const v = cur.getAttribute(`data-source-${attr}`) || cur.getAttribute(attr);\n if (v) return v;\n cur = cur.parentElement;\n }\n return fallback;\n };\n const _measureWidthCanvas = (srcNode: Element, content: string): number | null => {\n if (!_mctx || !content) return null;\n const family = _resolveFontAttr(srcNode, 'font-family', '').replace(/['\"]/g, '').trim();\n const weight = _resolveFontAttr(srcNode, 'font-weight', '400');\n const style = _resolveFontAttr(srcNode, 'font-style', 'normal');\n const size = _resolveFontSize(srcNode);\n if (!family) return null;\n try {\n _mctx.font = `${style} ${weight} ${size}px \"${family}\"`;\n const w = _mctx.measureText(content).width;\n return Number.isFinite(w) && w > 0 ? w : null;\n } catch { return null; }\n };\n try {\n const srcTexts = Array.from(svg.querySelectorAll('text'));\n const liveTexts = Array.from(clone.querySelectorAll('text')) as SVGTextElement[];\n for (let i = 0; i < srcTexts.length; i++) {\n const srcText = srcTexts[i];\n const liveText = liveTexts[i];\n if (!liveText) continue;\n const srcTspans = Array.from(srcText.querySelectorAll('tspan'));\n const liveTspans = Array.from(liveText.querySelectorAll('tspan')) as SVGTSpanElement[];\n\n const stripTextAnchorStyle = (node: Element) => {\n const style = node.getAttribute('style') || '';\n if (!/text-anchor\\s*:/i.test(style)) return;\n const cleaned = style\n .split(';')\n .map((p) => p.trim())\n .filter(Boolean)\n .filter((p) => !/^text-anchor\\s*:/i.test(p))\n .join('; ');\n if (cleaned) node.setAttribute('style', cleaned);\n else node.removeAttribute('style');\n };\n\n const readInheritedX = (node: Element): number => {\n let cur: Element | null = node;\n while (cur) {\n const v = cur.getAttribute('x');\n if (v) {\n const parsed = parseFloat(v.split(/[\\s,]+/)[0]);\n return Number.isFinite(parsed) ? parsed : NaN;\n }\n cur = cur.parentElement;\n }\n return NaN;\n };\n\n const bakeNode = (srcNode: Element, liveNode: any, anchorOverride?: string, refXOverride?: number) => {\n const anchor = (anchorOverride || _resolveAnchor(srcNode)).trim().toLowerCase();\n if (anchor !== 'middle' && anchor !== 'end') return;\n const stampedWidth = parseFloat(srcNode.getAttribute('data-pd-line-width') || '');\n const stampedStart = parseFloat(srcNode.getAttribute('data-pd-line-start') || '');\n if (Number.isFinite(stampedWidth) && stampedWidth > 0 && Number.isFinite(stampedStart)) {\n srcNode.setAttribute('x', String(stampedStart));\n srcNode.setAttribute('text-anchor', 'start');\n srcNode.setAttribute('textLength', String(stampedWidth));\n srcNode.setAttribute('lengthAdjust', 'spacing');\n stripTextAnchorStyle(srcNode);\n baked++;\n return;\n }\n // PRIMARY: compute new x from Canvas2D measureText. Fabric uses\n // Canvas2D for its measurement so this matches exactly what the\n // editor / preview rendered. Source x for middle anchor is the\n // center reference; for end anchor it's the right edge.\n try {\n const content = (srcNode.textContent || '');\n if (content.length > 0) {\n const width = _measureWidthCanvas(srcNode, content);\n // Resolve the reference x from the ORIGINAL source SVG (the value\n // Fabric wrote alongside text-anchor). For multi-line Textbox SVGs,\n // child <tspan>s often inherit x from the parent <text>; never read\n // that parent after mutating it, otherwise every line bakes from the\n // already-shifted first line and drifts left on server exports.\n const refX = Number.isFinite(refXOverride as number) ? (refXOverride as number) : readInheritedX(srcNode);\n if (width !== null && Number.isFinite(refX)) {\n const newX = anchor === 'middle' ? refX - width / 2 : refX - width;\n srcNode.setAttribute('x', String(newX));\n srcNode.setAttribute('text-anchor', 'start');\n stripTextAnchorStyle(srcNode);\n baked++;\n return;\n }\n }\n } catch { /* fall through to DOM measurement */ }\n try {\n const n = typeof liveNode.getNumberOfChars === 'function' ? liveNode.getNumberOfChars() : 0;\n if (!n) return;\n const start = liveNode.getStartPositionOfChar(0);\n if (!Number.isFinite(start?.x)) return;\n // Write the absolute glyph-start x back. Drop any inherited anchor\n // and any inline-style anchor so the new `start` anchor sticks.\n srcNode.setAttribute('x', String(start.x));\n srcNode.setAttribute('text-anchor', 'start');\n stripTextAnchorStyle(srcNode);\n baked++;\n } catch { /* live node not measurable — leave as-is */ }\n };\n\n if (srcTspans.length > 0) {\n const parentAnchor = _resolveAnchor(srcText);\n const tspanAnchors = srcTspans.map((tspan) => _resolveAnchor(tspan));\n const parentRefX = readInheritedX(srcText);\n const tspanRefXs = srcTspans.map((tspan) => readInheritedX(tspan));\n // Multi-line Fabric Textbox SVGs put each visual line in a <tspan>.\n // Bake each line independently from the unmodified parent center x;\n // do NOT bake the parent using concatenated textContent because that\n // corrupts the inherited x used by following tspans.\n for (let j = 0; j < srcTspans.length; j++) {\n const refX = Number.isFinite(tspanRefXs[j]) ? tspanRefXs[j] : parentRefX;\n if (liveTspans[j]) bakeNode(srcTspans[j], liveTspans[j], tspanAnchors[j] || parentAnchor, refX);\n }\n if (parentAnchor === 'middle' || parentAnchor === 'end') {\n srcText.setAttribute('text-anchor', 'start');\n stripTextAnchorStyle(srcText);\n }\n } else {\n bakeNode(srcText, liveText);\n }\n }\n } finally {\n try { document.body.removeChild(tempContainer); } catch { /* noop */ }\n }\n\n if (baked > 0) {\n try {\n console.log(`[Vector PDF][parity] baked text-anchor → start on ${baked} node(s) using live canvas measurement`);\n } catch { /* noop */ }\n }\n}\n\n\n/**\n * DIAGNOSTIC (temp v0.5.145): log per-<text> width measurements from THREE\n * sources so we can pinpoint exactly where client-vs-server PDF disparity\n * comes from on real exports. Output goes through console.log so it shows\n * in both the browser devtools AND puppeteer's `[browser:log]` capture on\n * the EC2 server — making client/server numbers directly comparable.\n *\n * • dom = getStartPositionOfChar(0).x of the live-mounted SVG\n * (what bakeTextAnchorPositionsFromLiveSvg writes back).\n * • measureCtx = canvas2d measureText(textContent).width of the same\n * string at the same font/size — the metric Fabric used\n * when it wrote text-anchor + x in toSVG().\n * • bbox = getBBox().width of the live-mounted node.\n * • srcAnchor / srcX = original anchor + x stamped by Fabric (pre-bake).\n *\n * Removable diagnostic — wrap behind `?pdfdiag=1` URL param so it doesn't\n * spam normal exports.\n */\nexport async function logTextMeasurementDiagnostic(svg: Element): Promise<void> {\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\n try {\n const params = new URLSearchParams(window.location?.search || '');\n if (params.get('pdfdiag') !== '1') return;\n } catch { return; }\n if (!svg) return;\n\n const tempContainer = document.createElement('div');\n tempContainer.style.cssText =\n 'position:fixed;left:-9999px;top:-9999px;visibility:hidden;pointer-events:none;';\n const clone = svg.cloneNode(true) as Element;\n for (const tn of clone.querySelectorAll('text, tspan, textPath')) {\n const sf = tn.getAttribute('data-source-font-family');\n const sw = tn.getAttribute('data-source-font-weight');\n const ss = tn.getAttribute('data-source-font-style');\n if (sf) tn.setAttribute('font-family', sf);\n if (sw) tn.setAttribute('font-weight', sw);\n if (ss) tn.setAttribute('font-style', ss);\n }\n tempContainer.appendChild(clone);\n document.body.appendChild(tempContainer);\n\n const measureCanvas = document.createElement('canvas');\n const mctx = measureCanvas.getContext('2d');\n\n try {\n const liveTexts = Array.from(clone.querySelectorAll('text')) as SVGTextElement[];\n const srcTexts = Array.from(svg.querySelectorAll('text'));\n const rows: any[] = [];\n for (let i = 0; i < liveTexts.length; i++) {\n const live = liveTexts[i];\n const src = srcTexts[i];\n if (!live || !src) continue;\n const liveTspans = Array.from(live.querySelectorAll('tspan')) as SVGTSpanElement[];\n const srcTspans = Array.from(src.querySelectorAll('tspan'));\n const tspans = liveTspans.length ? liveTspans : [live as any];\n const srcs = srcTspans.length ? srcTspans : [src];\n for (let j = 0; j < tspans.length; j++) {\n const ln = tspans[j];\n const sn = srcs[j];\n const text = ln.textContent || '';\n const fam = (ln.getAttribute('font-family') || '').replace(/['\"]/g, '').trim();\n const wt = ln.getAttribute('font-weight') || '400';\n const sty = ln.getAttribute('font-style') || 'normal';\n const sz = parseFloat(ln.getAttribute('font-size') || src.getAttribute('font-size') || '16') || 16;\n let domX: number | null = null;\n let bboxW: number | null = null;\n try {\n if ((ln as any).getNumberOfChars && (ln as any).getNumberOfChars() > 0) {\n domX = (ln as any).getStartPositionOfChar(0).x;\n }\n } catch {}\n try { bboxW = (ln as any).getBBox?.().width ?? null; } catch {}\n let canvasW: number | null = null;\n if (mctx) {\n mctx.font = `${sty} ${wt} ${sz}px \"${fam}\"`;\n try { canvasW = mctx.measureText(text).width; } catch {}\n }\n rows.push({\n line: text.length > 40 ? text.slice(0, 37) + '...' : text,\n font: `${fam} ${wt} ${sty}`,\n size: sz,\n srcAnchor: sn.getAttribute('text-anchor') || sn.parentElement?.getAttribute('text-anchor') || '',\n srcX: sn.getAttribute('x') || sn.parentElement?.getAttribute('x') || '',\n domX: domX !== null ? +domX.toFixed(2) : null,\n bboxW: bboxW !== null ? +bboxW.toFixed(2) : null,\n measureCtxW: canvasW !== null ? +canvasW.toFixed(2) : null,\n });\n }\n }\n if (rows.length > 0) {\n console.log('[PDF-DIAG] ===== text measurement diagnostic =====');\n console.log('[PDF-DIAG] env=', typeof navigator !== 'undefined' ? navigator.userAgent.slice(0, 80) : 'n/a',\n 'dpr=', window.devicePixelRatio,\n 'fontsReady=', !!(document as any).fonts?.ready);\n for (const r of rows) {\n console.log('[PDF-DIAG]', JSON.stringify(r));\n }\n console.log('[PDF-DIAG] ===== end =====');\n }\n } finally {\n try { document.body.removeChild(tempContainer); } catch {}\n }\n}\n\nasync function _convertTextDecorationsToLines_impl(svg: Element): Promise<void> {\n const doc = svg.ownerDocument;\n if (!doc) return;\n\n const resolveInheritedSvgValue = (el: Element, attr: string, styleProp = attr): string | null => {\n let current: Element | null = el;\n while (current) {\n const attrValue = current.getAttribute(attr)?.trim();\n if (attrValue) return attrValue;\n const styleValue = getInlineStyleValue(current, styleProp)?.trim();\n if (styleValue) return styleValue;\n current = current.parentElement;\n }\n return null;\n };\n\n // Ensure all fonts used in the SVG are loaded before measuring text widths.\n // Without this, Canvas 2D measureText and SVG getComputedTextLength both\n // return inaccurate (shorter) values because the browser uses a fallback font.\n if (typeof document !== 'undefined' && document.fonts) {\n // Collect unique font families from text elements\n const fontFamilies = new Set<string>();\n for (const textEl of svg.querySelectorAll('text')) {\n const ff = textEl.getAttribute('data-source-font-family') || textEl.getAttribute('font-family');\n if (ff) fontFamilies.add(ff.replace(/'/g, ''));\n for (const tspan of textEl.querySelectorAll('tspan')) {\n const tff = tspan.getAttribute('data-source-font-family') || tspan.getAttribute('font-family');\n if (tff) fontFamilies.add(tff.replace(/'/g, ''));\n }\n }\n // Load each font (triggers Google Fonts fetch if needed)\n const loadPromises: Promise<void>[] = [];\n for (const ff of fontFamilies) {\n if (!document.fonts.check(`16px \"${ff}\"`)) {\n loadPromises.push(\n document.fonts.load(`16px \"${ff}\"`).then(() => {}).catch(() => {})\n );\n loadPromises.push(\n document.fonts.load(`bold 16px \"${ff}\"`).then(() => {}).catch(() => {})\n );\n }\n }\n if (loadPromises.length > 0) {\n await Promise.all(loadPromises);\n }\n await document.fonts.ready;\n }\n\n // To get accurate text widths we temporarily insert the SVG into the real DOM\n // so that SVG's native getComputedTextLength() works with the loaded Google Fonts.\n let tempContainer: HTMLDivElement | null = null;\n let liveSvg: Element | null = null;\n try {\n if (typeof document !== 'undefined') {\n tempContainer = document.createElement('div');\n tempContainer.style.cssText = 'position:fixed;left:-9999px;top:-9999px;visibility:hidden;pointer-events:none;';\n document.body.appendChild(tempContainer);\n const clone = svg.cloneNode(true) as Element;\n for (const textNode of clone.querySelectorAll('text, tspan, textPath')) {\n const sourceFamily = textNode.getAttribute('data-source-font-family');\n const sourceWeight = textNode.getAttribute('data-source-font-weight');\n const sourceStyle = textNode.getAttribute('data-source-font-style');\n if (sourceFamily) textNode.setAttribute('font-family', sourceFamily);\n if (sourceWeight) textNode.setAttribute('font-weight', sourceWeight);\n if (sourceStyle) textNode.setAttribute('font-style', sourceStyle);\n\n const inlineStyle = textNode.getAttribute('style') || '';\n const stylePairs = inlineStyle\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .filter((part) => !/^font-family\\s*:/i.test(part) && !/^font-weight\\s*:/i.test(part) && !/^font-style\\s*:/i.test(part));\n if (sourceFamily) stylePairs.push(`font-family: ${sourceFamily}`);\n if (sourceWeight) stylePairs.push(`font-weight: ${sourceWeight}`);\n if (sourceStyle) stylePairs.push(`font-style: ${sourceStyle}`);\n if (stylePairs.length > 0) textNode.setAttribute('style', stylePairs.join('; '));\n }\n tempContainer.appendChild(clone);\n liveSvg = clone;\n }\n } catch { /* noop */ }\n\n // Canvas 2D for measurement (matches server/EC2 pipeline)\n let ctx: CanvasRenderingContext2D | null = null;\n try {\n const realDoc = typeof document !== 'undefined' ? document : doc;\n const measureCanvas = realDoc.createElement('canvas') as HTMLCanvasElement;\n ctx = measureCanvas.getContext('2d');\n } catch { /* noop */ }\n\n const textEls = Array.from(svg.querySelectorAll('text'));\n // If we have a live clone, query that in parallel for measurement\n const liveTextEls = liveSvg ? Array.from(liveSvg.querySelectorAll('text')) : null;\n\n for (let ti = 0; ti < textEls.length; ti++) {\n const textEl = textEls[ti];\n const liveTextEl = liveTextEls?.[ti] as SVGTextElement | undefined;\n const tspans = Array.from(textEl.querySelectorAll('tspan'));\n if (tspans.length === 0) continue;\n const liveTspans = liveTextEl ? Array.from(liveTextEl.querySelectorAll('tspan')) as SVGTSpanElement[] : null;\n\n const textDecOnText = (textEl.getAttribute('text-decoration') || '').toLowerCase();\n const textStyleDec = (getInlineStyleValue(textEl, 'text-decoration') || '').toLowerCase();\n const textHasUnderline = textDecOnText.includes('underline') || textStyleDec.includes('underline');\n const textHasLinethrough = textDecOnText.includes('line-through') || textStyleDec.includes('line-through');\n\n for (let si = 0; si < tspans.length; si++) {\n const tspan = tspans[si];\n const liveTspan = liveTspans?.[si];\n const tspanDec = (tspan.getAttribute('text-decoration') || '').toLowerCase();\n const tspanStyleDec = (getInlineStyleValue(tspan, 'text-decoration') || '').toLowerCase();\n const hasUnderline = tspanDec.includes('underline') || tspanStyleDec.includes('underline') || textHasUnderline;\n const hasLinethrough = tspanDec.includes('line-through') || tspanStyleDec.includes('line-through') || textHasLinethrough;\n\n if (!hasUnderline && !hasLinethrough) continue;\n\n const content = tspan.textContent || '';\n if (!content.trim()) continue;\n\n const xAttr = tspan.getAttribute('x') ?? textEl.getAttribute('x') ?? '0';\n const yAttr = tspan.getAttribute('y') ?? textEl.getAttribute('y') ?? '0';\n const x = parseFloat(xAttr) || 0;\n const y = parseFloat(yAttr) || 0;\n\n const fontSize = parseFloat(\n tspan.getAttribute('font-size') || textEl.getAttribute('font-size') || '16'\n );\n const fontFamily =\n tspan.getAttribute('data-source-font-family') ||\n textEl.getAttribute('data-source-font-family') ||\n resolveInheritedSvgValue(tspan, 'font-family') ||\n 'sans-serif';\n const fontWeight =\n tspan.getAttribute('data-source-font-weight') ||\n textEl.getAttribute('data-source-font-weight') ||\n resolveInheritedSvgValue(tspan, 'font-weight') ||\n 'normal';\n const fontStyle =\n tspan.getAttribute('data-source-font-style') ||\n textEl.getAttribute('data-source-font-style') ||\n resolveInheritedSvgValue(tspan, 'font-style') ||\n 'normal';\n // Resolve fill via attribute AND inline style up the inheritance chain.\n // Fabric.js writes the text color as `style=\"fill: rgb(...)\"` on <text>,\n // which is *not* picked up by getAttribute('fill'). Falling back to\n // '#000000' caused underlines to render black regardless of the text\n // color. Walk the chain so the underline matches the glyph color.\n const fill =\n tspan.getAttribute('fill') ||\n getInlineStyleValue(tspan, 'fill') ||\n resolveInheritedSvgValue(tspan, 'fill') ||\n textEl.getAttribute('fill') ||\n getInlineStyleValue(textEl, 'fill') ||\n '#000000';\n const fillOpacity =\n tspan.getAttribute('fill-opacity') ||\n getInlineStyleValue(tspan, 'fill-opacity') ||\n resolveInheritedSvgValue(tspan, 'fill-opacity') ||\n textEl.getAttribute('fill-opacity') ||\n getInlineStyleValue(textEl, 'fill-opacity') ||\n null;\n\n // Canvas-based fallback width — only used if the live SVG is not\n // available (e.g. when running outside a browser DOM).\n let textWidth = content.length * fontSize * 0.6;\n if (ctx) {\n ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily.replace(/'/g, '')}`;\n textWidth = ctx.measureText(content).width;\n }\n\n const textAnchorRaw = (resolveInheritedSvgValue(tspan, 'text-anchor') || 'start').toLowerCase();\n const textAnchor = textAnchorRaw === 'middle' || textAnchorRaw === 'end' ? textAnchorRaw : 'start';\n let lineStartX = x - (textAnchor === 'middle' ? textWidth / 2 : textAnchor === 'end' ? textWidth : 0);\n let lineEndX = lineStartX + textWidth;\n let baselineY = y;\n\n // Source of truth: the live SVG's per-glyph caret positions. This\n // exactly mirrors what Fabric's canvas `_renderTextDecoration` paints\n // from `__charBounds` (sum of glyph advances — NOT including italic\n // overhang or trailing-space padding). Using getBBox() OR `Math.max`\n // against canvas measureText would over-extend the underline past the\n // actual glyph endpoints, especially for italic — the bug the user\n // reported. We deliberately do NOT clamp with bbox/canvas width here.\n if (liveTspan) {\n try {\n const liveCharCount = liveTspan.getNumberOfChars();\n if (liveCharCount > 0) {\n const start = liveTspan.getStartPositionOfChar(0);\n const end = liveTspan.getEndPositionOfChar(liveCharCount - 1);\n if (Number.isFinite(start.x)) lineStartX = start.x;\n if (Number.isFinite(start.y)) baselineY = start.y;\n if (Number.isFinite(end.x)) lineEndX = end.x;\n if (Number.isFinite(end.y) && !Number.isFinite(baselineY)) baselineY = end.y;\n } else {\n const svgWidth = liveTspan.getComputedTextLength();\n if (Number.isFinite(svgWidth) && svgWidth > 0) {\n textWidth = svgWidth;\n lineEndX = lineStartX + textWidth;\n }\n }\n } catch { /* fall back to canvas width */ }\n }\n\n if (!(lineEndX > lineStartX)) {\n lineStartX = x - (textAnchor === 'middle' ? textWidth / 2 : textAnchor === 'end' ? textWidth : 0);\n lineEndX = lineStartX + textWidth;\n }\n\n const thickness = Math.max(0.5, fontSize * 0.066667);\n const strokeColor = fill.startsWith('url(') ? '#000000' : fill;\n const decorations: number[] = [];\n if (hasUnderline) decorations.push(baselineY + fontSize * 0.15);\n if (hasLinethrough) decorations.push(baselineY - fontSize * 0.3);\n for (const decoY of decorations) {\n const line = doc.createElementNS('http://www.w3.org/2000/svg', 'line');\n line.setAttribute('x1', String(lineStartX));\n line.setAttribute('y1', String(decoY));\n line.setAttribute('x2', String(lineEndX));\n line.setAttribute('y2', String(decoY));\n line.setAttribute('stroke', strokeColor);\n line.setAttribute('stroke-width', String(thickness));\n line.setAttribute('stroke-linecap', 'butt');\n line.setAttribute('fill', 'none');\n if (fillOpacity) line.setAttribute('stroke-opacity', fillOpacity);\n if (textEl.parentElement) {\n textEl.parentElement.insertBefore(line, textEl.nextSibling);\n }\n }\n }\n }\n\n // Clean up temporary DOM node\n if (tempContainer) {\n try { document.body.removeChild(tempContainer); } catch { /* noop */ }\n }\n}\n\n// ─── String wrapper for the underline conversion ───\n// Parses an SVG string, runs `convertTextDecorationsToLines` on the live\n// document, and serializes back. Used by callers (e.g. UsePackage) to insert\n// explicit <line> underlines BEFORE text-to-path outlining destroys the\n// `text-decoration` metadata on <text>/<tspan> nodes.\nexport async function convertSvgTextDecorationsToLinesString(svgStr: string): Promise<string> {\n if (typeof DOMParser === 'undefined' || typeof XMLSerializer === 'undefined') {\n return svgStr;\n }\n if (!/text-decoration/i.test(svgStr) && !/underline/i.test(svgStr)) {\n return svgStr;\n }\n try {\n const parser = new DOMParser();\n const docEl = parser.parseFromString(svgStr, 'image/svg+xml');\n const rootSvg = docEl.documentElement;\n if (!rootSvg) return svgStr;\n await convertTextDecorationsToLines(rootSvg as unknown as Element);\n const serializer = new XMLSerializer();\n return serializer.serializeToString(rootSvg);\n } catch {\n return svgStr;\n }\n}\n\n// ─── Text Shadow Raster Markers ───\n// svg2pdf.js does not render SVG filters (`feGaussianBlur`), so blur > 0 text\n// shadows cannot stay as real vector blur in the generated PDF. The editor's\n// `toSVG()` emits `__pdShadowRaster` placeholders for those layers; this step\n// converts only the soft shadow layer into a transparent PNG and keeps the real\n// text/background as vector.\nasync function rasterizeShadowMarkers(svg: SVGElement): Promise<void> {\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\n const markers = Array.from(svg.querySelectorAll('g.__pdShadowRaster')) as SVGGElement[];\n if (markers.length === 0) return;\n\n const SVG_NS = 'http://www.w3.org/2000/svg';\n const XLINK_NS = 'http://www.w3.org/1999/xlink';\n\n try { if ((document as any).fonts?.ready) await (document as any).fonts.ready; } catch { /* noop */ }\n // Inline @font-face URL() refs as base64 data URIs so the offscreen <img>\n // (loaded from a blob:) can render with the correct fonts. Without this\n // step the browser falls back to a default sans-serif inside the blob,\n // producing a shadow that looks smaller / narrower than the real text.\n const fontFaceCss = await collectInlinedFontFaceCss();\n\n for (const marker of markers) {\n try {\n const blur = parseFloat(marker.getAttribute('data-blur') || '0');\n const ox = parseFloat(marker.getAttribute('data-ox') || '0');\n const oy = parseFloat(marker.getAttribute('data-oy') || '0');\n const bx = parseFloat(marker.getAttribute('data-bx') || '0');\n const by = parseFloat(marker.getAttribute('data-by') || '0');\n const bw = parseFloat(marker.getAttribute('data-bw') || '0');\n const bh = parseFloat(marker.getAttribute('data-bh') || '0');\n\n if (!Number.isFinite(bw) || !Number.isFinite(bh) || bw <= 0 || bh <= 0) {\n marker.parentNode?.removeChild(marker);\n continue;\n }\n\n const innerXml = restoreSourceFontsForShadowRaster(\n Array.from(marker.childNodes)\n .map((n) => (n instanceof Element ? new XMLSerializer().serializeToString(n) : ''))\n .join(''),\n );\n\n // ── Race-condition guard: explicitly load every font referenced inside\n // this marker BEFORE rasterizing. Without this, on the user's browser\n // (where `document.fonts.ready` can resolve before custom fonts like\n // Excon/Fontshare are fully loaded) the offscreen <img> paints the\n // shadow silhouette with a fallback font whose wider glyphs merge\n // adjacent lines into solid horizontal bars instead of per-line halos.\n // Puppeteer (server) preloads Google Fonts via the harness, so the\n // bug was only visible in client-side exports. Mirrors the fix in\n // packages/canvas-renderer/src/pdf-export.ts.\n try {\n const fontSpecs = collectFontSpecsFromShadowMarkup(innerXml);\n if (fontSpecs.length > 0 && (document as any).fonts?.load) {\n await Promise.all(\n fontSpecs.map((spec) =>\n (document as any).fonts.load(spec).catch(() => undefined),\n ),\n );\n }\n } catch { /* noop */ }\n\n const scale = 2;\n const pxW = Math.min(4096, Math.max(8, Math.ceil(bw * scale)));\n const pxH = Math.min(4096, Math.max(8, Math.ceil(bh * scale)));\n // Canvas2D `shadowBlur` is roughly 2× SVG `feGaussianBlur stdDeviation`\n // (Canvas spec uses a Gaussian where the blur radius ≈ 2σ). Without\n // this conversion the rasterized PDF shadow spreads ~2× wider than the\n // canvas preview at the same blur value.\n const stdDev = Math.max(0, blur / 2);\n const filterId = `pdShadowBlur_${Math.random().toString(36).slice(2, 9)}`;\n const styleBlock = fontFaceCss ? `<style>${fontFaceCss}</style>` : '';\n // The filter region MUST cover the entire viewBox — otherwise the blurred\n // output is clipped at the source bbox and produces a hard rectangular\n // edge in the rasterized PNG. We anchor the filter region to the viewBox\n // in absolute user-space coordinates so it always matches no matter how\n // small the inner geometry is relative to the padded canvas.\n const miniSvg =\n `<svg xmlns=\"${SVG_NS}\" xmlns:xlink=\"${XLINK_NS}\" width=\"${pxW}\" height=\"${pxH}\" viewBox=\"${bx} ${by} ${bw} ${bh}\">` +\n `${styleBlock}<defs><filter id=\"${filterId}\" filterUnits=\"userSpaceOnUse\" x=\"${bx}\" y=\"${by}\" width=\"${bw}\" height=\"${bh}\" color-interpolation-filters=\"sRGB\">` +\n `<feOffset dx=\"${ox}\" dy=\"${oy}\" result=\"offsetShadow\" />` +\n `<feGaussianBlur in=\"offsetShadow\" stdDeviation=\"${stdDev}\" />` +\n `</filter></defs><g filter=\"url(#${filterId})\">${innerXml}</g></svg>`;\n\n const dataUrl = await rasterSvgToPngDataUrl(miniSvg, pxW, pxH);\n if (!dataUrl) {\n marker.parentNode?.removeChild(marker);\n continue;\n }\n\n const img = svg.ownerDocument!.createElementNS(SVG_NS, 'image') as SVGImageElement;\n img.setAttribute('x', String(bx));\n img.setAttribute('y', String(by));\n img.setAttribute('width', String(bw));\n img.setAttribute('height', String(bh));\n img.setAttribute('opacity', String(SHADOW_RASTER_ALPHA_COMPENSATION));\n img.setAttribute('preserveAspectRatio', 'none');\n img.setAttributeNS(XLINK_NS, 'xlink:href', dataUrl);\n img.setAttribute('href', dataUrl);\n marker.parentNode?.replaceChild(img, marker);\n } catch (error) {\n console.warn('[Vector PDF] text shadow rasterization failed for one marker:', error);\n try { marker.parentNode?.removeChild(marker); } catch { /* noop */ }\n }\n }\n}\n\nfunction restoreSourceFontsForShadowRaster(markup: string): string {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(`<svg xmlns=\"http://www.w3.org/2000/svg\">${markup}</svg>`, 'image/svg+xml');\n if (doc.querySelector('parsererror')) return markup;\n for (const node of Array.from(doc.querySelectorAll('text, tspan, textPath'))) {\n const family = node.getAttribute('data-source-font-family');\n const weight = node.getAttribute('data-source-font-weight');\n const style = node.getAttribute('data-source-font-style');\n if (!family && !weight && !style) continue;\n const stylePairs = (node.getAttribute('style') || '')\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .filter((part) => !/^font-family\\s*:/i.test(part) && !/^font-weight\\s*:/i.test(part) && !/^font-style\\s*:/i.test(part));\n if (family) { node.setAttribute('font-family', family); stylePairs.push(`font-family: ${family}`); }\n if (weight) { node.setAttribute('font-weight', weight); stylePairs.push(`font-weight: ${weight}`); }\n if (style) { node.setAttribute('font-style', style); stylePairs.push(`font-style: ${style}`); }\n if (stylePairs.length > 0) node.setAttribute('style', stylePairs.join('; '));\n }\n const root = doc.documentElement;\n return Array.from(root.childNodes)\n .map((n) => (n instanceof Element ? new XMLSerializer().serializeToString(n) : n.textContent || ''))\n .join('');\n } catch {\n return markup;\n }\n}\n\nfunction rasterSvgToPngDataUrl(svgMarkup: string, pxW: number, pxH: number): Promise<string | null> {\n return new Promise((resolve) => {\n try {\n const blob = new Blob([svgMarkup], { type: 'image/svg+xml;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const img = new Image();\n const cleanup = () => { try { URL.revokeObjectURL(url); } catch { /* noop */ } };\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = pxW;\n canvas.height = pxH;\n const ctx = canvas.getContext('2d');\n if (!ctx) { cleanup(); resolve(null); return; }\n ctx.clearRect(0, 0, pxW, pxH);\n ctx.drawImage(img, 0, 0, pxW, pxH);\n const dataUrl = canvas.toDataURL('image/png');\n cleanup();\n resolve(dataUrl);\n } catch {\n cleanup();\n resolve(null);\n }\n };\n img.onerror = () => { cleanup(); resolve(null); };\n img.src = url;\n } catch {\n resolve(null);\n }\n });\n}\n\nlet cachedShadowFontFaceCss: string | null = null;\nfunction collectDocumentFontFaceCss(): string {\n if (cachedShadowFontFaceCss !== null) return cachedShadowFontFaceCss;\n const out: string[] = [];\n try {\n for (const sheet of Array.from(document.styleSheets)) {\n let rules: CSSRuleList | null = null;\n try { rules = sheet.cssRules; } catch { rules = null; }\n if (!rules) continue;\n for (const rule of Array.from(rules)) {\n const r = rule as CSSRule & { cssText?: string };\n if (r && (r.type === 5 || /@font-face/i.test(r.cssText || '')) && r.cssText) out.push(r.cssText);\n }\n }\n } catch { /* noop */ }\n cachedShadowFontFaceCss = out.join('\\n');\n return cachedShadowFontFaceCss;\n}\n\n// ─── Font inlining for shadow rasterization ────────────────────────────────\n// We need the offscreen blob-SVG to render text with the same fonts the\n// document uses. Browsers won't load fonts via @font-face URL() inside a\n// blob: SVG loaded via <img> reliably (CORS + timing). Inlining the woff2\n// payload as a data: URI works in every browser.\n\nlet cachedInlinedFontFaceCss: string | null = null;\nconst fontUrlDataCache = new Map<string, string | null>();\n\nasync function fetchFontAsDataUri(url: string): Promise<string | null> {\n if (fontUrlDataCache.has(url)) return fontUrlDataCache.get(url) ?? null;\n try {\n const resp = await fetch(url, { mode: 'cors', credentials: 'omit' });\n if (!resp.ok) { fontUrlDataCache.set(url, null); return null; }\n const blob = await resp.blob();\n const dataUri: string = await new Promise((resolve, reject) => {\n const fr = new FileReader();\n fr.onload = () => resolve(String(fr.result));\n fr.onerror = () => reject(fr.error);\n fr.readAsDataURL(blob);\n });\n fontUrlDataCache.set(url, dataUri);\n return dataUri;\n } catch {\n fontUrlDataCache.set(url, null);\n return null;\n }\n}\n\nasync function inlineUrlsInCss(css: string): Promise<string> {\n // Match url(...) inside @font-face blocks. We replace each http(s) URL with\n // a data: URI; relative URLs are resolved against document.baseURI first.\n const urlRe = /url\\((['\"]?)([^'\")]+)\\1\\)/gi;\n const matches: { full: string; url: string }[] = [];\n let m: RegExpExecArray | null;\n while ((m = urlRe.exec(css)) !== null) {\n const raw = m[2].trim();\n if (raw.startsWith('data:')) continue;\n let abs = raw;\n try { abs = new URL(raw, document.baseURI).toString(); } catch { /* keep raw */ }\n matches.push({ full: m[0], url: abs });\n }\n if (matches.length === 0) return css;\n const unique = Array.from(new Set(matches.map((m) => m.url)));\n const results = await Promise.all(unique.map((u) => fetchFontAsDataUri(u)));\n const map = new Map<string, string | null>();\n unique.forEach((u, i) => map.set(u, results[i]));\n let out = css;\n for (const { full, url } of matches) {\n const data = map.get(url);\n if (!data) continue;\n // escape replacement specials\n const safeFull = full.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n out = out.replace(new RegExp(safeFull, 'g'), `url(\"${data}\")`);\n }\n return out;\n}\n\nasync function collectInlinedFontFaceCss(): Promise<string> {\n if (cachedInlinedFontFaceCss !== null) return cachedInlinedFontFaceCss;\n const raw = collectDocumentFontFaceCss();\n if (!raw) { cachedInlinedFontFaceCss = ''; return ''; }\n try {\n cachedInlinedFontFaceCss = await inlineUrlsInCss(raw);\n } catch {\n cachedInlinedFontFaceCss = raw;\n }\n return cachedInlinedFontFaceCss;\n}\n\nasync function prepareLiveCanvasSvgForPdf(\n rawSvg: string,\n pageWidth: number,\n pageHeight: number,\n pageKey: string,\n options?: {\n stripPageBackground?: boolean;\n },\n): Promise<Element | null> {\n try {\n const parser = new DOMParser();\n const processedSvg = inlineNestedSvgImageDataUris(rawSvg, parser);\n const doc = parser.parseFromString(processedSvg, 'image/svg+xml');\n if (doc.querySelector('parsererror')) return null;\n\n const svg = doc.documentElement;\n if (!svg || svg.tagName.toLowerCase() !== 'svg') return null;\n\n svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n if (/xlink:href/i.test(processedSvg) && !svg.getAttribute('xmlns:xlink')) {\n svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n }\n svg.setAttribute('width', String(pageWidth));\n svg.setAttribute('height', String(pageHeight));\n svg.setAttribute('viewBox', `0 0 ${pageWidth} ${pageHeight}`);\n\n sanitizeSvgTreeForPdf(svg);\n normalizeSvgViewBoxOrigin(svg);\n disambiguateNestedSvgIds(svg);\n expandSvgUseElements(svg, pageKey);\n\n let svgToDraw = normalizeSvgExplicitColors(svg);\n // Match EC2/server parity: flatten computed paint so transparent fills become explicit fill=\"none\"\n // instead of being left implicit and defaulting to black inside svg2pdf.\n inlineComputedStyles(svgToDraw);\n sanitizeSvgTreeForPdf(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n prefixSvgIds(svgToDraw, pageKey);\n bakeGroupOpacityIntoChildren(svgToDraw);\n stripSuspiciousFullPageOverlayNodes(svgToDraw);\n if (options?.stripPageBackground) {\n stripRootPageBackgroundFromSvg(svgToDraw);\n }\n sanitizeSvgTreeForPdf(svgToDraw);\n // ─── v0.5.131 PARITY: bake text-anchor → start from live canvas\n // measurement BEFORE any downstream code (shadow-bound outlining,\n // svg2pdf, decoration-to-line) tries to do its own width math.\n // After this pass every <text>/<tspan> uses anchor=start with x = the\n // exact leftmost glyph position the on-screen preview drew.\n try {\n await logTextMeasurementDiagnostic(svgToDraw);\n await bakeTextAnchorPositionsFromLiveSvg(svgToDraw);\n } catch (e) {\n console.warn('[Vector PDF] anchor-bake pass failed (continuing):', e);\n }\n await rasterizeShadowMarkers(svgToDraw as SVGElement);\n await convertTextDecorationsToLines(svgToDraw);\n\n // Live Fabric SVG still carries browser font-family/style attributes. svg2pdf\n // only uses fonts that were registered in jsPDF, so rewrite to the embedded\n // jsPDF font names and synthesize italic when the family has no italic file\n // (e.g. Pacifico Regular + fontStyle italic).\n const rewritten = rewriteSvgFontsForJsPDFWithSourceMeta(new XMLSerializer().serializeToString(svgToDraw));\n const rewrittenDoc = parser.parseFromString(rewritten, 'image/svg+xml');\n if (!rewrittenDoc.querySelector('parsererror') && rewrittenDoc.documentElement?.tagName.toLowerCase() === 'svg') {\n return rewrittenDoc.documentElement;\n }\n\n return svgToDraw;\n } catch {\n return null;\n }\n}\n\nexport async function drawPreparedLiveCanvasSvgPageToPdf(options: {\n rawSvg: string;\n pdf: jsPDF;\n pageWidth: number;\n pageHeight: number;\n pageKey: string;\n stripPageBackground?: boolean;\n}): Promise<boolean> {\n const { rawSvg, pdf, pageWidth, pageHeight, pageKey, stripPageBackground } = options;\n const svgToDraw = await prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey, {\n stripPageBackground,\n });\n if (!svgToDraw) return false;\n\n const seq = ++debugSvgDrawSequence;\n // Match EC2 pipeline: saveGraphicsState → reset colors → svg2pdf → restoreGraphicsState → reset\n // This prevents color leaking from the SVG into subsequent PDF operations and vice versa\n pdf.setFillColor(0, 0, 0);\n pdf.setDrawColor(0, 0, 0);\n pdf.saveGraphicsState();\n setPdfColorFromSvg(pdf, svgToDraw, pageKey);\n const pdfToUse = pdfWithColorLogging(pdf, seq, pageKey);\n // ─── DIAGNOSTIC (text-parity): dump every <text> element's raw outerHTML\n // and per-tspan x positions right before svg2pdf consumes the SVG. This\n // lets us diff the IDENTICAL SVG snapshot between client-Chrome and\n // server-Puppeteer to confirm whether divergence happens upstream (SVG\n // generation) or downstream (svg2pdf / jsPDF font rendering).\n try {\n const texts = Array.from((svgToDraw as Element).querySelectorAll('text'));\n for (let i = 0; i < texts.length; i++) {\n const t = texts[i];\n const content = (t.textContent || '').replace(/\\s+/g, ' ').trim().slice(0, 60);\n const tspans = Array.from(t.querySelectorAll('tspan')).map((s) => ({\n x: s.getAttribute('x'),\n y: s.getAttribute('y'),\n text: (s.textContent || '').slice(0, 40),\n }));\n const parentG = t.parentElement?.tagName === 'g' ? t.parentElement : null;\n console.log('[svg-parity-dump]', JSON.stringify({\n page: pageKey,\n idx: i,\n snippet: content,\n textAttrs: {\n x: t.getAttribute('x'),\n y: t.getAttribute('y'),\n anchor: t.getAttribute('text-anchor'),\n fontFamily: t.getAttribute('font-family'),\n fontSize: t.getAttribute('font-size'),\n fontWeight: t.getAttribute('font-weight'),\n },\n parentTransform: parentG?.getAttribute('transform') || null,\n tspans,\n }));\n }\n } catch (e) {\n console.warn('[svg-parity-dump] failed:', e);\n }\n await svg2pdfWithDomMount(svgToDraw, pdfToUse, svg2pdfOpts(0, 0, pageWidth, pageHeight));\n pdf.restoreGraphicsState();\n pdf.setFillColor(0, 0, 0);\n pdf.setDrawColor(0, 0, 0);\n return true;\n}\n\nexport function rewriteSvgFontsForJsPDFWithSourceMeta(svgStr: string): string {\n const parser = new DOMParser();\n const doc = parser.parseFromString(svgStr, 'image/svg+xml');\n const allTextEls = Array.from(doc.querySelectorAll('text, tspan, textPath'));\n\n const readStyleToken = (style: string, prop: string): string | null => {\n const match = style.match(new RegExp(`${prop}\\\\s*:\\\\s*([^;]+)`, 'i'));\n return match?.[1]?.trim() || null;\n };\n\n const resolveInheritedValue = (el: Element, attr: string, styleProp = attr): string | null => {\n let current: Element | null = el;\n while (current) {\n const attrVal = current.getAttribute(attr)?.trim();\n if (attrVal) return attrVal;\n const styleVal = readStyleToken(current.getAttribute('style') || '', styleProp);\n if (styleVal) return styleVal;\n current = current.parentElement;\n }\n return null;\n };\n\n const getDepth = (el: Element): number => {\n let depth = 0;\n let current = el.parentElement;\n while (current) { depth++; current = current.parentElement; }\n return depth;\n };\n\n const setRunFontAttrs = (target: Element, fontName: string, baseStyle = target.getAttribute('style') || '') => {\n target.setAttribute('font-family', fontName);\n target.setAttribute('font-weight', 'normal');\n target.setAttribute('font-style', 'normal');\n const stylePairs = baseStyle\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .filter((part) => !/^font-family\\s*:/i.test(part) && !/^font-weight\\s*:/i.test(part) && !/^font-style\\s*:/i.test(part));\n stylePairs.push(`font-family: ${fontName}`);\n stylePairs.push('font-weight: normal');\n stylePairs.push('font-style: normal');\n target.setAttribute('style', stylePairs.join('; '));\n };\n\n const needsSyntheticBold = (requestedWeight: number, actualWeight: number): boolean =>\n requestedWeight >= 600 && actualWeight < 600;\n\n // True when italic was requested but the best registered variant we found is\n // upright. We then apply synthetic italic via skewX on the <text>/<tspan>.\n const needsSyntheticItalic = (requestedItalic: boolean, actualItalic: boolean): boolean =>\n requestedItalic && !actualItalic;\n\n const SYNTHETIC_ITALIC_SKEW_DEG = 12;\n\n const applySyntheticItalicTransform = (el: Element): void => {\n // Skew around the element's anchor (x, y). Mixed rich-text styles usually\n // live on child <tspan>s, not the parent <text>, so read the closest\n // inherited x/y and apply the transform to the exact run that requested\n // italic while keeping the text live/selectable.\n const xRaw = resolveInheritedValue(el, 'x') ?? '0';\n const yRaw = resolveInheritedValue(el, 'y') ?? '0';\n const x = Number.parseFloat(xRaw) || 0;\n const y = Number.parseFloat(yRaw) || 0;\n const existing = el.getAttribute('transform') || '';\n // skewX is applied around (x, y) by translating to origin first.\n const synth = `translate(${x} ${y}) skewX(-${SYNTHETIC_ITALIC_SKEW_DEG}) translate(${-x} ${-y})`;\n el.setAttribute('transform', existing ? `${existing} ${synth}` : synth);\n };\n\n const sourceMeta = new Map<Element, {\n clean: string;\n requestedWeight: number;\n resolvedWeight: number;\n requestedItalic: boolean;\n italic: boolean;\n jsPdfName: string;\n inlineStyle: string;\n }>();\n\n for (const el of allTextEls) {\n const inlineStyle = el.getAttribute('style') || '';\n const rawFf = resolveInheritedValue(el, 'font-family');\n if (!rawFf) continue;\n const clean = rawFf.split(',')[0]?.replace(/['\"]/g, '').trim();\n if (!clean) continue;\n // Rewrite local fonts and runtime-embedded Google/Fontshare fonts. If a\n // remote font could not be embedded, leave its original SVG family intact\n // so svg2pdf can fall back gracefully instead of selecting a non-existent\n // jsPDF font name.\n if (!isFontAvailable(clean) && !isFamilyEmbedded(clean)) continue;\n\n const weightRaw = resolveInheritedValue(el, 'font-weight') || '400';\n const styleRaw = resolveInheritedValue(el, 'font-style') || 'normal';\n const parsedWeight = Number.parseInt(weightRaw, 10);\n const weight = Number.isFinite(parsedWeight)\n ? parsedWeight\n : /bold/i.test(weightRaw)\n ? 700\n : /medium/i.test(weightRaw)\n ? 500\n : /semi/i.test(weightRaw)\n ? 600\n : /light/i.test(weightRaw)\n ? 300\n : 400;\n const resolvedWeight = resolveFontWeight(weight);\n const italic = /italic|oblique/i.test(styleRaw);\n // Pick the closest variant ACTUALLY registered into jsPDF. Without this,\n // the rewriter could emit e.g. \"DMSerifDisplay-Bold\" when only Regular\n // was embedded (because the family has no real Bold and Google's\n // fallback fetch returned 404), causing jsPDF to silently fall back to\n // Helvetica and breaking visual font parity with the canvas preview.\n const best = resolveBestRegisteredVariant(clean, resolvedWeight, italic);\n if (!best) {\n // Family has no embedded variants at all — leave SVG family intact so\n // svg2pdf can degrade gracefully instead of selecting a bogus name.\n continue;\n }\n const jsPdfName = getEmbeddedJsPDFFontName(clean, best.weight, best.italic);\n sourceMeta.set(el, {\n clean,\n requestedWeight: resolvedWeight,\n resolvedWeight: best.weight,\n requestedItalic: italic,\n italic: best.italic,\n jsPdfName,\n inlineStyle,\n });\n }\n\n // Process children before parents. Fabric SVG commonly stores actual text on\n // <tspan> children; rewriting the parent <text> first would make the child\n // inherit the jsPDF-only name (e.g. PlayfairDisplay-Regular), causing us to\n // skip glyph fallback splitting for strings like \"₹18 LPA\".\n const textEls = allTextEls.sort((a, b) => getDepth(b) - getDepth(a));\n\n for (const el of textEls) {\n if (!el.isConnected) continue;\n const meta = sourceMeta.get(el);\n if (!meta) continue;\n const { clean, requestedWeight, resolvedWeight, requestedItalic, italic, jsPdfName, inlineStyle } = meta;\n\n el.setAttribute('data-source-font-family', clean);\n el.setAttribute('data-source-font-weight', String(requestedWeight));\n el.setAttribute('data-source-font-style', requestedItalic ? 'italic' : 'normal');\n if (needsSyntheticBold(requestedWeight, resolvedWeight)) {\n const fill = resolveInheritedValue(el, 'fill') || readStyleToken(inlineStyle, 'fill') || '#000000';\n el.setAttribute('stroke', fill);\n el.setAttribute('stroke-width', String(Math.max(0.35, Math.min(1.2, requestedWeight === 700 ? 0.7 : 0.5))));\n el.setAttribute('stroke-linejoin', 'round');\n }\n // Synthetic italic: when italic was requested but no italic-bearing\n // variant of this family was registered (e.g. a bold-italic span on a\n // family with no italic file), skew the glyphs around the anchor so\n // the PDF visually carries italic shape. Only apply when this element\n // has its OWN font-style:italic — otherwise both the parent <text>\n // and its child <tspan>s would each get a skew, producing a doubled\n // shear after the tspan→<text> promotion post-pass below.\n const hasOwnItalicStyle = /italic|oblique/i.test(\n `${el.getAttribute('font-style') || ''};${readStyleToken(inlineStyle, 'font-style') || ''}`,\n );\n if (needsSyntheticItalic(requestedItalic, italic) && hasOwnItalicStyle) {\n applySyntheticItalicTransform(el);\n }\n\n // ── Per-character font fallback (₹, €, ★, Devanagari, etc.) ──\n // Split direct text node children into <tspan> runs by classifyChar()\n // so non-Latin glyphs use the embedded fallback font (Noto Sans /\n // Noto Sans Devanagari) instead of rendering as missing glyphs.\n const directTextChildren = Array.from(el.childNodes).filter((n) => n.nodeType === 3);\n if (directTextChildren.length === 0) {\n setRunFontAttrs(el, jsPdfName, inlineStyle);\n continue;\n }\n\n const symbolJsPdfName = isFontAvailable(FONT_FALLBACK_SYMBOLS)\n ? getEmbeddedJsPDFFontName(FONT_FALLBACK_SYMBOLS, 400)\n : jsPdfName;\n const devanagariJsPdfName = isFontAvailable(FONT_FALLBACK_DEVANAGARI)\n ? getEmbeddedJsPDFFontName(FONT_FALLBACK_DEVANAGARI, resolvedWeight)\n : jsPdfName;\n const mathJsPdfName = isFontAvailable(FONT_FALLBACK_MATH)\n ? getEmbeddedJsPDFFontName(FONT_FALLBACK_MATH, 400)\n : symbolJsPdfName;\n const mainSupportsChar = (char: string) => doesVariantSupportChar(clean, resolvedWeight, italic, char);\n\n for (const node of directTextChildren) {\n const txt = node.textContent || '';\n if (!txt) continue;\n const runs = splitLineIntoRuns(txt, mainSupportsChar);\n // Skip if entire run is plain Latin — already handled by the parent rewrite above.\n if (runs.length === 1 && runs[0].runType === 'main') continue;\n\n const fragment = doc.createDocumentFragment();\n for (const run of runs) {\n const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');\n let runFont = jsPdfName;\n if (run.runType === 'symbol') runFont = symbolJsPdfName;\n else if (run.runType === 'devanagari') runFont = devanagariJsPdfName;\n else if (run.runType === 'math') runFont = mathJsPdfName;\n tspan.setAttribute('font-family', runFont);\n tspan.setAttribute('font-weight', 'normal');\n tspan.setAttribute('font-style', 'normal');\n tspan.textContent = run.text;\n fragment.appendChild(tspan);\n }\n el.replaceChild(fragment, node);\n }\n\n setRunFontAttrs(el, jsPdfName, inlineStyle);\n }\n\n // ── Synthetic italic post-pass ──\n // applySyntheticItalicTransform may have put a `transform` on <tspan>s.\n // SVG <tspan> does NOT honor `transform`. Promote each transformed\n // <tspan> to a wrapping sibling <text> that DOES honor it, while\n // keeping the text live/selectable.\n const SVG_NS = 'http://www.w3.org/2000/svg';\n const transformedTspans = Array.from(doc.querySelectorAll('tspan[transform]'));\n for (const tspan of transformedTspans) {\n const parentText = tspan.parentElement;\n if (!parentText || parentText.tagName.toLowerCase() !== 'text') continue;\n const transformVal = tspan.getAttribute('transform') || '';\n if (!/skewX/i.test(transformVal)) continue;\n\n const wrapper = doc.createElementNS(SVG_NS, 'text');\n let parentTransform = '';\n for (const attr of Array.from(parentText.attributes)) {\n if (attr.name === 'transform') {\n parentTransform = attr.value;\n continue;\n }\n wrapper.setAttribute(attr.name, attr.value);\n }\n const combined = parentTransform ? `${parentTransform} ${transformVal}` : transformVal;\n wrapper.setAttribute('transform', combined);\n tspan.removeAttribute('transform');\n wrapper.appendChild(tspan);\n parentText.parentNode?.insertBefore(wrapper, parentText.nextSibling);\n }\n\n return new XMLSerializer().serializeToString(doc.documentElement);\n}\n\n/** Find gradient element by id within the given SVG tree (clone), not the document. */\nfunction findGradientInTree(svgRoot: Element, gradientId: string): Element | null {\n for (const el of svgRoot.querySelectorAll('[id]')) {\n if (el.getAttribute('id') === gradientId) return el;\n }\n return null;\n}\n\n/** Return true if hex is white or very light (so shape would be invisible on white). */\nfunction isNearWhite(hex: string): boolean {\n if (!/^#[0-9a-f]{6}$/i.test(hex)) return false;\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n return r >= 250 && g >= 250 && b >= 250;\n}\n\nfunction getInlineStyleValue(el: Element, key: string): string | null {\n const style = el.getAttribute('style') || '';\n if (!style) return null;\n const hit = parseInlineSvgStyleDeclarations(style).find((decl) => decl.key === key);\n return hit?.value ?? null;\n}\n\nfunction isTransparentColorToken(value: string | null): boolean {\n if (!value) return false;\n const s = value.trim().toLowerCase();\n if (!s || s === 'none' || s === 'transparent') return true;\n\n if (/^#[0-9a-f]{8}$/i.test(s)) {\n const alphaHex = s.slice(7, 9);\n return Number.parseInt(alphaHex, 16) === 0;\n }\n\n const rgba = s.match(/^rgba\\s*\\(([^)]+)\\)$/i);\n if (rgba) {\n const parts = rgba[1].split(',').map((part) => part.trim());\n if (parts.length >= 4) {\n const alpha = parseSvgOpacity(parts[3]);\n return alpha != null && alpha <= 0.0001;\n }\n }\n\n return false;\n}\n\nfunction getStopOpacity(stop: Element): number | null {\n const fromAttr = parseSvgOpacity(stop.getAttribute('stop-opacity'));\n if (fromAttr != null) return fromAttr;\n\n const fromStyleObj = parseSvgOpacity((stop as SVGElement).style?.getPropertyValue('stop-opacity') || null);\n if (fromStyleObj != null) return fromStyleObj;\n\n const fromStyleAttr = parseSvgOpacity(getInlineStyleValue(stop, 'stop-opacity'));\n return fromStyleAttr;\n}\n\nfunction getStopColorRaw(stop: Element): string | null {\n return (\n stop.getAttribute('stop-color') ??\n (stop as SVGElement).style?.getPropertyValue('stop-color')?.trim() ??\n getInlineStyleValue(stop, 'stop-color')\n );\n}\n\nfunction isGradientStopFullyTransparent(stop: Element): boolean {\n const stopOpacity = getStopOpacity(stop);\n if (stopOpacity != null && stopOpacity <= 0.0001) return true;\n\n const stopColor = getStopColorRaw(stop);\n return isTransparentColorToken(stopColor);\n}\n\nfunction isGradientFullyTransparent(svgRoot: Element, gradientId: string, visited = new Set<string>()): boolean {\n if (visited.has(gradientId)) return false;\n visited.add(gradientId);\n\n const gradient = findGradientInTree(svgRoot, gradientId);\n if (!gradient) return false;\n\n const tag = gradient.tagName?.toLowerCase();\n if (tag !== 'lineargradient' && tag !== 'radialgradient') return false;\n\n const stops = Array.from(gradient.querySelectorAll('stop'));\n if (stops.length > 0) {\n return stops.every((stop) => isGradientStopFullyTransparent(stop));\n }\n\n const href = (gradient.getAttribute('href') || gradient.getAttribute('xlink:href') || '').trim();\n if (href.startsWith('#')) {\n return isGradientFullyTransparent(svgRoot, href.slice(1), visited);\n }\n\n return false;\n}\n\n/** Get a solid color from a gradient: first stop, or last stop if first is near-white. Follows xlink:href when gradient has no stops. */\nfunction getGradientStopColorAsHex(svgRoot: Element, gradientId: string, visited = new Set<string>()): string | null {\n if (visited.has(gradientId)) return null;\n visited.add(gradientId);\n const gradient = findGradientInTree(svgRoot, gradientId);\n if (!gradient) return null;\n const tag = gradient.tagName?.toLowerCase();\n if (tag !== 'lineargradient' && tag !== 'radialgradient') return null;\n const stops = Array.from(gradient.querySelectorAll('stop'));\n if (stops.length === 0) {\n const href = (gradient.getAttribute('href') || gradient.getAttribute('xlink:href') || '').trim();\n if (href.startsWith('#')) {\n const refId = href.slice(1);\n return getGradientStopColorAsHex(svgRoot, refId, visited);\n }\n return null;\n }\n const getStopColor = (stop: Element): string | null => {\n if (isGradientStopFullyTransparent(stop)) return null;\n const stopColor = getStopColorRaw(stop);\n return stopColor ? cssColorToHex(stopColor) : null;\n };\n const firstHex = getStopColor(stops[0]);\n if (firstHex && !isNearWhite(firstHex)) return firstHex;\n const lastStop = stops[stops.length - 1];\n if (lastStop !== stops[0]) {\n const lastHex = getStopColor(lastStop);\n if (lastHex) return lastHex;\n }\n return firstHex;\n}\n\nconst GRADIENT_ATTRS_LINEAR = ['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform', 'spreadMethod'];\nconst GRADIENT_ATTRS_RADIAL = ['cx', 'cy', 'r', 'fx', 'fy', 'gradientUnits', 'gradientTransform', 'spreadMethod'];\n\n/** Copy gradient geometry from ref to gradient for any attribute the gradient doesn't have (so expanded href gradient renders correctly). */\nfunction copyGradientAttrsFromRef(gradient: Element, ref: Element): void {\n const tag = gradient.tagName?.toLowerCase();\n const attrs = tag === 'radialgradient' ? GRADIENT_ATTRS_RADIAL : GRADIENT_ATTRS_LINEAR;\n for (const name of attrs) {\n if (!gradient.hasAttribute(name) && ref.hasAttribute(name)) {\n gradient.setAttribute(name, ref.getAttribute(name)!);\n }\n }\n}\n\n/** Inline xlink:href gradient refs: if a gradient has no stops but href=\"#id\", copy the referenced gradient's stops and geometry so svg2pdf can render it (including inner shapes). */\nfunction expandSvgGradientHrefs(svg: Element): void {\n const visited = new Set<string>();\n function expand(gradient: Element): void {\n const id = gradient.getAttribute('id');\n if (!id || visited.has(id)) return;\n visited.add(id);\n const stops = gradient.querySelectorAll('stop');\n if (stops.length > 0) return;\n const href = (gradient.getAttribute('href') || gradient.getAttribute('xlink:href') || '').trim();\n if (!href.startsWith('#')) return;\n const refId = href.slice(1);\n const ref = findGradientInTree(svg, refId);\n if (!ref) return;\n expand(ref);\n copyGradientAttrsFromRef(gradient, ref);\n const refStops = ref.querySelectorAll('stop');\n for (const stop of refStops) gradient.appendChild(stop.cloneNode(true));\n gradient.removeAttribute('href');\n gradient.removeAttribute('xlink:href');\n }\n for (const g of svg.querySelectorAll('linearGradient, radialGradient')) {\n expand(g);\n }\n}\n\n/** Convert a CSS color (hex, rgb, rgba, or name) to #rrggbb. */\nfunction cssColorToHex(css: string): string | null {\n const s = css.trim();\n if (/^#[0-9a-f]{3}$/i.test(s)) {\n const r = s[1] + s[1], g = s[2] + s[2], b = s[3] + s[3];\n return '#' + r + g + b;\n }\n if (/^#[0-9a-f]{6}$/i.test(s)) return s;\n if (/^#[0-9a-f]{8}$/i.test(s)) return '#' + s.slice(1, 7);\n const rgb = s.match(/^rgba?\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/i);\n if (rgb) {\n const r = Number(rgb[1]).toString(16).padStart(2, '0');\n const g = Number(rgb[2]).toString(16).padStart(2, '0');\n const b = Number(rgb[3]).toString(16).padStart(2, '0');\n return '#' + r + g + b;\n }\n if (typeof document === 'undefined') return null;\n const div = document.createElement('div');\n div.style.color = s;\n const computed = document.defaultView?.getComputedStyle(div).color;\n if (!computed || !computed.startsWith('rgb')) return null;\n const m = computed.match(/\\d+/g);\n if (!m || m.length < 3) return null;\n const r = Number(m[0]).toString(16).padStart(2, '0');\n const g = Number(m[1]).toString(16).padStart(2, '0');\n const b = Number(m[2]).toString(16).padStart(2, '0');\n return '#' + r + g + b;\n}\n\n/** Return true if this gradient has at least one stop (so svg2pdf can render it). */\nfunction gradientHasStops(svgRoot: Element, gradientId: string): boolean {\n const gradient = findGradientInTree(svgRoot, gradientId);\n if (!gradient) return false;\n return gradient.querySelectorAll('stop').length > 0;\n}\n\n/** Replace fill/stroke url(#id) with solid only when the gradient has no stops. Otherwise leave url() so svg2pdf can render gradients. */\nfunction resolveSvgGradientRefsToSolid(svg: Element, elementId?: string): void {\n const drawable = svg.querySelectorAll('path, rect, circle, ellipse, polygon, polyline, line');\n if (DEBUG_SVG_STRUCTURE && drawable.length > 0) {\n const before = Array.from(drawable).map((el) => ({ tag: el.tagName, fill: el.getAttribute('fill'), stroke: el.getAttribute('stroke') }));\n console.log('[PDF export] gradient resolve BEFORE', elementId ?? '', before);\n }\n const all = svg.querySelectorAll('*');\n let fallbackHex: string | null = null;\n for (const el of all) {\n for (const attr of ['fill', 'stroke'] as const) {\n const val = el.getAttribute(attr);\n if (!val) continue;\n const id = extractGradientIdFromPaint(val);\n if (!id) continue;\n // Keep paint-server refs in canonical local form for svg2pdf compatibility.\n const normalizedRef = `url(#${id})`;\n if (val !== normalizedRef) el.setAttribute(attr, normalizedRef);\n\n // If mapped gradient is fully transparent, force no paint so export can't fall back to black.\n if (isGradientFullyTransparent(svg, id)) {\n el.setAttribute(attr, 'none');\n continue;\n }\n\n if (!FLATTEN_SVG_GRADIENTS_FOR_PDF && gradientHasStops(svg, id)) continue;\n let hex = getGradientStopColorAsHex(svg, id);\n if (!hex && fallbackHex) hex = fallbackHex;\n if (!hex) {\n const firstGradient = svg.querySelector('linearGradient[id], radialGradient[id]');\n if (firstGradient) {\n const firstId = firstGradient.getAttribute('id');\n if (firstId) hex = getGradientStopColorAsHex(svg, firstId);\n }\n if (!hex) hex = '#000000';\n }\n if (hex) {\n el.setAttribute(attr, hex);\n if (!fallbackHex) fallbackHex = hex;\n }\n }\n }\n if (DEBUG_SVG_STRUCTURE && drawable.length > 0) {\n const after = Array.from(drawable).map((el) => ({ tag: el.tagName, fill: el.getAttribute('fill'), stroke: el.getAttribute('stroke') }));\n console.log('[PDF export] gradient resolve AFTER', elementId ?? '', after);\n }\n}\n\n/**\n * Disambiguate IDs across nested <svg> elements on the same page.\n * Two SVG images may share internal IDs (e.g. \"linearGradient-1\") —\n * without per-SVG prefixing the second one references the first's defs.\n */\nfunction disambiguateNestedSvgIds(rootSvg: Element): void {\n const nestedSvgs = Array.from(rootSvg.querySelectorAll('svg'));\n const toProcess = nestedSvgs.filter((s) => s !== rootSvg);\n if (toProcess.length < 2) return;\n\n toProcess.forEach((nested, idx) => {\n prefixSvgIds(nested, `n${idx}`);\n });\n}\n\n/**\n * Prefix all IDs and url(#id) refs in the SVG so this SVG's gradients/defs don't collide with others.\n * Fixes \"gradients with same id in different SVGs rendered in same color\" (yWorks/svg2pdf.js#171).\n * jsPDF reuses form objects by id; different SVGs must use different ids.\n */\nfunction prefixSvgIds(svg: Element, prefix: string): void {\n const safePrefix = String(prefix).replace(/[^a-zA-Z0-9-]/g, '_');\n const idMap = new Map<string, string>();\n\n svg.querySelectorAll('[id]').forEach((el) => {\n const id = el.getAttribute('id');\n if (id) idMap.set(id, `${safePrefix}_${id}`);\n });\n\n if (idMap.size === 0) return;\n\n // Rename actual IDs first\n idMap.forEach((newId, oldId) => {\n svg.querySelectorAll(`[id=\"${oldId}\"]`).forEach((el) => el.setAttribute('id', newId));\n });\n\n const replaceUrlRefs = (value: string): string => {\n // Replace only url(...#id) refs (safe for colors like #aabbcc)\n return value.replace(/url\\(\\s*(['\"]?)([^)]+?)\\1\\s*\\)/gi, (full, quoteRaw, refRaw) => {\n const ref = String(refRaw || '').trim();\n const hashIdx = ref.lastIndexOf('#');\n if (hashIdx < 0 || hashIdx === ref.length - 1) return full;\n const base = ref.slice(0, hashIdx + 1);\n const oldId = ref.slice(hashIdx + 1).trim().replace(/[\\s\"')].*$/, '');\n const mapped = idMap.get(oldId);\n if (!mapped) return full;\n const quote = String(quoteRaw || '');\n return `url(${quote}${base}${mapped}${quote})`;\n });\n };\n\n const replaceHrefRef = (value: string): string => {\n const trimmed = value.trim();\n if (trimmed.startsWith('#')) {\n const oldId = trimmed.slice(1);\n const mapped = idMap.get(oldId);\n return mapped ? `#${mapped}` : value;\n }\n return replaceUrlRefs(value);\n };\n\n const refAttrs = [\n 'fill',\n 'stroke',\n 'clip-path',\n 'mask',\n 'filter',\n 'href',\n 'xlink:href',\n 'marker-start',\n 'marker-mid',\n 'marker-end',\n ];\n\n svg.querySelectorAll('*').forEach((el) => {\n refAttrs.forEach((attr) => {\n const val = el.getAttribute(attr);\n if (!val) return;\n const next = attr === 'href' || attr === 'xlink:href' ? replaceHrefRef(val) : replaceUrlRefs(val);\n if (next !== val) el.setAttribute(attr, next);\n });\n\n const style = el.getAttribute('style');\n if (style) {\n const nextStyle = replaceUrlRefs(style);\n if (nextStyle !== style) el.setAttribute('style', nextStyle);\n }\n });\n\n // Keep <style> blocks consistent too\n svg.querySelectorAll('style').forEach((styleNode) => {\n const text = styleNode.textContent || '';\n const next = replaceUrlRefs(text);\n if (next !== text) styleNode.textContent = next;\n });\n}\n\n/** Expand <use href=\"#id\"> into a clone of the referenced element so svg2pdf draws it (inner \"house\" etc.). */\nfunction expandSvgUseElements(svg: Element, elementId?: string): void {\n const doc = svg.ownerDocument;\n const uses = Array.from(svg.querySelectorAll('use'));\n if (DEBUG_SVG_STRUCTURE && (uses.length > 0 || elementId)) {\n console.log('[PDF export] SVG structure', elementId ?? 'unknown', {\n useCount: uses.length,\n defsIds: Array.from(svg.querySelectorAll('defs [id], symbol[id]')).map((el) => el.getAttribute('id')),\n });\n }\n for (const use of uses) {\n const ref = (use.getAttribute('href') || use.getAttribute('xlink:href') || '').trim();\n if (!ref.startsWith('#')) {\n if (DEBUG_SVG_STRUCTURE) console.log('[PDF export] use skip (no #ref)', ref);\n continue;\n }\n const id = ref.slice(1);\n const target = doc.getElementById(id);\n if (DEBUG_SVG_STRUCTURE) {\n console.log('[PDF export] use', ref, 'targetFound=', !!target, 'targetTag=', target?.tagName, 'targetChildren=', target?.children?.length);\n }\n if (!target) continue;\n const x = parseFloat(use.getAttribute('x') || '0') || 0;\n const y = parseFloat(use.getAttribute('y') || '0') || 0;\n const w = parseFloat(use.getAttribute('width') || '0') || 0;\n const h = parseFloat(use.getAttribute('height') || '0') || 0;\n const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g');\n if (target.tagName?.toLowerCase() === 'symbol') {\n const viewBox = target.getAttribute('viewBox');\n for (let i = 0; i < target.children.length; i++) {\n g.appendChild(target.children[i].cloneNode(true));\n }\n if (viewBox && w && h) {\n const parts = viewBox.split(/\\s+/).map(Number);\n const vbW = parts[2];\n const vbH = parts[3];\n if (vbW && vbH) g.setAttribute('transform', `translate(${x},${y}) scale(${w / vbW},${h / vbH})`);\n else g.setAttribute('transform', `translate(${x},${y})`);\n } else if (x || y) {\n g.setAttribute('transform', `translate(${x},${y})`);\n }\n if (DEBUG_SVG_STRUCTURE) console.log('[PDF export] expanded symbol', id, 'children=', target.children.length);\n } else {\n const clone = target.cloneNode(true) as Element;\n if (x || y) g.setAttribute('transform', `translate(${x},${y})`);\n g.appendChild(clone);\n if (DEBUG_SVG_STRUCTURE) console.log('[PDF export] expanded use', id, 'tag=', target.tagName);\n }\n if (use.parentNode) use.parentNode.replaceChild(g, use);\n }\n if (DEBUG_SVG_STRUCTURE) {\n const topTags = Array.from(svg.children).map((c) => c.tagName + (c.id ? '#' + c.id : ''));\n const count = (sel: string) => svg.querySelectorAll(sel).length;\n console.log('[PDF export] SVG after expand', elementId ?? '', {\n topLevel: topTags,\n path: count('path'),\n rect: count('rect'),\n circle: count('circle'),\n g: count('g'),\n use: count('use'),\n });\n }\n}\n\nfunction normalizeSvgViewBoxOrigin(svg: Element): void {\n const viewBox = svg.getAttribute('viewBox');\n if (!viewBox) return;\n\n const parts = viewBox\n .split(/[\\s,]+/)\n .map((n) => Number.parseFloat(n))\n .filter((n) => Number.isFinite(n));\n\n if (parts.length !== 4) return;\n\n const [vx, vy, vw, vh] = parts;\n if (vw <= 0 || vh <= 0) return;\n if (Math.abs(vx) < 0.001 && Math.abs(vy) < 0.001) return;\n\n const doc = svg.ownerDocument;\n if (!doc) return;\n\n const keepAtRoot = new Set(['defs', 'style', 'title', 'desc', 'metadata']);\n const translatableChildren = Array.from(svg.children).filter(\n (child) => !keepAtRoot.has(child.tagName.toLowerCase())\n );\n if (translatableChildren.length === 0) {\n svg.setAttribute('viewBox', `0 0 ${vw} ${vh}`);\n return;\n }\n\n const wrapper = doc.createElementNS('http://www.w3.org/2000/svg', 'g');\n wrapper.setAttribute('transform', `translate(${-vx} ${-vy})`);\n\n for (const child of translatableChildren) {\n wrapper.appendChild(child);\n }\n\n svg.appendChild(wrapper);\n svg.setAttribute('viewBox', `0 0 ${vw} ${vh}`);\n}\n\n/** Fetch SVG from URL and return as DOM Element for vector embedding (svg2pdf). */\nasync function fetchSvgAsElement(imageUrl: string, colorMap?: Record<string, string>): Promise<Element | null> {\n if (!imageUrl) return null;\n const isSvgUrl = imageUrl.toLowerCase().includes('.svg') || imageUrl.startsWith('data:image/svg+xml');\n if (!isSvgUrl) return null;\n try {\n let text: string;\n if (imageUrl.startsWith('data:image/svg+xml;base64,')) {\n const b64 = imageUrl.slice('data:image/svg+xml;base64,'.length);\n const binary = atob(b64);\n try {\n text = decodeURIComponent(\n Array.from(binary)\n .map((ch) => `%${ch.charCodeAt(0).toString(16).padStart(2, '0')}`)\n .join('')\n );\n } catch {\n text = binary;\n }\n } else if (imageUrl.startsWith('data:image/svg+xml,')) {\n text = decodeURIComponent(imageUrl.slice('data:image/svg+xml,'.length).replace(/\\+/g, ' '));\n } else if (imageUrl.startsWith('data:') || imageUrl.startsWith('blob:')) {\n const res = await fetch(imageUrl);\n if (!res.ok) return null;\n text = await res.text();\n } else {\n const url = getProxiedImageUrl(imageUrl);\n const res = await fetch(url);\n if (!res.ok) return null;\n text = await res.text();\n }\n\n // Normalize legacy namespaced SVG markup so DOMParser/svg2pdf can consume it.\n text = text\n .trim()\n .replace(/^\\uFEFF/, '')\n .replace(/<(\\/?)\\s*svg:svg\\b/gi, '<$1svg')\n .replace(/<(\\/?)\\s*svg:/gi, '<$1')\n .replace(/(\\s)svg:([a-zA-Z_][\\w:.-]*)(\\s*=)/gi, '$1$2$3')\n .replace(/\\s+xmlns:svg\\s*=\\s*\"[^\"]*\"/gi, '')\n .replace(/\\s+xmlns:svg\\s*=\\s*'[^']*'/gi, '');\n\n if (!/\\sxmlns\\s*=\\s*[\"'][^\"']+[\"']/i.test(text)) {\n text = text.replace(/<svg\\b/i, '<svg xmlns=\"http://www.w3.org/2000/svg\"');\n }\n\n // Apply SVG color replacements before parsing into DOM\n if (colorMap && Object.keys(colorMap).length > 0) {\n const { applySvgColorMap } = await import('./svgColorUtils');\n text = applySvgColorMap(text, colorMap);\n }\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(text, 'image/svg+xml');\n if (doc.querySelector('parsererror')) return null;\n\n const svg = doc.documentElement;\n if (!svg || svg.tagName.toUpperCase() !== 'SVG') return null;\n\n if (/xlink:href/i.test(text) && !svg.getAttribute('xmlns:xlink')) {\n svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n }\n\n // Normalize non-zero viewBox origins to avoid svg2pdf transform drift/flip issues.\n normalizeSvgViewBoxOrigin(svg);\n\n return svg;\n } catch {\n return null;\n }\n}\n\n/** Get a recolored SVG as a data URL for raster fallback paths. Returns null if no colorMap or not SVG. */\nasync function getRecoloredSvgDataUrl(imageUrl: string, colorMap?: Record<string, string>): Promise<string | null> {\n if (!colorMap || Object.keys(colorMap).length === 0) return null;\n try {\n const { getNormalizedSvgUrl } = await import('./canvasImageLoader');\n return await getNormalizedSvgUrl(imageUrl, colorMap);\n } catch {\n return null;\n }\n}\n\n/**\n * True Vector PDF Export\n * Draws Fabric.js objects directly to jsPDF using native PDF primitives\n * Result: Small file size, infinite scalability, pixel-perfect match\n * \n * SCHEMA: Uses Fabric.js native properties exclusively:\n * - Position: left, top\n * - Dimensions: width, height, scaleX, scaleY\n * - Transform: angle, skewX, skewY, flipX, flipY\n * - Appearance: fill, stroke, strokeWidth, opacity\n * - Text: text, fontSize, fontFamily, fontWeight, textAlign, lineHeight\n */\n\n/**\n * Normalize element properties to Fabric.js schema\n * Handles both new Fabric.js format and legacy format with fallbacks\n */\nfunction normalizeElement(el: CanvasElement): {\n x: number;\n y: number;\n w: number;\n h: number;\n angle: number;\n skewX: number;\n skewY: number;\n opacity: number;\n fill: string;\n stroke: string;\n strokeWidth: number;\n strokeDashArray: string | undefined;\n // Text properties\n text: string;\n fontSize: number;\n fontFamily: string;\n fontWeight: number;\n fontStyle: 'normal' | 'italic';\n underline: boolean;\n letterSpacing: number;\n textAlign: 'left' | 'center' | 'right';\n lineHeight: number;\n splitByGrapheme: boolean;\n // Shape properties\n shapeType: string;\n borderRadius: number;\n rxTL?: number;\n rxTR?: number;\n rxBR?: number;\n rxBL?: number;\n // Triangle corner radii\n triRTop?: number;\n triRBR?: number;\n triRBL?: number;\n // Image properties\n imageUrl: string | undefined;\n // Origin properties\n originX: string;\n originY: string;\n} {\n // Dimensions: Apply scale to get final size\n const baseW = el.width ?? el.size?.width ?? 100;\n const baseH = el.height ?? el.size?.height ?? 100;\n const scaleX = el.scaleX ?? 1;\n const scaleY = el.scaleY ?? 1;\n const w = baseW * scaleX;\n const h = baseH * scaleY;\n\n // Origin point (Fabric.js default is 'left'/'top')\n const originX = el.originX ?? 'left';\n const originY = el.originY ?? 'top';\n\n // Position: left/top refer to the origin point position\n const rawX = el.left ?? el.position?.x ?? 0;\n const rawY = el.top ?? el.position?.y ?? 0;\n\n // Convert origin-based position to top-left corner position\n let x = rawX;\n let y = rawY;\n\n if (originX === 'center') x = rawX - w / 2;\n else if (originX === 'right') x = rawX - w;\n\n if (originY === 'center') y = rawY - h / 2;\n else if (originY === 'bottom') y = rawY - h;\n\n // Transform\n const angle = el.angle ?? el.rotation ?? 0;\n const skewX = el.skewX ?? 0;\n const skewY = el.skewY ?? 0;\n\n // Appearance (Fabric properties first, then legacy style object)\n const style = el.style || {};\n const opacity = el.opacity ?? style.opacity ?? 1;\n // Resolve fill: if a gradient is configured (`fillGradient` / `strokeGradient`),\n // use the FIRST stop colour as the PDF solid fallback. The host's vector PDF\n // pipeline draws text via `pdf.text()` (selectable text) and primitives via\n // direct jsPDF shape calls — neither path can render a real gradient. Falling\n // back to the first stop matches the gradient's dominant colour rather than\n // silently rendering as black (when the underlying solid `el.fill` is unset\n // or still its pre-gradient default like `#000000`).\n const firstStop = (g: any): string | null => {\n const stops = g?.stops;\n if (!Array.isArray(stops) || stops.length === 0) return null;\n const sorted = [...stops].sort((a: any, b: any) => (Number(a?.offset) || 0) - (Number(b?.offset) || 0));\n const c = sorted[0]?.color;\n return typeof c === 'string' && c ? c : null;\n };\n const fillGradientFirst = firstStop((el as any).fillGradient);\n const strokeGradientFirst = firstStop((el as any).strokeGradient);\n const fill = fillGradientFirst ?? (el.fill || style.fill || '');\n const stroke = strokeGradientFirst ?? (el.stroke || style.stroke || '');\n const strokeWidth = el.strokeWidth ?? style.strokeWidth ?? 0;\n const strokeDashArray = el.strokeDashArray?.join(',') || style.strokeDasharray;\n\n // Text properties\n const text = el.text || el.content || '';\n const fontSize = el.fontSize ?? style.fontSize ?? 16;\n const fontFamily = el.fontFamily || style.fontFamily || 'Open Sans';\n const fontWeightRaw = el.fontWeight ?? style.fontWeight ?? 400;\n const fontWeight = typeof fontWeightRaw === 'number'\n ? fontWeightRaw\n : parseInt(String(fontWeightRaw), 10) || 400;\n const fontStyleRaw = el.fontStyle || style.fontStyle || 'normal';\n const fontStyle: 'normal' | 'italic' = fontStyleRaw === 'italic' ? 'italic' : 'normal';\n const underline = el.underline ?? false;\n const letterSpacing = el.charSpacing ?? el.letterSpacing ?? style.letterSpacing ?? 0;\n const rawTextAlign = el.textAlign || style.textAlign || 'left';\n const textAlign = (rawTextAlign === 'left' || rawTextAlign === 'center' || rawTextAlign === 'right')\n ? rawTextAlign\n : 'left';\n const lineHeight = el.lineHeight ?? style.lineHeight ?? 1.2;\n \n // Word wrapping behavior\n const splitByGrapheme = el.splitByGrapheme ?? (el.wordWrap === 'break-word');\n\n // Shape properties\n const normalizedShapeType = normalizeShapeType(el.shapeType);\n const shapeType = normalizedShapeType === 'unsupported' ? (el.shapeType || 'rounded-rect') : normalizedShapeType;\n const borderRadius = el.rx ?? style.borderRadius ?? 0;\n const rxTL = el.rxTL;\n const rxTR = el.rxTR;\n const rxBR = el.rxBR;\n const rxBL = el.rxBL;\n const triRTop = el.triRTop;\n const triRBR = el.triRBR;\n const triRBL = el.triRBL;\n\n // Image properties\n const imageUrl = el.src || el.imageUrl;\n\n return {\n x,\n y,\n w,\n h,\n angle,\n skewX,\n skewY,\n opacity,\n fill,\n stroke,\n strokeWidth,\n strokeDashArray,\n text,\n fontSize,\n fontFamily,\n fontWeight,\n fontStyle,\n underline,\n letterSpacing,\n textAlign,\n lineHeight,\n splitByGrapheme,\n shapeType,\n borderRadius,\n rxTL,\n rxTR,\n rxBR,\n rxBL,\n triRTop,\n triRBR,\n triRBL,\n imageUrl,\n originX,\n originY,\n };\n}\n\nfunction createTransformReferenceObject(el: CanvasElement): fabric.FabricObject {\n const left = el.left ?? el.position?.x ?? 0;\n const top = el.top ?? el.position?.y ?? 0;\n const width = el.width ?? el.size?.width ?? 100;\n const height = el.height ?? el.size?.height ?? 100;\n\n const common = {\n left,\n top,\n width,\n height,\n scaleX: el.scaleX ?? 1,\n scaleY: el.scaleY ?? 1,\n angle: el.angle ?? el.rotation ?? 0,\n skewX: el.skewX ?? 0,\n skewY: el.skewY ?? 0,\n flipX: el.flipX ?? false,\n flipY: el.flipY ?? false,\n originX: el.originX ?? 'left',\n originY: el.originY ?? 'top',\n } as const;\n\n switch (el.type) {\n case 'text': {\n const textbox = new fabric.Textbox(el.text || el.content || '', {\n ...common,\n // Fabric uses these to compute internal layout\n fontSize: el.fontSize ?? el.style?.fontSize ?? 16,\n fontFamily: el.fontFamily ?? el.style?.fontFamily ?? 'Open Sans',\n lineHeight: el.lineHeight ?? 1.2,\n // Match the canvas splitByGrapheme setting\n splitByGrapheme: el.splitByGrapheme ?? (el.wordWrap === 'break-word'),\n });\n // Initialize dimensions to match canvas behavior\n textbox.initDimensions();\n return textbox;\n }\n\n case 'shape': {\n const shapeType = normalizeShapeType(el.shapeType);\n if (shapeType === 'circle') {\n return new fabric.Ellipse({\n ...common,\n rx: width / 2,\n ry: height / 2,\n });\n }\n\n return new fabric.Rect({\n ...common,\n rx: el.rx ?? el.style?.borderRadius ?? 0,\n ry: el.ry ?? el.style?.borderRadius ?? 0,\n });\n }\n\n case 'line': {\n // Represent line as a simple fabric.Line in local space\n return new fabric.Line([0, 0, width, 0], {\n ...common,\n });\n }\n\n case 'image': {\n // Matrix for image is identical to a rectangle with same box props.\n return new fabric.Rect({\n ...common,\n });\n }\n\n default: {\n return new fabric.Rect({\n ...common,\n });\n }\n }\n}\n// Helper to convert CSS colors to jsPDF-compatible RGB format\nfunction parseColor(color: string | undefined): { r: number; g: number; b: number } | null {\n if (!color) return null;\n\n const raw = color.trim().toLowerCase();\n if (!raw || raw === 'transparent' || raw === 'none') return null;\n\n const clamp = (value: number) => Math.max(0, Math.min(255, Math.round(value)));\n const parseNumeric = (token: string) => {\n const value = parseFloat(token);\n return Number.isFinite(value) ? value : NaN;\n };\n const parseRgbComponent = (token: string) => {\n const value = parseNumeric(token);\n if (!Number.isFinite(value)) return NaN;\n return token.endsWith('%') ? (value / 100) * 255 : value;\n };\n const parseAlpha = (token: string | undefined): number => {\n if (!token) return 1;\n const value = parseNumeric(token);\n if (!Number.isFinite(value)) return 1;\n return token.endsWith('%') ? value / 100 : value;\n };\n\n const toRgbFromHsl = (h: number, s: number, l: number) => {\n const hue = ((h % 360) + 360) % 360;\n const sat = Math.max(0, Math.min(1, s));\n const light = Math.max(0, Math.min(1, l));\n\n if (sat === 0) {\n const gray = clamp(light * 255);\n return { r: gray, g: gray, b: gray };\n }\n\n const q = light < 0.5 ? light * (1 + sat) : light + sat - light * sat;\n const p = 2 * light - q;\n const hueToRgb = (t: number) => {\n let tt = t;\n if (tt < 0) tt += 1;\n if (tt > 1) tt -= 1;\n if (tt < 1 / 6) return p + (q - p) * 6 * tt;\n if (tt < 1 / 2) return q;\n if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6;\n return p;\n };\n\n return {\n r: clamp(hueToRgb(hue / 360 + 1 / 3) * 255),\n g: clamp(hueToRgb(hue / 360) * 255),\n b: clamp(hueToRgb(hue / 360 - 1 / 3) * 255),\n };\n };\n\n // #RGB, #RGBA, #RRGGBB, #RRGGBBAA\n if (raw.startsWith('#')) {\n const hex = raw.slice(1);\n const expanded =\n hex.length === 3 || hex.length === 4\n ? hex.split('').map((char) => char + char).join('')\n : hex;\n\n if (expanded.length !== 6 && expanded.length !== 8) return null;\n\n const intValue = parseInt(expanded.slice(0, 6), 16);\n if (!Number.isFinite(intValue)) return null;\n\n if (expanded.length === 8) {\n const alphaHex = parseInt(expanded.slice(6, 8), 16);\n if (Number.isFinite(alphaHex) && alphaHex <= 0) return null;\n }\n\n return {\n r: (intValue >> 16) & 255,\n g: (intValue >> 8) & 255,\n b: intValue & 255,\n };\n }\n\n // rgb()/rgba() in comma or space syntax (e.g. rgb(255,0,0), rgb(255 0 0 / 50%))\n const rgbMatch = raw.match(/^rgba?\\((.+)\\)$/);\n if (rgbMatch) {\n const normalized = rgbMatch[1].replace(/\\//g, ' ').replace(/,/g, ' ');\n const parts = normalized.split(/\\s+/).filter(Boolean);\n if (parts.length >= 3) {\n const alpha = parseAlpha(parts[3]);\n if (alpha <= 0) return null;\n\n const r = parseRgbComponent(parts[0]);\n const g = parseRgbComponent(parts[1]);\n const b = parseRgbComponent(parts[2]);\n if (Number.isFinite(r) && Number.isFinite(g) && Number.isFinite(b)) {\n return { r: clamp(r), g: clamp(g), b: clamp(b) };\n }\n }\n }\n\n // hsl()/hsla() in comma or space syntax\n const hslMatch = raw.match(/^hsla?\\((.+)\\)$/);\n if (hslMatch) {\n const normalized = hslMatch[1].replace(/\\//g, ' ').replace(/,/g, ' ');\n const parts = normalized.split(/\\s+/).filter(Boolean);\n if (parts.length >= 3) {\n const alpha = parseAlpha(parts[3]);\n if (alpha <= 0) return null;\n\n const h = parseNumeric(parts[0].replace(/deg$/, ''));\n const sRaw = parseNumeric(parts[1].replace(/%$/, ''));\n const lRaw = parseNumeric(parts[2].replace(/%$/, ''));\n if (Number.isFinite(h) && Number.isFinite(sRaw) && Number.isFinite(lRaw)) {\n return toRgbFromHsl(h, sRaw / 100, lRaw / 100);\n }\n }\n }\n\n return null;\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((x) => Math.max(0, Math.min(255, Math.round(x))).toString(16).padStart(2, '0')).join('');\n}\n\n/** Mount SVG in document, read computed fill/stroke for every drawable element, set as attributes, unmount. Ensures each path has its actual rendered color so svg2pdf draws orange as orange (not e.g. first-found blue). */\nfunction inlineComputedStyles(svg: Element): void {\n if (typeof document === 'undefined') return;\n const wrap = document.createElement('div');\n wrap.style.cssText = 'position:fixed;left:-9999px;top:0;width:400px;height:400px;overflow:hidden;pointer-events:none';\n const root = svg as SVGElement;\n if (!root.hasAttribute('width')) root.setAttribute('width', '400');\n if (!root.hasAttribute('height')) root.setAttribute('height', '400');\n wrap.appendChild(root);\n document.body.appendChild(wrap);\n try {\n const drawable = ['path', 'rect', 'circle', 'ellipse', 'polygon', 'polyline', 'line', 'text', 'tspan'];\n function walk(el: Element) {\n const tag = el.tagName?.toLowerCase();\n if (drawable.includes(tag)) {\n const cs = window.getComputedStyle(el as SVGElement);\n const fill = cs.fill;\n const stroke = cs.stroke;\n if (fill && fill !== 'none' && fill !== 'rgba(0, 0, 0, 0)') {\n const parsed = parseColor(fill);\n if (parsed) el.setAttribute('fill', rgbToHex(parsed.r, parsed.g, parsed.b));\n } else if (fill === 'rgba(0, 0, 0, 0)' || fill === 'transparent') {\n // Prevent implicit black fill: svg2pdf defaults to black when no fill is set,\n // so we must explicitly mark transparent fills as 'none'\n el.setAttribute('fill', 'none');\n }\n if (stroke && stroke !== 'none' && stroke !== 'rgba(0, 0, 0, 0)') {\n const parsed = parseColor(stroke);\n if (parsed) el.setAttribute('stroke', rgbToHex(parsed.r, parsed.g, parsed.b));\n }\n }\n for (let i = 0; i < el.children.length; i++) walk(el.children[i]);\n }\n walk(root);\n root.remove();\n } finally {\n if (wrap.parentNode) document.body.removeChild(wrap);\n }\n}\n\ntype PaintStyle = 'FD' | 'F' | 'S';\n\ntype PdfPathOp = {\n op: 'm' | 'l' | 'c' | 'h';\n c: number[];\n};\n\nfunction applyPaintStyle(pdf: jsPDF, style: PaintStyle): void {\n if (style === 'FD') {\n pdf.fillStroke();\n return;\n }\n if (style === 'F') {\n pdf.fill();\n return;\n }\n pdf.stroke();\n}\n\n/**\n * jsPDF path() behaves differently between compat/advanced APIs.\n * Draw with path+explicit paint first, then fallback to path(style).\n */\nfunction drawPathWithStyle(pdf: jsPDF, pathOps: PdfPathOp[], style: PaintStyle): boolean {\n const anyPdf = pdf as any;\n if (typeof anyPdf.path !== 'function') return false;\n\n try {\n anyPdf.path(pathOps);\n applyPaintStyle(pdf, style);\n return true;\n } catch {\n // fallback below\n }\n\n try {\n anyPdf.path(pathOps, style);\n return true;\n } catch {\n return false;\n }\n}\n\n// Draw a rectangle (with optional rounded corners, including individual per-corner radii)\nfunction drawRect(\n pdf: jsPDF,\n x: number, y: number, w: number, h: number,\n fill: string | undefined,\n stroke: string | undefined,\n strokeWidth: number,\n borderRadius?: number,\n rxTL?: number, rxTR?: number, rxBR?: number, rxBL?: number\n): void {\n const fillColor = parseColor(fill);\n const strokeColor = parseColor(stroke);\n\n if (fillColor) {\n pdf.setFillColor(fillColor.r, fillColor.g, fillColor.b);\n }\n if (strokeColor && strokeWidth > 0) {\n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n // Use round joins only for uniformly rounded corners; miter for sharp or mixed corners\n // For individual corners (path-based), always use miter — the Bezier curves handle rounding\n const hasIndividualVals = (rxTL != null && rxTL > 0) || (rxTR != null && rxTR > 0) || (rxBR != null && rxBR > 0) || (rxBL != null && rxBL > 0);\n const hasUniformRounding = !hasIndividualVals && borderRadius != null && borderRadius > 0;\n // For paths with mixed radii, miter is correct — curves handle the rounding, lineJoin only affects straight-line junctions\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin(hasUniformRounding ? 'round' : 'miter');\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap(hasUniformRounding ? 'round' : 'butt');\n }\n\n const style: PaintStyle | undefined = fillColor && strokeColor && strokeWidth > 0\n ? 'FD'\n : fillColor\n ? 'F'\n : strokeColor && strokeWidth > 0\n ? 'S'\n : undefined;\n\n if (!style) return;\n\n const hasIndividualCorners = (rxTL != null && rxTL > 0) || (rxTR != null && rxTR > 0) || (rxBR != null && rxBR > 0) || (rxBL != null && rxBL > 0);\n\n if (hasIndividualCorners) {\n const { tl, tr, br, bl } = getRoundedRectRadii(w, h, {\n rx: borderRadius ?? 0,\n rxTL,\n rxTR,\n rxBR,\n rxBL,\n });\n\n const k = 0.5522847498307936;\n const pathOps: PdfPathOp[] = [\n { op: 'm', c: [x + tl, y] },\n { op: 'l', c: [x + w - tr, y] },\n ...(tr > 0\n ? [{ op: 'c' as const, c: [x + w - tr + tr * k, y, x + w, y + tr - tr * k, x + w, y + tr] }]\n : [{ op: 'l' as const, c: [x + w, y] }]),\n { op: 'l', c: [x + w, y + h - br] },\n ...(br > 0\n ? [{ op: 'c' as const, c: [x + w, y + h - br + br * k, x + w - br + br * k, y + h, x + w - br, y + h] }]\n : [{ op: 'l' as const, c: [x + w, y + h] }]),\n { op: 'l', c: [x + bl, y + h] },\n ...(bl > 0\n ? [{ op: 'c' as const, c: [x + bl - bl * k, y + h, x, y + h - bl + bl * k, x, y + h - bl] }]\n : [{ op: 'l' as const, c: [x, y + h] }]),\n { op: 'l', c: [x, y + tl] },\n ...(tl > 0\n ? [{ op: 'c' as const, c: [x, y + tl - tl * k, x + tl - tl * k, y, x + tl, y] }]\n : [{ op: 'l' as const, c: [x, y] }]),\n { op: 'h', c: [] },\n ];\n\n if (drawPathWithStyle(pdf, pathOps, style)) return;\n }\n\n if (borderRadius && borderRadius > 0) {\n const r = Math.min(borderRadius, w / 2, h / 2);\n pdf.roundedRect(x, y, w, h, r, r, style);\n } else {\n pdf.rect(x, y, w, h, style);\n }\n}\n\n// Draw an ellipse/circle\nfunction drawEllipse(\n pdf: jsPDF,\n cx: number, cy: number, rx: number, ry: number,\n fill: string | undefined,\n stroke: string | undefined,\n strokeWidth: number\n): void {\n const fillColor = parseColor(fill);\n const strokeColor = parseColor(stroke);\n\n if (fillColor) {\n pdf.setFillColor(fillColor.r, fillColor.g, fillColor.b);\n }\n if (strokeColor && strokeWidth > 0) {\n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin('round');\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap('round');\n }\n\n const style: PaintStyle | undefined = fillColor && strokeColor && strokeWidth > 0\n ? 'FD'\n : fillColor\n ? 'F'\n : strokeColor && strokeWidth > 0\n ? 'S'\n : undefined;\n\n if (!style) return;\n if (!Number.isFinite(rx) || !Number.isFinite(ry) || rx <= 0 || ry <= 0) return;\n\n const k = 0.5522847498307936;\n const ox = rx * k;\n const oy = ry * k;\n\n const pathOps: PdfPathOp[] = [\n { op: 'm', c: [cx - rx, cy] },\n { op: 'c', c: [cx - rx, cy - oy, cx - ox, cy - ry, cx, cy - ry] },\n { op: 'c', c: [cx + ox, cy - ry, cx + rx, cy - oy, cx + rx, cy] },\n { op: 'c', c: [cx + rx, cy + oy, cx + ox, cy + ry, cx, cy + ry] },\n { op: 'c', c: [cx - ox, cy + ry, cx - rx, cy + oy, cx - rx, cy] },\n { op: 'h', c: [] },\n ];\n\n if (drawPathWithStyle(pdf, pathOps, style)) return;\n\n pdf.ellipse(cx, cy, rx, ry, style);\n}\n\n// Draw a line\nfunction drawLine(\n pdf: jsPDF,\n x1: number, y1: number, x2: number, y2: number,\n stroke: string | undefined,\n strokeWidth: number,\n dashArray?: string\n) {\n const strokeColor = parseColor(stroke);\n if (!strokeColor || strokeWidth <= 0) return;\n \n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap('round');\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin('round');\n \n // Handle dash patterns\n if (dashArray) {\n const dashes = dashArray.split(/[\\s,]+/).map(Number).filter(n => !isNaN(n));\n if (dashes.length > 0) {\n pdf.setLineDashPattern(dashes, 0);\n }\n }\n \n pdf.line(x1, y1, x2, y2);\n \n // Reset dash pattern\n if (dashArray) {\n pdf.setLineDashPattern([], 0);\n }\n}\n\n// Draw a rounded triangle using SVG-style path converted to PDF path ops\nfunction drawRoundedTrianglePdf(\n pdf: jsPDF,\n x: number, y: number, w: number, h: number,\n svgPath: string,\n fill: string | undefined,\n stroke: string | undefined,\n strokeWidth: number\n): void {\n const fillColor = parseColor(fill);\n const strokeColor = parseColor(stroke);\n\n if (fillColor) pdf.setFillColor(fillColor.r, fillColor.g, fillColor.b);\n if (strokeColor && strokeWidth > 0) {\n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin('miter');\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap('butt');\n if (typeof (pdf as any).setMiterLimit === 'function') (pdf as any).setMiterLimit(TRIANGLE_STROKE_MITER_LIMIT);\n }\n\n const style: PaintStyle | undefined = fillColor && strokeColor && strokeWidth > 0\n ? 'FD'\n : fillColor\n ? 'F'\n : strokeColor && strokeWidth > 0\n ? 'S'\n : undefined;\n\n if (!style) return;\n\n // Parse SVG path and convert to PDF path ops with offset\n const pathOps: PdfPathOp[] = [];\n const tokens = svgPath.match(/[MLQZmlqz]|[-+]?[0-9]*\\.?[0-9]+/g) || [];\n let i = 0;\n while (i < tokens.length) {\n const cmd = tokens[i];\n if (cmd === 'M' || cmd === 'm') {\n i++;\n pathOps.push({ op: 'm', c: [x + parseFloat(tokens[i]), y + parseFloat(tokens[i + 1])] });\n i += 2;\n } else if (cmd === 'L' || cmd === 'l') {\n i++;\n pathOps.push({ op: 'l', c: [x + parseFloat(tokens[i]), y + parseFloat(tokens[i + 1])] });\n i += 2;\n } else if (cmd === 'Q' || cmd === 'q') {\n i++;\n // Convert quadratic bezier to cubic bezier for PDF\n // Q cx,cy ex,ey → approximate with cubic\n const qcx = x + parseFloat(tokens[i]);\n const qcy = y + parseFloat(tokens[i + 1]);\n const qex = x + parseFloat(tokens[i + 2]);\n const qey = y + parseFloat(tokens[i + 3]);\n // Get last point from previous op\n const lastOp = pathOps[pathOps.length - 1];\n const px = lastOp ? lastOp.c[lastOp.c.length - 2] : x;\n const py = lastOp ? lastOp.c[lastOp.c.length - 1] : y;\n // Quadratic to cubic: CP1 = P0 + 2/3*(QCP-P0), CP2 = P1 + 2/3*(QCP-P1)\n const cp1x = px + (2 / 3) * (qcx - px);\n const cp1y = py + (2 / 3) * (qcy - py);\n const cp2x = qex + (2 / 3) * (qcx - qex);\n const cp2y = qey + (2 / 3) * (qcy - qey);\n pathOps.push({ op: 'c', c: [cp1x, cp1y, cp2x, cp2y, qex, qey] });\n i += 4;\n } else if (cmd === 'Z' || cmd === 'z') {\n pathOps.push({ op: 'h', c: [] });\n i++;\n } else {\n i++; // skip unknown\n }\n }\n\n if (drawPathWithStyle(pdf, pathOps, style)) return;\n}\n\n// Draw a polygon (triangles and backwards-compatible legacy polygons)\nfunction drawPolygon(\n pdf: jsPDF,\n points: { x: number; y: number }[],\n fill: string | undefined,\n stroke: string | undefined,\n strokeWidth: number\n) {\n if (points.length < 3) return;\n \n const fillColor = parseColor(fill);\n const strokeColor = parseColor(stroke);\n \n if (fillColor) {\n pdf.setFillColor(fillColor.r, fillColor.g, fillColor.b);\n }\n if (strokeColor && strokeWidth > 0) {\n pdf.setDrawColor(strokeColor.r, strokeColor.g, strokeColor.b);\n pdf.setLineWidth(strokeWidth);\n if (typeof (pdf as any).setLineJoin === 'function') (pdf as any).setLineJoin('miter');\n if (typeof (pdf as any).setLineCap === 'function') (pdf as any).setLineCap('butt');\n if (typeof (pdf as any).setMiterLimit === 'function') (pdf as any).setMiterLimit(TRIANGLE_STROKE_MITER_LIMIT);\n }\n \n const style: PaintStyle | undefined = fillColor && strokeColor && strokeWidth > 0\n ? 'FD'\n : fillColor\n ? 'F'\n : strokeColor && strokeWidth > 0\n ? 'S'\n : undefined;\n \n if (!style) return;\n\n const pathOps: PdfPathOp[] = [\n { op: 'm', c: [points[0].x, points[0].y] },\n ...points.slice(1).map((point) => ({ op: 'l' as const, c: [point.x, point.y] })),\n { op: 'h', c: [] },\n ];\n\n if (drawPathWithStyle(pdf, pathOps, style)) return;\n \n // Fallback for older jsPDF path APIs\n pdf.moveTo(points[0].x, points[0].y);\n for (let i = 1; i < points.length; i++) {\n pdf.lineTo(points[i].x, points[i].y);\n }\n pdf.lineTo(points[0].x, points[0].y);\n applyPaintStyle(pdf, style);\n}\n\n/**\n * Add a clickable link annotation to the PDF\n * jsPDF uses bottom-left origin, so we need to flip Y coordinates\n */\nfunction addLinkAnnotation(\n pdf: jsPDF,\n url: string,\n x: number,\n y: number,\n w: number,\n h: number,\n canvasHeight: number\n): void {\n if (!url || !url.trim()) return;\n \n try {\n // jsPDF link uses top-left origin when unit is 'px' with hotfixes\n // The link method signature: link(x, y, w, h, options)\n pdf.link(x, y, w, h, { url: url.trim() });\n } catch {\n // Link annotation failed (e.g. invalid URL); skip\n }\n}\n\n// Draw text with proper font handling\n// IMPORTANT: jsPDF always interprets setFontSize() as POINTS, even when unit is 'px'.\n// Canvas/Fabric uses pixels, so we must convert: points = pixels * 72 / 96 = pixels * 0.75\nconst PX_TO_PT = 72 / 96; // 0.75\n// Fabric getHeightOfLine() includes _fontSizeMult (1.13) for underline/overline space. Use a slightly\n// higher divisor for the first line so text sits edge-to-edge with the section (not a little bit down).\nconst FABRIC_FONT_SIZE_MULT = 1.13;\nconst FIRST_LINE_BASELINE_MULT = 1.18;\n/** Nudge all text up by this many px so it aligns edge-to-edge with the section in PDF. */\nconst TEXT_UP_NUDGE_PX = 2;\n\n/** Scale down symbol (fallback font) size in PDF so it matches canvas. Tweak if still off: lower = smaller in PDF, higher = larger. */\nconst SYMBOL_FONT_SCALE = 0.78;\n\nfunction drawText(\n pdf: jsPDF,\n text: string,\n x: number, y: number, width: number,\n fontSizePx: number,\n fontFamily: string,\n fontWeight: number,\n fontStyle: 'normal' | 'italic',\n underline: boolean,\n letterSpacing: number,\n fill: string | undefined,\n textAlign: 'left' | 'center' | 'right',\n lineHeight: number,\n embeddedFonts: Set<string>,\n splitByGrapheme: boolean = true,\n liveFabricText?: fabric.FabricObject | null\n): void {\n const fillColor = parseColor(fill);\n if (!fillColor) return;\n \n // Convert pixel font size to points for jsPDF\n const fontSizePt = fontSizePx * PX_TO_PT;\n \n pdf.setTextColor(fillColor.r, fillColor.g, fillColor.b);\n pdf.setFontSize(fontSizePt);\n \n // Try to use actual italic font if available, otherwise fall back to skew transform\n const isItalic = fontStyle === 'italic';\n const resolvedWeight = resolveFontWeight(fontWeight);\n const fontKey = `${fontFamily}${FONT_KEY_SEP}${resolvedWeight}`;\n const italicFontKey = `${fontFamily}${FONT_KEY_SEP}${resolvedWeight}${FONT_KEY_SEP}italic`;\n const hasEmbeddedItalic = isItalic && embeddedFonts.has(italicFontKey);\n\n const mainJsPdfFontName = hasEmbeddedItalic\n ? (embeddedFonts.has(italicFontKey) ? getEmbeddedJsPDFFontName(fontFamily, fontWeight, true) : null)\n : (embeddedFonts.has(fontKey) ? getEmbeddedJsPDFFontName(fontFamily, fontWeight) : null);\n const mainStyle = fontWeight >= 600 ? 'bold' : 'normal';\n if (mainJsPdfFontName) {\n try {\n pdf.setFont(mainJsPdfFontName, 'normal');\n } catch {\n pdf.setFont('helvetica', mainStyle);\n }\n } else {\n pdf.setFont('helvetica', mainStyle);\n }\n // Only use skew for italic if we don't have an actual italic font embedded\n const useSkewForItalic = isItalic && !hasEmbeddedItalic;\n\n const fallbackFontKey = `${FONT_FALLBACK_SYMBOLS}${FONT_KEY_SEP}400`;\n const fallbackJsPdfName = embeddedFonts.has(fallbackFontKey) ? getEmbeddedJsPDFFontName(FONT_FALLBACK_SYMBOLS, 400) : null;\n\n const devanagariWeight = resolveFontWeight(fontWeight);\n const devanagariFontKey = `${FONT_FALLBACK_DEVANAGARI}${FONT_KEY_SEP}${devanagariWeight}`;\n const devanagariJsPdfName = embeddedFonts.has(devanagariFontKey) ? getEmbeddedJsPDFFontName(FONT_FALLBACK_DEVANAGARI, devanagariWeight) : null;\n\n function setRunFont(runType: RunType): void {\n if (runType === 'devanagari' && devanagariJsPdfName) {\n try { pdf.setFont(devanagariJsPdfName, 'normal'); } catch {\n if (mainJsPdfFontName) pdf.setFont(mainJsPdfFontName, 'normal');\n else pdf.setFont('helvetica', mainStyle);\n }\n } else if (runType === 'symbol' && fallbackJsPdfName) {\n try { pdf.setFont(fallbackJsPdfName, 'normal'); } catch {\n if (mainJsPdfFontName) pdf.setFont(mainJsPdfFontName, 'normal');\n else pdf.setFont('helvetica', mainStyle);\n }\n } else if (mainJsPdfFontName) {\n try {\n pdf.setFont(mainJsPdfFontName, 'normal');\n } catch {\n pdf.setFont('helvetica', mainStyle);\n }\n } else {\n pdf.setFont('helvetica', mainStyle);\n }\n }\n\n // Apply letter spacing if set (Fabric.js charSpacing is in 1/1000 em units)\n const charSpacePt = letterSpacing !== 0 ? (letterSpacing / 1000) * fontSizePt : 0;\n if (letterSpacing !== 0) {\n try {\n (pdf as any).setCharSpace?.(charSpacePt);\n } catch {\n // Ignore if not supported\n }\n }\n \n // Prefer live Fabric text object so line positions match preview exactly (WYSIWYG)\n let textLines: string[] = [];\n let getBaselineFromTopPx: (lineIndex: number) => number;\n let getLineLeftOffset: (lineIndex: number) => number;\n // Live object line heights are in canvas/design units (same as PDF points). Fallback Textbox uses px.\n let baselineInPoints = false;\n\n if (liveFabricText && typeof (liveFabricText as any).getHeightOfLine === 'function') {\n const live = liveFabricText as any;\n // Fabric: textLines is string[] (line strings); _textLines is string[][] (grapheme lines)\n textLines = (live.textLines && Array.isArray(live.textLines) ? live.textLines : []).map((line: string | string[]) => Array.isArray(line) ? line.join('') : line);\n const lh = (live.lineHeight ?? lineHeight) || 1.2;\n baselineInPoints = true; // Live object uses same coordinate system as canvas = PDF points\n getBaselineFromTopPx = (lineIndex: number): number => {\n let sum = 0;\n for (let j = 0; j < lineIndex; j++) {\n sum += live.getHeightOfLine(j);\n }\n const lineH = live.getHeightOfLine(lineIndex);\n return sum + lineH / lh;\n };\n getLineLeftOffset = (i: number) => (typeof live._getLineLeftOffset === 'function' ? live._getLineLeftOffset(i) : 0) ?? 0;\n } else {\n // Fallback: create a Fabric Textbox with same settings for layout (measures in px)\n const textbox = new fabric.Textbox(text, {\n width,\n fontSize: fontSizePx,\n fontFamily,\n fontWeight: String(fontWeight),\n charSpacing: letterSpacing,\n textAlign,\n lineHeight: lineHeight || 1.2,\n splitByGrapheme,\n left: 0,\n top: 0,\n originX: 'left',\n originY: 'top',\n });\n textbox.initDimensions();\n textLines = textbox.textLines || [];\n const lh = lineHeight || 1.2;\n getBaselineFromTopPx = (lineIndex: number): number => {\n let sum = 0;\n for (let j = 0; j < lineIndex; j++) {\n sum += (textbox as any).getHeightOfLine?.(j) ?? (fontSizePx * lh);\n }\n const lineH = (textbox as any).getHeightOfLine?.(lineIndex) ?? (fontSizePx * lh);\n return sum + lineH / lh;\n };\n getLineLeftOffset = (i: number) => (textbox as any)._getLineLeftOffset?.(i) ?? 0;\n }\n\n if (textLines.length === 0) return;\n \n // Italic skew angle (approx 12 degrees, like CSS oblique)\n const italicSkewAngle = isItalic ? -0.21 : 0; // tan(12°) ≈ 0.21\n \n // Draw each line at its Fabric.js-calculated position (by runs so symbols like ● use fallback font)\n for (let i = 0; i < textLines.length; i++) {\n const lineText = textLines[i];\n if (!lineText) continue;\n\n // ── Fast-path: pure Latin line → single pdf.text() call, no run-splitting ──\n const pureLatin = isPureLatin(lineText);\n\n let totalLineWidth: number;\n if (pureLatin) {\n setRunFont('main');\n totalLineWidth = pdf.getTextWidth(lineText);\n } else {\n const runs = splitLineIntoRuns(lineText);\n totalLineWidth = 0;\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n totalLineWidth += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) totalLineWidth += charSpacePt;\n }\n // Store runs for rendering below\n (lineText as any).__runs = runs;\n }\n\n let lineLeftOffset = getLineLeftOffset(i);\n if (lineLeftOffset === 0 && (textAlign === 'center' || textAlign === 'right')) {\n if (textAlign === 'center') {\n lineLeftOffset = (width - totalLineWidth) / 2;\n } else if (textAlign === 'right') {\n lineLeftOffset = width - totalLineWidth;\n }\n }\n\n const rawBaseline = getBaselineFromTopPx(i);\n const firstLineRaw = getBaselineFromTopPx(0);\n const baselineFromTop = i === 0\n ? rawBaseline / FIRST_LINE_BASELINE_MULT\n : (firstLineRaw / FIRST_LINE_BASELINE_MULT) + (rawBaseline - firstLineRaw);\n const lineY = y + (baselineInPoints ? baselineFromTop : baselineFromTop * PX_TO_PT) - TEXT_UP_NUDGE_PX;\n const lineX = x + lineLeftOffset;\n\n if (pureLatin) {\n // Single call — no font switching, preserves exact pre-Hindi metrics\n setRunFont('main');\n if (useSkewForItalic) {\n (pdf as any).saveGraphicsState?.();\n try {\n const pdfInternal = (pdf as any).internal;\n if (pdfInternal?.write) {\n pdfInternal.write('q');\n pdfInternal.write(`1 0 ${italicSkewAngle.toFixed(4)} 1 ${lineX.toFixed(2)} ${lineY.toFixed(2)} cm`);\n pdf.text(lineText, 0, 0);\n pdfInternal.write('Q');\n } else {\n pdf.text(lineText, lineX, lineY);\n }\n } catch {\n pdf.text(lineText, lineX, lineY);\n }\n (pdf as any).restoreGraphicsState?.();\n } else {\n pdf.text(lineText, lineX, lineY);\n }\n } else {\n // Multi-run path for non-Latin text\n const runs: { text: string; runType: RunType }[] = (lineText as any).__runs || splitLineIntoRuns(lineText);\n let runX = lineX;\n\n if (useSkewForItalic) {\n (pdf as any).saveGraphicsState?.();\n try {\n const pdfInternal = (pdf as any).internal;\n if (pdfInternal?.write) {\n pdfInternal.write('q');\n pdfInternal.write(`1 0 ${italicSkewAngle.toFixed(4)} 1 ${lineX.toFixed(2)} ${lineY.toFixed(2)} cm`);\n runX = 0;\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n pdf.text(runs[r].text, runX, 0);\n runX += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) runX += charSpacePt;\n }\n pdfInternal.write('Q');\n } else {\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n pdf.text(runs[r].text, runX, lineY);\n runX += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) runX += charSpacePt;\n }\n }\n } catch {\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n pdf.text(runs[r].text, runX, lineY);\n runX += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) runX += charSpacePt;\n }\n }\n (pdf as any).restoreGraphicsState?.();\n } else {\n for (let r = 0; r < runs.length; r++) {\n const rt = runs[r].runType;\n if (rt === 'symbol') pdf.setFontSize(fontSizePt * SYMBOL_FONT_SCALE);\n setRunFont(rt);\n pdf.text(runs[r].text, runX, lineY);\n runX += pdf.getTextWidth(runs[r].text);\n if (rt === 'symbol') pdf.setFontSize(fontSizePt);\n if (letterSpacing !== 0 && r < runs.length - 1) runX += charSpacePt;\n }\n }\n }\n\n if (underline && lineText.trim()) {\n const underlineY = lineY + fontSizePt * 0.15;\n const underlineThickness = Math.max(0.5, fontSizePt * 0.066667);\n pdf.setDrawColor(fillColor.r, fillColor.g, fillColor.b);\n pdf.setLineWidth(underlineThickness);\n pdf.line(lineX, underlineY, lineX + totalLineWidth, underlineY);\n }\n }\n \n // Reset letter spacing\n if (letterSpacing !== 0) {\n try {\n (pdf as any).setCharSpace?.(0);\n } catch {\n // Ignore\n }\n }\n}\n\ntype PdfImageData = { data: string; format: 'PNG' | 'JPEG' };\n\ntype FetchImageOptions = {\n /** Used when we must flatten transparency (fallback). */\n backgroundColor?: string;\n /** Target placement size in PDF points (used to downscale for speed/size). */\n targetWidthPt?: number;\n targetHeightPt?: number;\n /** If true, preserve transparency (e.g., border/frame overlays). */\n preserveAlpha?: boolean;\n /** Extra scale for rasterization (e.g. 4 for SVG so PDF stays sharp when zoomed). */\n resolutionMultiplier?: number;\n};\n\nfunction normalizeBgColor(bg?: string): string {\n if (!bg || bg === 'transparent' || bg === 'none') return '#ffffff';\n return bg;\n}\n\nfunction blobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = () => reject(new Error('Failed to read blob'));\n reader.readAsDataURL(blob);\n });\n}\n\nfunction readPngHeader(buf: ArrayBuffer): { bitDepth: number; colorType: number } | null {\n try {\n const bytes = new Uint8Array(buf);\n // PNG signature\n if (\n bytes[0] !== 0x89 ||\n bytes[1] !== 0x50 ||\n bytes[2] !== 0x4e ||\n bytes[3] !== 0x47\n ) {\n return null;\n }\n\n // Must have IHDR first\n const type = String.fromCharCode(bytes[12], bytes[13], bytes[14], bytes[15]);\n if (type !== 'IHDR') return null;\n\n const bitDepth = bytes[24];\n const colorType = bytes[25];\n return { bitDepth, colorType };\n } catch {\n return null;\n }\n}\n\nasync function detectAlpha(blob: Blob): Promise<boolean> {\n const bitmap = await createImageBitmap(blob);\n const w = 32;\n const h = 32;\n const c = document.createElement('canvas');\n c.width = w;\n c.height = h;\n const ctx = c.getContext('2d');\n if (!ctx) return false;\n ctx.clearRect(0, 0, w, h);\n ctx.drawImage(bitmap, 0, 0, w, h);\n const data = ctx.getImageData(0, 0, w, h).data;\n for (let i = 3; i < data.length; i += 4) {\n if (data[i] !== 255) return true;\n }\n return false;\n}\n\nfunction getTargetPixelSize(bitmap: ImageBitmap, opts: FetchImageOptions): { w: number; h: number } {\n // Points are 1/72\"; for sharp output we aim ~144 DPI (= 2 px per point). SVG uses higher multiplier so zoom stays crisp.\n const dpiScale = 1.5 * (opts.resolutionMultiplier ?? 1);\n const maxPx = opts.resolutionMultiplier && opts.resolutionMultiplier > 1 ? 4400 : 2200;\n const capByBitmap = !(opts.resolutionMultiplier && opts.resolutionMultiplier > 1);\n\n const desiredW = Math.max(1, Math.round((opts.targetWidthPt ?? bitmap.width) * dpiScale));\n const desiredH = Math.max(1, Math.round((opts.targetHeightPt ?? bitmap.height) * dpiScale));\n\n return {\n w: Math.min(maxPx, desiredW, capByBitmap ? bitmap.width : Infinity),\n h: Math.min(maxPx, desiredH, capByBitmap ? bitmap.height : Infinity),\n };\n}\n\nasync function rasterizeToDataUrl(\n blob: Blob,\n opts: FetchImageOptions,\n out: 'PNG' | 'JPEG',\n flattenBackground?: boolean\n): Promise<string> {\n const bitmap = await createImageBitmap(blob);\n const { w, h } = getTargetPixelSize(bitmap, opts);\n\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('Canvas context not available');\n\n // If flattening, paint background first (prevents black where alpha existed)\n if (flattenBackground) {\n ctx.fillStyle = normalizeBgColor(opts.backgroundColor);\n ctx.fillRect(0, 0, w, h);\n } else {\n ctx.clearRect(0, 0, w, h);\n }\n\n ctx.imageSmoothingEnabled = true;\n try {\n // @ts-ignore\n ctx.imageSmoothingQuality = 'high';\n } catch {\n // ignore\n }\n\n ctx.drawImage(bitmap, 0, 0, w, h);\n\n if (out === 'JPEG') {\n return canvas.toDataURL('image/jpeg', 0.82);\n }\n return canvas.toDataURL('image/png');\n}\n\n// Fetch image for PDF embedding.\n// Strategy:\n// - If the proxy returns real PNG/JPEG: embed original bytes (small + preserves alpha)\n// - If it returns WEBP/AVIF or a 16-bit PNG: rasterize to an 8-bit PNG (keeps alpha)\n// - Only flatten to JPEG when the image has no alpha (smaller) or as a last-resort\nasync function fetchImageAsBase64(imageUrl: string, opts: FetchImageOptions = {}): Promise<PdfImageData | null> {\n try {\n const forcePreserveAlpha = opts.preserveAlpha === true;\n\n // Normalize data URLs (some may be WEBP/PNG/etc)\n if (imageUrl.startsWith('data:')) {\n const res = await fetch(imageUrl);\n const blob = await res.blob();\n const type = (blob.type || '').toLowerCase();\n\n if (type === 'image/jpeg' || type === 'image/jpg') {\n return { data: imageUrl, format: 'JPEG' };\n }\n\n if (forcePreserveAlpha) {\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', false);\n return { data: pngUrl, format: 'PNG' };\n }\n\n const hasAlpha = await detectAlpha(blob);\n if (hasAlpha) {\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', false);\n return { data: pngUrl, format: 'PNG' };\n }\n\n const jpegUrl = await rasterizeToDataUrl(blob, opts, 'JPEG', true);\n return { data: jpegUrl, format: 'JPEG' };\n }\n\n // Determine fetch URL (proxy for external URLs via API server or Supabase edge function)\n let fetchUrl = imageUrl;\n if (imageUrl.startsWith('http://') || imageUrl.startsWith('https://')) {\n const { isPrivateUrl } = await import('./canvasImageLoader');\n if (isPrivateUrl(imageUrl)) return null;\n const proxyUrl = new URL(`${API_URL}/image-proxy`);\n proxyUrl.searchParams.set('url', imageUrl);\n fetchUrl = proxyUrl.toString();\n }\n\n const response = await fetch(fetchUrl, { cache: 'no-store', ...getImageProxyFetchOptions() });\n\n if (!response.ok) return null;\n\n const blob = await response.blob();\n const type = (blob.type || '').toLowerCase();\n\n // JPEG: keep as-is\n if (type === 'image/jpeg' || type === 'image/jpg') {\n const dataUrl = await blobToDataUrl(blob);\n return { data: dataUrl, format: 'JPEG' };\n }\n\n // PNG: try to embed original bytes (best size + preserves transparency)\n if (type === 'image/png') {\n const buf = await blob.arrayBuffer();\n const hdr = readPngHeader(buf);\n\n // 16-bit PNGs are known to break/blur in some jsPDF versions -> rasterize to 8-bit\n if (hdr?.bitDepth === 16) {\n const flattenWithBg = !forcePreserveAlpha && !!(opts.backgroundColor && opts.backgroundColor !== 'transparent' && opts.backgroundColor !== 'none');\n const pngUrl = await rasterizeToDataUrl(new Blob([buf], { type: 'image/png' }), opts, 'PNG', flattenWithBg);\n return { data: pngUrl, format: 'PNG' };\n }\n\n if (forcePreserveAlpha) {\n const dataUrl = await blobToDataUrl(blob);\n return { data: dataUrl, format: 'PNG' };\n }\n\n // When we have a background color, rasterize so transparent areas show it in PDF (not black)\n const flattenWithBg = !!(opts.backgroundColor && opts.backgroundColor !== 'transparent' && opts.backgroundColor !== 'none');\n if (flattenWithBg) {\n const hasAlpha = hdr?.colorType === 4 || hdr?.colorType === 6; // grayscale+alpha or RGBA\n if (hasAlpha) {\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', true);\n return { data: pngUrl, format: 'PNG' };\n }\n }\n\n // For typical 8-bit PNGs (including transparent frames), embed original bytes.\n const dataUrl = await blobToDataUrl(blob);\n return { data: dataUrl, format: 'PNG' };\n }\n\n // WEBP/AVIF/GIF/SVG/etc: rasterize.\n if (forcePreserveAlpha) {\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', false);\n return { data: pngUrl, format: 'PNG' };\n }\n\n const hasAlpha = await detectAlpha(blob);\n if (hasAlpha) {\n // Flatten with background when provided so transparent areas show page color in PDF (not black)\n const flattenWithBg = !!(opts.backgroundColor && opts.backgroundColor !== 'transparent' && opts.backgroundColor !== 'none');\n const pngUrl = await rasterizeToDataUrl(blob, opts, 'PNG', flattenWithBg);\n return { data: pngUrl, format: 'PNG' };\n }\n\n const jpegUrl = await rasterizeToDataUrl(blob, opts, 'JPEG', true);\n return { data: jpegUrl, format: 'JPEG' };\n } catch {\n return null;\n }\n}\n\n// Generate polygon points for various shapes\nfunction getShapePoints(\n shapeType: string,\n x: number, y: number, w: number, h: number\n): { x: number; y: number }[] | null {\n const cx = x + w / 2;\n const cy = y + h / 2;\n \n switch (shapeType) {\n case 'triangle':\n return getTrianglePoints(x, y, w, h);\n\n case 'diamond':\n return [\n { x: cx, y: y },\n { x: x + w, y: cy },\n { x: cx, y: y + h },\n { x: x, y: cy },\n ];\n \n case 'pentagon':\n return generateRegularPolygon(5, cx, cy, Math.min(w, h) / 2);\n \n case 'hexagon':\n return generateRegularPolygon(6, cx, cy, Math.min(w, h) / 2);\n \n case 'octagon':\n return generateRegularPolygon(8, cx, cy, Math.min(w, h) / 2);\n \n case 'star':\n return generateStar(5, cx, cy, Math.min(w, h) / 2);\n \n case 'arrow':\n return [\n { x: x, y: y + h * 0.3 },\n { x: x + w * 0.6, y: y + h * 0.3 },\n { x: x + w * 0.6, y: y },\n { x: x + w, y: cy },\n { x: x + w * 0.6, y: y + h },\n { x: x + w * 0.6, y: y + h * 0.7 },\n { x: x, y: y + h * 0.7 },\n ];\n \n case 'parallelogram':\n return [\n { x: x + w * 0.2, y: y },\n { x: x + w, y: y },\n { x: x + w * 0.8, y: y + h },\n { x: x, y: y + h },\n ];\n \n case 'trapezoid':\n return [\n { x: x + w * 0.2, y: y },\n { x: x + w * 0.8, y: y },\n { x: x + w, y: y + h },\n { x: x, y: y + h },\n ];\n \n case 'cross':\n const t = 0.35; // thickness ratio\n return [\n { x: x + w * t, y: y },\n { x: x + w * (1 - t), y: y },\n { x: x + w * (1 - t), y: y + h * t },\n { x: x + w, y: y + h * t },\n { x: x + w, y: y + h * (1 - t) },\n { x: x + w * (1 - t), y: y + h * (1 - t) },\n { x: x + w * (1 - t), y: y + h },\n { x: x + w * t, y: y + h },\n { x: x + w * t, y: y + h * (1 - t) },\n { x: x, y: y + h * (1 - t) },\n { x: x, y: y + h * t },\n { x: x + w * t, y: y + h * t },\n ];\n \n default:\n return null;\n }\n}\n\nfunction generateRegularPolygon(sides: number, cx: number, cy: number, radius: number): { x: number; y: number }[] {\n const points: { x: number; y: number }[] = [];\n const angleOffset = -Math.PI / 2;\n \n for (let i = 0; i < sides; i++) {\n const angle = angleOffset + (2 * Math.PI * i) / sides;\n points.push({\n x: cx + radius * Math.cos(angle),\n y: cy + radius * Math.sin(angle),\n });\n }\n \n return points;\n}\n\nfunction generateStar(points: number, cx: number, cy: number, outerRadius: number): { x: number; y: number }[] {\n const result: { x: number; y: number }[] = [];\n const innerRadius = outerRadius * 0.4;\n const angleOffset = -Math.PI / 2;\n \n for (let i = 0; i < points * 2; i++) {\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const angle = angleOffset + (Math.PI * i) / points;\n result.push({\n x: cx + radius * Math.cos(angle),\n y: cy + radius * Math.sin(angle),\n });\n }\n \n return result;\n}\n\n/**\n * Matrix math helpers (2D affine) for converting Fabric.js transforms to jsPDF's ADVANCED mode.\n *\n * Fabric canvas space: origin top-left, +Y down.\n * jsPDF ADVANCED space: origin bottom-left, +Y up.\n */\n\ntype Matrix6 = [number, number, number, number, number, number];\n\nfunction mulM(a: Matrix6, b: Matrix6): Matrix6 {\n return [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n a[0] * b[4] + a[2] * b[5] + a[4],\n a[1] * b[4] + a[3] * b[5] + a[5],\n ];\n}\n\nfunction getMatrixScaleFactors(matrix: number[] | Matrix6 | null | undefined): { sx: number; sy: number } {\n if (!matrix || matrix.length !== 6) return { sx: 1, sy: 1 };\n const [a, b, c, d] = matrix;\n const sx = Math.hypot(a, b);\n const sy = Math.hypot(c, d);\n return {\n sx: Number.isFinite(sx) && sx > 0 ? sx : 1,\n sy: Number.isFinite(sy) && sy > 0 ? sy : 1,\n };\n}\n\nfunction getStrokeScaleCompensationForMatrix(element: CanvasElement, matrix: number[] | Matrix6 | null | undefined): number {\n if (element.type !== 'shape' && element.type !== 'line') return 1;\n\n const { sx, sy } = getMatrixScaleFactors(matrix);\n if (sx <= 0 || sy <= 0) return 1;\n\n const isUniformScale = Math.abs(sx - sy) < 0.0001;\n const referenceScale = isUniformScale ? sx : Math.max(sx, sy);\n if (!Number.isFinite(referenceScale) || referenceScale <= 0) return 1;\n\n const compensation = 1 / referenceScale;\n return Math.max(0.0001, Math.min(1000, compensation));\n}\n\nfunction withCompensatedStrokeWidth(\n norm: ReturnType<typeof normalizeElement>,\n element: CanvasElement,\n matrix: number[] | Matrix6 | null | undefined\n): ReturnType<typeof normalizeElement> {\n if (norm.strokeWidth <= 0) return norm;\n\n const compensation = getStrokeScaleCompensationForMatrix(element, matrix);\n if (Math.abs(compensation - 1) < 0.0001) return norm;\n\n return {\n ...norm,\n strokeWidth: Number((norm.strokeWidth * compensation).toFixed(4)),\n };\n}\n\n/**\n * Convert a Fabric calcTransformMatrix() into a matrix usable in jsPDF ADVANCED mode.\n *\n * IMPORTANT: jsPDF's coordinate system is also Y-down (like canvas), even in advancedAPI.\n * So we can apply Fabric's matrix directly.\n */\nfunction fabricMatrixToJsPdfAdvancedMatrix(fabricM: number[], _pageHeight: number): Matrix6 {\n return (fabricM.length === 6 ? (fabricM as Matrix6) : ([1, 0, 0, 1, 0, 0] as Matrix6));\n}\n\n/** Stored crop/natural from element – used at export so we don't rely on Fabric's baked state after move. */\ninterface StoredCropExportInfo {\n naturalWidth?: number;\n naturalHeight?: number;\n panX?: number;\n panY?: number;\n zoom?: number;\n}\n\n/**\n * Rasterize a crop group (masked image) to PNG with clipPath applied.\n * When forceBlobReplace is true (retry after SecurityError), replace clone's image with same-origin blob.\n * Prefer stored when present so export is correct after move.\n * When backgroundColor is set, transparent areas of the image (e.g. transparent SVG) are filled with that\n * color so the PDF matches the preview (no black behind transparent regions).\n */\nasync function rasterizeCropGroupToPng(\n liveGroup: fabric.Group,\n frameW: number,\n frameH: number,\n multiplier = 2,\n maintainResolution = false,\n imageUrl?: string,\n forceBlobReplace = false,\n stored?: StoredCropExportInfo,\n backgroundColor?: string\n): Promise<string> {\n const bgFill = backgroundColor && backgroundColor !== 'transparent' && backgroundColor !== 'none'\n ? normalizeBgColor(backgroundColor)\n : undefined;\n const cropData = (liveGroup as any).__cropData;\n const rxRatio = cropData?.rx || 0;\n const minFrameDim = Math.min(frameW, frameH);\n const clipRx = Math.min(rxRatio > 0.5 ? rxRatio : rxRatio * minFrameDim, frameW / 2, frameH / 2);\n const shape = cropData?.shape || 'rect';\n const panX = Math.max(0, Math.min(1, stored?.panX ?? (cropData?._img as any)?._ct?.panX ?? 0.5));\n const panY = Math.max(0, Math.min(1, stored?.panY ?? (cropData?._img as any)?._ct?.panY ?? 0.5));\n const zoom = Math.max(1, stored?.zoom ?? (cropData?._img as any)?._ct?.zoom ?? 1);\n\n // Keep Resolution: full-resolution 2D canvas crop (any URL including data:). Embed visible crop at 1:1 pixels, draw at frame size in PDF.\n if (maintainResolution && imageUrl) {\n const dims = await loadNaturalDimensionsFromUrl(imageUrl);\n const natW = dims?.width ?? stored?.naturalWidth ?? frameW;\n const natH = dims?.height ?? stored?.naturalHeight ?? frameH;\n const useNatW = natW > 0 && natH > 0 ? natW : frameW;\n const useNatH = natW > 0 && natH > 0 ? natH : frameH;\n if (useNatW > frameW || useNatH > frameH) {\n let htmlImg: HTMLImageElement | null = null;\n if (imageUrl.startsWith('data:') || imageUrl.startsWith('blob:')) {\n try {\n htmlImg = await new Promise<HTMLImageElement>((resolve, reject) => {\n const im = new Image();\n im.onload = () => resolve(im);\n im.onerror = () => reject(new Error('Image load failed'));\n im.src = imageUrl;\n });\n } catch {\n htmlImg = null;\n }\n } else {\n try {\n const proxied = getProxiedImageUrl(imageUrl);\n const res = await fetch(proxied);\n if (!res.ok) throw new Error('Fetch failed');\n const blob = await res.blob();\n const blobUrl = URL.createObjectURL(blob);\n try {\n htmlImg = await new Promise<HTMLImageElement>((resolve, reject) => {\n const im = new Image();\n im.crossOrigin = 'anonymous';\n im.onload = () => resolve(im);\n im.onerror = () => reject(new Error('Image load failed'));\n im.src = blobUrl;\n });\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n } catch {\n htmlImg = null;\n }\n }\n if (htmlImg) {\n const iw = htmlImg.naturalWidth || useNatW;\n const ih = htmlImg.naturalHeight || useNatH;\n const baseScale = Math.max(frameW / iw, frameH / ih);\n const finalScale = baseScale * zoom;\n const drawW = iw * finalScale;\n const drawH = ih * finalScale;\n const overflowX = Math.max(0, drawW - frameW);\n const overflowY = Math.max(0, drawH - frameH);\n const offsetX = overflowX > 0 ? -overflowX * (panX - 0.5) : 0;\n const offsetY = overflowY > 0 ? -overflowY * (panY - 0.5) : 0;\n const imageLeft = frameW / 2 + offsetX - (iw * finalScale) / 2;\n const imageTop = frameH / 2 + offsetY - (ih * finalScale) / 2;\n const srcX = Math.max(0, Math.floor(-imageLeft / finalScale));\n const srcY = Math.max(0, Math.floor(-imageTop / finalScale));\n const srcW = Math.min(Math.ceil(frameW / finalScale), iw - srcX);\n const srcH = Math.min(Math.ceil(frameH / finalScale), ih - srcY);\n if (srcW >= 1 && srcH >= 1) {\n const cropCanvas = document.createElement('canvas');\n cropCanvas.width = srcW;\n cropCanvas.height = srcH;\n const ctx = cropCanvas.getContext('2d');\n if (ctx) {\n if (bgFill) {\n ctx.fillStyle = bgFill;\n ctx.fillRect(0, 0, srcW, srcH);\n } else {\n ctx.clearRect(0, 0, srcW, srcH);\n }\n ctx.drawImage(htmlImg, srcX, srcY, srcW, srcH, 0, 0, srcW, srcH);\n // Apply clip shape (circle or rounded rect) so export matches preview\n if (shape === 'circle' || shape === 'roundRect' || shape === 'rect') {\n ctx.globalCompositeOperation = 'destination-in';\n if (shape === 'circle') {\n ctx.beginPath();\n ctx.ellipse(srcW / 2, srcH / 2, srcW / 2, srcH / 2, 0, 0, 2 * Math.PI);\n ctx.fill();\n } else {\n const rx = Math.min(\n (rxRatio > 0.5 ? rxRatio : rxRatio * minFrameDim) * (srcW / frameW),\n srcW / 2,\n srcH / 2\n );\n const r = Math.max(0, rx);\n ctx.beginPath();\n ctx.moveTo(r, 0);\n ctx.lineTo(srcW - r, 0);\n if (r > 0) ctx.quadraticCurveTo(srcW, 0, srcW, r);\n ctx.lineTo(srcW, srcH - r);\n if (r > 0) ctx.quadraticCurveTo(srcW, srcH, srcW - r, srcH);\n ctx.lineTo(r, srcH);\n if (r > 0) ctx.quadraticCurveTo(0, srcH, 0, srcH - r);\n ctx.lineTo(0, r);\n if (r > 0) ctx.quadraticCurveTo(0, 0, r, 0);\n ctx.closePath();\n ctx.fill();\n }\n }\n return cropCanvas.toDataURL('image/png');\n }\n }\n }\n }\n }\n\n // BLOB-ONLY PATH: build from scratch (no clone). Avoids all baked-state issues after move.\n if (forceBlobReplace && imageUrl && !imageUrl.startsWith('data:') && !imageUrl.startsWith('blob:')) {\n const dims = await loadNaturalDimensionsFromUrl(imageUrl);\n const natW = dims?.width ?? stored?.naturalWidth ?? frameW;\n const natH = dims?.height ?? stored?.naturalHeight ?? frameH;\n const useNatW = natW > 0 && natH > 0 ? natW : frameW;\n const useNatH = natW > 0 && natH > 0 ? natH : frameH;\n const outW = maintainResolution && useNatW > frameW ? Math.max(1, Math.round(useNatW)) : Math.max(1, Math.round(frameW * multiplier));\n const outH = maintainResolution && useNatH > frameH ? Math.max(1, Math.round(useNatH)) : Math.max(1, Math.round(frameH * multiplier));\n const proxied = getProxiedImageUrl(imageUrl);\n const res = await fetch(proxied);\n if (!res.ok) throw new Error(`Export blob fetch failed: ${res.status}`);\n const blob = await res.blob();\n const blobUrl = URL.createObjectURL(blob);\n try {\n const img = await fabric.FabricImage.fromURL(blobUrl, { crossOrigin: 'anonymous' });\n img.set({ width: useNatW, height: useNatH, originX: 'center', originY: 'center', objectCaching: false, dirty: true });\n const baseScale = Math.max(frameW / useNatW, frameH / useNatH);\n const finalScale = baseScale * zoom;\n img.set({ scaleX: finalScale, scaleY: finalScale });\n const dispW = useNatW * finalScale;\n const dispH = useNatH * finalScale;\n const overflowX = Math.max(0, dispW - frameW);\n const overflowY = Math.max(0, dispH - frameH);\n img.set({ left: overflowX > 0 ? -overflowX * (panX - 0.5) : 0, top: overflowY > 0 ? -overflowY * (panY - 0.5) : 0 });\n img.setCoords();\n const clip = shape === 'circle'\n ? new fabric.Ellipse({ rx: frameW / 2, ry: frameH / 2, left: 0, top: 0, originX: 'center', originY: 'center', selectable: false, evented: false })\n : new fabric.Rect({ width: frameW, height: frameH, rx: clipRx, ry: clipRx, left: 0, top: 0, originX: 'center', originY: 'center', selectable: false, evented: false });\n (clip as any).absolutePositioned = false;\n (clip as any).excludeFromExport = false;\n const group = new fabric.Group([img], { left: outW / 2, top: outH / 2, originX: 'center', originY: 'center', width: frameW, height: frameH, scaleX: outW / frameW, scaleY: outH / frameH, angle: 0, opacity: liveGroup.opacity ?? 1, objectCaching: false });\n group.clipPath = clip;\n (group.clipPath as any).absolutePositioned = false;\n (group.clipPath as any).excludeFromExport = false;\n group.set({ width: frameW, height: frameH });\n group.setCoords();\n if (group.clipPath) group.clipPath.setCoords();\n const el = document.createElement('canvas');\n el.width = outW;\n el.height = outH;\n const exportCanvas = new fabric.StaticCanvas(el, {\n width: outW,\n height: outH,\n backgroundColor: bgFill ?? 'transparent',\n renderOnAddRemove: false,\n });\n exportCanvas.add(group);\n exportCanvas.renderAll();\n const png = exportCanvas.toDataURL({ format: 'png', multiplier: 1, enableRetinaScaling: false });\n exportCanvas.dispose();\n return png;\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n }\n\n // CLONE PATH\n let outW: number;\n let outH: number;\n let clipScaleX = 1;\n let clipScaleY = 1;\n const rx = rxRatio > 0.5 ? rxRatio : rxRatio * minFrameDim;\n let exportNaturalW = 0;\n let exportNaturalH = 0;\n let urlDims: { width: number; height: number } | null = null;\n if (imageUrl && (forceBlobReplace || maintainResolution)) {\n urlDims = await loadNaturalDimensionsFromUrl(imageUrl);\n }\n if (maintainResolution) {\n // Prefer URL-fetched (blob path), then stored, then Fabric\n let naturalWidth = urlDims?.width ?? ((stored?.naturalWidth ?? 0) > 0 && (stored?.naturalHeight ?? 0) > 0 ? stored!.naturalWidth! : 0);\n let naturalHeight = urlDims?.height ?? (naturalWidth > 0 ? stored!.naturalHeight! : 0);\n if (naturalWidth <= 0 || naturalHeight <= 0) {\n let img = cropData?._img;\n if (!img || (typeof (img as any).getElement !== 'function' && !(img as any)._element)) {\n const objects = liveGroup.getObjects();\n img = objects.find((o: fabric.FabricObject) => o instanceof fabric.FabricImage || (o as any).getElement) as fabric.FabricImage | undefined;\n }\n if (img && (typeof (img as any).getElement === 'function' || (img as any)._element)) {\n const orig = typeof (img as any).getOriginalSize === 'function' ? (img as any).getOriginalSize() : null;\n const htmlImg = orig ? null : (typeof (img as any).getElement === 'function' ? (img as any).getElement() : (img as any)._element);\n naturalWidth = (orig?.width ?? htmlImg?.naturalWidth ?? (img as any).width) || 0;\n naturalHeight = (orig?.height ?? htmlImg?.naturalHeight ?? (img as any).height) || 0;\n }\n }\n // After move/transform Fabric may bake dimensions. If still no good size, try URL.\n const fromFabricLooksBaked = naturalWidth > 0 && naturalHeight > 0 && naturalWidth <= frameW + 2 && naturalHeight <= frameH + 2;\n if (imageUrl && (naturalWidth <= 0 || naturalHeight <= 0 || fromFabricLooksBaked)) {\n const dims = await loadNaturalDimensionsFromUrl(imageUrl);\n if (dims && dims.width > 0 && dims.height > 0) {\n naturalWidth = dims.width;\n naturalHeight = dims.height;\n } else if (fromFabricLooksBaked) {\n // URL load failed or skipped (e.g. data:); don't use baked size - use at least 4x frame for export quality\n naturalWidth = Math.max(naturalWidth, Math.round(frameW * 4));\n naturalHeight = Math.max(naturalHeight, Math.round(frameH * 4));\n }\n }\n if (naturalWidth > 0 && naturalHeight > 0) {\n exportNaturalW = naturalWidth;\n exportNaturalH = naturalHeight;\n // Use frame aspect at high res so export matches preview; avoid image aspect (which crops wrong).\n let scaleUp = Math.max(naturalWidth / frameW, naturalHeight / frameH, multiplier);\n // SVG sources: ensure at least 4x resolution so PDF stays sharp when zoomed\n if (imageUrl && imageUrl.toLowerCase().includes('.svg')) {\n scaleUp = Math.max(scaleUp, 4);\n }\n outW = Math.max(1, Math.round(frameW * scaleUp));\n outH = Math.max(1, Math.round(frameH * scaleUp));\n clipScaleX = outW / frameW;\n clipScaleY = outH / frameH;\n } else {\n outW = Math.max(1, Math.round(frameW * multiplier));\n outH = Math.max(1, Math.round(frameH * multiplier));\n clipScaleX = multiplier;\n clipScaleY = multiplier;\n }\n } else {\n outW = Math.max(1, Math.round(frameW * multiplier));\n outH = Math.max(1, Math.round(frameH * multiplier));\n clipScaleX = multiplier;\n clipScaleY = multiplier;\n }\n\n const el = document.createElement('canvas');\n el.width = outW;\n el.height = outH;\n\n const exportCanvas = new fabric.StaticCanvas(el, {\n width: outW,\n height: outH,\n backgroundColor: bgFill ?? 'transparent',\n renderOnAddRemove: false,\n });\n\n // Fabric.js v6: clone() returns a Promise directly\n const clonedGroup = await liveGroup.clone() as fabric.Group;\n\n // Make sure clip exports + disable caching everywhere\n // CRITICAL: Preserve opacity from the original group\n clonedGroup.set({ \n objectCaching: false, \n dirty: true,\n opacity: liveGroup.opacity ?? 1, // Preserve opacity\n });\n (clonedGroup as any)._objects?.forEach((o: any) => o.set({ objectCaching: false, dirty: true }));\n \n // CRITICAL: Ensure clipPath is properly configured for export\n // The clip path is in group-local coordinates, so it will scale with the group\n // (shape already declared at top of function)\n \n // When Keep Resolution: use clip path and group at EXPORT size (outW x outH) so the clip is not at canvas resolution.\n // Otherwise Fabric can effectively clip at frame size and we see only a small region.\n const groupScaleX = maintainResolution ? 1 : multiplier;\n const groupScaleY = maintainResolution ? 1 : multiplier;\n const clipW = maintainResolution ? outW : frameW;\n const clipH = maintainResolution ? outH : frameH;\n const scaledClipRx = maintainResolution ? Math.min(clipRx * (outW / frameW), outW / 2, outH / 2) : Math.min(clipRx, clipW / 2, clipH / 2);\n \n // If clipPath wasn't cloned, recreate it from the original\n if (!clonedGroup.clipPath && liveGroup.clipPath) {\n if (shape === 'circle') {\n clonedGroup.clipPath = new fabric.Ellipse({\n rx: clipW / 2,\n ry: clipH / 2,\n left: 0,\n top: 0,\n originX: 'center',\n originY: 'center',\n selectable: false,\n evented: false,\n hasControls: false,\n hasBorders: false,\n });\n } else {\n clonedGroup.clipPath = new fabric.Rect({\n width: clipW,\n height: clipH,\n rx: scaledClipRx,\n ry: scaledClipRx,\n left: 0,\n top: 0,\n originX: 'center',\n originY: 'center',\n selectable: false,\n evented: false,\n hasControls: false,\n hasBorders: false,\n });\n }\n (clonedGroup.clipPath as any).absolutePositioned = false;\n (clonedGroup.clipPath as any).excludeFromExport = false;\n } else if (clonedGroup.clipPath) {\n // Update existing clipPath (works for both maintainResolution true and false)\n if (shape === 'circle' && clonedGroup.clipPath instanceof fabric.Ellipse) {\n clonedGroup.clipPath.set({\n rx: clipW / 2,\n ry: clipH / 2,\n });\n } else if (clonedGroup.clipPath instanceof fabric.Rect) {\n clonedGroup.clipPath.set({\n width: clipW,\n height: clipH,\n rx: scaledClipRx,\n ry: scaledClipRx,\n });\n }\n }\n \n // CRITICAL: Always ensure clipPath is configured for export\n if (clonedGroup.clipPath) {\n clonedGroup.clipPath.set({ \n excludeFromExport: false, \n objectCaching: false, \n dirty: true,\n absolutePositioned: false,\n });\n clonedGroup.clipPath.setCoords();\n }\n\n // CRITICAL: Ensure clipPath is properly configured BEFORE setting transforms\n if (clonedGroup.clipPath) {\n // Ensure clipPath is included in export\n clonedGroup.clipPath.set({ \n excludeFromExport: false,\n absolutePositioned: false,\n objectCaching: false,\n dirty: true,\n });\n clonedGroup.clipPath.setCoords();\n }\n\n // When maintainResolution: group is already at export size (clipW x clipH = outW x outH), scale 1.\n // Otherwise: group at frame size, scaled to fill canvas.\n clonedGroup.set({ width: clipW, height: clipH });\n clonedGroup.setCoords();\n\n // Reset transforms in clone-space, then place it in our export canvas\n clonedGroup.set({\n left: outW / 2,\n top: outH / 2,\n originX: 'center',\n originY: 'center',\n scaleX: groupScaleX,\n scaleY: groupScaleY,\n angle: 0,\n skewX: 0,\n skewY: 0,\n flipX: false,\n flipY: false,\n });\n clonedGroup.setCoords();\n \n // CRITICAL: Re-apply clipPath after setting transforms to ensure it's properly associated\n if (clonedGroup.clipPath) {\n clonedGroup.clipPath.setCoords();\n }\n\n // Only replace with blob on retry (forceBlobReplace). New image MUST use natural dimensions, not oldImg's baked (frame) size.\n if (forceBlobReplace && imageUrl && !imageUrl.startsWith('data:') && !imageUrl.startsWith('blob:')) {\n const objects = clonedGroup.getObjects();\n const imgIndex = objects.findIndex((o: fabric.FabricObject) => o instanceof fabric.FabricImage);\n if (imgIndex >= 0) {\n const oldImg = objects[imgIndex] as fabric.FabricImage;\n try {\n // Use urlDims we already fetched at top when forceBlobReplace, else fetch now\n const dims = urlDims ?? (await loadNaturalDimensionsFromUrl(imageUrl));\n const natW = dims?.width ?? stored?.naturalWidth ?? 0;\n const natH = dims?.height ?? stored?.naturalHeight ?? 0;\n const useNatW = natW > 0 && natH > 0 ? natW : frameW;\n const useNatH = natW > 0 && natH > 0 ? natH : frameH;\n\n const proxied = getProxiedImageUrl(imageUrl);\n const res = await fetch(proxied);\n if (!res.ok) {\n // blob fetch failed, fall through to clone path\n } else {\n const blob = await res.blob();\n const blobUrl = URL.createObjectURL(blob);\n try {\n const newImg = await fabric.FabricImage.fromURL(blobUrl, { crossOrigin: 'anonymous' });\n exportNaturalW = useNatW;\n exportNaturalH = useNatH;\n newImg.set({\n width: useNatW,\n height: useNatH,\n left: 0,\n top: 0,\n scaleX: 1,\n scaleY: 1,\n angle: oldImg.angle ?? 0,\n originX: 'center',\n originY: 'center',\n objectCaching: false,\n dirty: true,\n });\n newImg.setCoords();\n clonedGroup.remove(oldImg);\n clonedGroup.insertAt(imgIndex, newImg);\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n }\n } catch (_e) {\n // blob replace failed, clone path continues with existing image\n }\n }\n }\n\n // Reapply cover layout on clone image so export is correct even when Fabric baked dimensions.\n // When maintainResolution the \"frame\" is (outW x outH) so the image covers the full export area.\n const cloneImg = clonedGroup.getObjects().find((o: fabric.FabricObject) => o instanceof fabric.FabricImage) as fabric.FabricImage | undefined;\n if (cloneImg) {\n let natW = exportNaturalW;\n let natH = exportNaturalH;\n if (natW <= 0 || natH <= 0) {\n const el = (cloneImg as any).getElement?.() ?? (cloneImg as any)._element;\n natW = el?.naturalWidth ?? stored?.naturalWidth ?? 0;\n natH = el?.naturalHeight ?? stored?.naturalHeight ?? 0;\n }\n if (natW > 0 && natH > 0) {\n const _ct = (cropData?._img as any)?._ct;\n const panX = Math.max(0, Math.min(1, stored?.panX ?? _ct?.panX ?? 0.5));\n const panY = Math.max(0, Math.min(1, stored?.panY ?? _ct?.panY ?? 0.5));\n const zoom = Math.max(1, stored?.zoom ?? _ct?.zoom ?? 1);\n const layoutW = maintainResolution ? outW : frameW;\n const layoutH = maintainResolution ? outH : frameH;\n const baseScale = Math.max(layoutW / natW, layoutH / natH);\n const finalScale = baseScale * zoom;\n cloneImg.set({\n width: natW,\n height: natH,\n scaleX: finalScale,\n scaleY: finalScale,\n originX: 'center',\n originY: 'center',\n objectCaching: false,\n dirty: true,\n });\n const dispW = natW * finalScale;\n const dispH = natH * finalScale;\n const overflowX = Math.max(0, dispW - layoutW);\n const overflowY = Math.max(0, dispH - layoutH);\n const offsetX = overflowX > 0 ? -overflowX * (panX - 0.5) : 0;\n const offsetY = overflowY > 0 ? -overflowY * (panY - 0.5) : 0;\n cloneImg.set({ left: offsetX, top: offsetY });\n cloneImg.setCoords();\n }\n }\n\n clonedGroup.set({ width: clipW, height: clipH });\n clonedGroup.setCoords();\n\n exportCanvas.add(clonedGroup);\n exportCanvas.renderAll();\n const png = exportCanvas.toDataURL({\n format: 'png',\n multiplier: 1,\n enableRetinaScaling: false,\n });\n exportCanvas.dispose();\n return png;\n}\n\n/**\n * Draw a single element to the PDF.\n * \n * When a live Fabric transform matrix is available (from calcTransformMatrix),\n * we use it directly to get pixel-perfect positioning and rotation matching Fabric exactly.\n * Otherwise we fall back to normalizeElement() calculations.\n */\nasync function drawElement(\n pdf: jsPDF,\n element: CanvasElement,\n embeddedFonts: Set<string>,\n canvasWidth: number,\n canvasHeight: number,\n backgroundColor?: string,\n fabricMatrix?: number[] | null,\n /**\n * When we use a live Fabric transform matrix, we must also use the SAME intrinsic\n * width/height that Fabric used to compute that matrix (especially for images,\n * where the element's stored width/height represent the frame, not the source bitmap).\n */\n fabricIntrinsic?: { w: number; h: number } | null,\n pageId?: string,\n /** When provided, use this Fabric text object's exact line layout for WYSIWYG text export */\n liveFabricText?: fabric.FabricObject | null,\n /** When provided and no fabricMatrix, use getAbsoluteBounds so grouped elements export at correct position/size */\n pageChildren?: CanvasNode[]\n): Promise<void> {\n if (!element.visible) return;\n\n debugLog(`drawElement START id=${element.id} type=${element.type}`);\n const norm = normalizeElement(element);\n if (!fabricMatrix && pageChildren?.length) {\n const node = findNodeById(pageChildren, element.id);\n if (node) {\n const abs = getAbsoluteBounds(node, pageChildren);\n (norm as { x: number; y: number; w: number; h: number }).x = abs.left;\n (norm as { x: number; y: number; w: number; h: number }).y = abs.top;\n (norm as { x: number; y: number; w: number; h: number }).w = abs.width;\n (norm as { x: number; y: number; w: number; h: number }).h = abs.height;\n }\n }\n\n // ✅ Smart Element SVG regeneration — use the SAME shared renderer as the server\n // This ensures QR codes, ratings, tables, badges etc. produce identical SVGs\n // on both client and server, eliminating rendering drift.\n if (element.smartElementType && element.smartProps && norm.w > 0 && norm.h > 0) {\n const propsWithFont = {\n ...element.smartProps,\n fontFamily: element.smartProps.fontFamily || (element as any).fontFamily || 'sans-serif',\n };\n const freshSvg = renderSmartElementToSvg(element.smartElementType, propsWithFont, norm.w, norm.h);\n if (freshSvg) {\n // Overwrite the stale data URI with a freshly-rendered SVG\n element = {\n ...element,\n sourceFormat: 'svg',\n src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(freshSvg)}`,\n imageUrl: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(freshSvg)}`,\n };\n // Re-normalize with updated src\n Object.assign(norm, { imageUrl: element.src });\n debugLog(`Smart element regenerated: type=${element.smartElementType} id=${element.id}`);\n }\n }\n\n // ✅ EARLY: if this element is a live crop-group, rasterize it (with clip) and draw that PNG instead\n if (element.type === 'image' && pageId) {\n const liveCanvas = getCanvasForPage(pageId);\n if (liveCanvas) {\n const liveGroup = liveCanvas.getObjects().find(\n (obj) => (obj as any).__docuforgeId === element.id && (obj as any).__cropGroup\n ) as fabric.Group | undefined;\n\n if (liveGroup) {\n const cropData = (liveGroup as any).__cropData;\n const frameW = cropData?.frameW || liveGroup.width || norm.w;\n const frameH = cropData?.frameH || liveGroup.height || norm.h;\n const shape = cropData?.shape || 'rect';\n const rx = cropData?.rx || 0;\n // Check maintainResolution from element - only maintain if explicitly true\n // If undefined, default to true (checked by default)\n // If false, don't maintain resolution\n const maintainResolution = element.maintainResolution !== false;\n \n // Get natural image dimensions if maintainResolution is enabled\n let exportMultiplier = 2; // Default multiplier\n let exportFrameW = frameW;\n let exportFrameH = frameH;\n \n // Only maintain resolution if maintainResolution is true (checkbox is checked)\n if (maintainResolution) {\n let img = cropData?._img;\n if (!img || (typeof (img as any).getElement !== 'function' && !(img as any)._element)) {\n const objects = liveGroup.getObjects();\n img = objects.find((o: fabric.FabricObject) => o instanceof fabric.FabricImage || (o as any).getElement) as fabric.FabricImage | undefined;\n }\n if (img && (typeof (img as any).getElement === 'function' || (img as any)._element)) {\n const orig = typeof (img as any).getOriginalSize === 'function' ? (img as any).getOriginalSize() : null;\n const htmlImg = orig ? null : (typeof (img as any).getElement === 'function' ? (img as any).getElement() : (img as any)._element);\n const naturalWidth = (orig?.width ?? htmlImg?.naturalWidth ?? (img as any).width) || frameW;\n const naturalHeight = (orig?.height ?? htmlImg?.naturalHeight ?? (img as any).height) || frameH;\n const scaleX = naturalWidth / frameW;\n const scaleY = naturalHeight / frameH;\n exportMultiplier = Math.max(scaleX, scaleY, 2);\n exportFrameW = naturalWidth;\n exportFrameH = naturalHeight;\n }\n }\n\n const imageUrlForRaster = element.src || element.imageUrl || (liveGroup as any).__imageSrc;\n const isSvgSource = element.sourceFormat === 'svg' || (imageUrlForRaster && imageUrlForRaster.toLowerCase().includes('.svg'));\n if (isSvgSource) {\n exportMultiplier = Math.max(exportMultiplier, 4);\n }\n\n // SVG images: always use vector path (with clip for crop)\n // Edge fade requires raster; skip vector when fade is active so the\n // baked PNG carries the per-side feather.\n const canVectorizeSvg = isSvgSource && !!imageUrlForRaster && !elementHasFade(element);\n if (canVectorizeSvg) {\n const svgEl = await fetchSvgAsElement(imageUrlForRaster, element.svgColorMap);\n if (svgEl) {\n expandSvgUseElements(svgEl, element.id);\n const svgToDraw = normalizeSvgExplicitColors(svgEl);\n inlineComputedStyles(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n resolveSvgGradientRefsToSolid(svgToDraw, element.id);\n prefixSvgIds(svgToDraw, element.id);\n bakeGroupOpacityIntoChildren(svgToDraw);\n injectOpacityIntoSvg(svgToDraw, norm.opacity);\n try {\n const anyPdf = pdf as any;\n const canUseAdvancedTransforms =\n typeof anyPdf.advancedAPI === 'function' &&\n typeof anyPdf.setCurrentTransformationMatrix === 'function' &&\n typeof anyPdf.Matrix === 'function';\n // For vector SVGs, opacity is baked into SVG paint attributes\n // via injectOpacityIntoSvg(), so keep PDF GState neutral.\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n\n // Compute crop zoom/pan offsets for SVG draw area\n const cropZoomVal = cropData ? Math.max(1, (cropData._img as any)?._ct?.zoom ?? (element as any).cropZoom ?? 1) : 1;\n const cropPanXVal = cropData ? Math.max(0, Math.min(1, (cropData._img as any)?._ct?.panX ?? (element as any).cropPanX ?? 0.5)) : 0.5;\n const cropPanYVal = cropData ? Math.max(0, Math.min(1, (cropData._img as any)?._ct?.panY ?? (element as any).cropPanY ?? 0.5)) : 0.5;\n\n const naturalW = Math.max(1, Number((element as any).imageNaturalWidth ?? 0) || Number((cropData?._img as any)?.width ?? 0) || frameW);\n const naturalH = Math.max(1, Number((element as any).imageNaturalHeight ?? 0) || Number((cropData?._img as any)?.height ?? 0) || frameH);\n const fitContain = ((cropData as any)?.fit ?? (element as any).imageFit ?? 'cover') === 'contain';\n\n // Helper: given a clip rect (frame), compute the zoomed/panned SVG draw rect\n // using the same cover/contain math as canvas crop groups.\n const cropSvgRect = (clipX: number, clipY: number, clipW: number, clipH: number) => {\n const baseScale = fitContain ? Math.min(clipW / naturalW, clipH / naturalH) : Math.max(clipW / naturalW, clipH / naturalH);\n const finalScale = baseScale * (fitContain ? 1 : cropZoomVal);\n const drawW = naturalW * finalScale;\n const drawH = naturalH * finalScale;\n const overflowX = Math.max(0, drawW - clipW);\n const overflowY = Math.max(0, drawH - clipH);\n const offX = overflowX > 0 ? -overflowX * (cropPanXVal - 0.5) : 0;\n const offY = overflowY > 0 ? -overflowY * (cropPanYVal - 0.5) : 0;\n return {\n x: clipX + clipW / 2 + offX - drawW / 2,\n y: clipY + clipH / 2 + offY - drawH / 2,\n width: drawW,\n height: drawH,\n };\n };\n\n const localX = -frameW / 2;\n const localY = -frameH / 2;\n if (canUseAdvancedTransforms && fabricMatrix && fabricMatrix.length === 6) {\n const mPdf = fabricMatrixToJsPdfAdvancedMatrix(fabricMatrix, canvasHeight);\n const axisFrame = getAxisAlignedSvgFrameFromMatrix(mPdf, localX, localY, frameW, frameH);\n if (axisFrame) {\n const svgDrawRect = cropSvgRect(axisFrame.x, axisFrame.y, axisFrame.width, axisFrame.height);\n // Axis-aligned frame: draw directly in page space to avoid CTM flip/drift issues.\n const seq = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq} elementId=${element.id} path=cropGroup-axis`);\n resetPdfColorState(pdf, `before save #${seq} ${element.id}`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq} ${element.id}`);\n pdf.setLineWidth(0);\n pdf.rect(axisFrame.x, axisFrame.y, axisFrame.width, axisFrame.height, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n const pdfToUse = pdfWithColorLogging(pdf, seq, element.id);\n await svg2pdfWithDomMount(svgToDraw, pdfToUse, svg2pdfOpts(svgDrawRect.x, svgDrawRect.y, svgDrawRect.width, svgDrawRect.height));\n debugLog(`svg2pdf DONE #${seq} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq} ${element.id}`);\n } else {\n const transformed = buildMatrixTransformedSvgForPage(svgToDraw, mPdf, localX, localY, frameW, frameH);\n if (transformed) {\n const seq = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq} elementId=${element.id} path=cropGroup-matrix-wrapper`);\n resetPdfColorState(pdf, `before save #${seq} ${element.id} matrix-wrapper`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq} ${element.id}`);\n pdf.setLineWidth(0);\n pdf.rect(transformed.frame.x, transformed.frame.y, transformed.frame.width, transformed.frame.height, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq} ${element.id}`);\n setPdfColorFromSvg(pdf, transformed.svg, element.id);\n const tfCropRect = cropSvgRect(transformed.frame.x, transformed.frame.y, transformed.frame.width, transformed.frame.height);\n await svg2pdfWithDomMount(\n transformed.svg,\n pdfWithColorLogging(pdf, seq, element.id),\n svg2pdfOpts(tfCropRect.x, tfCropRect.y, tfCropRect.width, tfCropRect.height)\n );\n debugLog(`svg2pdf DONE #${seq} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq} ${element.id}`);\n } else {\n const pdfForSvg = new Proxy(pdf, {\n get(target, prop) {\n if (prop === 'advancedAPI') return () => {};\n return (target as any)[prop];\n },\n });\n await new Promise<void>((resolve, reject) => {\n anyPdf.advancedAPI(async () => {\n try {\n const seq = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq} elementId=${element.id} path=cropGroup-matrix-fallback`);\n resetPdfColorState(pdf, `before save #${seq} ${element.id} matrix`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq} ${element.id}`);\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n pdf.setLineWidth(0);\n pdf.rect(localX, localY, frameW, frameH, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n const mfCropRect = cropSvgRect(localX, localY, frameW, frameH);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq, element.id), svg2pdfOpts(mfCropRect.x, mfCropRect.y, mfCropRect.width, mfCropRect.height));\n debugLog(`svg2pdf DONE #${seq} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq} ${element.id}`);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n });\n }\n }\n } else {\n const angle = norm.angle ?? 0;\n const hasRotation = Math.abs(angle) > 0.01;\n const cx = norm.x + frameW / 2;\n const cy = norm.y + frameH / 2;\n if (hasRotation && canUseAdvancedTransforms) {\n const rad = (angle * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const computedM: Matrix6 = [cos, sin, -sin, cos, cx, cy];\n const localX2 = -frameW / 2;\n const localY2 = -frameH / 2;\n const pdfForSvg = new Proxy(pdf, {\n get(target, prop) {\n if (prop === 'advancedAPI') return () => {};\n return (target as any)[prop];\n },\n });\n await new Promise<void>((resolve, reject) => {\n anyPdf.advancedAPI(async () => {\n try {\n const seq2 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq2} elementId=${element.id} path=cropGroup-rotation`);\n resetPdfColorState(pdf, `before save #${seq2} ${element.id} rotation`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq2} ${element.id}`);\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...computedM));\n pdf.setLineWidth(0);\n pdf.rect(localX2, localY2, frameW, frameH, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq2} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n const rotCropRect = cropSvgRect(localX2, localY2, frameW, frameH);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq2, element.id), svg2pdfOpts(rotCropRect.x, rotCropRect.y, rotCropRect.width, rotCropRect.height));\n debugLog(`svg2pdf DONE #${seq2} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq2} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq2} ${element.id}`);\n resolve();\n } catch (e) {\n reject(e);\n }\n });\n });\n } else {\n const seq3 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq3} elementId=${element.id} path=cropGroup-norm`);\n resetPdfColorState(pdf, `before save #${seq3} ${element.id} norm`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `after save #${seq3} ${element.id}`);\n pdf.setLineWidth(0);\n pdf.rect(norm.x, norm.y, frameW, frameH, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq3} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n const normCropRect = cropSvgRect(norm.x, norm.y, frameW, frameH);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq3, element.id), svg2pdfOpts(normCropRect.x, normCropRect.y, normCropRect.width, normCropRect.height));\n debugLog(`svg2pdf DONE #${seq3} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq3} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq3} ${element.id}`);\n }\n }\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n return;\n } catch {\n // Fall through to raster path\n }\n }\n }\n\n const storedCrop: StoredCropExportInfo | undefined =\n (element as any).imageNaturalWidth != null && (element as any).imageNaturalHeight != null\n ? {\n naturalWidth: (element as any).imageNaturalWidth,\n naturalHeight: (element as any).imageNaturalHeight,\n panX: (element as any).cropPanX,\n panY: (element as any).cropPanY,\n zoom: (element as any).cropZoom,\n }\n : undefined;\n let png: string;\n try {\n png = await rasterizeCropGroupToPng(liveGroup, frameW, frameH, exportMultiplier, maintainResolution, imageUrlForRaster, false, storedCrop, backgroundColor);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isTainted = msg.includes('Tainted canvases') || (err as Error)?.name === 'SecurityError';\n if (isTainted && imageUrlForRaster && !imageUrlForRaster.startsWith('data:') && !imageUrlForRaster.startsWith('blob:')) {\n png = await rasterizeCropGroupToPng(liveGroup, frameW, frameH, exportMultiplier, maintainResolution, imageUrlForRaster, true, storedCrop, backgroundColor);\n } else {\n throw err;\n }\n }\n\n // If we have a matrix, draw the raster INSIDE the matrix (so rotation/scale matches perfectly)\n const anyPdf = pdf as any;\n const canUseAdvancedTransforms =\n typeof anyPdf.advancedAPI === 'function' &&\n typeof anyPdf.setCurrentTransformationMatrix === 'function' &&\n typeof anyPdf.Matrix === 'function';\n\n // Apply element opacity so export matches editor (rasterized PNG may not always bake group opacity correctly)\n const clampedOpacity = Math.max(0, Math.min(1, norm.opacity));\n pdf.setGState(pdf.GState({ opacity: clampedOpacity }));\n\n // Ensure we have valid PNG data for jsPDF (avoids corrupt/small image in PDF)\n if (!png || typeof png !== 'string' || !png.startsWith('data:image/') || png.length < 200) {\n return;\n }\n\n // Bake edge fade into the rasterized crop PNG so masked images keep\n // the same per-side fade visible in the editor.\n const fadedMasked = await bakeEdgeFadeIntoDataUrl(png, element);\n if (fadedMasked) {\n png = fadedMasked;\n }\n\n if (canUseAdvancedTransforms && fabricMatrix && fabricMatrix.length === 6) {\n const mPdf = fabricMatrixToJsPdfAdvancedMatrix(fabricMatrix, canvasHeight);\n const localX = -frameW / 2;\n const localY = -frameH / 2;\n anyPdf.advancedAPI(() => {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n\n // local origin is center; draw at frame size so PDF matches canvas frame\n pdf.addImage(png, 'PNG', localX, localY, frameW, frameH, undefined, 'SLOW');\n pdf.restoreGraphicsState();\n });\n \n // CRITICAL: Reset opacity to 1.0 after drawing masked image to avoid affecting subsequent elements\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n\n return; // ✅ done\n }\n\n // No matrix path: draw at element position with frame size (same as matrix path)\n pdf.addImage(png, 'PNG', norm.x, norm.y, frameW, frameH, undefined, 'SLOW');\n \n // CRITICAL: Reset opacity to 1.0 after drawing masked image to avoid affecting subsequent elements\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n \n return; // ✅ done\n }\n }\n }\n\n // CRITICAL: Always set opacity explicitly (even if 1.0) to ensure previous opacity state is cleared\n // Clamp opacity to valid range [0, 1]. For vector SVG image paths, opacity is baked\n // into SVG attributes (injectOpacityIntoSvg), so avoid double-application.\n const clampedOpacity = Math.max(0, Math.min(1, norm.opacity));\n const isSvgImageElement = element.type === 'image' && (\n element.sourceFormat === 'svg' ||\n ((norm.imageUrl || '').toLowerCase().includes('.svg')) ||\n (norm.imageUrl || '').startsWith('data:image/svg+xml')\n );\n pdf.setGState(pdf.GState({ opacity: isSvgImageElement ? 1 : clampedOpacity, 'stroke-opacity': isSvgImageElement ? 1 : clampedOpacity }));\n\n const { angle } = norm;\n const hasRotation = Math.abs(angle) > 0.01;\n\n const intrinsicW = (fabricIntrinsic?.w ?? 0) > 0 ? fabricIntrinsic!.w : (element.width ?? norm.w);\n const intrinsicH = (fabricIntrinsic?.h ?? 0) > 0 ? fabricIntrinsic!.h : (element.height ?? norm.h);\n\n const scaleX = element.scaleX ?? 1;\n const scaleY = element.scaleY ?? 1;\n\n // Visual size (what user sees on canvas)\n const visualW = intrinsicW * scaleX;\n const visualH = intrinsicH * scaleY;\n\n const anyPdf = pdf as any;\n const canUseAdvancedTransforms =\n typeof anyPdf.advancedAPI === 'function' &&\n typeof anyPdf.setCurrentTransformationMatrix === 'function' &&\n typeof anyPdf.Matrix === 'function';\n\n const drawWithMatrixAdvanced = async (fabricM: number[]) => {\n const mPdf = fabricMatrixToJsPdfAdvancedMatrix(fabricM, canvasHeight);\n\n // For images we must fetch bytes first (async), then draw inside advancedAPI.\n if (element.type === 'image') {\n const imageUrl = norm.imageUrl;\n if (!imageUrl) return;\n\n const isSvg = element.sourceFormat === 'svg' || (imageUrl && imageUrl.toLowerCase().includes('.svg'));\n // Edge-fade requires raster (alpha mask), so skip vector embed when fade is active.\n const canVectorizeSvg = isSvg && !elementHasFade(element);\n if (canVectorizeSvg) {\n const svgElement = await fetchSvgAsElement(imageUrl, element.svgColorMap);\n if (svgElement) {\n expandSvgUseElements(svgElement, element.id);\n const svgToDraw = normalizeSvgExplicitColors(svgElement);\n inlineComputedStyles(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n resolveSvgGradientRefsToSolid(svgToDraw, element.id);\n prefixSvgIds(svgToDraw, element.id);\n bakeGroupOpacityIntoChildren(svgToDraw);\n injectOpacityIntoSvg(svgToDraw, norm.opacity);\n try {\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n const axisFrame = getAxisAlignedSvgFrameFromMatrix(mPdf, localX, localY, intrinsicW, intrinsicH);\n const seq4 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq4} elementId=${element.id} path=${axisFrame ? 'drawContentCore-image-axis' : 'drawContentCore-image-matrix'}`);\n resetPdfColorState(pdf, `before setPdfColor #${seq4} ${element.id}`);\n\n if (axisFrame) {\n pdf.saveGraphicsState();\n pdf.setLineWidth(0);\n pdf.rect(axisFrame.x, axisFrame.y, axisFrame.width, axisFrame.height, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq4} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n await svg2pdfWithDomMount(\n svgToDraw,\n pdfWithColorLogging(pdf, seq4, element.id),\n svg2pdfOpts(axisFrame.x, axisFrame.y, axisFrame.width, axisFrame.height)\n );\n\n debugLog(`svg2pdf DONE #${seq4} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq4} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq4} ${element.id}`);\n } else {\n const transformed = buildMatrixTransformedSvgForPage(svgToDraw, mPdf, localX, localY, intrinsicW, intrinsicH);\n if (transformed) {\n pdf.saveGraphicsState();\n pdf.setLineWidth(0);\n pdf.rect(transformed.frame.x, transformed.frame.y, transformed.frame.width, transformed.frame.height, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq4} ${element.id}`);\n setPdfColorFromSvg(pdf, transformed.svg, element.id);\n await svg2pdfWithDomMount(\n transformed.svg,\n pdfWithColorLogging(pdf, seq4, element.id),\n svg2pdfOpts(transformed.frame.x, transformed.frame.y, transformed.frame.width, transformed.frame.height)\n );\n debugLog(`svg2pdf DONE #${seq4} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq4} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq4} ${element.id}`);\n } else {\n await new Promise<void>((resolve, reject) => {\n anyPdf.advancedAPI(async () => {\n try {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq4} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq4, element.id), svg2pdfOpts(localX, localY, intrinsicW, intrinsicH));\n debugLog(`svg2pdf DONE #${seq4} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq4} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq4} ${element.id}`);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n });\n }\n }\n } catch {\n const imageData = await fetchImageAsBase64(imageUrl, {\n backgroundColor,\n targetWidthPt: visualW,\n targetHeightPt: visualH,\n preserveAlpha: isSvg || (visualW > canvasWidth * 0.7 && visualH > canvasHeight * 0.7),\n resolutionMultiplier: 4,\n });\n if (imageData) {\n const fadedAdv = await bakeEdgeFadeIntoDataUrl(imageData.data, element);\n if (fadedAdv) {\n imageData.data = fadedAdv;\n imageData.format = 'PNG';\n }\n anyPdf.advancedAPI(() => {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n pdf.addImage(imageData.data, imageData.format, localX, localY, intrinsicW, intrinsicH, undefined, 'SLOW');\n pdf.restoreGraphicsState();\n });\n }\n }\n return;\n }\n }\n\n const preserveAlpha = isSvg || (visualW > canvasWidth * 0.7 && visualH > canvasHeight * 0.7);\n const imageData = await fetchImageAsBase64(imageUrl, {\n backgroundColor,\n targetWidthPt: visualW,\n targetHeightPt: visualH,\n preserveAlpha: preserveAlpha || elementHasFade(element),\n resolutionMultiplier: isSvg ? 4 : undefined,\n });\n if (!imageData) return;\n const fadedMain = await bakeEdgeFadeIntoDataUrl(imageData.data, element);\n if (fadedMain) {\n imageData.data = fadedMain;\n imageData.format = 'PNG';\n }\n\n anyPdf.advancedAPI(() => {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n pdf.addImage(imageData.data, imageData.format, localX, localY, intrinsicW, intrinsicH, undefined, 'SLOW');\n pdf.restoreGraphicsState();\n });\n\n return;\n }\n\n // Non-images: draw synchronously inside advancedAPI.\n anyPdf.advancedAPI(() => {\n pdf.saveGraphicsState();\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...mPdf));\n\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n const normForMatrix = withCompensatedStrokeWidth(norm, element, fabricM);\n\n // This is safe: for non-image element types, drawElementContentCore performs no awaits.\n void drawElementContentCore(\n pdf,\n element,\n normForMatrix,\n localX,\n localY,\n intrinsicW,\n intrinsicH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n 1.0,\n liveFabricText ?? undefined\n );\n\n pdf.restoreGraphicsState();\n });\n };\n\n const hasIndividualRoundedCorners =\n element.type === 'shape' &&\n norm.shapeType === 'rounded-rect' &&\n (norm.rxTL != null || norm.rxTR != null || norm.rxBR != null || norm.rxBL != null);\n const hasNonIdentityScale = Math.abs(scaleX - 1) > 0.0001 || Math.abs(scaleY - 1) > 0.0001;\n const hasSkew = Math.abs(norm.skewX) > 0.01 || Math.abs(norm.skewY) > 0.01;\n const hasLiveFabricMatrix = !!(fabricMatrix && fabricMatrix.length === 6);\n\n // Rounded-rect with custom corners relies on jsPDF path(); draw in page space only for truly static elements.\n // If a live matrix exists (group transforms, matrix-normalized objects), always use the matrix path.\n const canDrawRoundedRectInPageSpace =\n hasIndividualRoundedCorners &&\n !hasLiveFabricMatrix &&\n !hasNonIdentityScale &&\n !hasRotation &&\n !hasSkew &&\n !(element.flipX ?? false) &&\n !(element.flipY ?? false);\n\n if (canDrawRoundedRectInPageSpace) {\n await drawElementContent(\n pdf,\n element,\n norm,\n norm.x,\n norm.y,\n visualW,\n visualH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n scaleY,\n liveFabricText ?? undefined\n );\n\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n\n const linkUrl = element.linkConfig?.url;\n if (linkUrl) {\n addLinkAnnotation(pdf, linkUrl, norm.x, norm.y, visualW, visualH, canvasHeight);\n }\n\n debugLog(`drawElement END id=${element.id}`);\n return;\n }\n\n // Prefer live Fabric matrix when available (pixel-perfect + correct rotation direction)\n if (canUseAdvancedTransforms && fabricMatrix && fabricMatrix.length === 6) {\n await drawWithMatrixAdvanced(fabricMatrix);\n } else if (canUseAdvancedTransforms && hasIndividualRoundedCorners && hasNonIdentityScale) {\n // Force matrix path for scaled rounded-rect paths so corner geometry + stroke match Fabric exactly.\n const cx = norm.x + visualW / 2;\n const cy = norm.y + visualH / 2;\n const computedFabricM: number[] = [scaleX, 0, 0, scaleY, cx, cy];\n await drawWithMatrixAdvanced(computedFabricM);\n } else if (canUseAdvancedTransforms && hasRotation) {\n // No live matrix, compute equivalent Fabric-style matrix (y-down), then convert.\n const cx = norm.x + visualW / 2;\n const cy = norm.y + visualH / 2;\n const radians = (angle * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n\n const computedFabricM: number[] = [\n scaleX * cos,\n scaleX * sin,\n -scaleY * sin,\n scaleY * cos,\n cx,\n cy,\n ];\n\n await drawWithMatrixAdvanced(computedFabricM);\n } else if (fabricMatrix && fabricMatrix.length === 6) {\n // Fallback (no advanced API): apply the matrix directly (may differ by jsPDF version).\n pdf.saveGraphicsState();\n if (typeof anyPdf.setCurrentTransformationMatrix === 'function' && typeof anyPdf.Matrix === 'function') {\n const [a, b, c, d, e, f] = fabricMatrix;\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(a, b, c, d, e, f));\n }\n\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n const normForMatrix = withCompensatedStrokeWidth(norm, element, fabricMatrix);\n await drawElementContentWithIntrinsic(\n pdf,\n element,\n normForMatrix,\n localX,\n localY,\n intrinsicW,\n intrinsicH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n liveFabricText ?? undefined\n );\n pdf.restoreGraphicsState();\n } else if (hasRotation) {\n // Fallback rotation (no advanced transforms)\n const cx = norm.x + visualW / 2;\n const cy = norm.y + visualH / 2;\n const radians = (angle * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const computedMatrix: Matrix6 = [scaleX * cos, scaleX * sin, -scaleY * sin, scaleY * cos, cx, cy];\n\n pdf.saveGraphicsState();\n if (typeof anyPdf.setCurrentTransformationMatrix === 'function' && typeof anyPdf.Matrix === 'function') {\n anyPdf.setCurrentTransformationMatrix(anyPdf.Matrix(...computedMatrix));\n }\n\n const localX = -intrinsicW / 2;\n const localY = -intrinsicH / 2;\n const normForMatrix = withCompensatedStrokeWidth(norm, element, computedMatrix);\n await drawElementContentWithIntrinsic(\n pdf,\n element,\n normForMatrix,\n localX,\n localY,\n intrinsicW,\n intrinsicH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n liveFabricText ?? undefined\n );\n\n pdf.restoreGraphicsState();\n } else {\n // No rotation - draw directly at computed position with visual size\n // Pass scaleY as fontScale since dimensions are pre-scaled but fontSize isn't\n await drawElementContent(\n pdf,\n element,\n norm,\n norm.x,\n norm.y,\n visualW,\n visualH,\n embeddedFonts,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n scaleY,\n liveFabricText ?? undefined\n );\n }\n\n // CRITICAL: Always reset opacity to 1.0 after drawing element to avoid affecting subsequent elements\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n \n // Add link annotation if element has a link\n const linkUrl = element.linkConfig?.url;\n if (linkUrl) {\n addLinkAnnotation(pdf, linkUrl, norm.x, norm.y, visualW, visualH, canvasHeight);\n }\n debugLog(`drawElement END id=${element.id}`);\n}\n\n/**\n * Draw the actual content of an element at the given position (uses visual w/h)\n */\nasync function drawElementContent(\n pdf: jsPDF,\n element: CanvasElement,\n norm: ReturnType<typeof normalizeElement>,\n x: number,\n y: number,\n w: number,\n h: number,\n embeddedFonts: Set<string>,\n canvasWidth: number,\n canvasHeight: number,\n backgroundColor?: string,\n fontScale: number = 1.0,\n liveFabricText?: fabric.FabricObject | null\n): Promise<void> {\n await drawElementContentCore(pdf, element, norm, x, y, w, h, embeddedFonts, canvasWidth, canvasHeight, backgroundColor, fontScale, liveFabricText);\n}\n\n/**\n * Draw element content using intrinsic dimensions (for transformed contexts where scale is in the matrix)\n * fontScale is 1.0 because the transformation matrix handles scaling\n */\nasync function drawElementContentWithIntrinsic(\n pdf: jsPDF,\n element: CanvasElement,\n norm: ReturnType<typeof normalizeElement>,\n x: number,\n y: number,\n intrinsicW: number,\n intrinsicH: number,\n embeddedFonts: Set<string>,\n canvasWidth: number,\n canvasHeight: number,\n backgroundColor?: string,\n liveFabricText?: fabric.FabricObject | null\n): Promise<void> {\n await drawElementContentCore(pdf, element, norm, x, y, intrinsicW, intrinsicH, embeddedFonts, canvasWidth, canvasHeight, backgroundColor, 1.0, liveFabricText);\n}\n\n/**\n * Core drawing logic for element content\n * @param fontScale - Scale factor to apply to fontSize (1.0 when transforms handle scaling, scaleY when no transforms)\n */\nasync function drawElementContentCore(\n pdf: jsPDF,\n element: CanvasElement,\n norm: ReturnType<typeof normalizeElement>,\n x: number,\n y: number,\n w: number,\n h: number,\n embeddedFonts: Set<string>,\n canvasWidth: number,\n canvasHeight: number,\n backgroundColor?: string,\n fontScale: number = 1.0,\n liveFabricText?: fabric.FabricObject | null\n): Promise<void> {\n switch (element.type) {\n case 'shape': {\n const { shapeType, fill, stroke, strokeWidth, borderRadius, rxTL, rxTR, rxBR, rxBL } = norm;\n const canonicalShape = normalizeShapeType(shapeType);\n\n if (canonicalShape === 'rounded-rect') {\n drawRect(pdf, x, y, w, h, fill, stroke, strokeWidth, borderRadius, rxTL, rxTR, rxBR, rxBL);\n } else if (canonicalShape === 'circle') {\n const diameter = Math.max(1, Math.min(w, h));\n drawEllipse(pdf, x + diameter / 2, y + diameter / 2, diameter / 2, diameter / 2, fill, stroke, strokeWidth);\n } else if (canonicalShape === 'triangle') {\n const rTop = Math.max(0, Number(norm.triRTop ?? 0));\n const rBR = Math.max(0, Number(norm.triRBR ?? 0));\n const rBL = Math.max(0, Number(norm.triRBL ?? 0));\n const hasRounding = rTop > 0 || rBR > 0 || rBL > 0;\n\n if (hasRounding) {\n // Draw rounded triangle using path\n const pathStr = buildRoundedTrianglePath(w, h, rTop, rBR, rBL);\n drawRoundedTrianglePdf(pdf, x, y, w, h, pathStr, fill, stroke, strokeWidth);\n } else {\n const points = getTrianglePoints(x, y, w, h);\n drawPolygon(pdf, points, fill, stroke, strokeWidth);\n }\n } else {\n const points = getShapePoints(shapeType, x, y, w, h);\n if (points) {\n drawPolygon(pdf, points, fill, stroke, strokeWidth);\n }\n }\n break;\n }\n\n case 'line': {\n const { stroke, strokeWidth, strokeDashArray } = norm;\n drawLine(pdf, x, y, x + w, y, stroke, strokeWidth || 2, strokeDashArray);\n break;\n }\n\n case 'text': {\n const { text: originalText, fontSize, fontFamily, fontWeight, fontStyle, underline, letterSpacing, fill, textAlign, lineHeight, splitByGrapheme } = norm;\n const overflowPolicy = element.overflowPolicy || 'grow-and-push';\n const minFontSize = (element.minFontSize || 8) * fontScale;\n const maxLines = element.maxLines || 3;\n const effectiveSplitByGrapheme = overflowPolicy === 'auto-shrink' ? false : splitByGrapheme;\n \n let finalText = originalText;\n let finalFontSize = fontSize * fontScale;\n \n // For auto-shrink: keep width fixed, avoid implicit wrapping, and reduce font size until it fits.\n if (overflowPolicy === 'auto-shrink') {\n const explicitLineCount = Math.max(1, finalText.split('\\n').length);\n const measureWidth = Math.max(1, w / PX_TO_PT);\n while (finalFontSize > 1) {\n const testTextbox = new fabric.Textbox(finalText, {\n width: measureWidth,\n fontSize: finalFontSize / PX_TO_PT,\n fontFamily,\n fontWeight,\n fontStyle,\n lineHeight: lineHeight || 1.2,\n charSpacing: letterSpacing || 0,\n splitByGrapheme: false,\n });\n testTextbox.initDimensions();\n \n const textHeight = (testTextbox.height || 0) * PX_TO_PT;\n const renderedLineCount = testTextbox.textLines?.length || 1;\n const hasNoImplicitWrap = renderedLineCount <= explicitLineCount;\n const fitsHeight = h <= 0 || textHeight <= h;\n // Also check that no line overflows the fixed width (single long word case)\n const actualTextboxWidth = testTextbox.width ?? measureWidth;\n const widthDidGrow = actualTextboxWidth > measureWidth + 0.5;\n const lineWidths = (testTextbox as any).__lineWidths as number[] | undefined;\n const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;\n const fitsWidth = !widthDidGrow && maxLineWidth <= measureWidth + 1;\n\n if (hasNoImplicitWrap && fitsHeight && fitsWidth) {\n break;\n }\n finalFontSize--;\n }\n }\n \n // For max-lines-ellipsis: truncate text\n if (overflowPolicy === 'max-lines-ellipsis') {\n const testTextbox = new fabric.Textbox(originalText, {\n width: w / PX_TO_PT,\n fontSize: finalFontSize / PX_TO_PT,\n fontFamily,\n lineHeight: lineHeight || 1.2,\n splitByGrapheme: effectiveSplitByGrapheme,\n });\n testTextbox.initDimensions();\n \n const lines = testTextbox.textLines || [];\n if (lines.length > maxLines) {\n // Helper to count lines for a given text\n const countLines = (testText: string): number => {\n const tb = new fabric.Textbox(testText, {\n width: w / PX_TO_PT,\n fontSize: finalFontSize / PX_TO_PT,\n fontFamily,\n lineHeight: lineHeight || 1.2,\n splitByGrapheme: effectiveSplitByGrapheme,\n });\n tb.initDimensions();\n return tb.textLines?.length || 1;\n };\n \n // Binary search for the right cutoff point\n let low = 0;\n let high = originalText.length;\n let result = originalText;\n \n while (low < high) {\n const mid = Math.floor((low + high + 1) / 2);\n const testText = originalText.slice(0, mid) + '...';\n const lineCount = countLines(testText);\n \n if (lineCount <= maxLines) {\n low = mid;\n result = testText;\n } else {\n high = mid - 1;\n }\n }\n \n // Trim trailing spaces before ellipsis\n if (result.endsWith('...') && result.length > 3) {\n const beforeEllipsis = result.slice(0, -3).trimEnd();\n result = beforeEllipsis + '...';\n }\n \n finalText = result;\n }\n }\n \n drawText(pdf, finalText, x, y, w, finalFontSize, fontFamily, fontWeight, fontStyle, underline, letterSpacing, fill, textAlign, lineHeight, embeddedFonts, effectiveSplitByGrapheme, liveFabricText);\n break;\n }\n\n case 'image': {\n // Regular image export (masked images are handled early in drawElement())\n const { imageUrl } = norm;\n if (imageUrl) {\n const isSvg = element.sourceFormat === 'svg' || imageUrl.toLowerCase().includes('.svg');\n\n // Fallback crop path (when live crop-group isn't available):\n // use stored crop pan/zoom + frame clipping from element data.\n const hasStoredCrop = Boolean(\n (element as any).useCropHandles ||\n (element as any).cropZoom != null ||\n (element as any).cropPanX != null ||\n (element as any).cropPanY != null\n );\n\n // For SVGs with crop: use vector embed with PDF clip rect (no rasterization)\n if (hasStoredCrop && isSvg && !elementHasFade(element)) {\n const svgElement = await fetchSvgAsElement(imageUrl, element.svgColorMap);\n if (svgElement) {\n expandSvgUseElements(svgElement, element.id);\n const svgToDraw = normalizeSvgExplicitColors(svgElement);\n inlineComputedStyles(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n resolveSvgGradientRefsToSolid(svgToDraw, element.id);\n prefixSvgIds(svgToDraw, element.id);\n bakeGroupOpacityIntoChildren(svgToDraw);\n injectOpacityIntoSvg(svgToDraw, norm.opacity);\n\n const cropZoom = Math.max(1, Number((element as any).cropZoom ?? 1));\n const cropPanX = Math.max(0, Math.min(1, Number((element as any).cropPanX ?? 0.5)));\n const cropPanY = Math.max(0, Math.min(1, Number((element as any).cropPanY ?? 0.5)));\n const naturalW = Math.max(1, Number((element as any).imageNaturalWidth ?? 0) || w);\n const naturalH = Math.max(1, Number((element as any).imageNaturalHeight ?? 0) || h);\n const fitContain = ((element as any).imageFit ?? 'cover') === 'contain';\n const baseScale = fitContain ? Math.min(w / naturalW, h / naturalH) : Math.max(w / naturalW, h / naturalH);\n const finalScale = baseScale * (fitContain ? 1 : cropZoom);\n\n // Draw SVG at zoomed size, offset by pan, clipped to frame\n const drawW = naturalW * finalScale;\n const drawH = naturalH * finalScale;\n const overflowX = Math.max(0, drawW - w);\n const overflowY = Math.max(0, drawH - h);\n const offsetX = overflowX > 0 ? -overflowX * (cropPanX - 0.5) : 0;\n const offsetY = overflowY > 0 ? -overflowY * (cropPanY - 0.5) : 0;\n const svgX = x + w / 2 + offsetX - drawW / 2;\n const svgY = y + h / 2 + offsetY - drawH / 2;\n\n try {\n const seq6 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq6} elementId=${element.id} path=drawElement-svg-crop`);\n pdf.saveGraphicsState();\n // Clip to frame\n pdf.setLineWidth(0);\n pdf.rect(x, y, w, h, null as unknown as string);\n pdf.clip();\n if (typeof (pdf as any).discardPath === 'function') (pdf as any).discardPath();\n resetPdfColorState(pdf, `before svg2pdf #${seq6} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n pdf.setGState(pdf.GState({ opacity: 1, 'stroke-opacity': 1 }));\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq6, element.id), svg2pdfOpts(svgX, svgY, drawW, drawH));\n debugLog(`svg2pdf DONE #${seq6} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq6} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq6} ${element.id}`);\n break;\n } catch {\n pdf.restoreGraphicsState();\n // fall through to raster\n }\n }\n }\n\n // For raster images with crop: rasterize with clipping\n if (hasStoredCrop && !isSvg) {\n const croppedPng = await rasterizeStoredCropImageToPng({\n imageUrl,\n frameW: w,\n frameH: h,\n clipShape: (element as any).clipShape,\n borderRadius: Number((element as any).rx ?? (element as any).borderRadius ?? norm.borderRadius ?? 0) || 0,\n panX: Number((element as any).cropPanX ?? 0.5),\n panY: Number((element as any).cropPanY ?? 0.5),\n zoom: Number((element as any).cropZoom ?? 1),\n naturalWidth: Number((element as any).imageNaturalWidth ?? 0),\n naturalHeight: Number((element as any).imageNaturalHeight ?? 0),\n maintainResolution: (element as any).maintainResolution !== false,\n backgroundColor,\n });\n if (croppedPng) {\n try {\n const fadedCrop = await bakeEdgeFadeIntoDataUrl(croppedPng, element);\n const finalCropPng = fadedCrop || croppedPng;\n pdf.addImage(finalCropPng, 'PNG', x, y, w, h, undefined, 'SLOW');\n break;\n } catch {\n // fall through to default image path\n }\n }\n }\n\n // Embed SVG as vector for infinite scalability\n // Edge-fade requires a raster mask; skip vector embed when fade is active.\n const canVectorizeSvg = isSvg && !elementHasFade(element);\n if (canVectorizeSvg) {\n const svgElement = await fetchSvgAsElement(imageUrl, element.svgColorMap);\n if (svgElement) {\n expandSvgUseElements(svgElement, element.id);\n const svgToDraw = normalizeSvgExplicitColors(svgElement);\n inlineComputedStyles(svgToDraw);\n normalizeSvgGradientStopOffsets(svgToDraw);\n expandSvgGradientHrefs(svgToDraw);\n resolveSvgGradientRefsToSolid(svgToDraw, element.id);\n prefixSvgIds(svgToDraw, element.id);\n bakeGroupOpacityIntoChildren(svgToDraw);\n injectOpacityIntoSvg(svgToDraw, norm.opacity);\n try {\n const seq5 = ++debugSvgDrawSequence;\n debugLog(`svg2pdf START #${seq5} elementId=${element.id} path=drawElement-image`);\n pdf.saveGraphicsState();\n resetPdfColorState(pdf, `before svg2pdf #${seq5} ${element.id}`);\n resetPdfColorState(pdf, `immediately before svg2pdf #${seq5} ${element.id}`);\n setPdfColorFromSvg(pdf, svgToDraw, element.id);\n await svg2pdfWithDomMount(svgToDraw, pdfWithColorLogging(pdf, seq5, element.id), svg2pdfOpts(x, y, w, h));\n debugLog(`svg2pdf DONE #${seq5} elementId=${element.id}`);\n resetPdfColorState(pdf, `after svg2pdf #${seq5} ${element.id}`);\n pdf.restoreGraphicsState();\n resetPdfColorState(pdf, `after restore #${seq5} ${element.id}`);\n } catch {\n // Raster fallback for SVG vector embed failure — use recolored URL if available\n const rasterUrl = await getRecoloredSvgDataUrl(imageUrl, element.svgColorMap) || imageUrl;\n const imageData = await fetchImageAsBase64(rasterUrl, {\n backgroundColor,\n targetWidthPt: w,\n targetHeightPt: h,\n preserveAlpha: true,\n resolutionMultiplier: 4,\n });\n if (imageData) {\n const fadedFallback = await bakeEdgeFadeIntoDataUrl(imageData.data, element);\n if (fadedFallback) {\n imageData.data = fadedFallback;\n imageData.format = 'PNG';\n }\n try {\n pdf.addImage(imageData.data, imageData.format, x, y, w, h, undefined, 'SLOW');\n } catch {\n // Skip\n }\n }\n }\n break;\n }\n }\n // Raster path (PNG/JPG or SVG fallback)\n const rasterUrlFinal = isSvg ? (await getRecoloredSvgDataUrl(imageUrl, element.svgColorMap) || imageUrl) : imageUrl;\n const preserveAlpha = isSvg || (w > canvasWidth * 0.7 && h > canvasHeight * 0.7);\n const imageData = await fetchImageAsBase64(rasterUrlFinal, {\n backgroundColor: backgroundColor,\n targetWidthPt: w,\n targetHeightPt: h,\n preserveAlpha: preserveAlpha || elementHasFade(element),\n resolutionMultiplier: isSvg ? 4 : undefined,\n });\n if (imageData) {\n const faded = await bakeEdgeFadeIntoDataUrl(imageData.data, element);\n if (faded) {\n imageData.data = faded;\n imageData.format = 'PNG';\n }\n try {\n pdf.addImage(imageData.data, imageData.format, x, y, w, h, undefined, 'SLOW');\n } catch {\n // Skip image on add failure\n }\n }\n }\n break;\n }\n }\n}\n\n/**\n * Export canvas elements to a true vector PDF (single page)\n * @param _fabricCanvas - Deprecated, kept for API compatibility. Elements are read from options.\n */\nexport async function exportFabricCanvasToVectorPdf(\n _fabricCanvas: fabric.Canvas,\n options: {\n filename?: string;\n width: number;\n height: number;\n title?: string;\n elements: CanvasElement[];\n backgroundColor?: string;\n }\n): Promise<void> {\n const { filename = 'document.pdf', width, height, title, elements, backgroundColor } = options;\n resetPdfFontRegistry();\n\n // Create PDF with px units to match canvas exactly\n const orientation = width > height ? 'landscape' : 'portrait';\n const pdf = new jsPDF({\n orientation,\n unit: 'px',\n format: [width, height],\n hotfixes: ['px_scaling'],\n compress: true,\n });\n\n if (title) {\n pdf.setProperties({ title, creator: 'DocuForge' });\n }\n\n // Draw background\n if (backgroundColor && backgroundColor !== 'transparent') {\n const bgColor = parseColor(backgroundColor);\n if (bgColor) {\n pdf.setFillColor(bgColor.r, bgColor.g, bgColor.b);\n pdf.rect(0, 0, width, height, 'F');\n }\n }\n\n const fontKeysNeeded = new Set<string>();\n const italicKeysNeeded = new Set<string>();\n elements.forEach(el => {\n if (el.type === 'text') {\n collectTextFontVariantsForPdf(el, fontKeysNeeded, italicKeysNeeded);\n }\n });\n // Always embed symbol fallback so ● ◆ ★ etc. render\n fontKeysNeeded.add(`${FONT_FALLBACK_SYMBOLS}${FONT_KEY_SEP}400`);\n // Always embed math fallback so ≠ ≤ ≥ ≈ ∞ → ∑ √ ∈ … render\n fontKeysNeeded.add(`${FONT_FALLBACK_MATH}${FONT_KEY_SEP}400`);\n // Always embed Devanagari fallback for Hindi text support\n for (const w of [300, 400, 500, 600, 700]) {\n fontKeysNeeded.add(`${FONT_FALLBACK_DEVANAGARI}${FONT_KEY_SEP}${w}`);\n }\n\n const embeddedFonts = new Set<string>();\n for (const key of fontKeysNeeded) {\n const sep = key.indexOf(FONT_KEY_SEP);\n const fontName = key.slice(0, sep);\n const weight = parseInt(key.slice(sep + 1), 10);\n const success = await embedFontWithGoogleFallback(pdf, fontName, weight);\n if (success) embeddedFonts.add(key);\n }\n // Embed italic variants\n for (const key of italicKeysNeeded) {\n const parts = key.split(FONT_KEY_SEP);\n const fontName = parts[0];\n const weight = parseInt(parts[1], 10);\n const success = await embedFontWithGoogleFallback(pdf, fontName, weight, true);\n if (success) embeddedFonts.add(key);\n }\n\n // Diagnostic embed list\n try {\n const list = getEmbeddedVariantsList();\n // eslint-disable-next-line no-console\n console.log(`[pdfFonts] embedded variants (${list.length}):`, list);\n } catch {}\n\n // Draw elements in order (bottom to top) using the helper\n debugLog(`single-page export: drawing ${elements.length} elements (order = first=back, last=front)`);\n elements.forEach((el, i) => debugLog(` [${i}] id=${el.id} type=${el.type}`));\n for (const element of elements) {\n await drawElement(pdf, element, embeddedFonts, width, height, backgroundColor);\n }\n\n // Save the PDF\n pdf.save(filename);\n}\n\n/** Group background rect drawn in PDF (same z-order as on canvas) */\nexport type GroupBackgroundDrawable = {\n type: 'groupBackground';\n id: string;\n left: number;\n top: number;\n width: number;\n height: number;\n fill: string;\n};\n\nexport type PageDrawableItem = CanvasElement | GroupBackgroundDrawable;\n\nfunction isGroupBackgroundDrawable(item: PageDrawableItem): item is GroupBackgroundDrawable {\n return (item as GroupBackgroundDrawable).type === 'groupBackground';\n}\n\n/** Build draw list in tree order (group bgs behind their content) so PDF matches canvas. */\nfunction buildPageDrawList(\n children: CanvasNode[],\n pageTree: CanvasNode[],\n visibilityFilter: 'strict' | 'lenient'\n): PageDrawableItem[] {\n const out: PageDrawableItem[] = [];\n function visit(nodes: CanvasNode[], reverseGroupChildren: boolean) {\n const list = reverseGroupChildren ? [...nodes].reverse() : nodes;\n for (const n of list) {\n if (isElement(n)) {\n if (visibilityFilter === 'strict' ? n.visible !== false : n.visible) out.push(n);\n } else if (isGroup(n)) {\n const g = n as GroupNode;\n if (g.backgroundColor && g.backgroundColor !== 'transparent') {\n const abs = getAbsoluteBounds(g, pageTree);\n out.push({\n type: 'groupBackground',\n id: g.id,\n left: abs.left,\n top: abs.top,\n width: Math.max(1, abs.width),\n height: Math.max(1, abs.height),\n fill: g.backgroundColor,\n });\n }\n visit(g.children ?? [], true);\n }\n }\n }\n visit(children, false);\n return out;\n}\n\n/**\n * Prepare pages data for PDF export from either editor canvas or use template preview\n * This ensures consistent filtering and sorting across both export paths.\n * Includes group background rects in tree order so they appear in the rendered PDF.\n */\nexport function preparePagesForExport(\n pages: Array<{\n id?: string;\n children?: CanvasNode[] | any[];\n settings?: { backgroundColor?: string; backgroundGradient?: any };\n }>,\n canvasWidth: number,\n canvasHeight: number,\n options?: {\n sortByTop?: boolean; // Sort elements by top position (for z-order when no group bgs)\n visibilityFilter?: 'strict' | 'lenient'; // 'strict' = el.visible !== false, 'lenient' = el.visible\n }\n): Array<{\n pageId?: string;\n elements: PageDrawableItem[];\n pageChildren?: CanvasNode[];\n width: number;\n height: number;\n backgroundColor?: string;\n}> {\n const { sortByTop = false, visibilityFilter = 'strict' } = options || {};\n\n return pages.map(page => {\n const pageChildren = (page.children || []) as CanvasNode[];\n const drawList = buildPageDrawList(pageChildren, pageChildren, visibilityFilter);\n\n // If no group backgrounds were added, we can optionally sort elements by top for z-order\n const elements =\n sortByTop && drawList.every(item => !isGroupBackgroundDrawable(item))\n ? [...drawList].sort((a, b) => {\n const aTop = 'top' in a ? (a.top ?? (a as CanvasElement).position?.y ?? 0) : 0;\n const bTop = 'top' in b ? (b.top ?? (b as CanvasElement).position?.y ?? 0) : 0;\n return aTop - bTop;\n })\n : drawList;\n\n return {\n pageId: page.id,\n elements,\n pageChildren,\n width: canvasWidth,\n height: canvasHeight,\n backgroundColor: page.settings?.backgroundColor || '#ffffff',\n backgroundGradient: page.settings?.backgroundGradient,\n };\n });\n}\n\n/**\n * Export multiple pages to a single PDF.\n *\n * By default writes the PDF as a download via `pdf.save(filename)`. When\n * `returnBlob: true` is passed, returns `{ blob, arrayBuffer, totalPages, pages }`\n * instead so callers (e.g. the canvas-renderer package server harness) can use\n * the exact same draw pipeline without triggering a browser download.\n */\nexport async function exportMultiPagePdf(\n pages: Array<{\n pageId?: string;\n elements: PageDrawableItem[];\n pageChildren?: CanvasNode[];\n width: number;\n height: number;\n backgroundColor?: string;\n backgroundGradient?: any;\n }>,\n options: {\n filename?: string;\n title?: string;\n watermark?: boolean;\n /** When true, skip pdf.save() and return PDF blob/arraybuffer instead. */\n returnBlob?: boolean;\n /**\n * PDF text rendering mode. Affects how gradient text fills are handled:\n * - 'selectable' (default): text stays live; gradient fills resolve to the\n * first stop colour because svg2pdf can't render gradients on live text.\n * - 'auto': text with a gradient fill is outlined to <path> so the\n * gradient renders in the PDF (only that text loses selectability;\n * everything else stays selectable).\n * - 'pixel-perfect': every text element is outlined to vector paths for\n * visual parity, whether it uses a gradient fill or not.\n */\n pdfTextMode?: 'auto' | 'selectable' | 'pixel-perfect';\n }\n): Promise<void | { blob: Blob; arrayBuffer: ArrayBuffer; totalPages: number; pages: Array<{ width: number; height: number }> }> {\n const { filename = 'document.pdf', title, watermark = false, returnBlob = false, pdfTextMode = 'selectable' } = options;\n resetPdfFontRegistry();\n\n if (pages.length === 0) {\n throw new Error('No pages to export');\n }\n\n const firstPage = pages[0];\n const orientation = firstPage.width > firstPage.height ? 'landscape' : 'portrait';\n\n const pdf = new jsPDF({\n orientation,\n unit: 'px',\n format: [firstPage.width, firstPage.height],\n hotfixes: ['px_scaling'],\n compress: true,\n });\n\n if (title) {\n pdf.setProperties({ title, creator: 'DocuForge' });\n }\n\n const fontKeysNeeded = new Set<string>();\n const italicKeysNeeded = new Set<string>();\n pages.forEach(page => {\n page.elements.forEach(item => {\n if (!isGroupBackgroundDrawable(item) && item.type === 'text') {\n collectTextFontVariantsForPdf(item, fontKeysNeeded, italicKeysNeeded);\n }\n });\n });\n fontKeysNeeded.add(`${FONT_FALLBACK_SYMBOLS}${FONT_KEY_SEP}400`);\n fontKeysNeeded.add(`${FONT_FALLBACK_MATH}${FONT_KEY_SEP}400`);\n for (const w of [300, 400, 500, 600, 700]) {\n fontKeysNeeded.add(`${FONT_FALLBACK_DEVANAGARI}${FONT_KEY_SEP}${w}`);\n }\n\n const embeddedFonts = new Set<string>();\n for (const key of fontKeysNeeded) {\n const sep = key.indexOf(FONT_KEY_SEP);\n const fontName = key.slice(0, sep);\n const weight = parseInt(key.slice(sep + 1), 10);\n const success = await embedFontWithGoogleFallback(pdf, fontName, weight);\n if (success) embeddedFonts.add(key);\n await yieldToUI(); // Let spinner animate between font embeds\n }\n for (const key of italicKeysNeeded) {\n const parts = key.split(FONT_KEY_SEP);\n const fontName = parts[0];\n const weight = parseInt(parts[1], 10);\n const success = await embedFontWithGoogleFallback(pdf, fontName, weight, true);\n if (success) embeddedFonts.add(key);\n await yieldToUI();\n }\n\n await yieldToUI(); // Yield before page rendering begins\n\n // Diagnostic: log the exact embed list so we can compare client vs server.\n // Helps pinpoint file-size discrepancies between the two pipelines.\n try {\n const list = getEmbeddedVariantsList();\n // eslint-disable-next-line no-console\n console.log(`[pdfFonts] embedded variants (${list.length}):`, list);\n } catch {}\n\n // Draw each page\n for (let pageIndex = 0; pageIndex < pages.length; pageIndex++) {\n const page = pages[pageIndex];\n\n // Add new page for pages after the first\n if (pageIndex > 0) {\n const pageOrientation = page.width > page.height ? 'landscape' : 'portrait';\n pdf.addPage([page.width, page.height], pageOrientation);\n }\n\n // Draw background — gradient using native PDF shading patterns (axial/radial).\n // This produces perfectly smooth gradients with minimal file size — no strips needed.\n if (page.backgroundGradient && page.backgroundGradient.stops?.length >= 2) {\n const grad = page.backgroundGradient;\n const colorStops = grad.stops\n .map((s: any) => {\n const c = parseColor(s.color);\n return {\n offset: Math.max(0, Math.min(1, Number(s.offset))),\n color: c ? [c.r, c.g, c.b] as [number, number, number] : [0, 0, 0] as [number, number, number],\n };\n })\n .filter((s: any) => Number.isFinite(s.offset))\n .sort((a: any, b: any) => a.offset - b.offset);\n\n const normalizedStops = [...colorStops];\n if (normalizedStops.length > 0) {\n if (normalizedStops[0].offset > 0) {\n normalizedStops.unshift({ offset: 0, color: normalizedStops[0].color });\n }\n if (normalizedStops[normalizedStops.length - 1].offset < 1) {\n const last = normalizedStops[normalizedStops.length - 1];\n normalizedStops.push({ offset: 1, color: last.color });\n }\n }\n\n const shadingColors = normalizedStops.map(s => ({ offset: s.offset, color: s.color }));\n const patternKey = `bg-grad-${pageIndex}`;\n\n try {\n pdf.advancedAPI((doc: any) => {\n const isLinear = grad.type === 'linear';\n const isConic = grad.type === 'conic';\n\n if (isLinear || isConic) {\n // For conic gradients, approximate with a linear gradient at the specified angle\n // PDF doesn't support conic natively. We use a linear sweep as a reasonable fallback.\n const angleDeg = grad.angle ?? (isConic ? 0 : 90);\n const angleRad = (angleDeg * Math.PI) / 180;\n const sinA = Math.sin(angleRad);\n const cosA = Math.cos(angleRad);\n\n // Project page corners onto gradient direction to find extent\n const corners = [[0, 0], [page.width, 0], [page.width, page.height], [0, page.height]];\n const projs = corners.map(([x, y]) => x * sinA - y * cosA);\n const minP = Math.min(...projs);\n const maxP = Math.max(...projs);\n const gradLen = maxP - minP;\n\n const midX = page.width / 2;\n const midY = page.height / 2;\n const halfLen = gradLen / 2;\n const x1 = midX - sinA * halfLen;\n const y1 = midY + cosA * halfLen;\n const x2 = midX + sinA * halfLen;\n const y2 = midY - cosA * halfLen;\n\n // For conic, duplicate stops to wrap around (simulate the sweep)\n let finalStops = shadingColors;\n if (isConic && shadingColors.length >= 2) {\n // Mirror the stops to create a sweep effect: original + reversed\n const reversed = [...shadingColors].reverse().map((s, idx, arr) => ({\n offset: 0.5 + (1 - s.offset) * 0.5,\n color: s.color,\n }));\n const firstHalf = shadingColors.map(s => ({\n offset: s.offset * 0.5,\n color: s.color,\n }));\n finalStops = [...firstHalf, ...reversed.slice(1)];\n }\n\n doc.addShadingPattern(\n patternKey,\n new ShadingPattern('axial', [x1, y1, x2, y2], finalStops)\n );\n } else {\n // Radial gradient\n const cx = (grad.cx ?? 0.5) * page.width;\n const cy = (grad.cy ?? 0.5) * page.height;\n // Match canvas/Fabric radial gradient radius mapping for color parity.\n const maxR = (grad.r ?? 0.5) * Math.max(page.width, page.height);\n\n doc.addShadingPattern(\n patternKey,\n new ShadingPattern('radial', [cx, cy, 0, cx, cy, maxR], shadingColors)\n );\n }\n\n // Draw rect clipping path then fill with the shading pattern\n doc.rect(0, 0, page.width, page.height);\n doc.fill({ key: patternKey, matrix: doc.Matrix(1, 0, 0, 1, 0, 0) });\n });\n } catch (e) {\n debugLog(`Native gradient shading failed, falling back to solid: ${e}`);\n const fallback = colorStops[0]?.color || [255, 255, 255];\n pdf.setFillColor(fallback[0], fallback[1], fallback[2]);\n pdf.rect(0, 0, page.width, page.height, 'F');\n }\n } else {\n const bgColor = parseColor(page.backgroundColor && page.backgroundColor !== 'transparent' ? page.backgroundColor : '#ffffff');\n debugLog(`page ${pageIndex + 1} background: ${page.backgroundColor ?? 'default'} → rgb(${bgColor?.r ?? 0},${bgColor?.g ?? 0},${bgColor?.b ?? 0})`);\n if (bgColor) {\n pdf.setFillColor(bgColor.r, bgColor.g, bgColor.b);\n pdf.rect(0, 0, page.width, page.height, 'F');\n }\n }\n\n const liveCanvasForPage = page.pageId ? getCanvasForPage(page.pageId) : null;\n let allowLiveCanvasFallback = !!liveCanvasForPage;\n\n // Prefer exporting the actual live Fabric canvas as SVG first.\n // This is the closest client-side match to the server's Fabric -> SVG -> svg2pdf pipeline.\n if (liveCanvasForPage) {\n try {\n // SHARED CAPTURE: identical to the client `renderPageSvg` pipeline —\n // does VPT/retina neutralization, edge-fade bake, toSVG, and root\n // <svg> normalization in one place so client and server PDFs match.\n const liveSvgString = captureFabricCanvasSvgForPdf(\n liveCanvasForPage as any,\n page.width,\n page.height,\n );\n const liveSvgWidth = page.width;\n const liveSvgHeight = page.height;\n // SHARED JIT FONT EMBED: must run BEFORE prepareLiveCanvasSvgForPdf\n // so the SVG-font rewriter (inside prepareLiveCanvasSvgForPdf) maps\n // each (family, weight, italic) tuple in the live SVG to the correct\n // embedded jsPDF font. Without this the rewriter can fall back to a\n // different variant on the server (which never ran the JIT pass),\n // changing glyph advance widths → horizontal text drift on\n // center-aligned text and a slight shadow offset (the rasterized\n // shadow marker is anchored to the text's bounding box).\n try {\n await embedFontsForSvg(pdf, liveSvgString);\n } catch (fontEmbedErr) {\n console.warn('[client-pdf-export] JIT font embed for live SVG failed', fontEmbedErr);\n }\n // Shared text-prep contract with @pixldocs/canvas-renderer:\n // pixel-perfect → outline all text\n // auto → outline only gradient text\n // selectable → keep text live, replace gradient with first stop\n let preppedSvgString = liveSvgString;\n try {\n const { prepareSvgTextForPdfMode } = await import('@/lib/svgTextToPath');\n preppedSvgString = await prepareSvgTextForPdfMode(liveSvgString, pdfTextMode);\n console.log('[client-pdf-export] gradient text mode', {\n pdfTextMode,\n outlinedAllText: pdfTextMode === 'pixel-perfect',\n outlinedGradientText: pdfTextMode === 'auto',\n });\n } catch (gradErr) {\n console.warn('[client-pdf-export] gradient-text fill resolution failed', gradErr);\n }\n const liveSvg = await prepareLiveCanvasSvgForPdf(\n preppedSvgString,\n liveSvgWidth,\n liveSvgHeight,\n `page-${pageIndex + 1}`,\n { stripPageBackground: !!page.backgroundGradient },\n );\n\n if (liveSvg) {\n const seq = ++debugSvgDrawSequence;\n console.log(`[client-pdf-export] live SVG path active for page ${pageIndex + 1}`);\n debugLog(`live canvas svg2pdf START #${seq} page=${pageIndex + 1}`);\n resetPdfColorState(pdf, `before live canvas svg2pdf page ${pageIndex + 1}`);\n setPdfColorFromSvg(pdf, liveSvg, `page-${pageIndex + 1}`);\n await svg2pdfWithDomMount(\n liveSvg,\n pdfWithColorLogging(pdf, seq, `page-${pageIndex + 1}`),\n svg2pdfOpts(0, 0, page.width, page.height),\n );\n debugLog(`live canvas svg2pdf DONE #${seq} page=${pageIndex + 1}`);\n resetPdfColorState(pdf, `after live canvas svg2pdf page ${pageIndex + 1}`);\n await yieldToUI();\n continue;\n }\n allowLiveCanvasFallback = false;\n console.error(`[client-pdf-export] live SVG prep returned null for page ${pageIndex + 1}`, {\n pageId: page.pageId,\n hasLiveCanvas: !!liveCanvasForPage,\n svgLength: liveSvgString?.length ?? 0,\n });\n } catch (error) {\n allowLiveCanvasFallback = false;\n console.error(`[client-pdf-export] live SVG export failed for page ${pageIndex + 1}`, error);\n debugLog(`live canvas svg export failed on page ${pageIndex + 1}, falling back to config-space export without live matrices: ${error}`);\n }\n }\n\n // If we have a live Fabric canvas for this page, use its objects' transform matrices.\n // This avoids any subtle drift between stored values and Fabric's internal layout math.\n // IMPORTANT: For grouped elements, we need to look inside fabric.Group objects\n // because group members are not top-level canvas objects.\n const matrixByElementId = new Map<string, number[]>();\n const intrinsicByElementId = new Map<string, { w: number; h: number }>();\n\n const getIntrinsic = (o: fabric.FabricObject): { w: number; h: number } => {\n if (o instanceof fabric.Circle) {\n const r = (o as any).radius ?? 0;\n return { w: r * 2, h: r * 2 };\n }\n if (o instanceof fabric.Ellipse) {\n return { w: (o.rx ?? 0) * 2, h: (o.ry ?? 0) * 2 };\n }\n return { w: o.width ?? 0, h: o.height ?? 0 };\n };\n\n // Live Fabric text objects: use their exact line layout for WYSIWYG text export\n const liveTextByElementId = new Map<string, fabric.FabricObject>();\n\n if (page.pageId && allowLiveCanvasFallback) {\n const liveCanvas = getCanvasForPage(page.pageId);\n if (liveCanvas) {\n const objects = liveCanvas.getObjects();\n const isTextLike = (o: fabric.FabricObject) =>\n o instanceof fabric.Textbox || o instanceof fabric.IText || (o as any).constructor?.name === 'Textbox' || (o as any).constructor?.name === 'Text';\n\n for (const obj of objects) {\n const isCropGroup = obj instanceof fabric.Group && (obj as any).__cropGroup;\n if (isCropGroup) {\n const id = (obj as any).__docuforgeId as string | undefined;\n if (!id || id === '__background__') continue;\n (obj as any).__exportAsRenderedImage = true;\n intrinsicByElementId.set(id, getIntrinsic(obj));\n try {\n matrixByElementId.set(id, (obj as any).calcTransformMatrix());\n } catch {\n }\n continue;\n }\n\n const isSectionGroup = obj instanceof fabric.Group && (obj as any).__docuforgeSectionGroup;\n const groupId = (obj as any).__docuforgeGroupId as string | undefined;\n if ((groupId || isSectionGroup) && obj instanceof fabric.Group) {\n const groupMatrix = obj.calcTransformMatrix();\n const memberObjects = obj.getObjects();\n for (const memberObj of memberObjects) {\n const memberId = (memberObj as any).__docuforgeId as string | undefined;\n if (!memberId) continue;\n\n intrinsicByElementId.set(memberId, getIntrinsic(memberObj));\n if (isTextLike(memberObj)) {\n liveTextByElementId.set(memberId, memberObj);\n }\n\n try {\n const memberLocalMatrix =\n (memberObj as any).calcOwnMatrix?.() ?? (memberObj as any).calcTransformMatrix?.();\n\n if (memberLocalMatrix && memberLocalMatrix.length === 6) {\n const [a1, b1, c1, d1, e1, f1] = groupMatrix;\n const [a2, b2, c2, d2, e2, f2] = memberLocalMatrix;\n const absoluteMatrix = [\n a1 * a2 + c1 * b2,\n b1 * a2 + d1 * b2,\n a1 * c2 + c1 * d2,\n b1 * c2 + d1 * d2,\n a1 * e2 + c1 * f2 + e1,\n b1 * e2 + d1 * f2 + f1,\n ];\n matrixByElementId.set(memberId, absoluteMatrix);\n }\n } catch {\n }\n }\n continue;\n }\n\n const id = (obj as any).__docuforgeId as string | undefined;\n if (!id || id === '__background__') continue;\n\n intrinsicByElementId.set(id, getIntrinsic(obj));\n if (isTextLike(obj)) {\n liveTextByElementId.set(id, obj);\n }\n\n try {\n matrixByElementId.set(id, (obj as any).calcTransformMatrix());\n } catch {\n }\n }\n }\n }\n\n // When we have a live canvas, use its object order so PDF z-order matches what's on screen.\n // (sortByTop in preparePagesForExport can reorder by y-position and break stacking.)\n let drawList = page.elements;\n if (page.pageId && allowLiveCanvasFallback) {\n const liveCanvas = getCanvasForPage(page.pageId);\n const hasGroupBgs = page.elements.some(item => isGroupBackgroundDrawable(item));\n if (liveCanvas && !hasGroupBgs) {\n const canvasOrderIds = liveCanvas.getObjects().map((o: fabric.FabricObject) => (o as any).__docuforgeId as string).filter(Boolean);\n const byId = new Map((page.elements as CanvasElement[]).map(el => [el.id, el]));\n const reordered: PageDrawableItem[] = [];\n for (const id of canvasOrderIds) {\n const el = byId.get(id);\n if (el) reordered.push(el);\n }\n for (const item of page.elements) {\n if (!reordered.includes(item)) reordered.push(item);\n }\n drawList = reordered.length ? reordered : page.elements;\n }\n }\n\n // ── CLIENT PARITY LOG: print text positions in same format as EC2 server ──\n const clientTextPositions: Array<{p:number; id:string; top:number; left:number; w:number; h:number; fs:number; lh:number; angle:number; text:string}> = [];\n for (const item of drawList) {\n if (isGroupBackgroundDrawable(item)) continue;\n const el = item as CanvasElement;\n if (el.type !== 'text') continue;\n const n = normalizeElement(el);\n // If we have pageChildren, use getAbsoluteBounds for true position\n let absX = n.x, absY = n.y, absW = n.w, absH = n.h;\n if (page.pageChildren?.length) {\n const node = findNodeById(page.pageChildren, el.id);\n if (node) {\n const abs = getAbsoluteBounds(node, page.pageChildren);\n absX = abs.left; absY = abs.top; absW = abs.width; absH = abs.height;\n }\n }\n clientTextPositions.push({\n p: pageIndex + 1,\n id: el.id.slice(0, 50),\n top: Math.round(absY * 100) / 100,\n left: Math.round(absX * 100) / 100,\n w: Math.round(absW * 100) / 100,\n h: Math.round(absH * 100) / 100,\n fs: n.fontSize,\n lh: n.lineHeight,\n angle: n.angle,\n text: (n.text || '').replace(/\\s+/g, ' ').trim().slice(0, 60),\n });\n }\n if (clientTextPositions.length > 0) {\n console.log(`[client-pdf-export] page ${pageIndex + 1} textPositions (${clientTextPositions.length}):`, JSON.stringify(clientTextPositions));\n }\n\n // Draw items in order (first=back, last=front)\n debugSvgDrawSequence = 0;\n debugLog(`page ${pageIndex + 1}: drawing ${drawList.length} items (order = first=back, last=front)`);\n resetPdfColorState(pdf, `page ${pageIndex + 1} start`);\n for (let drawIndex = 0; drawIndex < drawList.length; drawIndex++) {\n const item = drawList[drawIndex];\n if (isGroupBackgroundDrawable(item)) {\n debugLog(` [${drawIndex}] groupBg id=${item.id}`);\n const c = parseColor(item.fill);\n if (c) {\n pdf.setFillColor(c.r, c.g, c.b);\n pdf.rect(item.left, item.top, item.width, item.height, 'F');\n }\n continue;\n }\n const element = item;\n const imgUrl = element.type === 'image' ? (element.imageUrl || element.src || '').slice(-40) : '';\n debugLog(` [${drawIndex}] element id=${element.id} type=${element.type} ${imgUrl ? `imageUrl=...${imgUrl}` : ''}`);\n // Prefer live canvas matrix, fall back to stored transformMatrix if available\n const liveMatrix = matrixByElementId.get(element.id);\n const storedMatrix = element.transformMatrix;\n const m = liveMatrix ?? storedMatrix ?? null;\n let intrinsic = intrinsicByElementId.get(element.id) ?? null;\n \n const liveText = element.type === 'text' ? liveTextByElementId.get(element.id) : undefined;\n await drawElement(pdf, element, embeddedFonts, page.width, page.height, page.backgroundColor, m, intrinsic, page.pageId, liveText, page.pageChildren);\n\n // Yield every 3 elements to keep UI responsive (spinners, progress bars)\n if (drawIndex % 3 === 2) await yieldToUI();\n }\n\n // Yield between pages\n await yieldToUI();\n }\n\n // Add watermark if requested (free downloads)\n if (watermark) {\n const { addWatermarkToAllPages } = await import('@/lib/pdfWatermark');\n addWatermarkToAllPages(pdf);\n }\n\n if (returnBlob) {\n const arrayBuffer = (pdf.output('arraybuffer') as ArrayBuffer);\n const blob = new Blob([arrayBuffer], { type: 'application/pdf' });\n return {\n blob,\n arrayBuffer,\n totalPages: pages.length,\n pages: pages.map(p => ({ width: p.width, height: p.height })),\n };\n }\n\n pdf.save(filename);\n}\n"],"names":["FONT_FALLBACK_SYMBOLS","FONT_FALLBACK_DEVANAGARI","FONT_FALLBACK_MATH","_a","elementHasEdgeFade","m","r","g","b","_b","blob","type","hasAlpha","jpegUrl","flattenWithBg","dataUrl","rx","outW","outH","el","exportCanvas","png","_e","panX","panY","zoom","scaleX","scaleY","anyPdf","canUseAdvancedTransforms","angle","hasRotation","clampedOpacity","imageData","linkUrl","id"],"mappings":"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"}